Skip to content

feat(protocol): TLV metadata on controller arrival, player LED and mic LED extensions#137

Open
hkirste wants to merge 2 commits intomoonlight-stream:masterfrom
hkirste:feat/controller-metadata-tlv
Open

feat(protocol): TLV metadata on controller arrival, player LED and mic LED extensions#137
hkirste wants to merge 2 commits intomoonlight-stream:masterfrom
hkirste:feat/controller-metadata-tlv

Conversation

@hkirste
Copy link
Copy Markdown

@hkirste hkirste commented Apr 5, 2026

Summary

Adds three Sunshine protocol extensions for DualSense controller support:

TLV metadata on controller arrival:

  • LiSendControllerArrivalEventWithMetadata() appends optional TLV (Type-Length-Value) entries after the fixed arrival packet fields
  • Defined tag LI_CTRL_META_TAG_FIRMWARE_INFO (0x01): carries the raw 64-byte HID feature report 0x20 from the client's physical controller
  • Existing LiSendControllerArrivalEvent() preserved as a thin wrapper (backwards compatible)
  • Old hosts ignore trailing bytes; old clients don't send them

Player LED (0x5504):

  • Forwards the 5-bit player indicator LED bitmask from host to client
  • Standard values: P1=0x04, P2=0x0A, P3=0x15, P4=0x1B, all=0x1F

Mic LED (0x5505):

  • Forwards the mic mute LED state from host to client
  • Values: 0=off, 1=on (solid), 2=pulse (blink)

Adds ConnListenerSetPlayerLed and ConnListenerSetMicLed to CONNECTION_LISTENER_CALLBACKS.

Context

These extensions support Sunshine's WinUHid-based virtual DualSense emulation on Windows (LizardByte/Sunshine#4948). The firmware passthrough prevents spurious "firmware update required" prompts, and the LED extensions enable full DualSense indicator fidelity during streaming.

Test plan

  • Firmware TLV parsed correctly by Sunshine, real firmware version appears on virtual DualSense
  • Player LED and mic LED states forwarded end-to-end from host game to physical controller on client
  • Backwards compatible: old clients without metadata work unchanged, old hosts ignore trailing bytes

hkirste added 2 commits April 4, 2026 20:45
Add LiSendControllerArrivalEventWithMetadata() which appends optional
TLV (Type-Length-Value) entries after the fixed controller arrival fields.

This enables clients to pass through controller-specific metadata such as
firmware version info to the host. The host can use this to configure the
virtual controller more accurately (e.g., matching the real DualSense
firmware version on the virtual device).

The existing LiSendControllerArrivalEvent() is preserved as a thin wrapper
for backwards compatibility. Old hosts that don't know about TLV extensions
will simply ignore the extra trailing bytes since they only read the fixed
fields they know about.

Defined tags:
  - LI_CTRL_META_TAG_FIRMWARE_INFO (0x01): 64-byte raw HID feature report 0x20
Add Sunshine protocol extensions 0x5504 (player LED) and 0x5505 (mic LED)
for forwarding DualSense indicator states from host to client.

Player LED carries a 5-bit bitmask for the indicator LEDs.
Mic LED carries a state byte: 0=off, 1=on, 2=pulse.

Adds ConnListenerSetPlayerLed and ConnListenerSetMicLed callbacks to
CONNECTION_LISTENER_CALLBACKS.
moyogii added a commit to moyogii/moonlight-common-c that referenced this pull request Apr 5, 2026
Implements three Sunshine protocol extensions for DualSense controller
support (based on moonlight-stream#137 by Heinz Kirste):

- TLV metadata on controller arrival:
  LiSendControllerArrivalEventWithMetadata() appends optional TLV entries
  after the fixed arrival packet fields. LI_CTRL_META_TAG_FIRMWARE_INFO
  carries the raw 64-byte HID feature report 0x20 for firmware passthrough.
  Existing LiSendControllerArrivalEvent() preserved as a backwards-compatible
  wrapper.

- Player LED (0x5504): forwards 5-bit player indicator LED bitmask from
  host to client via ConnListenerSetPlayerLed callback.

- Mic LED (0x5505): forwards mic mute LED state from host to client
  (off/on/pulse) via ConnListenerSetMicLed callback.

Original implementation by Heinz Kirste (hkirste@outlook.com).
 moonlight-stream#137

Co-Authored-By: Heinz Kirste <hkirste@outlook.com>
moyogii added a commit to moyogii/moonlight-common-c that referenced this pull request Apr 5, 2026
Implements three Sunshine protocol extensions for DualSense controller
support (based on moonlight-stream#137 by Heinz Kirste):

- TLV metadata on controller arrival:
  LiSendControllerArrivalEventWithMetadata() appends optional TLV entries
  after the fixed arrival packet fields. LI_CTRL_META_TAG_FIRMWARE_INFO
  carries the raw 64-byte HID feature report 0x20 for firmware passthrough.
  Existing LiSendControllerArrivalEvent() preserved as a backwards-compatible
  wrapper.

- Player LED (0x5504): forwards 5-bit player indicator LED bitmask from
  host to client via ConnListenerSetPlayerLed callback.

- Mic LED (0x5505): forwards mic mute LED state from host to client
  (off/on/pulse) via ConnListenerSetMicLed callback.

Original implementation by Heinz Kirste (hkirste@outlook.com).
 moonlight-stream#137

Co-Authored-By: Heinz Kirste <hkirste@outlook.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