Control specifications

Overview

The control stream runs over UDP via a custom fork of ENET that supports IPV4 and IPV6.

All the exchanged messages are encrypted using AES GCM 128 bit.
In order to decrypt you’ll have to use the keys that are exchanged during the HTTP launch phase.

Encrypted packet format

AES GCM not only provides confidentiality by encrypting the message but, by using the GCM TAG, it also guarantees that no one has tampered the original payload.

The format of encrypted packets (bytes)
Figure 1. The format of encrypted packets (bytes)
Element Size in bytes C++ type Description

Type

2

unsigned short int

The type of message, fixed at 0x0001 for this type of packet

Len

2

unsigned short int

The size of the rest of the message in bytes (Seq + TAG + Payload)

Seq

4

unsigned int

Monotonically increasing sequence number (used as IV for AES-GCM)

GCM TAG

16

char *

The AES GCM TAG

Payload

until Len

char *

The AES encrypted payload

All data is little-endian encoded

Decrypted payload

The first two bytes of the decrypted payload represent the type of the message; the following types are encoded:

  • START_A (0x0305)

  • START_B (0x0307)

  • INVALIDATE_REF_FRAMES (0x0301)

  • LOSS_STATS (0x0201)

  • FRAME_STATS (0x0204)

  • INPUT_DATA (0x0206)

  • TERMINATION (0x0100)

  • PERIODIC_PING (0x0200)

  • IDR_FRAME (0x0302)

  • HDR_MODE (0x010e)

  • RUMBLE_DATA (0x010b)

  • RUMBLE_TRIGGERS (0x5500)

  • MOTION_EVENT (0x5501)

  • RGB_LED (0x5502)

The next two bytes indicate the size of the decrypted payload. The format of the remaining data depends on the message type.

Server events

The following events are originating from the server and will be sent to Moonlight clients.

Rumble data

A simple schema for a controller number and low/high frequencies

The payload for a Rumble packet (bytes)
Figure 2. The payload for a Rumble packet (bytes)

Rumble Triggers

new in Moonlight 5.0.0

A simple schema for a controller number and left/right values

The payload for a Trigger packet (bytes)
Figure 3. The payload for a Trigger packet (bytes)

Motion Event

new in Moonlight 5.0.0

This is used to signal to Moonlight clients to start sending motion events (Gyro or Acceleration) to the server.
By default Moonlight disables these events in order to save bandwith.

The payload for a Motion packet (bytes)
Figure 4. The payload for a Motion packet (bytes)

Type could be:

  • ACCELERATION (0x01)

  • GYROSCOPE (0x02)

RGB LED

new in Moonlight 5.0.0

This is used to control the color of the LED of supported controllers.
An example of this is when setting the LED color in Steam, the server has to send this event all the way to the Moonlight client.

The payload for a LED packet (bytes)
Figure 5. The payload for a LED packet (bytes)