Skip to content

feat(wolwifi): Wake-on-LAN over Wi-Fi (Waveshare RP2350B-Plus-W) - #120

Open
gunCannoli wants to merge 4 commits into
SundayMoments:port-devfrom
gunCannoli:feature/wol-wifi
Open

gunCannoli wants to merge 4 commits into
SundayMoments:port-devfrom
gunCannoli:feature/wol-wifi

Conversation

@gunCannoli

@gunCannoli gunCannoli commented Aug 10, 2026

Copy link
Copy Markdown

Summary

Adds Wake-on-LAN over Wi-Fi: when your DualSense controller connects to
the Pico, the firmware can send a real network magic packet to wake your PC
— even from a full shutdown, not just sleep. This is separate from the
existing USB-based "Wake PC on Controller" toggle, which relies on USB
remote wake and only works while the Pico stays connected to a PC that's
merely asleep.

Works on any board with a CYW43 Wi-Fi radio (ENABLE_WOLWIFI, on by default
for Waveshare RP2350B-Plus-W, opt-in via -DENABLE_WOLWIFI=ON on the
default Pico 2 W target — same chip). Only tested on Waveshare so far.
Boards without a radio are unaffected, with the feature compiled out via
no-op stubs.

Confirmed working end-to-end on real hardware: controller connects while
the target PC is off → WOL fires, gets ARP-confirmed within ~10s, PC wakes,
controller stays connected through the whole boot with no disconnect.

How it works

  1. Host-alive gate (ObserveHost) — on controller connect, checks
    whether the target PC already looks awake over USB before firing WOL.
    Skips the wake if the PC is already on.
  2. Wi-Fi connect — reuses the CYW43 radio already initialized for
    Bluetooth, using the SSID/password set in the companion app.
  3. Magic packet + resend-until-confirmed — sends a UDP WOL magic
    packet, watches for the target via ARP, and resends a few times if
    needed so one dropped packet doesn't leave the PC asleep.
  4. Lightbar feedback — pulses green while a send is in flight, holds
    solid green once confirmed, then restores the previous color (silently,
    with no distinct failure color, if the resend budget runs out).
  5. Non-blocking by construction — Wi-Fi/WOL failure never blocks or
    delays Bluetooth pairing, controller input, or audio. Isolated in
    wolwifi.cpp/wolwifi.h with a single call site into the existing
    connect path (bt.cpp, at the point a connection becomes Ready).

Companion app

New Wake-on-LAN section in Bridge Settings: enable toggle, Wi-Fi
SSID/password fields, and target MAC address field. Section is hidden
entirely on firmware without ENABLE_WOLWIFI.

Testing

  • Firmware: Waveshare (ENABLE_WOLWIFI on by default) and the default
    pico2_w target with -DENABLE_WOLWIFI=ON both build clean, each
    producing a valid ds5-bridge.uf2.
  • Companion: full vitest suite passes (320/320).
  • Firmware host-side test suites (firmware_logic_tests,
    usb_descriptor_migration_test, diagnostics_config_test) pass.
  • Real hardware: end-to-end WOL wake confirmed on Waveshare (PC off →
    controller connects → WOL fires → PC wakes, ARP-confirmed, no controller
    disconnect during boot); host-alive gate confirmed skipping WOL correctly
    when the PC is already on. The pico2_w build is compile-verified only —
    not run on that hardware.
  • Rebased onto current main/port-dev (v1.7.0) and reconciled the one
    real conflict: this branch's SET_WOL_* command IDs collided with
    v1.7.0's new SET_RADIAL_DEADZONES/SET_EDGE_PROFILE_SWITCHING_BLOCKED
    at 0x37. WOL's four command IDs now sit at 0x46-0x49
    (PROTOCOL_MINOR 23), past everything currently assigned.

Docs

  • README.md — new "Wake-on-LAN" section: how it works, setup steps,
    requirements.

