diff --git a/channels/sig_analog.c b/channels/sig_analog.c index 879007658d..d45644fa1d 100644 --- a/channels/sig_analog.c +++ b/channels/sig_analog.c @@ -2422,6 +2422,7 @@ static void *__analog_ss_thread(void *data) while (len < AST_MAX_EXTENSION-1) { int is_exten_parking = 0; int is_lastnumredial = 0; + int is_endofdialing = 0; /* Read digit unless it's supposed to be immediate, in which case the only answer is 's' */ @@ -2438,8 +2439,27 @@ static void *__analog_ss_thread(void *data) goto quit; } else if (res) { ast_debug(1,"waitfordigit returned '%c' (%d), timeout = %d\n", res, res, timeout); - exten[len++]=res; + exten[len++] = res; exten[len] = '\0'; + if (len > 1 && res == '#' && !ast_exists_extension(chan, ast_channel_context(chan), exten, 1, p->cid_num)) { + /* The user was dialing something that matched, but as soon as he dialed #, we no longer have a match. + * Check if what was dialed immediately prior to the # is an extension that exists. + * If so, we can treat "#" as the end of dialing terminator to allow user to complete the call without a timeout. + * This is fully compatible with the user's dialplan, since we only do this if there isn't a dialplan match. */ + exten[--len] = '\0'; /* Remove '#' from the buffer to test the extension without it */ + if (ast_exists_extension(chan, ast_channel_context(chan), exten, 1, p->cid_num)) { + /* The number dialed prior to the # exists as a valid extension. + * Since the number with # does not exist, treat # as end of dialing. */ + ast_debug(1, "Interpreting '#' as end of dialing\n"); + is_endofdialing = 1; + } else { + /* Even without the #, the number in the buffer is not a valid extension. + * In this case, it's still invalid; do nothing special. + * We simply reverse the removal of '#' from the buffer, i.e. we append it again. */ + exten[len++] = res; + exten[len ] = '\0'; + } + } } if (!ast_ignore_pattern(ast_channel_context(chan), exten)) { analog_play_tone(p, idx, -1); @@ -2468,7 +2488,7 @@ static void *__analog_ss_thread(void *data) } } if (ast_exists_extension(chan, ast_channel_context(chan), exten, 1, p->cid_num) && !is_exten_parking) { - if (!res || is_lastnumredial || !ast_matchmore_extension(chan, ast_channel_context(chan), exten, 1, p->cid_num)) { + if (!res || is_lastnumredial || is_endofdialing || !ast_matchmore_extension(chan, ast_channel_context(chan), exten, 1, p->cid_num)) { if (getforward) { /* Record this as the forwarding extension */ analog_lock_private(p);