2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2010, Digium, Inc.
6 * Mark Michelson <mmichelson@digium.com>
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
20 * \brief Call Completion Supplementary Services implementation
21 * \author Mark Michelson <mmichelson@digium.com>
26 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
28 #include "asterisk/astobj2.h"
29 #include "asterisk/strings.h"
30 #include "asterisk/ccss.h"
31 #include "asterisk/channel.h"
32 #include "asterisk/pbx.h"
33 #include "asterisk/utils.h"
34 #include "asterisk/taskprocessor.h"
35 #include "asterisk/event.h"
36 #include "asterisk/module.h"
37 #include "asterisk/app.h"
38 #include "asterisk/cli.h"
39 #include "asterisk/manager.h"
40 #include "asterisk/causes.h"
43 <application name="CallCompletionRequest" language="en_US">
45 Request call completion service for previous call
49 <para>Request call completion service for a previously failed
53 <application name="CallCompletionCancel" language="en_US">
55 Cancel call completion service
59 <para>Cancel a Call Completion Request.</para>
64 /* These are some file-scoped variables. It would be
65 * nice to define them closer to their first usage, but since
66 * they are used in many places throughout the file, defining
67 * them here at the top is easiest.
71 * The sched_thread ID used for all generic CC timeouts
73 static struct ast_sched_thread *cc_sched_thread;
75 * Counter used to create core IDs for CC calls. Each new
76 * core ID is created by atomically adding 1 to the core_id_counter
78 static int core_id_counter;
80 * Taskprocessor from which all CC agent and monitor callbacks
83 static struct ast_taskprocessor *cc_core_taskprocessor;
85 * Name printed on all CC log messages.
87 static const char *CC_LOGGER_LEVEL_NAME = "CC";
89 * Logger level registered by the CC core.
91 static int cc_logger_level;
93 * Parsed configuration value for cc_max_requests
95 static unsigned int global_cc_max_requests;
97 * The current number of CC requests in the system
99 static int cc_request_count;
101 #define cc_ref(obj, debug) ({ao2_t_ref((obj), +1, (debug)); (obj);})
102 #define cc_unref(obj, debug) ({ao2_t_ref((obj), -1, (debug)); NULL;})
107 * \brief A structure for holding the configuration parameters
110 struct ast_cc_config_params {
111 enum ast_cc_agent_policies cc_agent_policy;
112 enum ast_cc_monitor_policies cc_monitor_policy;
113 unsigned int cc_offer_timer;
114 unsigned int ccnr_available_timer;
115 unsigned int ccbs_available_timer;
116 unsigned int cc_recall_timer;
117 unsigned int cc_max_agents;
118 unsigned int cc_max_monitors;
119 char cc_callback_macro[AST_MAX_EXTENSION];
120 char cc_agent_dialstring[AST_MAX_EXTENSION];
125 * \brief The states used in the CCSS core state machine
127 * For more information, see doc/CCSS_architecture.pdf
130 /*! Entered when it is determined that CCSS may be used for the call */
132 /*! Entered when a CCSS agent has offered CCSS to a caller */
134 /*! Entered when a CCSS agent confirms that a caller has
137 /*! Entered when a CCSS monitor confirms acknowledgment of an
138 * outbound CCSS request */
140 /*! Entered when a CCSS monitor alerts the core that the called party
141 * has become available */
143 /*! Entered when a CCSS agent alerts the core that the calling party
144 * may not be recalled because he is unavailable
147 /*! Entered when a CCSS agent alerts the core that the calling party
148 * is attempting to recall the called party
151 /*! Entered when an application alerts the core that the calling party's
152 * recall attempt has had a call progress response indicated
155 /*! Entered any time that something goes wrong during the process, thus
156 * resulting in the failure of the attempted CCSS transaction. Note also
157 * that cancellations of CC are treated as failures.
163 * \brief The payload for an AST_CONTROL_CC frame
166 * This contains all the necessary data regarding
167 * a called device so that the CC core will be able
168 * to allocate the proper monitoring resources.
170 struct cc_control_payload {
172 * \brief The type of monitor to allocate.
175 * The type of monitor to allocate. This is a string which corresponds
176 * to a set of monitor callbacks registered. Examples include "generic"
179 * \note This really should be an array of characters in case this payload
180 * is sent accross an IAX2 link. However, this would not make too much sense
181 * given this type may not be recognized by the other end.
182 * Protection may be necessary to prevent it from being transmitted.
184 * In addition the following other problems are also possible:
185 * 1) Endian issues with the integers/enums stored in the config_params.
186 * 2) Alignment padding issues for the element types.
188 const char *monitor_type;
190 * \brief Private data allocated by the callee
193 * All channel drivers that monitor endpoints will need to allocate
194 * data that is not usable by the CC core. In most cases, some or all
195 * of this data is allocated at the time that the channel driver offers
196 * CC to the caller. There are many opportunities for failures to occur
197 * between when a channel driver offers CC and when a monitor is actually
198 * allocated to watch the endpoint. For this reason, the channel driver
199 * must give the core a pointer to the private data that was allocated so
200 * that the core can call back into the channel driver to destroy it if
201 * a failure occurs. If no private data has been allocated at the time that
202 * CC is offered, then it is perfectly acceptable to pass NULL for this
207 * \brief Service offered by the endpoint
210 * This indicates the type of call completion service offered by the
211 * endpoint. This data is not crucial to the machinations of the CC core,
212 * but it is helpful for debugging purposes.
214 enum ast_cc_service_type service;
216 * \brief Configuration parameters used by this endpoint
219 * Each time an endpoint offers call completion, it must provide its call
220 * completion configuration parameters. This is because settings may be different
221 * depending on the circumstances.
223 struct ast_cc_config_params config_params;
225 * \brief ID of parent extension
228 * This is the only datum that the CC core derives on its own and is not
229 * provided by the offerer of CC. This provides the core with information on
230 * which extension monitor is the most immediate parent of this device.
232 int parent_interface_id;
234 * \brief Name of device to be monitored
237 * The device name by which this monitored endpoint will be referred in the
238 * CC core. It is highly recommended that this device name is derived by using
239 * the function ast_channel_get_device_name.
241 char device_name[AST_CHANNEL_NAME];
243 * \brief Recall dialstring
246 * Certain channel drivers (DAHDI in particular) will require that a special
247 * dialstring be used to indicate that the outgoing call is to interpreted as
248 * a CC recall. If the channel driver has such a requirement, then this is
249 * where that special recall dialstring is placed. If no special dialstring
250 * is to be used, then the channel driver must provide the original dialstring
251 * used to call this endpoint.
253 char dialstring[AST_CHANNEL_NAME];
257 * \brief The "tree" of interfaces that is dialed.
260 * Though this is a linked list, it is logically treated
261 * as a tree of monitors. Each monitor has an id and a parent_id
262 * associated with it. The id is a unique ID for that monitor, and
263 * the parent_id is the unique ID of the monitor's parent in the
264 * tree. The tree is structured such that all of a parent's children
265 * will appear after the parent in the tree. However, it cannot be
266 * guaranteed exactly where after the parent the children are.
268 * The tree is reference counted since several threads may need
269 * to use it, and it may last beyond the lifetime of a single
272 AST_LIST_HEAD(cc_monitor_tree, ast_cc_monitor);
274 static const int CC_CORE_INSTANCES_BUCKETS = 17;
275 static struct ao2_container *cc_core_instances;
277 struct cc_core_instance {
279 * Unique identifier for this instance of the CC core.
283 * The current state for this instance of the CC core.
285 enum cc_state current_state;
287 * The CC agent in use for this call
289 struct ast_cc_agent *agent;
291 * Reference to the monitor tree formed during the initial call
293 struct cc_monitor_tree *monitors;
298 * \brief Request that the core change states
299 * \param state The state to which we wish to change
300 * \param core_id The unique identifier for this instance of the CCSS core state machine
301 * \param debug Optional message explaining the reason for the state change
302 * \param ap varargs list
303 * \retval 0 State change successfully queued
304 * \retval -1 Unable to queue state change request
306 static int __attribute__((format(printf, 3, 0))) cc_request_state_change(enum cc_state state, const int core_id, const char *debug, va_list ap);
310 * \brief create a new instance of the CC core and an agent for the calling channel
312 * This function will check to make sure that the incoming channel
313 * is allowed to request CC by making sure that the incoming channel
314 * has not exceeded its maximum number of allowed agents.
316 * Should that check pass, the core instance is created, and then the
317 * agent for the channel.
319 * \param caller_chan The incoming channel for this particular call
320 * \param called_tree A reference to the tree of called devices. The agent
321 * will gain a reference to this tree as well
322 * \param core_id The core_id that this core_instance will assume
323 * \retval NULL Failed to create the core instance either due to memory allocation
324 * errors or due to the agent count for the caller being too high
325 * \retval non-NULL A reference to the newly created cc_core_instance
327 static struct cc_core_instance *cc_core_init_instance(struct ast_channel *caller_chan,
328 struct cc_monitor_tree *called_tree, const int core_id, struct cc_control_payload *cc_data);
330 static const struct {
331 enum ast_cc_service_type service;
332 const char *service_string;
333 } cc_service_to_string_map[] = {
334 {AST_CC_NONE, "NONE"},
335 {AST_CC_CCBS, "CCBS"},
336 {AST_CC_CCNR, "CCNR"},
337 {AST_CC_CCNL, "CCNL"},
340 static const struct {
342 const char *state_string;
343 } cc_state_to_string_map[] = {
344 {CC_AVAILABLE, "CC is available"},
345 {CC_CALLER_OFFERED, "CC offered to caller"},
346 {CC_CALLER_REQUESTED, "CC requested by caller"},
347 {CC_ACTIVE, "CC accepted by callee"},
348 {CC_CALLEE_READY, "Callee has become available"},
349 {CC_CALLER_BUSY, "Callee was ready, but caller is now unavailable"},
350 {CC_RECALLING, "Caller is attempting to recall"},
351 {CC_COMPLETE, "Recall complete"},
352 {CC_FAILED, "CC has failed"},
355 static const char *cc_state_to_string(enum cc_state state)
357 return cc_state_to_string_map[state].state_string;
360 static const char *cc_service_to_string(enum ast_cc_service_type service)
362 return cc_service_to_string_map[service].service_string;
365 static int cc_core_instance_hash_fn(const void *obj, const int flags)
367 const struct cc_core_instance *core_instance = obj;
368 return core_instance->core_id;
371 static int cc_core_instance_cmp_fn(void *obj, void *arg, int flags)
373 struct cc_core_instance *core_instance1 = obj;
374 struct cc_core_instance *core_instance2 = arg;
376 return core_instance1->core_id == core_instance2->core_id ? CMP_MATCH | CMP_STOP : 0;
379 static struct cc_core_instance *find_cc_core_instance(const int core_id)
381 struct cc_core_instance finder = {.core_id = core_id,};
383 return ao2_t_find(cc_core_instances, &finder, OBJ_POINTER, "Finding a core_instance");
386 struct cc_callback_helper {
387 ao2_callback_fn *function;
392 static int cc_agent_callback_helper(void *obj, void *args, int flags)
394 struct cc_core_instance *core_instance = obj;
395 struct cc_callback_helper *helper = args;
397 if (strcmp(core_instance->agent->callbacks->type, helper->type)) {
401 return helper->function(core_instance->agent, helper->args, flags);
404 struct ast_cc_agent *ast_cc_agent_callback(int flags, ao2_callback_fn *function, void *args, const char * const type)
406 struct cc_callback_helper helper = {.function = function, .args = args, .type = type};
407 struct cc_core_instance *core_instance;
408 if ((core_instance = ao2_t_callback(cc_core_instances, flags, cc_agent_callback_helper, &helper,
409 "Calling provided agent callback function"))) {
410 struct ast_cc_agent *agent = cc_ref(core_instance->agent, "An outside entity needs the agent");
411 cc_unref(core_instance, "agent callback done with the core_instance");
418 /* Only match agents that have not yet
421 MATCH_NO_REQUEST = (1 << 0),
422 /* Only match agents that have made
425 MATCH_REQUEST = (1 << 1),
428 /* ao2_callbacks for cc_core_instances */
432 * \brief find a core instance based on its agent
434 * The match flags tell whether we wish to find core instances
435 * that have a monitor or core instances that do not. Core instances
436 * with no monitor are core instances for which a caller has not yet
437 * requested CC. Core instances with a monitor are ones for which the
438 * caller has requested CC.
440 static int match_agent(void *obj, void *arg, void *data, int flags)
442 struct cc_core_instance *core_instance = obj;
443 const char *name = arg;
444 unsigned long match_flags = *(unsigned long *)data;
445 int possible_match = 0;
447 if ((match_flags & MATCH_NO_REQUEST) && core_instance->current_state < CC_CALLER_REQUESTED) {
451 if ((match_flags & MATCH_REQUEST) && core_instance->current_state >= CC_CALLER_REQUESTED) {
455 if (!possible_match) {
459 if (!strcmp(core_instance->agent->device_name, name)) {
460 return CMP_MATCH | CMP_STOP;
465 struct count_agents_cb_data {
467 int core_id_exception;
472 * \brief Count the number of agents a specific interface is using
474 * We're only concerned with the number of agents that have requested
475 * CC, so we restrict our search to core instances which have a non-NULL
478 static int count_agents_cb(void *obj, void *arg, void *data, int flags)
480 struct cc_core_instance *core_instance = obj;
481 const char *name = arg;
482 struct count_agents_cb_data *cb_data = data;
484 if (cb_data->core_id_exception == core_instance->core_id) {
485 ast_log_dynamic_level(cc_logger_level, "Found agent with core_id %d but not counting it toward total\n", core_instance->core_id);
489 if (core_instance->current_state >= CC_CALLER_REQUESTED && !strcmp(core_instance->agent->device_name, name)) {
495 static const unsigned int CC_OFFER_TIMER_DEFAULT = 20u;
496 static const unsigned int CCNR_AVAILABLE_TIMER_DEFAULT = 7200u;
497 static const unsigned int CCBS_AVAILABLE_TIMER_DEFAULT = 4800u;
498 static const unsigned int CC_RECALL_TIMER_DEFAULT = 20u;
499 static const unsigned int CC_MAX_AGENTS_DEFAULT = 5u;
500 static const unsigned int CC_MAX_MONITORS_DEFAULT = 5u;
501 static const unsigned int GLOBAL_CC_MAX_REQUESTS_DEFAULT = 20u;
503 struct ast_cc_config_params *__ast_cc_config_params_init(const char *file, int line, const char *function)
505 #if defined(__AST_DEBUG_MALLOC)
506 struct ast_cc_config_params *params = __ast_calloc(1, sizeof(*params), file, line, function);
508 struct ast_cc_config_params *params = ast_calloc(1, sizeof(*params));
515 /* Yeah, I could use the get/set functions, but what's the point since
516 * I have direct access to the structure fields in this file.
518 params->cc_agent_policy = AST_CC_AGENT_NEVER;
519 params->cc_monitor_policy = AST_CC_MONITOR_NEVER;
520 params->cc_offer_timer = CC_OFFER_TIMER_DEFAULT;
521 params->ccnr_available_timer = CCNR_AVAILABLE_TIMER_DEFAULT;
522 params->ccbs_available_timer = CCBS_AVAILABLE_TIMER_DEFAULT;
523 params->cc_recall_timer = CC_RECALL_TIMER_DEFAULT;
524 params->cc_max_agents = CC_MAX_AGENTS_DEFAULT;
525 params->cc_max_monitors = CC_MAX_MONITORS_DEFAULT;
526 /* No need to set cc_callback_macro since calloc will 0 it out anyway */
530 void ast_cc_config_params_destroy(struct ast_cc_config_params *params)
535 static enum ast_cc_agent_policies str_to_agent_policy(const char * const value)
537 if (!strcasecmp(value, "never")) {
538 return AST_CC_AGENT_NEVER;
539 } else if (!strcasecmp(value, "native")) {
540 return AST_CC_AGENT_NATIVE;
541 } else if (!strcasecmp(value, "generic")) {
542 return AST_CC_AGENT_GENERIC;
544 ast_log(LOG_WARNING, "%s is an invalid value for cc_agent_policy. Switching to 'never'\n", value);
545 return AST_CC_AGENT_NEVER;
549 static enum ast_cc_monitor_policies str_to_monitor_policy(const char * const value)
551 if (!strcasecmp(value, "never")) {
552 return AST_CC_MONITOR_NEVER;
553 } else if (!strcasecmp(value, "native")) {
554 return AST_CC_MONITOR_NATIVE;
555 } else if (!strcasecmp(value, "generic")) {
556 return AST_CC_MONITOR_GENERIC;
557 } else if (!strcasecmp(value, "always")) {
558 return AST_CC_MONITOR_ALWAYS;
560 ast_log(LOG_WARNING, "%s is an invalid value for cc_monitor_policy. Switching to 'never'\n", value);
561 return AST_CC_MONITOR_NEVER;
565 static const char *agent_policy_to_str(enum ast_cc_agent_policies policy)
568 case AST_CC_AGENT_NEVER:
570 case AST_CC_AGENT_NATIVE:
572 case AST_CC_AGENT_GENERIC:
575 /* This should never happen... */
580 static const char *monitor_policy_to_str(enum ast_cc_monitor_policies policy)
583 case AST_CC_MONITOR_NEVER:
585 case AST_CC_MONITOR_NATIVE:
587 case AST_CC_MONITOR_GENERIC:
589 case AST_CC_MONITOR_ALWAYS:
592 /* This should never happen... */
596 int ast_cc_get_param(struct ast_cc_config_params *params, const char * const name,
597 char *buf, size_t buf_len)
599 const char *value = NULL;
600 if (!strcasecmp(name, "cc_callback_macro")) {
601 value = ast_get_cc_callback_macro(params);
602 } else if (!strcasecmp(name, "cc_agent_policy")) {
603 value = agent_policy_to_str(ast_get_cc_agent_policy(params));
604 } else if (!strcasecmp(name, "cc_monitor_policy")) {
605 value = monitor_policy_to_str(ast_get_cc_monitor_policy(params));
606 } else if (!strcasecmp(name, "cc_agent_dialstring")) {
607 value = ast_get_cc_agent_dialstring(params);
610 if (!ast_strlen_zero(value)) {
611 ast_copy_string(buf, value, buf_len);
615 /* The rest of these are all ints of some sort and require some
619 if (!strcasecmp(name, "cc_offer_timer")) {
620 snprintf(buf, buf_len, "%u", ast_get_cc_offer_timer(params));
621 } else if (!strcasecmp(name, "ccnr_available_timer")) {
622 snprintf(buf, buf_len, "%u", ast_get_ccnr_available_timer(params));
623 } else if (!strcasecmp(name, "ccbs_available_timer")) {
624 snprintf(buf, buf_len, "%u", ast_get_ccbs_available_timer(params));
625 } else if (!strcasecmp(name, "cc_max_agents")) {
626 snprintf(buf, buf_len, "%u", ast_get_cc_max_agents(params));
627 } else if (!strcasecmp(name, "cc_max_monitors")) {
628 snprintf(buf, buf_len, "%u", ast_get_cc_max_monitors(params));
629 } else if (!strcasecmp(name, "cc_recall_timer")) {
630 snprintf(buf, buf_len, "%u", ast_get_cc_recall_timer(params));
632 ast_log(LOG_WARNING, "%s is not a valid CC parameter. Ignoring.\n", name);
639 int ast_cc_set_param(struct ast_cc_config_params *params, const char * const name,
640 const char * const value)
642 unsigned int value_as_uint;
643 if (!strcasecmp(name, "cc_agent_policy")) {
644 return ast_set_cc_agent_policy(params, str_to_agent_policy(value));
645 } else if (!strcasecmp(name, "cc_monitor_policy")) {
646 return ast_set_cc_monitor_policy(params, str_to_monitor_policy(value));
647 } else if (!strcasecmp(name, "cc_agent_dialstring")) {
648 ast_set_cc_agent_dialstring(params, value);
649 } else if (!strcasecmp(name, "cc_callback_macro")) {
650 ast_set_cc_callback_macro(params, value);
654 if (!sscanf(value, "%30u", &value_as_uint) == 1) {
658 if (!strcasecmp(name, "cc_offer_timer")) {
659 ast_set_cc_offer_timer(params, value_as_uint);
660 } else if (!strcasecmp(name, "ccnr_available_timer")) {
661 ast_set_ccnr_available_timer(params, value_as_uint);
662 } else if (!strcasecmp(name, "ccbs_available_timer")) {
663 ast_set_ccbs_available_timer(params, value_as_uint);
664 } else if (!strcasecmp(name, "cc_max_agents")) {
665 ast_set_cc_max_agents(params, value_as_uint);
666 } else if (!strcasecmp(name, "cc_max_monitors")) {
667 ast_set_cc_max_monitors(params, value_as_uint);
668 } else if (!strcasecmp(name, "cc_recall_timer")) {
669 ast_set_cc_recall_timer(params, value_as_uint);
671 ast_log(LOG_WARNING, "%s is not a valid CC parameter. Ignoring.\n", name);
678 int ast_cc_is_config_param(const char * const name)
680 return (!strcasecmp(name, "cc_agent_policy") ||
681 !strcasecmp(name, "cc_monitor_policy") ||
682 !strcasecmp(name, "cc_offer_timer") ||
683 !strcasecmp(name, "ccnr_available_timer") ||
684 !strcasecmp(name, "ccbs_available_timer") ||
685 !strcasecmp(name, "cc_max_agents") ||
686 !strcasecmp(name, "cc_max_monitors") ||
687 !strcasecmp(name, "cc_callback_macro") ||
688 !strcasecmp(name, "cc_agent_dialstring") ||
689 !strcasecmp(name, "cc_recall_timer"));
692 void ast_cc_copy_config_params(struct ast_cc_config_params *dest, const struct ast_cc_config_params *src)
697 enum ast_cc_agent_policies ast_get_cc_agent_policy(struct ast_cc_config_params *config)
699 return config->cc_agent_policy;
702 int ast_set_cc_agent_policy(struct ast_cc_config_params *config, enum ast_cc_agent_policies value)
704 /* Screw C and its weak type checking for making me have to do this
705 * validation at runtime.
707 if (value < AST_CC_AGENT_NEVER || value > AST_CC_AGENT_GENERIC) {
710 config->cc_agent_policy = value;
714 enum ast_cc_monitor_policies ast_get_cc_monitor_policy(struct ast_cc_config_params *config)
716 return config->cc_monitor_policy;
719 int ast_set_cc_monitor_policy(struct ast_cc_config_params *config, enum ast_cc_monitor_policies value)
721 /* Screw C and its weak type checking for making me have to do this
722 * validation at runtime.
724 if (value < AST_CC_MONITOR_NEVER || value > AST_CC_MONITOR_ALWAYS) {
727 config->cc_monitor_policy = value;
731 unsigned int ast_get_cc_offer_timer(struct ast_cc_config_params *config)
733 return config->cc_offer_timer;
736 void ast_set_cc_offer_timer(struct ast_cc_config_params *config, unsigned int value)
738 /* 0 is an unreasonable value for any timer. Stick with the default */
740 ast_log(LOG_WARNING, "0 is an invalid value for cc_offer_timer. Retaining value as %u\n", config->cc_offer_timer);
743 config->cc_offer_timer = value;
746 unsigned int ast_get_ccnr_available_timer(struct ast_cc_config_params *config)
748 return config->ccnr_available_timer;
751 void ast_set_ccnr_available_timer(struct ast_cc_config_params *config, unsigned int value)
753 /* 0 is an unreasonable value for any timer. Stick with the default */
755 ast_log(LOG_WARNING, "0 is an invalid value for ccnr_available_timer. Retaining value as %u\n", config->ccnr_available_timer);
758 config->ccnr_available_timer = value;
761 unsigned int ast_get_cc_recall_timer(struct ast_cc_config_params *config)
763 return config->cc_recall_timer;
766 void ast_set_cc_recall_timer(struct ast_cc_config_params *config, unsigned int value)
768 /* 0 is an unreasonable value for any timer. Stick with the default */
770 ast_log(LOG_WARNING, "0 is an invalid value for ccnr_available_timer. Retaining value as %u\n", config->cc_recall_timer);
773 config->cc_recall_timer = value;
776 unsigned int ast_get_ccbs_available_timer(struct ast_cc_config_params *config)
778 return config->ccbs_available_timer;
781 void ast_set_ccbs_available_timer(struct ast_cc_config_params *config, unsigned int value)
783 /* 0 is an unreasonable value for any timer. Stick with the default */
785 ast_log(LOG_WARNING, "0 is an invalid value for ccbs_available_timer. Retaining value as %u\n", config->ccbs_available_timer);
788 config->ccbs_available_timer = value;
791 const char *ast_get_cc_agent_dialstring(struct ast_cc_config_params *config)
793 return config->cc_agent_dialstring;
796 void ast_set_cc_agent_dialstring(struct ast_cc_config_params *config, const char *const value)
798 if (ast_strlen_zero(value)) {
799 config->cc_agent_dialstring[0] = '\0';
801 ast_copy_string(config->cc_agent_dialstring, value, sizeof(config->cc_agent_dialstring));
805 unsigned int ast_get_cc_max_agents(struct ast_cc_config_params *config)
807 return config->cc_max_agents;
810 void ast_set_cc_max_agents(struct ast_cc_config_params *config, unsigned int value)
812 config->cc_max_agents = value;
815 unsigned int ast_get_cc_max_monitors(struct ast_cc_config_params *config)
817 return config->cc_max_monitors;
820 void ast_set_cc_max_monitors(struct ast_cc_config_params *config, unsigned int value)
822 config->cc_max_monitors = value;
825 const char *ast_get_cc_callback_macro(struct ast_cc_config_params *config)
827 return config->cc_callback_macro;
830 void ast_set_cc_callback_macro(struct ast_cc_config_params *config, const char * const value)
832 if (ast_strlen_zero(value)) {
833 config->cc_callback_macro[0] = '\0';
835 ast_copy_string(config->cc_callback_macro, value, sizeof(config->cc_callback_macro));
839 struct cc_monitor_backend {
840 AST_LIST_ENTRY(cc_monitor_backend) next;
841 const struct ast_cc_monitor_callbacks *callbacks;
844 AST_RWLIST_HEAD_STATIC(cc_monitor_backends, cc_monitor_backend);
846 int ast_cc_monitor_register(const struct ast_cc_monitor_callbacks *callbacks)
848 struct cc_monitor_backend *backend = ast_calloc(1, sizeof(*backend));
854 backend->callbacks = callbacks;
856 AST_RWLIST_WRLOCK(&cc_monitor_backends);
857 AST_RWLIST_INSERT_TAIL(&cc_monitor_backends, backend, next);
858 AST_RWLIST_UNLOCK(&cc_monitor_backends);
862 static const struct ast_cc_monitor_callbacks *find_monitor_callbacks(const char * const type)
864 struct cc_monitor_backend *backend;
865 const struct ast_cc_monitor_callbacks *callbacks = NULL;
867 AST_RWLIST_RDLOCK(&cc_monitor_backends);
868 AST_RWLIST_TRAVERSE(&cc_monitor_backends, backend, next) {
869 if (!strcmp(backend->callbacks->type, type)) {
870 ast_log_dynamic_level(cc_logger_level, "Returning monitor backend %s\n", backend->callbacks->type);
871 callbacks = backend->callbacks;
875 AST_RWLIST_UNLOCK(&cc_monitor_backends);
879 void ast_cc_monitor_unregister(const struct ast_cc_monitor_callbacks *callbacks)
881 struct cc_monitor_backend *backend;
882 AST_RWLIST_WRLOCK(&cc_monitor_backends);
883 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&cc_monitor_backends, backend, next) {
884 if (backend->callbacks == callbacks) {
885 AST_RWLIST_REMOVE_CURRENT(next);
890 AST_RWLIST_TRAVERSE_SAFE_END;
891 AST_RWLIST_UNLOCK(&cc_monitor_backends);
894 struct cc_agent_backend {
895 AST_LIST_ENTRY(cc_agent_backend) next;
896 const struct ast_cc_agent_callbacks *callbacks;
899 AST_RWLIST_HEAD_STATIC(cc_agent_backends, cc_agent_backend);
901 int ast_cc_agent_register(const struct ast_cc_agent_callbacks *callbacks)
903 struct cc_agent_backend *backend = ast_calloc(1, sizeof(*backend));
909 backend->callbacks = callbacks;
910 AST_RWLIST_WRLOCK(&cc_agent_backends);
911 AST_RWLIST_INSERT_TAIL(&cc_agent_backends, backend, next);
912 AST_RWLIST_UNLOCK(&cc_agent_backends);
916 void ast_cc_agent_unregister(const struct ast_cc_agent_callbacks *callbacks)
918 struct cc_agent_backend *backend;
919 AST_RWLIST_WRLOCK(&cc_agent_backends);
920 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&cc_agent_backends, backend, next) {
921 if (backend->callbacks == callbacks) {
922 AST_RWLIST_REMOVE_CURRENT(next);
927 AST_RWLIST_TRAVERSE_SAFE_END;
928 AST_RWLIST_UNLOCK(&cc_agent_backends);
931 static const struct ast_cc_agent_callbacks *find_agent_callbacks(struct ast_channel *chan)
933 struct cc_agent_backend *backend;
934 const struct ast_cc_agent_callbacks *callbacks = NULL;
935 struct ast_cc_config_params *cc_params;
938 cc_params = ast_channel_get_cc_config_params(chan);
942 switch (ast_get_cc_agent_policy(cc_params)) {
943 case AST_CC_AGENT_GENERIC:
944 ast_copy_string(type, "generic", sizeof(type));
946 case AST_CC_AGENT_NATIVE:
947 ast_channel_get_cc_agent_type(chan, type, sizeof(type));
950 ast_log_dynamic_level(cc_logger_level, "Not returning agent callbacks since this channel is configured not to have a CC agent\n");
954 AST_RWLIST_RDLOCK(&cc_agent_backends);
955 AST_RWLIST_TRAVERSE(&cc_agent_backends, backend, next) {
956 if (!strcmp(backend->callbacks->type, type)) {
957 ast_log_dynamic_level(cc_logger_level, "Returning agent backend %s\n", backend->callbacks->type);
958 callbacks = backend->callbacks;
962 AST_RWLIST_UNLOCK(&cc_agent_backends);
966 static int cc_generic_monitor_request_cc(struct ast_cc_monitor *monitor, int *available_timer_id);
967 static int cc_generic_monitor_suspend(struct ast_cc_monitor *monitor);
968 static int cc_generic_monitor_unsuspend(struct ast_cc_monitor *monitor);
969 static int cc_generic_monitor_cancel_available_timer(struct ast_cc_monitor *monitor, int *sched_id);
970 static void cc_generic_monitor_destructor(void *private_data);
972 static struct ast_cc_monitor_callbacks generic_monitor_cbs = {
974 .request_cc = cc_generic_monitor_request_cc,
975 .suspend = cc_generic_monitor_suspend,
976 .unsuspend = cc_generic_monitor_unsuspend,
977 .cancel_available_timer = cc_generic_monitor_cancel_available_timer,
978 .destructor = cc_generic_monitor_destructor,
981 struct ao2_container *generic_monitors;
983 struct generic_monitor_instance {
987 AST_LIST_ENTRY(generic_monitor_instance) next;
990 struct generic_monitor_instance_list {
991 const char *device_name;
992 enum ast_device_state current_state;
993 struct ast_event_sub *sub;
994 AST_LIST_HEAD_NOLOCK(, generic_monitor_instance) list;
998 * \brief private data for generic device monitor
1000 struct generic_monitor_pvt {
1002 * We need the device name during destruction so we
1003 * can find the appropriate item to destroy.
1005 const char *device_name;
1007 * We need the core ID for similar reasons. Once we
1008 * find the appropriate item in our ao2_container, we
1009 * need to remove the appropriate cc_monitor from the
1015 static int generic_monitor_hash_fn(const void *obj, const int flags)
1017 const struct generic_monitor_instance_list *generic_list = obj;
1018 return ast_str_hash(generic_list->device_name);
1021 static int generic_monitor_cmp_fn(void *obj, void *arg, int flags)
1023 const struct generic_monitor_instance_list *generic_list1 = obj;
1024 const struct generic_monitor_instance_list *generic_list2 = arg;
1026 return !strcmp(generic_list1->device_name, generic_list2->device_name) ? CMP_MATCH | CMP_STOP : 0;
1029 static struct generic_monitor_instance_list *find_generic_monitor_instance_list(const char * const device_name)
1031 struct generic_monitor_instance_list finder = {.device_name = device_name};
1033 return ao2_t_find(generic_monitors, &finder, OBJ_POINTER, "Finding generic monitor instance list");
1036 static void generic_monitor_instance_list_destructor(void *obj)
1038 struct generic_monitor_instance_list *generic_list = obj;
1039 struct generic_monitor_instance *generic_instance;
1041 generic_list->sub = ast_event_unsubscribe(generic_list->sub);
1042 while ((generic_instance = AST_LIST_REMOVE_HEAD(&generic_list->list, next))) {
1043 ast_free(generic_instance);
1045 ast_free((char *)generic_list->device_name);
1048 static void generic_monitor_devstate_cb(const struct ast_event *event, void *userdata);
1049 static struct generic_monitor_instance_list *create_new_generic_list(struct ast_cc_monitor *monitor)
1051 struct generic_monitor_instance_list *generic_list = ao2_t_alloc(sizeof(*generic_list),
1052 generic_monitor_instance_list_destructor, "allocate generic monitor instance list");
1054 if (!generic_list) {
1058 if (!(generic_list->device_name = ast_strdup(monitor->interface->device_name))) {
1059 cc_unref(generic_list, "Failed to strdup the monitor's device name");
1063 if (!(generic_list->sub = ast_event_subscribe(AST_EVENT_DEVICE_STATE, generic_monitor_devstate_cb,
1064 "Requesting CC", NULL, AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR,
1065 monitor->interface->device_name, AST_EVENT_IE_END))) {
1066 cc_unref(generic_list, "Failed to subscribe to device state");
1069 generic_list->current_state = ast_device_state(monitor->interface->device_name);
1070 ao2_t_link(generic_monitors, generic_list, "linking new generic monitor instance list");
1071 return generic_list;
1074 struct generic_tp_cb_data {
1075 const char *device_name;
1076 enum ast_device_state new_state;
1079 static int generic_monitor_devstate_tp_cb(void *data)
1081 struct generic_tp_cb_data *gtcd = data;
1082 enum ast_device_state new_state = gtcd->new_state;
1083 enum ast_device_state previous_state = gtcd->new_state;
1084 const char *monitor_name = gtcd->device_name;
1085 struct generic_monitor_instance_list *generic_list;
1086 struct generic_monitor_instance *generic_instance;
1088 if (!(generic_list = find_generic_monitor_instance_list(monitor_name))) {
1089 /* The most likely cause for this is that we destroyed the monitor in the
1090 * time between subscribing to its device state and the time this executes.
1091 * Not really a big deal.
1093 ast_free((char *) gtcd->device_name);
1098 if (generic_list->current_state == new_state) {
1099 /* The device state hasn't actually changed, so we don't really care */
1100 cc_unref(generic_list, "Kill reference of generic list in devstate taskprocessor callback");
1101 ast_free((char *) gtcd->device_name);
1106 previous_state = generic_list->current_state;
1107 generic_list->current_state = new_state;
1109 if ((new_state == AST_DEVICE_NOT_INUSE || new_state == AST_DEVICE_UNKNOWN) &&
1110 (previous_state == AST_DEVICE_INUSE || previous_state == AST_DEVICE_UNAVAILABLE ||
1111 previous_state == AST_DEVICE_BUSY)) {
1112 AST_LIST_TRAVERSE(&generic_list->list, generic_instance, next) {
1113 if (!generic_instance->is_suspended && generic_instance->monitoring) {
1114 generic_instance->monitoring = 0;
1115 ast_cc_monitor_callee_available(generic_instance->core_id, "Generic monitored party has become available");
1120 cc_unref(generic_list, "Kill reference of generic list in devstate taskprocessor callback");
1121 ast_free((char *) gtcd->device_name);
1126 static void generic_monitor_devstate_cb(const struct ast_event *event, void *userdata)
1128 /* Wow, it's cool that we've picked up on a state change, but we really want
1129 * the actual work to be done in the core's taskprocessor execution thread
1130 * so that all monitor operations can be serialized. Locks?! We don't need
1131 * no steenkin' locks!
1133 struct generic_tp_cb_data *gtcd = ast_calloc(1, sizeof(*gtcd));
1139 if (!(gtcd->device_name = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_DEVICE)))) {
1143 gtcd->new_state = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE);
1145 if (ast_taskprocessor_push(cc_core_taskprocessor, generic_monitor_devstate_tp_cb, gtcd)) {
1146 ast_free((char *)gtcd->device_name);
1151 int ast_cc_available_timer_expire(const void *data)
1153 struct ast_cc_monitor *monitor = (struct ast_cc_monitor *) data;
1155 monitor->available_timer_id = -1;
1156 res = ast_cc_monitor_failed(monitor->core_id, monitor->interface->device_name, "Available timer expired for monitor");
1157 cc_unref(monitor, "Unref reference from scheduler\n");
1161 static int cc_generic_monitor_request_cc(struct ast_cc_monitor *monitor, int *available_timer_id)
1163 struct generic_monitor_instance_list *generic_list;
1164 struct generic_monitor_instance *generic_instance;
1165 struct generic_monitor_pvt *gen_mon_pvt;
1166 enum ast_cc_service_type service = monitor->service_offered;
1169 /* First things first. Native channel drivers will have their private data allocated
1170 * at the time that they tell the core that they can offer CC. Generic is quite a bit
1171 * different, and we wait until this point to allocate our private data.
1173 if (!(gen_mon_pvt = ast_calloc(1, sizeof(*gen_mon_pvt)))) {
1177 if (!(gen_mon_pvt->device_name = ast_strdup(monitor->interface->device_name))) {
1178 ast_free(gen_mon_pvt);
1182 gen_mon_pvt->core_id = monitor->core_id;
1184 monitor->private_data = gen_mon_pvt;
1186 if (!(generic_list = find_generic_monitor_instance_list(monitor->interface->device_name))) {
1187 if (!(generic_list = create_new_generic_list(monitor))) {
1192 if (!(generic_instance = ast_calloc(1, sizeof(*generic_instance)))) {
1193 /* The generic monitor destructor will take care of the appropriate
1196 cc_unref(generic_list, "Generic monitor instance failed to allocate");
1199 generic_instance->core_id = monitor->core_id;
1200 generic_instance->monitoring = 1;
1201 AST_LIST_INSERT_TAIL(&generic_list->list, generic_instance, next);
1202 when = service == AST_CC_CCBS ? ast_get_ccbs_available_timer(monitor->interface->config_params) :
1203 ast_get_ccnr_available_timer(monitor->interface->config_params);
1205 *available_timer_id = ast_sched_thread_add(cc_sched_thread, when * 1000,
1206 ast_cc_available_timer_expire, cc_ref(monitor, "Give the scheduler a monitor reference"));
1207 if (*available_timer_id == -1) {
1208 cc_unref(monitor, "Failed to schedule available timer. (monitor)");
1209 cc_unref(generic_list, "Failed to schedule available timer. (generic_list)");
1212 ast_cc_monitor_request_acked(monitor->core_id, "Generic monitor for %s subscribed to device state.",
1213 monitor->interface->device_name);
1214 cc_unref(generic_list, "Finished with monitor instance reference in request cc callback");
1218 static int cc_generic_monitor_suspend(struct ast_cc_monitor *monitor)
1220 struct generic_monitor_instance_list *generic_list;
1221 struct generic_monitor_instance *generic_instance;
1222 enum ast_device_state state = ast_device_state(monitor->interface->device_name);
1224 if (!(generic_list = find_generic_monitor_instance_list(monitor->interface->device_name))) {
1228 /* First we need to mark this particular monitor as being suspended. */
1229 AST_LIST_TRAVERSE(&generic_list->list, generic_instance, next) {
1230 if (generic_instance->core_id == monitor->core_id) {
1231 generic_instance->is_suspended = 1;
1236 /* If the device being suspended is currently in use, then we don't need to
1237 * take any further actions
1239 if (state != AST_DEVICE_NOT_INUSE && state != AST_DEVICE_UNKNOWN) {
1240 cc_unref(generic_list, "Device is in use. Nothing to do. Unref generic list.");
1244 /* If the device is not in use, though, then it may be possible to report the
1245 * device's availability using a different monitor which is monitoring the
1249 AST_LIST_TRAVERSE(&generic_list->list, generic_instance, next) {
1250 if (!generic_instance->is_suspended) {
1251 ast_cc_monitor_callee_available(generic_instance->core_id, "Generic monitored party has become available");
1255 cc_unref(generic_list, "Done with generic list in suspend callback");
1259 static int cc_generic_monitor_unsuspend(struct ast_cc_monitor *monitor)
1261 struct generic_monitor_instance *generic_instance;
1262 struct generic_monitor_instance_list *generic_list = find_generic_monitor_instance_list(monitor->interface->device_name);
1263 enum ast_device_state state = ast_device_state(monitor->interface->device_name);
1265 if (!generic_list) {
1268 /* If the device is currently available, we can immediately announce
1271 if (state == AST_DEVICE_NOT_INUSE || state == AST_DEVICE_UNKNOWN) {
1272 ast_cc_monitor_callee_available(monitor->core_id, "Generic monitored party has become available");
1275 /* In addition, we need to mark this generic_monitor_instance as not being suspended anymore */
1276 AST_LIST_TRAVERSE(&generic_list->list, generic_instance, next) {
1277 if (generic_instance->core_id == monitor->core_id) {
1278 generic_instance->is_suspended = 0;
1279 generic_instance->monitoring = 1;
1283 cc_unref(generic_list, "Done with generic list in cc_generic_monitor_unsuspend");
1287 static int cc_generic_monitor_cancel_available_timer(struct ast_cc_monitor *monitor, int *sched_id)
1289 ast_assert(sched_id != NULL);
1291 if (*sched_id == -1) {
1295 ast_log_dynamic_level(cc_logger_level, "Core %d: Canceling generic monitor available timer for monitor %s\n",
1296 monitor->core_id, monitor->interface->device_name);
1297 if (!ast_sched_thread_del(cc_sched_thread, *sched_id)) {
1298 cc_unref(monitor, "Remove scheduler's reference to the monitor");
1304 static void cc_generic_monitor_destructor(void *private_data)
1306 struct generic_monitor_pvt *gen_mon_pvt = private_data;
1307 struct generic_monitor_instance_list *generic_list;
1308 struct generic_monitor_instance *generic_instance;
1310 if (!private_data) {
1311 /* If the private data is NULL, that means that the monitor hasn't even
1312 * been created yet, but that the destructor was called. While this sort
1313 * of behavior is useful for native monitors, with a generic one, there is
1314 * nothing in particular to do.
1319 ast_log_dynamic_level(cc_logger_level, "Core %d: Destroying generic monitor %s\n",
1320 gen_mon_pvt->core_id, gen_mon_pvt->device_name);
1322 if (!(generic_list = find_generic_monitor_instance_list(gen_mon_pvt->device_name))) {
1323 /* If there's no generic list, that means that the monitor is being destroyed
1324 * before we actually got to request CC. Not a biggie. Same in the situation
1325 * below if the list traversal should complete without finding an entry.
1327 ast_free((char *)gen_mon_pvt->device_name);
1328 ast_free(gen_mon_pvt);
1332 AST_LIST_TRAVERSE_SAFE_BEGIN(&generic_list->list, generic_instance, next) {
1333 if (generic_instance->core_id == gen_mon_pvt->core_id) {
1334 AST_LIST_REMOVE_CURRENT(next);
1335 ast_free(generic_instance);
1339 AST_LIST_TRAVERSE_SAFE_END;
1341 if (AST_LIST_EMPTY(&generic_list->list)) {
1342 /* No more monitors with this device name exist. Time to unlink this
1343 * list from the container
1345 ao2_t_unlink(generic_monitors, generic_list, "Generic list is empty. Unlink it from the container");
1347 cc_unref(generic_list, "Done with generic list in generic monitor destructor");
1348 ast_free((char *)gen_mon_pvt->device_name);
1349 ast_free(gen_mon_pvt);
1352 static void cc_interface_destroy(void *data)
1354 struct ast_cc_interface *interface = data;
1355 ast_log_dynamic_level(cc_logger_level, "Destroying cc interface %s\n", interface->device_name);
1356 ast_cc_config_params_destroy(interface->config_params);
1360 * \brief Data regarding an extension monitor's child's dialstrings
1363 * In developing CCSS, we had most aspects of its operation finished,
1364 * but there was one looming problem that we had failed to get right.
1365 * In our design document, we stated that when a CC recall occurs, all
1366 * endpoints that had been dialed originally would be called back.
1367 * Unfortunately, our implementation only allowed for devices which had
1368 * active monitors to inhabit the CC_INTERFACES channel variable, thus
1369 * making the automated recall only call monitored devices.
1371 * Devices that were not CC-capable, or devices which failed CC at some
1372 * point during the process would not make it into the CC_INTERFACES
1373 * channel variable. This struct is meant as a remedy for the problem.
1375 struct extension_child_dialstring {
1377 * \brief the original dialstring used to call a particular device
1380 * When someone dials a particular endpoint, the dialstring used in
1381 * the dialplan is copied into this buffer. What's important here is
1382 * that this is the ORIGINAL dialstring, not the dialstring saved on
1383 * a device monitor. The dialstring on a device monitor is what should
1384 * be used when recalling that device. The two dialstrings may not be
1387 * By keeping a copy of the original dialstring used, we can fall back
1388 * to using it if the device either does not ever offer CC or if the
1389 * device at some point fails for some reason, such as a timer expiration.
1391 char original_dialstring[AST_CHANNEL_NAME];
1393 * \brief The name of the device being dialed
1396 * This serves mainly as a key when searching for a particular dialstring.
1397 * For instance, let's say that we have called device SIP/400@somepeer. This
1398 * device offers call completion, but then due to some unforeseen circumstance,
1399 * this device backs out and makes CC unavailable. When that happens, we need
1400 * to find the dialstring that corresponds to that device, and we use the
1401 * stored device name as a way to find it.
1403 * Note that there is one particular case where the device name stored here
1404 * will be empty. This is the case where we fail to request a channel, but we
1405 * still can make use of generic call completion. In such a case, since we never
1406 * were able to request the channel, we can't find what its device name is. In
1407 * this case, however, it is not important because the dialstring is guaranteed
1408 * to be the same both here and in the device monitor.
1410 char device_name[AST_CHANNEL_NAME];
1412 * \brief Is this structure valid for use in CC_INTERFACES?
1415 * When this structure is first created, all information stored here is planned
1416 * to be used, so we set the is_valid flag. However, if a device offers call
1417 * completion, it will potentially have its own dialstring to use for the recall,
1418 * so we find this structure and clear the is_valid flag. By clearing the is_valid
1419 * flag, we won't try to populate the CC_INTERFACES variable with the dialstring
1420 * stored in this struct. Now, if later, the device which had offered CC should fail,
1421 * perhaps due to a timer expiration, then we need to re-set the is_valid flag. This
1422 * way, we still will end up placing a call to the device again, and the dialstring
1423 * used will be the same as was originally used.
1426 AST_LIST_ENTRY(extension_child_dialstring) next;
1430 * \brief Private data for an extension monitor
1432 struct extension_monitor_pvt {
1433 AST_LIST_HEAD_NOLOCK(, extension_child_dialstring) child_dialstrings;
1436 static void cc_extension_monitor_destructor(void *private_data)
1438 struct extension_monitor_pvt *extension_pvt = private_data;
1439 struct extension_child_dialstring *child_dialstring;
1441 /* This shouldn't be possible, but I'm paranoid */
1442 if (!extension_pvt) {
1446 while ((child_dialstring = AST_LIST_REMOVE_HEAD(&extension_pvt->child_dialstrings, next))) {
1447 ast_free(child_dialstring);
1449 ast_free(extension_pvt);
1452 static void cc_monitor_destroy(void *data)
1454 struct ast_cc_monitor *monitor = data;
1455 /* During the monitor creation process, it is possible for this
1456 * function to be called prior to when callbacks are assigned
1457 * to the monitor. Also, extension monitors do not have callbacks
1458 * assigned to them, so we wouldn't want to segfault when we try
1459 * to destroy one of them.
1461 ast_log_dynamic_level(cc_logger_level, "Core %d: Calling destructor for monitor %s\n",
1462 monitor->core_id, monitor->interface->device_name);
1463 if (monitor->interface->monitor_class == AST_CC_EXTENSION_MONITOR) {
1464 cc_extension_monitor_destructor(monitor->private_data);
1466 if (monitor->callbacks) {
1467 monitor->callbacks->destructor(monitor->private_data);
1469 cc_unref(monitor->interface, "Unreffing tree's reference to interface");
1470 ast_free(monitor->dialstring);
1473 static void cc_interface_tree_destroy(void *data)
1475 struct cc_monitor_tree *cc_interface_tree = data;
1476 struct ast_cc_monitor *monitor;
1477 while ((monitor = AST_LIST_REMOVE_HEAD(cc_interface_tree, next))) {
1478 if (monitor->callbacks) {
1479 monitor->callbacks->cancel_available_timer(monitor, &monitor->available_timer_id);
1481 cc_unref(monitor, "Destroying all monitors");
1483 AST_LIST_HEAD_DESTROY(cc_interface_tree);
1487 * This counter is used for assigning unique ids
1488 * to CC-enabled dialed interfaces.
1490 static int dialed_cc_interface_counter;
1494 * \brief data stored in CC datastore
1496 * The datastore creates a list of interfaces that were
1497 * dialed, including both extensions and devices. In addition
1498 * to the intrinsic data of the tree, some extra information
1499 * is needed for use by app_dial.
1501 struct dialed_cc_interfaces {
1503 * This value serves a dual-purpose. When dial starts, if the
1504 * dialed_cc_interfaces datastore currently exists on the calling
1505 * channel, then the dial_parent_id will serve as a means of
1506 * letting the new extension cc_monitor we create know
1507 * who his parent is. This value will be the extension
1508 * cc_monitor that dialed the local channel that resulted
1509 * in the new Dial app being called.
1511 * In addition, once an extension cc_monitor is created,
1512 * the dial_parent_id will be changed to the id of that newly
1513 * created interface. This way, device interfaces created from
1514 * receiving AST_CONTROL_CC frames can use this field to determine
1515 * who their parent extension interface should be.
1517 unsigned int dial_parent_id;
1519 * Identifier for the potential CC request that may be made
1520 * based on this call. Even though an instance of the core may
1521 * not be made (since the caller may not request CC), we allocate
1522 * a new core_id at the beginning of the call so that recipient
1523 * channel drivers can have the information handy just in case
1524 * the caller does end up requesting CC.
1528 * When a new Dial application is started, and the datastore
1529 * already exists on the channel, we can determine if we
1530 * should be adding any new interface information to tree.
1534 * When it comes time to offer CC to the caller, we only want to offer
1535 * it to the original incoming channel. For nested Dials and outbound
1536 * channels, it is incorrect to attempt such a thing. This flag indicates
1537 * if the channel to which this datastore is attached may be legally
1538 * offered CC when the call is finished.
1540 char is_original_caller;
1542 * Reference-counted "tree" of interfaces.
1544 struct cc_monitor_tree *interface_tree;
1549 * \brief Destructor function for cc_interfaces datastore
1551 * This function will free the actual datastore and drop
1552 * the refcount for the monitor tree by one. In cases
1553 * where CC can actually be used, this unref will not
1554 * result in the destruction of the monitor tree, because
1555 * the CC core will still have a reference.
1557 * \param data The dialed_cc_interfaces struct to destroy
1559 static void dialed_cc_interfaces_destroy(void *data)
1561 struct dialed_cc_interfaces *cc_interfaces = data;
1562 cc_unref(cc_interfaces->interface_tree, "Unref dial's ref to monitor tree");
1563 ast_free(cc_interfaces);
1568 * \brief Duplicate callback for cc_interfaces datastore
1570 * Integers are copied by value, but the monitor tree
1571 * is done via a shallow copy and a bump of the refcount.
1572 * This way, sub-Dials will be appending interfaces onto
1573 * the same list as this call to Dial.
1575 * \param data The old dialed_cc_interfaces we want to copy
1576 * \retval NULL Could not allocate memory for new dialed_cc_interfaces
1577 * \retval non-NULL The new copy of the dialed_cc_interfaces
1579 static void *dialed_cc_interfaces_duplicate(void *data)
1581 struct dialed_cc_interfaces *old_cc_interfaces = data;
1582 struct dialed_cc_interfaces *new_cc_interfaces = ast_calloc(1, sizeof(*new_cc_interfaces));
1583 if (!new_cc_interfaces) {
1586 new_cc_interfaces->ignore = old_cc_interfaces->ignore;
1587 new_cc_interfaces->dial_parent_id = old_cc_interfaces->dial_parent_id;
1588 new_cc_interfaces->is_original_caller = 0;
1589 cc_ref(old_cc_interfaces->interface_tree, "New ref due to duplication of monitor tree");
1590 new_cc_interfaces->core_id = old_cc_interfaces->core_id;
1591 new_cc_interfaces->interface_tree = old_cc_interfaces->interface_tree;
1592 return new_cc_interfaces;
1597 * \brief information regarding the dialed_cc_interfaces datastore
1599 * The dialed_cc_interfaces datastore is responsible for keeping track
1600 * of what CC-enabled interfaces have been dialed by the caller. For
1601 * more information regarding the actual structure of the tree, see
1602 * the documentation provided in include/asterisk/ccss.h
1604 static const struct ast_datastore_info dialed_cc_interfaces_info = {
1605 .type = "Dial CC Interfaces",
1606 .duplicate = dialed_cc_interfaces_duplicate,
1607 .destroy = dialed_cc_interfaces_destroy,
1610 static struct extension_monitor_pvt *extension_monitor_pvt_init(void)
1612 struct extension_monitor_pvt *ext_pvt = ast_calloc(1, sizeof(*ext_pvt));
1616 AST_LIST_HEAD_INIT_NOLOCK(&ext_pvt->child_dialstrings);
1620 void ast_cc_extension_monitor_add_dialstring(struct ast_channel *incoming, const char * const dialstring, const char * const device_name)
1622 struct ast_datastore *cc_datastore;
1623 struct dialed_cc_interfaces *cc_interfaces;
1624 struct ast_cc_monitor *monitor;
1625 struct extension_monitor_pvt *extension_pvt;
1626 struct extension_child_dialstring *child_dialstring;
1627 struct cc_monitor_tree *interface_tree;
1630 ast_channel_lock(incoming);
1631 if (!(cc_datastore = ast_channel_datastore_find(incoming, &dialed_cc_interfaces_info, NULL))) {
1632 ast_channel_unlock(incoming);
1636 cc_interfaces = cc_datastore->data;
1637 interface_tree = cc_interfaces->interface_tree;
1638 id = cc_interfaces->dial_parent_id;
1639 ast_channel_unlock(incoming);
1641 AST_LIST_LOCK(interface_tree);
1642 AST_LIST_TRAVERSE(interface_tree, monitor, next) {
1643 if (monitor->id == id) {
1649 AST_LIST_UNLOCK(interface_tree);
1653 extension_pvt = monitor->private_data;
1654 if (!(child_dialstring = ast_calloc(1, sizeof(*child_dialstring)))) {
1655 AST_LIST_UNLOCK(interface_tree);
1658 ast_copy_string(child_dialstring->original_dialstring, dialstring, sizeof(child_dialstring->original_dialstring));
1659 ast_copy_string(child_dialstring->device_name, device_name, sizeof(child_dialstring->device_name));
1660 child_dialstring->is_valid = 1;
1661 AST_LIST_INSERT_TAIL(&extension_pvt->child_dialstrings, child_dialstring, next);
1662 AST_LIST_UNLOCK(interface_tree);
1665 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)
1667 struct ast_cc_monitor *monitor_iter;
1668 struct extension_monitor_pvt *extension_pvt;
1669 struct extension_child_dialstring *child_dialstring;
1671 AST_LIST_TRAVERSE(core_instance->monitors, monitor_iter, next) {
1672 if (monitor_iter->id == parent_id) {
1677 if (!monitor_iter) {
1680 extension_pvt = monitor_iter->private_data;
1682 AST_LIST_TRAVERSE(&extension_pvt->child_dialstrings, child_dialstring, next) {
1683 if (!strcmp(child_dialstring->device_name, device_name)) {
1684 child_dialstring->is_valid = is_valid;
1692 * \brief Allocate and initialize an "extension" interface for CC purposes
1694 * When app_dial starts, this function is called in order to set up the
1695 * information about the extension in which this Dial is occurring. Any
1696 * devices dialed will have this particular cc_monitor as a parent.
1698 * \param exten Extension from which Dial is occurring
1699 * \param context Context to which exten belongs
1700 * \param parent_id What should we set the parent_id of this interface to?
1701 * \retval NULL Memory allocation failure
1702 * \retval non-NULL The newly-created cc_monitor for the extension
1704 static struct ast_cc_monitor *cc_extension_monitor_init(const char * const exten, const char * const context, const unsigned int parent_id)
1706 struct ast_str *str = ast_str_alloca(2 * AST_MAX_EXTENSION);
1707 struct ast_cc_interface *cc_interface;
1708 struct ast_cc_monitor *monitor;
1710 ast_str_set(&str, 0, "%s@%s", exten, context);
1712 if (!(cc_interface = ao2_t_alloc(sizeof(*cc_interface) + ast_str_strlen(str), cc_interface_destroy,
1713 "Allocating new ast_cc_interface"))) {
1717 if (!(monitor = ao2_t_alloc(sizeof(*monitor), cc_monitor_destroy, "Allocating new ast_cc_monitor"))) {
1718 cc_unref(cc_interface, "failed to allocate the monitor, so unref the interface");
1722 if (!(monitor->private_data = extension_monitor_pvt_init())) {
1723 cc_unref(monitor, "Failed to initialize extension monitor private data. uref monitor");
1724 cc_unref(cc_interface, "Failed to initialize extension monitor private data. unref cc_interface");
1727 monitor->id = ast_atomic_fetchadd_int(&dialed_cc_interface_counter, +1);
1728 monitor->parent_id = parent_id;
1729 cc_interface->monitor_type = "extension";
1730 cc_interface->monitor_class = AST_CC_EXTENSION_MONITOR;
1731 strcpy(cc_interface->device_name, ast_str_buffer(str));
1732 monitor->interface = cc_interface;
1733 ast_log_dynamic_level(cc_logger_level, "Created an extension cc interface for '%s' with id %d and parent %d\n", cc_interface->device_name, monitor->id, monitor->parent_id);
1739 * \brief allocate dialed_cc_interfaces datastore and initialize fields
1741 * This function is called when Situation 1 occurs in ast_cc_call_init.
1742 * See that function for more information on what Situation 1 is.
1744 * In this particular case, we have to do a lot of memory allocation in order
1745 * to create the datastore, the data for the datastore, the tree of interfaces
1746 * that we'll be adding to, and the initial extension interface for this Dial
1749 * \param chan The channel onto which the datastore should be added.
1750 * \retval -1 An error occurred
1753 static int cc_interfaces_datastore_init(struct ast_channel *chan) {
1754 struct dialed_cc_interfaces *interfaces;
1755 struct ast_cc_monitor *monitor;
1756 struct ast_datastore *dial_cc_datastore;
1758 /*XXX This may be a bit controversial. In an attempt to not allocate
1759 * extra resources, I make sure that a future request will be within
1760 * limits. The problem here is that it is reasonable to think that
1761 * even if we're not within the limits at this point, we may be by
1762 * the time the requestor will have made his request. This may be
1763 * deleted at some point.
1765 if (!ast_cc_request_is_within_limits()) {
1769 if (!(interfaces = ast_calloc(1, sizeof(*interfaces)))) {
1773 if (!(monitor = cc_extension_monitor_init(S_OR(chan->macroexten, chan->exten), S_OR(chan->macrocontext, chan->context), 0))) {
1774 ast_free(interfaces);
1778 if (!(dial_cc_datastore = ast_datastore_alloc(&dialed_cc_interfaces_info, NULL))) {
1779 cc_unref(monitor, "Could not allocate the dialed interfaces datastore. Unreffing monitor");
1780 ast_free(interfaces);
1784 if (!(interfaces->interface_tree = ao2_t_alloc(sizeof(*interfaces->interface_tree), cc_interface_tree_destroy,
1785 "Allocate monitor tree"))) {
1786 ast_datastore_free(dial_cc_datastore);
1787 cc_unref(monitor, "Could not allocate monitor tree on dialed interfaces datastore. Unreffing monitor");
1788 ast_free(interfaces);
1792 /* Finally, all that allocation is done... */
1793 AST_LIST_HEAD_INIT(interfaces->interface_tree);
1794 AST_LIST_INSERT_TAIL(interfaces->interface_tree, monitor, next);
1795 cc_ref(monitor, "List's reference to extension monitor");
1796 dial_cc_datastore->data = interfaces;
1797 dial_cc_datastore->inheritance = DATASTORE_INHERIT_FOREVER;
1798 interfaces->dial_parent_id = monitor->id;
1799 interfaces->core_id = monitor->core_id = ast_atomic_fetchadd_int(&core_id_counter, +1);
1800 interfaces->is_original_caller = 1;
1801 ast_channel_lock(chan);
1802 ast_channel_datastore_add(chan, dial_cc_datastore);
1803 ast_channel_unlock(chan);
1804 cc_unref(monitor, "Unreffing allocation's reference");
1810 * \brief Call a monitor's destructor before the monitor has been allocated
1813 * \param monitor_type The type of monitor callbacks to use when calling the destructor
1814 * \param private_data Data allocated by a channel driver that must be freed
1817 * I'll admit, this is a bit evil.
1819 * When a channel driver determines that it can offer a call completion service to
1820 * a caller, it is very likely that the channel driver will need to allocate some
1821 * data so that when the time comes to request CC, the channel driver will have the
1822 * necessary data at hand.
1824 * The problem is that there are many places where failures may occur before the monitor
1825 * has been properly allocated and had its callbacks assigned to it. If one of these
1826 * failures should occur, then we still need to let the channel driver know that it
1827 * must destroy the data that it allocated.
1831 static void call_destructor_with_no_monitor(const char * const monitor_type, void *private_data)
1833 const struct ast_cc_monitor_callbacks *monitor_callbacks = find_monitor_callbacks(monitor_type);
1835 if (!monitor_callbacks) {
1839 monitor_callbacks->destructor(private_data);
1844 * \brief Allocate and intitialize a device cc_monitor
1846 * For all intents and purposes, this is the same as
1847 * cc_extension_monitor_init, except that there is only
1848 * a single parameter used for naming the interface.
1850 * This function is called when handling AST_CONTROL_CC frames.
1851 * The device has reported that CC is possible, so we add it
1852 * to the interface_tree.
1854 * Note that it is not necessarily erroneous to add the same
1855 * device to the tree twice. If the same device is called by
1856 * two different extension during the same call, then
1857 * that is a legitimate situation. Of course, I'm pretty sure
1858 * the dialed_interfaces global datastore will not allow that
1861 * \param device_name The name of the device being added to the tree
1862 * \param dialstring The dialstring used to dial the device being added
1863 * \param parent_id The parent of this new tree node.
1864 * \retval NULL Memory allocation failure
1865 * \retval non-NULL The new ast_cc_interface created.
1867 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)
1869 struct ast_cc_interface *cc_interface;
1870 struct ast_cc_monitor *monitor;
1871 size_t device_name_len = strlen(device_name);
1872 int parent_id = cc_data->parent_interface_id;
1874 if (!(cc_interface = ao2_t_alloc(sizeof(*cc_interface) + device_name_len, cc_interface_destroy,
1875 "Allocating new ast_cc_interface"))) {
1879 if (!(cc_interface->config_params = ast_cc_config_params_init())) {
1880 cc_unref(cc_interface, "Failed to allocate config params, unref interface");
1884 if (!(monitor = ao2_t_alloc(sizeof(*monitor), cc_monitor_destroy, "Allocating new ast_cc_monitor"))) {
1885 cc_unref(cc_interface, "Failed to allocate monitor, unref interface");
1889 if (!(monitor->dialstring = ast_strdup(dialstring))) {
1890 cc_unref(monitor, "Failed to copy dialable name. Unref monitor");
1891 cc_unref(cc_interface, "Failed to copy dialable name");
1895 if (!(monitor->callbacks = find_monitor_callbacks(cc_data->monitor_type))) {
1896 cc_unref(monitor, "Failed to find monitor callbacks. Unref monitor");
1897 cc_unref(cc_interface, "Failed to find monitor callbacks");
1901 strcpy(cc_interface->device_name, device_name);
1902 monitor->id = ast_atomic_fetchadd_int(&dialed_cc_interface_counter, +1);
1903 monitor->parent_id = parent_id;
1904 monitor->core_id = core_id;
1905 monitor->service_offered = cc_data->service;
1906 monitor->private_data = cc_data->private_data;
1907 cc_interface->monitor_type = cc_data->monitor_type;
1908 cc_interface->monitor_class = AST_CC_DEVICE_MONITOR;
1909 monitor->interface = cc_interface;
1910 monitor->available_timer_id = -1;
1911 ast_cc_copy_config_params(cc_interface->config_params, &cc_data->config_params);
1912 ast_log_dynamic_level(cc_logger_level, "Core %d: Created a device cc interface for '%s' with id %d and parent %d\n",
1913 monitor->core_id, cc_interface->device_name, monitor->id, monitor->parent_id);
1919 * Unless we are ignoring CC for some reason, we will always
1920 * call this function when we read an AST_CONTROL_CC frame
1921 * from an outbound channel.
1923 * This function will call cc_device_monitor_init to
1924 * create the new cc_monitor for the device from which
1925 * we read the frame. In addition, the new device will be added
1926 * to the monitor tree on the dialed_cc_interfaces datastore
1927 * on the inbound channel.
1929 * If this is the first AST_CONTROL_CC frame that we have handled
1930 * for this call, then we will also initialize the CC core for
1933 void ast_handle_cc_control_frame(struct ast_channel *inbound, struct ast_channel *outbound, void *frame_data)
1937 struct ast_cc_monitor *monitor;
1938 struct ast_datastore *cc_datastore;
1939 struct dialed_cc_interfaces *cc_interfaces;
1940 struct cc_control_payload *cc_data = frame_data;
1941 struct cc_core_instance *core_instance;
1943 device_name = cc_data->device_name;
1944 dialstring = cc_data->dialstring;
1946 ast_channel_lock(inbound);
1947 if (!(cc_datastore = ast_channel_datastore_find(inbound, &dialed_cc_interfaces_info, NULL))) {
1948 ast_log(LOG_WARNING, "Unable to retrieve CC datastore while processing CC frame from '%s'. CC services will be unavailable.\n", device_name);
1949 ast_channel_unlock(inbound);
1950 call_destructor_with_no_monitor(cc_data->monitor_type, cc_data->private_data);
1954 cc_interfaces = cc_datastore->data;
1956 if (cc_interfaces->ignore) {
1957 ast_channel_unlock(inbound);
1958 call_destructor_with_no_monitor(cc_data->monitor_type, cc_data->private_data);
1962 if (!cc_interfaces->is_original_caller) {
1963 /* If the is_original_caller is not set on the *inbound* channel, then
1964 * it must be a local channel. As such, we do not want to create a core instance
1965 * or an agent for the local channel. Instead, we want to pass this along to the
1966 * other side of the local channel so that the original caller can benefit.
1968 ast_channel_unlock(inbound);
1969 ast_indicate_data(inbound, AST_CONTROL_CC, cc_data, sizeof(*cc_data));
1973 core_instance = find_cc_core_instance(cc_interfaces->core_id);
1974 if (!core_instance) {
1975 core_instance = cc_core_init_instance(inbound, cc_interfaces->interface_tree,
1976 cc_interfaces->core_id, cc_data);
1977 if (!core_instance) {
1978 cc_interfaces->ignore = 1;
1979 ast_channel_unlock(inbound);
1980 call_destructor_with_no_monitor(cc_data->monitor_type, cc_data->private_data);
1985 ast_channel_unlock(inbound);
1987 /* Yeah this kind of sucks, but luckily most people
1988 * aren't dialing thousands of interfaces on every call
1990 * This traversal helps us to not create duplicate monitors in
1991 * case a device queues multiple CC control frames.
1993 AST_LIST_LOCK(cc_interfaces->interface_tree);
1994 AST_LIST_TRAVERSE(cc_interfaces->interface_tree, monitor, next) {
1995 if (!strcmp(monitor->interface->device_name, device_name)) {
1996 ast_log_dynamic_level(cc_logger_level, "Core %d: Device %s sent us multiple CC control frames. Ignoring those beyond the first.\n",
1997 core_instance->core_id, device_name);
1998 AST_LIST_UNLOCK(cc_interfaces->interface_tree);
1999 cc_unref(core_instance, "Returning early from ast_handle_cc_control_frame. Unref core_instance");
2000 call_destructor_with_no_monitor(cc_data->monitor_type, cc_data->private_data);
2004 AST_LIST_UNLOCK(cc_interfaces->interface_tree);
2006 if (!(monitor = cc_device_monitor_init(device_name, dialstring, cc_data, core_instance->core_id))) {
2007 ast_log(LOG_WARNING, "Unable to create CC device interface for '%s'. CC services will be unavailable on this interface.\n", device_name);
2008 cc_unref(core_instance, "Returning early from ast_handle_cc_control_frame. Unref core_instance");
2009 call_destructor_with_no_monitor(cc_data->monitor_type, cc_data->private_data);
2013 AST_LIST_LOCK(cc_interfaces->interface_tree);
2014 cc_ref(monitor, "monitor tree's reference to the monitor");
2015 AST_LIST_INSERT_TAIL(cc_interfaces->interface_tree, monitor, next);
2016 AST_LIST_UNLOCK(cc_interfaces->interface_tree);
2018 cc_extension_monitor_change_is_valid(core_instance, monitor->parent_id, monitor->interface->device_name, 0);
2020 manager_event(EVENT_FLAG_CC, "CCAvailable",
2024 cc_interfaces->core_id, device_name, cc_service_to_string(cc_data->service)
2027 cc_unref(core_instance, "Done with core_instance after handling CC control frame");
2028 cc_unref(monitor, "Unref reference from allocating monitor");
2031 int ast_cc_call_init(struct ast_channel *chan, int *ignore_cc)
2033 /* There are three situations to deal with here:
2035 * 1. The channel does not have a dialed_cc_interfaces datastore on
2036 * it. This means that this is the first time that Dial has
2037 * been called. We need to create/initialize the datastore.
2039 * 2. The channel does have a cc_interface datastore on it and
2040 * the "ignore" indicator is 0. This means that a Local channel
2041 * was called by a "parent" dial. We can check the datastore's
2042 * parent field to see who the root of this particular dial tree
2045 * 3. The channel does have a cc_interface datastore on it and
2046 * the "ignore" indicator is 1. This means that a second Dial call
2047 * is being made from an extension. In this case, we do not
2048 * want to make any additions/modifications to the datastore. We
2049 * will instead set a flag to indicate that CCSS is completely
2050 * disabled for this Dial attempt.
2053 struct ast_datastore *cc_interfaces_datastore;
2054 struct dialed_cc_interfaces *interfaces;
2055 struct ast_cc_monitor *monitor;
2056 struct ast_cc_config_params *cc_params;
2058 ast_channel_lock(chan);
2060 cc_params = ast_channel_get_cc_config_params(chan);
2062 ast_channel_unlock(chan);
2065 if (ast_get_cc_agent_policy(cc_params) == AST_CC_AGENT_NEVER) {
2066 /* We can't offer CC to this caller anyway, so don't bother with CC on this call
2069 ast_channel_unlock(chan);
2070 ast_log_dynamic_level(cc_logger_level, "Agent policy for %s is 'never'. CC not possible\n", chan->name);
2074 if (!(cc_interfaces_datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL))) {
2075 /* Situation 1 has occurred */
2076 ast_channel_unlock(chan);
2077 return cc_interfaces_datastore_init(chan);
2079 interfaces = cc_interfaces_datastore->data;
2080 ast_channel_unlock(chan);
2082 if (interfaces->ignore) {
2083 /* Situation 3 has occurred */
2085 ast_log_dynamic_level(cc_logger_level, "Datastore is present with ignore flag set. Ignoring CC offers on this call\n");
2089 /* Situation 2 has occurred */
2090 if (!(monitor = cc_extension_monitor_init(S_OR(chan->macroexten, chan->exten),
2091 S_OR(chan->macrocontext, chan->context), interfaces->dial_parent_id))) {
2094 monitor->core_id = interfaces->core_id;
2095 AST_LIST_LOCK(interfaces->interface_tree);
2096 cc_ref(monitor, "monitor tree's reference to the monitor");
2097 AST_LIST_INSERT_TAIL(interfaces->interface_tree, monitor, next);
2098 AST_LIST_UNLOCK(interfaces->interface_tree);
2099 interfaces->dial_parent_id = monitor->id;
2100 cc_unref(monitor, "Unref monitor's allocation reference");
2104 int ast_cc_request_is_within_limits(void)
2106 return cc_request_count < global_cc_max_requests;
2109 int ast_cc_get_current_core_id(struct ast_channel *chan)
2111 struct ast_datastore *datastore;
2112 struct dialed_cc_interfaces *cc_interfaces;
2115 ast_channel_lock(chan);
2116 if (!(datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL))) {
2117 ast_channel_unlock(chan);
2121 cc_interfaces = datastore->data;
2122 core_id_return = cc_interfaces->ignore ? -1 : cc_interfaces->core_id;
2123 ast_channel_unlock(chan);
2124 return core_id_return;
2128 static long count_agents(const char * const caller, const int core_id_exception)
2130 struct count_agents_cb_data data = {.core_id_exception = core_id_exception,};
2132 ao2_t_callback_data(cc_core_instances, OBJ_NODATA, count_agents_cb, (char *)caller, &data, "Counting agents");
2133 ast_log_dynamic_level(cc_logger_level, "Counted %d agents\n", data.count);
2137 static void kill_duplicate_offers(char *caller)
2139 unsigned long match_flags = MATCH_NO_REQUEST;
2140 ao2_t_callback_data(cc_core_instances, OBJ_UNLINK | OBJ_NODATA, match_agent, caller, &match_flags, "Killing duplicate offers");
2143 static void check_callback_sanity(const struct ast_cc_agent_callbacks *callbacks)
2145 ast_assert(callbacks->init != NULL);
2146 ast_assert(callbacks->start_offer_timer != NULL);
2147 ast_assert(callbacks->stop_offer_timer != NULL);
2148 ast_assert(callbacks->ack != NULL);
2149 ast_assert(callbacks->status_request != NULL);
2150 ast_assert(callbacks->start_monitoring != NULL);
2151 ast_assert(callbacks->callee_available != NULL);
2152 ast_assert(callbacks->destructor != NULL);
2155 static void agent_destroy(void *data)
2157 struct ast_cc_agent *agent = data;
2159 if (agent->callbacks) {
2160 agent->callbacks->destructor(agent);
2162 ast_cc_config_params_destroy(agent->cc_params);
2165 static struct ast_cc_agent *cc_agent_init(struct ast_channel *caller_chan,
2166 const char * const caller_name, const int core_id,
2167 struct cc_monitor_tree *interface_tree)
2169 struct ast_cc_agent *agent;
2170 struct ast_cc_config_params *cc_params;
2172 if (!(agent = ao2_t_alloc(sizeof(*agent) + strlen(caller_name), agent_destroy,
2173 "Allocating new ast_cc_agent"))) {
2177 agent->core_id = core_id;
2178 strcpy(agent->device_name, caller_name);
2180 cc_params = ast_channel_get_cc_config_params(caller_chan);
2182 cc_unref(agent, "Could not get channel config params.");
2185 if (!(agent->cc_params = ast_cc_config_params_init())) {
2186 cc_unref(agent, "Could not init agent config params.");
2189 ast_cc_copy_config_params(agent->cc_params, cc_params);
2191 if (!(agent->callbacks = find_agent_callbacks(caller_chan))) {
2192 cc_unref(agent, "Could not find agent callbacks.");
2195 check_callback_sanity(agent->callbacks);
2197 if (agent->callbacks->init(agent, caller_chan)) {
2198 cc_unref(agent, "Agent init callback failed.");
2201 ast_log_dynamic_level(cc_logger_level, "Core %d: Created an agent for caller %s\n",
2202 agent->core_id, agent->device_name);
2206 /* Generic agent callbacks */
2207 static int cc_generic_agent_init(struct ast_cc_agent *agent, struct ast_channel *chan);
2208 static int cc_generic_agent_start_offer_timer(struct ast_cc_agent *agent);
2209 static int cc_generic_agent_stop_offer_timer(struct ast_cc_agent *agent);
2210 static void cc_generic_agent_ack(struct ast_cc_agent *agent);
2211 static int cc_generic_agent_status_request(struct ast_cc_agent *agent);
2212 static int cc_generic_agent_stop_ringing(struct ast_cc_agent *agent);
2213 static int cc_generic_agent_start_monitoring(struct ast_cc_agent *agent);
2214 static int cc_generic_agent_recall(struct ast_cc_agent *agent);
2215 static void cc_generic_agent_destructor(struct ast_cc_agent *agent);
2217 static struct ast_cc_agent_callbacks generic_agent_callbacks = {
2219 .init = cc_generic_agent_init,
2220 .start_offer_timer = cc_generic_agent_start_offer_timer,
2221 .stop_offer_timer = cc_generic_agent_stop_offer_timer,
2222 .ack = cc_generic_agent_ack,
2223 .status_request = cc_generic_agent_status_request,
2224 .stop_ringing = cc_generic_agent_stop_ringing,
2225 .start_monitoring = cc_generic_agent_start_monitoring,
2226 .callee_available = cc_generic_agent_recall,
2227 .destructor = cc_generic_agent_destructor,
2230 struct cc_generic_agent_pvt {
2232 * Subscription to device state
2234 * Used in the CC_CALLER_BUSY state. The
2235 * generic agent will subscribe to the
2236 * device state of the caller in order to
2237 * determine when we may move on
2239 struct ast_event_sub *sub;
2241 * Scheduler id of offer timer.
2247 * When we re-call the caller, we need
2248 * to provide this information to
2249 * ast_request_and_dial so that the
2250 * information will be present in the
2251 * call to the callee
2253 char cid_num[AST_CHANNEL_NAME];
2257 * See the description of cid_num.
2258 * The same applies here, except this
2259 * is the caller's name.
2261 char cid_name[AST_CHANNEL_NAME];
2265 * The original extension dialed. This is used
2266 * so that when performing a recall, we can
2267 * call the proper extension.
2269 char exten[AST_CHANNEL_NAME];
2273 * The original context dialed. This is used
2274 * so that when performaing a recall, we can
2275 * call into the proper context
2277 char context[AST_CHANNEL_NAME];
2280 static int cc_generic_agent_init(struct ast_cc_agent *agent, struct ast_channel *chan)
2282 struct cc_generic_agent_pvt *generic_pvt = ast_calloc(1, sizeof(*generic_pvt));
2288 generic_pvt->offer_timer_id = -1;
2289 ast_copy_string(generic_pvt->cid_num, chan->cid.cid_num, sizeof(generic_pvt->cid_num));
2290 ast_copy_string(generic_pvt->cid_name, chan->cid.cid_name, sizeof(generic_pvt->cid_name));
2291 ast_copy_string(generic_pvt->exten, S_OR(chan->macroexten, chan->exten), sizeof(generic_pvt->exten));
2292 ast_copy_string(generic_pvt->context, S_OR(chan->macrocontext, chan->context), sizeof(generic_pvt->context));
2293 agent->private_data = generic_pvt;
2294 ast_set_flag(agent, AST_CC_AGENT_SKIP_OFFER);
2298 static int offer_timer_expire(const void *data)
2300 const struct ast_cc_agent *agent = data;
2301 struct cc_generic_agent_pvt *agent_pvt = agent->private_data;
2302 ast_log_dynamic_level(cc_logger_level, "Core %d: Queuing change request because offer timer has expired.\n",
2304 agent_pvt->offer_timer_id = -1;
2305 ast_cc_failed(agent->core_id, "Generic agent %s offer timer expired", agent->device_name);
2306 cc_unref((struct ast_cc_agent *)agent, "Remove scheduler's reference to the agent");
2310 static int cc_generic_agent_start_offer_timer(struct ast_cc_agent *agent)
2314 struct cc_generic_agent_pvt *generic_pvt = agent->private_data;
2316 ast_assert(cc_sched_thread != NULL);
2317 ast_assert(agent->cc_params != NULL);
2319 when = ast_get_cc_offer_timer(agent->cc_params) * 1000;
2320 ast_log_dynamic_level(cc_logger_level, "Core %d: About to schedule offer timer expiration for %d ms\n",
2321 agent->core_id, when);
2322 if ((sched_id = ast_sched_thread_add(cc_sched_thread, when, offer_timer_expire, cc_ref(agent, "Give scheduler an agent ref"))) == -1) {
2325 generic_pvt->offer_timer_id = sched_id;
2329 static int cc_generic_agent_stop_offer_timer(struct ast_cc_agent *agent)
2331 struct cc_generic_agent_pvt *generic_pvt = agent->private_data;
2333 if (generic_pvt->offer_timer_id != -1) {
2334 if (!ast_sched_thread_del(cc_sched_thread, generic_pvt->offer_timer_id)) {
2335 cc_unref(agent, "Remove scheduler's reference to the agent");
2337 generic_pvt->offer_timer_id = -1;
2342 static void cc_generic_agent_ack(struct ast_cc_agent *agent)
2344 /* The generic agent doesn't have to do anything special to
2345 * acknowledge a CC request. Just return.
2350 static int cc_generic_agent_status_request(struct ast_cc_agent *agent)
2352 ast_cc_agent_status_response(agent->core_id, ast_device_state(agent->device_name));
2356 static int cc_generic_agent_stop_ringing(struct ast_cc_agent *agent)
2358 struct ast_channel *recall_chan = ast_channel_get_by_name_prefix(agent->device_name, strlen(agent->device_name));
2364 ast_softhangup(recall_chan, AST_SOFTHANGUP_EXPLICIT);
2368 static int generic_agent_devstate_unsubscribe(void *data)
2370 struct ast_cc_agent *agent = data;
2371 struct cc_generic_agent_pvt *generic_pvt = agent->private_data;
2373 if (generic_pvt->sub != NULL) {
2374 generic_pvt->sub = ast_event_unsubscribe(generic_pvt->sub);
2376 cc_unref(agent, "Done unsubscribing from devstate");
2380 static void generic_agent_devstate_cb(const struct ast_event *event, void *userdata)
2382 struct ast_cc_agent *agent = userdata;
2384 /* We can't unsubscribe from device state events here because it causes a deadlock */
2385 if (ast_taskprocessor_push(cc_core_taskprocessor, generic_agent_devstate_unsubscribe,
2386 cc_ref(agent, "ref agent for device state unsubscription"))) {
2387 cc_unref(agent, "Unref agent unsubscribing from devstate failed");
2389 ast_cc_agent_caller_available(agent->core_id, "%s is no longer busy", agent->device_name);
2392 static int cc_generic_agent_start_monitoring(struct ast_cc_agent *agent)
2394 struct cc_generic_agent_pvt *generic_pvt = agent->private_data;
2395 struct ast_str *str = ast_str_alloca(128);
2397 ast_assert(generic_pvt->sub == NULL);
2398 ast_str_set(&str, 0, "Starting to monitor %s device state since it is busy\n", agent->device_name);
2400 if (!(generic_pvt->sub = ast_event_subscribe(
2401 AST_EVENT_DEVICE_STATE, generic_agent_devstate_cb, ast_str_buffer(str), agent,
2402 AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, agent->device_name,
2403 AST_EVENT_IE_STATE, AST_EVENT_IE_PLTYPE_UINT, AST_DEVICE_NOT_INUSE,
2404 AST_EVENT_IE_END))) {
2410 static void *generic_recall(void *data)
2412 struct ast_cc_agent *agent = data;
2413 struct cc_generic_agent_pvt *generic_pvt = agent->private_data;
2414 const char *interface = S_OR(ast_get_cc_agent_dialstring(agent->cc_params), ast_strdupa(agent->device_name));
2418 struct ast_channel *chan;
2419 const char *callback_macro = ast_get_cc_callback_macro(agent->cc_params);
2420 unsigned int recall_timer = ast_get_cc_recall_timer(agent->cc_params) * 1000;
2423 if ((target = strchr(interface, '/'))) {
2426 if (!(chan = ast_request_and_dial(tech, AST_FORMAT_SLINEAR, NULL, target, recall_timer, &reason, generic_pvt->cid_num, generic_pvt->cid_name))) {
2427 /* Hmm, no channel. Sucks for you, bud.
2429 ast_log_dynamic_level(cc_logger_level, "Core %d: Failed to call back %s for reason %d\n",
2430 agent->core_id, agent->device_name, reason);
2431 ast_cc_failed(agent->core_id, "Failed to call back device %s/%s", tech, target);
2434 if (!ast_strlen_zero(callback_macro)) {
2435 ast_log_dynamic_level(cc_logger_level, "Core %d: There's a callback macro configured for agent %s\n",
2436 agent->core_id, agent->device_name);
2437 if (ast_app_run_macro(NULL, chan, callback_macro, NULL)) {
2438 ast_cc_failed(agent->core_id, "Callback macro to %s failed. Maybe a hangup?", agent->device_name);
2443 /* We have a channel. It's time now to set up the datastore of recalled CC interfaces.
2444 * This will be a common task for all recall functions. If it were possible, I'd have
2445 * the core do it automatically, but alas I cannot. Instead, I will provide a public
2446 * function to do so.
2448 ast_setup_cc_recall_datastore(chan, agent->core_id);
2449 ast_cc_agent_set_interfaces_chanvar(chan);
2451 ast_copy_string(chan->exten, generic_pvt->exten, sizeof(chan->exten));
2452 ast_copy_string(chan->context, generic_pvt->context, sizeof(chan->context));
2454 ast_cc_agent_recalling(agent->core_id, "Generic agent %s is recalling", agent->device_name);
2455 ast_pbx_start(chan);
2459 static int cc_generic_agent_recall(struct ast_cc_agent *agent)
2462 enum ast_device_state current_state = ast_device_state(agent->device_name);
2464 if (current_state != AST_DEVICE_NOT_INUSE && current_state != AST_DEVICE_UNKNOWN) {
2465 /* We can't try to contact the device right now because he's not available
2466 * Let the core know he's busy.
2468 ast_cc_agent_caller_busy(agent->core_id, "Generic agent caller %s is busy", agent->device_name);
2471 ast_pthread_create_detached_background(&clotho, NULL, generic_recall, agent);
2475 static void cc_generic_agent_destructor(struct ast_cc_agent *agent)
2477 struct cc_generic_agent_pvt *agent_pvt = agent->private_data;
2480 /* The agent constructor probably failed. */
2484 cc_generic_agent_stop_offer_timer(agent);
2485 if (agent_pvt->sub) {
2486 agent_pvt->sub = ast_event_unsubscribe(agent_pvt->sub);
2489 ast_free(agent_pvt);
2492 static void cc_core_instance_destructor(void *data)
2494 struct cc_core_instance *core_instance = data;
2495 ast_log_dynamic_level(cc_logger_level, "Core %d: Destroying core instance\n", core_instance->core_id);
2496 if (core_instance->agent) {
2497 cc_unref(core_instance->agent, "Core instance is done with the agent now");
2499 if (core_instance->monitors) {
2500 core_instance->monitors = cc_unref(core_instance->monitors, "Core instance is done with interface list");
2504 static struct cc_core_instance *cc_core_init_instance(struct ast_channel *caller_chan,
2505 struct cc_monitor_tree *called_tree, const int core_id, struct cc_control_payload *cc_data)
2507 char caller[AST_CHANNEL_NAME];
2508 struct cc_core_instance *core_instance;
2509 struct ast_cc_config_params *cc_params;
2513 ast_channel_get_device_name(caller_chan, caller, sizeof(caller));
2514 cc_params = ast_channel_get_cc_config_params(caller_chan);
2516 ast_log_dynamic_level(cc_logger_level, "Could not get CC parameters for %s\n",
2520 /* First, we need to kill off other pending CC offers from caller. If the caller is going
2521 * to request a CC service, it may only be for the latest call he made.
2523 if (ast_get_cc_agent_policy(cc_params) == AST_CC_AGENT_GENERIC) {
2524 kill_duplicate_offers(caller);
2527 ast_cc_is_recall(caller_chan, &recall_core_id, NULL);
2528 agent_count = count_agents(caller, recall_core_id);
2529 if (agent_count >= ast_get_cc_max_agents(cc_params)) {
2530 ast_log_dynamic_level(cc_logger_level, "Caller %s already has the maximum number of agents configured\n", caller);
2534 /* Generic agents can only have a single outstanding CC request per caller. */
2535 if (agent_count > 0 && ast_get_cc_agent_policy(cc_params) == AST_CC_AGENT_GENERIC) {
2536 ast_log_dynamic_level(cc_logger_level, "Generic agents can only have a single outstanding request\n");
2540 /* Next, we need to create the core instance for this call */
2541 if (!(core_instance = ao2_t_alloc(sizeof(*core_instance), cc_core_instance_destructor, "Creating core instance for CC"))) {
2545 core_instance->core_id = core_id;
2546 if (!(core_instance->agent = cc_agent_init(caller_chan, caller, core_instance->core_id, called_tree))) {
2547 cc_unref(core_instance, "Couldn't allocate agent, unref core_instance");
2551 core_instance->monitors = cc_ref(called_tree, "Core instance getting ref to monitor tree");
2553 ao2_t_link(cc_core_instances, core_instance, "Link core instance into container");
2555 return core_instance;
2558 struct cc_state_change_args {
2559 enum cc_state state;
2564 static int is_state_change_valid(enum cc_state current_state, const enum cc_state new_state, struct ast_cc_agent *agent)
2567 switch (new_state) {
2569 ast_log_dynamic_level(cc_logger_level, "Core %d: Asked to change to state %d? That should never happen.\n",
2570 agent->core_id, new_state);
2572 case CC_CALLER_OFFERED:
2573 if (current_state == CC_AVAILABLE) {
2577 case CC_CALLER_REQUESTED:
2578 if (current_state == CC_CALLER_OFFERED ||
2579 (current_state == CC_AVAILABLE && ast_test_flag(agent, AST_CC_AGENT_SKIP_OFFER))) {
2584 if (current_state == CC_CALLER_REQUESTED || current_state == CC_CALLER_BUSY) {
2588 case CC_CALLEE_READY:
2589 if (current_state == CC_ACTIVE) {
2593 case CC_CALLER_BUSY:
2594 if (current_state == CC_CALLEE_READY) {
2599 if (current_state == CC_CALLEE_READY) {
2604 if (current_state == CC_RECALLING) {
2612 ast_log_dynamic_level(cc_logger_level, "Core %d: Asked to change to unknown state %d\n",
2613 agent->core_id, new_state);
2620 static int cc_available(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
2622 /* This should never happen... */
2623 ast_log(LOG_WARNING, "Someone requested to change to CC_AVAILABLE? Ignoring.\n");
2627 static int cc_caller_offered(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
2629 if (core_instance->agent->callbacks->start_offer_timer(core_instance->agent)) {
2630 ast_cc_failed(core_instance->core_id, "Failed to start the offer timer for %s\n",
2631 core_instance->agent->device_name);
2634 manager_event(EVENT_FLAG_CC, "CCOfferTimerStart",
2638 core_instance->core_id, core_instance->agent->device_name, core_instance->agent->cc_params->cc_offer_timer);
2639 ast_log_dynamic_level(cc_logger_level, "Core %d: Started the offer timer for the agent %s!\n",
2640 core_instance->core_id, core_instance->agent->device_name);
2645 * \brief check if the core instance has any device monitors
2647 * In any case where we end up removing a device monitor from the
2648 * list of device monitors, it is important to see what the state
2649 * of the list is afterwards. If we find that we only have extension
2650 * monitors left, then no devices are actually being monitored.
2651 * In such a case, we need to declare that CC has failed for this
2652 * call. This function helps those cases to determine if they should
2655 * \param core_instance The core instance we are checking for the existence
2656 * of device monitors
2657 * \retval 0 No device monitors exist on this core_instance
2658 * \retval 1 There is still at least 1 device monitor remaining
2660 static int has_device_monitors(struct cc_core_instance *core_instance)
2662 struct ast_cc_monitor *iter;
2665 AST_LIST_TRAVERSE(core_instance->monitors, iter, next) {
2666 if (iter->interface->monitor_class == AST_CC_DEVICE_MONITOR) {
2675 static void request_cc(struct cc_core_instance *core_instance)
2677 struct ast_cc_monitor *monitor_iter;
2678 AST_LIST_LOCK(core_instance->monitors);
2679 AST_LIST_TRAVERSE_SAFE_BEGIN(core_instance->monitors, monitor_iter, next) {
2680 if (monitor_iter->interface->monitor_class == AST_CC_DEVICE_MONITOR) {
2681 if (monitor_iter->callbacks->request_cc(monitor_iter, &monitor_iter->available_timer_id)) {
2682 AST_LIST_REMOVE_CURRENT(next);
2683 cc_extension_monitor_change_is_valid(core_instance, monitor_iter->parent_id,
2684 monitor_iter->interface->device_name, 1);
2685 cc_unref(monitor_iter, "request_cc failed. Unref list's reference to monitor");
2687 manager_event(EVENT_FLAG_CC, "CCRequested",
2691 core_instance->core_id, core_instance->agent->device_name, monitor_iter->interface->device_name);
2695 AST_LIST_TRAVERSE_SAFE_END;
2697 if (!has_device_monitors(core_instance)) {
2698 ast_cc_failed(core_instance->core_id, "All device monitors failed to request CC");
2700 AST_LIST_UNLOCK(core_instance->monitors);
2703 static int cc_caller_requested(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
2705 if (!ast_cc_request_is_within_limits()) {
2706 ast_log(LOG_WARNING, "Cannot request CC since there is no more room for requests\n");
2707 ast_cc_failed(core_instance->core_id, "Too many requests in the system");
2710 core_instance->agent->callbacks->stop_offer_timer(core_instance->agent);
2711 request_cc(core_instance);
2715 static void unsuspend(struct cc_core_instance *core_instance)
2717 struct ast_cc_monitor *monitor_iter;
2718 AST_LIST_LOCK(core_instance->monitors);
2719 AST_LIST_TRAVERSE_SAFE_BEGIN(core_instance->monitors, monitor_iter, next) {
2720 if (monitor_iter->interface->monitor_class == AST_CC_DEVICE_MONITOR) {
2721 if (monitor_iter->callbacks->unsuspend(monitor_iter)) {
2722 AST_LIST_REMOVE_CURRENT(next);
2723 cc_extension_monitor_change_is_valid(core_instance, monitor_iter->parent_id,
2724 monitor_iter->interface->device_name, 1);
2725 cc_unref(monitor_iter, "unsuspend failed. Unref list's reference to monitor");
2729 AST_LIST_TRAVERSE_SAFE_END;
2731 if (!has_device_monitors(core_instance)) {
2732 ast_cc_failed(core_instance->core_id, "All device monitors failed to unsuspend CC");
2734 AST_LIST_UNLOCK(core_instance->monitors);
2737 static int cc_active(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
2740 * 1. Callee accepted CC request, call agent's ack callback.
2741 * 2. Caller became available, call agent's stop_monitoring callback and
2742 * call monitor's unsuspend callback.
2744 if (previous_state == CC_CALLER_REQUESTED) {
2745 core_instance->agent->callbacks->ack(core_instance->agent);
2746 manager_event(EVENT_FLAG_CC, "CCRequestAcknowledged",
2749 core_instance->core_id, core_instance->agent->device_name);
2750 } else if (previous_state == CC_CALLER_BUSY) {
2751 manager_event(EVENT_FLAG_CC, "CCCallerStopMonitoring",
2754 core_instance->core_id, core_instance->agent->device_name);
2755 unsuspend(core_instance);
2757 /* Not possible for previous_state to be anything else due to the is_state_change_valid check at the beginning */
2761 static int cc_callee_ready(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
2763 core_instance->agent->callbacks->callee_available(core_instance->agent);
2767 static void suspend(struct cc_core_instance *core_instance)
2769 struct ast_cc_monitor *monitor_iter;
2770 AST_LIST_LOCK(core_instance->monitors);
2771 AST_LIST_TRAVERSE_SAFE_BEGIN(core_instance->monitors, monitor_iter, next) {
2772 if (monitor_iter->interface->monitor_class == AST_CC_DEVICE_MONITOR) {
2773 if (monitor_iter->callbacks->suspend(monitor_iter)) {
2774 AST_LIST_REMOVE_CURRENT(next);
2775 cc_extension_monitor_change_is_valid(core_instance, monitor_iter->parent_id,
2776 monitor_iter->interface->device_name, 1);
2777 cc_unref(monitor_iter, "suspend failed. Unref list's reference to monitor");
2781 AST_LIST_TRAVERSE_SAFE_END;
2783 if (!has_device_monitors(core_instance)) {
2784 ast_cc_failed(core_instance->core_id, "All device monitors failed to suspend CC");
2786 AST_LIST_UNLOCK(core_instance->monitors);
2789 static int cc_caller_busy(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
2791 /* Callee was available, but caller was busy, call agent's begin_monitoring callback
2792 * and call monitor's suspend callback.
2794 suspend(core_instance);
2795 core_instance->agent->callbacks->start_monitoring(core_instance->agent);
2796 manager_event(EVENT_FLAG_CC, "CCCallerStartMonitoring",
2799 core_instance->core_id, core_instance->agent->device_name);
2803 static void cancel_available_timer(struct cc_core_instance *core_instance)
2805 struct ast_cc_monitor *monitor_iter;
2806 AST_LIST_LOCK(core_instance->monitors);
2807 AST_LIST_TRAVERSE_SAFE_BEGIN(core_instance->monitors, monitor_iter, next) {
2808 if (monitor_iter->interface->monitor_class == AST_CC_DEVICE_MONITOR) {
2809 if (monitor_iter->callbacks->cancel_available_timer(monitor_iter, &monitor_iter->available_timer_id)) {
2810 AST_LIST_REMOVE_CURRENT(next);
2811 cc_extension_monitor_change_is_valid(core_instance, monitor_iter->parent_id,
2812 monitor_iter->interface->device_name, 1);
2813 cc_unref(monitor_iter, "cancel_available_timer failed. Unref list's reference to monitor");
2817 AST_LIST_TRAVERSE_SAFE_END;
2819 if (!has_device_monitors(core_instance)) {
2820 ast_cc_failed(core_instance->core_id, "All device monitors failed to cancel their available timers");
2822 AST_LIST_UNLOCK(core_instance->monitors);
2825 static int cc_recalling(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
2827 /* Both caller and callee are available, call agent's recall callback
2829 cancel_available_timer(core_instance);
2830 manager_event(EVENT_FLAG_CC, "CCCallerRecalling",
2833 core_instance->core_id, core_instance->agent->device_name);
2837 static int cc_complete(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
2839 /* Recall has made progress, call agent and monitor destructor functions
2841 manager_event(EVENT_FLAG_CC, "CCRecallComplete",
2844 core_instance->core_id, core_instance->agent->device_name);
2845 ao2_t_unlink(cc_core_instances, core_instance, "Unlink core instance since CC recall has completed");
2849 static int cc_failed(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
2851 /* Something along the way failed, call agent and monitor destructor functions
2853 manager_event(EVENT_FLAG_CC, "CCFailure",
2857 core_instance->core_id, core_instance->agent->device_name, args->debug);
2858 ao2_t_unlink(cc_core_instances, core_instance, "Unlink core instance since CC failed");
2862 static int (* const state_change_funcs [])(struct cc_core_instance *, struct cc_state_change_args *, enum cc_state previous_state) = {
2863 [CC_AVAILABLE] = cc_available,
2864 [CC_CALLER_OFFERED] = cc_caller_offered,
2865 [CC_CALLER_REQUESTED] = cc_caller_requested,
2866 [CC_ACTIVE] = cc_active,
2867 [CC_CALLEE_READY] = cc_callee_ready,
2868 [CC_CALLER_BUSY] = cc_caller_busy,
2869 [CC_RECALLING] = cc_recalling,
2870 [CC_COMPLETE] = cc_complete,
2871 [CC_FAILED] = cc_failed,
2874 static int cc_do_state_change(void *datap)
2876 struct cc_state_change_args *args = datap;
2877 struct cc_core_instance *core_instance;
2878 enum cc_state previous_state;
2881 ast_log_dynamic_level(cc_logger_level, "Core %d: State change to %d requested. Reason: %s\n",
2882 args->core_id, args->state, args->debug);
2884 if (!(core_instance = find_cc_core_instance(args->core_id))) {
2885 ast_log_dynamic_level(cc_logger_level, "Core %d: Unable to find core instance.\n", args->core_id);
2890 if (!is_state_change_valid(core_instance->current_state, args->state, core_instance->agent)) {
2891 ast_log_dynamic_level(cc_logger_level, "Core %d: Invalid state change requested. Cannot go from %s to %s\n",
2892 args->core_id, cc_state_to_string(core_instance->current_state), cc_state_to_string(args->state));
2894 cc_unref(core_instance, "Unref core instance from when it was found earlier");
2898 /* We can change to the new state now. */
2899 previous_state = core_instance->current_state;
2900 core_instance->current_state = args->state;
2901 res = state_change_funcs[core_instance->current_state](core_instance, args, previous_state);
2904 cc_unref(core_instance, "Unref since state change has completed"); /* From ao2_find */
2908 static int cc_request_state_change(enum cc_state state, const int core_id, const char *debug, va_list ap)
2914 struct cc_state_change_args *args;
2915 /* This initial call to vsnprintf is simply to find what the
2916 * size of the string needs to be
2919 /* We add 1 to the result since vsnprintf's return does not
2920 * include the terminating null byte
2922 debuglen = vsnprintf(dummy, sizeof(dummy), debug, aq) + 1;
2925 if (!(args = ast_calloc(1, sizeof(*args) + debuglen))) {
2929 args->state = state;
2930 args->core_id = core_id;
2931 vsnprintf(args->debug, debuglen, debug, ap);
2933 res = ast_taskprocessor_push(cc_core_taskprocessor, cc_do_state_change, args);
2940 struct cc_recall_ds_data {
2944 struct cc_monitor_tree *interface_tree;
2947 static void *cc_recall_ds_duplicate(void *data)
2949 struct cc_recall_ds_data *old_data = data;
2950 struct cc_recall_ds_data *new_data = ast_calloc(1, sizeof(*new_data));
2955 new_data->interface_tree = cc_ref(old_data->interface_tree, "Bump refcount of monitor tree for recall datastore duplicate");
2956 new_data->core_id = old_data->core_id;
2957 new_data->nested = 1;
2961 static void cc_recall_ds_destroy(void *data)
2963 struct cc_recall_ds_data *recall_data = data;
2964 recall_data->interface_tree = cc_unref(recall_data->interface_tree, "Unref recall monitor tree");
2965 ast_free(recall_data);
2968 static struct ast_datastore_info recall_ds_info = {
2969 .type = "cc_recall",
2970 .duplicate = cc_recall_ds_duplicate,
2971 .destroy = cc_recall_ds_destroy,
2974 int ast_setup_cc_recall_datastore(struct ast_channel *chan, const int core_id)
2976 struct ast_datastore *recall_datastore = ast_datastore_alloc(&recall_ds_info, NULL);
2977 struct cc_recall_ds_data *recall_data;
2978 struct cc_core_instance *core_instance;
2980 if (!recall_datastore) {
2984 if (!(recall_data = ast_calloc(1, sizeof(*recall_data)))) {
2985 ast_datastore_free(recall_datastore);
2989 if (!(core_instance = find_cc_core_instance(core_id))) {
2990 ast_free(recall_data);
2991 ast_datastore_free(recall_datastore);
2995 recall_data->interface_tree = cc_ref(core_instance->monitors,
2996 "Bump refcount for monitor tree for recall datastore");
2997 recall_data->core_id = core_id;
2998 recall_datastore->data = recall_data;
2999 recall_datastore->inheritance = DATASTORE_INHERIT_FOREVER;
3000 ast_channel_lock(chan);
3001 ast_channel_datastore_add(chan, recall_datastore);
3002 ast_channel_unlock(chan);
3003 cc_unref(core_instance, "Recall datastore set up. No need for core_instance ref");
3007 int ast_cc_is_recall(struct ast_channel *chan, int *core_id, const char * const monitor_type)
3009 struct ast_datastore *recall_datastore;
3010 struct cc_recall_ds_data *recall_data;
3011 struct cc_monitor_tree *interface_tree;
3012 char device_name[AST_CHANNEL_NAME];
3013 struct ast_cc_monitor *device_monitor;
3014 int core_id_candidate;
3016 ast_assert(core_id != NULL);
3020 ast_channel_lock(chan);
3021 if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
3022 /* Obviously not a recall if the datastore isn't present */
3023 ast_channel_unlock(chan);
3027 recall_data = recall_datastore->data;
3029 if (recall_data->ignore) {
3030 /* Though this is a recall, the call to this particular interface is not part of the
3031 * recall either because this is a call forward or because this is not the first
3032 * invocation of Dial during this call
3034 ast_channel_unlock(chan);
3038 if (!recall_data->nested) {
3039 /* If the nested flag is not set, then this means that
3040 * the channel passed to this function is the caller making
3041 * the recall. This means that we shouldn't look through
3042 * the monitor tree for the channel because it shouldn't be
3043 * there. However, this is a recall though, so return true.
3045 *core_id = recall_data->core_id;
3046 ast_channel_unlock(chan);
3050 if (ast_strlen_zero(monitor_type)) {
3051 /* If someone passed a NULL or empty monitor type, then it is clear
3052 * the channel they passed in was an incoming channel, and so searching
3053 * the list of dialed interfaces is not going to be helpful. Just return
3054 * false immediately.
3056 ast_channel_unlock(chan);
3060 interface_tree = recall_data->interface_tree;
3061 ast_channel_get_device_name(chan, device_name, sizeof(device_name));
3062 /* We grab the value of the recall_data->core_id so that we
3063 * can unlock the channel before we start looking through the
3064 * interface list. That way we don't have to worry about a possible
3065 * clash between the channel lock and the monitor tree lock.
3067 core_id_candidate = recall_data->core_id;
3068 ast_channel_unlock(chan);
3071 * Now we need to find out if the channel device name
3072 * is in the list of interfaces in the called tree.
3074 AST_LIST_LOCK(interface_tree);
3075 AST_LIST_TRAVERSE(interface_tree, device_monitor, next) {
3076 if (!strcmp(device_monitor->interface->device_name, device_name) &&
3077 !strcmp(device_monitor->interface->monitor_type, monitor_type)) {
3078 /* BOOM! Device is in the tree! We have a winner! */
3079 *core_id = core_id_candidate;
3080 AST_LIST_UNLOCK(interface_tree);
3084 AST_LIST_UNLOCK(interface_tree);
3088 struct ast_cc_monitor *ast_cc_get_monitor_by_recall_core_id(const int core_id, const char * const device_name)
3090 struct cc_core_instance *core_instance = find_cc_core_instance(core_id);
3091 struct ast_cc_monitor *monitor_iter;
3093 if (!core_instance) {
3097 AST_LIST_LOCK(core_instance->monitors);
3098 AST_LIST_TRAVERSE(core_instance->monitors, monitor_iter, next) {
3099 if (!strcmp(monitor_iter->interface->device_name, device_name)) {
3100 /* Found a monitor. */
3101 cc_ref(monitor_iter, "Hand the requester of the monitor a reference");
3105 AST_LIST_UNLOCK(core_instance->monitors);
3106 cc_unref(core_instance, "Done with core instance ref in ast_cc_get_monitor_by_recall_core_id");
3107 return monitor_iter;
3112 * \brief uniquely append a dialstring to our CC_INTERFACES chanvar string.
3114 * We will only append a string if it has not already appeared in our channel
3115 * variable earlier. We ensure that we don't erroneously match substrings by
3116 * adding an ampersand to the end of our potential dialstring and searching for
3117 * it plus the ampersand in our variable.
3119 * It's important to note that once we have built the full CC_INTERFACES string,
3120 * there will be an extra ampersand at the end which must be stripped off by
3121 * the caller of this function.
3123 * \param str An ast_str holding what we will add to CC_INTERFACES
3124 * \param dialstring A new dialstring to add
3127 static void cc_unique_append(struct ast_str *str, const char * const dialstring)
3129 char dialstring_search[AST_CHANNEL_NAME];
3131 snprintf(dialstring_search, sizeof(dialstring_search), "%s%c", dialstring, '&');
3132 if (strstr(ast_str_buffer(str), dialstring_search)) {
3135 ast_str_append(&str, 0, "%s", dialstring_search);
3140 * \brief Build the CC_INTERFACES channel variable
3142 * The method used is to traverse the child dialstrings in the
3143 * passed-in extension monitor, adding any that have the is_valid
3144 * flag set. Then, traverse the monitors, finding all children
3145 * of the starting extension monitor and adding their dialstrings
3148 * \param starting_point The extension monitor that is the parent to all
3149 * monitors whose dialstrings should be added to CC_INTERFACES
3150 * \param str Where we will store CC_INTERFACES
3153 static void build_cc_interfaces_chanvar(struct ast_cc_monitor *starting_point, struct ast_str *str)
3155 struct extension_monitor_pvt *extension_pvt;
3156 struct extension_child_dialstring *child_dialstring;
3157 struct ast_cc_monitor *monitor_iter = starting_point;
3158 int top_level_id = starting_point->id;
3160 /* First we need to take all of the is_valid child_dialstrings from
3161 * the extension monitor we found and add them to the CC_INTERFACES
3164 extension_pvt = starting_point->private_data;
3165 AST_LIST_TRAVERSE(&extension_pvt->child_dialstrings, child_dialstring, next) {
3166 if (child_dialstring->is_valid) {
3167 cc_unique_append(str, child_dialstring->original_dialstring);
3171 /* And now we get the dialstrings from each of the device monitors */
3172 while ((monitor_iter = AST_LIST_NEXT(monitor_iter, next))) {
3173 if (monitor_iter->parent_id == top_level_id) {
3174 cc_unique_append(str, monitor_iter->dialstring);
3178 /* str will have an extra '&' tacked onto the end of it, so we need
3179 * to get rid of that.
3181 ast_str_truncate(str, ast_str_strlen(str) - 1);
3184 int ast_cc_agent_set_interfaces_chanvar(struct ast_channel *chan)
3186 struct ast_datastore *recall_datastore;
3187 struct cc_monitor_tree *interface_tree;
3188 struct ast_cc_monitor *monitor;
3189 struct cc_recall_ds_data *recall_data;
3190 struct ast_str *str = ast_str_create(64);
3197 ast_channel_lock(chan);
3198 if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
3199 ast_channel_unlock(chan);
3203 recall_data = recall_datastore->data;
3204 interface_tree = recall_data->interface_tree;
3205 core_id = recall_data->core_id;
3206 ast_channel_unlock(chan);
3208 AST_LIST_LOCK(interface_tree);
3209 monitor = AST_LIST_FIRST(interface_tree);
3210 build_cc_interfaces_chanvar(monitor, str);
3211 AST_LIST_UNLOCK(interface_tree);
3213 pbx_builtin_setvar_helper(chan, "CC_INTERFACES", ast_str_buffer(str));
3214 ast_log_dynamic_level(cc_logger_level, "Core %d: CC_INTERFACES set to %s\n",
3215 core_id, ast_str_buffer(str));
3221 int ast_set_cc_interfaces_chanvar(struct ast_channel *chan, const char * const extension)
3223 struct ast_datastore *recall_datastore;
3224 struct cc_monitor_tree *interface_tree;
3225 struct ast_cc_monitor *monitor_iter;
3226 struct cc_recall_ds_data *recall_data;
3227 struct ast_str *str = ast_str_create(64);
3234 ast_channel_lock(chan);
3235 if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
3236 ast_channel_unlock(chan);
3240 recall_data = recall_datastore->data;
3241 interface_tree = recall_data->interface_tree;
3242 core_id = recall_data->core_id;
3243 ast_channel_unlock(chan);
3245 AST_LIST_LOCK(interface_tree);
3246 AST_LIST_TRAVERSE(interface_tree, monitor_iter, next) {
3247 if (!strcmp(monitor_iter->interface->device_name, extension)) {
3252 if (!monitor_iter) {
3253 /* We couldn't find this extension. This may be because
3254 * we have been directed into an unexpected extension because
3255 * the admin has changed a CC_INTERFACES variable at some point.
3257 AST_LIST_UNLOCK(interface_tree);
3262 build_cc_interfaces_chanvar(monitor_iter, str);
3263 AST_LIST_UNLOCK(interface_tree);
3265 pbx_builtin_setvar_helper(chan, "CC_INTERFACES", ast_str_buffer(str));
3266 ast_log_dynamic_level(cc_logger_level, "Core %d: CC_INTERFACES set to %s\n",
3267 core_id, ast_str_buffer(str));
3273 void ast_ignore_cc(struct ast_channel *chan)
3275 struct ast_datastore *cc_datastore;
3276 struct ast_datastore *cc_recall_datastore;
3277 struct dialed_cc_interfaces *cc_interfaces;
3278 struct cc_recall_ds_data *recall_cc_data;
3280 ast_channel_lock(chan);
3281 if ((cc_datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL))) {
3282 cc_interfaces = cc_datastore->data;
3283 cc_interfaces->ignore = 1;
3286 if ((cc_recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
3287 recall_cc_data = cc_recall_datastore->data;
3288 recall_cc_data->ignore = 1;
3290 ast_channel_unlock(chan);
3293 static __attribute__((format(printf, 2, 3))) int cc_offer(const int core_id, const char * const debug, ...)
3298 va_start(ap, debug);
3299 res = cc_request_state_change(CC_CALLER_OFFERED, core_id, debug, ap);
3304 int ast_cc_offer(struct ast_channel *caller_chan)
3308 struct ast_datastore *datastore;
3309 struct dialed_cc_interfaces *cc_interfaces;
3310 char cc_is_offerable;
3312 ast_channel_lock(caller_chan);
3313 if (!(datastore = ast_channel_datastore_find(caller_chan, &dialed_cc_interfaces_info, NULL))) {
3314 ast_channel_unlock(caller_chan);
3318 cc_interfaces = datastore->data;
3319 cc_is_offerable = cc_interfaces->is_original_caller;
3320 core_id = cc_interfaces->core_id;
3321 ast_channel_unlock(caller_chan);
3323 if (cc_is_offerable) {
3324 res = cc_offer(core_id, "CC offered to caller %s", caller_chan->name);
3329 int ast_cc_agent_accept_request(int core_id, const char * const debug, ...)
3334 va_start(ap, debug);
3335 res = cc_request_state_change(CC_CALLER_REQUESTED, core_id, debug, ap);
3340 int ast_cc_monitor_request_acked(int core_id, const char * const debug, ...)
3345 va_start(ap, debug);
3346 res = cc_request_state_change(CC_ACTIVE, core_id, debug, ap);
3351 int ast_cc_monitor_callee_available(const int core_id, const char * const debug, ...)
3356 va_start(ap, debug);
3357 res = cc_request_state_change(CC_CALLEE_READY, core_id, debug, ap);
3362 int ast_cc_agent_caller_busy(int core_id, const char * debug, ...)
3367 va_start(ap, debug);
3368 res = cc_request_state_change(CC_CALLER_BUSY, core_id, debug, ap);
3373 int ast_cc_agent_caller_available(int core_id, const char * const debug, ...)
3378 va_start(ap, debug);
3379 res = cc_request_state_change(CC_ACTIVE, core_id, debug, ap);
3384 int ast_cc_agent_recalling(int core_id, const char * const debug, ...)
3389 va_start(ap, debug);
3390 res = cc_request_state_change(CC_RECALLING, core_id, debug, ap);
3395 int ast_cc_completed(struct ast_channel *chan, const char * const debug, ...)
3397 struct ast_datastore *recall_datastore;
3398 struct cc_recall_ds_data *recall_data;
3403 ast_channel_lock(chan);
3404 if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
3405 /* Silly! Why did you call this function if there's no recall DS? */
3406 ast_channel_unlock(chan);
3409 recall_data = recall_datastore->data;
3410 if (recall_data->nested || recall_data->ignore) {
3411 /* If this is being called from a nested Dial, it is too
3412 * early to determine if the recall has actually completed.
3413 * The outermost dial is the only one with the authority to
3414 * declare the recall to be complete.
3416 * Similarly, if this function has been called when the
3417 * recall has progressed beyond the first dial, this is not
3418 * a legitimate time to declare the recall to be done. In fact,
3419 * that should have been done already.
3421 ast_channel_unlock(chan);
3424 core_id = recall_data->core_id;
3425 ast_channel_unlock(chan);
3426 va_start(ap, debug);
3427 res = cc_request_state_change(CC_COMPLETE, core_id, debug, ap);
3432 int ast_cc_failed(int core_id, const char * const debug, ...)
3437 va_start(ap, debug);
3438 res = cc_request_state_change(CC_FAILED, core_id, debug, ap);
3443 struct ast_cc_monitor_failure_data {
3444 const char *device_name;
3449 static int cc_monitor_failed(void *data)
3451 struct ast_cc_monitor_failure_data *failure_data = data;
3452 struct cc_core_instance *core_instance;
3453 struct ast_cc_monitor *monitor_iter;
3455 core_instance = find_cc_core_instance(failure_data->core_id);
3456 if (!core_instance) {
3457 /* Core instance no longer exists or invalid core_id. */
3458 ast_log_dynamic_level(cc_logger_level,
3459 "Core %d: Could not find core instance for device %s '%s'\n",
3460 failure_data->core_id, failure_data->device_name, failure_data->debug);
3461 ast_free((char *) failure_data->device_name);
3462 ast_free((char *) failure_data->debug);
3463 ast_free(failure_data);
3467 AST_LIST_LOCK(core_instance->monitors);
3468 AST_LIST_TRAVERSE_SAFE_BEGIN(core_instance->monitors, monitor_iter, next) {
3469 if (monitor_iter->interface->monitor_class == AST_CC_DEVICE_MONITOR) {
3470 if (!strcmp(monitor_iter->interface->device_name, failure_data->device_name)) {
3471 AST_LIST_REMOVE_CURRENT(next);
3472 cc_extension_monitor_change_is_valid(core_instance, monitor_iter->parent_id,
3473 monitor_iter->interface->device_name, 1);
3474 monitor_iter->callbacks->cancel_available_timer(monitor_iter, &monitor_iter->available_timer_id);
3475 manager_event(EVENT_FLAG_CC, "CCMonitorFailed",
3478 monitor_iter->core_id, monitor_iter->interface->device_name);
3479 cc_unref(monitor_iter, "Monitor reported failure. Unref list's reference.");
3483 AST_LIST_TRAVERSE_SAFE_END;
3485 if (!has_device_monitors(core_instance)) {
3486 ast_cc_failed(core_instance->core_id, "All monitors have failed\n");
3488 AST_LIST_UNLOCK(core_instance->monitors);
3489 cc_unref(core_instance, "Finished with core_instance in cc_monitor_failed\n");
3491 ast_free((char *) failure_data->device_name);
3492 ast_free((char *) failure_data->debug);
3493 ast_free(failure_data);
3497 int ast_cc_monitor_failed(int core_id, const char *const monitor_name, const char * const debug, ...)
3499 struct ast_cc_monitor_failure_data *failure_data;
3503 if (!(failure_data = ast_calloc(1, sizeof(*failure_data)))) {
3507 if (!(failure_data->device_name = ast_strdup(monitor_name))) {
3508 ast_free(failure_data);
3512 va_start(ap, debug);
3513 if (ast_vasprintf(&failure_data->debug, debug, ap) == -1) {
3515 ast_free((char *)failure_data->device_name);
3516 ast_free(failure_data);
3521 failure_data->core_id = core_id;
3523 res = ast_taskprocessor_push(cc_core_taskprocessor, cc_monitor_failed, failure_data);
3525 ast_free((char *)failure_data->device_name);
3526 ast_free((char *)failure_data->debug);
3527 ast_free(failure_data);
3532 static int cc_status_request(void *data)
3534 struct cc_core_instance *core_instance= data;
3537 res = core_instance->agent->callbacks->status_request(core_instance->agent);
3538 cc_unref(core_instance, "Status request finished. Unref core instance");
3542 int ast_cc_monitor_status_request(int core_id)
3545 struct cc_core_instance *core_instance = find_cc_core_instance(core_id);
3547 if (!core_instance) {
3551 res = ast_taskprocessor_push(cc_core_taskprocessor, cc_status_request, core_instance);
3553 cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed");
3558 static int cc_stop_ringing(void *data)
3560 struct cc_core_instance *core_instance = data;
3563 if (core_instance->agent->callbacks->stop_ringing) {
3564 res = core_instance->agent->callbacks->stop_ringing(core_instance->agent);
3566 /* If an agent is being asked to stop ringing, then he needs to be prepared if for
3567 * whatever reason he needs to be called back again. The proper state to be in to
3568 * detect such a circumstance is the CC_ACTIVE state.
3570 * We get to this state using the slightly unintuitive method of calling
3571 * ast_cc_monitor_request_acked because it gets us to the proper state.
3573 ast_cc_monitor_request_acked(core_instance->core_id, "Agent %s asked to stop ringing. Be prepared to be recalled again.",
3574 core_instance->agent->device_name);
3575 cc_unref(core_instance, "Stop ringing finished. Unref core_instance");
3579 int ast_cc_monitor_stop_ringing(int core_id)
3582 struct cc_core_instance *core_instance = find_cc_core_instance(core_id);
3584 if (!core_instance) {
3588 res = ast_taskprocessor_push(cc_core_taskprocessor, cc_stop_ringing, core_instance);
3590 cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed");
3595 static int cc_party_b_free(void *data)
3597 struct cc_core_instance *core_instance = data;
3600 if (core_instance->agent->callbacks->party_b_free) {
3601 res = core_instance->agent->callbacks->party_b_free(core_instance->agent);
3603 cc_unref(core_instance, "Party B free finished. Unref core_instance");
3607 int ast_cc_monitor_party_b_free(int core_id)
3610 struct cc_core_instance *core_instance = find_cc_core_instance(core_id);
3612 if (!core_instance) {
3616 res = ast_taskprocessor_push(cc_core_taskprocessor, cc_party_b_free, core_instance);
3618 cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed");
3623 struct cc_status_response_args {
3624 struct cc_core_instance *core_instance;
3625 enum ast_device_state devstate;
3628 static int cc_status_response(void *data)
3630 struct cc_status_response_args *args = data;
3631 struct cc_core_instance *core_instance = args->core_instance;
3632 struct ast_cc_monitor *monitor_iter;
3633 enum ast_device_state devstate = args->devstate;
3637 AST_LIST_LOCK(core_instance->monitors);
3638 AST_LIST_TRAVERSE(core_instance->monitors, monitor_iter, next) {
3639 if (monitor_iter->interface->monitor_class == AST_CC_DEVICE_MONITOR &&
3640 monitor_iter->callbacks->status_response) {
3641 monitor_iter->callbacks->status_response(monitor_iter, devstate);
3644 AST_LIST_UNLOCK(core_instance->monitors);
3645 cc_unref(core_instance, "Status response finished. Unref core instance");
3649 int ast_cc_agent_status_response(int core_id, enum ast_device_state devstate)
3651 struct cc_status_response_args *args;
3652 struct cc_core_instance *core_instance;
3655 args = ast_calloc(1, sizeof(*args));
3660 core_instance = find_cc_core_instance(core_id);
3661 if (!core_instance) {
3666 args->core_instance = core_instance;
3667 args->devstate = devstate;
3669 res = ast_taskprocessor_push(cc_core_taskprocessor, cc_status_response, args);
3671 cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed");
3677 static int cc_build_payload(struct ast_channel *chan, struct ast_cc_config_params *cc_params,
3678 const char *monitor_type, const char * const device_name, const char * dialstring,
3679 enum ast_cc_service_type service, void *private_data, struct cc_control_payload *payload)
3681 struct ast_datastore *datastore;
3682 struct dialed_cc_interfaces *cc_interfaces;
3685 ast_channel_lock(chan);
3686 datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL);
3688 ast_channel_unlock(chan);
3691 cc_interfaces = datastore->data;
3692 dial_parent_id = cc_interfaces->dial_parent_id;
3693 ast_channel_unlock(chan);
3695 payload->monitor_type = monitor_type;
3696 payload->private_data = private_data;
3697 payload->service = service;
3698 ast_cc_copy_config_params(&payload->config_params, cc_params);
3699 payload->parent_interface_id = dial_parent_id;
3700 ast_copy_string(payload->device_name, device_name, sizeof(payload->device_name));
3701 ast_copy_string(payload->dialstring, dialstring, sizeof(payload->dialstring));
3705 int ast_queue_cc_frame(struct ast_channel *chan, const char *monitor_type,
3706 const char * const dialstring, enum ast_cc_service_type service, void *private_data)
3708 struct ast_frame frame = {0,};
3709 char device_name[AST_CHANNEL_NAME];
3711 struct ast_cc_config_params *cc_params;
3713 cc_params = ast_channel_get_cc_config_params(chan);
3717 ast_channel_get_device_name(chan, device_name, sizeof(device_name));
3718 if (ast_cc_monitor_count(device_name, monitor_type) >= ast_get_cc_max_monitors(cc_params)) {
3719 ast_log(LOG_NOTICE, "Not queuing a CC frame for device %s since it already has its maximum monitors allocated\n", device_name);
3723 if (ast_cc_build_frame(chan, cc_params, monitor_type, device_name, dialstring, service, private_data, &frame)) {
3724 /* Frame building failed. We can't use this. */
3727 retval = ast_queue_frame(chan, &frame);
3732 int ast_cc_build_frame(struct ast_channel *chan, struct ast_cc_config_params *cc_params,
3733 const char *monitor_type, const char * const device_name,
3734 const char * const dialstring, enum ast_cc_service_type service, void *private_data,
3735 struct ast_frame *frame)
3737 struct cc_control_payload *payload = ast_calloc(1, sizeof(*payload));
3742 if (cc_build_payload(chan, cc_params, monitor_type, device_name, dialstring, service, private_data, payload)) {
3743 /* Something screwed up, we can't make a frame with this */
3747 frame->frametype = AST_FRAME_CONTROL;
3748 frame->subclass.integer = AST_CONTROL_CC;
3749 frame->data.ptr = payload;
3750 frame->datalen = sizeof(*payload);
3751 frame->mallocd = AST_MALLOCD_DATA;
3755 void ast_cc_call_failed(struct ast_channel *incoming, struct ast_channel *outgoing, const char * const dialstring)
3757 char device_name[AST_CHANNEL_NAME];
3758 struct cc_control_payload payload;
3759 struct ast_cc_config_params *cc_params;
3761 if (outgoing->hangupcause != AST_CAUSE_BUSY && outgoing->hangupcause != AST_CAUSE_CONGESTION) {
3762 /* It doesn't make sense to try to offer CCBS to the caller if the reason for ast_call
3763 * failing is something other than busy or congestion
3768 cc_params = ast_channel_get_cc_config_params(outgoing);
3772 if (ast_get_cc_monitor_policy(cc_params) != AST_CC_MONITOR_GENERIC) {
3773 /* This sort of CCBS only works if using generic CC. For native, we would end up sending
3774 * a CC request for a non-existent call. The far end will reject this every time
3779 ast_channel_get_device_name(outgoing, device_name, sizeof(device_name));
3780 if (cc_build_payload(outgoing, cc_params, AST_CC_GENERIC_MONITOR_TYPE, device_name,
3781 dialstring, AST_CC_CCBS, NULL, &payload)) {
3782 /* Something screwed up, we can't make a frame with this */
3785 ast_handle_cc_control_frame(incoming, outgoing, &payload);
3788 void ast_cc_busy_interface(struct ast_channel *inbound, struct ast_cc_config_params *cc_params,
3789 const char *monitor_type, const char * const device_name, const char * const dialstring, void *private_data)
3791 struct cc_control_payload payload;
3792 if (cc_build_payload(inbound, cc_params, monitor_type, device_name, dialstring, AST_CC_CCBS, private_data, &payload)) {
3793 /* Something screwed up. Don't try to handle this payload */
3794 call_destructor_with_no_monitor(monitor_type, private_data);
3797 ast_handle_cc_control_frame(inbound, NULL, &payload);
3800 int ast_cc_callback(struct ast_channel *inbound, const char * const tech, const char * const dest, ast_cc_callback_fn callback)
3802 const struct ast_channel_tech *chantech = ast_get_channel_tech(tech);
3804 if (chantech && chantech->cc_callback) {
3805 chantech->cc_callback(inbound, dest, callback);
3811 static const char *ccreq_app = "CallCompletionRequest";
3813 static int ccreq_exec(struct ast_channel *chan, const char *data)
3815 struct cc_core_instance *core_instance;
3816 char device_name[AST_CHANNEL_NAME];
3817 unsigned long match_flags;
3820 ast_channel_get_device_name(chan, device_name, sizeof(device_name));
3822 match_flags = MATCH_NO_REQUEST;
3823 if (!(core_instance = ao2_t_callback_data(cc_core_instances, 0, match_agent, device_name, &match_flags, "Find core instance for CallCompletionRequest"))) {
3824 ast_log_dynamic_level(cc_logger_level, "Couldn't find a core instance for caller %s\n", device_name);
3828 ast_log_dynamic_level(cc_logger_level, "Core %d: Found core_instance for caller %s\n",
3829 core_instance->core_id, device_name);
3831 if (strcmp(core_instance->agent->callbacks->type, "generic")) {
3832 ast_log_dynamic_level(cc_logger_level, "Core %d: CallCompletionRequest is only for generic agent types.\n",
3833 core_instance->core_id);
3834 pbx_builtin_setvar_helper(chan, "CC_REQUEST_RESULT", "FAIL");
3835 cc_unref(core_instance, "Unref core_instance since CallCompletionRequest was called with native agent");
3839 if (!ast_cc_request_is_within_limits()) {
3840 ast_log_dynamic_level(cc_logger_level, "Core %d: CallCompletionRequest failed. Too many requests in the system\n",
3841 core_instance->core_id);
3842 ast_cc_failed(core_instance->core_id, "Too many CC requests\n");
3843 pbx_builtin_setvar_helper(chan, "CC_REQUEST_RESULT", "FAIL");
3844 cc_unref(core_instance, "Unref core_instance since too many CC requests");
3848 res = ast_cc_agent_accept_request(core_instance->core_id, "CallCompletionRequest called by caller %s for core_id %d", device_name, core_instance->core_id);
3849 pbx_builtin_setvar_helper(chan, "CC_REQUEST_RESULT", res ? "FAIL" : "SUCCESS");
3850 cc_unref(core_instance, "Done with CallCompletionRequest");
3854 static const char *cccancel_app = "CallCompletionCancel";
3856 static int cccancel_exec(struct ast_channel *chan, const char *data)
3858 struct cc_core_instance *core_instance;
3859 char device_name[AST_CHANNEL_NAME];
3860 unsigned long match_flags;
3863 ast_channel_get_device_name(chan, device_name, sizeof(device_name));
3865 match_flags = MATCH_REQUEST;
3866 if (!(core_instance = ao2_t_callback_data(cc_core_instances, 0, match_agent, device_name, &match_flags, "Find core instance for CallCompletionCancel"))) {
3867 ast_log(LOG_WARNING, "Cannot find CC transaction to cancel for caller %s\n", device_name);
3871 if (strcmp(core_instance->agent->callbacks->type, "generic")) {
3872 ast_log(LOG_WARNING, "CallCompletionCancel may only be used for calles with a generic agent\n");
3873 cc_unref(core_instance, "Unref core instance found during CallCompletionCancel");
3876 res = ast_cc_failed(core_instance->core_id, "Call completion request Cancelled for core ID %d by caller %s",
3877 core_instance->core_id, device_name);
3878 cc_unref(core_instance, "Unref core instance found during CallCompletionCancel");
3882 struct count_monitors_cb_data {
3883 const char *device_name;
3884 const char *monitor_type;
3888 static int count_monitors_cb(void *obj, void *arg, int flags)
3890 struct cc_core_instance *core_instance = obj;
3891 struct count_monitors_cb_data *cb_data = arg;
3892 const char *device_name = cb_data->device_name;
3893 const char *monitor_type = cb_data->monitor_type;
3894 struct ast_cc_monitor *monitor_iter;
3896 AST_LIST_LOCK(core_instance->monitors);
3897 AST_LIST_TRAVERSE(core_instance->monitors, monitor_iter, next) {
3898 if (!strcmp(monitor_iter->interface->device_name, device_name) &&
3899 !strcmp(monitor_iter->interface->monitor_type, monitor_type)) {
3904 AST_LIST_UNLOCK(core_instance->monitors);
3908 int ast_cc_monitor_count(const char * const name, const char * const type)
3910 struct count_monitors_cb_data data = {.device_name = name, .monitor_type = type,};
3912 ao2_t_callback(cc_core_instances, OBJ_NODATA, count_monitors_cb, &data, "Counting agents");
3913 ast_log_dynamic_level(cc_logger_level, "Counted %d monitors\n", data.count);
3917 static void initialize_cc_max_requests(void)
3919 struct ast_config *cc_config;
3920 const char *cc_max_requests_str;
3921 struct ast_flags config_flags = {0,};
3924 cc_config = ast_config_load2("ccss.conf", "ccss", config_flags);
3925 if (!cc_config || cc_config == CONFIG_STATUS_FILEINVALID) {
3926 ast_log(LOG_WARNING, "Could not find valid ccss.conf file. Using cc_max_requests default\n");
3927 global_cc_max_requests = GLOBAL_CC_MAX_REQUESTS_DEFAULT;
3931 if (!(cc_max_requests_str = ast_variable_retrieve(cc_config, "general", "cc_max_requests"))) {
3932 ast_config_destroy(cc_config);
3933 ast_log(LOG_WARNING, "No cc_max_requests defined. Using default\n");
3934 global_cc_max_requests = GLOBAL_CC_MAX_REQUESTS_DEFAULT;
3938 global_cc_max_requests = strtol(cc_max_requests_str, &endptr, 10);
3940 if (!ast_strlen_zero(endptr)) {
3941 ast_log(LOG_WARNING, "Invalid input given for cc_max_requests. Using default\n");
3942 global_cc_max_requests = GLOBAL_CC_MAX_REQUESTS_DEFAULT;
3945 ast_config_destroy(cc_config);
3949 static void cc_cli_print_monitor_stats(struct ast_cc_monitor *monitor, int fd, int parent_id)
3951 struct ast_cc_monitor *child_monitor_iter = monitor;
3956 ast_cli(fd, "\t\t|-->%s", monitor->interface->device_name);
3957 if (monitor->interface->monitor_class == AST_CC_DEVICE_MONITOR) {
3958 ast_cli(fd, "(%s)", cc_service_to_string(monitor->service_offered));
3962 while ((child_monitor_iter = AST_LIST_NEXT(child_monitor_iter, next))) {
3963 if (child_monitor_iter->parent_id == monitor->id) {
3964 cc_cli_print_monitor_stats(child_monitor_iter, fd, child_monitor_iter->id);
3969 static int print_stats_cb(void *obj, void *arg, int flags)
3972 struct cc_core_instance *core_instance = obj;
3974 ast_cli(*cli_fd, "%d\t\t%s\t\t%s\n", core_instance->core_id, core_instance->agent->devi