summaryrefslogtreecommitdiff
path: root/apps/app_chanspy.c
diff options
context:
space:
mode:
authorJonathan Rose <jrose@digium.com>2014-05-09 17:03:41 +0000
committerJonathan Rose <jrose@digium.com>2014-05-09 17:03:41 +0000
commit57704832176d6c84e0d95e7f78e53f819c70a1e4 (patch)
tree4008de497a7d9e991470ca87b85852a42127e438 /apps/app_chanspy.c
parentf2ca3438e7923b8fdca2f89b68a88f6cc4bbc0b8 (diff)
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/ ........ Merged revisions 413551 from http://svn.asterisk.org/svn/asterisk/branches/11 ........ Merged revisions 413556 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@413557 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'apps/app_chanspy.c')
-rw-r--r--apps/app_chanspy.c65
1 files changed, 46 insertions, 19 deletions
diff --git a/apps/app_chanspy.c b/apps/app_chanspy.c
index f568083fd..987eacfb6 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)