Index: apps/app_dial.c =================================================================== --- apps/app_dial.c (revision 370315) +++ apps/app_dial.c (working copy) @@ -67,6 +67,7 @@ #include "asterisk/privacy.h" #include "asterisk/stringfields.h" #include "asterisk/global_datastores.h" +#include "asterisk/dsp.h" static char *app = "Dial"; @@ -199,6 +200,7 @@ " family/key is not specified.\n" " r - Indicate ringing to the calling party. Pass no audio to the calling\n" " party until the called channel has answered.\n" +" s - Enable SIT detection on outbound early media.\n" " S(x) - Hang up the call after 'x' seconds *after* the called party has\n" " answered the call.\n" " t - Allow the called party to transfer the calling party by sending the\n" @@ -261,6 +263,7 @@ OPT_CALLEE_PARK = (1 << 25), OPT_CALLER_PARK = (1 << 26), OPT_IGNORE_FORWARDING = (1 << 27), + OPT_SIT_DETECT = (1 << 28), } dial_exec_option_flags; #define DIAL_STILLGOING (1 << 30) @@ -305,6 +308,7 @@ AST_APP_OPTION('p', OPT_SCREENING), AST_APP_OPTION_ARG('P', OPT_PRIVACY, OPT_ARG_PRIVACY), AST_APP_OPTION('r', OPT_RINGBACK), + AST_APP_OPTION('s', OPT_SIT_DETECT), AST_APP_OPTION_ARG('S', OPT_DURATION_STOP, OPT_ARG_DURATION_STOP), AST_APP_OPTION('t', OPT_CALLEE_TRANSFER), AST_APP_OPTION('T', OPT_CALLER_TRANSFER), @@ -429,6 +433,7 @@ struct ast_channel *peer = NULL; /* single is set if only one destination is enabled */ int single = outgoing && !outgoing->next && !ast_test_flag(outgoing, OPT_MUSICBACK | OPT_RINGBACK); + struct ast_dsp *dsp = NULL; char featurecode[FEATURE_MAX_LEN + 1] = { 0, }; @@ -455,6 +460,7 @@ int numlines = prestart; struct ast_channel *winner; struct ast_channel *watchers[AST_MAX_WATCHERS]; + int origrformat=0; watchers[pos++] = in; for (o = outgoing; o; o = o->next) { @@ -493,6 +499,12 @@ if (!peer) { if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name); + if (origrformat && ast_set_read_format(c, origrformat)) { + ast_log(LOG_WARNING, "Failed to restore read format for %s to %s\n", + c->name, ast_getformatname(origrformat)); + } + if (dsp) + ast_dsp_free(dsp); peer = c; ast_copy_flags(peerflags, o, OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER | @@ -502,6 +514,7 @@ DIAL_NOFORWARDHTML); ast_copy_string(c->dialcontext, "", sizeof(c->dialcontext)); ast_copy_string(c->exten, "", sizeof(c->exten)); + } continue; } @@ -612,6 +625,14 @@ HANDLE_CAUSE(in->hangupcause, in); continue; } + if (ast_test_flag(outgoing, OPT_SIT_DETECT) && f->frametype == AST_FRAME_VOICE && dsp) { + /* push a frame through the DSP */ + f = ast_dsp_process(winner, dsp, f); + if (f->frametype == AST_FRAME_VOICE) { + /* Set frametype to null to avoid sending bad audio to listeners */ + f->frametype = AST_FRAME_NULL; + } + } if (f->frametype == AST_FRAME_CONTROL) { switch(f->subclass) { case AST_CONTROL_ANSWER: @@ -632,6 +653,12 @@ DIAL_NOFORWARDHTML); ast_copy_string(c->dialcontext, "", sizeof(c->dialcontext)); ast_copy_string(c->exten, "", sizeof(c->exten)); + if (origrformat && ast_set_read_format(c, origrformat)) { + ast_log(LOG_WARNING, "Failed to restore read format for %s to %s\n", + c->name, ast_getformatname(origrformat)); + } + if (dsp) + ast_dsp_free(dsp); /* Setup RTP early bridge if appropriate */ if (CAN_EARLY_BRIDGE(peerflags, in, peer)) ast_rtp_early_bridge(in, peer); @@ -682,6 +709,21 @@ ast_indicate(in, AST_CONTROL_PROGRESS); } } + if (ast_test_flag(outgoing, OPT_SIT_DETECT)) { + /* We have progress and want to check for SIT */ + origrformat = c->readformat; + if (!ast_set_read_format(c, AST_FORMAT_SLINEAR)) { + ast_log(LOG_WARNING, "Unable to set read format to linear!\n"); + } else { + ast_verbose (VERBOSE_PREFIX_3 "%s format set to SLIN\n", c->name); + } + if (!(dsp = ast_dsp_new())) { + ast_log(LOG_WARNING, "Unable to allocate DSP for %s!\n", c->name); + } else { + ast_verbose (VERBOSE_PREFIX_3 "DSP allocated for SIT detect on %s\n", c->name); + } + ast_dsp_set_features(dsp, DSP_PROGRESS_CONGESTION); + } break; case AST_CONTROL_VIDUPDATE: if (option_verbose > 2) @@ -1236,7 +1278,7 @@ OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP | OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR | OPT_CALLEE_PARK | OPT_CALLER_PARK | - OPT_RINGBACK | OPT_MUSICBACK | OPT_FORCECLID); + OPT_RINGBACK | OPT_MUSICBACK | OPT_FORCECLID | OPT_SIT_DETECT); ast_set2_flag(tmp, args.url, DIAL_NOFORWARDHTML); } ast_copy_string(numsubst, number, sizeof(numsubst));