mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-30 02:26:23 +00:00
Created API call ast_dtmf_stream
int ast_dtmf_stream(struct ast_channel *chan,struct ast_channel *peer,char *digits,int between) changed app_senddtmf.c to use this new call added D() parameter to app_dial to allow post connect dtmf stream to be sent using above call -Tony git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@2918 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
45
app.c
45
app.c
@@ -259,3 +259,48 @@ int ast_app_messagecount(const char *mailbox, int *newmsgs, int *oldmsgs)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ast_dtmf_stream(struct ast_channel *chan,struct ast_channel *peer,char *digits,int between) {
|
||||||
|
char *ptr=NULL;
|
||||||
|
int res=0;
|
||||||
|
struct ast_frame f;
|
||||||
|
if(!between)
|
||||||
|
between = 100;
|
||||||
|
|
||||||
|
if(peer)
|
||||||
|
res = ast_autoservice_start(peer);
|
||||||
|
|
||||||
|
if (!res) {
|
||||||
|
res = ast_waitfor(chan,100);
|
||||||
|
if(res > -1) {
|
||||||
|
for(ptr=digits;*ptr;*ptr++) {
|
||||||
|
if(*ptr == 'w') {
|
||||||
|
res = ast_safe_sleep(chan, 500);
|
||||||
|
if(res)
|
||||||
|
break;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
memset(&f, 0, sizeof(f));
|
||||||
|
f.frametype = AST_FRAME_DTMF;
|
||||||
|
f.subclass = *ptr;
|
||||||
|
f.src = "ast_dtmf_stream";
|
||||||
|
if (strchr("0123456789*#abcdABCD",*ptr)==NULL) {
|
||||||
|
ast_log(LOG_WARNING, "Illegal DTMF character '%c' in string. (0-9*#aAbBcCdD allowed)\n",*ptr);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
res = ast_write(chan, &f);
|
||||||
|
if (res)
|
||||||
|
break;
|
||||||
|
/* pause between digits */
|
||||||
|
res = ast_safe_sleep(chan,between);
|
||||||
|
if (res)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(peer)
|
||||||
|
res = ast_autoservice_stop(peer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
210
apps/app_dial.c
210
apps/app_dial.c
@@ -70,6 +70,8 @@ static char *descrip =
|
|||||||
" 'g' -- goes on in context if the destination channel hangs up\n"
|
" 'g' -- goes on in context if the destination channel hangs up\n"
|
||||||
" 'A(x)' -- play an announcement to the called party, using x as file\n"
|
" 'A(x)' -- play an announcement to the called party, using x as file\n"
|
||||||
" 'S(x)' -- hangup the call after x seconds AFTER called party picked up\n"
|
" 'S(x)' -- hangup the call after x seconds AFTER called party picked up\n"
|
||||||
|
" 'D([digits])' -- Send DTMF digit string *after* called party has answered\n"
|
||||||
|
" but before the bridge. (w=500ms sec pause)\n"
|
||||||
" 'L(x[:y][:z])' -- Limit the call to 'x' ms warning when 'y' ms are left (repeated every 'z' ms)\n"
|
" 'L(x[:y][:z])' -- Limit the call to 'x' ms warning when 'y' ms are left (repeated every 'z' ms)\n"
|
||||||
" -- Only 'x' is required, 'y' and 'z' are optional.\n"
|
" -- Only 'x' is required, 'y' and 'z' are optional.\n"
|
||||||
" -- The following special variables are optional:\n"
|
" -- The following special variables are optional:\n"
|
||||||
@@ -410,6 +412,8 @@ static int dial_exec(struct ast_channel *chan, void *data)
|
|||||||
char *start_sound=NULL;
|
char *start_sound=NULL;
|
||||||
char *limitptr;
|
char *limitptr;
|
||||||
char limitdata[256];
|
char limitdata[256];
|
||||||
|
char *sdtmfptr;
|
||||||
|
char sdtmfdata[256] = "";
|
||||||
char *stack,*var;
|
char *stack,*var;
|
||||||
int play_to_caller=0,play_to_callee=0;
|
int play_to_caller=0,play_to_callee=0;
|
||||||
int playargs=0;
|
int playargs=0;
|
||||||
@@ -461,80 +465,97 @@ static int dial_exec(struct ast_channel *chan, void *data)
|
|||||||
ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %i seconds.\n",calldurationlimit);
|
ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %i seconds.\n",calldurationlimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* DTMF SCRIPT*/
|
||||||
|
if ((sdtmfptr = strstr(transfer, "D("))) {
|
||||||
|
strncpy(sdtmfdata, sdtmfptr + 2, sizeof(sdtmfdata) - 1);
|
||||||
|
/* Overwrite with X's what was the sdtmf info */
|
||||||
|
while(*sdtmfptr && (*sdtmfptr != ')'))
|
||||||
|
*(sdtmfptr++) = 'X';
|
||||||
|
if (*sdtmfptr)
|
||||||
|
*sdtmfptr = 'X';
|
||||||
|
/* Now find the end */
|
||||||
|
sdtmfptr = strchr(sdtmfdata, ')');
|
||||||
|
if (sdtmfptr)
|
||||||
|
*sdtmfptr = '\0';
|
||||||
|
else {
|
||||||
|
ast_log(LOG_WARNING, "D( Data lacking trailing ')'\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* XXX LIMIT SUPPORT */
|
/* XXX LIMIT SUPPORT */
|
||||||
if ((limitptr = strstr(transfer, "L("))) {
|
if ((limitptr = strstr(transfer, "L("))) {
|
||||||
strncpy(limitdata, limitptr + 2, sizeof(limitdata) - 1);
|
strncpy(limitdata, limitptr + 2, sizeof(limitdata) - 1);
|
||||||
/* Overwrite with X's what was the limit info */
|
/* Overwrite with X's what was the limit info */
|
||||||
while(*limitptr && (*limitptr != ')'))
|
while(*limitptr && (*limitptr != ')'))
|
||||||
*(limitptr++) = 'X';
|
*(limitptr++) = 'X';
|
||||||
if (*limitptr)
|
if (*limitptr)
|
||||||
*limitptr = 'X';
|
*limitptr = 'X';
|
||||||
/* Now find the end of the privdb */
|
/* Now find the end */
|
||||||
limitptr = strchr(limitdata, ')');
|
limitptr = strchr(limitdata, ')');
|
||||||
if (limitptr)
|
if (limitptr)
|
||||||
*limitptr = '\0';
|
*limitptr = '\0';
|
||||||
else {
|
else {
|
||||||
ast_log(LOG_WARNING, "Limit Data lacking trailing ')'\n");
|
ast_log(LOG_WARNING, "Limit Data lacking trailing ')'\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLER");
|
var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLER");
|
||||||
play_to_caller = var ? ast_true(var) : 1;
|
play_to_caller = var ? ast_true(var) : 1;
|
||||||
|
|
||||||
var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLEE");
|
var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLEE");
|
||||||
play_to_callee = var ? ast_true(var) : 0;
|
play_to_callee = var ? ast_true(var) : 0;
|
||||||
|
|
||||||
if(! play_to_caller && ! play_to_callee)
|
if(! play_to_caller && ! play_to_callee)
|
||||||
play_to_caller=1;
|
play_to_caller=1;
|
||||||
|
|
||||||
var = pbx_builtin_getvar_helper(chan,"LIMIT_WARNING_FILE");
|
var = pbx_builtin_getvar_helper(chan,"LIMIT_WARNING_FILE");
|
||||||
warning_sound = var ? var : "timeleft";
|
warning_sound = var ? var : "timeleft";
|
||||||
|
|
||||||
var = pbx_builtin_getvar_helper(chan,"LIMIT_TIMEOUT_FILE");
|
var = pbx_builtin_getvar_helper(chan,"LIMIT_TIMEOUT_FILE");
|
||||||
end_sound = var ? var : NULL;
|
end_sound = var ? var : NULL;
|
||||||
|
|
||||||
var = pbx_builtin_getvar_helper(chan,"LIMIT_CONNECT_FILE");
|
var = pbx_builtin_getvar_helper(chan,"LIMIT_CONNECT_FILE");
|
||||||
start_sound = var ? var : NULL;
|
start_sound = var ? var : NULL;
|
||||||
|
|
||||||
var=stack=limitdata;
|
var=stack=limitdata;
|
||||||
|
|
||||||
var = strsep(&stack, ":");
|
var = strsep(&stack, ":");
|
||||||
if(var) {
|
if(var) {
|
||||||
timelimit = atol(var);
|
timelimit = atol(var);
|
||||||
playargs++;
|
playargs++;
|
||||||
}
|
var = strsep(&stack, ":");
|
||||||
var = strsep(&stack, ":");
|
if(var) {
|
||||||
if(var) {
|
play_warning = atol(var);
|
||||||
play_warning = atol(var);
|
playargs++;
|
||||||
playargs++;
|
var = strsep(&stack, ":");
|
||||||
}
|
if(var) {
|
||||||
|
warning_freq = atol(var);
|
||||||
|
playargs++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var = strsep(&stack, ":");
|
if(! timelimit) {
|
||||||
if(var) {
|
timelimit=play_to_caller=play_to_callee=play_warning=warning_freq=0;
|
||||||
warning_freq = atol(var);
|
warning_sound=NULL;
|
||||||
playargs++;
|
}
|
||||||
}
|
/* undo effect of S(x) in case they are both used */
|
||||||
|
calldurationlimit=0;
|
||||||
if(! timelimit) {
|
/* more efficient do it like S(x) does since no advanced opts*/
|
||||||
timelimit=play_to_caller=play_to_callee=play_warning=warning_freq=0;
|
if(! play_warning && ! start_sound && ! end_sound && timelimit) {
|
||||||
warning_sound=NULL;
|
calldurationlimit=timelimit/1000;
|
||||||
}
|
timelimit=play_to_caller=play_to_callee=play_warning=warning_freq=0;
|
||||||
calldurationlimit=0; /* undo effect of S(x) in case they are both used */
|
}
|
||||||
/* more efficient do it like S(x) does since no advanced opts*/
|
else if (option_verbose > 2) {
|
||||||
if(! play_warning && ! start_sound && ! end_sound && timelimit) {
|
ast_verbose(VERBOSE_PREFIX_3"Limit Data:\n");
|
||||||
calldurationlimit=timelimit/1000;
|
ast_verbose(VERBOSE_PREFIX_3"timelimit=%ld\n",timelimit);
|
||||||
timelimit=play_to_caller=play_to_callee=play_warning=warning_freq=0;
|
ast_verbose(VERBOSE_PREFIX_3"play_warning=%ld\n",play_warning);
|
||||||
}
|
ast_verbose(VERBOSE_PREFIX_3"play_to_caller=%s\n",play_to_caller ? "yes" : "no");
|
||||||
else {
|
ast_verbose(VERBOSE_PREFIX_3"play_to_callee=%s\n",play_to_callee ? "yes" : "no");
|
||||||
ast_verbose(VERBOSE_PREFIX_3"Limit Data:\n");
|
ast_verbose(VERBOSE_PREFIX_3"warning_freq=%ld\n",warning_freq);
|
||||||
ast_verbose(VERBOSE_PREFIX_3"timelimit=%ld\n",timelimit);
|
ast_verbose(VERBOSE_PREFIX_3"start_sound=%s\n",start_sound ? start_sound : "UNDEF");
|
||||||
ast_verbose(VERBOSE_PREFIX_3"play_warning=%ld\n",play_warning);
|
ast_verbose(VERBOSE_PREFIX_3"warning_sound=%s\n",warning_sound ? warning_sound : "UNDEF");
|
||||||
ast_verbose(VERBOSE_PREFIX_3"play_to_caller=%s\n",play_to_caller ? "yes" : "no");
|
ast_verbose(VERBOSE_PREFIX_3"end_sound=%s\n",end_sound ? end_sound : "UNDEF");
|
||||||
ast_verbose(VERBOSE_PREFIX_3"play_to_callee=%s\n",play_to_callee ? "yes" : "no");
|
}
|
||||||
ast_verbose(VERBOSE_PREFIX_3"warning_freq=%ld\n",warning_freq);
|
|
||||||
ast_verbose(VERBOSE_PREFIX_3"start_sound=%s\n",start_sound ? start_sound : "UNDEF");
|
|
||||||
ast_verbose(VERBOSE_PREFIX_3"warning_sound=%s\n",warning_sound ? warning_sound : "UNDEF");
|
|
||||||
ast_verbose(VERBOSE_PREFIX_3"end_sound=%s\n",end_sound ? end_sound : "UNDEF");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -813,40 +834,51 @@ static int dial_exec(struct ast_channel *chan, void *data)
|
|||||||
ast_log(LOG_DEBUG, "app_dial: sendurl=%s.\n", url);
|
ast_log(LOG_DEBUG, "app_dial: sendurl=%s.\n", url);
|
||||||
ast_channel_sendurl( peer, url );
|
ast_channel_sendurl( peer, url );
|
||||||
} /* /JDG */
|
} /* /JDG */
|
||||||
if (announce && announcemsg)
|
if (announce && announcemsg) {
|
||||||
{
|
|
||||||
int res2;
|
|
||||||
// Start autoservice on the other chan
|
// Start autoservice on the other chan
|
||||||
res2 = ast_autoservice_start(chan);
|
res = ast_autoservice_start(chan);
|
||||||
// Now Stream the File
|
// Now Stream the File
|
||||||
if (!res2)
|
if (!res)
|
||||||
res2 = ast_streamfile(peer,announcemsg,peer->language);
|
res = ast_streamfile(peer,announcemsg,peer->language);
|
||||||
if (!res2)
|
if (!res)
|
||||||
res2 = ast_waitstream(peer,"");
|
res = ast_waitstream(peer,"");
|
||||||
|
|
||||||
// Ok, done. stop autoservice
|
// Ok, done. stop autoservice
|
||||||
res2 = ast_autoservice_stop(chan);
|
res = ast_autoservice_stop(chan);
|
||||||
}
|
}
|
||||||
if (calldurationlimit > 0) {
|
else
|
||||||
time(&now);
|
res = 0;
|
||||||
chan->whentohangup = now + calldurationlimit;
|
|
||||||
|
if(!res) {
|
||||||
|
if (calldurationlimit > 0) {
|
||||||
|
time(&now);
|
||||||
|
chan->whentohangup = now + calldurationlimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(strlen(sdtmfdata))
|
||||||
|
res = ast_dtmf_stream(peer,chan,sdtmfdata,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&config,0,sizeof(struct ast_bridge_config));
|
if(!res) {
|
||||||
config.play_to_caller=play_to_caller;
|
memset(&config,0,sizeof(struct ast_bridge_config));
|
||||||
config.play_to_callee=play_to_callee;
|
config.play_to_caller=play_to_caller;
|
||||||
config.allowredirect_in = allowredir_in;
|
config.play_to_callee=play_to_callee;
|
||||||
config.allowredirect_out = allowredir_out;
|
config.allowredirect_in = allowredir_in;
|
||||||
config.allowdisconnect = allowdisconnect;
|
config.allowredirect_out = allowredir_out;
|
||||||
config.timelimit = timelimit;
|
config.allowdisconnect = allowdisconnect;
|
||||||
config.play_warning = play_warning;
|
config.timelimit = timelimit;
|
||||||
config.warning_freq = warning_freq;
|
config.play_warning = play_warning;
|
||||||
config.warning_sound = warning_sound;
|
config.warning_freq = warning_freq;
|
||||||
config.end_sound = end_sound;
|
config.warning_sound = warning_sound;
|
||||||
config.start_sound = start_sound;
|
config.end_sound = end_sound;
|
||||||
res = ast_bridge_call(chan,peer,&config);
|
config.start_sound = start_sound;
|
||||||
|
res = ast_bridge_call(chan,peer,&config);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
res = -1;
|
||||||
|
|
||||||
if (res != AST_PBX_NO_HANGUP_PEER)
|
if (res != AST_PBX_NO_HANGUP_PEER)
|
||||||
ast_hangup(peer);
|
ast_hangup(peer);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
hanguptree(outgoing, NULL);
|
hanguptree(outgoing, NULL);
|
||||||
|
@@ -43,34 +43,13 @@ static int senddtmf_exec(struct ast_channel *chan, void *data)
|
|||||||
int res = 0;
|
int res = 0;
|
||||||
struct localuser *u;
|
struct localuser *u;
|
||||||
char *digits = data;
|
char *digits = data;
|
||||||
struct ast_frame f;
|
|
||||||
int x;
|
|
||||||
if (!digits || !strlen(digits)) {
|
if (!digits || !strlen(digits)) {
|
||||||
ast_log(LOG_WARNING, "SendDTMF requires an argument (digits or *#abcd)\n");
|
ast_log(LOG_WARNING, "SendDTMF requires an argument (digits or *#aAbBcCdD)\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
LOCAL_USER_ADD(u);
|
LOCAL_USER_ADD(u);
|
||||||
for (x=0;x<strlen(digits);x++) {
|
res = ast_dtmf_stream(chan,NULL,digits,250);
|
||||||
memset(&f, 0, sizeof(f));
|
|
||||||
f.frametype = AST_FRAME_DTMF;
|
|
||||||
f.subclass = digits[x];
|
|
||||||
f.src = "app_senddtmf";
|
|
||||||
if (strchr("0123456789*#abcd",digits[x])==NULL) {
|
|
||||||
ast_log(LOG_WARNING, "Illegal DTMF character in string. (0-9*#abcd allowed)\n");
|
|
||||||
} else {
|
|
||||||
res = ast_write(chan, &f);
|
|
||||||
if (res)
|
|
||||||
break;
|
|
||||||
/* Wait 250ms */
|
|
||||||
res = ast_safe_sleep(chan, 250);
|
|
||||||
if (res)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!res)
|
|
||||||
if (option_verbose > 2)
|
|
||||||
ast_verbose(VERBOSE_PREFIX_3 "Sent digit string '%s' on %s\n", digits, chan->name);
|
|
||||||
|
|
||||||
LOCAL_USER_REMOVE(u);
|
LOCAL_USER_REMOVE(u);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@@ -48,6 +48,9 @@ extern int ast_app_messagecount(const char *mailbox, int *newmsgs, int *oldmsgs)
|
|||||||
//! Safely spawn an external program while closingn file descriptors
|
//! Safely spawn an external program while closingn file descriptors
|
||||||
extern int ast_safe_system(const char *s);
|
extern int ast_safe_system(const char *s);
|
||||||
|
|
||||||
|
// send DTMF to chan (optionally entertain peer)
|
||||||
|
int ast_dtmf_stream(struct ast_channel *chan,struct ast_channel *peer,char *digits,int between);
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user