From b5138fccf441ed814b2b0aadb7cd1bae9dc93fef Mon Sep 17 00:00:00 2001 From: Richard Mudgett Date: Fri, 28 Sep 2012 18:27:02 +0000 Subject: Add pause one second W dial modifier. * The following dialplan applications now recognize 'W' to pause sending DTMF for one second in addition to the previously existing 'w' that paused sending DTMF for half a second. Dial, ExternalIVR, and SendDTMF. * The chan_dahdi analog port dialing and deferred DTMF dialing for PRI now distinguishes between 'w' and 'W'. The 'w' pauses dialing for half a second. The 'W' pauses dialing for one second. * Created dahdi_dial_str() in chan_dahdi that eliminated a lot of duplicated dialing code and diagnostic messages for the channel driver. (closes issue ASTERISK-20039) Reported by: Jeremiah Gowdy Patches: jgowdy-wait-6-22-2012.diff (license #5621) patch uploaded by Jeremiah Gowdy Expanded patch to add support in chan_dahdi. Tested by: rmudgett git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@374030 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- UPGRADE.txt | 17 +++++++ apps/app_senddtmf.c | 2 +- channels/chan_dahdi.c | 126 +++++++++++++++++++++++++++++--------------------- channels/sig_analog.c | 19 ++------ main/app.c | 5 ++ 5 files changed, 101 insertions(+), 68 deletions(-) diff --git a/UPGRADE.txt b/UPGRADE.txt index 73e67ff42..dd5ce7c76 100644 --- a/UPGRADE.txt +++ b/UPGRADE.txt @@ -32,6 +32,23 @@ Queue: - Queue logging for PAUSEALL/UNPAUSEALL now only occurs if the interface this is performed on is a member of at least one queue. +Dial: + - Now recognizes 'W' to pause sending DTMF for one second in addition to + the previously existing 'w' that paused sending DTMF for half a second. + +ExternalIVR: + - Now recognizes 'W' to pause sending DTMF for one second in addition to + the previously existing 'w' that paused sending DTMF for half a second. + +SendDTMF: + - Now recognizes 'W' to pause sending DTMF for one second in addition to + the previously existing 'w' that paused sending DTMF for half a second. + +chan_dahdi: + - Analog port dialing and deferred DTMF dialing for PRI now distinguishes + between 'w' and 'W'. The 'w' pauses dialing for half a second. The 'W' + pauses dialing for one second. + From 10 to 11: Voicemail: diff --git a/apps/app_senddtmf.c b/apps/app_senddtmf.c index 7db9a3f4b..be70d7b0f 100644 --- a/apps/app_senddtmf.c +++ b/apps/app_senddtmf.c @@ -47,7 +47,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") List of digits 0-9,*#,a-d,A-D to send also w for a half second pause, - and f or F for a flash-hook if the channel supports + W for a one second pause, and f or F for a flash-hook if the channel supports flash-hook. diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c index 8506b01c4..f669e2ead 100644 --- a/channels/chan_dahdi.c +++ b/channels/chan_dahdi.c @@ -1738,6 +1738,60 @@ static int analogsub_to_dahdisub(enum analog_sub analogsub) return index; } +/*! + * \internal + * \brief Send a dial string to DAHDI. + * \since 12.0.0 + * + * \param pvt DAHDI private pointer + * \param operation DAHDI dial operation to do to string + * \param dial_str Dial string to send + * + * \retval 0 on success. + * \retval non-zero on error. + */ +static int dahdi_dial_str(struct dahdi_pvt *pvt, int operation, const char *dial_str) +{ + int res; + int offset; + const char *pos; + struct dahdi_dialoperation zo = { + .op = operation, + }; + + /* Convert the W's to ww. */ + pos = dial_str; + for (offset = 0; offset < sizeof(zo.dialstr) - 1; ++offset) { + if (!*pos) { + break; + } + if (*pos == 'W') { + /* Convert 'W' to "ww" */ + ++pos; + if (offset >= sizeof(zo.dialstr) - 3) { + /* No room to expand */ + break; + } + zo.dialstr[offset] = 'w'; + ++offset; + zo.dialstr[offset] = 'w'; + continue; + } + zo.dialstr[offset] = *pos++; + } + /* The zo initialization has already terminated the dialstr. */ + + ast_debug(1, "Channel %d: Dial str '%s' expanded to '%s' sent to DAHDI_DIAL.\n", + pvt->channel, dial_str, zo.dialstr); + res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_DIAL, &zo); + if (res) { + ast_log(LOG_WARNING, "Channel %d: Couldn't dial '%s': %s\n", + pvt->channel, dial_str, strerror(errno)); + } + + return res; +} + static enum analog_event dahdievent_to_analogevent(int event); static int bump_gains(struct dahdi_pvt *p); static int dahdi_setlinear(int dfd, int linear); @@ -2792,19 +2846,13 @@ static void my_pri_ss7_open_media(void *p) */ static void my_pri_dial_digits(void *p, const char *dial_string) { - struct dahdi_dialoperation zo = { - .op = DAHDI_DIAL_OP_APPEND, - }; + char dial_str[DAHDI_MAX_DTMF_BUF]; struct dahdi_pvt *pvt = p; int res; - snprintf(zo.dialstr, sizeof(zo.dialstr), "T%s", dial_string); - ast_debug(1, "Channel %d: Sending '%s' to DAHDI_DIAL.\n", pvt->channel, zo.dialstr); - res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_DIAL, &zo); - if (res) { - ast_log(LOG_WARNING, "Channel %d: Couldn't dial '%s': %s\n", - pvt->channel, dial_string, strerror(errno)); - } else { + snprintf(dial_str, sizeof(dial_str), "T%s", dial_string); + res = dahdi_dial_str(pvt, DAHDI_DIAL_OP_APPEND, dial_str); + if (!res) { pvt->dialing = 1; } } @@ -3095,10 +3143,7 @@ static int my_start(void *pvt) static int my_dial_digits(void *pvt, enum analog_sub sub, struct analog_dialoperation *dop) { - int index = analogsub_to_dahdisub(sub); - int res; struct dahdi_pvt *p = pvt; - struct dahdi_dialoperation ddop; if (dop->op != ANALOG_DIAL_OP_REPLACE) { ast_log(LOG_ERROR, "Fix the dial_digits callback!\n"); @@ -3111,17 +3156,7 @@ static int my_dial_digits(void *pvt, enum analog_sub sub, struct analog_dialoper return -1; } - ddop.op = DAHDI_DIAL_OP_REPLACE; - ast_copy_string(ddop.dialstr, dop->dialstr, sizeof(ddop.dialstr)); - - ast_debug(1, "Channel %d: Sending '%s' to DAHDI_DIAL.\n", p->channel, ddop.dialstr); - - res = ioctl(p->subs[index].dfd, DAHDI_DIAL, &ddop); - if (res == -1) { - ast_debug(1, "DAHDI_DIAL ioctl failed on %s: %s\n", ast_channel_name(p->owner), strerror(errno)); - } - - return res; + return dahdi_dial_str(p, DAHDI_DIAL_OP_REPLACE, dop->dialstr); } static void dahdi_train_ec(struct dahdi_pvt *p); @@ -4635,18 +4670,12 @@ static int dahdi_digit_begin(struct ast_channel *chan, char digit) goto out; if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &dtmf)) { - struct dahdi_dialoperation zo = { - .op = DAHDI_DIAL_OP_APPEND, - }; + char dial_str[] = { 'T', digit, '\0' }; - zo.dialstr[0] = 'T'; - zo.dialstr[1] = digit; - zo.dialstr[2] = '\0'; - if ((res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_DIAL, &zo))) - ast_log(LOG_WARNING, "Channel %s couldn't dial digit %c: %s\n", - ast_channel_name(chan), digit, strerror(errno)); - else + res = dahdi_dial_str(pvt, DAHDI_DIAL_OP_APPEND, dial_str); + if (!res) { pvt->dialing = 1; + } } else { ast_debug(1, "Channel %s started VLDTMF digit '%c'\n", ast_channel_name(chan), digit); @@ -8196,7 +8225,7 @@ static struct ast_frame *dahdi_handle_event(struct ast_channel *ast) dahdi_train_ec(p); ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr)); p->dop.op = DAHDI_DIAL_OP_REPLACE; - res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop); + res = dahdi_dial_str(p, p->dop.op, p->dop.dialstr); p->echobreak = 0; } else { p->dialing = 0; @@ -8431,14 +8460,11 @@ static struct ast_frame *dahdi_handle_event(struct ast_channel *ast) p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0'; } else p->echobreak = 0; - if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop)) { - int saveerr = errno; - + if (dahdi_dial_str(p, p->dop.op, p->dop.dialstr)) { x = DAHDI_ONHOOK; ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); - ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(saveerr)); return NULL; - } + } p->dialing = 1; return &p->subs[idx].f; } @@ -8470,9 +8496,8 @@ static struct ast_frame *dahdi_handle_event(struct ast_channel *ast) p->subs[idx].f.subclass.integer = 0; } else if (!ast_strlen_zero(p->dop.dialstr)) { /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */ - res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop); - if (res < 0) { - ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno)); + res = dahdi_dial_str(p, p->dop.op, p->dop.dialstr); + if (res) { p->dop.dialstr[0] = '\0'; return NULL; } else { @@ -8843,9 +8868,8 @@ winkflashdone: case SIG_EMWINK: /* FGD MF and EMWINK *Must* wait for wink */ if (!ast_strlen_zero(p->dop.dialstr)) { - res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop); - if (res < 0) { - ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno)); + res = dahdi_dial_str(p, p->dop.op, p->dop.dialstr); + if (res) { p->dop.dialstr[0] = '\0'; return NULL; } else @@ -8873,9 +8897,8 @@ winkflashdone: case SIG_SFWINK: case SIG_SF_FEATD: if (!ast_strlen_zero(p->dop.dialstr)) { - res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop); - if (res < 0) { - ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno)); + res = dahdi_dial_str(p, p->dop.op, p->dop.dialstr); + if (res) { p->dop.dialstr[0] = '\0'; return NULL; } else @@ -9473,9 +9496,8 @@ static struct ast_frame *dahdi_read(struct ast_channel *ast) ast_dsp_set_features(p->dsp, p->dsp_features); ast_debug(1, "Got 10 samples of dialtone!\n"); if (!ast_strlen_zero(p->dop.dialstr)) { /* Dial deferred digits */ - res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop); - if (res < 0) { - ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); + res = dahdi_dial_str(p, p->dop.op, p->dop.dialstr); + if (res) { p->dop.dialstr[0] = '\0'; ast_mutex_unlock(&p->lock); ast_frfree(f); diff --git a/channels/sig_analog.c b/channels/sig_analog.c index 79e8e7cb2..395f1a520 100644 --- a/channels/sig_analog.c +++ b/channels/sig_analog.c @@ -1257,10 +1257,7 @@ int analog_call(struct analog_pvt *p, struct ast_channel *ast, const char *rdest analog_set_waitingfordt(p, ast); if (!res) { if (analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop)) { - int saveerr = errno; - analog_on_hook(p); - ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(saveerr)); return -1; } } else { @@ -2767,10 +2764,7 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_ analog_train_echocanceller(p); ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr)); p->dop.op = ANALOG_DIAL_OP_REPLACE; - if (analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop)) { - int dial_err = errno; - ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(dial_err)); - } + analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop); p->echobreak = 0; } else { analog_set_dialing(p, 0); @@ -2963,9 +2957,7 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_ p->echobreak = 0; } if (analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop)) { - int saveerr = errno; analog_on_hook(p); - ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(saveerr)); return NULL; } analog_set_dialing(p, 1); @@ -2999,8 +2991,7 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_ } else if (!ast_strlen_zero(p->dop.dialstr)) { /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */ res = analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop); - if (res < 0) { - ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno)); + if (res) { p->dop.dialstr[0] = '\0'; return NULL; } else { @@ -3409,8 +3400,7 @@ winkflashdone: /* FGD MF and EMWINK *Must* wait for wink */ if (!ast_strlen_zero(p->dop.dialstr)) { res = analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop); - if (res < 0) { - ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno)); + if (res) { p->dop.dialstr[0] = '\0'; return NULL; } else { @@ -3441,8 +3431,7 @@ winkflashdone: case ANALOG_SIG_SF_FEATD: if (!ast_strlen_zero(p->dop.dialstr)) { res = analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop); - if (res < 0) { - ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno)); + if (res) { p->dop.dialstr[0] = '\0'; return NULL; } else { diff --git a/main/app.c b/main/app.c index 8f90ddf7e..875bed1d5 100644 --- a/main/app.c +++ b/main/app.c @@ -757,6 +757,11 @@ int ast_dtmf_stream(struct ast_channel *chan, struct ast_channel *peer, const ch if ((res = ast_safe_sleep(chan, 500))) { break; } + } else if (*ptr == 'W') { + /* 'W' -- wait a second */ + if ((res = ast_safe_sleep(chan, 1000))) { + break; + } } else if (strchr("0123456789*#abcdfABCDF", *ptr)) { if (*ptr == 'f' || *ptr == 'F') { /* ignore return values if not supported by channel */ -- cgit v1.2.3