From a24979a2d763712f037bbe5bb2bc9c5ab3e35eb9 Mon Sep 17 00:00:00 2001 From: Naveen Albert Date: Tue, 26 Apr 2022 19:00:14 +0000 Subject: [PATCH] chan_dahdi: Fix broken operator mode clearing. Currently, the operator services mode in DAHDI is broken and unusable. The actual operator recall functionality works properly; however, when the operator hangs up (which is the only way that such a call is allowed to end), both lines are permanently taken out of service until "dahdi restart" is run. This prevents this feature from being used. Operator mode is one of the few factors that can cause the general analog event handling in sig_analog not to be used. Several years back, much of the analog handling was moved from chan_dahdi to sig_analog. However, this was not done fully or consistently at the time, and when operator mode is active, sig_analog does not get used. Generally this is correct, but in the case of hangup it should be using sig_analog regardless of the operator mode; otherwise, the lines do not properly clear and they become unusable. This bug is fixed so the operator can now hang up and properly release the call. It is treated just like any other hangup. The operator mode functionality continues to work as it did before. ASTERISK-29993 #close Change-Id: Ib2e3ddb40d9c71e8801e0b4bb0a12e2b52f51d24 --- channels/chan_dahdi.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c index 616e317176..9135937a41 100644 --- a/channels/chan_dahdi.c +++ b/channels/chan_dahdi.c @@ -6027,7 +6027,9 @@ static int dahdi_hangup(struct ast_channel *ast) ast_mutex_lock(&p->lock); p->exten[0] = '\0'; - if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) { + /* Always use sig_analog hangup handling for operator mode */ + if (dahdi_analog_lib_handles(p->sig, p->radio, 0)) { + p->oprmode = 0; dahdi_confmute(p, 0); restore_gains(p); p->ignoredtmf = 0; @@ -7643,7 +7645,11 @@ static struct ast_frame *dahdi_handle_event(struct ast_channel *ast) } if (p->oprmode < 0) { - if (p->oprmode != -1) break; + if (p->oprmode != -1) { /* Operator flash recall */ + ast_verb(4, "Operator mode enabled on channel %d, holding line for channel %d\n", p->channel, p->oprpeer->channel); + break; + } + /* Otherwise, immediate recall */ if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS)) { /* Make sure it starts ringing */ @@ -7651,6 +7657,7 @@ static struct ast_frame *dahdi_handle_event(struct ast_channel *ast) dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RING); save_conference(p->oprpeer); tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE); + ast_verb(4, "Operator recall, channel %d ringing back channel %d\n", p->oprpeer->channel, p->channel); } break; } @@ -7763,6 +7770,7 @@ static struct ast_frame *dahdi_handle_event(struct ast_channel *ast) dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RINGOFF); tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].dfd, -1); restore_conference(p->oprpeer); + ast_debug(1, "Operator recall by channel %d for channel %d complete\n", p->oprpeer->channel, p->channel); } break; } @@ -7976,6 +7984,7 @@ static struct ast_frame *dahdi_handle_event(struct ast_channel *ast) dahdi_set_hook(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_RING); save_conference(p); tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE); + ast_verb(4, "Operator flash recall, channel %d ringing back channel %d\n", p->oprpeer->channel, p->channel); } } break;