diff --git a/apps/app_chanspy.c b/apps/app_chanspy.c index f568083fdaf56c32101dbdff7b68687988be0685..987eacfb64ce6a179dd80904a252c91f76e5c6ff 100644 --- a/apps/app_chanspy.c +++ b/apps/app_chanspy.c @@ -593,12 +593,43 @@ static void publish_chanspy_message(struct ast_channel *spyer, stasis_publish(ast_channel_topic(spyer), message); } +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; + RAII_VAR(struct ast_channel *, bridged, ast_channel_bridge_peer(spyee_autochan->chan), ast_channel_cleanup); + + 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; @@ -646,23 +677,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)) { - RAII_VAR(struct ast_channel *, bridged, ast_channel_bridge_peer(spyee_autochan->chan), ast_channel_cleanup); - - /* 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(bridged))) { - 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); @@ -702,6 +716,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); @@ -717,7 +744,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)