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')
-
+
+
+
+
+
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'",