]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
app_dial: Fix progress timeout.
authorNaveen Albert <asterisk@phreaknet.org>
Thu, 3 Oct 2024 21:33:39 +0000 (17:33 -0400)
committerAsterisk Development Team <asteriskteam@digium.com>
Thu, 14 Nov 2024 20:01:34 +0000 (20:01 +0000)
Under some circumstances, the progress timeout feature added in commit
320c98eec87c473bfa814f76188a37603ea65ddd does not work as expected,
such as if there is no media flowing. Adjust the waitfor call to
explicitly use the progress timeout if it would be reached sooner than
the answer timeout to ensure we handle the timers properly.

Resolves: #821
(cherry picked from commit 97dfe4cd4044f56b3b0a474f1a682a1f73de1a0f)

apps/app_dial.c

index f24419137688bbb71b4dc4018f4deaa883c485ae..252539d615532b1e22fe79030f7874b50ccfc694 100644 (file)
@@ -1214,7 +1214,6 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
        struct cause_args num = *num_in;
        int prestart = num.busy + num.congestion + num.nochan;
        int orig_answer_to = *to_answer;
-       int progress_to_dup = *to_progress;
        int orig_progress_to = *to_progress;
        struct ast_channel *peer = NULL;
        struct chanlist *outgoing = AST_LIST_FIRST(out_chans);
@@ -1259,7 +1258,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
 
        is_cc_recall = ast_cc_is_recall(in, &cc_recall_core_id, NULL);
 
-       while ((*to_answer = ast_remaining_ms(start, orig_answer_to)) && (*to_progress = ast_remaining_ms(start, progress_to_dup)) && !peer) {
+       while ((*to_answer = ast_remaining_ms(start, orig_answer_to)) && (*to_progress = ast_remaining_ms(start, orig_progress_to)) && !peer) {
                struct chanlist *o;
                int pos = 0; /* how many channels do we handle */
                int numlines = prestart;
@@ -1291,7 +1290,10 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
                        }
                        SCOPE_EXIT_RTN_VALUE(NULL, "%s: No outgoing channels available\n", ast_channel_name(in));
                }
-               winner = ast_waitfor_n(watchers, pos, to_answer);
+
+               /* If progress timeout is active, use that if it's the shorter of the 2 timeouts. */
+               winner = ast_waitfor_n(watchers, pos, *to_progress > 0 && *to_progress < *to_answer ? to_progress : to_answer);
+
                AST_LIST_TRAVERSE(out_chans, o, node) {
                        int res = 0;
                        struct ast_frame *f;
@@ -1506,7 +1508,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
                                         */
                                        ++num_ringing;
                                        *to_progress = -1;
-                                       progress_to_dup = -1;
+                                       orig_progress_to = -1;
                                        if (ignore_cc || cc_frame_received || num_ringing == numlines) {
                                                ast_verb(3, "%s is ringing\n", ast_channel_name(c));
                                                /* Setup early media if appropriate */
@@ -1551,7 +1553,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
                                                }
                                        }
                                        *to_progress = -1;
-                                       progress_to_dup = -1;
+                                       orig_progress_to = -1;
                                        if (!sent_progress) {
                                                struct timeval now, then;
                                                int64_t diff;
@@ -1741,7 +1743,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
                                        break;
                                }
                                *to_progress = -1;
-                               progress_to_dup = -1;
+                               orig_progress_to = -1;
                                /* Fall through */
                        case AST_FRAME_TEXT:
                                if (single && ast_write(in, f)) {