From d55a68a53184eda8b679bb6220e31fd616ee49db Mon Sep 17 00:00:00 2001 From: Jonathan Rose Date: Fri, 9 May 2014 16:10:14 +0000 Subject: [PATCH] app_chanspy: Fix a bug where Barge mode could fail If the barge audiohook was attached prior to the spyee and its peer actually being bridged, the audiohook would not be applied and the connected peer would not be able to hear audio from the spy when the spy is in barge mode. (closes issue ASTERISK-23381) Reported by: Robert Moss Review: https://reviewboard.asterisk.org/r/3505/ git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/11@413551 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- apps/app_chanspy.c | 63 +++++++++++++++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 17 deletions(-) diff --git a/apps/app_chanspy.c b/apps/app_chanspy.c index d8a82e3488..657848aa97 100644 --- a/apps/app_chanspy.c +++ b/apps/app_chanspy.c @@ -513,12 +513,43 @@ static void change_spy_mode(const char digit, struct ast_flags *flags) } } +static int attach_barge(struct ast_autochan *spyee_autochan, + struct ast_autochan **spyee_bridge_autochan, struct ast_audiohook *bridge_whisper_audiohook, + const char *spyer_name, const char *name) +{ + int retval = 0; + struct ast_autochan *internal_bridge_autochan; + struct ast_channel *bridged = ast_bridged_channel(spyee_autochan->chan); + + if (!bridged) { + return -1; + } + + ast_audiohook_init(bridge_whisper_audiohook, AST_AUDIOHOOK_TYPE_WHISPER, "Chanspy", 0); + + internal_bridge_autochan = ast_autochan_setup(bridged); + if (!internal_bridge_autochan) { + return -1; + } + + ast_channel_lock(internal_bridge_autochan->chan); + if (start_spying(internal_bridge_autochan, spyer_name, bridge_whisper_audiohook)) { + ast_log(LOG_WARNING, "Unable to attach barge audiohook on spyee '%s'. Barge mode disabled.\n", name); + retval = -1; + } + ast_channel_unlock(internal_bridge_autochan->chan); + + *spyee_bridge_autochan = internal_bridge_autochan; + + return retval; +} + static int channel_spy(struct ast_channel *chan, struct ast_autochan *spyee_autochan, int *volfactor, int fd, struct spy_dtmf_options *user_options, struct ast_flags *flags, char *exitcontext) { struct chanspy_translation_helper csth; - int running = 0, res, x = 0; + int running = 0, bridge_connected = 0, res, x = 0; char inp[24] = {0}; char *name; struct ast_frame *f; @@ -582,21 +613,6 @@ static int channel_spy(struct ast_channel *chan, struct ast_autochan *spyee_auto } } - if (ast_test_flag(flags, OPTION_BARGE | OPTION_DTMF_SWITCH_MODES)) { - /* And this hook lets us inject audio into the channel that the spied on - channel is currently bridged with. - */ - ast_audiohook_init(&csth.bridge_whisper_audiohook, AST_AUDIOHOOK_TYPE_WHISPER, "Chanspy", 0); - - if ((spyee_bridge_autochan = ast_autochan_setup(ast_bridged_channel(spyee_autochan->chan)))) { - ast_channel_lock(spyee_bridge_autochan->chan); - if (start_spying(spyee_bridge_autochan, spyer_name, &csth.bridge_whisper_audiohook)) { - ast_log(LOG_WARNING, "Unable to attach barge audiohook on spyee %s. Barge mode disabled!\n", name); - } - ast_channel_unlock(spyee_bridge_autochan->chan); - } - } - ast_channel_lock(chan); ast_set_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY); ast_channel_unlock(chan); @@ -636,6 +652,19 @@ static int channel_spy(struct ast_channel *chan, struct ast_autochan *spyee_auto } if (ast_test_flag(flags, OPTION_BARGE) && f->frametype == AST_FRAME_VOICE) { + /* This hook lets us inject audio into the channel that the spyee is currently + * bridged with. If the spyee isn't bridged with anything yet, nothing will + * be attached and we'll need to continue attempting to attach the barge + * audio hook. */ + if (!bridge_connected && attach_barge(spyee_autochan, &spyee_bridge_autochan, + &csth.bridge_whisper_audiohook, spyer_name, name) == 0) { + bridge_connected = 1; + } + + if (!bridge_connected) { + continue; + } + ast_audiohook_lock(&csth.whisper_audiohook); ast_audiohook_lock(&csth.bridge_whisper_audiohook); ast_audiohook_write_frame(&csth.whisper_audiohook, AST_AUDIOHOOK_DIRECTION_WRITE, f); @@ -651,7 +680,7 @@ static int channel_spy(struct ast_channel *chan, struct ast_autochan *spyee_auto ast_frfree(f); continue; } - + res = (f->frametype == AST_FRAME_DTMF) ? f->subclass.integer : 0; ast_frfree(f); if (!res) -- 2.47.2