32 #include "asterisk/astobj2.h"
134 static inline void *
cc_ref(
void *obj,
const char *debug)
140 static inline void *
cc_unref(
void *obj,
const char *debug)
372 static const struct {
382 static const struct {
391 {
CC_CALLER_BUSY,
"Callee was ready, but caller is now unavailable"},
451 "Calling provided agent callback function"))) {
453 cc_unref(core_instance,
"agent callback done with the core_instance");
485 const char *
name = arg;
486 unsigned long match_flags = *(
unsigned long *)data;
487 int possible_match = 0;
497 if (!possible_match) {
523 const char *
name = arg;
537 #define CC_OFFER_TIMER_DEFAULT 20
538 #define CCNR_AVAILABLE_TIMER_DEFAULT 7200
539 #define CCBS_AVAILABLE_TIMER_DEFAULT 4800
540 #define CC_RECALL_TIMER_DEFAULT 20
541 #define CC_MAX_AGENTS_DEFAULT 5
542 #define CC_MAX_MONITORS_DEFAULT 5
543 #define GLOBAL_CC_MAX_REQUESTS_DEFAULT 20
554 .cc_callback_macro =
"",
555 .cc_agent_dialstring =
"",
565 #if defined(__AST_DEBUG_MALLOC)
586 if (!strcasecmp(value,
"never")) {
588 }
else if (!strcasecmp(value,
"native")) {
590 }
else if (!strcasecmp(value,
"generic")) {
593 ast_log(
LOG_WARNING,
"%s is an invalid value for cc_agent_policy. Switching to 'never'\n", value);
600 if (!strcasecmp(value,
"never")) {
602 }
else if (!strcasecmp(value,
"native")) {
604 }
else if (!strcasecmp(value,
"generic")) {
606 }
else if (!strcasecmp(value,
"always")) {
609 ast_log(
LOG_WARNING,
"%s is an invalid value for cc_monitor_policy. Switching to 'never'\n", value);
646 char *buf,
size_t buf_len)
648 const char *
value = NULL;
650 if (!strcasecmp(name,
"cc_callback_macro")) {
652 }
else if (!strcasecmp(name,
"cc_agent_policy")) {
654 }
else if (!strcasecmp(name,
"cc_monitor_policy")) {
656 }
else if (!strcasecmp(name,
"cc_agent_dialstring")) {
668 if (!strcasecmp(name,
"cc_offer_timer")) {
670 }
else if (!strcasecmp(name,
"ccnr_available_timer")) {
672 }
else if (!strcasecmp(name,
"ccbs_available_timer")) {
674 }
else if (!strcasecmp(name,
"cc_max_agents")) {
676 }
else if (!strcasecmp(name,
"cc_max_monitors")) {
678 }
else if (!strcasecmp(name,
"cc_recall_timer")) {
689 const char *
const value)
691 unsigned int value_as_uint;
692 if (!strcasecmp(name,
"cc_agent_policy")) {
694 }
else if (!strcasecmp(name,
"cc_monitor_policy")) {
696 }
else if (!strcasecmp(name,
"cc_agent_dialstring")) {
698 }
else if (!strcasecmp(name,
"cc_callback_macro")) {
703 if (!sscanf(value,
"%30u", &value_as_uint) == 1) {
707 if (!strcasecmp(name,
"cc_offer_timer")) {
709 }
else if (!strcasecmp(name,
"ccnr_available_timer")) {
711 }
else if (!strcasecmp(name,
"ccbs_available_timer")) {
713 }
else if (!strcasecmp(name,
"cc_max_agents")) {
715 }
else if (!strcasecmp(name,
"cc_max_monitors")) {
717 }
else if (!strcasecmp(name,
"cc_recall_timer")) {
729 return (!strcasecmp(name,
"cc_agent_policy") ||
730 !strcasecmp(name,
"cc_monitor_policy") ||
731 !strcasecmp(name,
"cc_offer_timer") ||
732 !strcasecmp(name,
"ccnr_available_timer") ||
733 !strcasecmp(name,
"ccbs_available_timer") ||
734 !strcasecmp(name,
"cc_max_agents") ||
735 !strcasecmp(name,
"cc_max_monitors") ||
736 !strcasecmp(name,
"cc_callback_macro") ||
737 !strcasecmp(name,
"cc_agent_dialstring") ||
738 !strcasecmp(name,
"cc_recall_timer"));
897 struct cc_monitor_backend *backend =
ast_calloc(1,
sizeof(*backend));
952 struct cc_agent_backend *backend =
ast_calloc(1,
sizeof(*backend));
999 ast_log_dynamic_level(cc_logger_level,
"Not returning agent callbacks since this channel is configured not to have a CC agent\n");
1096 const struct generic_monitor_instance_list *generic_list = obj;
1102 const struct generic_monitor_instance_list *generic_list1 = obj;
1103 const struct generic_monitor_instance_list *generic_list2 = arg;
1110 struct generic_monitor_instance_list finder = {0};
1120 struct generic_monitor_instance_list *generic_list = obj;
1133 struct generic_monitor_instance_list *generic_list =
ao2_t_alloc(
sizeof(*generic_list),
1137 if (!generic_list) {
1142 cc_unref(generic_list,
"Failed to strdup the monitor's device name");
1153 cc_unref(generic_list,
"Failed to subscribe to device state");
1158 return generic_list;
1172 struct generic_monitor_instance_list *generic_list;
1187 cc_unref(generic_list,
"Kill reference of generic list in devstate taskprocessor callback");
1208 cc_unref(generic_list,
"Kill reference of generic list in devstate taskprocessor callback");
1245 cc_unref(monitor,
"Unref reference from scheduler\n");
1251 struct generic_monitor_instance_list *generic_list;
1261 if (!(gen_mon_pvt =
ast_calloc(1,
sizeof(*gen_mon_pvt)))) {
1280 if (!(generic_instance =
ast_calloc(1,
sizeof(*generic_instance)))) {
1284 cc_unref(generic_list,
"Generic monitor instance failed to allocate");
1295 if (*available_timer_id == -1) {
1296 cc_unref(monitor,
"Failed to schedule available timer. (monitor)");
1297 cc_unref(generic_list,
"Failed to schedule available timer. (generic_list)");
1308 cc_unref(generic_list,
"Finished with monitor instance reference in request cc callback");
1314 struct generic_monitor_instance_list *generic_list;
1334 cc_unref(generic_list,
"Device is in use. Nothing to do. Unref generic list.");
1349 cc_unref(generic_list,
"Done with generic list in suspend callback");
1359 if (!generic_list) {
1377 cc_unref(generic_list,
"Done with generic list in cc_generic_monitor_unsuspend");
1385 if (*sched_id == -1) {
1389 ast_log_dynamic_level(cc_logger_level,
"Core %d: Canceling generic monitor available timer for monitor %s\n",
1392 cc_unref(monitor,
"Remove scheduler's reference to the monitor");
1401 struct generic_monitor_instance_list *generic_list;
1404 if (!private_data) {
1456 "availability due to other instance's failure.");
1462 cc_unref(generic_list,
"Done with generic list in generic monitor destructor");
1553 struct extension_monitor_pvt *extension_pvt = private_data;
1557 if (!extension_pvt) {
1596 cc_unref(monitor,
"Destroying all monitors");
1698 if (!new_cc_interfaces) {
1707 return new_cc_interfaces;
1720 .
type =
"Dial CC Interfaces",
1727 struct extension_monitor_pvt *ext_pvt =
ast_calloc(1,
sizeof(*ext_pvt));
1740 struct extension_monitor_pvt *extension_pvt;
1751 cc_interfaces = cc_datastore->
data;
1758 if (monitor->
id ==
id) {
1769 if (!(child_dialstring =
ast_calloc(1,
sizeof(*child_dialstring)))) {
1783 struct extension_monitor_pvt *extension_pvt;
1787 if (monitor_iter->
id == parent_id) {
1792 if (!monitor_iter) {
1798 if (!strcmp(child_dialstring->
device_name, device_name)) {
1828 "Allocating new ast_cc_interface"))) {
1833 cc_unref(cc_interface,
"failed to allocate the monitor, so unref the interface");
1838 cc_unref(monitor,
"Failed to initialize extension monitor private data. uref monitor");
1839 cc_unref(cc_interface,
"Failed to initialize extension monitor private data. unref cc_interface");
1884 if (!(interfaces =
ast_calloc(1,
sizeof(*interfaces)))) {
1894 cc_unref(monitor,
"Could not allocate the dialed interfaces datastore. Unreffing monitor");
1900 "Allocate monitor tree"))) {
1902 cc_unref(monitor,
"Could not allocate monitor tree on dialed interfaces datastore. Unreffing monitor");
1910 cc_ref(monitor,
"List's reference to extension monitor");
1911 dial_cc_datastore->
data = interfaces;
1919 cc_unref(monitor,
"Unreffing allocation's reference");
1950 if (!monitor_callbacks) {
1986 size_t device_name_len = strlen(device_name);
1990 "Allocating new ast_cc_interface"))) {
1995 cc_unref(cc_interface,
"Failed to allocate config params, unref interface");
2000 cc_unref(cc_interface,
"Failed to allocate monitor, unref interface");
2005 cc_unref(monitor,
"Failed to copy dialable name. Unref monitor");
2006 cc_unref(cc_interface,
"Failed to copy dialable name");
2011 cc_unref(monitor,
"Failed to find monitor callbacks. Unref monitor");
2012 cc_unref(cc_interface,
"Failed to find monitor callbacks");
2027 ast_log_dynamic_level(cc_logger_level,
"Core %d: Created a device cc interface for '%s' with id %u and parent %u\n",
2063 ast_log(
LOG_WARNING,
"Unable to retrieve CC datastore while processing CC frame from '%s'. CC services will be unavailable.\n", device_name);
2069 cc_interfaces = cc_datastore->
data;
2071 if (cc_interfaces->
ignore) {
2089 if (!core_instance) {
2091 cc_interfaces->
core_id, cc_data);
2092 if (!core_instance) {
2093 cc_interfaces->
ignore = 1;
2111 ast_log_dynamic_level(cc_logger_level,
"Core %d: Device %s sent us multiple CC control frames. Ignoring those beyond the first.\n",
2112 core_instance->
core_id, device_name);
2114 cc_unref(core_instance,
"Returning early from ast_handle_cc_control_frame. Unref core_instance");
2122 ast_log(
LOG_WARNING,
"Unable to create CC device interface for '%s'. CC services will be unavailable on this interface.\n", device_name);
2123 cc_unref(core_instance,
"Returning early from ast_handle_cc_control_frame. Unref core_instance");
2129 cc_ref(monitor,
"monitor tree's reference to the monitor");
2142 cc_unref(core_instance,
"Done with core_instance after handling CC control frame");
2143 cc_unref(monitor,
"Unref reference from allocating monitor");
2194 interfaces = cc_interfaces_datastore->
data;
2197 if (interfaces->
ignore) {
2200 ast_log_dynamic_level(cc_logger_level,
"Datastore is present with ignore flag set. Ignoring CC offers on this call\n");
2211 cc_ref(monitor,
"monitor tree's reference to the monitor");
2215 cc_unref(monitor,
"Unref monitor's allocation reference");
2236 cc_interfaces = datastore->
data;
2237 core_id_return = cc_interfaces->
ignore ? -1 : cc_interfaces->
core_id;
2239 return core_id_return;
2243 static long count_agents(
const char *
const caller,
const int core_id_exception)
2262 match_agent, caller, &match_flags,
"Killing duplicate offers");
2292 const char *
const caller_name,
const int core_id,
2299 "Allocating new ast_cc_agent"))) {
2308 cc_unref(agent,
"Could not get channel config params.");
2312 cc_unref(agent,
"Could not init agent config params.");
2318 cc_unref(agent,
"Could not find agent callbacks.");
2324 cc_unref(agent,
"Agent init callback failed.");
2432 ast_log_dynamic_level(cc_logger_level,
"Core %u: Queuing change request because offer timer has expired.\n",
2436 cc_unref(agent,
"Remove scheduler's reference to the agent");
2450 ast_log_dynamic_level(cc_logger_level,
"Core %u: About to schedule offer timer expiration for %d ms\n",
2465 cc_unref(agent,
"Remove scheduler's reference to the agent");
2503 if (generic_pvt->
sub != NULL) {
2506 cc_unref(agent,
"Done unsubscribing from devstate");
2523 cc_ref(agent,
"ref agent for device state unsubscription"))) {
2524 cc_unref(agent,
"Unref agent unsubscribing from devstate failed");
2535 ast_str_set(&str, 0,
"Agent monitoring %s device state since it is busy\n",
2552 const char *
interface =
S_OR(ast_get_cc_agent_dialstring(agent->cc_params), ast_strdupa(agent->device_name));
2561 if ((target = strchr(interface,
'/'))) {
2568 agent->core_id, agent->device_name, reason);
2569 ast_cc_failed(agent->core_id,
"Failed to call back device %s/%s", tech, target);
2589 ast_log_dynamic_level(cc_logger_level,
"Core %u: There's a callback macro configured for agent %s\n",
2590 agent->core_id, agent->device_name);
2592 ast_cc_failed(agent->core_id,
"Callback macro to %s failed. Maybe a hangup?", agent->device_name);
2598 ast_cc_failed(agent->core_id,
"PBX failed to start for %s.", agent->device_name);
2603 agent->device_name);
2633 if (agent_pvt->
sub) {
2644 if (core_instance->
agent) {
2645 cc_unref(core_instance->
agent,
"Core instance is done with the agent now");
2678 ast_log_dynamic_level(cc_logger_level,
"Caller %s already has the maximum number of agents configured\n", caller);
2684 ast_log_dynamic_level(cc_logger_level,
"Generic agents can only have a single outstanding request\n");
2693 core_instance->
core_id = core_id;
2695 cc_unref(core_instance,
"Couldn't allocate agent, unref core_instance");
2699 core_instance->
monitors =
cc_ref(called_tree,
"Core instance getting ref to monitor tree");
2701 ao2_t_link(cc_core_instances, core_instance,
"Link core instance into container");
2703 return core_instance;
2716 switch (new_state) {
2718 ast_log_dynamic_level(cc_logger_level,
"Core %u: Asked to change to state %u? That should never happen.\n",
2834 cc_unref(monitor_iter,
"request_cc failed. Unref list's reference to monitor");
2855 ast_log(
LOG_WARNING,
"Cannot request CC since there is no more room for requests\n");
2876 cc_unref(monitor_iter,
"unsuspend failed. Unref list's reference to monitor");
2929 cc_unref(monitor_iter,
"suspend failed. Unref list's reference to monitor");
2965 cc_unref(monitor_iter,
"cancel_available_timer failed. Unref list's reference to monitor");
2972 ast_cc_failed(core_instance->
core_id,
"All device monitors failed to cancel their available timers");
2997 ao2_t_unlink(cc_core_instances, core_instance,
"Unlink core instance since CC recall has completed");
3008 ao2_t_unlink(cc_core_instances, core_instance,
"Unlink core instance since CC failed");
3037 ast_log_dynamic_level(cc_logger_level,
"Core %d: Invalid state change requested. Cannot go from %s to %s\n",
3048 cc_unref(core_instance,
"Unref core instance from when it was found earlier");
3058 cc_unref(core_instance,
"Unref since state change has completed");
3077 debuglen = vsnprintf(dummy,
sizeof(dummy), debug, aq) + 1;
3080 if (!(args =
ast_calloc(1,
sizeof(*args) + debuglen))) {
3085 if (!core_instance) {
3095 vsnprintf(args->
debug, debuglen, debug, ap);
3099 cc_unref(core_instance,
"Unref core instance. ast_taskprocessor_push failed");
3134 .
type =
"cc_recall",
3145 if (!recall_datastore) {
3149 if (!(recall_data =
ast_calloc(1,
sizeof(*recall_data)))) {
3161 "Bump refcount for monitor tree for recall datastore");
3163 recall_datastore->
data = recall_data;
3168 cc_unref(core_instance,
"Recall datastore set up. No need for core_instance ref");
3179 int core_id_candidate;
3192 recall_data = recall_datastore->
data;
3194 if (recall_data->
ignore) {
3203 if (!recall_data->
nested) {
3210 *core_id = recall_data->
core_id;
3232 core_id_candidate = recall_data->
core_id;
3244 *core_id = core_id_candidate;
3258 if (!core_instance) {
3266 cc_ref(monitor_iter,
"Hand the requester of the monitor a reference");
3271 cc_unref(core_instance,
"Done with core instance ref in ast_cc_get_monitor_by_recall_core_id");
3272 return monitor_iter;
3300 snprintf(dialstring_search,
sizeof(dialstring_search),
"%s%c", dialstring,
'&');
3324 struct extension_monitor_pvt *extension_pvt;
3327 int top_level_id = starting_point->
id;
3345 while ((monitor_iter =
AST_LIST_NEXT(monitor_iter, next))) {
3346 if (monitor_iter->
parent_id == top_level_id) {
3384 recall_data = recall_datastore->
data;
3386 core_id = recall_data->
core_id;
3421 recall_data = recall_datastore->
data;
3423 core_id = recall_data->
core_id;
3433 if (!monitor_iter) {
3463 cc_interfaces = cc_datastore->
data;
3464 cc_interfaces->
ignore = 1;
3468 recall_cc_data = cc_recall_datastore->
data;
3469 recall_cc_data->
ignore = 1;
3479 va_start(ap, debug);
3491 char cc_is_offerable;
3499 cc_interfaces = datastore->
data;
3501 core_id = cc_interfaces->
core_id;
3504 if (cc_is_offerable) {
3505 res =
cc_offer(core_id,
"CC offered to caller %s", caller_chan->
name);
3515 va_start(ap, debug);
3526 va_start(ap, debug);
3537 va_start(ap, debug);
3548 va_start(ap, debug);
3559 va_start(ap, debug);
3570 va_start(ap, debug);
3590 recall_data = recall_datastore->
data;
3605 core_id = recall_data->
core_id;
3607 va_start(ap, debug);
3618 va_start(ap, debug);
3637 if (!core_instance) {
3640 "Core %d: Could not find core instance for device %s '%s'\n",
3660 cc_unref(monitor_iter,
"Monitor reported failure. Unref list's reference.");
3670 cc_unref(core_instance,
"Finished with core_instance in cc_monitor_failed\n");
3684 if (!(failure_data =
ast_calloc(1,
sizeof(*failure_data)))) {
3693 va_start(ap, debug);
3719 cc_unref(core_instance,
"Status request finished. Unref core instance");
3728 if (!core_instance) {
3734 cc_unref(core_instance,
"Unref core instance. ast_taskprocessor_push failed");
3756 cc_unref(core_instance,
"Stop ringing finished. Unref core_instance");
3765 if (!core_instance) {
3771 cc_unref(core_instance,
"Unref core instance. ast_taskprocessor_push failed");
3784 cc_unref(core_instance,
"Party B free finished. Unref core_instance");
3793 if (!core_instance) {
3799 cc_unref(core_instance,
"Unref core instance. ast_taskprocessor_push failed");
3826 cc_unref(core_instance,
"Status response finished. Unref core instance");
3842 if (!core_instance) {
3852 cc_unref(core_instance,
"Unref core instance. ast_taskprocessor_push failed");
3859 const char *monitor_type,
const char *
const device_name,
const char * dialstring,
3872 cc_interfaces = datastore->
data;
3900 ast_log(
LOG_NOTICE,
"Not queuing a CC frame for device %s since it already has its maximum monitors allocated\n", device_name);
3904 if (
ast_cc_build_frame(chan, cc_params, monitor_type, device_name, dialstring, service, private_data, &frame)) {
3914 const char *monitor_type,
const char *
const device_name,
3923 if (
cc_build_payload(chan, cc_params, monitor_type, device_name, dialstring, service, private_data, payload)) {
3931 frame->
datalen =
sizeof(*payload);
3970 const char *monitor_type,
const char *
const device_name,
const char *
const dialstring,
void *private_data)
4004 if (!(core_instance =
ao2_t_callback_data(cc_core_instances, 0,
match_agent, device_name, &match_flags,
"Find core instance for CallCompletionRequest"))) {
4005 ast_log_dynamic_level(cc_logger_level,
"Couldn't find a core instance for caller %s\n", device_name);
4012 core_instance->
core_id, device_name);
4015 ast_log_dynamic_level(cc_logger_level,
"Core %d: CallCompletionRequest is only for generic agent types.\n",
4019 cc_unref(core_instance,
"Unref core_instance since CallCompletionRequest was called with native agent");
4024 ast_log_dynamic_level(cc_logger_level,
"Core %d: CallCompletionRequest failed. Too many requests in the system\n",
4029 cc_unref(core_instance,
"Unref core_instance since too many CC requests");
4039 cc_unref(core_instance,
"Done with CallCompletionRequest");
4055 if (!(core_instance =
ao2_t_callback_data(cc_core_instances, 0,
match_agent, device_name, &match_flags,
"Find core instance for CallCompletionCancel"))) {
4056 ast_log_dynamic_level(cc_logger_level,
"Cannot find CC transaction to cancel for caller %s\n", device_name);
4063 ast_log(
LOG_WARNING,
"CallCompletionCancel may only be used for calles with a generic agent\n");
4064 cc_unref(core_instance,
"Unref core instance found during CallCompletionCancel");
4069 res =
ast_cc_failed(core_instance->
core_id,
"Call completion request Cancelled for core ID %d by caller %s",
4070 core_instance->
core_id, device_name);
4071 cc_unref(core_instance,
"Unref core instance found during CallCompletionCancel");
4117 const char *cc_max_requests_str;
4123 ast_log(
LOG_WARNING,
"Could not find valid ccss.conf file. Using cc_max_requests default\n");
4134 global_cc_max_requests = strtol(cc_max_requests_str, &endptr, 10);
4158 while ((child_monitor_iter =
AST_LIST_NEXT(child_monitor_iter, next))) {
4159 if (child_monitor_iter->
parent_id == monitor->
id) {
4184 ast_cli(*cli_fd,
"There are currently no active call completion transactions\n");
4186 ast_cli(*cli_fd,
"%d Call completion transactions\n", count);
4187 ast_cli(*cli_fd,
"Core ID\t\tCaller\t\t\t\tStatus\n");
4188 ast_cli(*cli_fd,
"----------------------------------------------------------------------------\n");
4201 e->
command =
"cc report status";
4203 "Usage: cc report status\n"
4204 " Report the current status of any ongoing CC transactions\n";
4233 if (!core_id || (core_instance->
core_id == *core_id)) {
4242 int wordlen = strlen(word);
4248 cc_unref(core_instance,
"CLI tab completion iteration")) {
4249 char core_id_str[20];
4250 snprintf(core_id_str,
sizeof(core_id_str),
"%d", core_instance->
core_id);
4251 if (!strncmp(word, core_id_str, wordlen) && ++which > state) {
4253 cc_unref(core_instance,
"Found a matching core ID for CLI tab-completion");
4264 static const char *
const option[] = {
"core",
"all", NULL };
4270 "Usage: cc cancel can be used in two ways.\n"
4271 " 1. 'cc cancel core [core ID]' will cancel the CC transaction with\n"
4272 " core ID equal to the specified core ID.\n"
4273 " 2. 'cc cancel all' will cancel all active CC transactions.\n";
4288 if (strcasecmp(a->
argv[2],
"core")) {
4291 core_id = strtol(a->
argv[3], &endptr, 10);
4292 if ((
errno != 0 && core_id == 0) || (endptr == a->
argv[3])) {
4296 }
else if (a->
argc == 3) {
4297 if (strcasecmp(a->
argv[2],
"all")) {
4323 if (cc_sched_thread) {
4326 if (cc_core_taskprocessor) {
4330 if (cc_core_instances) {
4331 ao2_t_ref(cc_core_instances, -1,
"Unref cc_core_instances container in cc_shutdown");
4332 cc_core_instances = NULL;
4346 "Create core instance container"))) {
4351 "Create generic monitor container"))) {
4366 dialed_cc_interface_counter = 1;
static void cc_unique_append(struct ast_str **str, const char *dialstring)
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
int(* request_cc)(struct ast_cc_monitor *monitor, int *available_timer_id)
Request CCSS.
int ast_cc_monitor_failed(int core_id, const char *const monitor_name, const char *const debug,...)
Indicate that a failure has occurred on a specific monitor.
int ast_cc_agent_register(const struct ast_cc_agent_callbacks *callbacks)
Register a set of agent callbacks with the core.
union ast_frame_subclass subclass
#define ao2_t_find(arg1, arg2, arg3, arg4)
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
struct cc_monitor_tree * monitors
static const char * cc_service_to_string(enum ast_cc_service_type service)
static int cc_generic_agent_status_request(struct ast_cc_agent *agent)
enum sip_cc_notify_state state
int ast_set_cc_agent_policy(struct ast_cc_config_params *config, enum ast_cc_agent_policies value)
Set the cc_agent_policy.
#define ast_channel_lock(chan)
static int cc_generic_monitor_cancel_available_timer(struct ast_cc_monitor *monitor, int *sched_id)
static char exten[AST_MAX_EXTENSION]
Main Channel structure associated with a channel.
The payload for an AST_CONTROL_CC frame.
#define AST_CLI_DEFINE(fn, txt,...)
ast_device_state
Device States.
#define CC_OFFER_TIMER_DEFAULT
const char * type
Type of monitor the callbacks belong to.
char * str
Subscriber phone number (Malloced)
static int cc_generic_agent_start_monitoring(struct ast_cc_agent *agent)
void ast_cc_agent_unregister(const struct ast_cc_agent_callbacks *callbacks)
Unregister a set of agent callbacks with the core.
static void cc_recall_ds_destroy(void *data)
#define AST_LIST_LOCK(head)
Locks a list.
static char * handle_cc_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void * generic_recall(void *data)
Asterisk main include file. File version handling, generic pbx functions.
void * private_data
Private data allocated by the callee.
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
int(* status_response)(struct ast_cc_monitor *monitor, enum ast_device_state devstate)
Status response to an ast_cc_monitor_status_request().
struct ast_sched_thread * ast_sched_thread_destroy(struct ast_sched_thread *st)
Destroy a scheduler and its thread.
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
static int cc_generic_monitor_suspend(struct ast_cc_monitor *monitor)
static unsigned int global_cc_max_requests
static enum ast_cc_monitor_policies str_to_monitor_policy(const char *const value)
#define AST_LIST_HEAD(name, type)
Defines a structure to be used to hold a list of specified type.
static const char config[]
struct ast_party_caller caller
Channel Caller ID information.
#define AST_RWLIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a read/write list of specified type, statically initialized...
struct ast_sched_thread * ast_sched_thread_create(void)
Create a scheduler with a dedicated thread.
int ast_cc_failed(int core_id, const char *const debug,...)
Indicate failure has occurred.
struct ast_channel_tech * ast_get_channel_tech(const char *name)
Get a channel technology structure by name.
static struct ast_cc_config_params cc_default_params
void * __ast_malloc(size_t size, const char *file, int lineno, const char *func)
String manipulation functions.
static struct extension_monitor_pvt * extension_monitor_pvt_init(void)
char cid_num[AST_CHANNEL_NAME]
void ast_cc_config_params_destroy(struct ast_cc_config_params *params)
Free memory from CCSS configuration params.
int(* init)(struct ast_cc_agent *agent, struct ast_channel *chan)
CC agent initialization.
static void unsuspend(struct cc_core_instance *core_instance)
#define ao2_t_alloc(data_size, destructor_fn, debug_msg)
Allocate and initialize an object.
int(* party_b_free)(struct ast_cc_agent *agent)
Let the caller know that the callee has become free but that the caller cannot attempt to call back b...
int ast_cc_get_current_core_id(struct ast_channel *chan)
Get the core id for the current call.
#define ast_vasprintf(a, b, c)
static int count_agents_cb(void *obj, void *arg, void *data, int flags)
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
struct ast_cc_monitor_callbacks * callbacks
#define ast_test_flag(p, flag)
static void cc_generic_monitor_destructor(void *private_data)
static int cc_caller_requested(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
int is_valid
Is this structure valid for use in CC_INTERFACES?
int ast_cc_monitor_count(const char *const name, const char *const type)
Return the number of outstanding CC requests to a specific device.
static int dialed_cc_interface_counter
struct ast_party_name name
Subscriber name.
static const int CC_CORE_INSTANCES_BUCKETS
static void * cc_unref(void *obj, const char *debug)
static void cc_interface_destroy(void *data)
struct generic_monitor_instance_list::@233 list
enum ast_cc_agent_policies cc_agent_policy
int ast_taskprocessor_push(struct ast_taskprocessor *tps, int(*task_exe)(void *datap), void *datap)
Push a task into the specified taskprocessor queue and signal the taskprocessor thread.
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
char context[AST_MAX_CONTEXT]
#define ast_set_flag(p, flag)
static struct cc_core_instance * find_cc_core_instance(const int core_id)
int ast_cc_is_config_param(const char *const name)
Is this a CCSS configuration parameter?
descriptor for a cli entry.
unsigned int ast_get_cc_max_monitors(struct ast_cc_config_params *config)
Get the cc_max_monitors.
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
struct ast_cc_config_params * cc_params
static void * cc_ref(void *obj, const char *debug)
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
unsigned int ast_get_cc_recall_timer(struct ast_cc_config_params *config)
Get the cc_recall_timer.
char context[AST_CHANNEL_NAME]
static void dummy(char *unused,...)
static void call_destructor_with_no_monitor(const char *const monitor_type, void *private_data)
struct ast_taskprocessor * ast_taskprocessor_get(const char *name, enum ast_tps_options create)
Get a reference to a taskprocessor with the specified name and create the taskprocessor if necessary...
int parent_interface_id
ID of parent extension.
static struct ast_sched_thread * cc_sched_thread
static int cc_recalling(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
const char * service_string
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
static void generic_monitor_instance_list_destructor(void *obj)
int ast_cc_agent_caller_busy(int core_id, const char *const debug,...)
Indicate that the caller is busy.
static struct ast_cc_monitor * cc_extension_monitor_init(const char *const exten, const char *const context, const unsigned int parent_id)
#define CC_RECALL_TIMER_DEFAULT
int ast_cc_agent_status_response(int core_id, enum ast_device_state devstate)
Response with a caller's current status.
static int generic_agent_devstate_unsubscribe(void *data)
int ast_cc_monitor_request_acked(int core_id, const char *const debug,...)
Indicate that an outbound entity has accepted our CC request.
#define ast_sched_thread_del(st, id)
Delete a scheduler entry.
int(* cc_callback)(struct ast_channel *inbound, const char *dest, ast_cc_callback_fn callback)
Call a function with cc parameters as a function parameter.
#define ao2_t_iterator_next(arg1, arg2)
return a reference to a taskprocessor, create one if it does not exist
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
int ast_cc_monitor_party_b_free(int core_id)
Alert a caller that though the callee has become free, the caller himself is not and may not call bac...
enum ast_cc_service_type service
int ast_devstate_prov_del(const char *label)
Remove device state provider.
int ast_cc_available_timer_expire(const void *data)
Scheduler callback for available timer expiration.
void ast_set_cc_max_monitors(struct ast_cc_config_params *config, unsigned int value)
Set the cc_max_monitors.
unsigned int cc_recall_timer
Structure for a data store type.
const char * monitor_type
char * str
Subscriber name (Malloced)
int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, size_t datalen)
Indicates condition of channel, with payload.
char exten[AST_CHANNEL_NAME]
#define ast_log_dynamic_level(level,...)
Send a log message to a dynamically registered log level.
static void build_cc_interfaces_chanvar(struct ast_cc_monitor *starting_point, struct ast_str **str)
ao2_callback_fn * function
static int count_monitors_cb(void *obj, void *arg, int flags)
#define ao2_t_callback_data(arg1, arg2, arg3, arg4, arg5, arg6)
ao2_callback_data() is a generic function that applies cb_fn() to all objects in a container...
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
unsigned int ccnr_available_timer
struct ast_str * ast_str_create(size_t init_len)
Create a malloc'ed dynamic length string.
int ast_cc_init(void)
Initialize CCSS.
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
#define ast_str_alloca(init_len)
static void cc_extension_monitor_destructor(void *private_data)
Structure for a data store object.
static void cc_extension_monitor_change_is_valid(struct cc_core_instance *core_instance, unsigned int parent_id, const char *const device_name, int is_valid)
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
ast_cc_agent_response_reason
void ast_set_ccnr_available_timer(struct ast_cc_config_params *config, unsigned int value)
Set the ccnr_available_timer.
static const char * monitor_policy_to_str(enum ast_cc_monitor_policies policy)
static int cc_generic_agent_stop_offer_timer(struct ast_cc_agent *agent)
int(* stop_offer_timer)(struct ast_cc_agent *agent)
Stop the offer timer.
static const char * ccreq_app
int ast_queue_cc_frame(struct ast_channel *chan, const char *const monitor_type, const char *const dialstring, enum ast_cc_service_type service, void *private_data)
Queue an AST_CONTROL_CC frame.
static int core_id_counter
int ast_cc_agent_accept_request(int core_id, const char *const debug,...)
Accept inbound CC request.
static struct ast_cc_monitor_callbacks * find_monitor_callbacks(const char *const type)
#define ao2_t_container_alloc(arg1, arg2, arg3, arg4)
Allocate and initialize a container with the desired number of buckets.
static char * complete_core_id(const char *line, const char *word, int pos, int state)
void ast_cli(int fd, const char *fmt,...)
#define ast_cc_config_params_init()
Allocate and initialize an ast_cc_config_params structure.
struct cc_core_instance * core_instance
int ast_cc_agent_recalling(int core_id, const char *const debug,...)
Tell the CC core that a caller is currently recalling.
struct ast_cc_agent_callbacks * callbacks
int ast_unregister_application(const char *app)
Unregister an application.
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
static char cid_num[AST_MAX_EXTENSION]
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
void ast_set_cc_offer_timer(struct ast_cc_config_params *config, unsigned int value)
Set the cc_offer_timer.
#define ast_pthread_create_detached_background(a, b, c, d)
static const char * CC_LOGGER_LEVEL_NAME
void ast_config_destroy(struct ast_config *config)
Destroys a config.
int ast_cc_is_recall(struct ast_channel *chan, int *core_id, const char *const monitor_type)
Decide if a call to a particular channel is a CC recall.
void ast_handle_cc_control_frame(struct ast_channel *inbound, struct ast_channel *outbound, void *frame_data)
Properly react to a CC control frame.
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
ast_cc_monitor_policies
The various possibilities for cc_monitor_policy values.
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
unsigned int ast_get_cc_max_agents(struct ast_cc_config_params *config)
Get the cc_max_agents.
static int cc_build_payload(struct ast_channel *chan, struct ast_cc_config_params *cc_params, const char *monitor_type, const char *const device_name, const char *dialstring, enum ast_cc_service_type service, void *private_data, struct cc_control_payload *payload)
struct ast_cc_config_params * ast_channel_get_cc_config_params(struct ast_channel *chan)
Get the CCSS parameters from a channel.
void ast_cc_call_failed(struct ast_channel *incoming, struct ast_channel *outgoing, const char *const dialstring)
Make CCBS available in the case that ast_call fails.
static void cc_generic_agent_respond(struct ast_cc_agent *agent, enum ast_cc_agent_response_reason reason)
static int generic_monitor_cmp_fn(void *obj, void *arg, int flags)
#define ao2_t_link(arg1, arg2, arg3)
Add an object to a container.
struct ast_channel * ast_channel_get_by_name_prefix(const char *name, size_t name_len)
Find a channel by a name prefix.
char * ast_str_truncate(struct ast_str *buf, ssize_t len)
Truncates the enclosed string to the given length.
static int cc_caller_offered(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
static int generic_monitor_devstate_tp_cb(void *data)
enum ast_cc_monitor_policies ast_get_cc_monitor_policy(struct ast_cc_config_params *config)
Get the cc_monitor_policy.
#define AST_LIST_HEAD_DESTROY(head)
Destroys a list head structure.
int ast_cc_completed(struct ast_channel *chan, const char *const debug,...)
Indicate recall has been acknowledged.
char * ast_cli_complete(const char *word, const char *const choices[], int pos)
void ast_set_cc_callback_macro(struct ast_cc_config_params *config, const char *const value)
Set the callback_macro name.
unsigned int ast_get_ccbs_available_timer(struct ast_cc_config_params *config)
Get the ccbs_available_timer.
void ast_cc_default_config_params(struct ast_cc_config_params *params)
Set the specified CC config params to default values.
static struct ast_cc_monitor * cc_device_monitor_init(const char *const device_name, const char *const dialstring, const struct cc_control_payload *cc_data, int core_id)
static void cc_interface_tree_destroy(void *data)
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
struct ast_party_id id
Caller party ID.
void ast_logger_unregister_level(const char *name)
Unregister a previously registered logger level.
int ast_cc_monitor_register(const struct ast_cc_monitor_callbacks *callbacks)
Register a set of monitor callbacks with the core.
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
static int cc_generic_monitor_request_cc(struct ast_cc_monitor *monitor, int *available_timer_id)
void ast_cc_extension_monitor_add_dialstring(struct ast_channel *incoming, const char *const dialstring, const char *const device_name)
Add a child dialstring to an extension monitor.
static int cccancel_exec(struct ast_channel *chan, const char *data)
unsigned int ast_get_ccnr_available_timer(struct ast_cc_config_params *config)
Get the ccnr_available_timer.
static struct cc_core_instance * cc_core_init_instance(struct ast_channel *caller_chan, struct cc_monitor_tree *called_tree, const int core_id, struct cc_control_payload *cc_data)
char device_name[AST_CHANNEL_NAME]
Name of device to be monitored.
int ast_cc_agent_set_interfaces_chanvar(struct ast_channel *chan)
Set the first level CC_INTERFACES channel variable for a channel.
General Asterisk PBX channel definitions.
char cc_callback_macro[AST_MAX_EXTENSION]
int(* callee_available)(struct ast_cc_agent *agent)
Alert the caller that it is time to try recalling.
static const char * cc_state_to_string(enum cc_state state)
int ast_setup_cc_recall_datastore(struct ast_channel *chan, const int core_id)
Set up a CC recall datastore on a channel.
static int generic_monitor_hash_fn(const void *obj, const int flags)
static void request_cc(struct cc_core_instance *core_instance)
static int cc_generic_agent_recall(struct ast_cc_agent *agent)
char dialstring[AST_CHANNEL_NAME]
Recall dialstring.
static int cc_failed(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
static force_inline int attribute_pure ast_strlen_zero(const char *s)
static int offer_timer_expire(const void *data)
Structure with information about an outbound interface.
static struct generic_monitor_instance_list * create_new_generic_list(struct ast_cc_monitor *monitor)
#define AST_MAX_EXTENSION
#define AST_RWLIST_TRAVERSE
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
static int cc_do_state_change(void *datap)
int ast_cc_get_param(struct ast_cc_config_params *params, const char *const name, char *buf, size_t buf_len)
get a CCSS configuration parameter, given its name
static struct ast_datastore_info dialed_cc_interfaces_info
int ast_cc_build_frame(struct ast_channel *chan, struct ast_cc_config_params *cc_params, const char *monitor_type, const char *const device_name, const char *const dialstring, enum ast_cc_service_type service, void *private_data, struct ast_frame *frame)
Create a CC Control frame.
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
static int cc_stop_ringing(void *data)
int ast_cc_agent_caller_available(int core_id, const char *const debug,...)
Indicate that a previously unavailable caller has become available.
#define AST_RWLIST_REMOVE_CURRENT
int ast_channel_get_cc_agent_type(struct ast_channel *chan, char *agent_type, size_t size)
Find the appropriate CC agent type to use given a channel.
static int cc_monitor_failed(void *data)
int ast_cc_set_param(struct ast_cc_config_params *params, const char *const name, const char *value)
set a CCSS configuration parameter, given its name
unsigned int cc_max_agents
static int cc_caller_busy(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
const char * ast_get_cc_agent_dialstring(struct ast_cc_config_params *config)
Get the cc_agent_dialstring.
cc_state
The states used in the CCSS core state machine.
static struct ast_cli_entry cc_cli[]
static enum ast_cc_agent_policies str_to_agent_policy(const char *const value)
struct ast_event_sub * sub
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
void ast_set_cc_recall_timer(struct ast_cc_config_params *config, unsigned int value)
Set the cc_recall_timer.
int ast_logger_register_level(const char *name)
Register a new logger level.
Structure to describe a channel "technology", ie a channel driver See for examples: ...
Core PBX routines and definitions.
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
static int cc_active(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
int ast_cc_callback(struct ast_channel *inbound, const char *const tech, const char *const dest, ast_cc_callback_fn callback)
Run a callback for potential matching destinations.
#define AST_CC_GENERIC_MONITOR_TYPE
static int cc_request_state_change(enum cc_state state, const int core_id, const char *debug, va_list ap)
static int cc_status_response(void *data)
static int cc_generic_monitor_unsuspend(struct ast_cc_monitor *monitor)
int(* suspend)(struct ast_cc_monitor *monitor)
Suspend monitoring.
int ast_cc_call_init(struct ast_channel *chan, int *ignore_cc)
Start the CC process on a call.
static int ccreq_exec(struct ast_channel *chan, const char *data)
struct ast_cc_config_params * config_params
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
static int cc_interfaces_datastore_init(struct ast_channel *chan)
#define ast_strdupa(s)
duplicate a string in memory from the stack
struct ast_cc_agent_callbacks * callbacks
static void check_callback_sanity(const struct ast_cc_agent_callbacks *callbacks)
const char * ast_get_cc_callback_macro(struct ast_cc_config_params *config)
Get the name of the callback_macro.
const char * type
Type of agent the callbacks belong to.
struct ao2_container * generic_monitors
static struct ast_cc_agent_callbacks generic_agent_callbacks
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define ao2_t_unlink(arg1, arg2, arg3)
Remove an object from a container.
char * ast_tech_to_upper(char *dev_str)
Convert the tech portion of a device string to upper case.
static int(*const state_change_funcs[])(struct cc_core_instance *, struct cc_state_change_args *, enum cc_state previous_state)
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
int ast_cc_offer(struct ast_channel *caller_chan)
Offer CC to a caller.
struct ast_cc_config_params * __ast_cc_config_params_init(const char *file, int line, const char *function)
Allocate and initialize an ast_cc_config_params structure.
char device_name[AST_CHANNEL_NAME]
The name of the device being dialed.
Structure representing an agent.
static void cc_monitor_destroy(void *data)
struct extension_monitor_pvt::@235 child_dialstrings
#define CCNR_AVAILABLE_TIMER_DEFAULT
static unsigned int monitor
static int cc_generic_agent_start_offer_timer(struct ast_cc_agent *agent)
void(* ast_cc_callback_fn)(struct ast_channel *chan, struct ast_cc_config_params *cc_params, const char *monitor_type, const char *const device_name, const char *const dialstring, void *private_data)
Callback made from ast_cc_callback for certain channel types.
static int cc_available(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
static struct generic_monitor_instance_list * find_generic_monitor_instance_list(const char *const device_name)
static int cc_core_instance_cmp_fn(void *obj, void *arg, int flags)
#define CC_MAX_AGENTS_DEFAULT
static int kill_cores(void *obj, void *arg, int flags)
struct ast_cc_agent * ast_cc_agent_callback(int flags, ao2_callback_fn *function, void *arg, const char *const type)
Call a callback on all agents of a specific type.
#define ao2_t_callback(c, flags, cb_fn, arg, tag)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
enum ast_cc_service_type service
Service offered by the endpoint.
const ast_string_field name
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
void(* destructor)(struct ast_cc_agent *agent)
Destroy private data on the agent.
static int cc_status_request(void *data)
The "tree" of interfaces that is dialed.
struct ast_datastore * ast_datastore_alloc(const struct ast_datastore_info *info, const char *uid)
enum cc_state current_state
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
int ast_app_run_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const char *macro_name, const char *macro_args)
Run a macro on a channel, placing an optional second channel into autoservice.
#define ast_channel_unlock(chan)
int ast_cc_monitor_status_request(int core_id)
Request the status of a caller or callers.
struct cc_core_instance * core_instance
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
static void cancel_available_timer(struct cc_core_instance *core_instance)
char macrocontext[AST_MAX_CONTEXT]
char * dialstring
Name that should be used to recall specified interface.
const char * monitor_type
The type of monitor that should be used for this interface.
Call Completion Supplementary Services API.
void(* destructor)(void *private_data)
Destroy private data on the monitor.
unsigned int ast_get_cc_offer_timer(struct ast_cc_config_params *config)
Get the cc_offer_timer.
static struct @228 cc_service_to_string_map[]
#define CC_MAX_MONITORS_DEFAULT
static void suspend(struct cc_core_instance *core_instance)
static const char * agent_policy_to_str(enum ast_cc_agent_policies policy)
static int match_agent(void *obj, void *arg, void *data, int flags)
static void dialed_cc_interfaces_destroy(void *data)
#define DATASTORE_INHERIT_FOREVER
struct cc_monitor_backend * next
An API for managing task processing threads that can be shared across modules.
int ast_cc_request_is_within_limits(void)
Check if the incoming CC request is within the bounds set by the cc_max_requests configuration option...
int(* start_monitoring)(struct ast_cc_agent *agent)
Begin monitoring a busy device.
void ast_cc_copy_config_params(struct ast_cc_config_params *dest, const struct ast_cc_config_params *src)
copy CCSS configuration parameters from one structure to another
struct ast_cc_interface * interface
static int is_state_change_valid(enum cc_state current_state, const enum cc_state new_state, struct ast_cc_agent *agent)
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
static void kill_duplicate_offers(char *caller)
Structure used to handle boolean flags.
private data for generic device monitor
struct cc_monitor_tree * interface_tree
void ast_set_ccbs_available_timer(struct ast_cc_config_params *config, unsigned int value)
Set the ccbs_available_timer.
static void generic_monitor_devstate_cb(const struct ast_event *event, void *userdata)
int(* unsuspend)(struct ast_cc_monitor *monitor)
Unsuspend monitoring.
static char cid_name[AST_MAX_EXTENSION]
static struct ast_cc_agent * cc_agent_init(struct ast_channel *caller_chan, const char *const caller_name, const int core_id, struct cc_monitor_tree *interface_tree)
void ast_set_cc_max_agents(struct ast_cc_config_params *config, unsigned int value)
Set the cc_max_agents.
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
uint32_t ast_event_get_ie_uint(const struct ast_event *event, enum ast_event_ie_type ie_type)
Get the value of an information element that has an integer payload.
void ast_cc_busy_interface(struct ast_channel *inbound, struct ast_cc_config_params *cc_params, const char *monitor_type, const char *const device_name, const char *const dialstring, void *private_data)
Callback made from ast_cc_callback for certain channel types.
char macroexten[AST_MAX_EXTENSION]
static void initialize_cc_max_requests(void)
static void cc_cli_print_monitor_stats(struct ast_cc_monitor *monitor, int fd, int parent_id)
static int cc_generic_agent_init(struct ast_cc_agent *agent, struct ast_channel *chan)
static int cc_offer(const int core_id, const char *const debug,...)
static struct @229 cc_state_to_string_map[]
void ast_ignore_cc(struct ast_channel *chan)
Mark the channel to ignore further CC activity.
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
#define AST_RWLIST_INSERT_TAIL
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
A ast_taskprocessor structure is a singleton by name.
char original_dialstring[AST_CHANNEL_NAME]
the original dialstring used to call a particular device
#define AST_FORMAT_SLINEAR
struct ast_cc_config_params config_params
Configuration parameters used by this endpoint.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
struct ast_channel * ast_request_and_dial(const char *type, format_t format, const struct ast_channel *requestor, void *data, int timeout, int *reason, const char *cid_num, const char *cid_name)
Request a channel of a given type, with data as optional information used by the low level module and...
Standard Command Line Interface.
unsigned int cc_max_monitors
struct ast_event_sub * ast_event_subscribe(enum ast_event_type event_type, ast_event_cb_t cb, const char *description, void *userdata,...)
Subscribe to events.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
static int cc_cli_output_status(void *data)
static void * dialed_cc_interfaces_duplicate(void *data)
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
void * ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
Unreference the specified taskprocessor and its reference count will decrement.
int(* stop_ringing)(struct ast_cc_agent *agent)
Request for an agent's phone to stop ringing.
static int cc_agent_callback_helper(void *obj, void *args, int flags)
Data regarding an extension monitor's child's dialstrings.
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
void ast_set_cc_agent_dialstring(struct ast_cc_config_params *config, const char *const value)
Set the cc_agent_dialstring.
static struct ast_cc_agent_callbacks * find_agent_callbacks(struct ast_channel *chan)
Private data for an extension monitor.
int(* cancel_available_timer)(struct ast_cc_monitor *monitor, int *sched_id)
Cancel the running available timer.
static void cc_core_instance_destructor(void *data)
static struct ao2_container * cc_core_instances
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
char cid_name[AST_CHANNEL_NAME]
static struct ast_datastore_info recall_ds_info
unsigned int flags
Flags for agent operation.
int(* start_offer_timer)(struct ast_cc_agent *agent)
Start the offer timer.
int ast_channel_get_device_name(struct ast_channel *chan, char *device_name, size_t name_buffer_length)
Get a device name given its channel structure.
Data structure associated with a single frame of data.
Internal Asterisk hangup causes.
struct cc_monitor_tree * interface_tree
static int has_device_monitors(struct cc_core_instance *core_instance)
check if the core instance has any device monitors
int ast_register_application2(const char *app, int(*execute)(struct ast_channel *, const char *), const char *synopsis, const char *description, void *mod)
Register an application.
static int print_stats_cb(void *obj, void *arg, int flags)
int(* status_request)(struct ast_cc_agent *agent)
Request the status of the agent's device.
struct ast_event_sub * sub
static struct ast_cc_monitor_callbacks generic_monitor_cbs
static int cc_generic_agent_stop_ringing(struct ast_cc_agent *agent)
ast_cc_agent_policies
The various possibilities for cc_agent_policy values.
static int cc_generic_is_device_available(enum ast_device_state state)
void ast_cc_monitor_unregister(const struct ast_cc_monitor_callbacks *callbacks)
Unregister a set of monitor callbacks with the core.
int ast_sched_thread_add(struct ast_sched_thread *st, int when, ast_sched_cb cb, const void *data)
Add a scheduler entry.
const char * monitor_type
The type of monitor to allocate.
static long count_agents(const char *const caller, const int core_id_exception)
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
enum ast_frame_type frametype
struct ast_cc_agent * agent
void * private_data
Data that is private to a monitor technology.
static const char * cccancel_app
static void cc_generic_agent_destructor(struct ast_cc_agent *agent)
Callbacks defined by CC monitors.
unsigned char valid
TRUE if the name information is valid/present.
unsigned int dial_parent_id
#define CONFIG_STATUS_FILEINVALID
static char context[AST_MAX_CONTEXT]
static void generic_agent_devstate_cb(const struct ast_event *event, void *userdata)
#define CCBS_AVAILABLE_TIMER_DEFAULT
const char * state_string
Generic State IE Used by AST_EVENT_DEVICE_STATE_CHANGE Payload type: UINT The actual state values dep...
const char * ast_event_get_ie_str(const struct ast_event *event, enum ast_event_ie_type ie_type)
Get the value of an information element that has a string payload.
struct ast_cc_monitor_callbacks * callbacks
static int cc_logger_level
enum ast_device_state current_state
static char * handle_cc_kill(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
enum ast_cc_service_type service_offered
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
struct ast_cc_monitor * ast_cc_get_monitor_by_recall_core_id(const int core_id, const char *const device_name)
Get the associated monitor given the device name and core_id.
Asterisk module definitions.
void(* respond)(struct ast_cc_agent *agent, enum ast_cc_agent_response_reason reason)
Respond to a CC request.
int ast_cc_monitor_stop_ringing(int core_id)
Alert a caller to stop ringing.
Device Name Used by AST_EVENT_DEVICE_STATE_CHANGE Payload type: STR.
static snd_pcm_format_t format
union ast_frame::@172 data
enum ast_cc_agent_policies ast_get_cc_agent_policy(struct ast_cc_config_params *config)
Get the cc_agent_policy.
unsigned int ccbs_available_timer
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
static int cc_core_instance_hash_fn(const void *obj, const int flags)
enum ast_device_state new_state
#define GLOBAL_CC_MAX_REQUESTS_DEFAULT
struct ast_event_sub * ast_event_unsubscribe(struct ast_event_sub *event_sub)
Un-subscribe from events.
unsigned char valid
TRUE if the number information is valid/present.
enum ast_device_state devstate
static int cc_request_count
#define AST_RWLIST_TRAVERSE_SAFE_END
static int cc_callee_ready(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
#define AST_CAUSE_CONGESTION
int ast_set_cc_monitor_policy(struct ast_cc_config_params *config, enum ast_cc_monitor_policies value)
Set the cc_monitor_policy.
int( ao2_callback_fn)(void *obj, void *arg, int flags)
Type of a generic callback function.
char exten[AST_MAX_EXTENSION]
int ast_cc_monitor_callee_available(const int core_id, const char *const debug,...)
Alert the core that a device being monitored has become available.
enum ast_cc_monitor_class monitor_class
int ast_set_cc_interfaces_chanvar(struct ast_channel *chan, const char *const extension)
Set the CC_INTERFACES channel variable for a channel using an extension as a starting point...
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
char cc_agent_dialstring[AST_MAX_EXTENSION]
enum ast_cc_monitor_policies cc_monitor_policy
unsigned int cc_offer_timer
static int cc_party_b_free(void *data)
static void cc_shutdown(void)
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
static struct ast_taskprocessor * cc_core_taskprocessor
static void * cc_recall_ds_duplicate(void *data)
struct ast_party_number number
Subscriber phone number.
static int cc_complete(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
static void agent_destroy(void *data)