diff --git a/src/Connection.c b/src/Connection.c index b914827..3cfb352 100644 --- a/src/Connection.c +++ b/src/Connection.c @@ -31,6 +31,7 @@ uint16_t AudioPortNumber; uint16_t VideoPortNumber; SS_PING AudioPingPayload; SS_PING VideoPingPayload; +uint32_t ControlConnectData; uint32_t SunshineFeatureFlags; // Connection stages diff --git a/src/ControlStream.c b/src/ControlStream.c index a332798..43ef153 100644 --- a/src/ControlStream.c +++ b/src/ControlStream.c @@ -1625,7 +1625,7 @@ int startControlStream(void) { enet_socket_set_option (client->socket, ENET_SOCKOPT_QOS, 1); // Connect to the host - peer = enet_host_connect(client, &remoteAddress, CTRL_CHANNEL_COUNT, 0); + peer = enet_host_connect(client, &remoteAddress, CTRL_CHANNEL_COUNT, ControlConnectData); if (peer == NULL) { stopping = true; enet_host_destroy(client); diff --git a/src/Limelight-internal.h b/src/Limelight-internal.h index fd04083..e8a9784 100644 --- a/src/Limelight-internal.h +++ b/src/Limelight-internal.h @@ -40,6 +40,7 @@ extern uint16_t VideoPortNumber; extern SS_PING AudioPingPayload; extern SS_PING VideoPingPayload; +extern uint32_t ControlConnectData; extern uint32_t SunshineFeatureFlags; @@ -76,6 +77,7 @@ extern uint32_t SunshineFeatureFlags; // Client feature flags for x-ml-general.featureFlags SDP attribute #define ML_FF_FEC_STATUS 0x01 // Client sends SS_FRAME_FEC_STATUS for frame losses +#define ML_FF_SESSION_ID_V1 0x02 // Client supports X-SS-Ping-Payload and X-SS-Connect-Data #define UDP_RECV_POLL_TIMEOUT_MS 100 diff --git a/src/RtspConnection.c b/src/RtspConnection.c index e94bb52..a37ce23 100644 --- a/src/RtspConnection.c +++ b/src/RtspConnection.c @@ -1067,6 +1067,7 @@ int performRtspHandshake(PSERVER_INFORMATION serverInfo) { if (AppVersionQuad[0] >= 5) { RTSP_MESSAGE response; int error = -1; + char* connectData; if (!setupStream(&response, controlStreamId, @@ -1083,6 +1084,15 @@ int performRtspHandshake(PSERVER_INFORMATION serverInfo) { goto Exit; } + // Parse the Sunshine control connect data extension if present + connectData = getOptionContent(response.options, "X-SS-Connect-Data"); + if (connectData != NULL) { + ControlConnectData = (uint32_t)strtoul(connectData, NULL, 0); + } + else { + ControlConnectData = 0; + } + // Parse the control port out of the RTSP SETUP response LC_ASSERT(ControlPortNumber == 0); if (!parseServerPortFromTransport(&response, &ControlPortNumber)) { diff --git a/src/SdpGenerator.c b/src/SdpGenerator.c index 2942a66..c6d8d36 100644 --- a/src/SdpGenerator.c +++ b/src/SdpGenerator.c @@ -268,7 +268,7 @@ static PSDP_OPTION getAttributesList(char*urlSafeAddr) { // Send client feature flags to Sunshine hosts if (IS_SUNSHINE()) { - uint32_t moonlightFeatureFlags = ML_FF_FEC_STATUS; + uint32_t moonlightFeatureFlags = ML_FF_FEC_STATUS | ML_FF_SESSION_ID_V1; snprintf(payloadStr, sizeof(payloadStr), "%u", moonlightFeatureFlags); err |= addAttributeString(&optionHead, "x-ml-general.featureFlags", payloadStr); }