--- res_agi.c (revision 207352) +++ res_agi.c (working copy) @@ -686,13 +686,21 @@ + + + + Waits up to timeout milliseconds for channel to receive a DTMF digit. Returns -1 on channel failure, 0 if no digit is received in the timeout, or the numerical value of the ascii of the digit if one is received. Use -1 for the timeout value if - you desire the call to block indefinitely. + you desire the call to block indefinitely. + + If 'voicefile' is specified it is played as long 'previously die chars' (default '#') are + not typed in or as long as any of 'escape chars' (default '1234567890*#ABCD') is pressed a + 'maxdigit' (default 1) times . @@ -1602,14 +1610,97 @@ static int handle_waitfordigit(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[]) { - int res, to; + int res; + int to; + char *valid_dtmf_digits = AST_DIGIT_ANY; + char *previously_die_on = "#"; + char *digits = NULL; + char *escape_digits = NULL; + char *voicefile = NULL; + int maxdigits = 1; - if (argc != 4) + if (argc < 4) return RESULT_SHOWUSAGE; if (sscanf(argv[3], "%d", &to) != 1) return RESULT_SHOWUSAGE; - res = ast_waitfordigit_full(chan, to, agi->audio, agi->ctrl); - ast_agi_send(agi->fd, chan, "200 result=%d\n", res); + + if (chan->_state != AST_STATE_UP) { + /* Answer the chan */ + res = ast_answer(chan); + } + + if (argc >= 5) { + // soundfile specified + + if (argc >= 6) + { + // escape characters defined + valid_dtmf_digits = (char *) argv[5]; + } + + if (argc >= 7) { + // maxdigits + if (sscanf(argv[6], "%d", &maxdigits) != 1) + return RESULT_SHOWUSAGE; + } + + if (argc >= 8) { + // escape before escape chars on + previously_die_on = (char *) argv[7]; + } + + voicefile = (char *) argv[4]; + res = ast_streamfile(chan, voicefile, chan->language); + if (res < 0) + return RESULT_FAILURE; + + // allocate space for the digits (2 chars per digit + \0 - ||...) + digits = (char *)ast_malloc(maxdigits * 2 + 1); + ast_copy_string(digits, "", 1); + + // catenate the escape digits together with previously die digits + escape_digits = (char *)ast_malloc(strlen(valid_dtmf_digits) + strlen(previously_die_on)+ 1); + ast_copy_string(escape_digits, valid_dtmf_digits, sizeof(valid_dtmf_digits)); + strcat(escape_digits, previously_die_on); + + if (chan->stream) + { + int dtmf_count = 0; + do { + char buf[3]; + res = ast_waitstream_full(chan, escape_digits, agi->audio, agi->ctrl); + + if (res > 0) { + if (strchr(previously_die_on, res) != NULL) { + // previously die character found - end loop + + ast_log(LOG_DEBUG, "prev die digit %c pressed\n", res); + break; + } else { + // chars in valid_dtmf_digits found + + ast_log(LOG_DEBUG, "dtmf turn=%d of %d | res=%d\n", dtmf_count, maxdigits, res); + sprintf(buf, "%c|", res); + strcat(digits, buf); + dtmf_count++; + } + } + } while ( strchr(previously_die_on, res) == NULL && dtmf_count < maxdigits && chan->stream); + ast_stopstream(chan); + + ast_agi_send(agi->fd, chan, "200 result=%s\n", digits); + } else { + res = ast_waitfordigit_full(chan, to, agi->audio, agi->ctrl); + ast_agi_send(agi->fd, chan, "200 result=%c\n", res); + } + } else { + res = ast_waitfordigit_full(chan, to, agi->audio, agi->ctrl); + ast_agi_send(agi->fd, chan, "200 result=%c\n", res); + } + + ast_free(escape_digits); + ast_free(digits); + return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; }