Notes for the maintainer

  • Targets port-dev and is up to date with its current tip (through the
    v1.7.0 merge into main) — happy to retarget if you'd prefer a different
    base branch.
  • History has been squashed to two commits (firmware core, then the
    protocol/companion-app wiring) for easier review — the original
    iterative bring-up history (bug-by-bug Wi-Fi/BT contention tuning,
    boot-race fixes, host-alive gate redesign, etc.) is preserved on this
    fork if useful for context, just not carried into this PR.
  • Only tested on Waveshare RP2350B-Plus-W. If someone can run the
    pico2_w build on real Pico 2 W (or Pico W) hardware before this merges,
    that'd close the one remaining gap.

@gunCannoli

Copy link
Copy Markdown
Author

UI additions for WOL feature:
image

Adds an isolated wolwifi.cpp/.h module gated behind ENABLE_WOLWIFI, wired
into the existing Bluetooth connect path in bt.cpp with a single call site
at the point a connection becomes Ready. Other boards build unaffected
via no-op stubs.

- Host-alive gate (ObserveHost): an event-driven observation window checks
  whether the target PC already looks awake over USB before firing WOL, so
  a PC that's already on doesn't get a pointless magic packet + lightbar
  pulse. Backed by a new usb_host_active() query in usb.cpp/.h.
- Wi-Fi connect reuses the CYW43 radio already initialized for Bluetooth.
- Magic packet send with resend-until-confirmed: watches for the target to
  come back on the network via ARP and resends a few times if needed, so
  one dropped packet on a slow-associating Wi-Fi network doesn't leave the
  PC asleep.
- Wi-Fi/WOL failure (missing network, bad credentials, unreachable target)
  never blocks or delays Bluetooth pairing, controller input, or audio --
  strictly best-effort.
- USB-suspend controller power-off is suppressed while a WOL send is in
  flight, and a pulsing lightbar indicates the send is in progress.
- New watchdog_telemetry phase (Wolwifi) so a reboot during the WOL path
  is distinguishable from other phases in the existing crash-reason report.

Requires boards/headers/lwipopts.h (lwIP config for the UDP magic packet
send and ARP snoop) and CMakeLists.txt wiring for the Waveshare
RP2350B-Plus-W board's ENABLE_WOLWIFI option.
Wires the firmware WOL module up to the companion protocol and app:

- New COMMAND_ID values (SET_WOL_ENABLED, SET_WOL_WIFI_SSID,
  SET_WOL_WIFI_PASSWORD, SET_WOL_TARGET_MAC) at 0x46-0x49, placed after
  the existing SET_EDGE_PROFILE_SWITCHING_BLOCKED (0x45) so they don't
  collide with any currently-assigned command ID. PROTOCOL_MINOR bumped
  to 23 for the new commands and status flag.
- src/companion.cpp: command handlers for the four new commands, plus a
  wolControl status flag (protocol-minor gated) so the companion app can
  tell whether the connected firmware supports WOL at all.
- Companion app: new Wake-on-LAN section in Bridge Settings with an
  enable toggle, Wi-Fi SSID/password fields, and a target MAC address
  field, wired through preload/IPC/bridge-service the same way existing
  settings are. Hidden entirely on firmware without ENABLE_WOLWIFI
  (i.e. wolControl false).

Both sides were verified against each other end-to-end on real hardware:
controller connects while the target PC is off -> WOL fires, gets
ARP-confirmed, PC wakes, controller stays connected through the boot.
@ivancuric

Copy link
Copy Markdown

How does the WOL impact bluetooth stability since the antenna and resources are shared?

@gunCannoli

Copy link
Copy Markdown
Author

How does the WOL impact bluetooth stability since the antenna and resources are shared?

I guess is zero, WOL activity is short-lived and only exists during the wake-up process.

@ivancuric

Copy link
Copy Markdown

What about hosting a live server for the config? It still has to listen and poll.

@gunCannoli

Copy link
Copy Markdown
Author

What about hosting a live server for the config? It still has to listen and poll.

There's no live server anywhere in this, the Wi-Fi/BT radio contention is a few seconds during target host boot. Once the target host/pc is alive Wi-Fi is off and there is zero ongoing impact.

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.

4 participants