Nelson Sotonsoto.dev

</ CASE STUDY >

When the display wakes but the TV does not

A real WoL bug, a capture that changed the question, and a purpose-built sync tool

Updated

Implemented

Packaged interim utility — service + tray, validated under VPN

Display sleep/wake drives TV standby → WoL → screen on. v0.1.0 ships a self-contained Windows x64 zip (service, console, optional tray). ColorControl PR #597 is a related upstream WoL fix — not claimed to fix the daily webOS control-channel failure.

</ CONTEXT >

Dedicated Ethernet, then VPN

An LG webOS OLED is the machine’s only display, driven over a dedicated Ethernet segment — its own isolated subnet, no internet on that link. PC↔TV control stays on that cable; the PC reaches the internet on a separate interface. ColorControl already handled “display sleeps → TV off, wake → TV on” and worked.

After a WireGuard VPN came up, wake stopped working: lock the PC, the display sleeps, move the mouse — and the TV never comes back. With the VPN off it always worked. Reachability still looked fine — ping and a TCP open to the TV succeeded — but the control session never finished, so no “screen on” was sent.

</ CHAPTER 1 >

A real Wake-on-LAN bug

The first investigation assumed the daily failure was WoL under VPN. Wireshark captures on the TV segment showed ColorControl spraying magic packets across all NICs and targeting a host-style “broadcast” of x.x.x.0 instead of the subnet’s directed broadcast.

The fix: send directed broadcast from the matching NIC on the TV subnet. A harness then woke the TV from full standby with the VPN connected. That landed upstream as ColorControl PR #597.

Honest claim: that PR (and the local patch) fixed full-standby WoL-over-VPN in the harness. It did not, by itself, explain or fix the everyday lock → mouse-wake path.

</ PIVOT >

The capture that changed the question

A lock → wake Wireshark capture with the daily failure reproduced showed no WoL at all. On this path the TV was already in a Quick Start+ / control-channel regime: Windows expected “screen on” over the secure WebSocket, not a cold magic packet.

The same captures localized the intermittent failure to TLS on wss://<tv>:3001: TCP connects, the client sends ClientHello, the TV ACKs it and never returns `ServerHello` for the whole timeout, then RSTs roughly fifteen seconds later. Stalls cluster in waves — long stretches succeed in ~130 ms, then a bad period produces a run of hangs. Connection churn makes it worse: each stalled socket lingers on the TV, and webOS has a small connection budget.

Patched WoL alone ≠ daily mouse-wake fix. Two bugs had been sharing one symptom.

</ DEAD ENDS >

What looked true and wasn’t

  • Assumed WoL path — daily wake never sent a magic packet; the control channel did.
  • Split-tunnel / bad route — control traffic stayed on the TV Ethernet with the expected source; still stalled.
  • Allow LAN / VPN exclusions — already excluded; failure remained with VPN on.
  • IP scheme — not explanatory under the conditions tested.
  • SSDP noise — distraction, not the TLS stall.
  • Screensaver-only path — different from console display sleep; wrong instrument for the bug.
  • Burst retries into a bad wave — short connect timeout with rapid reconnects storm the TV while sockets linger.

</ CHAPTER 2 >

Probe the handshake, then change the retry shape

Wireshark framed the problem; a purpose-built, instrumented SSAP probe timed each connect phase separately. Together they made the TLS stall measurable instead of “sometimes the TV doesn’t wake.”

ColorControl’s connect strategy (as observed) uses a ~5 s timeout with a burst of retries at the wake moment — easy to stall and storm through a bad period. The tool that followed uses a fresh connect with a short (~2.5 s) timeout and gentle, spaced retries, keeping at most one warm connection so a wave can pass without filling the TV’s budget.

</ CONSTRAINTS >

What the fix had to honor

Architecture constraints
ConstraintImplication
VPN on during the failureAny fix must work with the tunnel up; “disable VPN” is not a solution
Isolated Ethernet TV segmentControl stays on a dedicated subnet; internet and TV paths are separate
Shippable interim without forking ColorControlOwn SSAP transport + retry policy; optional key migrate; package as service/console/tray when ready
Don’t overclaim ColorControlPR #597 is a related WoL fix — not the daily control-channel fix
Upstream PR etiquetteContribute the proven WoL fix; don’t dump a private rewrite as their roadmap

</ OPTIONS >

Three paths after the pivot

Once the capture showed the daily path wasn’t WoL, the remaining choices were operational, not theoretical.

Consumption options matrix
OptionProsConsVerdict
VPN settings onlyNo codeTopology already broke naive IP exclude; exclusion alone still failedInsufficient alone
Patch ColorControl onlyHelps all ColorControl users on the WoL pathDaily path wasn’t WoL; TLS stall still flaky under burst retriesPartial — ship WoL PR
Purpose-built tool + probeOwn retry policy; instrumentable; DPMS-driven; later packaged (service + tray)Niche; interim until a broader client catches upChosen

</ DIRECTION >

Ship a small sync utility; leave the WoL PR upstream

Chosen: `lgtv-display-sync` — a small Windows/.NET rewrite on standard webOS SSAP with an original short-timeout / spaced-retry transport. It watches console display state, drives standby / screen off, WoL + screen on, and keeps at most one warm control connection.

Also keep: ColorControl PR #597 as an upstream contribution for the real WoL-over-VPN bug other setups still hit. Soft language on ColorControl: it worked until this topology + VPN; the daily failure was a different layer.

Not a ColorControl fork. Pairing keys can migrate from ColorControl for convenience.

</ OUTCOME >

Validated under VPN — then packaged as v0.1.0

End-to-end: real display sleep → TV standby; wake → WoL → screen on, VPN connected, ColorControl not in the loop.

In the meantime the tool moved from a console prototype to a first packaged interim release`v0.1.0`: self-contained Windows x64 zip (no separate .NET install), Windows service (session 0 / LocalSystem, auto-start), console watcher when launched directly, and an optional `--tray` companion for SCM status / start / stop. ProgramData holds keys and logs. Still positioned as an interim daily driver until a broader client handles this VPN + TLS-stall case again.

Unknown (stated as such): why the TV withholds ServerHello in clustered waves. The portfolio claim stops at measurement + a retry shape that rides the waves — not a root-cause story about webOS internals.

</ REPOS >

Where to look

</ TAKEAWAYS >

Two bugs, one symptom

  • Verify the path you think you are on. A Wireshark capture with no WoL reframed the whole investigation.
  • One symptom can hide two defects. Shipping the WoL PR was still right — just not the daily mouse-wake fix.
  • Instrument before you rewrite. Packet capture plus phased connect timings beat guessing at VPN routing.
  • Retry shape is product behavior. Bursting into a bad TLS wave is different from spaced, short-timeout attempts.
  • Say what you proved. Directed broadcast under VPN is proven; why ServerHello is withheld is not.