diff --git a/public/api.php b/public/api.php index 763414b..b8a4a5b 100644 --- a/public/api.php +++ b/public/api.php @@ -2017,6 +2017,7 @@ try { $rtpChecksums = !empty($payload['rtp_checksums']) ? 1 : 0; $rtpStrict = !empty($payload['rtp_strict']) ? 1 : 0; $rtpTimeout = max(5, (int)($payload['rtp_timeout'] ?? 30)); + $rtpHoldTimeout = max(0, (int)($payload['rtp_timeout_hold'] ?? 0)); $rtpKeepalive = max(0, (int)($payload['rtp_keepalive'] ?? 15)); $allowAnonymousSip = !empty($payload['allow_anonymous_sip']) ? 1 : 0; @@ -2051,6 +2052,7 @@ try { rtp_checksums = :rtp_checksums, rtp_strict = :rtp_strict, rtp_timeout = :rtp_timeout, + rtp_timeout_hold = :rtp_timeout_hold, rtp_keepalive = :rtp_keepalive, allow_anonymous_sip = :anon, updated_at = CURRENT_TIMESTAMP @@ -2068,9 +2070,10 @@ try { ':rtp_start' => $rtpStart, ':rtp_end' => $rtpEnd, ':rtp_checksums' => $rtpChecksums, - ':rtp_strict' => $rtpStrict, - ':rtp_timeout' => $rtpTimeout, - ':rtp_keepalive' => $rtpKeepalive, + ':rtp_strict' => $rtpStrict, + ':rtp_timeout' => $rtpTimeout, + ':rtp_timeout_hold' => $rtpHoldTimeout, + ':rtp_keepalive' => $rtpKeepalive, ':anon' => $allowAnonymousSip, ]); diff --git a/public/assets/app.js b/public/assets/app.js index a1cd727..47e64fc 100644 --- a/public/assets/app.js +++ b/public/assets/app.js @@ -4152,6 +4152,7 @@ document.addEventListener('DOMContentLoaded', () => { rtp_checksums: Number(document.getElementById('sip-rtp-checksums')?.value || 1), rtp_keepalive: Number(document.getElementById('sip-rtp-keepalive')?.value || 15), rtp_timeout: Number(document.getElementById('sip-rtp-timeout')?.value || 30), + rtp_timeout_hold: Number(document.getElementById('sip-rtp-timeout-hold')?.value || 0), allow_anonymous_sip: Number(document.getElementById('sip-allow-anonymous')?.value || 0), local_networks: localNets }; @@ -4613,6 +4614,11 @@ function renderSipSettings() { rtpTimeoutEl.value = (s.rtp_timeout !== undefined && s.rtp_timeout !== null) ? s.rtp_timeout : 30; } + const rtpHoldTimeoutEl = document.getElementById('sip-rtp-timeout-hold'); + if (rtpHoldTimeoutEl && document.activeElement !== rtpHoldTimeoutEl) { + rtpHoldTimeoutEl.value = (s.rtp_timeout_hold !== undefined && s.rtp_timeout_hold !== null) ? s.rtp_timeout_hold : 0; + } + const allowAnonEl = document.getElementById('sip-allow-anonymous'); if (allowAnonEl) { allowAnonEl.value = (s.allow_anonymous_sip !== undefined && s.allow_anonymous_sip !== null) ? String(s.allow_anonymous_sip) : '0'; diff --git a/public/index.php b/public/index.php index 7abd29f..2f22ce4 100644 --- a/public/index.php +++ b/public/index.php @@ -2554,7 +2554,7 @@ $isDevEnv = file_exists(__DIR__ . '/../.dev') -
+

Durée avant coupure si aucun flux voix n'est reçu (raccroché distant brutal).

+
+ + +

Délai max d'un appel en attente sans flux RTP (0 = illimité / désactivé).

+
diff --git a/src/ConfigGenerator.php b/src/ConfigGenerator.php index f923434..479a919 100644 --- a/src/ConfigGenerator.php +++ b/src/ConfigGenerator.php @@ -237,7 +237,7 @@ class ConfigGenerator // Détection automatique et purge des flux RTP fantômes / morts (ex: basculement HA, coupure réseau) $rtpTimeout = max(5, (int)($settings['rtp_timeout'] ?? 30)); - $rtpHoldTimeout = max(60, (int)($settings['rtp_timeout_hold'] ?? 600)); // Par défaut 600s = 10 minutes d'attente max + $rtpHoldTimeout = max(0, (int)($settings['rtp_timeout_hold'] ?? 0)); $rtpKeepalive = max(0, (int)($settings['rtp_keepalive'] ?? 15)); $lines[] = "rtp_timeout = {$rtpTimeout}"; $lines[] = "rtp_timeout_hold = {$rtpHoldTimeout}"; @@ -401,7 +401,7 @@ class ConfigGenerator $lines[] = "trust_id_outbound = {$trustOutbound}"; $lines[] = "timers = {$timers}"; $rtpTimeout = max(5, (int)($settings['rtp_timeout'] ?? 30)); - $rtpHoldTimeout = max(60, (int)($settings['rtp_timeout_hold'] ?? 600)); // Par défaut 600s = 10 minutes d'attente max + $rtpHoldTimeout = max(0, (int)($settings['rtp_timeout_hold'] ?? 0)); $lines[] = "rtp_timeout = {$rtpTimeout}"; $lines[] = "rtp_timeout_hold = {$rtpHoldTimeout}"; if ($rtpKeepalive > 0) { @@ -1779,9 +1779,10 @@ class ConfigGenerator $rtpEnd = max($rtpStart + 4, min(65535, (int)($settings['rtp_end'] ?? 20000))); $checksums = !empty($settings['rtp_checksums']) ? 'yes' : 'no'; $strict = !empty($settings['rtp_strict']) ? 'yes' : 'no'; - $timeout = max(5, (int)($settings['rtp_timeout'] ?? 30)); - $keepalive = max(0, (int)($settings['rtp_keepalive'] ?? 15)); - $date = date('Y-m-d H:i:s'); + $timeout = max(5, (int)($settings['rtp_timeout'] ?? 30)); + $holdTimeout = max(0, (int)($settings['rtp_timeout_hold'] ?? 0)); + $keepalive = max(0, (int)($settings['rtp_keepalive'] ?? 15)); + $date = date('Y-m-d H:i:s'); $lines = []; $lines[] = "; ==========================================================================="; @@ -1794,7 +1795,7 @@ class ConfigGenerator $lines[] = "rtpchecksums = {$checksums}"; $lines[] = "strictrtp = {$strict}"; $lines[] = "rtptimeout = {$timeout}"; - $lines[] = "rtpholdtimeout = 300"; + $lines[] = "rtpholdtimeout = {$holdTimeout}"; if ($keepalive > 0) { $lines[] = "rtpkeepalive = {$keepalive}"; } diff --git a/src/Database.php b/src/Database.php index 37d1f40..0d8f0b7 100644 --- a/src/Database.php +++ b/src/Database.php @@ -46,9 +46,9 @@ class Database @chmod(self::DB_PATH, 0660); } else { // Si la base existe déjà, éviter d'exécuter l'intégralité du DDL à chaque requête HTTP - // ce qui sature SQLite de verrous exclusifs inutiles. On teste juste l'existence de la table principale. + // ce qui sature SQLite de verrous exclusifs inutiles. On s'assure des colonnes requises. try { - self::$instance->query("SELECT 1 FROM settings LIMIT 1"); + self::$instance->query("SELECT rtp_timeout_hold FROM settings LIMIT 1"); } catch (\Throwable $e) { self::initializeSchema(); } @@ -89,7 +89,7 @@ class Database rtp_checksums INTEGER NOT NULL DEFAULT 1, rtp_strict INTEGER NOT NULL DEFAULT 1, rtp_timeout INTEGER NOT NULL DEFAULT 30, - rtp_timeout_hold INTEGER NOT NULL DEFAULT 600, + rtp_timeout_hold INTEGER NOT NULL DEFAULT 0, rtp_keepalive INTEGER NOT NULL DEFAULT 15, allow_anonymous_sip INTEGER NOT NULL DEFAULT 0, last_applied_at DATETIME DEFAULT NULL, @@ -393,7 +393,7 @@ class Database 'rtp_checksums' => "INTEGER NOT NULL DEFAULT 1", 'rtp_strict' => "INTEGER NOT NULL DEFAULT 1", 'rtp_timeout' => "INTEGER NOT NULL DEFAULT 30", - 'rtp_timeout_hold' => "INTEGER NOT NULL DEFAULT 600", + 'rtp_timeout_hold' => "INTEGER NOT NULL DEFAULT 0", 'rtp_keepalive' => "INTEGER NOT NULL DEFAULT 15", 'allow_anonymous_sip' => "INTEGER NOT NULL DEFAULT 0", 'system_language' => "VARCHAR(16) NOT NULL DEFAULT 'fr'",