Index: apps/app_dial.c =================================================================== RCS file: /usr/cvsroot/asterisk/apps/app_dial.c,v retrieving revision 1.128 diff -u -r1.128 app_dial.c --- apps/app_dial.c 18 Jan 2005 03:12:53 -0000 1.128 +++ apps/app_dial.c 18 Jan 2005 09:56:13 -0000 @@ -60,6 +60,8 @@ " This application returns -1 if the originating channel hangs up, or if the\n" "call is bridged and either of the parties in the bridge terminate the call.\n" "The option string may contain zero or more of the following characters:\n" +" 'c' -- confirm of answer with key 9\n" +" 'v(x)' -- verbose message when the user answer (only with work with flag c)\n" " 'd' -- allow the calling user to dial a 1 digit extension while waiting for a call to\n" " be answered exiting to that extension if it exists in the context defined by\n" " ${EXITCONTEXT} or the current context.\n" @@ -145,6 +147,7 @@ #define DIAL_MONITOR_OUT (1 << 9) #define DIAL_GO_ON (1 << 10) #define DIAL_HALT_ON_DTMF (1 << 11) +#define DIAL_CONFIRM (1 << 12) struct localuser { struct ast_channel *chan; @@ -217,7 +220,7 @@ } -static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localuser *outgoing, int *to, struct ast_flags *peerflags, int *sentringing, char *status, size_t statussize, int busystart, int nochanstart, int congestionstart, int *result) +static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localuser *outgoing, int *to, struct ast_flags *peerflags, int *sentringing, char *status, size_t statussize, int busystart, int nochanstart, int congestionstart,int announceconfirm,char *announceconfirmmsg, int *result) { struct localuser *o; int found; @@ -235,6 +238,8 @@ int single; struct ast_channel *winner; char *context = NULL; + int intAccepted = 0; + int res; single = (outgoing && !outgoing->next && !ast_test_flag(outgoing, DIAL_MUSICONHOLD | DIAL_RINGBACKONLY)); @@ -246,7 +251,7 @@ } - while (*to && !peer) { + while(*to && (!peer || (intAccepted == 0 && ast_test_flag(outgoing, DIAL_CONFIRM)))) { o = outgoing; found = -1; pos = 1; @@ -274,6 +279,8 @@ /* See if there is a special busy message */ if (ast_exists_extension(in, in->context, in->exten, in->priority + 101, in->cid.cid_num)) in->priority+=100; + if (ast_test_flag(outgoing, DIAL_CONFIRM)) + intAccepted = -1; } else { if (option_verbose > 2) ast_verbose( VERBOSE_PREFIX_2 "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, numbusy, numcongestion, numnochan); @@ -284,7 +291,7 @@ winner = ast_waitfor_n(watchers, pos, to); o = outgoing; while (o) { - if (ast_test_flag(o, DIAL_STILLGOING) && o->chan && (o->chan->_state == AST_STATE_UP)) { + if (ast_test_flag(o, DIAL_STILLGOING) && o->chan && (o->chan->_state == AST_STATE_UP) && (intAccepted != 0 || !ast_test_flag(outgoing, DIAL_CONFIRM))) { if (!peer) { if (option_verbose > 2) ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", o->chan->name, in->name); @@ -391,15 +398,36 @@ } f = ast_read(winner); if (f) { - if (f->frametype == AST_FRAME_CONTROL) { + if (f->frametype == AST_FRAME_DTMF) { switch(f->subclass) { - case AST_CONTROL_ANSWER: + case '9': + peer = winner; + intAccepted = 1; + } + } else if (f->frametype == AST_FRAME_CONTROL) { + switch(f->subclass) { + case AST_CONTROL_HANGUP: + in->hangupcause = winner->hangupcause; + ast_hangup(winner); + winner = NULL; + ast_clear_flag(o, DIAL_STILLGOING); + break; + case AST_CONTROL_ANSWER: /* This is our guy if someone answered. */ if (!peer) { if (option_verbose > 2) ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", o->chan->name, in->name); - peer = o->chan; ast_copy_flags(peerflags, o, DIAL_ALLOWREDIRECT_IN|DIAL_ALLOWREDIRECT_OUT|DIAL_ALLOWDISCONNECT_IN|DIAL_ALLOWDISCONNECT_OUT); + if (ast_test_flag(outgoing, DIAL_CONFIRM)) { + if (announceconfirm && announceconfirmmsg) { + res = ast_streamfile(winner, announceconfirmmsg, winner->language); + if (!res) + res = ast_waitstream(winner, ""); + } + } + if (!ast_test_flag(outgoing, DIAL_CONFIRM)) { + peer = o->chan; + } } /* If call has been answered, then the eventual hangup is likely to be normal hangup */ in->hangupcause = AST_CAUSE_NORMAL_CLEARING; @@ -545,12 +573,14 @@ char *info, *peers, *timeout, *tech, *number, *rest, *cur; char privdb[256] = "", *s; char announcemsg[256] = "", *ann; + char announceconfirmmsg[254] = "", *annconfirm; struct localuser *outgoing=NULL, *tmp; struct ast_channel *peer; int to; int hasmacro = 0; int privacy=0; int announce=0; + int announceconfirm=0; int resetcdr=0; int numbusy = 0; int numcongestion = 0; @@ -658,6 +688,26 @@ ast_log(LOG_WARNING, "D( Data lacking trailing ')'\n"); } + /* XXX ANNOUNCE CONFIRM SUPPORT */ + if ((annconfirm = strstr(transfer, "v("))) { + announceconfirm = 1; + strncpy(announceconfirmmsg, annconfirm + 2, sizeof(announceconfirmmsg) - 1); + /* Overwrite with X's what was the announce info */ + while(*annconfirm && (*annconfirm != ')')) + *(annconfirm++) = 'X'; + if (*annconfirm) + *annconfirm = 'X'; + /* Now find the end of the privdb */ + annconfirm = strchr(announceconfirmmsg, ')'); + if (annconfirm) + *annconfirm = '\0'; + else { + ast_log(LOG_WARNING, "Transfer with Announce confirm spec lacking trailing ')'\n"); + announceconfirm = 0; + } + } + + /* XXX LIMIT SUPPORT */ if ((limitptr = strstr(transfer, "L("))) { strncpy(limitdata, limitptr + 2, sizeof(limitdata) - 1); @@ -855,6 +905,7 @@ } memset(tmp, 0, sizeof(struct localuser)); if (transfer) { + ast_set2_flag(tmp, strchr(transfer, 'c'), DIAL_CONFIRM); ast_set2_flag(tmp, strchr(transfer, 't'), DIAL_ALLOWREDIRECT_IN); ast_set2_flag(tmp, strchr(transfer, 'T'), DIAL_ALLOWREDIRECT_OUT); ast_set2_flag(tmp, strchr(transfer, 'r'), DIAL_RINGBACKONLY); @@ -1027,7 +1078,7 @@ strncpy(status, "CHANUNAVAIL", sizeof(status) - 1); time(&start_time); - peer = wait_for_answer(chan, outgoing, &to, peerflags, &sentringing, status, sizeof(status), numbusy, numnochan, numcongestion, &result); + peer = wait_for_answer(chan, outgoing, &to, peerflags, &sentringing, status, sizeof(status), numbusy, numnochan, numcongestion, announceconfirm, announceconfirmmsg, &result); if (!peer) { if (result) {