[Asterisk-code-review] cdr: Allow bridging and dial state changes to be ignored. (asterisk[master])

N A asteriskteam at digium.com
Wed Jun 1 11:07:23 CDT 2022


N A has uploaded this change for review. ( https://gerrit.asterisk.org/c/asterisk/+/18603 )


Change subject: cdr: Allow bridging and dial state changes to be ignored.
......................................................................

cdr: Allow bridging and dial state changes to be ignored.

Allows bridging, parking, and dial messages to be globally
ignored for all CDRs.

This is useful when CDRs should endure for the lifetime of
an entire channel and bridging and dial updates in the
dialplan should not affect the CDR in any way. This can
reduce the amount of "CDR hacks" that were previously
needed to ensure that CDR was not "spoiled" by these
messages if that was undesired, such as putting a dummy
optimization-disabled local channel between the caller
and the actual call and putting the CDR on the channel
in the middle to ensure that CDR would persist for the entire
call and properly record start, answer, and end times.

Current default behavior remains unchanged.

ASTERISK-30091 #close

Change-Id: I393981af42732ec5ac3ff9266444abb453b7c832
---
A doc/CHANGES-staging/cdr_ignore.txt
M include/asterisk/cdr.h
M main/cdr.c
3 files changed, 62 insertions(+), 4 deletions(-)



  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/03/18603/1

diff --git a/doc/CHANGES-staging/cdr_ignore.txt b/doc/CHANGES-staging/cdr_ignore.txt
new file mode 100644
index 0000000..e82f404
--- /dev/null
+++ b/doc/CHANGES-staging/cdr_ignore.txt
@@ -0,0 +1,6 @@
+Subject: cdr
+
+Two new options have been added which allow
+bridging and dial state changes to be ignored
+in CDRs, which can be useful if a single CDR
+is desired for a channel.
diff --git a/include/asterisk/cdr.h b/include/asterisk/cdr.h
index 2bbfbdb..06307c9 100644
--- a/include/asterisk/cdr.h
+++ b/include/asterisk/cdr.h
@@ -225,6 +225,8 @@
 	CDR_INITIATED_SECONDS = 1 << 5,     /*!< Include microseconds into the billing time */
 	CDR_DEBUG = 1 << 6,                 /*!< Enables extra debug statements */
 	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 */
 };
 
 /*! \brief CDR Batch Mode settings */
diff --git a/main/cdr.c b/main/cdr.c
index b059082..f41ae42 100644
--- a/main/cdr.c
+++ b/main/cdr.c
@@ -111,6 +111,28 @@
 					to undisable (enable) CDR for a call.</para>
 					</description>
 				</configOption>
+				<configOption name="ignorestatechanges" default="no">
+					<synopsis>Whether CDR is updated or forked by bridging changes.</synopsis>
+					<description><para>Define whether or not CDR should be updated by bridging changes.
+					This includes entering and leaving bridges and call parking.</para>
+					<para>If this is set to "no", bridging changes will be ignored for all CDRs.
+					This should only be done if these events should not affect CDRs and are undesired,
+					such as to use a single CDR for the lifetime of the channel.</para>
+					</description>
+				</configOption>
+				<configOption name="ignoredialchanges" default="no">
+					<synopsis>Whether CDR is updated or forked by dial updates.</synopsis>
+					<description><para>Define whether or not CDR should be updated by dial updates.</para>
+					<para>If this is set to "no", a single CDR will be used for the channel, even if
+					multiple endpoints or destinations are dialed sequentially. Note that you will also
+					lose detailed nonanswer dial dispositions if this option is enabled, which may not be acceptable,
+					e.g. instead of detailed no-answer dispositions like BUSY and CONGESTION, the disposition
+					will always be NO ANSWER if the channel was unanswered (it will still be ANSWERED
+					if the channel was answered).</para>
+					<para>This option should be enabled if a single CDR is desired for the lifetime of
+					the channel.</para>
+					</description>
+				</configOption>
 				<configOption name="unanswered">
 					<synopsis>Log calls that are never answered and don't set an outgoing party.</synopsis>
 					<description><para>
@@ -208,6 +230,8 @@
 #define DEFAULT_END_BEFORE_H_EXTEN "1"
 #define DEFAULT_INITIATED_SECONDS "0"
 #define DEFAULT_CHANNEL_ENABLED "1"
+#define DEFAULT_IGNORE_STATE_CHANGES "0"
+#define DEFAULT_IGNORE_DIAL_CHANGES "0"
 
 #define DEFAULT_BATCH_SIZE "100"
 #define MAX_BATCH_SIZE 1000
