diff options
Diffstat (limited to 'main/features.c')
-rw-r--r-- | main/features.c | 241 |
1 files changed, 123 insertions, 118 deletions
diff --git a/main/features.c b/main/features.c index 4ff629fb4..cbf7c1f42 100644 --- a/main/features.c +++ b/main/features.c @@ -2166,6 +2166,9 @@ static int builtin_automonitor(struct ast_channel *chan, struct ast_channel *pee struct ast_channel *caller_chan, *callee_chan; const char *automon_message_start = NULL; const char *automon_message_stop = NULL; + const char *touch_format = NULL; + const char *touch_monitor = NULL; + const char *touch_monitor_prefix = NULL; if (!monitor_ok) { ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n"); @@ -2179,10 +2182,13 @@ static int builtin_automonitor(struct ast_channel *chan, struct ast_channel *pee } set_peers(&caller_chan, &callee_chan, peer, chan, sense); - if (caller_chan) { /* Find extra messages */ - automon_message_start = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_MESSAGE_START"); - automon_message_stop = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_MESSAGE_STOP"); + if (!caller_chan || !callee_chan) { + ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n"); + return -1; } + /* Find extra messages */ + automon_message_start = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_MESSAGE_START"); + automon_message_stop = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_MESSAGE_STOP"); if (!ast_strlen_zero(courtesytone)) { /* Play courtesy tone if configured */ if(play_message_in_bridged_call(caller_chan, callee_chan, courtesytone) == -1) { @@ -2199,58 +2205,53 @@ static int builtin_automonitor(struct ast_channel *chan, struct ast_channel *pee return AST_FEATURE_RETURN_SUCCESS; } - if (caller_chan && callee_chan) { - const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_FORMAT"); - const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR"); - const char *touch_monitor_prefix = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_PREFIX"); + touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_FORMAT"); + touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR"); + touch_monitor_prefix = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_PREFIX"); - if (!touch_format) - touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_FORMAT"); - - if (!touch_monitor) - touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR"); + if (!touch_format) + touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_FORMAT"); - if (!touch_monitor_prefix) - touch_monitor_prefix = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_PREFIX"); + if (!touch_monitor) + touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR"); - if (touch_monitor) { - len = strlen(touch_monitor) + 50; - args = alloca(len); - touch_filename = alloca(len); - snprintf(touch_filename, len, "%s-%ld-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), touch_monitor); - snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename); - } else { - caller_chan_id = ast_strdupa(S_COR(ast_channel_caller(caller_chan)->id.number.valid, - ast_channel_caller(caller_chan)->id.number.str, ast_channel_name(caller_chan))); - callee_chan_id = ast_strdupa(S_COR(ast_channel_caller(callee_chan)->id.number.valid, - ast_channel_caller(callee_chan)->id.number.str, ast_channel_name(callee_chan))); - len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50; - args = alloca(len); - touch_filename = alloca(len); - snprintf(touch_filename, len, "%s-%ld-%s-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), caller_chan_id, callee_chan_id); - snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename); - } + if (!touch_monitor_prefix) + touch_monitor_prefix = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_PREFIX"); - for(x = 0; x < strlen(args); x++) { - if (args[x] == '/') - args[x] = '-'; - } + if (touch_monitor) { + len = strlen(touch_monitor) + 50; + args = alloca(len); + touch_filename = alloca(len); + snprintf(touch_filename, len, "%s-%ld-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), touch_monitor); + snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename); + } else { + caller_chan_id = ast_strdupa(S_COR(ast_channel_caller(caller_chan)->id.number.valid, + ast_channel_caller(caller_chan)->id.number.str, ast_channel_name(caller_chan))); + callee_chan_id = ast_strdupa(S_COR(ast_channel_caller(callee_chan)->id.number.valid, + ast_channel_caller(callee_chan)->id.number.str, ast_channel_name(callee_chan))); + len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50; + args = alloca(len); + touch_filename = alloca(len); + snprintf(touch_filename, len, "%s-%ld-%s-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), caller_chan_id, callee_chan_id); + snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename); + } - ast_verb(4, "User hit '%s' to record call. filename: %s\n", code, args); + for(x = 0; x < strlen(args); x++) { + if (args[x] == '/') + args[x] = '-'; + } - pbx_exec(callee_chan, monitor_app, args); - pbx_builtin_setvar_helper(callee_chan, "TOUCH_MONITOR_OUTPUT", touch_filename); - pbx_builtin_setvar_helper(caller_chan, "TOUCH_MONITOR_OUTPUT", touch_filename); + ast_verb(4, "User hit '%s' to record call. filename: %s\n", code, args); - if (!ast_strlen_zero(automon_message_start)) { /* Play start message for both channels */ - play_message_in_bridged_call(caller_chan, callee_chan, automon_message_start); - } + pbx_exec(callee_chan, monitor_app, args); + pbx_builtin_setvar_helper(callee_chan, "TOUCH_MONITOR_OUTPUT", touch_filename); + pbx_builtin_setvar_helper(caller_chan, "TOUCH_MONITOR_OUTPUT", touch_filename); - return AST_FEATURE_RETURN_SUCCESS; + if (!ast_strlen_zero(automon_message_start)) { /* Play start message for both channels */ + play_message_in_bridged_call(caller_chan, callee_chan, automon_message_start); } - ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n"); - return -1; + return AST_FEATURE_RETURN_SUCCESS; } static int builtin_automixmonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data) @@ -3415,12 +3416,10 @@ static int feature_exec_app(struct ast_channel *chan, struct ast_channel *peer, ast_autoservice_start(idle); ast_autoservice_ignore(idle, AST_FRAME_DTMF_END); - if(work && idle) { - pbx_builtin_setvar_helper(work, "DYNAMIC_PEERNAME", ast_channel_name(idle)); - pbx_builtin_setvar_helper(idle, "DYNAMIC_PEERNAME", ast_channel_name(work)); - pbx_builtin_setvar_helper(work, "DYNAMIC_FEATURENAME", feature->sname); - pbx_builtin_setvar_helper(idle, "DYNAMIC_FEATURENAME", feature->sname); - } + pbx_builtin_setvar_helper(work, "DYNAMIC_PEERNAME", ast_channel_name(idle)); + pbx_builtin_setvar_helper(idle, "DYNAMIC_PEERNAME", ast_channel_name(work)); + pbx_builtin_setvar_helper(work, "DYNAMIC_FEATURENAME", feature->sname); + pbx_builtin_setvar_helper(idle, "DYNAMIC_FEATURENAME", feature->sname); if (!ast_strlen_zero(feature->moh_class)) ast_moh_start(idle, feature->moh_class, NULL); @@ -3543,7 +3542,9 @@ static int feature_interpret_helper(struct ast_channel *chan, struct ast_channel if (operation) { res = fge->feature->operation(chan, peer, config, code, sense, fge->feature); } - memcpy(feature, fge->feature, sizeof(*feature)); + if (feature) { + memcpy(feature, fge->feature, sizeof(*feature)); + } if (res != AST_FEATURE_RETURN_KEEPTRYING) { AST_RWLIST_UNLOCK(&feature_groups); break; @@ -5019,76 +5020,80 @@ static int manage_parked_call(struct parkeduser *pu, const struct pollfd *pfds, /* And take them out of the parking lot */ parking_complete = 1; } else { /* still within parking time, process descriptors */ - for (x = 0; x < AST_MAX_FDS; x++) { - struct ast_frame *f; - int y; - - if (!ast_channel_fd_isset(chan, x)) { - continue; /* nothing on this descriptor */ - } - - for (y = 0; y < nfds; y++) { - if (pfds[y].fd == ast_channel_fd(chan, x)) { - /* Found poll record! */ - break; + x = 0; + if (pfds) { + for (; x < AST_MAX_FDS; x++) { + struct ast_frame *f; + int y; + + if (!ast_channel_fd_isset(chan, x)) { + continue; /* nothing on this descriptor */ } - } - if (y == nfds) { - /* Not found */ - continue; - } - - if (!(pfds[y].revents & (POLLIN | POLLERR | POLLPRI))) { - /* Next x */ - continue; - } - - if (pfds[y].revents & POLLPRI) { - ast_set_flag(ast_channel_flags(chan), AST_FLAG_EXCEPTION); - } else { - ast_clear_flag(ast_channel_flags(chan), AST_FLAG_EXCEPTION); - } - ast_channel_fdno_set(chan, x); - - /* See if they need servicing */ - f = ast_read(pu->chan); - /* Hangup? */ - if (!f || (f->frametype == AST_FRAME_CONTROL - && f->subclass.integer == AST_CONTROL_HANGUP)) { - if (f) { - ast_frfree(f); + + for (y = 0; y < nfds; y++) { + if (pfds[y].fd == ast_channel_fd(chan, x)) { + /* Found poll record! */ + break; + } } - post_manager_event("ParkedCallGiveUp", pu); - ast_cel_report_event(pu->chan, AST_CEL_PARK_END, NULL, "ParkedCallGiveUp", - NULL); - - /* There's a problem, hang them up */ - ast_verb(2, "%s got tired of being parked\n", ast_channel_name(chan)); - ast_hangup(chan); - - /* And take them out of the parking lot */ - parking_complete = 1; - break; - } else { - /* XXX Maybe we could do something with packets, like dial "0" for operator or something XXX */ - ast_frfree(f); - if (pu->hold_method == AST_CONTROL_HOLD - && pu->moh_trys < 3 - && !ast_channel_generatordata(chan)) { - ast_debug(1, - "MOH on parked call stopped by outside source. Restarting on channel %s.\n", - ast_channel_name(chan)); - ast_indicate_data(chan, AST_CONTROL_HOLD, - S_OR(pu->parkinglot->cfg.mohclass, NULL), - (!ast_strlen_zero(pu->parkinglot->cfg.mohclass) - ? strlen(pu->parkinglot->cfg.mohclass) + 1 : 0)); - pu->moh_trys++; + if (y == nfds) { + /* Not found */ + continue; } - goto std; /* XXX Ick: jumping into an else statement??? XXX */ - } - } /* End for */ + + if (!(pfds[y].revents & (POLLIN | POLLERR | POLLPRI))) { + /* Next x */ + continue; + } + + if (pfds[y].revents & POLLPRI) { + ast_set_flag(ast_channel_flags(chan), AST_FLAG_EXCEPTION); + } else { + ast_clear_flag(ast_channel_flags(chan), AST_FLAG_EXCEPTION); + } + ast_channel_fdno_set(chan, x); + + /* See if they need servicing */ + f = ast_read(pu->chan); + /* Hangup? */ + if (!f || (f->frametype == AST_FRAME_CONTROL + && f->subclass.integer == AST_CONTROL_HANGUP)) { + if (f) { + ast_frfree(f); + } + post_manager_event("ParkedCallGiveUp", pu); + ast_cel_report_event(pu->chan, AST_CEL_PARK_END, NULL, "ParkedCallGiveUp", + NULL); + + /* There's a problem, hang them up */ + ast_verb(2, "%s got tired of being parked\n", ast_channel_name(chan)); + ast_hangup(chan); + + /* And take them out of the parking lot */ + parking_complete = 1; + break; + } else { + /* XXX Maybe we could do something with packets, like dial "0" for operator or something XXX */ + ast_frfree(f); + if (pu->hold_method == AST_CONTROL_HOLD + && pu->moh_trys < 3 + && !ast_channel_generatordata(chan)) { + ast_debug(1, + "MOH on parked call stopped by outside source. Restarting on channel %s.\n", + ast_channel_name(chan)); + ast_indicate_data(chan, AST_CONTROL_HOLD, + S_OR(pu->parkinglot->cfg.mohclass, NULL), + (!ast_strlen_zero(pu->parkinglot->cfg.mohclass) + ? strlen(pu->parkinglot->cfg.mohclass) + 1 : 0)); + pu->moh_trys++; + } + goto std; /* XXX Ick: jumping into an else statement??? XXX */ + } + } /* End for */ + } if (x >= AST_MAX_FDS) { -std: for (x = 0; x < AST_MAX_FDS; x++) { /* mark fds for next round */ +std: + for (x = 0; x < AST_MAX_FDS; x++) { /* mark fds for next round */ if (ast_channel_fd_isset(chan, x)) { void *tmp = ast_realloc(*new_pfds, (*new_nfds + 1) * sizeof(struct pollfd)); |