SDL: Make sure pairing remains enabled for the entire time dongle pairing is active

From af6ce629c49adda5a057f833323fb2517a2da469 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sat, 16 Nov 2024 13:42:12 -0800
Subject: [PATCH] Make sure pairing remains enabled for the entire time dongle
 pairing is active

---
 src/joystick/hidapi/SDL_hidapi_steam.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/src/joystick/hidapi/SDL_hidapi_steam.c b/src/joystick/hidapi/SDL_hidapi_steam.c
index ad41b9300323a..55a1b344cfc21 100644
--- a/src/joystick/hidapi/SDL_hidapi_steam.c
+++ b/src/joystick/hidapi/SDL_hidapi_steam.c
@@ -40,6 +40,9 @@
 #define SDL_HINT_JOYSTICK_HIDAPI_STEAM_DEFAULT  SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI, SDL_HIDAPI_DEFAULT)
 #endif
 
+#define PAIRING_STATE_DURATION_SECONDS  60
+
+
 /*****************************************************************************************************/
 
 #include "steam/controller_constants.h"
@@ -635,7 +638,7 @@ static void SetPairingState(SDL_HIDAPI_Device *dev, bool bEnablePairing)
     buf[1] = ID_ENABLE_PAIRING;
     buf[2] = 2; // 2 payload bytes: bool + timeout
     buf[3] = bEnablePairing ? 1 : 0;
-    buf[4] = bEnablePairing ? 60 : 0;
+    buf[4] = bEnablePairing ? PAIRING_STATE_DURATION_SECONDS : 0;
     SetFeatureReport(dev, buf, 5);
 }
 
@@ -1002,6 +1005,7 @@ typedef struct
     bool report_sensors;
     uint32_t update_rate_in_us;
     Uint64 sensor_timestamp;
+    Uint64 pairing_time;
 
     SteamControllerPacketAssembler m_assembler;
     SteamControllerStateInternal_t m_state;
@@ -1053,12 +1057,24 @@ static void HIDAPI_DriverSteam_SetPairingState(SDL_DriverSteam_Context *ctx, boo
     SetPairingState(ctx->device, enabled);
 
     if (enabled) {
+        ctx->pairing_time = SDL_GetTicks();
         s_PairingContext = ctx;
     } else {
+        ctx->pairing_time = 0;
         s_PairingContext = NULL;
     }
 }
 
+static void HIDAPI_DriverSteam_RenewPairingState(SDL_DriverSteam_Context *ctx)
+{
+    Uint64 now = SDL_GetTicks();
+
+    if (now >= ctx->pairing_time + PAIRING_STATE_DURATION_SECONDS * 1000) {
+        SetPairingState(ctx->device, true);
+        ctx->pairing_time = now;
+    }
+}
+
 static void HIDAPI_DriverSteam_CommitPairing(SDL_DriverSteam_Context *ctx)
 {
     CommitPairing(ctx->device);
@@ -1248,6 +1264,10 @@ static bool HIDAPI_DriverSteam_UpdateDevice(SDL_HIDAPI_Device *device)
         joystick = SDL_GetJoystickFromID(device->joysticks[0]);
     }
 
+    if (ctx->pairing_time) {
+        HIDAPI_DriverSteam_RenewPairingState(ctx);
+    }
+
     for (;;) {
         uint8_t data[128];
         int r, nPacketLength;