@@ -4200,6 +4224,8 @@
 		ast_cli(a->fd, "  Log calls by default:       %s\n", ast_test_flag(&mod_cfg->general->settings, CDR_CHANNEL_DEFAULT_ENABLED) ? "Yes" : "No");
 		ast_cli(a->fd, "  Log unanswered calls:       %s\n", ast_test_flag(&mod_cfg->general->settings, CDR_UNANSWERED) ? "Yes" : "No");
 		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");
 		if (ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE)) {
 			ast_cli(a->fd, "* Batch Mode Settings\n");
 			ast_cli(a->fd, "  -------------------\n");
@@ -4379,6 +4405,8 @@
 		aco_option_register(&cfg_info, "size", ACO_EXACT, general_options, DEFAULT_BATCH_SIZE, OPT_UINT_T, PARSE_IN_RANGE, FLDSET(struct ast_cdr_config, batch_settings.size), 0, MAX_BATCH_SIZE);
 		aco_option_register(&cfg_info, "time", ACO_EXACT, general_options, DEFAULT_BATCH_TIME, OPT_UINT_T, PARSE_IN_RANGE, FLDSET(struct ast_cdr_config, batch_settings.time), 1, MAX_BATCH_TIME);
 		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);
 	}
 
 	if (aco_process_config(&cfg_info, reload) == ACO_PROCESS_ERROR) {
@@ -4541,6 +4569,7 @@
 
 static int load_module(void)
 {
+	struct module_config *mod_cfg = NULL;
 	if (process_config(0)) {
 		return AST_MODULE_LOAD_FAILURE;
 	}
@@ -4561,13 +4590,34 @@
 		return AST_MODULE_LOAD_FAILURE;
 	}
 
+	mod_cfg = ao2_global_obj_ref(module_configs);
+
 	stasis_message_router_add(stasis_router, ast_channel_snapshot_type(), handle_channel_snapshot_update_message, NULL);
-	stasis_message_router_add(stasis_router, ast_channel_dial_type(), handle_dial_message, NULL);
-	stasis_message_router_add(stasis_router, ast_channel_entered_bridge_type(), handle_bridge_enter_message, NULL);
-	stasis_message_router_add(stasis_router, ast_channel_left_bridge_type(), handle_bridge_leave_message, NULL);
-	stasis_message_router_add(stasis_router, ast_parked_call_type(), handle_parked_call_message, NULL);
+
+	/* If explicitly requested to ignore dial state changes, then ignore dial messages */
+	if (!mod_cfg || !ast_test_flag(&mod_cfg->general->settings, CDR_IGNORE_DIAL_CHANGES)) {
+		stasis_message_router_add(stasis_router, ast_channel_dial_type(), handle_dial_message, NULL);
+	} else {
+		CDR_DEBUG("All dial messages will be ignored\n");
+	}
+
+	/* If explicitly instructed to ignore call state changes, then ignore bridging events, parking, etc. */
+	if (!mod_cfg || !ast_test_flag(&mod_cfg->general->settings, CDR_IGNORE_STATE_CHANGES)) {
+		stasis_message_router_add(stasis_router, ast_channel_entered_bridge_type(), handle_bridge_enter_message, NULL);
+		stasis_message_router_add(stasis_router, ast_channel_left_bridge_type(), handle_bridge_leave_message, NULL);
+		stasis_message_router_add(stasis_router, ast_parked_call_type(), handle_parked_call_message, NULL);
+	} else {
+		CDR_DEBUG("All bridge and parking messages will be ignored\n");
+	}
+
 	stasis_message_router_add(stasis_router, cdr_sync_message_type(), handle_cdr_sync_message, NULL);
 
+	if (mod_cfg) {
+		ao2_cleanup(mod_cfg);
+	} else {
+		ast_log(LOG_WARNING, "Unable to obtain CDR configuration during module load?\n");
+	}
+
 	active_cdrs_master = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_MUTEX, 0,
 		AST_NUM_CHANNEL_BUCKETS, cdr_master_hash_fn, NULL, cdr_master_cmp_fn);
 	if (!active_cdrs_master) {

-- 
To view, visit https://gerrit.asterisk.org/c/asterisk/+/18603
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Change-Id: I393981af42732ec5ac3ff9266444abb453b7c832
Gerrit-Change-Number: 18603
Gerrit-PatchSet: 1
Gerrit-Owner: N A <mail at interlinked.x10host.com>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20220601/54706c57/attachment-0001.html>


More information about the asterisk-code-review mailing list