From 511d22ef5ee39461a69e0edc9d59ca5b702d0261 Mon Sep 17 00:00:00 2001 From: zhou_jiajian Date: Thu, 24 Jul 2025 19:39:27 +0800 Subject: [PATCH] cdr: add CANCEL dispostion in CDR In the original implementation, both CANCEL and NO ANSWER states were consolidated under the NO ANSWER disposition. This patch introduces a separate CANCEL disposition, with an optional configuration switch to enable this new disposition. Resolves: #1323 UserNote: A new CDR option "canceldispositionenabled" has been added that when set to true, the NO ANSWER disposition will be split into two dispositions: CANCEL and NO ANSWER. The default value is 'no' --- configs/samples/cdr.conf.sample | 6 ++++++ include/asterisk/cdr.h | 2 ++ main/cdr.c | 20 +++++++++++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/configs/samples/cdr.conf.sample b/configs/samples/cdr.conf.sample index 46ddb96b7d..459a3861c1 100644 --- a/configs/samples/cdr.conf.sample +++ b/configs/samples/cdr.conf.sample @@ -96,6 +96,12 @@ ; is "yes". ;safeshutdown=yes +; Define if the CANCEL disposition state should be used. +; When enabled, The NO ANSWER disposition will be split into two distinct +; dispositions: CANCEL and NO ANSWER. +; The default value is "no". +;canceldispositionenabled = no + ; ; ; CHOOSING A CDR "BACKEND" (what kind of output to generate) diff --git a/include/asterisk/cdr.h b/include/asterisk/cdr.h index 788a879720..14f644a2cd 100644 --- a/include/asterisk/cdr.h +++ b/include/asterisk/cdr.h @@ -227,6 +227,7 @@ enum ast_cdr_settings { CDR_CHANNEL_DEFAULT_ENABLED = 1 << 7, /*!< Whether CDR is enabled for each channel by default */ CDR_IGNORE_STATE_CHANGES = 1 << 8, /*!< Whether to ignore bridge and other call state change events */ CDR_IGNORE_DIAL_CHANGES = 1 << 9, /*!< Whether to ignore dial state changes */ + CDR_CANCEL_DISPOSITION_ENABLED = 1 << 10, /*!< Whether to enable CANCEL disposition in CDR */ }; /*! \brief CDR Batch Mode settings */ @@ -260,6 +261,7 @@ enum ast_cdr_disposition { AST_CDR_BUSY = (1 << 2), AST_CDR_ANSWERED = (1 << 3), AST_CDR_CONGESTION = (1 << 4), + AST_CDR_CANCEL = (1 << 5), }; diff --git a/main/cdr.c b/main/cdr.c index e4018fbd10..bae1feec17 100644 --- a/main/cdr.c +++ b/main/cdr.c @@ -273,6 +273,14 @@ submission of CDR data during asterisk shutdown, set this to yes. + + Whether to enable CANCEL disposition in CDR + + Define if the CANCEL disposition state should be used. + When enabled, The NO ANSWER disposition will be split into two distinct dispositions: CANCEL and NO ANSWER. + + + @@ -1927,7 +1935,13 @@ static enum ast_cdr_disposition dial_status_to_disposition(const char *dial_stat return AST_CDR_ANSWERED; } else if (!strcmp(dial_status, "BUSY")) { return AST_CDR_BUSY; - } else if (!strcmp(dial_status, "CANCEL") || !strcmp(dial_status, "NOANSWER")) { + } else if (!strcmp(dial_status, "CANCEL")) { + if (!is_cdr_flag_set(CDR_CANCEL_DISPOSITION_ENABLED)) { + return AST_CDR_NOANSWER; + } else { + return AST_CDR_CANCEL; + } + } else if (!strcmp(dial_status, "NOANSWER")) { return AST_CDR_NOANSWER; } else if (!strcmp(dial_status, "CONGESTION")) { if (!is_cdr_flag_set(CDR_CONGESTION)) { @@ -3574,6 +3588,8 @@ const char *ast_cdr_disp2str(int disposition) return "ANSWERED"; case AST_CDR_CONGESTION: return "CONGESTION"; + case AST_CDR_CANCEL: + return "CANCEL"; } return "UNKNOWN"; } @@ -4312,6 +4328,7 @@ static char *handle_cli_status(struct ast_cli_entry *e, int cmd, struct ast_cli_ ast_cli(a->fd, " Log congestion: %s\n\n", ast_test_flag(&mod_cfg->general->settings, CDR_CONGESTION) ? "Yes" : "No"); ast_cli(a->fd, " Ignore bridging changes: %s\n\n", ast_test_flag(&mod_cfg->general->settings, CDR_IGNORE_STATE_CHANGES) ? "Yes" : "No"); ast_cli(a->fd, " Ignore dial state changes: %s\n\n", ast_test_flag(&mod_cfg->general->settings, CDR_IGNORE_DIAL_CHANGES) ? "Yes" : "No"); + ast_cli(a->fd, " Cancel disposition enabled: %s\n\n", ast_test_flag(&mod_cfg->general->settings, CDR_CANCEL_DISPOSITION_ENABLED) ? "Yes" : "No"); if (ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE)) { ast_cli(a->fd, "* Batch Mode Settings\n"); ast_cli(a->fd, " -------------------\n"); @@ -4493,6 +4510,7 @@ static int process_config(int reload) aco_option_register(&cfg_info, "channeldefaultenabled", ACO_EXACT, general_options, DEFAULT_CHANNEL_ENABLED, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, settings), CDR_CHANNEL_DEFAULT_ENABLED); aco_option_register(&cfg_info, "ignorestatechanges", ACO_EXACT, general_options, DEFAULT_IGNORE_STATE_CHANGES, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, settings), CDR_IGNORE_STATE_CHANGES); aco_option_register(&cfg_info, "ignoredialchanges", ACO_EXACT, general_options, DEFAULT_IGNORE_DIAL_CHANGES, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, settings), CDR_IGNORE_DIAL_CHANGES); + aco_option_register(&cfg_info, "canceldispositionenabled", ACO_EXACT, general_options, "0", OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, settings), CDR_CANCEL_DISPOSITION_ENABLED); } if (aco_process_config(&cfg_info, reload) == ACO_PROCESS_ERROR) {