diff options
author | file <file@f38db490-d61c-443f-a65b-d21fe96a405b> | 2008-01-16 20:33:47 +0000 |
---|---|---|
committer | file <file@f38db490-d61c-443f-a65b-d21fe96a405b> | 2008-01-16 20:33:47 +0000 |
commit | e13f2a7488382aabc3ac369c5495f013e2a0adc0 (patch) | |
tree | f2bf111805d3da287f8981b96532cdd0a84aecbe /apps | |
parent | f4896114d2d146ab65a296e4090d564af0676459 (diff) |
Replace current spy architecture with backport of audiohooks. This should take care of current known spy issues.
git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.4@98972 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'apps')
-rw-r--r-- | apps/app_chanspy.c | 154 | ||||
-rw-r--r-- | apps/app_meetme.c | 6 | ||||
-rw-r--r-- | apps/app_mixmonitor.c | 124 |
3 files changed, 103 insertions, 181 deletions
diff --git a/apps/app_chanspy.c b/apps/app_chanspy.c index b84835196..a99c03216 100644 --- a/apps/app_chanspy.c +++ b/apps/app_chanspy.c @@ -40,7 +40,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/file.h" #include "asterisk/logger.h" #include "asterisk/channel.h" -#include "asterisk/chanspy.h" +#include "asterisk/audiohook.h" #include "asterisk/features.h" #include "asterisk/options.h" #include "asterisk/app.h" @@ -143,7 +143,8 @@ AST_APP_OPTIONS(spy_opts, { struct chanspy_translation_helper { /* spy data */ - struct ast_channel_spy spy; + struct ast_audiohook spy_audiohook; + struct ast_audiohook whisper_audiohook; int fd; int volfactor; }; @@ -163,15 +164,17 @@ static int spy_generate(struct ast_channel *chan, void *data, int len, int sampl { struct chanspy_translation_helper *csth = data; struct ast_frame *f; - - if (csth->spy.status != CHANSPY_RUNNING) - /* Channel is already gone more than likely */ + + ast_audiohook_lock(&csth->spy_audiohook); + if (csth->spy_audiohook.status != AST_AUDIOHOOK_STATUS_RUNNING) { + ast_audiohook_unlock(&csth->spy_audiohook); return -1; + } + + f = ast_audiohook_read_frame(&csth->spy_audiohook, samples, AST_AUDIOHOOK_DIRECTION_BOTH, AST_FORMAT_SLINEAR); + + ast_audiohook_unlock(&csth->spy_audiohook); - ast_mutex_lock(&csth->spy.lock); - f = ast_channel_spy_read_frame(&csth->spy, samples); - ast_mutex_unlock(&csth->spy.lock); - if (!f) return 0; @@ -194,16 +197,14 @@ static struct ast_generator spygen = { .generate = spy_generate, }; -static int start_spying(struct ast_channel *chan, struct ast_channel *spychan, struct ast_channel_spy *spy) +static int start_spying(struct ast_channel *chan, struct ast_channel *spychan, struct ast_audiohook *audiohook) { int res; struct ast_channel *peer; ast_log(LOG_NOTICE, "Attaching %s to %s\n", spychan->name, chan->name); - ast_channel_lock(chan); - res = ast_channel_spy_add(chan, spy); - ast_channel_unlock(chan); + res = ast_audiohook_attach(chan, audiohook); if (!res && ast_test_flag(chan, AST_FLAG_NBRIDGE) && (peer = ast_bridged_channel(chan))) ast_softhangup(peer, AST_SOFTHANGUP_UNBRIDGE); @@ -211,35 +212,6 @@ static int start_spying(struct ast_channel *chan, struct ast_channel *spychan, s return res; } -/* Map 'volume' levels from -4 through +4 into - decibel (dB) settings for channel drivers -*/ -static signed char volfactor_map[] = { - -24, - -18, - -12, - -6, - 0, - 6, - 12, - 18, - 24, -}; - -/* attempt to set the desired gain adjustment via the channel driver; - if successful, clear it out of the csth structure so the - generator will not attempt to do the adjustment itself -*/ -static void set_volume(struct ast_channel *chan, struct chanspy_translation_helper *csth) -{ - signed char volume_adjust = volfactor_map[csth->volfactor + 4]; - - if (!ast_channel_setoption(chan, AST_OPTION_TXGAIN, &volume_adjust, sizeof(volume_adjust), 0)) - csth->volfactor = 0; - csth->spy.read_vol_adjustment = csth->volfactor; - csth->spy.write_vol_adjustment = csth->volfactor; -} - static int channel_spy(struct ast_channel *chan, struct ast_channel *spyee, int *volfactor, int fd, const struct ast_flags *flags) { @@ -258,49 +230,27 @@ static int channel_spy(struct ast_channel *chan, struct ast_channel *spyee, int ast_verbose(VERBOSE_PREFIX_2 "Spying on channel %s\n", name); memset(&csth, 0, sizeof(csth)); - ast_set_flag(&csth.spy, CHANSPY_FORMAT_AUDIO); - ast_set_flag(&csth.spy, CHANSPY_TRIGGER_NONE); - ast_set_flag(&csth.spy, CHANSPY_MIXAUDIO); - csth.spy.type = "ChanSpy"; - csth.spy.status = CHANSPY_RUNNING; - csth.spy.read_queue.format = AST_FORMAT_SLINEAR; - csth.spy.write_queue.format = AST_FORMAT_SLINEAR; - ast_mutex_init(&csth.spy.lock); - csth.volfactor = *volfactor; - set_volume(chan, &csth); - if (csth.volfactor) { - ast_set_flag(&csth.spy, CHANSPY_READ_VOLADJUST); - csth.spy.read_vol_adjustment = csth.volfactor; - ast_set_flag(&csth.spy, CHANSPY_WRITE_VOLADJUST); - csth.spy.write_vol_adjustment = csth.volfactor; - } - csth.fd = fd; - if (start_spying(spyee, chan, &csth.spy)) { - ast_mutex_destroy(&csth.spy.lock); + ast_audiohook_init(&csth.spy_audiohook, AST_AUDIOHOOK_TYPE_SPY, "ChanSpy"); + + if (start_spying(spyee, chan, &csth.spy_audiohook)) { + ast_audiohook_destroy(&csth.spy_audiohook); return 0; } - + if (ast_test_flag(flags, OPTION_WHISPER)) { - struct ast_filestream *beepstream; - int old_write_format = 0; - - ast_channel_whisper_start(csth.spy.chan); - old_write_format = chan->writeformat; - if ((beepstream = ast_openstream_full(chan, "beep", chan->language, 1))) { - struct ast_frame *f; - - while ((f = ast_readframe(beepstream))) { - ast_channel_whisper_feed(csth.spy.chan, f); - ast_frfree(f); - } - - ast_closestream(beepstream); - chan->stream = NULL; - } - if (old_write_format) - ast_set_write_format(chan, old_write_format); + ast_audiohook_init(&csth.whisper_audiohook, AST_AUDIOHOOK_TYPE_WHISPER, "ChanSpy"); + start_spying(spyee, chan, &csth.whisper_audiohook); + } + + csth.volfactor = *volfactor; + + if (csth.volfactor) { + csth.spy_audiohook.options.read_volume = csth.volfactor; + csth.spy_audiohook.options.write_volume = csth.volfactor; } + + csth.fd = fd; if (ast_test_flag(flags, OPTION_PRIVATE)) silgen = ast_channel_start_silence_generator(chan); @@ -321,17 +271,16 @@ static int channel_spy(struct ast_channel *chan, struct ast_channel *spyee, int has arrived, since the spied-on channel could have gone away while we were waiting */ - while ((res = ast_waitfor(chan, -1) > -1) && - csth.spy.status == CHANSPY_RUNNING && - csth.spy.chan) { + while ((res = ast_waitfor(chan, -1) > -1) && csth.spy_audiohook.status == AST_AUDIOHOOK_STATUS_RUNNING) { if (!(f = ast_read(chan)) || ast_check_hangup(chan)) { running = -1; break; } - if (ast_test_flag(flags, OPTION_WHISPER) && - (f->frametype == AST_FRAME_VOICE)) { - ast_channel_whisper_feed(csth.spy.chan, f); + if (ast_test_flag(flags, OPTION_WHISPER) && (f->frametype == AST_FRAME_VOICE)) { + ast_audiohook_lock(&csth.whisper_audiohook); + ast_audiohook_write_frame(&csth.whisper_audiohook, AST_AUDIOHOOK_DIRECTION_WRITE, f); + ast_audiohook_unlock(&csth.whisper_audiohook); ast_frfree(f); continue; } @@ -364,38 +313,29 @@ static int channel_spy(struct ast_channel *chan, struct ast_channel *spyee, int if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Setting spy volume on %s to %d\n", chan->name, *volfactor); csth.volfactor = *volfactor; - set_volume(chan, &csth); - if (csth.volfactor) { - ast_set_flag(&csth.spy, CHANSPY_READ_VOLADJUST); - csth.spy.read_vol_adjustment = csth.volfactor; - ast_set_flag(&csth.spy, CHANSPY_WRITE_VOLADJUST); - csth.spy.write_vol_adjustment = csth.volfactor; - } else { - ast_clear_flag(&csth.spy, CHANSPY_READ_VOLADJUST); - ast_clear_flag(&csth.spy, CHANSPY_WRITE_VOLADJUST); - } + csth.spy_audiohook.options.read_volume = csth.volfactor; + csth.spy_audiohook.options.write_volume = csth.volfactor; } else if (res >= '0' && res <= '9') { inp[x++] = res; } } - if (ast_test_flag(flags, OPTION_WHISPER) && csth.spy.chan) - ast_channel_whisper_stop(csth.spy.chan); - if (ast_test_flag(flags, OPTION_PRIVATE)) ast_channel_stop_silence_generator(chan, silgen); else ast_deactivate_generator(chan); - csth.spy.status = CHANSPY_DONE; - - /* If a channel still exists on our spy structure then we need to remove ourselves */ - if (csth.spy.chan) { - ast_channel_lock(csth.spy.chan); - ast_channel_spy_remove(csth.spy.chan, &csth.spy); - ast_channel_unlock(csth.spy.chan); + if (ast_test_flag(flags, OPTION_WHISPER)) { + ast_audiohook_lock(&csth.whisper_audiohook); + ast_audiohook_detach(&csth.whisper_audiohook); + ast_audiohook_unlock(&csth.whisper_audiohook); + ast_audiohook_destroy(&csth.whisper_audiohook); } - ast_channel_spy_free(&csth.spy); + + ast_audiohook_lock(&csth.spy_audiohook); + ast_audiohook_detach(&csth.spy_audiohook); + ast_audiohook_unlock(&csth.spy_audiohook); + ast_audiohook_destroy(&csth.spy_audiohook); if (option_verbose >= 2) ast_verbose(VERBOSE_PREFIX_2 "Done Spying on channel %s\n", name); diff --git a/apps/app_meetme.c b/apps/app_meetme.c index 0c8842b8a..9ab8db54e 100644 --- a/apps/app_meetme.c +++ b/apps/app_meetme.c @@ -1578,7 +1578,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int c goto outrun; } - retryzap = (strcasecmp(chan->tech->type, "Zap") || (chan->spies || chan->monitor) ? 1 : 0); + retryzap = (strcasecmp(chan->tech->type, "Zap") || (chan->audiohooks || chan->monitor) ? 1 : 0); user->zapchannel = !retryzap; zapretry: @@ -1896,14 +1896,14 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int c break; if (c) { - if (c->fds[0] != origfd || (user->zapchannel && (c->spies || c->monitor))) { + if (c->fds[0] != origfd || (user->zapchannel && (c->audiohooks || c->monitor))) { if (using_pseudo) { /* Kill old pseudo */ close(fd); using_pseudo = 0; } ast_log(LOG_DEBUG, "Ooh, something swapped out under us, starting over\n"); - retryzap = (strcasecmp(c->tech->type, "Zap") || (c->spies || c->monitor) ? 1 : 0); + retryzap = (strcasecmp(c->tech->type, "Zap") || (c->audiohooks || c->monitor) ? 1 : 0); user->zapchannel = !retryzap; goto zapretry; } diff --git a/apps/app_mixmonitor.c b/apps/app_mixmonitor.c index eed159d69..430035251 100644 --- a/apps/app_mixmonitor.c +++ b/apps/app_mixmonitor.c @@ -45,7 +45,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/file.h" #include "asterisk/logger.h" #include "asterisk/channel.h" -#include "asterisk/chanspy.h" +#include "asterisk/audiohook.h" #include "asterisk/pbx.h" #include "asterisk/module.h" #include "asterisk/lock.h" @@ -93,11 +93,12 @@ struct module_symbols *me; static const char *mixmonitor_spy_type = "MixMonitor"; struct mixmonitor { - struct ast_channel_spy spy; + struct ast_audiohook audiohook; char *filename; char *post_process; char *name; unsigned int flags; + struct ast_channel *chan; }; enum { @@ -123,7 +124,7 @@ AST_APP_OPTIONS(mixmonitor_opts, { AST_APP_OPTION_ARG('W', MUXFLAG_VOLUME, OPT_ARG_VOLUME), }); -static int startmon(struct ast_channel *chan, struct ast_channel_spy *spy) +static int startmon(struct ast_channel *chan, struct ast_audiohook *audiohook) { struct ast_channel *peer; int res; @@ -131,9 +132,7 @@ static int startmon(struct ast_channel *chan, struct ast_channel_spy *spy) if (!chan) return -1; - ast_channel_lock(chan); - res = ast_channel_spy_add(chan, spy); - ast_channel_unlock(chan); + res = ast_audiohook_attach(chan, audiohook); if (!res && ast_test_flag(chan, AST_FLAG_NBRIDGE) && (peer = ast_bridged_channel(chan))) ast_softhangup(peer, AST_SOFTHANGUP_UNBRIDGE); @@ -146,7 +145,6 @@ static int startmon(struct ast_channel *chan, struct ast_channel_spy *spy) static void *mixmonitor_thread(void *obj) { struct mixmonitor *mixmonitor = obj; - struct ast_frame *f = NULL; struct ast_filestream *fs = NULL; unsigned int oflags; char *ext; @@ -155,58 +153,48 @@ static void *mixmonitor_thread(void *obj) if (option_verbose > 1) ast_verbose(VERBOSE_PREFIX_2 "Begin MixMonitor Recording %s\n", mixmonitor->name); - ast_mutex_lock(&mixmonitor->spy.lock); + ast_audiohook_lock(&mixmonitor->audiohook); - while (mixmonitor->spy.chan) { - struct ast_frame *next; - int write; - - ast_channel_spy_trigger_wait(&mixmonitor->spy); + while (mixmonitor->audiohook.status == AST_AUDIOHOOK_STATUS_RUNNING) { + struct ast_frame *fr = NULL; + + ast_audiohook_trigger_wait(&mixmonitor->audiohook); - if (!mixmonitor->spy.chan || mixmonitor->spy.status != CHANSPY_RUNNING) + if (mixmonitor->audiohook.status != AST_AUDIOHOOK_STATUS_RUNNING) break; - while (1) { - if (!(f = ast_channel_spy_read_frame(&mixmonitor->spy, SAMPLES_PER_FRAME))) - break; - - write = (!ast_test_flag(mixmonitor, MUXFLAG_BRIDGED) || - ast_bridged_channel(mixmonitor->spy.chan)); - - /* it is possible for ast_channel_spy_read_frame() to return a chain - of frames if a queue flush was necessary, so process them - */ - for (; f; f = next) { - next = AST_LIST_NEXT(f, frame_list); - if (write && errflag == 0) { - if (!fs) { - /* Determine creation flags and filename plus extension for filestream */ - oflags = O_CREAT | O_WRONLY; - oflags |= ast_test_flag(mixmonitor, MUXFLAG_APPEND) ? O_APPEND : O_TRUNC; - - if ((ext = strrchr(mixmonitor->filename, '.'))) - *(ext++) = '\0'; - else - ext = "raw"; - - /* Move onto actually creating the filestream */ - if (!(fs = ast_writefile(mixmonitor->filename, ext, NULL, oflags, 0, 0644))) { - ast_log(LOG_ERROR, "Cannot open %s.%s\n", mixmonitor->filename, ext); - errflag = 1; - } - - } - if (fs) - ast_writestream(fs, f); + if (!(fr = ast_audiohook_read_frame(&mixmonitor->audiohook, SAMPLES_PER_FRAME, AST_AUDIOHOOK_DIRECTION_BOTH, AST_FORMAT_SLINEAR))) + continue; + + if (!ast_test_flag(mixmonitor, MUXFLAG_BRIDGED) || ast_bridged_channel(mixmonitor->chan)) { + /* Initialize the file if not already done so */ + if (!fs && !errflag) { + oflags = O_CREAT | O_WRONLY; + oflags |= ast_test_flag(mixmonitor, MUXFLAG_APPEND) ? O_APPEND : O_TRUNC; + + if ((ext = strrchr(mixmonitor->filename, '.'))) + *(ext++) = '\0'; + else + ext = "raw"; + + if (!(fs = ast_writefile(mixmonitor->filename, ext, NULL, oflags, 0, 0644))) { + ast_log(LOG_ERROR, "Cannot open %s.%s\n", mixmonitor->filename, ext); + errflag = 1; } - ast_frame_free(f, 0); } + + /* Write out the frame */ + if (fs) + ast_writestream(fs, fr); } - } - ast_mutex_unlock(&mixmonitor->spy.lock); + /* All done! free it. */ + ast_frame_free(fr, 0); + } - ast_channel_spy_free(&mixmonitor->spy); + ast_audiohook_detach(&mixmonitor->audiohook); + ast_audiohook_unlock(&mixmonitor->audiohook); + ast_audiohook_destroy(&mixmonitor->audiohook); if (option_verbose > 1) ast_verbose(VERBOSE_PREFIX_2 "End MixMonitor Recording %s\n", mixmonitor->name); @@ -271,27 +259,23 @@ static void launch_monitor_thread(struct ast_channel *chan, const char *filename strcpy(mixmonitor->filename, filename); /* Setup the actual spy before creating our thread */ - ast_set_flag(&mixmonitor->spy, CHANSPY_FORMAT_AUDIO); - ast_set_flag(&mixmonitor->spy, CHANSPY_MIXAUDIO); - mixmonitor->spy.type = mixmonitor_spy_type; - mixmonitor->spy.status = CHANSPY_RUNNING; - mixmonitor->spy.read_queue.format = AST_FORMAT_SLINEAR; - mixmonitor->spy.write_queue.format = AST_FORMAT_SLINEAR; - if (readvol) { - ast_set_flag(&mixmonitor->spy, CHANSPY_READ_VOLADJUST); - mixmonitor->spy.read_vol_adjustment = readvol; - } - if (writevol) { - ast_set_flag(&mixmonitor->spy, CHANSPY_WRITE_VOLADJUST); - mixmonitor->spy.write_vol_adjustment = writevol; + if (ast_audiohook_init(&mixmonitor->audiohook, AST_AUDIOHOOK_TYPE_SPY, mixmonitor_spy_type)) { + free(mixmonitor); + return; } - ast_mutex_init(&mixmonitor->spy.lock); + + ast_set_flag(&mixmonitor->audiohook, AST_AUDIOHOOK_TRIGGER_WRITE); + + if (readvol) + mixmonitor->audiohook.options.read_volume = readvol; + if (writevol) + mixmonitor->audiohook.options.write_volume = writevol; - if (startmon(chan, &mixmonitor->spy)) { + if (startmon(chan, &mixmonitor->audiohook)) { ast_log(LOG_WARNING, "Unable to add '%s' spy to channel '%s'\n", - mixmonitor->spy.type, chan->name); + mixmonitor_spy_type, chan->name); /* Since we couldn't add ourselves - bail out! */ - ast_mutex_destroy(&mixmonitor->spy.lock); + ast_audiohook_destroy(&mixmonitor->audiohook); free(mixmonitor); return; } @@ -391,9 +375,7 @@ static int stop_mixmonitor_exec(struct ast_channel *chan, void *data) u = ast_module_user_add(chan); - ast_channel_lock(chan); - ast_channel_spy_stop_by_type(chan, mixmonitor_spy_type); - ast_channel_unlock(chan); + ast_audiohook_detach_source(chan, mixmonitor_spy_type); ast_module_user_remove(u); @@ -415,7 +397,7 @@ static int mixmonitor_cli(int fd, int argc, char **argv) if (!strcasecmp(argv[1], "start")) mixmonitor_exec(chan, argv[3]); else if (!strcasecmp(argv[1], "stop")) - ast_channel_spy_stop_by_type(chan, mixmonitor_spy_type); + ast_audiohook_detach_source(chan, mixmonitor_spy_type); ast_channel_unlock(chan); |