chan_dahdi: Fix erroneously persistent dialmode.

It is possible to modify the dialmode setting in the chan_dahdi/sig_analog
private using the CHANNEL function, to modify it during calls. However,
it was not being reset between calls, meaning that if, for example, tone
dialing was disabled, it would never work again unless explicitly enabled.

This fixes the setting by pairing it with a "perm" version of the setting,
as a few other features have, so that it can be reset to the permanent
setting between calls. The documentation is also clarified to explain
the interaction of this setting and the digitdetect setting more clearly.

Resolves: #1378
This commit is contained in:
Naveen Albert
2025-08-18 08:56:23 -04:00
parent e3877360f6
commit 7e68659616
4 changed files with 64 additions and 14 deletions

View File

@@ -862,6 +862,16 @@ int analog_available(struct analog_pvt *p)
static int analog_stop_callwait(struct analog_pvt *p)
{
p->callwaitcas = 0;
/* There are 3 scenarios in which we need to reset the dialmode to permdialmode.
* 1) When placing a new outgoing call (either the first or a three-way)
* 2) When receiving a new incoming call
* 2A) If it's the first incoming call (not a call waiting), we reset
* in dahdi_hangup.
* 2B ) If it's a call waiting we've answered, either by swapping calls
* or having it ring through, we call analog_stop_callwait. That's this! */
p->dialmode = p->permdialmode;
if (analog_callbacks.stop_callwait) {
return analog_callbacks.stop_callwait(p->chan_pvt);
}
@@ -2372,6 +2382,29 @@ static void *__analog_ss_thread(void *data)
*/
p->hidecallerid = p->permhidecallerid;
/* Set the default dial mode.
* As with Caller ID, this is independent for each call,
* and changes made using the CHANNEL function are only temporary.
* This reset ensures temporary changes are discarded when a new call is originated.
*
* XXX There is a slight edge case in that because the dialmode is reset to permdialmode,
* assuming permdialmode=both, if a user disables dtmf during call 1, then flashes and
* starts call 2, this will set dialmode back to permcallmode on the private,
* allowing tone dialing to (correctly) work on call 2.
* If the user flashes back to call 1, however, tone dialing will again work on call 1.
*
* This problem does not exist with the other settings that involve a "permanent"
* and "transient" settings (e.g. hidecallerid, callwaiting), because hidecallerid
* only matters when originating a call, so as soon as it's been placed, it doesn't
* matter if it gets reset. For callwaiting, the setting is supposed to be common
* to the entire channel private (all subchannels), which is NOT the case with this setting.
*
* The correct and probably only fix for this edge case is to move dialmode out of the channel private
* (which is shared by all subchannels), and into the Asterisk channel structure. Just using an array for
* each chan_dahdi subchannel won't work because the indices change as calls flip around.
*/
p->dialmode = p->permdialmode;
/* Read the first digit */
timeout = analog_get_firstdigit_timeout(p);
/* If starting a threeway call, never timeout on the first digit so someone