From ed8d5c6430fb4ebaef79834ff8268c831b14de04 Mon Sep 17 00:00:00 2001 From: George Joseph Date: Wed, 19 Nov 2025 14:57:46 -0700 Subject: [PATCH] ccss: Add option to ccss.conf to globally disable it. The Call Completion Supplementary Service feature is rarely used but many of it's functions are called by app_dial and channel.c "just in case". These functions lock and unlock the channel just to see if CCSS is enabled on it, which it isn't 99.99% of the time. UserNote: A new "enabled" parameter has been added to ccss.conf. It defaults to "yes" to preserve backwards compatibility but CCSS is rarely used so setting "enabled = no" in the "general" section can save some unneeded channel locking operations and log message spam. Disabling ccss will also prevent the func_callcompletion and chan_dahdi modules from loading. DeveloperNote: A new API ast_is_cc_enabled() has been added. It should be used to ensure that CCSS is enabled before making any other ast_cc_* calls. --- apps/app_dial.c | 1 - configs/samples/ccss.conf.sample | 5 + include/asterisk/ccss.h | 11 ++ include/asterisk/channel.h | 10 +- main/ccss.c | 186 +++++++++++++++++++++++++------ main/channel.c | 4 + main/core_local.c | 4 +- main/core_unreal.c | 23 ++-- 8 files changed, 196 insertions(+), 48 deletions(-) diff --git a/apps/app_dial.c b/apps/app_dial.c index ec39ab6504..3c2b6a6684 100644 --- a/apps/app_dial.c +++ b/apps/app_dial.c @@ -3615,5 +3615,4 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Dialing Application", .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, - .requires = "ccss", ); diff --git a/configs/samples/ccss.conf.sample b/configs/samples/ccss.conf.sample index efb24928ae..5723e196cd 100644 --- a/configs/samples/ccss.conf.sample +++ b/configs/samples/ccss.conf.sample @@ -6,6 +6,11 @@ ; [general] +; +;enabled = yes ; CCSS is rarely used so setting this to "no" +; ; will globally disable it and save some unneeded +; ; channel locking and log messages. +; ; The cc_max_requests option is a global limit on the number of ; CC requests that may be in the Asterisk system at any time. ; diff --git a/include/asterisk/ccss.h b/include/asterisk/ccss.h index ef821d9eb0..63f37e3107 100644 --- a/include/asterisk/ccss.h +++ b/include/asterisk/ccss.h @@ -1578,4 +1578,15 @@ typedef void (*ast_cc_callback_fn)(struct ast_channel *chan, struct ast_cc_confi */ int ast_cc_callback(struct ast_channel *inbound, const char * const tech, const char * const dest, ast_cc_callback_fn callback); +/*! + * \since 23.2.0 + * \since 22.8.0 + * \since 20.18.0 + * + * \brief Determine if CCSS is enabled. + * \retval 0 Not enabled. + * \retval 1 Enabled + */ +int ast_cc_is_enabled(void); + #endif /* _ASTERISK_CCSS_H */ diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h index 276037b25d..7e8b3e353e 100644 --- a/include/asterisk/channel.h +++ b/include/asterisk/channel.h @@ -3996,10 +3996,13 @@ int ast_channel_redirecting_sub(struct ast_channel *autoservice_chan, struct ast * This function makes use of datastore operations on the channel, so * it is important to lock the channel before calling this function. * + * \warning You should call this function only if \ref ast_cc_is_enabled() + * returns true. + * * \param chan The channel to create the datastore on * \param base_params CCSS parameters we wish to copy into the channel * \retval 0 Success - * \retval -1 Failure + * \retval -1 Failure or CCSS is globally disabled. */ int ast_channel_cc_params_init(struct ast_channel *chan, const struct ast_cc_config_params *base_params); @@ -4012,8 +4015,11 @@ int ast_channel_cc_params_init(struct ast_channel *chan, * This function makes use of datastore operations on the channel, so * it is important to lock the channel before calling this function. * + * \warning You should call this function only if \ref ast_cc_is_enabled() + * returns true. + * * \param chan Channel to retrieve parameters from - * \retval NULL Failure + * \retval NULL Failure or CCSS is globally disabled. * \retval non-NULL The parameters desired */ struct ast_cc_config_params *ast_channel_get_cc_config_params(struct ast_channel *chan); diff --git a/main/ccss.c b/main/ccss.c index 5ec67cd289..49b40f7dde 100644 --- a/main/ccss.c +++ b/main/ccss.c @@ -115,6 +115,16 @@ * them here at the top is easiest. */ +static int global_enabled; + +#define RETURN_IF_NOT_ENABLED(rc) \ +({ \ + if (!global_enabled) { \ + ast_debug(3, "CCSS disabled globally\n"); \ + return rc; \ + } \ +}) + /*! * The ast_sched_context used for all generic CC timeouts */ @@ -463,6 +473,9 @@ struct ast_cc_agent *ast_cc_agent_callback(int flags, ao2_callback_fn *function, { struct cc_callback_helper helper = {.function = function, .args = args, .type = type}; struct cc_core_instance *core_instance; + + RETURN_IF_NOT_ENABLED(NULL); + if ((core_instance = ao2_t_callback(cc_core_instances, flags, cc_agent_callback_helper, &helper, "Calling provided agent callback function"))) { struct ast_cc_agent *agent = cc_ref(core_instance->agent, "An outside entity needs the agent"); @@ -685,8 +698,11 @@ void ast_cc_default_config_params(struct ast_cc_config_params *params) struct ast_cc_config_params *__ast_cc_config_params_init(const char *file, int line, const char *function) { - struct ast_cc_config_params *params = __ast_malloc(sizeof(*params), file, line, function); + struct ast_cc_config_params *params; + + RETURN_IF_NOT_ENABLED(NULL); + params = __ast_malloc(sizeof(*params), file, line, function); if (!params) { return NULL; } @@ -859,7 +875,9 @@ int ast_cc_is_config_param(const char * const name) void ast_cc_copy_config_params(struct ast_cc_config_params *dest, const struct ast_cc_config_params *src) { - *dest = *src; + if (dest && src) { + *dest = *src; + } } enum ast_cc_agent_policies ast_get_cc_agent_policy(struct ast_cc_config_params *config) @@ -1167,8 +1185,11 @@ AST_RWLIST_HEAD_STATIC(cc_monitor_backends, cc_monitor_backend); int ast_cc_monitor_register(const struct ast_cc_monitor_callbacks *callbacks) { - struct cc_monitor_backend *backend = ast_calloc(1, sizeof(*backend)); + struct cc_monitor_backend *backend; + + RETURN_IF_NOT_ENABLED(0); + backend = ast_calloc(1, sizeof(*backend)); if (!backend) { return -1; } @@ -1201,6 +1222,9 @@ static const struct ast_cc_monitor_callbacks *find_monitor_callbacks(const char void ast_cc_monitor_unregister(const struct ast_cc_monitor_callbacks *callbacks) { struct cc_monitor_backend *backend; + + RETURN_IF_NOT_ENABLED(); + AST_RWLIST_WRLOCK(&cc_monitor_backends); AST_RWLIST_TRAVERSE_SAFE_BEGIN(&cc_monitor_backends, backend, next) { if (backend->callbacks == callbacks) { @@ -1222,8 +1246,11 @@ AST_RWLIST_HEAD_STATIC(cc_agent_backends, cc_agent_backend); int ast_cc_agent_register(const struct ast_cc_agent_callbacks *callbacks) { - struct cc_agent_backend *backend = ast_calloc(1, sizeof(*backend)); + struct cc_agent_backend *backend; + RETURN_IF_NOT_ENABLED(0); + + backend = ast_calloc(1, sizeof(*backend)); if (!backend) { return -1; } @@ -1238,6 +1265,9 @@ int ast_cc_agent_register(const struct ast_cc_agent_callbacks *callbacks) void ast_cc_agent_unregister(const struct ast_cc_agent_callbacks *callbacks) { struct cc_agent_backend *backend; + + RETURN_IF_NOT_ENABLED(); + AST_RWLIST_WRLOCK(&cc_agent_backends); AST_RWLIST_TRAVERSE_SAFE_BEGIN(&cc_agent_backends, backend, next) { if (backend->callbacks == callbacks) { @@ -1494,6 +1524,9 @@ int ast_cc_available_timer_expire(const void *data) { struct ast_cc_monitor *monitor = (struct ast_cc_monitor *) data; int res; + + RETURN_IF_NOT_ENABLED(0); + monitor->available_timer_id = -1; res = ast_cc_monitor_failed(monitor->core_id, monitor->interface->device_name, "Available timer expired for monitor"); cc_unref(monitor, "Unref reference from scheduler\n"); @@ -1996,6 +2029,8 @@ void ast_cc_extension_monitor_add_dialstring(struct ast_channel *incoming, const struct cc_monitor_tree *interface_tree; int id; + RETURN_IF_NOT_ENABLED(); + ast_channel_lock(incoming); if (!(cc_datastore = ast_channel_datastore_find(incoming, &dialed_cc_interfaces_info, NULL))) { ast_channel_unlock(incoming); @@ -2306,6 +2341,8 @@ void ast_handle_cc_control_frame(struct ast_channel *inbound, struct ast_channel struct cc_control_payload *cc_data = frame_data; struct cc_core_instance *core_instance; + RETURN_IF_NOT_ENABLED(); + device_name = cc_data->device_name; dialstring = cc_data->dialstring; @@ -2416,6 +2453,12 @@ int ast_cc_call_init(struct ast_channel *chan, int *ignore_cc) struct ast_cc_monitor *monitor; struct ast_cc_config_params *cc_params; + if (!global_enabled) { + ast_debug(3, "CCSS disabled globally\n"); + *ignore_cc = 1; + return 0; + } + ast_channel_lock(chan); cc_params = ast_channel_get_cc_config_params(chan); @@ -2474,6 +2517,8 @@ int ast_cc_get_current_core_id(struct ast_channel *chan) struct dialed_cc_interfaces *cc_interfaces; int core_id_return; + RETURN_IF_NOT_ENABLED(-1); + ast_channel_lock(chan); if (!(datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL))) { ast_channel_unlock(chan); @@ -3377,10 +3422,13 @@ static const struct ast_datastore_info recall_ds_info = { int ast_setup_cc_recall_datastore(struct ast_channel *chan, const int core_id) { - struct ast_datastore *recall_datastore = ast_datastore_alloc(&recall_ds_info, NULL); + struct ast_datastore *recall_datastore; struct cc_recall_ds_data *recall_data; struct cc_core_instance *core_instance; + RETURN_IF_NOT_ENABLED(0); + + recall_datastore = ast_datastore_alloc(&recall_ds_info, NULL); if (!recall_datastore) { return -1; } @@ -3417,6 +3465,8 @@ int ast_cc_is_recall(struct ast_channel *chan, int *core_id, const char * const struct ast_cc_monitor *device_monitor; int core_id_candidate; + RETURN_IF_NOT_ENABLED(0); + ast_assert(core_id != NULL); *core_id = -1; @@ -3494,6 +3544,8 @@ struct ast_cc_monitor *ast_cc_get_monitor_by_recall_core_id(const int core_id, c struct cc_core_instance *core_instance = find_cc_core_instance(core_id); struct ast_cc_monitor *monitor_iter; + RETURN_IF_NOT_ENABLED(NULL); + if (!core_instance) { return NULL; } @@ -3608,6 +3660,8 @@ int ast_cc_agent_set_interfaces_chanvar(struct ast_channel *chan) struct ast_str *str = ast_str_create(64); int core_id; + RETURN_IF_NOT_ENABLED(0); + if (!str) { return -1; } @@ -3645,6 +3699,8 @@ int ast_set_cc_interfaces_chanvar(struct ast_channel *chan, const char * const e struct ast_str *str = ast_str_create(64); int core_id; + RETURN_IF_NOT_ENABLED(0); + if (!str) { return -1; } @@ -3695,6 +3751,8 @@ void ast_ignore_cc(struct ast_channel *chan) struct dialed_cc_interfaces *cc_interfaces; struct cc_recall_ds_data *recall_cc_data; + RETURN_IF_NOT_ENABLED(); + ast_channel_lock(chan); if ((cc_datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL))) { cc_interfaces = cc_datastore->data; @@ -3727,6 +3785,8 @@ int ast_cc_offer(struct ast_channel *caller_chan) struct dialed_cc_interfaces *cc_interfaces; char cc_is_offerable; + RETURN_IF_NOT_ENABLED(0); + ast_channel_lock(caller_chan); if (!(datastore = ast_channel_datastore_find(caller_chan, &dialed_cc_interfaces_info, NULL))) { ast_channel_unlock(caller_chan); @@ -3749,6 +3809,8 @@ int ast_cc_agent_accept_request(int core_id, const char * const debug, ...) va_list ap; int res; + RETURN_IF_NOT_ENABLED(0); + va_start(ap, debug); res = cc_request_state_change(CC_CALLER_REQUESTED, core_id, debug, ap); va_end(ap); @@ -3760,6 +3822,8 @@ int ast_cc_monitor_request_acked(int core_id, const char * const debug, ...) va_list ap; int res; + RETURN_IF_NOT_ENABLED(0); + va_start(ap, debug); res = cc_request_state_change(CC_ACTIVE, core_id, debug, ap); va_end(ap); @@ -3771,6 +3835,8 @@ int ast_cc_monitor_callee_available(const int core_id, const char * const debug, va_list ap; int res; + RETURN_IF_NOT_ENABLED(0); + va_start(ap, debug); res = cc_request_state_change(CC_CALLEE_READY, core_id, debug, ap); va_end(ap); @@ -3782,6 +3848,8 @@ int ast_cc_agent_caller_busy(int core_id, const char * debug, ...) va_list ap; int res; + RETURN_IF_NOT_ENABLED(0); + va_start(ap, debug); res = cc_request_state_change(CC_CALLER_BUSY, core_id, debug, ap); va_end(ap); @@ -3793,6 +3861,8 @@ int ast_cc_agent_caller_available(int core_id, const char * const debug, ...) va_list ap; int res; + RETURN_IF_NOT_ENABLED(0); + va_start(ap, debug); res = cc_request_state_change(CC_ACTIVE, core_id, debug, ap); va_end(ap); @@ -3804,6 +3874,8 @@ int ast_cc_agent_recalling(int core_id, const char * const debug, ...) va_list ap; int res; + RETURN_IF_NOT_ENABLED(0); + va_start(ap, debug); res = cc_request_state_change(CC_RECALLING, core_id, debug, ap); va_end(ap); @@ -3818,6 +3890,8 @@ int ast_cc_completed(struct ast_channel *chan, const char * const debug, ...) va_list ap; int res; + RETURN_IF_NOT_ENABLED(0); + ast_channel_lock(chan); if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) { /* Silly! Why did you call this function if there's no recall DS? */ @@ -3852,6 +3926,8 @@ int ast_cc_failed(int core_id, const char * const debug, ...) va_list ap; int res; + RETURN_IF_NOT_ENABLED(0); + va_start(ap, debug); res = cc_request_state_change(CC_FAILED, core_id, debug, ap); va_end(ap); @@ -3915,6 +3991,8 @@ int ast_cc_monitor_failed(int core_id, const char *const monitor_name, const cha int res; va_list ap; + RETURN_IF_NOT_ENABLED(0); + if (!(failure_data = ast_calloc(1, sizeof(*failure_data)))) { return -1; } @@ -3959,6 +4037,8 @@ int ast_cc_monitor_status_request(int core_id) int res; struct cc_core_instance *core_instance = find_cc_core_instance(core_id); + RETURN_IF_NOT_ENABLED(0); + if (!core_instance) { return -1; } @@ -3996,6 +4076,8 @@ int ast_cc_monitor_stop_ringing(int core_id) int res; struct cc_core_instance *core_instance = find_cc_core_instance(core_id); + RETURN_IF_NOT_ENABLED(0); + if (!core_instance) { return -1; } @@ -4024,6 +4106,8 @@ int ast_cc_monitor_party_b_free(int core_id) int res; struct cc_core_instance *core_instance = find_cc_core_instance(core_id); + RETURN_IF_NOT_ENABLED(0); + if (!core_instance) { return -1; } @@ -4067,6 +4151,8 @@ int ast_cc_agent_status_response(int core_id, enum ast_device_state devstate) struct cc_core_instance *core_instance; int res; + RETURN_IF_NOT_ENABLED(0); + args = ast_calloc(1, sizeof(*args)); if (!args) { return -1; @@ -4125,6 +4211,8 @@ int ast_queue_cc_frame(struct ast_channel *chan, const char *monitor_type, int retval; struct ast_cc_config_params *cc_params; + RETURN_IF_NOT_ENABLED(0); + cc_params = ast_channel_get_cc_config_params(chan); if (!cc_params) { return -1; @@ -4149,8 +4237,11 @@ int ast_cc_build_frame(struct ast_channel *chan, struct ast_cc_config_params *cc const char * const dialstring, enum ast_cc_service_type service, void *private_data, struct ast_frame *frame) { - struct cc_control_payload *payload = ast_calloc(1, sizeof(*payload)); + struct cc_control_payload *payload; + + RETURN_IF_NOT_ENABLED(0); + payload = ast_calloc(1, sizeof(*payload)); if (!payload) { return -1; } @@ -4173,6 +4264,8 @@ void ast_cc_call_failed(struct ast_channel *incoming, struct ast_channel *outgoi struct cc_control_payload payload; struct ast_cc_config_params *cc_params; + RETURN_IF_NOT_ENABLED(); + if (ast_channel_hangupcause(outgoing) != AST_CAUSE_BUSY && ast_channel_hangupcause(outgoing) != AST_CAUSE_CONGESTION) { /* It doesn't make sense to try to offer CCBS to the caller if the reason for ast_call * failing is something other than busy or congestion @@ -4204,6 +4297,9 @@ void ast_cc_busy_interface(struct ast_channel *inbound, struct ast_cc_config_par const char *monitor_type, const char * const device_name, const char * const dialstring, void *private_data) { struct cc_control_payload payload; + + RETURN_IF_NOT_ENABLED(); + if (cc_build_payload(inbound, cc_params, monitor_type, device_name, dialstring, AST_CC_CCBS, private_data, &payload)) { /* Something screwed up. Don't try to handle this payload */ call_destructor_with_no_monitor(monitor_type, private_data); @@ -4214,8 +4310,11 @@ void ast_cc_busy_interface(struct ast_channel *inbound, struct ast_cc_config_par int ast_cc_callback(struct ast_channel *inbound, const char * const tech, const char * const dest, ast_cc_callback_fn callback) { - const struct ast_channel_tech *chantech = ast_get_channel_tech(tech); + const struct ast_channel_tech *chantech; + + RETURN_IF_NOT_ENABLED(0); + chantech = ast_get_channel_tech(tech); if (chantech && chantech->cc_callback) { chantech->cc_callback(inbound, dest, callback); } @@ -4340,27 +4439,19 @@ int ast_cc_monitor_count(const char * const name, const char * const type) { struct count_monitors_cb_data data = {.device_name = name, .monitor_type = type,}; + RETURN_IF_NOT_ENABLED(0); + ao2_t_callback(cc_core_instances, OBJ_NODATA, count_monitors_cb, &data, "Counting agents"); ast_log_dynamic_level(cc_logger_level, "Counted %d monitors\n", data.count); return data.count; } -static void initialize_cc_max_requests(void) +static void initialize_cc_max_requests(struct ast_config *cc_config) { - struct ast_config *cc_config; const char *cc_max_requests_str; - struct ast_flags config_flags = {0,}; char *endptr; - cc_config = ast_config_load2("ccss.conf", "ccss", config_flags); - if (!cc_config || cc_config == CONFIG_STATUS_FILEINVALID) { - ast_log(LOG_WARNING, "Could not find valid ccss.conf file. Using cc_max_requests default\n"); - global_cc_max_requests = GLOBAL_CC_MAX_REQUESTS_DEFAULT; - return; - } - if (!(cc_max_requests_str = ast_variable_retrieve(cc_config, "general", "cc_max_requests"))) { - ast_config_destroy(cc_config); global_cc_max_requests = GLOBAL_CC_MAX_REQUESTS_DEFAULT; return; } @@ -4372,7 +4463,6 @@ static void initialize_cc_max_requests(void) global_cc_max_requests = GLOBAL_CC_MAX_REQUESTS_DEFAULT; } - ast_config_destroy(cc_config); return; } @@ -4404,18 +4494,8 @@ static void initialize_cc_devstate_map_helper(struct ast_config *cc_config, enum * should use any valid device state form that is recognized by * ast_devstate_val() function. */ -static void initialize_cc_devstate_map(void) +static void initialize_cc_devstate_map(struct ast_config *cc_config) { - struct ast_config *cc_config; - struct ast_flags config_flags = { 0, }; - - cc_config = ast_config_load2("ccss.conf", "ccss", config_flags); - if (!cc_config || cc_config == CONFIG_STATUS_FILEINVALID) { - ast_log(LOG_WARNING, - "Could not find valid ccss.conf file. Using cc_[state]_devstate defaults\n"); - return; - } - initialize_cc_devstate_map_helper(cc_config, CC_AVAILABLE, "cc_available_devstate"); initialize_cc_devstate_map_helper(cc_config, CC_CALLER_OFFERED, "cc_caller_offered_devstate"); initialize_cc_devstate_map_helper(cc_config, CC_CALLER_REQUESTED, "cc_caller_requested_devstate"); @@ -4426,7 +4506,40 @@ static void initialize_cc_devstate_map(void) initialize_cc_devstate_map_helper(cc_config, CC_COMPLETE, "cc_complete_devstate"); initialize_cc_devstate_map_helper(cc_config, CC_FAILED, "cc_failed_devstate"); +} + +static int load_config(void) +{ + struct ast_flags config_flags = { 0, }; + const char *enabled = NULL; + struct ast_config *cc_config = ast_config_load2("ccss.conf", "ccss", config_flags); + + global_enabled = 1; + + if (!cc_config || cc_config == CONFIG_STATUS_FILEINVALID) { + ast_log(LOG_WARNING, "Could not find valid ccss.conf file. Using cc_max_requests and devstate defaults\n"); + global_cc_max_requests = GLOBAL_CC_MAX_REQUESTS_DEFAULT; + return 0; + } + + if ((enabled = ast_variable_retrieve(cc_config, "general", "enabled"))) { + global_enabled = ast_true(enabled); + } + + if (global_enabled) { + initialize_cc_max_requests(cc_config); + initialize_cc_devstate_map(cc_config); + } else { + ast_log(LOG_NOTICE, "CCSS disabled globally\n"); + } ast_config_destroy(cc_config); + + return !global_enabled; +} + +int ast_cc_is_enabled(void) +{ + return global_enabled; } static void cc_cli_print_monitor_stats(struct ast_cc_monitor *monitor, int fd, int parent_id) @@ -4593,6 +4706,10 @@ static struct ast_cli_entry cc_cli[] = { static int unload_module(void) { + if (!global_enabled) { + return 0; + } + ast_devstate_prov_del("ccss"); ast_cc_agent_unregister(&generic_agent_callbacks); ast_cc_monitor_unregister(&generic_monitor_cbs); @@ -4625,6 +4742,11 @@ static int load_module(void) { int res; + res = load_config(); + if (res != 0) { + return AST_MODULE_LOAD_DECLINE; + } + cc_core_instances = ao2_t_container_alloc_hash(AO2_ALLOC_OPT_LOCK_MUTEX, 0, CC_CORE_INSTANCES_BUCKETS, cc_core_instance_hash_fn, NULL, cc_core_instance_cmp_fn, @@ -4657,10 +4779,6 @@ static int load_module(void) ast_cli_register_multiple(cc_cli, ARRAY_LEN(cc_cli)); cc_logger_level = ast_logger_register_level(CC_LOGGER_LEVEL_NAME); dialed_cc_interface_counter = 1; - initialize_cc_max_requests(); - - /* Read the map and register the device state callback for generic agents */ - initialize_cc_devstate_map(); res |= ast_devstate_prov_add("ccss", ccss_device_state); return res ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_SUCCESS; diff --git a/main/channel.c b/main/channel.c index 787bdb8886..8121b5c3d7 100644 --- a/main/channel.c +++ b/main/channel.c @@ -10519,6 +10519,10 @@ struct ast_cc_config_params *ast_channel_get_cc_config_params(struct ast_channel { struct ast_datastore *cc_datastore; + if (!ast_cc_is_enabled()) { + return NULL; + } + if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) { /* If we can't find the datastore, it almost definitely means that the channel type being * used has not had its driver modified to parse CC config parameters. The best action diff --git a/main/core_local.c b/main/core_local.c index 32625bccba..af38dd7bbb 100644 --- a/main/core_local.c +++ b/main/core_local.c @@ -732,7 +732,9 @@ static int local_call(struct ast_channel *ast, const char *dest, int timeout) if ((slash = strrchr(reduced_dest, '/'))) { *slash = '\0'; } - ast_set_cc_interfaces_chanvar(chan, reduced_dest); + if (ast_cc_is_enabled()) { + ast_set_cc_interfaces_chanvar(chan, reduced_dest); + } ao2_unlock(p); pvt_locked = 0; diff --git a/main/core_unreal.c b/main/core_unreal.c index fd0f05b4e3..b9cbaebfd4 100644 --- a/main/core_unreal.c +++ b/main/core_unreal.c @@ -896,7 +896,9 @@ void ast_unreal_call_setup(struct ast_channel *semi1, struct ast_channel *semi2) ast_channel_accountcode_set(semi2, ast_channel_peeraccount(semi1)); ast_channel_peeraccount_set(semi2, ast_channel_accountcode(semi1)); - ast_channel_cc_params_init(semi2, ast_channel_get_cc_config_params(semi1)); + if (ast_cc_is_enabled()) { + ast_channel_cc_params_init(semi2, ast_channel_get_cc_config_params(semi1)); + } /* * Make sure we inherit the AST_CAUSE_ANSWERED_ELSEWHERE if it's @@ -1259,16 +1261,17 @@ struct ast_channel *ast_unreal_new_channels(struct ast_unreal_pvt *p, ast_jb_configure(owner, &p->jb_conf); - if (ast_channel_cc_params_init(owner, requestor - ? ast_channel_get_cc_config_params((struct ast_channel *) requestor) : NULL)) { - ast_channel_tech_pvt_set(owner, NULL); - ao2_ref(p, -1); - ast_channel_tech_pvt_set(owner, NULL); - ast_channel_unlock(owner); - ast_channel_release(owner); - return NULL; + if (ast_cc_is_enabled()) { + if (ast_channel_cc_params_init(owner, requestor + ? ast_channel_get_cc_config_params((struct ast_channel *) requestor) : NULL)) { + ast_channel_tech_pvt_set(owner, NULL); + ao2_ref(p, -1); + ast_channel_tech_pvt_set(owner, NULL); + ast_channel_unlock(owner); + ast_channel_release(owner); + return NULL; + } } - p->owner = owner; ast_channel_unlock(owner); -- 2.47.3