401 {
CC_CALLER_BUSY,
"Callee was ready, but caller is now unavailable"},
461 "Calling provided agent callback function"))) {
463 cc_unref(core_instance,
"agent callback done with the core_instance");
495 const char *
name = arg;
496 unsigned long match_flags = *(
unsigned long *)data;
497 int possible_match = 0;
507 if (!possible_match) {
533 const char *
name = arg;
549#define CC_AVAILABLE_DEVSTATE_DEFAULT AST_DEVICE_NOT_INUSE
550#define CC_CALLER_OFFERED_DEVSTATE_DEFAULT AST_DEVICE_NOT_INUSE
551#define CC_CALLER_REQUESTED_DEVSTATE_DEFAULT AST_DEVICE_NOT_INUSE
552#define CC_ACTIVE_DEVSTATE_DEFAULT AST_DEVICE_INUSE
553#define CC_CALLEE_READY_DEVSTATE_DEFAULT AST_DEVICE_RINGING
554#define CC_CALLER_BUSY_DEVSTATE_DEFAULT AST_DEVICE_ONHOLD
555#define CC_RECALLING_DEVSTATE_DEFAULT AST_DEVICE_RINGING
556#define CC_COMPLETE_DEVSTATE_DEFAULT AST_DEVICE_NOT_INUSE
557#define CC_FAILED_DEVSTATE_DEFAULT AST_DEVICE_NOT_INUSE
609 "Find Core Instance for ccss_device_state reqeust.");
610 if (!core_instance) {
612 "Couldn't find a core instance for caller %s\n", device_name);
617 "Core %d: Found core_instance for caller %s in state %s\n",
622 "Core %d: Device State is only for generic agent types.\n",
624 cc_unref(core_instance,
"Unref core_instance since ccss_device_state was called with native agent");
628 cc_unref(core_instance,
"Unref core_instance done with ccss_device_state");
629 return cc_current_state;
648 "Notification of CCSS state change to '%s', device state '%s' for device '%s'\n",
654#define CC_OFFER_TIMER_DEFAULT 20
655#define CCNR_AVAILABLE_TIMER_DEFAULT 7200
656#define CCBS_AVAILABLE_TIMER_DEFAULT 4800
657#define CC_RECALL_TIMER_DEFAULT 20
658#define CC_MAX_AGENTS_DEFAULT 5
659#define CC_MAX_MONITORS_DEFAULT 5
660#define GLOBAL_CC_MAX_REQUESTS_DEFAULT 20
671 .cc_callback_sub =
"",
672 .cc_agent_dialstring =
"",
699 if (!strcasecmp(
value,
"never")) {
701 }
else if (!strcasecmp(
value,
"native")) {
703 }
else if (!strcasecmp(
value,
"generic")) {
713 if (!strcasecmp(
value,
"never")) {
715 }
else if (!strcasecmp(
value,
"native")) {
717 }
else if (!strcasecmp(
value,
"generic")) {
719 }
else if (!strcasecmp(
value,
"always")) {
759 char *
buf,
size_t buf_len)
763 if (!strcasecmp(
name,
"cc_callback_sub")) {
765 }
else if (!strcasecmp(
name,
"cc_agent_policy")) {
767 }
else if (!strcasecmp(
name,
"cc_monitor_policy")) {
769 }
else if (!strcasecmp(
name,
"cc_agent_dialstring")) {
781 if (!strcasecmp(
name,
"cc_offer_timer")) {
783 }
else if (!strcasecmp(
name,
"ccnr_available_timer")) {
785 }
else if (!strcasecmp(
name,
"ccbs_available_timer")) {
787 }
else if (!strcasecmp(
name,
"cc_max_agents")) {
789 }
else if (!strcasecmp(
name,
"cc_max_monitors")) {
791 }
else if (!strcasecmp(
name,
"cc_recall_timer")) {
802 const char *
const value)
804 unsigned int value_as_uint;
805 if (!strcasecmp(
name,
"cc_agent_policy")) {
807 }
else if (!strcasecmp(
name,
"cc_monitor_policy")) {
809 }
else if (!strcasecmp(
name,
"cc_agent_dialstring")) {
811 }
else if (!strcasecmp(
name,
"cc_callback_sub")) {
816 if (sscanf(
value,
"%30u", &value_as_uint) != 1) {
820 if (!strcasecmp(
name,
"cc_offer_timer")) {
822 }
else if (!strcasecmp(
name,
"ccnr_available_timer")) {
824 }
else if (!strcasecmp(
name,
"ccbs_available_timer")) {
826 }
else if (!strcasecmp(
name,
"cc_max_agents")) {
828 }
else if (!strcasecmp(
name,
"cc_max_monitors")) {
830 }
else if (!strcasecmp(
name,
"cc_recall_timer")) {
842 return (!strcasecmp(
name,
"cc_agent_policy") ||
843 !strcasecmp(
name,
"cc_monitor_policy") ||
844 !strcasecmp(
name,
"cc_offer_timer") ||
845 !strcasecmp(
name,
"ccnr_available_timer") ||
846 !strcasecmp(
name,
"ccbs_available_timer") ||
847 !strcasecmp(
name,
"cc_max_agents") ||
848 !strcasecmp(
name,
"cc_max_monitors") ||
849 !strcasecmp(
name,
"cc_callback_sub") ||
850 !strcasecmp(
name,
"cc_agent_dialstring") ||
851 !strcasecmp(
name,
"cc_recall_timer"));
861 return config->cc_agent_policy;
878 return config->cc_monitor_policy;
895 return config->cc_offer_timer;
910 return config->ccnr_available_timer;
917 ast_log(
LOG_WARNING,
"0 is an invalid value for ccnr_available_timer. Retaining value as %u\n",
config->ccnr_available_timer);
925 return config->cc_recall_timer;
932 ast_log(
LOG_WARNING,
"0 is an invalid value for ccnr_available_timer. Retaining value as %u\n",
config->cc_recall_timer);
940 return config->ccbs_available_timer;
947 ast_log(
LOG_WARNING,
"0 is an invalid value for ccbs_available_timer. Retaining value as %u\n",
config->ccbs_available_timer);
955 return config->cc_agent_dialstring;
961 config->cc_agent_dialstring[0] =
'\0';
969 return config->cc_max_agents;
979 return config->cc_max_monitors;
989 return config->cc_callback_sub;
995 config->cc_callback_sub[0] =
'\0';
1007 if (!message_type) {
1012 "core_id", core_id);
1394 if (!generic_list) {
1399 cc_unref(generic_list,
"Failed to strdup the monitor's device name");
1406 if (!device_specific_topic) {
1411 cc_unref(generic_list,
"Failed to subscribe to device state");
1418 return generic_list;
1439 cc_unref(generic_list,
"Kill reference of generic list in devstate taskprocessor callback");
1458 cc_unref(generic_list,
"Kill reference of generic list in devstate taskprocessor callback");
1475 if (dev_state->
eid) {
1480 ao2_t_ref(dev_state, +1,
"Bumping dev_state ref for cc_core_taskprocessor");
1493 cc_unref(monitor,
"Unref reference from scheduler\n");
1509 if (!(gen_mon_pvt =
ast_calloc(1,
sizeof(*gen_mon_pvt)))) {
1528 if (!(generic_instance =
ast_calloc(1,
sizeof(*generic_instance)))) {
1532 cc_unref(generic_list,
"Generic monitor instance failed to allocate");
1543 if (*available_timer_id == -1) {
1544 cc_unref(monitor,
"Failed to schedule available timer. (monitor)");
1545 cc_unref(generic_list,
"Failed to schedule available timer. (generic_list)");
1556 cc_unref(generic_list,
"Finished with monitor instance reference in request cc callback");
1582 cc_unref(generic_list,
"Device is in use. Nothing to do. Unref generic list.");
1597 cc_unref(generic_list,
"Done with generic list in suspend callback");
1607 if (!generic_list) {
1625 cc_unref(generic_list,
"Done with generic list in cc_generic_monitor_unsuspend");
1640 cc_unref(monitor,
"Remove scheduler's reference to the monitor");
1652 if (!private_data) {
1704 "availability due to other instance's failure.");
1710 cc_unref(generic_list,
"Done with generic list in generic monitor destructor");
1805 if (!extension_pvt) {
1844 cc_unref(monitor,
"Destroying all monitors");
1946 if (!new_cc_interfaces) {
1955 return new_cc_interfaces;
1968 .
type =
"Dial CC Interfaces",
1999 cc_interfaces = cc_datastore->
data;
2006 if (monitor->
id ==
id) {
2017 if (!(child_dialstring =
ast_calloc(1,
sizeof(*child_dialstring)))) {
2035 if (monitor_iter->
id == parent_id) {
2040 if (!monitor_iter) {
2076 "Allocating new ast_cc_interface"))) {
2081 cc_unref(cc_interface,
"failed to allocate the monitor, so unref the interface");
2086 cc_unref(monitor,
"Failed to initialize extension monitor private data. uref monitor");
2087 cc_unref(cc_interface,
"Failed to initialize extension monitor private data. unref cc_interface");
2142 cc_unref(monitor,
"Could not allocate the dialed interfaces datastore. Unreffing monitor");
2148 "Allocate monitor tree"))) {
2150 cc_unref(monitor,
"Could not allocate monitor tree on dialed interfaces datastore. Unreffing monitor");
2158 cc_ref(monitor,
"List's reference to extension monitor");
2167 cc_unref(monitor,
"Unreffing allocation's reference");
2196 if (!monitor_callbacks) {
2231 size_t device_name_len = strlen(device_name);
2235 "Allocating new ast_cc_interface"))) {
2240 cc_unref(cc_interface,
"Failed to allocate config params, unref interface");
2245 cc_unref(cc_interface,
"Failed to allocate monitor, unref interface");
2250 cc_unref(monitor,
"Failed to copy dialable name. Unref monitor");
2251 cc_unref(cc_interface,
"Failed to copy dialable name");
2256 cc_unref(monitor,
"Failed to find monitor callbacks. Unref monitor");
2257 cc_unref(cc_interface,
"Failed to find monitor callbacks");
2308 ast_log(
LOG_WARNING,
"Unable to retrieve CC datastore while processing CC frame from '%s'. CC services will be unavailable.\n", device_name);
2314 cc_interfaces = cc_datastore->
data;
2316 if (cc_interfaces->
ignore) {
2334 if (!core_instance) {
2336 cc_interfaces->
core_id, cc_data);
2337 if (!core_instance) {
2338 cc_interfaces->
ignore = 1;
2357 core_instance->
core_id, device_name);
2359 cc_unref(core_instance,
"Returning early from ast_handle_cc_control_frame. Unref core_instance");
2367 ast_log(
LOG_WARNING,
"Unable to create CC device interface for '%s'. CC services will be unavailable on this interface.\n", device_name);
2368 cc_unref(core_instance,
"Returning early from ast_handle_cc_control_frame. Unref core_instance");
2374 cc_ref(monitor,
"monitor tree's reference to the monitor");
2382 cc_unref(core_instance,
"Done with core_instance after handling CC control frame");
2383 cc_unref(monitor,
"Unref reference from allocating monitor");
2452 cc_ref(monitor,
"monitor tree's reference to the monitor");
2456 cc_unref(monitor,
"Unref monitor's allocation reference");
2477 cc_interfaces = datastore->
data;
2478 core_id_return = cc_interfaces->
ignore ? -1 : cc_interfaces->
core_id;
2480 return core_id_return;
2484static long count_agents(
const char *
const caller,
const int core_id_exception)
2533 const char *
const caller_name,
const int core_id,
2540 "Allocating new ast_cc_agent"))) {
2549 cc_unref(agent,
"Could not get channel config params.");
2553 cc_unref(agent,
"Could not init agent config params.");
2559 cc_unref(agent,
"Could not find agent callbacks.");
2565 cc_unref(agent,
"Agent init callback failed.");
2677 cc_unref(agent,
"Remove scheduler's reference to the agent");
2706 cc_unref(agent,
"Remove scheduler's reference to the agent");
2747 cc_unref(agent,
"Done holding ref for subscription");
2754 if (dev_state->
eid) {
2759 new_state = dev_state->
state;
2776 ast_str_set(&
str, 0,
"Agent monitoring %s device state since it is busy\n",
2780 if (!device_specific_topic) {
2790 cc_ref(agent,
"Ref agent for subscription");
2812 if ((target = strchr(interface,
'/'))) {
2899 if (core_instance->
agent) {
2900 cc_unref(core_instance->
agent,
"Core instance is done with the agent now");
2948 core_instance->
core_id = core_id;
2950 cc_unref(core_instance,
"Couldn't allocate agent, unref core_instance");
2954 core_instance->
monitors =
cc_ref(called_tree,
"Core instance getting ref to monitor tree");
2958 return core_instance;
2971 switch (new_state) {
3085 cc_unref(monitor_iter,
"request_cc failed. Unref list's reference to monitor");
3102 ast_log(
LOG_WARNING,
"Cannot request CC since there is no more room for requests\n");
3123 cc_unref(monitor_iter,
"unsuspend failed. Unref list's reference to monitor");
3170 cc_unref(monitor_iter,
"suspend failed. Unref list's reference to monitor");
3203 cc_unref(monitor_iter,
"cancel_available_timer failed. Unref list's reference to monitor");
3210 ast_cc_failed(core_instance->
core_id,
"All device monitors failed to cancel their available timers");
3262 core_instance =
args->core_instance;
3276 cc_unref(core_instance,
"Unref core instance from when it was found earlier");
3291 cc_unref(core_instance,
"Unref since state change has completed");
3328 vsnprintf(
args->debug, debuglen,
debug, ap);
3367 .
type =
"cc_recall",
3378 if (!recall_datastore) {
3382 if (!(recall_data =
ast_calloc(1,
sizeof(*recall_data)))) {
3394 "Bump refcount for monitor tree for recall datastore");
3396 recall_datastore->
data = recall_data;
3401 cc_unref(core_instance,
"Recall datastore set up. No need for core_instance ref");
3412 int core_id_candidate;
3425 recall_data = recall_datastore->
data;
3427 if (recall_data->
ignore) {
3436 if (!recall_data->
nested) {
3465 core_id_candidate = recall_data->
core_id;
3491 if (!core_instance) {
3499 cc_ref(monitor_iter,
"Hand the requester of the monitor a reference");
3504 cc_unref(core_instance,
"Done with core instance ref in ast_cc_get_monitor_by_recall_core_id");
3505 return monitor_iter;
3532 snprintf(dialstring_search,
sizeof(dialstring_search),
"%s%c",
dialstring,
'&');
3558 int top_level_id = starting_point->
id;
3577 if (monitor_iter->
parent_id == top_level_id) {
3615 recall_data = recall_datastore->
data;
3617 core_id = recall_data->
core_id;
3652 recall_data = recall_datastore->
data;
3654 core_id = recall_data->
core_id;
3664 if (!monitor_iter) {
3694 cc_interfaces = cc_datastore->
data;
3695 cc_interfaces->
ignore = 1;
3699 recall_cc_data = cc_recall_datastore->
data;
3700 recall_cc_data->
ignore = 1;
3710 va_start(ap,
debug);
3722 char cc_is_offerable;
3730 cc_interfaces = datastore->
data;
3735 if (cc_is_offerable) {
3746 va_start(ap,
debug);
3757 va_start(ap,
debug);
3768 va_start(ap,
debug);
3779 va_start(ap,
debug);
3790 va_start(ap,
debug);
3801 va_start(ap,
debug);
3821 recall_data = recall_datastore->
data;
3838 va_start(ap,
debug);
3849 va_start(ap,
debug);
3868 if (!core_instance) {
3871 "Core %d: Could not find core instance for device %s '%s'\n",
3888 cc_unref(monitor_iter,
"Monitor reported failure. Unref list's reference.");
3898 cc_unref(core_instance,
"Finished with core_instance in cc_monitor_failed\n");
3912 if (!(failure_data =
ast_calloc(1,
sizeof(*failure_data)))) {
3921 va_start(ap,
debug);
3947 cc_unref(core_instance,
"Status request finished. Unref core instance");
3956 if (!core_instance) {
3962 cc_unref(core_instance,
"Unref core instance. ast_taskprocessor_push failed");
3984 cc_unref(core_instance,
"Stop ringing finished. Unref core_instance");
3993 if (!core_instance) {
3999 cc_unref(core_instance,
"Unref core instance. ast_taskprocessor_push failed");
4012 cc_unref(core_instance,
"Party B free finished. Unref core_instance");
4021 if (!core_instance) {
4027 cc_unref(core_instance,
"Unref core instance. ast_taskprocessor_push failed");
4054 cc_unref(core_instance,
"Status response finished. Unref core instance");
4070 if (!core_instance) {
4075 args->core_instance = core_instance;
4076 args->devstate = devstate;
4080 cc_unref(core_instance,
"Unref core instance. ast_taskprocessor_push failed");
4087 const char *monitor_type,
const char *
const device_name,
const char * dialstring,
4100 cc_interfaces = datastore->
data;
4128 ast_log(
LOG_NOTICE,
"Not queuing a CC frame for device %s since it already has its maximum monitors allocated\n", device_name);
4142 const char *monitor_type,
const char *
const device_name,
4159 frame->
datalen =
sizeof(*payload);
4198 const char *monitor_type,
const char *
const device_name,
const char *
const dialstring,
void *private_data)
4240 core_instance->
core_id, device_name);
4247 cc_unref(core_instance,
"Unref core_instance since CallCompletionRequest was called with native agent");
4257 cc_unref(core_instance,
"Unref core_instance since too many CC requests");
4267 cc_unref(core_instance,
"Done with CallCompletionRequest");
4291 ast_log(
LOG_WARNING,
"CallCompletionCancel may only be used for calles with a generic agent\n");
4292 cc_unref(core_instance,
"Unref core instance found during CallCompletionCancel");
4297 res =
ast_cc_failed(core_instance->
core_id,
"Call completion request Cancelled for core ID %d by caller %s",
4298 core_instance->
core_id, device_name);
4299 cc_unref(core_instance,
"Unref core instance found during CallCompletionCancel");
4345 const char *cc_max_requests_str;
4351 ast_log(
LOG_WARNING,
"Could not find valid ccss.conf file. Using cc_max_requests default\n");
4379 const char *cc_devstate_str;
4409 "Could not find valid ccss.conf file. Using cc_[state]_devstate defaults\n");