Commit ee51d78c68 for asterisk.org

commit ee51d78c68f8fa0d7aa4f99a5a3f93f5ebb4a8b0
Author: Evgeniy Kravtsov <ek@oborona.net>
Date:   Fri Sep 25 22:05:01 2026 +0500

    cdr: Preserve ANSWERED disposition with ignoredialchanges

    When ignoredialchanges is enabled, Dial End events update the
    disposition of the single CDR. With calls that dial multiple
    destinations, such as Queue(), one destination can answer while
    other dialed channels are subsequently cancelled.

    Those later Dial End events currently overwrite ANSWERED with a
    non-answer disposition even though the call was answered.

    Once the CDR reaches AST_CDR_ANSWERED, retain that disposition while
    dial changes are ignored.

    Fixes: #2181

    UserNote: With ignoredialchanges enabled, answered calls retain an
    ANSWERED disposition when later dial attempts end without answer.

diff --git a/main/cdr.c b/main/cdr.c
index bae1feec17..504a6c7767 100644
--- a/main/cdr.c
+++ b/main/cdr.c
@@ -2283,9 +2283,14 @@ static void handle_dial_message(void *data, struct stasis_subscription *sub, str
 				continue;
 			}
 			if (dial_changes_ignored) {
-				/* Set the disposition, and do nothing else. */
-				it_cdr->disposition = dial_status_to_disposition(dial_status);
-				CDR_DEBUG("%p - Setting disposition and that's it (%s)\n", it_cdr, dial_status);
+				/*
+				 * Once a dial has been answered, later non-answer Dial End events
+				 * must not downgrade the CDR disposition.
+				 */
+				if (it_cdr->disposition != AST_CDR_ANSWERED) {
+					it_cdr->disposition = dial_status_to_disposition(dial_status);
+				}
+				CDR_DEBUG("%p - Handling disposition only (%s)\n", it_cdr, dial_status);
 				continue;
 			}
 			CDR_DEBUG("%p - Processing Dial End message for channel %s, peer %s\n",