From a2075438435daf06b1192f2b8bba2f2cc71bc190 Mon Sep 17 00:00:00 2001 From: Yalu Zhang <yalu.zhang@iopsys.eu> Date: Wed, 10 Jul 2024 17:02:19 +0200 Subject: [PATCH] Pass DTMF to Voicemail applications correctly --- src/channels/chan_voicemngr.c | 57 +++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/src/channels/chan_voicemngr.c b/src/channels/chan_voicemngr.c index 9f20edd..9f96818 100644 --- a/src/channels/chan_voicemngr.c +++ b/src/channels/chan_voicemngr.c @@ -3138,17 +3138,33 @@ static void handle_dtmf(enum LINE_EVENT event, gettimeofday(&tim, NULL); p = sub->parent; - if (p->dtmf_first < 0) { + if (p->dtmf_first < 0) { // DTMF pressed p->dtmf_first = dtmf_button; ast_debug(9,"Pressed DTMF %s\n", dtmfMap->name); + if (owner) { + struct ast_channel *bridged_chan = ast_channel_bridge_peer(owner); + if (bridged_chan) { + const struct ast_channel_tech *chan_tech = ast_channel_tech(bridged_chan); + if (chan_tech && chan_tech->type && *chan_tech->type) { + ast_debug(1, "debug_tmp: the type of the bridged channel is %s, sub->direct_extension = %d\n", + chan_tech->type, sub->direct_extension); + } else { + ast_debug(1, "debug_tmp: the type of the bridged channel is unknown, sub->direct_extension = %d\n", + sub->direct_extension); + } + ast_channel_unref(bridged_chan); + } else { + ast_debug(1, "debug_tmp: there is no bridged channel, sub->direct_extension = %d. is there a bridge? %s\n", + sub->direct_extension, ast_channel_internal_bridge(owner) ? "yes" : "no"); + } + } if (owner && chan_voicemngr_should_relay_dtmf(sub) && (sub->dtmf_mode == AST_SIP_DTMF_INFO || sub->conference_initiator == 1 || sub->direct_extension == 1)) { // INCALL send_outgoing_dtmf(owner, dtmf_button, AST_FRAME_DTMF_BEGIN); } /* Do not send AST_FRAME_DTMF_BEGIN to allow DSP-generated tone to pass through */ - } - else if (p->dtmf_first == dtmf_button) { + } else if (p->dtmf_first == dtmf_button) { // DTMF released ast_log(LOG_NOTICE,"Released DTMF %s\n", dtmfMap->name); //ast_log(LOG_DTMF, "Detected DTMF %c, line %d\n", dtmfMap->c, sub->parent->line_id); @@ -3179,8 +3195,29 @@ static void handle_dtmf(enum LINE_EVENT event, if (sub->channel_state == OFFHOOK) { sub->channel_state = DIALING; //ast_debug(5,"Set to state %s.\n", state2str(sub->channel_state)); - } - else if (sub->channel_state != INCALL) { + } else if (sub->channel_state == INCALL) { + if (owner) { + struct ast_channel *bridged_chan = ast_channel_bridge_peer(owner); + if (bridged_chan) { + const struct ast_channel_tech *chan_tech = ast_channel_tech(bridged_chan); + if (chan_tech && chan_tech->type && *chan_tech->type) { + ast_debug(1, "debug_tmp: the type of the bridged channel is %s, sub->direct_extension = %d\n", + chan_tech->type, sub->direct_extension); + } else { + ast_debug(1, "debug_tmp: the type of the bridged channel is unknown, sub->direct_extension = %d\n", + sub->direct_extension); + } + ast_channel_unref(bridged_chan); + } else { + ast_debug(1, "debug_tmp: there is no bridged channel, sub->direct_extension = %d. is there a bridge? %s\n", + sub->direct_extension, ast_channel_internal_bridge(owner) ? "yes" : "no"); + } + } + if (owner && (sub->dtmf_mode == AST_SIP_DTMF_INFO || sub->conference_initiator == 1 || sub->direct_extension)) { + // INCALL + send_outgoing_dtmf(owner, dtmf_button, AST_FRAME_DTMF_END); + } + } else { struct ast_frame f = { 0, }; f.subclass.integer = dtmf_button; f.src = "TELCHAN"; @@ -3192,15 +3229,9 @@ static void handle_dtmf(enum LINE_EVENT event, //ast_debug(5,"DTMF %s queuing frame.\n", dtmfMap->name); ast_queue_frame(owner, &f); } - } else { - if (owner && (sub->dtmf_mode == AST_SIP_DTMF_INFO || sub->conference_initiator == 1 || sub->direct_extension)) { - // INCALL - send_outgoing_dtmf(owner, dtmf_button, AST_FRAME_DTMF_END); - } } - } - } - else { + } // end of if (p->hf_detected) + } else { p->dtmf_first = -1; } } -- GitLab