Skip to content

fix: Go2 EDU connection on Windows (multicast, AP IP, data2=3 AES, error messages) - #6

Open
fractalsuar wants to merge 1 commit into
legion1581:mainfrom
fractalsuar:fix/go2-edu-windows-connection
Open

fix: Go2 EDU connection on Windows (multicast, AP IP, data2=3 AES, error messages)#6
fractalsuar wants to merge 1 commit into
legion1581:mainfrom
fractalsuar:fix/go2-edu-windows-connection

Conversation

@fractalsuar

Copy link
Copy Markdown

Summary

Four bugs found while connecting a Go2 EDU from a Windows 11 laptop in Access Point (dongle WiFi) mode. All four blocked connection independently.


Bug 1 — Windows multicast scan always returns empty

File: src/proxy-plugin.ts

On Windows, machines almost always have multiple virtual network adapters (WSL, Hyper-V, VirtualBox). The OS routes the outgoing UDP multicast query on a virtual adapter rather than the physical WiFi — the robot never sees it and scan returns nothing.

Fix: Enumerate all non-loopback IPv4 interfaces with os.networkInterfaces() and create a separate sender socket per interface with socket.setMulticastInterface(iface). Also call addMembership / dropMembership per interface on the listener socket.


Bug 2 — AP mode default IP is wrong for Go2 EDU

File: src/connection/modes.ts

DEFAULT_AP_IP was 192.168.12.1. The Go2 EDU has a two-computer architecture: a companion Ubuntu computer (eth0: 192.168.123.18, wlan0/hotspot: 10.42.0.1) and a separate main MCU at 192.168.123.161 where the WebRTC service actually runs on port 9991.

Fix: Changed DEFAULT_AP_IP to 192.168.123.161.


Bug 3 — No way to auto-detect the correct robot IP

Files: src/proxy-plugin.ts, src/ui/connection-panel.ts

With scan broken and the default IP wrong, there was no way to find the robot without already knowing the address.

Fix: Added a /gateway endpoint to the Vite proxy that probes known Go2 candidate IPs on port 9991 and returns the first that responds. Added a Detect button next to the IP field that calls this and auto-fills the result.


Bug 4 — data2=3 from /con_notify causes silent failure on Go2 EDU

File: src/connection/local-connector.ts

Go2 EDU with current firmware returns data2=3 from /con_notify, meaning the payload is AES-128-GCM encrypted with a per-device 16-byte key stored on the robot at /unitree/dev.key. The existing code only handled data2=2 (static key) and silently fell through on data2=3, causing an opaque failure with no useful error message.

Fix: Added a data2=3 branch that:

  1. Checks localStorage for a cached per-device key (keyed by serial number)
  2. If missing, prompts the user once to enter the 32-char hex key
  3. Decrypts using AES-128-GCM with Unitree payload layout: [ ciphertext | nonce(12) | tag(16) ]
  4. Caches the key on success so it is never asked again
  5. On GCM tag mismatch (wrong key), flushes the cache and re-prompts up to 3 times

Also improved detectPort() to report per-port HTTP status or error in the failure message.


Test environment

  • Robot: Unitree Go2 EDU, firmware returning data2=3
  • OS: Windows 11 with WSL + Hyper-V adapters present
  • Mode: Access Point (laptop WiFi switched to Go2 dongle hotspot)
  • Robot IP: 192.168.123.161:9991

Test plan

  • Scan finds robot on Windows with multiple network adapters
  • Detect button fills correct IP in AP mode
  • Connection succeeds on Go2 EDU after entering device AES key once
  • AES key remembered across page reloads
  • Wrong key clears cache and re-prompts
  • Existing Go2 (data2=2) and G1 connections unaffected

🤖 Generated with Claude Code

…rror messages

Tested on Go2 EDU (firmware returning data2=3) from a Windows 11 laptop
connected via the robot's WiFi dongle in Access Point mode.

Four independent fixes:

1. Windows multicast scan always fails (proxy-plugin.ts)
   On Windows, multiple virtual adapters (WSL, Hyper-V, VirtualBox) cause
   the OS to route the outgoing UDP multicast on the wrong interface.
   Fix: enumerate all non-loopback IPv4 interfaces via os.networkInterfaces()
   and create a separate sender socket per interface with
   socket.setMulticastInterface(iface). Also call addMembership /
   dropMembership per interface on the listener socket.

2. AP mode default IP wrong for Go2 EDU (modes.ts)
   DEFAULT_AP_IP was 192.168.12.1. The Go2 EDU has a two-computer
   architecture: companion Ubuntu (eth0: 192.168.123.18, wlan0: 10.42.0.1)
   and a main MCU at 192.168.123.161 where the WebRTC service runs.
   Fix: change DEFAULT_AP_IP to 192.168.123.161.

3. Detect button + /gateway endpoint (proxy-plugin.ts, connection-panel.ts)
   Added a Detect button next to the IP field that probes the known
   candidate IPs (192.168.123.161, 10.42.0.1, 192.168.12.1) on port 9991
   and auto-fills the first one that responds. Useful when the correct IP
   is unknown or differs from the default.

4. data2=3 AES-128-GCM authentication for Go2 EDU (local-connector.ts)
   Go2 EDU with current firmware returns data2=3 from /con_notify, meaning
   the payload is encrypted with a per-device AES-128-GCM key (stored on
   the robot). The existing code only handled data2=2 (static key) and
   silently failed for data2=3 with no error message.
   Fix: added decryptData1() that detects data2=3, checks localStorage for
   a cached per-device key (keyed by serial number), prompts the user once
   if missing, caches it on success, and retries up to 3 times flushing the
   cache on each GCM tag mismatch. Also improved detectPort() error messages
   to report the HTTP status or network error for each port tried.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant