Asterisk - The Open Source Telephony Project GIT-master-2070bb5
ccss.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 1999 - 2010, Digium, Inc.
5 *
6 * Mark Michelson <mmichelson@digium.com>
7 *
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.
13 *
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.
17 */
18
19/*! \file
20 * \brief Call Completion Supplementary Services implementation
21 * \author Mark Michelson <mmichelson@digium.com>
22 */
23
24/*! \li \ref ccss.c uses the configuration file \ref ccss.conf
25 * \addtogroup configuration_file Configuration Files
26 */
27
28/*!
29 * \page ccss.conf ccss.conf
30 * \verbinclude ccss.conf.sample
31 */
32
33/*** MODULEINFO
34 <support_level>core</support_level>
35 ***/
36
37#include "asterisk.h"
38
39#include "asterisk/astobj2.h"
40#include "asterisk/strings.h"
41#include "asterisk/ccss.h"
42#include "asterisk/channel.h"
43#include "asterisk/pbx.h"
44#include "asterisk/utils.h"
47#include "asterisk/module.h"
48#include "asterisk/app.h"
49#include "asterisk/cli.h"
50#include "asterisk/manager.h"
51#include "asterisk/causes.h"
54
55/*** DOCUMENTATION
56 <application name="CallCompletionRequest" language="en_US">
57 <synopsis>
58 Request call completion service for previous call
59 </synopsis>
60 <syntax />
61 <description>
62 <para>Request call completion service for a previously failed
63 call attempt.</para>
64 <para>This application sets the following channel variables:</para>
65 <variablelist>
66 <variable name="CC_REQUEST_RESULT">
67 <para>This is the returned status of the request.</para>
68 <value name="SUCCESS" />
69 <value name="FAIL" />
70 </variable>
71 <variable name="CC_REQUEST_REASON">
72 <para>This is the reason the request failed.</para>
73 <value name="NO_CORE_INSTANCE" />
74 <value name="NOT_GENERIC" />
75 <value name="TOO_MANY_REQUESTS" />
76 <value name="UNSPECIFIED" />
77 </variable>
78 </variablelist>
79 </description>
80 </application>
81 <application name="CallCompletionCancel" language="en_US">
82 <synopsis>
83 Cancel call completion service
84 </synopsis>
85 <syntax />
86 <description>
87 <para>Cancel a Call Completion Request.</para>
88 <para>This application sets the following channel variables:</para>
89 <variablelist>
90 <variable name="CC_CANCEL_RESULT">
91 <para>This is the returned status of the cancel.</para>
92 <value name="SUCCESS" />
93 <value name="FAIL" />
94 </variable>
95 <variable name="CC_CANCEL_REASON">
96 <para>This is the reason the cancel failed.</para>
97 <value name="NO_CORE_INSTANCE" />
98 <value name="NOT_GENERIC" />
99 <value name="UNSPECIFIED" />
100 </variable>
101 </variablelist>
102 </description>
103 </application>
104 ***/
105
106/* These are some file-scoped variables. It would be
107 * nice to define them closer to their first usage, but since
108 * they are used in many places throughout the file, defining
109 * them here at the top is easiest.
110 */
111
112/*!
113 * The ast_sched_context used for all generic CC timeouts
114 */
116/*!
117 * Counter used to create core IDs for CC calls. Each new
118 * core ID is created by atomically adding 1 to the core_id_counter
119 */
121/*!
122 * Taskprocessor from which all CC agent and monitor callbacks
123 * are called.
124 */
126/*!
127 * Name printed on all CC log messages.
128 */
129static const char *CC_LOGGER_LEVEL_NAME = "CC";
130/*!
131 * Logger level registered by the CC core.
132 */
134/*!
135 * Parsed configuration value for cc_max_requests
136 */
137static unsigned int global_cc_max_requests;
138/*!
139 * The current number of CC requests in the system
140 */
142
143static inline void *cc_ref(void *obj, const char *debug)
144{
145 ao2_t_ref(obj, +1, debug);
146 return obj;
147}
148
149static inline void *cc_unref(void *obj, const char *debug)
150{
151 ao2_t_ref(obj, -1, debug);
152 return NULL;
153}
154
155/*!
156 * \since 1.8
157 * \internal
158 * \brief A structure for holding the configuration parameters
159 * relating to CCSS
160 */
164 unsigned int cc_offer_timer;
167 unsigned int cc_recall_timer;
168 unsigned int cc_max_agents;
169 unsigned int cc_max_monitors;
172};
173
174/*!
175 * \since 1.8
176 * \brief The states used in the CCSS core state machine
177 *
178 * For more information, see doc/CCSS_architecture.pdf
179 */
181 /*! Entered when it is determined that CCSS may be used for the call */
183 /*! Entered when a CCSS agent has offered CCSS to a caller */
185 /*! Entered when a CCSS agent confirms that a caller has
186 * requested CCSS */
188 /*! Entered when a CCSS monitor confirms acknowledgment of an
189 * outbound CCSS request */
191 /*! Entered when a CCSS monitor alerts the core that the called party
192 * has become available */
194 /*! Entered when a CCSS agent alerts the core that the calling party
195 * may not be recalled because he is unavailable
196 */
198 /*! Entered when a CCSS agent alerts the core that the calling party
199 * is attempting to recall the called party
200 */
202 /*! Entered when an application alerts the core that the calling party's
203 * recall attempt has had a call progress response indicated
204 */
206 /*! Entered any time that something goes wrong during the process, thus
207 * resulting in the failure of the attempted CCSS transaction. Note also
208 * that cancellations of CC are treated as failures.
209 */
211};
212
213/*!
214 * \brief The payload for an AST_CONTROL_CC frame
215 *
216 * \details
217 * This contains all the necessary data regarding
218 * a called device so that the CC core will be able
219 * to allocate the proper monitoring resources.
220 */
222 /*!
223 * \brief The type of monitor to allocate.
224 *
225 * \details
226 * The type of monitor to allocate. This is a string which corresponds
227 * to a set of monitor callbacks registered. Examples include "generic"
228 * and "SIP"
229 *
230 * \note This really should be an array of characters in case this payload
231 * is sent across an IAX2 link. However, this would not make too much sense
232 * given this type may not be recognized by the other end.
233 * Protection may be necessary to prevent it from being transmitted.
234 *
235 * In addition the following other problems are also possible:
236 * 1) Endian issues with the integers/enums stored in the config_params.
237 * 2) Alignment padding issues for the element types.
238 */
239 const char *monitor_type;
240 /*!
241 * \brief Private data allocated by the callee
242 *
243 * \details
244 * All channel drivers that monitor endpoints will need to allocate
245 * data that is not usable by the CC core. In most cases, some or all
246 * of this data is allocated at the time that the channel driver offers
247 * CC to the caller. There are many opportunities for failures to occur
248 * between when a channel driver offers CC and when a monitor is actually
249 * allocated to watch the endpoint. For this reason, the channel driver
250 * must give the core a pointer to the private data that was allocated so
251 * that the core can call back into the channel driver to destroy it if
252 * a failure occurs. If no private data has been allocated at the time that
253 * CC is offered, then it is perfectly acceptable to pass NULL for this
254 * field.
255 */
257 /*!
258 * \brief Service offered by the endpoint
259 *
260 * \details
261 * This indicates the type of call completion service offered by the
262 * endpoint. This data is not crucial to the machinations of the CC core,
263 * but it is helpful for debugging purposes.
264 */
266 /*!
267 * \brief Configuration parameters used by this endpoint
268 *
269 * \details
270 * Each time an endpoint offers call completion, it must provide its call
271 * completion configuration parameters. This is because settings may be different
272 * depending on the circumstances.
273 */
275 /*!
276 * \brief ID of parent extension
277 *
278 * \details
279 * This is the only datum that the CC core derives on its own and is not
280 * provided by the offerer of CC. This provides the core with information on
281 * which extension monitor is the most immediate parent of this device.
282 */
284 /*!
285 * \brief Name of device to be monitored
286 *
287 * \details
288 * The device name by which this monitored endpoint will be referred in the
289 * CC core. It is highly recommended that this device name is derived by using
290 * the function ast_channel_get_device_name.
291 */
293 /*!
294 * \brief Recall dialstring
295 *
296 * \details
297 * Certain channel drivers (DAHDI in particular) will require that a special
298 * dialstring be used to indicate that the outgoing call is to interpreted as
299 * a CC recall. If the channel driver has such a requirement, then this is
300 * where that special recall dialstring is placed. If no special dialstring
301 * is to be used, then the channel driver must provide the original dialstring
302 * used to call this endpoint.
303 */
305};
306
307/*!
308 * \brief The "tree" of interfaces that is dialed.
309 *
310 * \details
311 * Though this is a linked list, it is logically treated
312 * as a tree of monitors. Each monitor has an id and a parent_id
313 * associated with it. The id is a unique ID for that monitor, and
314 * the parent_id is the unique ID of the monitor's parent in the
315 * tree. The tree is structured such that all of a parent's children
316 * will appear after the parent in the tree. However, it cannot be
317 * guaranteed exactly where after the parent the children are.
318 *
319 * The tree is reference counted since several threads may need
320 * to use it, and it may last beyond the lifetime of a single
321 * thread.
322 */
324
325static const int CC_CORE_INSTANCES_BUCKETS = 17;
327
329 /*!
330 * Unique identifier for this instance of the CC core.
331 */
333 /*!
334 * The current state for this instance of the CC core.
335 */
337 /*!
338 * The CC agent in use for this call
339 */
341 /*!
342 * Reference to the monitor tree formed during the initial call
343 */
345};
346
347/*!
348 * \internal
349 * \brief Request that the core change states
350 * \param state The state to which we wish to change
351 * \param core_id The unique identifier for this instance of the CCSS core state machine
352 * \param debug Optional message explaining the reason for the state change
353 * \param ap varargs list
354 * \retval 0 State change successfully queued
355 * \retval -1 Unable to queue state change request
356 */
357static int __attribute__((format(printf, 3, 0))) cc_request_state_change(enum cc_state state, const int core_id, const char *debug, va_list ap);
358
359/*!
360 * \internal
361 * \brief create a new instance of the CC core and an agent for the calling channel
362 *
363 * This function will check to make sure that the incoming channel
364 * is allowed to request CC by making sure that the incoming channel
365 * has not exceeded its maximum number of allowed agents.
366 *
367 * Should that check pass, the core instance is created, and then the
368 * agent for the channel.
369 *
370 * \param caller_chan The incoming channel for this particular call
371 * \param called_tree A reference to the tree of called devices. The agent
372 * will gain a reference to this tree as well
373 * \param core_id The core_id that this core_instance will assume
374 * \param cc_data
375 * \retval NULL Failed to create the core instance either due to memory allocation
376 * errors or due to the agent count for the caller being too high
377 * \retval non-NULL A reference to the newly created cc_core_instance
378 */
379static struct cc_core_instance *cc_core_init_instance(struct ast_channel *caller_chan,
380 struct cc_monitor_tree *called_tree, const int core_id, struct cc_control_payload *cc_data);
381
382static const struct {
384 const char *service_string;
386 {AST_CC_NONE, "NONE"},
387 {AST_CC_CCBS, "CCBS"},
388 {AST_CC_CCNR, "CCNR"},
389 {AST_CC_CCNL, "CCNL"},
391
392static const struct {
394 const char *state_string;
396 {CC_AVAILABLE, "CC is available"},
397 {CC_CALLER_OFFERED, "CC offered to caller"},
398 {CC_CALLER_REQUESTED, "CC requested by caller"},
399 {CC_ACTIVE, "CC accepted by callee"},
400 {CC_CALLEE_READY, "Callee has become available"},
401 {CC_CALLER_BUSY, "Callee was ready, but caller is now unavailable"},
402 {CC_RECALLING, "Caller is attempting to recall"},
403 {CC_COMPLETE, "Recall complete"},
404 {CC_FAILED, "CC has failed"},
406
407static const char *cc_state_to_string(enum cc_state state)
408{
409 return cc_state_to_string_map[state].state_string;
410}
411
413{
414 return cc_service_to_string_map[service].service_string;
415}
416
417static int cc_core_instance_hash_fn(const void *obj, const int flags)
418{
419 const struct cc_core_instance *core_instance = obj;
420 return core_instance->core_id;
421}
422
423static int cc_core_instance_cmp_fn(void *obj, void *arg, int flags)
424{
425 struct cc_core_instance *core_instance1 = obj;
426 struct cc_core_instance *core_instance2 = arg;
427
428 return core_instance1->core_id == core_instance2->core_id ? CMP_MATCH | CMP_STOP : 0;
429}
430
432{
433 struct cc_core_instance finder = {.core_id = core_id,};
434
435 return ao2_t_find(cc_core_instances, &finder, OBJ_POINTER, "Finding a core_instance");
436}
437
440 void *args;
441 const char *type;
442};
443
444static int cc_agent_callback_helper(void *obj, void *args, int flags)
445{
446 struct cc_core_instance *core_instance = obj;
447 struct cc_callback_helper *helper = args;
448
449 if (strcmp(core_instance->agent->callbacks->type, helper->type)) {
450 return 0;
451 }
452
453 return helper->function(core_instance->agent, helper->args, flags);
454}
455
456struct ast_cc_agent *ast_cc_agent_callback(int flags, ao2_callback_fn *function, void *args, const char * const type)
457{
458 struct cc_callback_helper helper = {.function = function, .args = args, .type = type};
459 struct cc_core_instance *core_instance;
460 if ((core_instance = ao2_t_callback(cc_core_instances, flags, cc_agent_callback_helper, &helper,
461 "Calling provided agent callback function"))) {
462 struct ast_cc_agent *agent = cc_ref(core_instance->agent, "An outside entity needs the agent");
463 cc_unref(core_instance, "agent callback done with the core_instance");
464 return agent;
465 }
466 return NULL;
467}
468
470 /* Only match agents that have not yet
471 * made a CC request
472 */
474 /* Only match agents that have made
475 * a CC request
476 */
477 MATCH_REQUEST = (1 << 1),
478};
479
480/* ao2_callbacks for cc_core_instances */
481
482/*!
483 * \internal
484 * \brief find a core instance based on its agent
485 *
486 * The match flags tell whether we wish to find core instances
487 * that have a monitor or core instances that do not. Core instances
488 * with no monitor are core instances for which a caller has not yet
489 * requested CC. Core instances with a monitor are ones for which the
490 * caller has requested CC.
491 */
492static int match_agent(void *obj, void *arg, void *data, int flags)
493{
494 struct cc_core_instance *core_instance = obj;
495 const char *name = arg;
496 unsigned long match_flags = *(unsigned long *)data;
497 int possible_match = 0;
498
500 possible_match = 1;
501 }
502
503 if ((match_flags & MATCH_REQUEST) && core_instance->current_state >= CC_CALLER_REQUESTED) {
504 possible_match = 1;
505 }
506
507 if (!possible_match) {
508 return 0;
509 }
510
511 if (!strcmp(core_instance->agent->device_name, name)) {
512 return CMP_MATCH | CMP_STOP;
513 }
514 return 0;
515}
516
518 int count;
520};
521
522/*!
523 * \internal
524 * \brief Count the number of agents a specific interface is using
525 *
526 * We're only concerned with the number of agents that have requested
527 * CC, so we restrict our search to core instances which have a non-NULL
528 * monitor pointer
529 */
530static int count_agents_cb(void *obj, void *arg, void *data, int flags)
531{
532 struct cc_core_instance *core_instance = obj;
533 const char *name = arg;
534 struct count_agents_cb_data *cb_data = data;
535
536 if (cb_data->core_id_exception == core_instance->core_id) {
537 ast_log_dynamic_level(cc_logger_level, "Found agent with core_id %d but not counting it toward total\n", core_instance->core_id);
538 return 0;
539 }
540
541 if (core_instance->current_state >= CC_CALLER_REQUESTED && !strcmp(core_instance->agent->device_name, name)) {
542 cb_data->count++;
543 }
544 return 0;
545}
546
547/* default values mapping from cc_state to ast_dev_state */
548
549#define CC_AVAILABLE_DEVSTATE_DEFAULT AST_DEVICE_NOT_INUSE
550#define CC_CALLER_OFFERED_DEVSTATE_DEFAULT AST_DEVICE_NOT_INUSE
551#define CC_CALLER_REQUESTED_DEVSTATE_DEFAULT AST_DEVICE_NOT_INUSE
552#define CC_ACTIVE_DEVSTATE_DEFAULT AST_DEVICE_INUSE
553#define CC_CALLEE_READY_DEVSTATE_DEFAULT AST_DEVICE_RINGING
554#define CC_CALLER_BUSY_DEVSTATE_DEFAULT AST_DEVICE_ONHOLD
555#define CC_RECALLING_DEVSTATE_DEFAULT AST_DEVICE_RINGING
556#define CC_COMPLETE_DEVSTATE_DEFAULT AST_DEVICE_NOT_INUSE
557#define CC_FAILED_DEVSTATE_DEFAULT AST_DEVICE_NOT_INUSE
558
559/*!
560 * \internal
561 * \brief initialization of defaults for CC_STATE to DEVICE_STATE map
562 */
573};
574
575/*!
576 * \internal
577 * \brief lookup the ast_device_state mapped to cc_state
578 *
579 * \param state
580 *
581 * \return the correponding DEVICE STATE from the cc_state_to_devstate_map
582 * when passed an internal state.
583 */
585{
587}
588
589/*!
590 * \internal
591 * \brief Callback for devicestate providers
592 *
593 * \details
594 * Initialize with ast_devstate_prov_add() and returns the corresponding
595 * DEVICE STATE based on the current CC_STATE state machine if the requested
596 * device is found and is a generic device. Returns the equivalent of
597 * CC_FAILED, which defaults to NOT_INUSE, if no device is found. NOT_INUSE would
598 * indicate that there is no presence of any pending call back.
599 */
600static enum ast_device_state ccss_device_state(const char *device_name)
601{
602 struct cc_core_instance *core_instance;
603 unsigned long match_flags;
604 enum ast_device_state cc_current_state;
605
608 (char *) device_name, &match_flags,
609 "Find Core Instance for ccss_device_state reqeust.");
610 if (!core_instance) {
612 "Couldn't find a core instance for caller %s\n", device_name);
614 }
615
617 "Core %d: Found core_instance for caller %s in state %s\n",
618 core_instance->core_id, device_name, cc_state_to_string(core_instance->current_state));
619
620 if (strcmp(core_instance->agent->callbacks->type, "generic")) {
622 "Core %d: Device State is only for generic agent types.\n",
623 core_instance->core_id);
624 cc_unref(core_instance, "Unref core_instance since ccss_device_state was called with native agent");
626 }
627 cc_current_state = cc_state_to_devstate(core_instance->current_state);
628 cc_unref(core_instance, "Unref core_instance done with ccss_device_state");
629 return cc_current_state;
630}
631
632/*!
633 * \internal
634 * \brief Notify Device State Changes from CC STATE MACHINE
635 *
636 * \details
637 * Any time a state is changed, we call this function to notify the DEVICE STATE
638 * subsystem of the change so that subscribed phones to any corresponding hints that
639 * are using that state are updated.
640 */
641static void ccss_notify_device_state_change(const char *device, enum cc_state state)
642{
643 enum ast_device_state devstate;
644
645 devstate = cc_state_to_devstate(state);
646
648 "Notification of CCSS state change to '%s', device state '%s' for device '%s'\n",
649 cc_state_to_string(state), ast_devstate2str(devstate), device);
650
651 ast_devstate_changed(devstate, AST_DEVSTATE_CACHABLE, "ccss:%s", device);
652}
653
654#define CC_OFFER_TIMER_DEFAULT 20 /* Seconds */
655#define CCNR_AVAILABLE_TIMER_DEFAULT 7200 /* Seconds */
656#define CCBS_AVAILABLE_TIMER_DEFAULT 4800 /* Seconds */
657#define CC_RECALL_TIMER_DEFAULT 20 /* Seconds */
658#define CC_MAX_AGENTS_DEFAULT 5
659#define CC_MAX_MONITORS_DEFAULT 5
660#define GLOBAL_CC_MAX_REQUESTS_DEFAULT 20
661
664 .cc_monitor_policy = AST_CC_MONITOR_NEVER,
665 .cc_offer_timer = CC_OFFER_TIMER_DEFAULT,
666 .ccnr_available_timer = CCNR_AVAILABLE_TIMER_DEFAULT,
667 .ccbs_available_timer = CCBS_AVAILABLE_TIMER_DEFAULT,
668 .cc_recall_timer = CC_RECALL_TIMER_DEFAULT,
669 .cc_max_agents = CC_MAX_AGENTS_DEFAULT,
670 .cc_max_monitors = CC_MAX_MONITORS_DEFAULT,
671 .cc_callback_sub = "",
672 .cc_agent_dialstring = "",
673};
674
676{
677 *params = cc_default_params;
678}
679
680struct ast_cc_config_params *__ast_cc_config_params_init(const char *file, int line, const char *function)
681{
682 struct ast_cc_config_params *params = __ast_malloc(sizeof(*params), file, line, function);
683
684 if (!params) {
685 return NULL;
686 }
687
689 return params;
690}
691
693{
694 ast_free(params);
695}
696
697static enum ast_cc_agent_policies str_to_agent_policy(const char * const value)
698{
699 if (!strcasecmp(value, "never")) {
700 return AST_CC_AGENT_NEVER;
701 } else if (!strcasecmp(value, "native")) {
702 return AST_CC_AGENT_NATIVE;
703 } else if (!strcasecmp(value, "generic")) {
705 } else {
706 ast_log(LOG_WARNING, "%s is an invalid value for cc_agent_policy. Switching to 'never'\n", value);
707 return AST_CC_AGENT_NEVER;
708 }
709}
710
712{
713 if (!strcasecmp(value, "never")) {
715 } else if (!strcasecmp(value, "native")) {
717 } else if (!strcasecmp(value, "generic")) {
719 } else if (!strcasecmp(value, "always")) {
721 } else {
722 ast_log(LOG_WARNING, "%s is an invalid value for cc_monitor_policy. Switching to 'never'\n", value);
724 }
725}
726
727static const char *agent_policy_to_str(enum ast_cc_agent_policies policy)
728{
729 switch (policy) {
731 return "never";
733 return "native";
735 return "generic";
736 default:
737 /* This should never happen... */
738 return "";
739 }
740}
741
742static const char *monitor_policy_to_str(enum ast_cc_monitor_policies policy)
743{
744 switch (policy) {
746 return "never";
748 return "native";
750 return "generic";
752 return "always";
753 default:
754 /* This should never happen... */
755 return "";
756 }
757}
758int ast_cc_get_param(struct ast_cc_config_params *params, const char * const name,
759 char *buf, size_t buf_len)
760{
761 const char *value = NULL;
762
763 if (!strcasecmp(name, "cc_callback_sub")) {
765 } else if (!strcasecmp(name, "cc_agent_policy")) {
767 } else if (!strcasecmp(name, "cc_monitor_policy")) {
769 } else if (!strcasecmp(name, "cc_agent_dialstring")) {
771 }
772 if (value) {
773 ast_copy_string(buf, value, buf_len);
774 return 0;
775 }
776
777 /* The rest of these are all ints of some sort and require some
778 * snprintf-itude
779 */
780
781 if (!strcasecmp(name, "cc_offer_timer")) {
782 snprintf(buf, buf_len, "%u", ast_get_cc_offer_timer(params));
783 } else if (!strcasecmp(name, "ccnr_available_timer")) {
784 snprintf(buf, buf_len, "%u", ast_get_ccnr_available_timer(params));
785 } else if (!strcasecmp(name, "ccbs_available_timer")) {
786 snprintf(buf, buf_len, "%u", ast_get_ccbs_available_timer(params));
787 } else if (!strcasecmp(name, "cc_max_agents")) {
788 snprintf(buf, buf_len, "%u", ast_get_cc_max_agents(params));
789 } else if (!strcasecmp(name, "cc_max_monitors")) {
790 snprintf(buf, buf_len, "%u", ast_get_cc_max_monitors(params));
791 } else if (!strcasecmp(name, "cc_recall_timer")) {
792 snprintf(buf, buf_len, "%u", ast_get_cc_recall_timer(params));
793 } else {
794 ast_log(LOG_WARNING, "%s is not a valid CC parameter. Ignoring.\n", name);
795 return -1;
796 }
797
798 return 0;
799}
800
801int ast_cc_set_param(struct ast_cc_config_params *params, const char * const name,
802 const char * const value)
803{
804 unsigned int value_as_uint;
805 if (!strcasecmp(name, "cc_agent_policy")) {
807 } else if (!strcasecmp(name, "cc_monitor_policy")) {
809 } else if (!strcasecmp(name, "cc_agent_dialstring")) {
811 } else if (!strcasecmp(name, "cc_callback_sub")) {
813 return 0;
814 }
815
816 if (sscanf(value, "%30u", &value_as_uint) != 1) {
817 return -1;
818 }
819
820 if (!strcasecmp(name, "cc_offer_timer")) {
821 ast_set_cc_offer_timer(params, value_as_uint);
822 } else if (!strcasecmp(name, "ccnr_available_timer")) {
823 ast_set_ccnr_available_timer(params, value_as_uint);
824 } else if (!strcasecmp(name, "ccbs_available_timer")) {
825 ast_set_ccbs_available_timer(params, value_as_uint);
826 } else if (!strcasecmp(name, "cc_max_agents")) {
827 ast_set_cc_max_agents(params, value_as_uint);
828 } else if (!strcasecmp(name, "cc_max_monitors")) {
829 ast_set_cc_max_monitors(params, value_as_uint);
830 } else if (!strcasecmp(name, "cc_recall_timer")) {
831 ast_set_cc_recall_timer(params, value_as_uint);
832 } else {
833 ast_log(LOG_WARNING, "%s is not a valid CC parameter. Ignoring.\n", name);
834 return -1;
835 }
836
837 return 0;
838}
839
840int ast_cc_is_config_param(const char * const name)
841{
842 return (!strcasecmp(name, "cc_agent_policy") ||
843 !strcasecmp(name, "cc_monitor_policy") ||
844 !strcasecmp(name, "cc_offer_timer") ||
845 !strcasecmp(name, "ccnr_available_timer") ||
846 !strcasecmp(name, "ccbs_available_timer") ||
847 !strcasecmp(name, "cc_max_agents") ||
848 !strcasecmp(name, "cc_max_monitors") ||
849 !strcasecmp(name, "cc_callback_sub") ||
850 !strcasecmp(name, "cc_agent_dialstring") ||
851 !strcasecmp(name, "cc_recall_timer"));
852}
853
855{
856 *dest = *src;
857}
858
860{
861 return config->cc_agent_policy;
862}
863
865{
866 /* Screw C and its weak type checking for making me have to do this
867 * validation at runtime.
868 */
869 if (value < AST_CC_AGENT_NEVER || value > AST_CC_AGENT_GENERIC) {
870 return -1;
871 }
872 config->cc_agent_policy = value;
873 return 0;
874}
875
877{
878 return config->cc_monitor_policy;
879}
880
882{
883 /* Screw C and its weak type checking for making me have to do this
884 * validation at runtime.
885 */
886 if (value < AST_CC_MONITOR_NEVER || value > AST_CC_MONITOR_ALWAYS) {
887 return -1;
888 }
889 config->cc_monitor_policy = value;
890 return 0;
891}
892
894{
895 return config->cc_offer_timer;
896}
897
899{
900 /* 0 is an unreasonable value for any timer. Stick with the default */
901 if (value == 0) {
902 ast_log(LOG_WARNING, "0 is an invalid value for cc_offer_timer. Retaining value as %u\n", config->cc_offer_timer);
903 return;
904 }
905 config->cc_offer_timer = value;
906}
907
909{
910 return config->ccnr_available_timer;
911}
912
914{
915 /* 0 is an unreasonable value for any timer. Stick with the default */
916 if (value == 0) {
917 ast_log(LOG_WARNING, "0 is an invalid value for ccnr_available_timer. Retaining value as %u\n", config->ccnr_available_timer);
918 return;
919 }
920 config->ccnr_available_timer = value;
921}
922
924{
925 return config->cc_recall_timer;
926}
927
929{
930 /* 0 is an unreasonable value for any timer. Stick with the default */
931 if (value == 0) {
932 ast_log(LOG_WARNING, "0 is an invalid value for ccnr_available_timer. Retaining value as %u\n", config->cc_recall_timer);
933 return;
934 }
935 config->cc_recall_timer = value;
936}
937
939{
940 return config->ccbs_available_timer;
941}
942
944{
945 /* 0 is an unreasonable value for any timer. Stick with the default */
946 if (value == 0) {
947 ast_log(LOG_WARNING, "0 is an invalid value for ccbs_available_timer. Retaining value as %u\n", config->ccbs_available_timer);
948 return;
949 }
950 config->ccbs_available_timer = value;
951}
952
954{
955 return config->cc_agent_dialstring;
956}
957
959{
960 if (ast_strlen_zero(value)) {
961 config->cc_agent_dialstring[0] = '\0';
962 } else {
963 ast_copy_string(config->cc_agent_dialstring, value, sizeof(config->cc_agent_dialstring));
964 }
965}
966
968{
969 return config->cc_max_agents;
970}
971
973{
974 config->cc_max_agents = value;
975}
976
978{
979 return config->cc_max_monitors;
980}
981
983{
984 config->cc_max_monitors = value;
985}
986
988{
989 return config->cc_callback_sub;
990}
991
993{
994 if (ast_strlen_zero(value)) {
995 config->cc_callback_sub[0] = '\0';
996 } else {
997 ast_copy_string(config->cc_callback_sub, value, sizeof(config->cc_callback_sub));
998 }
999}
1000
1001static int cc_publish(struct stasis_message_type *message_type, int core_id, struct ast_json *extras)
1002{
1003 struct ast_json *blob;
1004 struct ast_json_payload *payload;
1005 struct stasis_message *message;
1006
1007 if (!message_type) {
1008 return -1;
1009 }
1010
1011 blob = ast_json_pack("{s: i}",
1012 "core_id", core_id);
1013 if (!blob) {
1014 return -1;
1015 }
1016
1017 if (extras) {
1018 ast_json_object_update(blob, extras);
1019 }
1020
1021 payload = ast_json_payload_create(blob);
1022 ast_json_unref(blob);
1023
1024 if (!payload) {
1025 return -1;
1026 }
1027
1028 message = stasis_message_create(message_type, payload);
1029 ao2_ref(payload, -1);
1030
1031 if (!message) {
1032 return -1;
1033 }
1034
1036 ao2_ref(message, -1);
1037
1038 return 0;
1039}
1040
1041static void cc_publish_available(int core_id, const char *callee, const char *service)
1042{
1043 struct ast_json *extras;
1044
1045 extras = ast_json_pack("{s: s, s: s}",
1046 "callee", callee,
1047 "service", service);
1048
1049 cc_publish(ast_cc_available_type(), core_id, extras);
1050 ast_json_unref(extras);
1051}
1052
1053static void cc_publish_offertimerstart(int core_id, const char *caller, unsigned int expires)
1054{
1055 struct ast_json *extras;
1056
1057 extras = ast_json_pack("{s: s, s: I}",
1058 "caller", caller,
1059 "expires", (ast_json_int_t)expires);
1060
1061 cc_publish(ast_cc_offertimerstart_type(), core_id, extras);
1062 ast_json_unref(extras);
1063}
1064
1065static void cc_publish_requested(int core_id, const char *caller, const char *callee)
1066{
1067 struct ast_json *extras;
1068
1069 extras = ast_json_pack("{s: s, s: s}",
1070 "caller", caller,
1071 "callee", callee);
1072
1073 cc_publish(ast_cc_requested_type(), core_id, extras);
1074 ast_json_unref(extras);
1075}
1076
1077static void cc_publish_requestacknowledged(int core_id, const char *caller)
1078{
1079 struct ast_json *extras;
1080
1081 extras = ast_json_pack("{s: s}",
1082 "caller", caller);
1083
1084 cc_publish(ast_cc_requestacknowledged_type(), core_id, extras);
1085 ast_json_unref(extras);
1086}
1087
1088static void cc_publish_callerstopmonitoring(int core_id, const char *caller)
1089{
1090 struct ast_json *extras;
1091
1092 extras = ast_json_pack("{s: s}",
1093 "caller", caller);
1094
1095 cc_publish(ast_cc_callerstopmonitoring_type(), core_id, extras);
1096 ast_json_unref(extras);
1097}
1098
1099static void cc_publish_callerstartmonitoring(int core_id, const char *caller)
1100{
1101 struct ast_json *extras;
1102
1103 extras = ast_json_pack("{s: s}",
1104 "caller", caller);
1105
1107 ast_json_unref(extras);
1108}
1109
1110static void cc_publish_callerrecalling(int core_id, const char *caller)
1111{
1112 struct ast_json *extras;
1113
1114 extras = ast_json_pack("{s: s}",
1115 "caller", caller);
1116
1117 cc_publish(ast_cc_callerrecalling_type(), core_id, extras);
1118 ast_json_unref(extras);
1119}
1120
1121static void cc_publish_recallcomplete(int core_id, const char *caller)
1122{
1123 struct ast_json *extras;
1124
1125 extras = ast_json_pack("{s: s}",
1126 "caller", caller);
1127
1128 cc_publish(ast_cc_recallcomplete_type(), core_id, extras);
1129 ast_json_unref(extras);
1130}
1131
1132static void cc_publish_failure(int core_id, const char *caller, const char *reason)
1133{
1134 struct ast_json *extras;
1135
1136 extras = ast_json_pack("{s: s, s: s}",
1137 "caller", caller,
1138 "reason", reason);
1139
1140 cc_publish(ast_cc_failure_type(), core_id, extras);
1141 ast_json_unref(extras);
1142}
1143
1144static void cc_publish_monitorfailed(int core_id, const char *callee)
1145{
1146 struct ast_json *extras;
1147
1148 extras = ast_json_pack("{s: s}",
1149 "callee", callee);
1150
1151 cc_publish(ast_cc_monitorfailed_type(), core_id, extras);
1152 ast_json_unref(extras);
1153}
1154
1158};
1159
1161
1163{
1164 struct cc_monitor_backend *backend = ast_calloc(1, sizeof(*backend));
1165
1166 if (!backend) {
1167 return -1;
1168 }
1169
1170 backend->callbacks = callbacks;
1171
1175 return 0;
1176}
1177
1178static const struct ast_cc_monitor_callbacks *find_monitor_callbacks(const char * const type)
1179{
1180 struct cc_monitor_backend *backend;
1181 const struct ast_cc_monitor_callbacks *callbacks = NULL;
1182
1184 AST_RWLIST_TRAVERSE(&cc_monitor_backends, backend, next) {
1185 if (!strcmp(backend->callbacks->type, type)) {
1186 ast_log_dynamic_level(cc_logger_level, "Returning monitor backend %s\n", backend->callbacks->type);
1187 callbacks = backend->callbacks;
1188 break;
1189 }
1190 }
1192 return callbacks;
1193}
1194
1196{
1197 struct cc_monitor_backend *backend;
1200 if (backend->callbacks == callbacks) {
1202 ast_free(backend);
1203 break;
1204 }
1205 }
1208}
1209
1213};
1214
1216
1218{
1219 struct cc_agent_backend *backend = ast_calloc(1, sizeof(*backend));
1220
1221 if (!backend) {
1222 return -1;
1223 }
1224
1225 backend->callbacks = callbacks;
1229 return 0;
1230}
1231
1233{
1234 struct cc_agent_backend *backend;
1237 if (backend->callbacks == callbacks) {
1239 ast_free(backend);
1240 break;
1241 }
1242 }
1245}
1246
1248{
1249 struct cc_agent_backend *backend;
1250 const struct ast_cc_agent_callbacks *callbacks = NULL;
1251 struct ast_cc_config_params *cc_params;
1252 char type[32];
1253
1254 cc_params = ast_channel_get_cc_config_params(chan);
1255 if (!cc_params) {
1256 return NULL;
1257 }
1258 switch (ast_get_cc_agent_policy(cc_params)) {
1260 ast_copy_string(type, "generic", sizeof(type));
1261 break;
1263 ast_channel_get_cc_agent_type(chan, type, sizeof(type));
1264 break;
1265 default:
1266 ast_log_dynamic_level(cc_logger_level, "Not returning agent callbacks since this channel is configured not to have a CC agent\n");
1267 return NULL;
1268 }
1269
1271 AST_RWLIST_TRAVERSE(&cc_agent_backends, backend, next) {
1272 if (!strcmp(backend->callbacks->type, type)) {
1273 ast_log_dynamic_level(cc_logger_level, "Returning agent backend %s\n", backend->callbacks->type);
1274 callbacks = backend->callbacks;
1275 break;
1276 }
1277 }
1279 return callbacks;
1280}
1281
1282/*!
1283 * \internal
1284 * \brief Determine if the given device state is considered available by generic CCSS.
1285 * \since 1.8
1286 *
1287 * \param state Device state to test.
1288 *
1289 * \retval TRUE if the given device state is considered available by generic CCSS.
1290 */
1292{
1294}
1295
1296static int cc_generic_monitor_request_cc(struct ast_cc_monitor *monitor, int *available_timer_id);
1297static int cc_generic_monitor_suspend(struct ast_cc_monitor *monitor);
1298static int cc_generic_monitor_unsuspend(struct ast_cc_monitor *monitor);
1299static int cc_generic_monitor_cancel_available_timer(struct ast_cc_monitor *monitor, int *sched_id);
1300static void cc_generic_monitor_destructor(void *private_data);
1301
1303 .type = "generic",
1304 .request_cc = cc_generic_monitor_request_cc,
1305 .suspend = cc_generic_monitor_suspend,
1306 .unsuspend = cc_generic_monitor_unsuspend,
1307 .cancel_available_timer = cc_generic_monitor_cancel_available_timer,
1308 .destructor = cc_generic_monitor_destructor,
1309};
1310
1312
1318};
1319
1321 const char *device_name;
1323 /* If there are multiple instances monitoring the
1324 * same device and one should fail, we need to know
1325 * whether to signal that the device can be recalled.
1326 * The problem is that the device state is not enough
1327 * to check. If a caller has requested CCNR, then the
1328 * fact that the device is available does not indicate
1329 * that the device is ready to be recalled. Instead, as
1330 * soon as one instance of the monitor becomes available
1331 * for a recall, we mark the entire list as being fit
1332 * for recall. If a CCNR request comes in, then we will
1333 * have to mark the list as unfit for recall since this
1334 * is a clear indicator that the person at the monitored
1335 * device has gone away and is actually not fit to be
1336 * recalled
1337 */
1341};
1342
1343/*!
1344 * \brief private data for generic device monitor
1345 */
1347 /*!
1348 * We need the device name during destruction so we
1349 * can find the appropriate item to destroy.
1350 */
1351 const char *device_name;
1352 /*!
1353 * We need the core ID for similar reasons. Once we
1354 * find the appropriate item in our ao2_container, we
1355 * need to remove the appropriate cc_monitor from the
1356 * list of monitors.
1357 */
1359};
1360
1363
1364static struct generic_monitor_instance_list *find_generic_monitor_instance_list(const char * const device_name)
1365{
1366 struct generic_monitor_instance_list finder = {0};
1367 char *uppertech = ast_strdupa(device_name);
1368 ast_tech_to_upper(uppertech);
1369 finder.device_name = uppertech;
1370
1371 return ao2_t_find(generic_monitors, &finder, OBJ_POINTER, "Finding generic monitor instance list");
1372}
1373
1375{
1376 struct generic_monitor_instance_list *generic_list = obj;
1377 struct generic_monitor_instance *generic_instance;
1378
1379 generic_list->sub = stasis_unsubscribe(generic_list->sub);
1380 while ((generic_instance = AST_LIST_REMOVE_HEAD(&generic_list->list, next))) {
1381 ast_free(generic_instance);
1382 }
1383 ast_free((char *)generic_list->device_name);
1384}
1385
1386static void generic_monitor_devstate_cb(void *userdata, struct stasis_subscription *sub, struct stasis_message *msg);
1388{
1389 struct generic_monitor_instance_list *generic_list = ao2_t_alloc(sizeof(*generic_list),
1390 generic_monitor_instance_list_destructor, "allocate generic monitor instance list");
1391 char * device_name;
1392 struct stasis_topic *device_specific_topic;
1393
1394 if (!generic_list) {
1395 return NULL;
1396 }
1397
1398 if (!(device_name = ast_strdup(monitor->interface->device_name))) {
1399 cc_unref(generic_list, "Failed to strdup the monitor's device name");
1400 return NULL;
1401 }
1402 ast_tech_to_upper(device_name);
1403 generic_list->device_name = device_name;
1404
1405 device_specific_topic = ast_device_state_topic(device_name);
1406 if (!device_specific_topic) {
1407 return NULL;
1408 }
1409
1410 if (!(generic_list->sub = stasis_subscribe(device_specific_topic, generic_monitor_devstate_cb, NULL))) {
1411 cc_unref(generic_list, "Failed to subscribe to device state");
1412 return NULL;
1413 }
1416 generic_list->current_state = ast_device_state(monitor->interface->device_name);
1417 ao2_t_link(generic_monitors, generic_list, "linking new generic monitor instance list");
1418 return generic_list;
1419}
1420
1422{
1423 RAII_VAR(struct ast_device_state_message *, dev_state, data, ao2_cleanup);
1424 enum ast_device_state new_state = dev_state->state;
1425 enum ast_device_state previous_state;
1426 struct generic_monitor_instance_list *generic_list;
1427 struct generic_monitor_instance *generic_instance;
1428
1429 if (!(generic_list = find_generic_monitor_instance_list(dev_state->device))) {
1430 /* The most likely cause for this is that we destroyed the monitor in the
1431 * time between subscribing to its device state and the time this executes.
1432 * Not really a big deal.
1433 */
1434 return 0;
1435 }
1436
1437 if (generic_list->current_state == new_state) {
1438 /* The device state hasn't actually changed, so we don't really care */
1439 cc_unref(generic_list, "Kill reference of generic list in devstate taskprocessor callback");
1440 return 0;
1441 }
1442
1443 previous_state = generic_list->current_state;
1444 generic_list->current_state = new_state;
1445
1446 if (cc_generic_is_device_available(new_state) &&
1447 (previous_state == AST_DEVICE_INUSE || previous_state == AST_DEVICE_UNAVAILABLE ||
1448 previous_state == AST_DEVICE_BUSY)) {
1449 AST_LIST_TRAVERSE(&generic_list->list, generic_instance, next) {
1450 if (!generic_instance->is_suspended && generic_instance->monitoring) {
1451 generic_instance->monitoring = 0;
1452 generic_list->fit_for_recall = 1;
1453 ast_cc_monitor_callee_available(generic_instance->core_id, "Generic monitored party has become available");
1454 break;
1455 }
1456 }
1457 }
1458 cc_unref(generic_list, "Kill reference of generic list in devstate taskprocessor callback");
1459 return 0;
1460}
1461
1462static void generic_monitor_devstate_cb(void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)
1463{
1464 /* Wow, it's cool that we've picked up on a state change, but we really want
1465 * the actual work to be done in the core's taskprocessor execution thread
1466 * so that all monitor operations can be serialized. Locks?! We don't need
1467 * no steenkin' locks!
1468 */
1469 struct ast_device_state_message *dev_state;
1471 return;
1472 }
1473
1474 dev_state = stasis_message_data(msg);
1475 if (dev_state->eid) {
1476 /* ignore non-aggregate states */
1477 return;
1478 }
1479
1480 ao2_t_ref(dev_state, +1, "Bumping dev_state ref for cc_core_taskprocessor");
1482 ao2_cleanup(dev_state);
1483 return;
1484 }
1485}
1486
1488{
1489 struct ast_cc_monitor *monitor = (struct ast_cc_monitor *) data;
1490 int res;
1491 monitor->available_timer_id = -1;
1492 res = ast_cc_monitor_failed(monitor->core_id, monitor->interface->device_name, "Available timer expired for monitor");
1493 cc_unref(monitor, "Unref reference from scheduler\n");
1494 return res;
1495}
1496
1498{
1499 struct generic_monitor_instance_list *generic_list;
1500 struct generic_monitor_instance *generic_instance;
1501 struct generic_monitor_pvt *gen_mon_pvt;
1503 int when;
1504
1505 /* First things first. Native channel drivers will have their private data allocated
1506 * at the time that they tell the core that they can offer CC. Generic is quite a bit
1507 * different, and we wait until this point to allocate our private data.
1508 */
1509 if (!(gen_mon_pvt = ast_calloc(1, sizeof(*gen_mon_pvt)))) {
1510 return -1;
1511 }
1512
1513 if (!(gen_mon_pvt->device_name = ast_strdup(monitor->interface->device_name))) {
1514 ast_free(gen_mon_pvt);
1515 return -1;
1516 }
1517
1518 gen_mon_pvt->core_id = monitor->core_id;
1519
1520 monitor->private_data = gen_mon_pvt;
1521
1522 if (!(generic_list = find_generic_monitor_instance_list(monitor->interface->device_name))) {
1523 if (!(generic_list = create_new_generic_list(monitor))) {
1524 return -1;
1525 }
1526 }
1527
1528 if (!(generic_instance = ast_calloc(1, sizeof(*generic_instance)))) {
1529 /* The generic monitor destructor will take care of the appropriate
1530 * deallocations
1531 */
1532 cc_unref(generic_list, "Generic monitor instance failed to allocate");
1533 return -1;
1534 }
1535 generic_instance->core_id = monitor->core_id;
1536 generic_instance->monitoring = 1;
1537 AST_LIST_INSERT_TAIL(&generic_list->list, generic_instance, next);
1540
1541 *available_timer_id = ast_sched_add(cc_sched_context, when * 1000,
1542 ast_cc_available_timer_expire, cc_ref(monitor, "Give the scheduler a monitor reference"));
1543 if (*available_timer_id == -1) {
1544 cc_unref(monitor, "Failed to schedule available timer. (monitor)");
1545 cc_unref(generic_list, "Failed to schedule available timer. (generic_list)");
1546 return -1;
1547 }
1548 /* If the new instance was created as CCNR, then that means this device is not currently
1549 * fit for recall even if it previously was.
1550 */
1551 if (service == AST_CC_CCNR || service == AST_CC_CCNL) {
1552 generic_list->fit_for_recall = 0;
1553 }
1554 ast_cc_monitor_request_acked(monitor->core_id, "Generic monitor for %s subscribed to device state.",
1555 monitor->interface->device_name);
1556 cc_unref(generic_list, "Finished with monitor instance reference in request cc callback");
1557 return 0;
1558}
1559
1561{
1562 struct generic_monitor_instance_list *generic_list;
1563 struct generic_monitor_instance *generic_instance;
1565
1566 if (!(generic_list = find_generic_monitor_instance_list(monitor->interface->device_name))) {
1567 return -1;
1568 }
1569
1570 /* First we need to mark this particular monitor as being suspended. */
1571 AST_LIST_TRAVERSE(&generic_list->list, generic_instance, next) {
1572 if (generic_instance->core_id == monitor->core_id) {
1573 generic_instance->is_suspended = 1;
1574 break;
1575 }
1576 }
1577
1578 /* If the device being suspended is currently in use, then we don't need to
1579 * take any further actions
1580 */
1582 cc_unref(generic_list, "Device is in use. Nothing to do. Unref generic list.");
1583 return 0;
1584 }
1585
1586 /* If the device is not in use, though, then it may be possible to report the
1587 * device's availability using a different monitor which is monitoring the
1588 * same device
1589 */
1590
1591 AST_LIST_TRAVERSE(&generic_list->list, generic_instance, next) {
1592 if (!generic_instance->is_suspended) {
1593 ast_cc_monitor_callee_available(generic_instance->core_id, "Generic monitored party has become available");
1594 break;
1595 }
1596 }
1597 cc_unref(generic_list, "Done with generic list in suspend callback");
1598 return 0;
1599}
1600
1602{
1603 struct generic_monitor_instance *generic_instance;
1606
1607 if (!generic_list) {
1608 return -1;
1609 }
1610 /* If the device is currently available, we can immediately announce
1611 * its availability
1612 */
1614 ast_cc_monitor_callee_available(monitor->core_id, "Generic monitored party has become available");
1615 }
1616
1617 /* In addition, we need to mark this generic_monitor_instance as not being suspended anymore */
1618 AST_LIST_TRAVERSE(&generic_list->list, generic_instance, next) {
1619 if (generic_instance->core_id == monitor->core_id) {
1620 generic_instance->is_suspended = 0;
1621 generic_instance->monitoring = 1;
1622 break;
1623 }
1624 }
1625 cc_unref(generic_list, "Done with generic list in cc_generic_monitor_unsuspend");
1626 return 0;
1627}
1628
1630{
1632
1633 if (*sched_id == -1) {
1634 return 0;
1635 }
1636
1637 ast_log_dynamic_level(cc_logger_level, "Core %d: Canceling generic monitor available timer for monitor %s\n",
1638 monitor->core_id, monitor->interface->device_name);
1640 cc_unref(monitor, "Remove scheduler's reference to the monitor");
1641 }
1642 *sched_id = -1;
1643 return 0;
1644}
1645
1646static void cc_generic_monitor_destructor(void *private_data)
1647{
1648 struct generic_monitor_pvt *gen_mon_pvt = private_data;
1649 struct generic_monitor_instance_list *generic_list;
1650 struct generic_monitor_instance *generic_instance;
1651
1652 if (!private_data) {
1653 /* If the private data is NULL, that means that the monitor hasn't even
1654 * been created yet, but that the destructor was called. While this sort
1655 * of behavior is useful for native monitors, with a generic one, there is
1656 * nothing in particular to do.
1657 */
1658 return;
1659 }
1660
1661 ast_log_dynamic_level(cc_logger_level, "Core %d: Destroying generic monitor %s\n",
1662 gen_mon_pvt->core_id, gen_mon_pvt->device_name);
1663
1664 if (!(generic_list = find_generic_monitor_instance_list(gen_mon_pvt->device_name))) {
1665 /* If there's no generic list, that means that the monitor is being destroyed
1666 * before we actually got to request CC. Not a biggie. Same in the situation
1667 * below if the list traversal should complete without finding an entry.
1668 */
1669 ast_free((char *)gen_mon_pvt->device_name);
1670 ast_free(gen_mon_pvt);
1671 return;
1672 }
1673
1674 AST_LIST_TRAVERSE_SAFE_BEGIN(&generic_list->list, generic_instance, next) {
1675 if (generic_instance->core_id == gen_mon_pvt->core_id) {
1677 ast_free(generic_instance);
1678 break;
1679 }
1680 }
1682
1683 if (AST_LIST_EMPTY(&generic_list->list)) {
1684 /* No more monitors with this device name exist. Time to unlink this
1685 * list from the container
1686 */
1687 ao2_t_unlink(generic_monitors, generic_list, "Generic list is empty. Unlink it from the container");
1688 } else {
1689 /* There are still instances for this particular device. The situation
1690 * may be that we were attempting a CC recall and a failure occurred, perhaps
1691 * on the agent side. If a failure happens here and the device being monitored
1692 * is available, then we need to signal on the first unsuspended instance that
1693 * the device is available for recall.
1694 */
1695
1696 /* First things first. We don't even want to consider this action if
1697 * the device in question isn't available right now.
1698 */
1699 if (generic_list->fit_for_recall
1701 AST_LIST_TRAVERSE(&generic_list->list, generic_instance, next) {
1702 if (!generic_instance->is_suspended && generic_instance->monitoring) {
1703 ast_cc_monitor_callee_available(generic_instance->core_id, "Signaling generic monitor "
1704 "availability due to other instance's failure.");
1705 break;
1706 }
1707 }
1708 }
1709 }
1710 cc_unref(generic_list, "Done with generic list in generic monitor destructor");
1711 ast_free((char *)gen_mon_pvt->device_name);
1712 ast_free(gen_mon_pvt);
1713}
1714
1715static void cc_interface_destroy(void *data)
1716{
1717 struct ast_cc_interface *interface = data;
1718 ast_log_dynamic_level(cc_logger_level, "Destroying cc interface %s\n", interface->device_name);
1719 ast_cc_config_params_destroy(interface->config_params);
1720}
1721
1722/*!
1723 * \brief Data regarding an extension monitor's child's dialstrings
1724 *
1725 * \details
1726 * In developing CCSS, we had most aspects of its operation finished,
1727 * but there was one looming problem that we had failed to get right.
1728 * In our design document, we stated that when a CC recall occurs, all
1729 * endpoints that had been dialed originally would be called back.
1730 * Unfortunately, our implementation only allowed for devices which had
1731 * active monitors to inhabit the CC_INTERFACES channel variable, thus
1732 * making the automated recall only call monitored devices.
1733 *
1734 * Devices that were not CC-capable, or devices which failed CC at some
1735 * point during the process would not make it into the CC_INTERFACES
1736 * channel variable. This struct is meant as a remedy for the problem.
1737 */
1739 /*!
1740 * \brief the original dialstring used to call a particular device
1741 *
1742 * \details
1743 * When someone dials a particular endpoint, the dialstring used in
1744 * the dialplan is copied into this buffer. What's important here is
1745 * that this is the ORIGINAL dialstring, not the dialstring saved on
1746 * a device monitor. The dialstring on a device monitor is what should
1747 * be used when recalling that device. The two dialstrings may not be
1748 * the same.
1749 *
1750 * By keeping a copy of the original dialstring used, we can fall back
1751 * to using it if the device either does not ever offer CC or if the
1752 * device at some point fails for some reason, such as a timer expiration.
1753 */
1755 /*!
1756 * \brief The name of the device being dialed
1757 *
1758 * \details
1759 * This serves mainly as a key when searching for a particular dialstring.
1760 * For instance, let's say that we have called device SIP/400\@somepeer. This
1761 * device offers call completion, but then due to some unforeseen circumstance,
1762 * this device backs out and makes CC unavailable. When that happens, we need
1763 * to find the dialstring that corresponds to that device, and we use the
1764 * stored device name as a way to find it.
1765 *
1766 * \note There is one particular case where the device name stored here
1767 * will be empty. This is the case where we fail to request a channel, but we
1768 * still can make use of generic call completion. In such a case, since we never
1769 * were able to request the channel, we can't find what its device name is. In
1770 * this case, however, it is not important because the dialstring is guaranteed
1771 * to be the same both here and in the device monitor.
1772 */
1774 /*!
1775 * \brief Is this structure valid for use in CC_INTERFACES?
1776 *
1777 * \details
1778 * When this structure is first created, all information stored here is planned
1779 * to be used, so we set the is_valid flag. However, if a device offers call
1780 * completion, it will potentially have its own dialstring to use for the recall,
1781 * so we find this structure and clear the is_valid flag. By clearing the is_valid
1782 * flag, we won't try to populate the CC_INTERFACES variable with the dialstring
1783 * stored in this struct. Now, if later, the device which had offered CC should fail,
1784 * perhaps due to a timer expiration, then we need to re-set the is_valid flag. This
1785 * way, we still will end up placing a call to the device again, and the dialstring
1786 * used will be the same as was originally used.
1787 */
1790};
1791
1792/*!
1793 * \brief Private data for an extension monitor
1794 */
1797};
1798
1799static void cc_extension_monitor_destructor(void *private_data)
1800{
1801 struct extension_monitor_pvt *extension_pvt = private_data;
1802 struct extension_child_dialstring *child_dialstring;
1803
1804 /* This shouldn't be possible, but I'm paranoid */
1805 if (!extension_pvt) {
1806 return;
1807 }
1808
1809 while ((child_dialstring = AST_LIST_REMOVE_HEAD(&extension_pvt->child_dialstrings, next))) {
1810 ast_free(child_dialstring);
1811 }
1812 ast_free(extension_pvt);
1813}
1814
1815static void cc_monitor_destroy(void *data)
1816{
1817 struct ast_cc_monitor *monitor = data;
1818 /* During the monitor creation process, it is possible for this
1819 * function to be called prior to when callbacks are assigned
1820 * to the monitor. Also, extension monitors do not have callbacks
1821 * assigned to them, so we wouldn't want to segfault when we try
1822 * to destroy one of them.
1823 */
1824 ast_log_dynamic_level(cc_logger_level, "Core %d: Calling destructor for monitor %s\n",
1825 monitor->core_id, monitor->interface->device_name);
1828 }
1829 if (monitor->callbacks) {
1830 monitor->callbacks->destructor(monitor->private_data);
1831 }
1832 cc_unref(monitor->interface, "Unreffing tree's reference to interface");
1833 ast_free(monitor->dialstring);
1834}
1835
1836static void cc_interface_tree_destroy(void *data)
1837{
1838 struct cc_monitor_tree *cc_interface_tree = data;
1839 struct ast_cc_monitor *monitor;
1840 while ((monitor = AST_LIST_REMOVE_HEAD(cc_interface_tree, next))) {
1841 if (monitor->callbacks) {
1842 monitor->callbacks->cancel_available_timer(monitor, &monitor->available_timer_id);
1843 }
1844 cc_unref(monitor, "Destroying all monitors");
1845 }
1846 AST_LIST_HEAD_DESTROY(cc_interface_tree);
1847}
1848
1849/*!
1850 * This counter is used for assigning unique ids
1851 * to CC-enabled dialed interfaces.
1852 */
1854
1855/*!
1856 * \internal
1857 * \brief data stored in CC datastore
1858 *
1859 * The datastore creates a list of interfaces that were
1860 * dialed, including both extensions and devices. In addition
1861 * to the intrinsic data of the tree, some extra information
1862 * is needed for use by app_dial.
1863 */
1865 /*!
1866 * This value serves a dual-purpose. When dial starts, if the
1867 * dialed_cc_interfaces datastore currently exists on the calling
1868 * channel, then the dial_parent_id will serve as a means of
1869 * letting the new extension cc_monitor we create know
1870 * who his parent is. This value will be the extension
1871 * cc_monitor that dialed the local channel that resulted
1872 * in the new Dial app being called.
1873 *
1874 * In addition, once an extension cc_monitor is created,
1875 * the dial_parent_id will be changed to the id of that newly
1876 * created interface. This way, device interfaces created from
1877 * receiving AST_CONTROL_CC frames can use this field to determine
1878 * who their parent extension interface should be.
1879 */
1880 unsigned int dial_parent_id;
1881 /*!
1882 * Identifier for the potential CC request that may be made
1883 * based on this call. Even though an instance of the core may
1884 * not be made (since the caller may not request CC), we allocate
1885 * a new core_id at the beginning of the call so that recipient
1886 * channel drivers can have the information handy just in case
1887 * the caller does end up requesting CC.
1888 */
1890 /*!
1891 * When a new Dial application is started, and the datastore
1892 * already exists on the channel, we can determine if we
1893 * should be adding any new interface information to tree.
1894 */
1896 /*!
1897 * When it comes time to offer CC to the caller, we only want to offer
1898 * it to the original incoming channel. For nested Dials and outbound
1899 * channels, it is incorrect to attempt such a thing. This flag indicates
1900 * if the channel to which this datastore is attached may be legally
1901 * offered CC when the call is finished.
1902 */
1904 /*!
1905 * Reference-counted "tree" of interfaces.
1906 */
1908};
1909
1910/*!
1911 * \internal
1912 * \brief Destructor function for cc_interfaces datastore
1913 *
1914 * This function will free the actual datastore and drop
1915 * the refcount for the monitor tree by one. In cases
1916 * where CC can actually be used, this unref will not
1917 * result in the destruction of the monitor tree, because
1918 * the CC core will still have a reference.
1919 *
1920 * \param data The dialed_cc_interfaces struct to destroy
1921 */
1922static void dialed_cc_interfaces_destroy(void *data)
1923{
1924 struct dialed_cc_interfaces *cc_interfaces = data;
1925 cc_unref(cc_interfaces->interface_tree, "Unref dial's ref to monitor tree");
1926 ast_free(cc_interfaces);
1927}
1928
1929/*!
1930 * \internal
1931 * \brief Duplicate callback for cc_interfaces datastore
1932 *
1933 * Integers are copied by value, but the monitor tree
1934 * is done via a shallow copy and a bump of the refcount.
1935 * This way, sub-Dials will be appending interfaces onto
1936 * the same list as this call to Dial.
1937 *
1938 * \param data The old dialed_cc_interfaces we want to copy
1939 * \retval NULL Could not allocate memory for new dialed_cc_interfaces
1940 * \retval non-NULL The new copy of the dialed_cc_interfaces
1941 */
1942static void *dialed_cc_interfaces_duplicate(void *data)
1943{
1944 struct dialed_cc_interfaces *old_cc_interfaces = data;
1945 struct dialed_cc_interfaces *new_cc_interfaces = ast_calloc(1, sizeof(*new_cc_interfaces));
1946 if (!new_cc_interfaces) {
1947 return NULL;
1948 }
1949 new_cc_interfaces->ignore = old_cc_interfaces->ignore;
1950 new_cc_interfaces->dial_parent_id = old_cc_interfaces->dial_parent_id;
1951 new_cc_interfaces->is_original_caller = 0;
1952 cc_ref(old_cc_interfaces->interface_tree, "New ref due to duplication of monitor tree");
1953 new_cc_interfaces->core_id = old_cc_interfaces->core_id;
1954 new_cc_interfaces->interface_tree = old_cc_interfaces->interface_tree;
1955 return new_cc_interfaces;
1956}
1957
1958/*!
1959 * \internal
1960 * \brief information regarding the dialed_cc_interfaces datastore
1961 *
1962 * The dialed_cc_interfaces datastore is responsible for keeping track
1963 * of what CC-enabled interfaces have been dialed by the caller. For
1964 * more information regarding the actual structure of the tree, see
1965 * the documentation provided in include/asterisk/ccss.h
1966 */
1968 .type = "Dial CC Interfaces",
1969 .duplicate = dialed_cc_interfaces_duplicate,
1971};
1972
1974{
1975 struct extension_monitor_pvt *ext_pvt = ast_calloc(1, sizeof(*ext_pvt));
1976 if (!ext_pvt) {
1977 return NULL;
1978 }
1980 return ext_pvt;
1981}
1982
1983void ast_cc_extension_monitor_add_dialstring(struct ast_channel *incoming, const char * const dialstring, const char * const device_name)
1984{
1985 struct ast_datastore *cc_datastore;
1986 struct dialed_cc_interfaces *cc_interfaces;
1987 struct ast_cc_monitor *monitor;
1988 struct extension_monitor_pvt *extension_pvt;
1989 struct extension_child_dialstring *child_dialstring;
1990 struct cc_monitor_tree *interface_tree;
1991 int id;
1992
1993 ast_channel_lock(incoming);
1994 if (!(cc_datastore = ast_channel_datastore_find(incoming, &dialed_cc_interfaces_info, NULL))) {
1995 ast_channel_unlock(incoming);
1996 return;
1997 }
1998
1999 cc_interfaces = cc_datastore->data;
2000 interface_tree = cc_interfaces->interface_tree;
2001 id = cc_interfaces->dial_parent_id;
2002 ast_channel_unlock(incoming);
2003
2004 AST_LIST_LOCK(interface_tree);
2005 AST_LIST_TRAVERSE(interface_tree, monitor, next) {
2006 if (monitor->id == id) {
2007 break;
2008 }
2009 }
2010
2011 if (!monitor) {
2012 AST_LIST_UNLOCK(interface_tree);
2013 return;
2014 }
2015
2016 extension_pvt = monitor->private_data;
2017 if (!(child_dialstring = ast_calloc(1, sizeof(*child_dialstring)))) {
2018 AST_LIST_UNLOCK(interface_tree);
2019 return;
2020 }
2021 ast_copy_string(child_dialstring->original_dialstring, dialstring, sizeof(child_dialstring->original_dialstring));
2022 ast_copy_string(child_dialstring->device_name, device_name, sizeof(child_dialstring->device_name));
2023 child_dialstring->is_valid = 1;
2024 AST_LIST_INSERT_TAIL(&extension_pvt->child_dialstrings, child_dialstring, next);
2025 AST_LIST_UNLOCK(interface_tree);
2026}
2027
2028static 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)
2029{
2030 struct ast_cc_monitor *monitor_iter;
2031 struct extension_monitor_pvt *extension_pvt;
2032 struct extension_child_dialstring *child_dialstring;
2033
2034 AST_LIST_TRAVERSE(core_instance->monitors, monitor_iter, next) {
2035 if (monitor_iter->id == parent_id) {
2036 break;
2037 }
2038 }
2039
2040 if (!monitor_iter) {
2041 return;
2042 }
2043 extension_pvt = monitor_iter->private_data;
2044
2045 AST_LIST_TRAVERSE(&extension_pvt->child_dialstrings, child_dialstring, next) {
2046 if (!strcmp(child_dialstring->device_name, device_name)) {
2047 child_dialstring->is_valid = is_valid;
2048 break;
2049 }
2050 }
2051}
2052
2053/*!
2054 * \internal
2055 * \brief Allocate and initialize an "extension" interface for CC purposes
2056 *
2057 * When app_dial starts, this function is called in order to set up the
2058 * information about the extension in which this Dial is occurring. Any
2059 * devices dialed will have this particular cc_monitor as a parent.
2060 *
2061 * \param exten Extension from which Dial is occurring
2062 * \param context Context to which exten belongs
2063 * \param parent_id What should we set the parent_id of this interface to?
2064 * \retval NULL Memory allocation failure
2065 * \retval non-NULL The newly-created cc_monitor for the extension
2066 */
2067static struct ast_cc_monitor *cc_extension_monitor_init(const char * const exten, const char * const context, const unsigned int parent_id)
2068{
2070 struct ast_cc_interface *cc_interface;
2071 struct ast_cc_monitor *monitor;
2072
2073 ast_str_set(&str, 0, "%s@%s", exten, context);
2074
2075 if (!(cc_interface = ao2_t_alloc(sizeof(*cc_interface) + ast_str_strlen(str), cc_interface_destroy,
2076 "Allocating new ast_cc_interface"))) {
2077 return NULL;
2078 }
2079
2080 if (!(monitor = ao2_t_alloc(sizeof(*monitor), cc_monitor_destroy, "Allocating new ast_cc_monitor"))) {
2081 cc_unref(cc_interface, "failed to allocate the monitor, so unref the interface");
2082 return NULL;
2083 }
2084
2085 if (!(monitor->private_data = extension_monitor_pvt_init())) {
2086 cc_unref(monitor, "Failed to initialize extension monitor private data. uref monitor");
2087 cc_unref(cc_interface, "Failed to initialize extension monitor private data. unref cc_interface");
2088 }
2089
2091 monitor->parent_id = parent_id;
2092 cc_interface->monitor_type = "extension";
2094 strcpy(cc_interface->device_name, ast_str_buffer(str));
2095 monitor->interface = cc_interface;
2096 ast_log_dynamic_level(cc_logger_level, "Created an extension cc interface for '%s' with id %u and parent %u\n", cc_interface->device_name, monitor->id, monitor->parent_id);
2097 return monitor;
2098}
2099
2100/*!
2101 * \internal
2102 * \brief allocate dialed_cc_interfaces datastore and initialize fields
2103 *
2104 * This function is called when Situation 1 occurs in ast_cc_call_init.
2105 * See that function for more information on what Situation 1 is.
2106 *
2107 * In this particular case, we have to do a lot of memory allocation in order
2108 * to create the datastore, the data for the datastore, the tree of interfaces
2109 * that we'll be adding to, and the initial extension interface for this Dial
2110 * attempt.
2111 *
2112 * \param chan The channel onto which the datastore should be added.
2113 * \retval -1 An error occurred
2114 * \retval 0 Success
2115 */
2118 struct ast_cc_monitor *monitor;
2119 struct ast_datastore *dial_cc_datastore;
2120
2121 /*XXX This may be a bit controversial. In an attempt to not allocate
2122 * extra resources, I make sure that a future request will be within
2123 * limits. The problem here is that it is reasonable to think that
2124 * even if we're not within the limits at this point, we may be by
2125 * the time the requestor will have made his request. This may be
2126 * deleted at some point.
2127 */
2129 return 0;
2130 }
2131
2132 if (!(interfaces = ast_calloc(1, sizeof(*interfaces)))) {
2133 return -1;
2134 }
2135
2136 if (!(monitor = cc_extension_monitor_init(ast_channel_exten(chan), ast_channel_context(chan), 0))) {
2138 return -1;
2139 }
2140
2141 if (!(dial_cc_datastore = ast_datastore_alloc(&dialed_cc_interfaces_info, NULL))) {
2142 cc_unref(monitor, "Could not allocate the dialed interfaces datastore. Unreffing monitor");
2144 return -1;
2145 }
2146
2147 if (!(interfaces->interface_tree = ao2_t_alloc(sizeof(*interfaces->interface_tree), cc_interface_tree_destroy,
2148 "Allocate monitor tree"))) {
2149 ast_datastore_free(dial_cc_datastore);
2150 cc_unref(monitor, "Could not allocate monitor tree on dialed interfaces datastore. Unreffing monitor");
2152 return -1;
2153 }
2154
2155 /* Finally, all that allocation is done... */
2156 AST_LIST_HEAD_INIT(interfaces->interface_tree);
2157 AST_LIST_INSERT_TAIL(interfaces->interface_tree, monitor, next);
2158 cc_ref(monitor, "List's reference to extension monitor");
2159 dial_cc_datastore->data = interfaces;
2160 dial_cc_datastore->inheritance = DATASTORE_INHERIT_FOREVER;
2161 interfaces->dial_parent_id = monitor->id;
2162 interfaces->core_id = monitor->core_id = ast_atomic_fetchadd_int(&core_id_counter, +1);
2163 interfaces->is_original_caller = 1;
2164 ast_channel_lock(chan);
2165 ast_channel_datastore_add(chan, dial_cc_datastore);
2166 ast_channel_unlock(chan);
2167 cc_unref(monitor, "Unreffing allocation's reference");
2168 return 0;
2169}
2170
2171/*!
2172 * \internal
2173 * \brief Call a monitor's destructor before the monitor has been allocated
2174 * \since 1.8
2175 *
2176 * \param monitor_type The type of monitor callbacks to use when calling the destructor
2177 * \param private_data Data allocated by a channel driver that must be freed
2178 *
2179 * \details
2180 * I'll admit, this is a bit evil.
2181 *
2182 * When a channel driver determines that it can offer a call completion service to
2183 * a caller, it is very likely that the channel driver will need to allocate some
2184 * data so that when the time comes to request CC, the channel driver will have the
2185 * necessary data at hand.
2186 *
2187 * The problem is that there are many places where failures may occur before the monitor
2188 * has been properly allocated and had its callbacks assigned to it. If one of these
2189 * failures should occur, then we still need to let the channel driver know that it
2190 * must destroy the data that it allocated.
2191 */
2192static void call_destructor_with_no_monitor(const char * const monitor_type, void *private_data)
2193{
2194 const struct ast_cc_monitor_callbacks *monitor_callbacks = find_monitor_callbacks(monitor_type);
2195
2196 if (!monitor_callbacks) {
2197 return;
2198 }
2199
2200 monitor_callbacks->destructor(private_data);
2201}
2202
2203/*!
2204 * \internal
2205 * \brief Allocate and intitialize a device cc_monitor
2206 *
2207 * For all intents and purposes, this is the same as
2208 * cc_extension_monitor_init, except that there is only
2209 * a single parameter used for naming the interface.
2210 *
2211 * This function is called when handling AST_CONTROL_CC frames.
2212 * The device has reported that CC is possible, so we add it
2213 * to the interface_tree.
2214 *
2215 * Note that it is not necessarily erroneous to add the same
2216 * device to the tree twice. If the same device is called by
2217 * two different extension during the same call, then
2218 * that is a legitimate situation.
2219 *
2220 * \param device_name The name of the device being added to the tree
2221 * \param dialstring The dialstring used to dial the device being added
2222 * \param core_id
2223 * \param cc_data
2224 * \retval NULL Memory allocation failure
2225 * \retval non-NULL The new ast_cc_interface created.
2226 */
2227static 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)
2228{
2229 struct ast_cc_interface *cc_interface;
2230 struct ast_cc_monitor *monitor;
2231 size_t device_name_len = strlen(device_name);
2232 int parent_id = cc_data->parent_interface_id;
2233
2234 if (!(cc_interface = ao2_t_alloc(sizeof(*cc_interface) + device_name_len, cc_interface_destroy,
2235 "Allocating new ast_cc_interface"))) {
2236 return NULL;
2237 }
2238
2239 if (!(cc_interface->config_params = ast_cc_config_params_init())) {
2240 cc_unref(cc_interface, "Failed to allocate config params, unref interface");
2241 return NULL;
2242 }
2243
2244 if (!(monitor = ao2_t_alloc(sizeof(*monitor), cc_monitor_destroy, "Allocating new ast_cc_monitor"))) {
2245 cc_unref(cc_interface, "Failed to allocate monitor, unref interface");
2246 return NULL;
2247 }
2248
2249 if (!(monitor->dialstring = ast_strdup(dialstring))) {
2250 cc_unref(monitor, "Failed to copy dialable name. Unref monitor");
2251 cc_unref(cc_interface, "Failed to copy dialable name");
2252 return NULL;
2253 }
2254
2255 if (!(monitor->callbacks = find_monitor_callbacks(cc_data->monitor_type))) {
2256 cc_unref(monitor, "Failed to find monitor callbacks. Unref monitor");
2257 cc_unref(cc_interface, "Failed to find monitor callbacks");
2258 return NULL;
2259 }
2260
2261 strcpy(cc_interface->device_name, device_name);
2263 monitor->parent_id = parent_id;
2264 monitor->core_id = core_id;
2265 monitor->service_offered = cc_data->service;
2266 monitor->private_data = cc_data->private_data;
2267 cc_interface->monitor_type = cc_data->monitor_type;
2268 cc_interface->monitor_class = AST_CC_DEVICE_MONITOR;
2269 monitor->interface = cc_interface;
2270 monitor->available_timer_id = -1;
2271 ast_cc_copy_config_params(cc_interface->config_params, &cc_data->config_params);
2272 ast_log_dynamic_level(cc_logger_level, "Core %d: Created a device cc interface for '%s' with id %u and parent %u\n",
2273 monitor->core_id, cc_interface->device_name, monitor->id, monitor->parent_id);
2274 return monitor;
2275}
2276
2277/*!
2278 * \details
2279 * Unless we are ignoring CC for some reason, we will always
2280 * call this function when we read an AST_CONTROL_CC frame
2281 * from an outbound channel.
2282 *
2283 * This function will call cc_device_monitor_init to
2284 * create the new cc_monitor for the device from which
2285 * we read the frame. In addition, the new device will be added
2286 * to the monitor tree on the dialed_cc_interfaces datastore
2287 * on the inbound channel.
2288 *
2289 * If this is the first AST_CONTROL_CC frame that we have handled
2290 * for this call, then we will also initialize the CC core for
2291 * this call.
2292 */
2293void ast_handle_cc_control_frame(struct ast_channel *inbound, struct ast_channel *outbound, void *frame_data)
2294{
2295 char *device_name;
2296 char *dialstring;
2297 struct ast_cc_monitor *monitor;
2298 struct ast_datastore *cc_datastore;
2299 struct dialed_cc_interfaces *cc_interfaces;
2300 struct cc_control_payload *cc_data = frame_data;
2301 struct cc_core_instance *core_instance;
2302
2303 device_name = cc_data->device_name;
2304 dialstring = cc_data->dialstring;
2305
2306 ast_channel_lock(inbound);
2307 if (!(cc_datastore = ast_channel_datastore_find(inbound, &dialed_cc_interfaces_info, NULL))) {
2308 ast_log(LOG_WARNING, "Unable to retrieve CC datastore while processing CC frame from '%s'. CC services will be unavailable.\n", device_name);
2309 ast_channel_unlock(inbound);
2311 return;
2312 }
2313
2314 cc_interfaces = cc_datastore->data;
2315
2316 if (cc_interfaces->ignore) {
2317 ast_channel_unlock(inbound);
2319 return;
2320 }
2321
2322 if (!cc_interfaces->is_original_caller) {
2323 /* If the is_original_caller is not set on the *inbound* channel, then
2324 * it must be a local channel. As such, we do not want to create a core instance
2325 * or an agent for the local channel. Instead, we want to pass this along to the
2326 * other side of the local channel so that the original caller can benefit.
2327 */
2328 ast_channel_unlock(inbound);
2329 ast_indicate_data(inbound, AST_CONTROL_CC, cc_data, sizeof(*cc_data));
2330 return;
2331 }
2332
2333 core_instance = find_cc_core_instance(cc_interfaces->core_id);
2334 if (!core_instance) {
2335 core_instance = cc_core_init_instance(inbound, cc_interfaces->interface_tree,
2336 cc_interfaces->core_id, cc_data);
2337 if (!core_instance) {
2338 cc_interfaces->ignore = 1;
2339 ast_channel_unlock(inbound);
2341 return;
2342 }
2343 }
2344
2345 ast_channel_unlock(inbound);
2346
2347 /* Yeah this kind of sucks, but luckily most people
2348 * aren't dialing thousands of interfaces on every call
2349 *
2350 * This traversal helps us to not create duplicate monitors in
2351 * case a device queues multiple CC control frames.
2352 */
2353 AST_LIST_LOCK(cc_interfaces->interface_tree);
2354 AST_LIST_TRAVERSE(cc_interfaces->interface_tree, monitor, next) {
2355 if (!strcmp(monitor->interface->device_name, device_name)) {
2356 ast_log_dynamic_level(cc_logger_level, "Core %d: Device %s sent us multiple CC control frames. Ignoring those beyond the first.\n",
2357 core_instance->core_id, device_name);
2358 AST_LIST_UNLOCK(cc_interfaces->interface_tree);
2359 cc_unref(core_instance, "Returning early from ast_handle_cc_control_frame. Unref core_instance");
2361 return;
2362 }
2363 }
2364 AST_LIST_UNLOCK(cc_interfaces->interface_tree);
2365
2366 if (!(monitor = cc_device_monitor_init(device_name, dialstring, cc_data, core_instance->core_id))) {
2367 ast_log(LOG_WARNING, "Unable to create CC device interface for '%s'. CC services will be unavailable on this interface.\n", device_name);
2368 cc_unref(core_instance, "Returning early from ast_handle_cc_control_frame. Unref core_instance");
2370 return;
2371 }
2372
2373 AST_LIST_LOCK(cc_interfaces->interface_tree);
2374 cc_ref(monitor, "monitor tree's reference to the monitor");
2375 AST_LIST_INSERT_TAIL(cc_interfaces->interface_tree, monitor, next);
2376 AST_LIST_UNLOCK(cc_interfaces->interface_tree);
2377
2378 cc_extension_monitor_change_is_valid(core_instance, monitor->parent_id, monitor->interface->device_name, 0);
2379
2380 cc_publish_available(cc_interfaces->core_id, device_name, cc_service_to_string(cc_data->service));
2381
2382 cc_unref(core_instance, "Done with core_instance after handling CC control frame");
2383 cc_unref(monitor, "Unref reference from allocating monitor");
2384}
2385
2386int ast_cc_call_init(struct ast_channel *chan, int *ignore_cc)
2387{
2388 /* There are three situations to deal with here:
2389 *
2390 * 1. The channel does not have a dialed_cc_interfaces datastore on
2391 * it. This means that this is the first time that Dial has
2392 * been called. We need to create/initialize the datastore.
2393 *
2394 * 2. The channel does have a cc_interface datastore on it and
2395 * the "ignore" indicator is 0. This means that a Local channel
2396 * was called by a "parent" dial. We can check the datastore's
2397 * parent field to see who the root of this particular dial tree
2398 * is.
2399 *
2400 * 3. The channel does have a cc_interface datastore on it and
2401 * the "ignore" indicator is 1. This means that a second Dial call
2402 * is being made from an extension. In this case, we do not
2403 * want to make any additions/modifications to the datastore. We
2404 * will instead set a flag to indicate that CCSS is completely
2405 * disabled for this Dial attempt.
2406 */
2407
2408 struct ast_datastore *cc_interfaces_datastore;
2410 struct ast_cc_monitor *monitor;
2411 struct ast_cc_config_params *cc_params;
2412
2413 ast_channel_lock(chan);
2414
2415 cc_params = ast_channel_get_cc_config_params(chan);
2416 if (!cc_params) {
2417 ast_channel_unlock(chan);
2418 return -1;
2419 }
2420 if (ast_get_cc_agent_policy(cc_params) == AST_CC_AGENT_NEVER) {
2421 /* We can't offer CC to this caller anyway, so don't bother with CC on this call
2422 */
2423 *ignore_cc = 1;
2424 ast_channel_unlock(chan);
2425 ast_log_dynamic_level(cc_logger_level, "Agent policy for %s is 'never'. CC not possible\n", ast_channel_name(chan));
2426 return 0;
2427 }
2428
2429 if (!(cc_interfaces_datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL))) {
2430 /* Situation 1 has occurred */
2431 ast_channel_unlock(chan);
2432 return cc_interfaces_datastore_init(chan);
2433 }
2434 interfaces = cc_interfaces_datastore->data;
2435 ast_channel_unlock(chan);
2436
2437 if (interfaces->ignore) {
2438 /* Situation 3 has occurred */
2439 *ignore_cc = 1;
2440 ast_log_dynamic_level(cc_logger_level, "Datastore is present with ignore flag set. Ignoring CC offers on this call\n");
2441 return 0;
2442 }
2443
2444 /* Situation 2 has occurred */
2445 if (!(monitor = cc_extension_monitor_init(ast_channel_exten(chan),
2446 ast_channel_context(chan),
2447 interfaces->dial_parent_id))) {
2448 return -1;
2449 }
2450 monitor->core_id = interfaces->core_id;
2451 AST_LIST_LOCK(interfaces->interface_tree);
2452 cc_ref(monitor, "monitor tree's reference to the monitor");
2453 AST_LIST_INSERT_TAIL(interfaces->interface_tree, monitor, next);
2454 AST_LIST_UNLOCK(interfaces->interface_tree);
2455 interfaces->dial_parent_id = monitor->id;
2456 cc_unref(monitor, "Unref monitor's allocation reference");
2457 return 0;
2458}
2459
2461{
2463}
2464
2466{
2467 struct ast_datastore *datastore;
2468 struct dialed_cc_interfaces *cc_interfaces;
2469 int core_id_return;
2470
2471 ast_channel_lock(chan);
2472 if (!(datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL))) {
2473 ast_channel_unlock(chan);
2474 return -1;
2475 }
2476
2477 cc_interfaces = datastore->data;
2478 core_id_return = cc_interfaces->ignore ? -1 : cc_interfaces->core_id;
2479 ast_channel_unlock(chan);
2480 return core_id_return;
2481
2482}
2483
2484static long count_agents(const char * const caller, const int core_id_exception)
2485{
2487
2488 ao2_t_callback_data(cc_core_instances, OBJ_NODATA, count_agents_cb, (char *)caller, &data, "Counting agents");
2489 ast_log_dynamic_level(cc_logger_level, "Counted %d agents\n", data.count);
2490 return data.count;
2491}
2492
2493static void kill_duplicate_offers(char *caller)
2494{
2495 unsigned long match_flags = MATCH_NO_REQUEST;
2496 struct ao2_iterator *dups_iter;
2497
2498 /*
2499 * Must remove the ref that was in cc_core_instances outside of
2500 * the container lock to prevent deadlock.
2501 */
2503 match_agent, caller, &match_flags, "Killing duplicate offers");
2504 if (dups_iter) {
2505 /* Now actually unref any duplicate offers by simply destroying the iterator. */
2506 ao2_iterator_destroy(dups_iter);
2507 }
2508}
2509
2511{
2512 ast_assert(callbacks->init != NULL);
2513 ast_assert(callbacks->start_offer_timer != NULL);
2514 ast_assert(callbacks->stop_offer_timer != NULL);
2515 ast_assert(callbacks->respond != NULL);
2516 ast_assert(callbacks->status_request != NULL);
2517 ast_assert(callbacks->start_monitoring != NULL);
2518 ast_assert(callbacks->callee_available != NULL);
2519 ast_assert(callbacks->destructor != NULL);
2520}
2521
2522static void agent_destroy(void *data)
2523{
2524 struct ast_cc_agent *agent = data;
2525
2526 if (agent->callbacks) {
2527 agent->callbacks->destructor(agent);
2528 }
2530}
2531
2532static struct ast_cc_agent *cc_agent_init(struct ast_channel *caller_chan,
2533 const char * const caller_name, const int core_id,
2534 struct cc_monitor_tree *interface_tree)
2535{
2536 struct ast_cc_agent *agent;
2537 struct ast_cc_config_params *cc_params;
2538
2539 if (!(agent = ao2_t_alloc(sizeof(*agent) + strlen(caller_name), agent_destroy,
2540 "Allocating new ast_cc_agent"))) {
2541 return NULL;
2542 }
2543
2544 agent->core_id = core_id;
2545 strcpy(agent->device_name, caller_name);
2546
2547 cc_params = ast_channel_get_cc_config_params(caller_chan);
2548 if (!cc_params) {
2549 cc_unref(agent, "Could not get channel config params.");
2550 return NULL;
2551 }
2552 if (!(agent->cc_params = ast_cc_config_params_init())) {
2553 cc_unref(agent, "Could not init agent config params.");
2554 return NULL;
2555 }
2556 ast_cc_copy_config_params(agent->cc_params, cc_params);
2557
2558 if (!(agent->callbacks = find_agent_callbacks(caller_chan))) {
2559 cc_unref(agent, "Could not find agent callbacks.");
2560 return NULL;
2561 }
2563
2564 if (agent->callbacks->init(agent, caller_chan)) {
2565 cc_unref(agent, "Agent init callback failed.");
2566 return NULL;
2567 }
2568 ast_log_dynamic_level(cc_logger_level, "Core %u: Created an agent for caller %s\n",
2569 agent->core_id, agent->device_name);
2570 return agent;
2571}
2572
2573/* Generic agent callbacks */
2574static int cc_generic_agent_init(struct ast_cc_agent *agent, struct ast_channel *chan);
2575static int cc_generic_agent_start_offer_timer(struct ast_cc_agent *agent);
2576static int cc_generic_agent_stop_offer_timer(struct ast_cc_agent *agent);
2577static void cc_generic_agent_respond(struct ast_cc_agent *agent, enum ast_cc_agent_response_reason reason);
2578static int cc_generic_agent_status_request(struct ast_cc_agent *agent);
2579static int cc_generic_agent_stop_ringing(struct ast_cc_agent *agent);
2580static int cc_generic_agent_start_monitoring(struct ast_cc_agent *agent);
2581static int cc_generic_agent_recall(struct ast_cc_agent *agent);
2582static void cc_generic_agent_destructor(struct ast_cc_agent *agent);
2583
2585 .type = "generic",
2586 .init = cc_generic_agent_init,
2587 .start_offer_timer = cc_generic_agent_start_offer_timer,
2588 .stop_offer_timer = cc_generic_agent_stop_offer_timer,
2589 .respond = cc_generic_agent_respond,
2590 .status_request = cc_generic_agent_status_request,
2591 .stop_ringing = cc_generic_agent_stop_ringing,
2592 .start_monitoring = cc_generic_agent_start_monitoring,
2593 .callee_available = cc_generic_agent_recall,
2594 .destructor = cc_generic_agent_destructor,
2595};
2596
2598 /*!
2599 * Subscription to device state
2600 *
2601 * Used in the CC_CALLER_BUSY state. The
2602 * generic agent will subscribe to the
2603 * device state of the caller in order to
2604 * determine when we may move on
2605 */
2607 /*!
2608 * Scheduler id of offer timer.
2609 */
2611 /*!
2612 * Caller ID number
2613 *
2614 * When we re-call the caller, we need
2615 * to provide this information to
2616 * ast_request_and_dial so that the
2617 * information will be present in the
2618 * call to the callee
2619 */
2621 /*!
2622 * Caller ID name
2623 *
2624 * See the description of cid_num.
2625 * The same applies here, except this
2626 * is the caller's name.
2627 */
2629 /*!
2630 * Extension dialed
2631 *
2632 * The original extension dialed. This is used
2633 * so that when performing a recall, we can
2634 * call the proper extension.
2635 */
2637 /*!
2638 * Context dialed
2639 *
2640 * The original context dialed. This is used
2641 * so that when performing a recall, we can
2642 * call into the proper context
2643 */
2645};
2646
2647static int cc_generic_agent_init(struct ast_cc_agent *agent, struct ast_channel *chan)
2648{
2649 struct cc_generic_agent_pvt *generic_pvt = ast_calloc(1, sizeof(*generic_pvt));
2650
2651 if (!generic_pvt) {
2652 return -1;
2653 }
2654
2655 generic_pvt->offer_timer_id = -1;
2656 if (ast_channel_caller(chan)->id.number.valid && ast_channel_caller(chan)->id.number.str) {
2657 ast_copy_string(generic_pvt->cid_num, ast_channel_caller(chan)->id.number.str, sizeof(generic_pvt->cid_num));
2658 }
2659 if (ast_channel_caller(chan)->id.name.valid && ast_channel_caller(chan)->id.name.str) {
2660 ast_copy_string(generic_pvt->cid_name, ast_channel_caller(chan)->id.name.str, sizeof(generic_pvt->cid_name));
2661 }
2662 ast_copy_string(generic_pvt->exten, ast_channel_exten(chan), sizeof(generic_pvt->exten));
2663 ast_copy_string(generic_pvt->context, ast_channel_context(chan), sizeof(generic_pvt->context));
2664 agent->private_data = generic_pvt;
2666 return 0;
2667}
2668
2669static int offer_timer_expire(const void *data)
2670{
2671 struct ast_cc_agent *agent = (struct ast_cc_agent *) data;
2673 ast_log_dynamic_level(cc_logger_level, "Core %u: Queuing change request because offer timer has expired.\n",
2674 agent->core_id);
2675 agent_pvt->offer_timer_id = -1;
2676 ast_cc_failed(agent->core_id, "Generic agent %s offer timer expired", agent->device_name);
2677 cc_unref(agent, "Remove scheduler's reference to the agent");
2678 return 0;
2679}
2680
2682{
2683 int when;
2684 int sched_id;
2685 struct cc_generic_agent_pvt *generic_pvt = agent->private_data;
2686
2688 ast_assert(agent->cc_params != NULL);
2689
2690 when = ast_get_cc_offer_timer(agent->cc_params) * 1000;
2691 ast_log_dynamic_level(cc_logger_level, "Core %u: About to schedule offer timer expiration for %d ms\n",
2692 agent->core_id, when);
2693 if ((sched_id = ast_sched_add(cc_sched_context, when, offer_timer_expire, cc_ref(agent, "Give scheduler an agent ref"))) == -1) {
2694 return -1;
2695 }
2696 generic_pvt->offer_timer_id = sched_id;
2697 return 0;
2698}
2699
2701{
2702 struct cc_generic_agent_pvt *generic_pvt = agent->private_data;
2703
2704 if (generic_pvt->offer_timer_id != -1) {
2705 if (!ast_sched_del(cc_sched_context, generic_pvt->offer_timer_id)) {
2706 cc_unref(agent, "Remove scheduler's reference to the agent");
2707 }
2708 generic_pvt->offer_timer_id = -1;
2709 }
2710 return 0;
2711}
2712
2714{
2715 /* The generic agent doesn't have to do anything special to
2716 * acknowledge a CC request. Just return.
2717 */
2718 return;
2719}
2720
2722{
2724 return 0;
2725}
2726
2728{
2729 struct ast_channel *recall_chan = ast_channel_get_by_name_prefix(agent->device_name, strlen(agent->device_name));
2730
2731 if (!recall_chan) {
2732 return 0;
2733 }
2734
2736 return 0;
2737}
2738
2739static void generic_agent_devstate_cb(void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)
2740{
2741 struct ast_cc_agent *agent = userdata;
2742 enum ast_device_state new_state;
2743 struct ast_device_state_message *dev_state;
2744 struct cc_generic_agent_pvt *generic_pvt = agent->private_data;
2745
2747 cc_unref(agent, "Done holding ref for subscription");
2748 return;
2750 return;
2751 }
2752
2753 dev_state = stasis_message_data(msg);
2754 if (dev_state->eid) {
2755 /* ignore non-aggregate states */
2756 return;
2757 }
2758
2759 new_state = dev_state->state;
2760 if (!cc_generic_is_device_available(new_state)) {
2761 /* Not interested in this new state of the device. It is still busy. */
2762 return;
2763 }
2764
2765 generic_pvt->sub = stasis_unsubscribe(sub);
2766 ast_cc_agent_caller_available(agent->core_id, "%s is no longer busy", agent->device_name);
2767}
2768
2770{
2771 struct cc_generic_agent_pvt *generic_pvt = agent->private_data;
2772 struct ast_str *str = ast_str_alloca(128);
2773 struct stasis_topic *device_specific_topic;
2774
2775 ast_assert(generic_pvt->sub == NULL);
2776 ast_str_set(&str, 0, "Agent monitoring %s device state since it is busy\n",
2777 agent->device_name);
2778
2779 device_specific_topic = ast_device_state_topic(agent->device_name);
2780 if (!device_specific_topic) {
2781 return -1;
2782 }
2783
2784 if (!(generic_pvt->sub = stasis_subscribe(device_specific_topic, generic_agent_devstate_cb, agent))) {
2785 return -1;
2786 }
2790 cc_ref(agent, "Ref agent for subscription");
2791 return 0;
2792}
2793
2794static void *generic_recall(void *data)
2795{
2796 struct ast_cc_agent *agent = data;
2797 struct cc_generic_agent_pvt *generic_pvt = agent->private_data;
2798 const char *interface = S_OR(ast_get_cc_agent_dialstring(agent->cc_params), ast_strdupa(agent->device_name));
2799 const char *tech;
2800 char *target;
2801 int reason;
2802 struct ast_channel *chan;
2803 const char *callback_sub = ast_get_cc_callback_sub(agent->cc_params);
2804 unsigned int recall_timer = ast_get_cc_recall_timer(agent->cc_params) * 1000;
2806
2807 if (!tmp_cap) {
2808 return NULL;
2809 }
2810
2811 tech = interface;
2812 if ((target = strchr(interface, '/'))) {
2813 *target++ = '\0';
2814 }
2815
2817 if (!(chan = ast_request_and_dial(tech, tmp_cap, NULL, NULL, target, recall_timer, &reason, generic_pvt->cid_num, generic_pvt->cid_name))) {
2818 /* Hmm, no channel. Sucks for you, bud.
2819 */
2820 ast_log_dynamic_level(cc_logger_level, "Core %u: Failed to call back %s for reason %d\n",
2821 agent->core_id, agent->device_name, reason);
2822 ast_cc_failed(agent->core_id, "Failed to call back device %s/%s", tech, target);
2823 ao2_ref(tmp_cap, -1);
2824 return NULL;
2825 }
2826 ao2_ref(tmp_cap, -1);
2827
2828 /* We have a channel. It's time now to set up the datastore of recalled CC interfaces.
2829 * This will be a common task for all recall functions. If it were possible, I'd have
2830 * the core do it automatically, but alas I cannot. Instead, I will provide a public
2831 * function to do so.
2832 */
2835
2836 ast_channel_exten_set(chan, generic_pvt->exten);
2837 ast_channel_context_set(chan, generic_pvt->context);
2838 ast_channel_priority_set(chan, 1);
2839
2840 pbx_builtin_setvar_helper(chan, "CC_EXTEN", generic_pvt->exten);
2841 pbx_builtin_setvar_helper(chan, "CC_CONTEXT", generic_pvt->context);
2842
2843 if (!ast_strlen_zero(callback_sub)) {
2844 ast_log_dynamic_level(cc_logger_level, "Core %u: There's a callback subroutine configured for agent %s\n",
2845 agent->core_id, agent->device_name);
2846 if (ast_app_exec_sub(NULL, chan, callback_sub, 0)) {
2847 ast_cc_failed(agent->core_id, "Callback subroutine to %s failed. Maybe a hangup?", agent->device_name);
2848 ast_hangup(chan);
2849 return NULL;
2850 }
2851 }
2852 if (ast_pbx_start(chan)) {
2853 ast_cc_failed(agent->core_id, "PBX failed to start for %s.", agent->device_name);
2854 ast_hangup(chan);
2855 return NULL;
2856 }
2857 ast_cc_agent_recalling(agent->core_id, "Generic agent %s is recalling",
2858 agent->device_name);
2859 return NULL;
2860}
2861
2862static int cc_generic_agent_recall(struct ast_cc_agent *agent)
2863{
2864 pthread_t clotho;
2865 enum ast_device_state current_state = ast_device_state(agent->device_name);
2866
2867 if (!cc_generic_is_device_available(current_state)) {
2868 /* We can't try to contact the device right now because he's not available
2869 * Let the core know he's busy.
2870 */
2871 ast_cc_agent_caller_busy(agent->core_id, "Generic agent caller %s is busy", agent->device_name);
2872 return 0;
2873 }
2875 return 0;
2876}
2877
2879{
2881
2882 if (!agent_pvt) {
2883 /* The agent constructor probably failed. */
2884 return;
2885 }
2886
2888 if (agent_pvt->sub) {
2890 }
2891
2893}
2894
2895static void cc_core_instance_destructor(void *data)
2896{
2897 struct cc_core_instance *core_instance = data;
2898 ast_log_dynamic_level(cc_logger_level, "Core %d: Destroying core instance\n", core_instance->core_id);
2899 if (core_instance->agent) {
2900 cc_unref(core_instance->agent, "Core instance is done with the agent now");
2901 }
2902 if (core_instance->monitors) {
2903 core_instance->monitors = cc_unref(core_instance->monitors, "Core instance is done with interface list");
2904 }
2905}
2906
2907static struct cc_core_instance *cc_core_init_instance(struct ast_channel *caller_chan,
2908 struct cc_monitor_tree *called_tree, const int core_id, struct cc_control_payload *cc_data)
2909{
2910 char caller[AST_CHANNEL_NAME];
2911 struct cc_core_instance *core_instance;
2912 struct ast_cc_config_params *cc_params;
2913 long agent_count;
2914 int recall_core_id;
2915
2916 ast_channel_get_device_name(caller_chan, caller, sizeof(caller));
2917 cc_params = ast_channel_get_cc_config_params(caller_chan);
2918 if (!cc_params) {
2919 ast_log_dynamic_level(cc_logger_level, "Could not get CC parameters for %s\n",
2920 caller);
2921 return NULL;
2922 }
2923 /* First, we need to kill off other pending CC offers from caller. If the caller is going
2924 * to request a CC service, it may only be for the latest call he made.
2925 */
2927 kill_duplicate_offers(caller);
2928 }
2929
2930 ast_cc_is_recall(caller_chan, &recall_core_id, NULL);
2931 agent_count = count_agents(caller, recall_core_id);
2932 if (agent_count >= ast_get_cc_max_agents(cc_params)) {
2933 ast_log_dynamic_level(cc_logger_level, "Caller %s already has the maximum number of agents configured\n", caller);
2934 return NULL;
2935 }
2936
2937 /* Generic agents can only have a single outstanding CC request per caller. */
2938 if (agent_count > 0 && ast_get_cc_agent_policy(cc_params) == AST_CC_AGENT_GENERIC) {
2939 ast_log_dynamic_level(cc_logger_level, "Generic agents can only have a single outstanding request\n");
2940 return NULL;
2941 }
2942
2943 /* Next, we need to create the core instance for this call */
2944 if (!(core_instance = ao2_t_alloc(sizeof(*core_instance), cc_core_instance_destructor, "Creating core instance for CC"))) {
2945 return NULL;
2946 }
2947
2948 core_instance->core_id = core_id;
2949 if (!(core_instance->agent = cc_agent_init(caller_chan, caller, core_instance->core_id, called_tree))) {
2950 cc_unref(core_instance, "Couldn't allocate agent, unref core_instance");
2951 return NULL;
2952 }
2953
2954 core_instance->monitors = cc_ref(called_tree, "Core instance getting ref to monitor tree");
2955
2956 ao2_t_link(cc_core_instances, core_instance, "Link core instance into container");
2957
2958 return core_instance;
2959}
2960
2962 struct cc_core_instance *core_instance;/*!< Holds reference to core instance. */
2965 char debug[1];
2966};
2967
2968static int is_state_change_valid(enum cc_state current_state, const enum cc_state new_state, struct ast_cc_agent *agent)
2969{
2970 int is_valid = 0;
2971 switch (new_state) {
2972 case CC_AVAILABLE:
2973 ast_log_dynamic_level(cc_logger_level, "Core %u: Asked to change to state %u? That should never happen.\n",
2974 agent->core_id, new_state);
2975 break;
2976 case CC_CALLER_OFFERED:
2977 if (current_state == CC_AVAILABLE) {
2978 is_valid = 1;
2979 }
2980 break;
2984 is_valid = 1;
2985 }
2986 break;
2987 case CC_ACTIVE:
2989 is_valid = 1;
2990 }
2991 break;
2992 case CC_CALLEE_READY:
2993 if (current_state == CC_ACTIVE) {
2994 is_valid = 1;
2995 }
2996 break;
2997 case CC_CALLER_BUSY:
2999 is_valid = 1;
3000 }
3001 break;
3002 case CC_RECALLING:
3004 is_valid = 1;
3005 }
3006 break;
3007 case CC_COMPLETE:
3008 if (current_state == CC_RECALLING) {
3009 is_valid = 1;
3010 }
3011 break;
3012 case CC_FAILED:
3013 is_valid = 1;
3014 break;
3015 default:
3016 ast_log_dynamic_level(cc_logger_level, "Core %u: Asked to change to unknown state %u\n",
3017 agent->core_id, new_state);
3018 break;
3019 }
3020
3021 return is_valid;
3022}
3023
3024static int cc_available(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
3025{
3026 /* This should never happen... */
3027 ast_log(LOG_WARNING, "Someone requested to change to CC_AVAILABLE? Ignoring.\n");
3028 return -1;
3029}
3030
3031static int cc_caller_offered(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
3032{
3033 if (core_instance->agent->callbacks->start_offer_timer(core_instance->agent)) {
3034 ast_cc_failed(core_instance->core_id, "Failed to start the offer timer for %s\n",
3035 core_instance->agent->device_name);
3036 return -1;
3037 }
3038 cc_publish_offertimerstart(core_instance->core_id, core_instance->agent->device_name, core_instance->agent->cc_params->cc_offer_timer);
3039 ast_log_dynamic_level(cc_logger_level, "Core %d: Started the offer timer for the agent %s!\n",
3040 core_instance->core_id, core_instance->agent->device_name);
3041 return 0;
3042}
3043
3044/*!
3045 * \brief check if the core instance has any device monitors
3046 *
3047 * In any case where we end up removing a device monitor from the
3048 * list of device monitors, it is important to see what the state
3049 * of the list is afterwards. If we find that we only have extension
3050 * monitors left, then no devices are actually being monitored.
3051 * In such a case, we need to declare that CC has failed for this
3052 * call. This function helps those cases to determine if they should
3053 * declare failure.
3054 *
3055 * \param core_instance The core instance we are checking for the existence
3056 * of device monitors
3057 * \retval 0 No device monitors exist on this core_instance
3058 * \retval 1 There is still at least 1 device monitor remaining
3059 */
3060static int has_device_monitors(struct cc_core_instance *core_instance)
3061{
3062 struct ast_cc_monitor *iter;
3063 int res = 0;
3064
3065 AST_LIST_TRAVERSE(core_instance->monitors, iter, next) {
3067 res = 1;
3068 break;
3069 }
3070 }
3071
3072 return res;
3073}
3074
3075static void request_cc(struct cc_core_instance *core_instance)
3076{
3077 struct ast_cc_monitor *monitor_iter;
3078 AST_LIST_LOCK(core_instance->monitors);
3079 AST_LIST_TRAVERSE_SAFE_BEGIN(core_instance->monitors, monitor_iter, next) {
3080 if (monitor_iter->interface->monitor_class == AST_CC_DEVICE_MONITOR) {
3081 if (monitor_iter->callbacks->request_cc(monitor_iter, &monitor_iter->available_timer_id)) {
3083 cc_extension_monitor_change_is_valid(core_instance, monitor_iter->parent_id,
3084 monitor_iter->interface->device_name, 1);
3085 cc_unref(monitor_iter, "request_cc failed. Unref list's reference to monitor");
3086 } else {
3087 cc_publish_requested(core_instance->core_id, core_instance->agent->device_name, monitor_iter->interface->device_name);
3088 }
3089 }
3090 }
3092
3093 if (!has_device_monitors(core_instance)) {
3094 ast_cc_failed(core_instance->core_id, "All device monitors failed to request CC");
3095 }
3096 AST_LIST_UNLOCK(core_instance->monitors);
3097}
3098
3099static int cc_caller_requested(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
3100{
3102 ast_log(LOG_WARNING, "Cannot request CC since there is no more room for requests\n");
3103 core_instance->agent->callbacks->respond(core_instance->agent,
3105 ast_cc_failed(core_instance->core_id, "Too many requests in the system");
3106 return -1;
3107 }
3108 core_instance->agent->callbacks->stop_offer_timer(core_instance->agent);
3109 request_cc(core_instance);
3110 return 0;
3111}
3112
3113static void unsuspend(struct cc_core_instance *core_instance)
3114{
3115 struct ast_cc_monitor *monitor_iter;
3116 AST_LIST_LOCK(core_instance->monitors);
3117 AST_LIST_TRAVERSE_SAFE_BEGIN(core_instance->monitors, monitor_iter, next) {
3118 if (monitor_iter->interface->monitor_class == AST_CC_DEVICE_MONITOR) {
3119 if (monitor_iter->callbacks->unsuspend(monitor_iter)) {
3121 cc_extension_monitor_change_is_valid(core_instance, monitor_iter->parent_id,
3122 monitor_iter->interface->device_name, 1);
3123 cc_unref(monitor_iter, "unsuspend failed. Unref list's reference to monitor");
3124 }
3125 }
3126 }
3128
3129 if (!has_device_monitors(core_instance)) {
3130 ast_cc_failed(core_instance->core_id, "All device monitors failed to unsuspend CC");
3131 }
3132 AST_LIST_UNLOCK(core_instance->monitors);
3133}
3134
3135static int cc_active(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
3136{
3137 /* Either
3138 * 1. Callee accepted CC request, call agent's ack callback.
3139 * 2. Caller became available, call agent's stop_monitoring callback and
3140 * call monitor's unsuspend callback.
3141 */
3142 if (previous_state == CC_CALLER_REQUESTED) {
3143 core_instance->agent->callbacks->respond(core_instance->agent,
3145 cc_publish_requestacknowledged(core_instance->core_id, core_instance->agent->device_name);
3146 } else if (previous_state == CC_CALLER_BUSY) {
3147 cc_publish_callerstopmonitoring(core_instance->core_id, core_instance->agent->device_name);
3148 unsuspend(core_instance);
3149 }
3150 /* Not possible for previous_state to be anything else due to the is_state_change_valid check at the beginning */
3151 return 0;
3152}
3153
3154static int cc_callee_ready(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
3155{
3156 core_instance->agent->callbacks->callee_available(core_instance->agent);
3157 return 0;
3158}
3159
3160static void suspend(struct cc_core_instance *core_instance)
3161{
3162 struct ast_cc_monitor *monitor_iter;
3163 AST_LIST_LOCK(core_instance->monitors);
3164 AST_LIST_TRAVERSE_SAFE_BEGIN(core_instance->monitors, monitor_iter, next) {
3165 if (monitor_iter->interface->monitor_class == AST_CC_DEVICE_MONITOR) {
3166 if (monitor_iter->callbacks->suspend(monitor_iter)) {
3168 cc_extension_monitor_change_is_valid(core_instance, monitor_iter->parent_id,
3169 monitor_iter->interface->device_name, 1);
3170 cc_unref(monitor_iter, "suspend failed. Unref list's reference to monitor");
3171 }
3172 }
3173 }
3175
3176 if (!has_device_monitors(core_instance)) {
3177 ast_cc_failed(core_instance->core_id, "All device monitors failed to suspend CC");
3178 }
3179 AST_LIST_UNLOCK(core_instance->monitors);
3180}
3181
3182static int cc_caller_busy(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
3183{
3184 /* Callee was available, but caller was busy, call agent's begin_monitoring callback
3185 * and call monitor's suspend callback.
3186 */
3187 suspend(core_instance);
3188 core_instance->agent->callbacks->start_monitoring(core_instance->agent);
3189 cc_publish_callerstartmonitoring(core_instance->core_id, core_instance->agent->device_name);
3190 return 0;
3191}
3192
3193static void cancel_available_timer(struct cc_core_instance *core_instance)
3194{
3195 struct ast_cc_monitor *monitor_iter;
3196 AST_LIST_LOCK(core_instance->monitors);
3197 AST_LIST_TRAVERSE_SAFE_BEGIN(core_instance->monitors, monitor_iter, next) {
3198 if (monitor_iter->interface->monitor_class == AST_CC_DEVICE_MONITOR) {
3199 if (monitor_iter->callbacks->cancel_available_timer(monitor_iter, &monitor_iter->available_timer_id)) {
3201 cc_extension_monitor_change_is_valid(core_instance, monitor_iter->parent_id,
3202 monitor_iter->interface->device_name, 1);
3203 cc_unref(monitor_iter, "cancel_available_timer failed. Unref list's reference to monitor");
3204 }
3205 }
3206 }
3208
3209 if (!has_device_monitors(core_instance)) {
3210 ast_cc_failed(core_instance->core_id, "All device monitors failed to cancel their available timers");
3211 }
3212 AST_LIST_UNLOCK(core_instance->monitors);
3213}
3214
3215static int cc_recalling(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
3216{
3217 /* Both caller and callee are available, call agent's recall callback
3218 */
3219 cancel_available_timer(core_instance);
3220 cc_publish_callerrecalling(core_instance->core_id, core_instance->agent->device_name);
3221 return 0;
3222}
3223
3224static int cc_complete(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
3225{
3226 /* Recall has made progress, call agent and monitor destructor functions
3227 */
3228 cc_publish_recallcomplete(core_instance->core_id, core_instance->agent->device_name);
3229 ao2_t_unlink(cc_core_instances, core_instance, "Unlink core instance since CC recall has completed");
3230 return 0;
3231}
3232
3233static int cc_failed(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
3234{
3235 cc_publish_failure(core_instance->core_id, core_instance->agent->device_name, args->debug);
3236 ao2_t_unlink(cc_core_instances, core_instance, "Unlink core instance since CC failed");
3237 return 0;
3238}
3239
3240static int (* const state_change_funcs [])(struct cc_core_instance *, struct cc_state_change_args *, enum cc_state previous_state) = {
3244 [CC_ACTIVE] = cc_active,
3249 [CC_FAILED] = cc_failed,
3250};
3251
3252static int cc_do_state_change(void *datap)
3253{
3254 struct cc_state_change_args *args = datap;
3255 struct cc_core_instance *core_instance;
3256 enum cc_state previous_state;
3257 int res;
3258
3259 ast_log_dynamic_level(cc_logger_level, "Core %d: State change to %u requested. Reason: %s\n",
3260 args->core_id, args->state, args->debug);
3261
3262 core_instance = args->core_instance;
3263
3264 if (!is_state_change_valid(core_instance->current_state, args->state, core_instance->agent)) {
3265 ast_log_dynamic_level(cc_logger_level, "Core %d: Invalid state change requested. Cannot go from %s to %s\n",
3266 args->core_id, cc_state_to_string(core_instance->current_state), cc_state_to_string(args->state));
3267 if (args->state == CC_CALLER_REQUESTED) {
3268 /*
3269 * For out-of-order requests, we need to let the requester know that
3270 * we can't handle the request now.
3271 */
3272 core_instance->agent->callbacks->respond(core_instance->agent,
3274 }
3275 ast_free(args);
3276 cc_unref(core_instance, "Unref core instance from when it was found earlier");
3277 return -1;
3278 }
3279
3280 /* We can change to the new state now. */
3281 previous_state = core_instance->current_state;
3282 core_instance->current_state = args->state;
3283 res = state_change_funcs[core_instance->current_state](core_instance, args, previous_state);
3284
3285 /* If state change successful then notify any device state watchers of the change */
3286 if (!res && !strcmp(core_instance->agent->callbacks->type, "generic")) {
3287 ccss_notify_device_state_change(core_instance->agent->device_name, core_instance->current_state);
3288 }
3289
3290 ast_free(args);
3291 cc_unref(core_instance, "Unref since state change has completed"); /* From ao2_find */
3292 return res;
3293}
3294
3295static int cc_request_state_change(enum cc_state state, const int core_id, const char *debug, va_list ap)
3296{
3297 int res;
3298 int debuglen;
3299 char dummy[1];
3300 va_list aq;
3301 struct cc_core_instance *core_instance;
3302 struct cc_state_change_args *args;
3303 /* This initial call to vsnprintf is simply to find what the
3304 * size of the string needs to be
3305 */
3306 va_copy(aq, ap);
3307 /* We add 1 to the result since vsnprintf's return does not
3308 * include the terminating null byte
3309 */
3310 debuglen = vsnprintf(dummy, sizeof(dummy), debug, aq) + 1;
3311 va_end(aq);
3312
3313 if (!(args = ast_calloc(1, sizeof(*args) + debuglen))) {
3314 return -1;
3315 }
3316
3318 if (!core_instance) {
3319 ast_log_dynamic_level(cc_logger_level, "Core %d: Unable to find core instance.\n",
3320 core_id);
3321 ast_free(args);
3322 return -1;
3323 }
3324
3325 args->core_instance = core_instance;
3326 args->state = state;
3327 args->core_id = core_id;
3328 vsnprintf(args->debug, debuglen, debug, ap);
3329
3331 if (res) {
3332 cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed");
3333 ast_free(args);
3334 }
3335 return res;
3336}
3337
3343};
3344
3345static void *cc_recall_ds_duplicate(void *data)
3346{
3347 struct cc_recall_ds_data *old_data = data;
3348 struct cc_recall_ds_data *new_data = ast_calloc(1, sizeof(*new_data));
3349
3350 if (!new_data) {
3351 return NULL;
3352 }
3353 new_data->interface_tree = cc_ref(old_data->interface_tree, "Bump refcount of monitor tree for recall datastore duplicate");
3354 new_data->core_id = old_data->core_id;
3355 new_data->nested = 1;
3356 return new_data;
3357}
3358
3359static void cc_recall_ds_destroy(void *data)
3360{
3361 struct cc_recall_ds_data *recall_data = data;
3362 recall_data->interface_tree = cc_unref(recall_data->interface_tree, "Unref recall monitor tree");
3363 ast_free(recall_data);
3364}
3365
3366static const struct ast_datastore_info recall_ds_info = {
3367 .type = "cc_recall",
3368 .duplicate = cc_recall_ds_duplicate,
3369 .destroy = cc_recall_ds_destroy,
3370};
3371
3372int ast_setup_cc_recall_datastore(struct ast_channel *chan, const int core_id)
3373{
3374 struct ast_datastore *recall_datastore = ast_datastore_alloc(&recall_ds_info, NULL);
3375 struct cc_recall_ds_data *recall_data;
3376 struct cc_core_instance *core_instance;
3377
3378 if (!recall_datastore) {
3379 return -1;
3380 }
3381
3382 if (!(recall_data = ast_calloc(1, sizeof(*recall_data)))) {
3383 ast_datastore_free(recall_datastore);
3384 return -1;
3385 }
3386
3387 if (!(core_instance = find_cc_core_instance(core_id))) {
3388 ast_free(recall_data);
3389 ast_datastore_free(recall_datastore);
3390 return -1;
3391 }
3392
3393 recall_data->interface_tree = cc_ref(core_instance->monitors,
3394 "Bump refcount for monitor tree for recall datastore");
3395 recall_data->core_id = core_id;
3396 recall_datastore->data = recall_data;
3397 recall_datastore->inheritance = DATASTORE_INHERIT_FOREVER;
3398 ast_channel_lock(chan);
3399 ast_channel_datastore_add(chan, recall_datastore);
3400 ast_channel_unlock(chan);
3401 cc_unref(core_instance, "Recall datastore set up. No need for core_instance ref");
3402 return 0;
3403}
3404
3405int ast_cc_is_recall(struct ast_channel *chan, int *core_id, const char * const monitor_type)
3406{
3407 struct ast_datastore *recall_datastore;
3408 struct cc_recall_ds_data *recall_data;
3409 struct cc_monitor_tree *interface_tree;
3410 char device_name[AST_CHANNEL_NAME];
3411 struct ast_cc_monitor *device_monitor;
3412 int core_id_candidate;
3413
3415
3416 *core_id = -1;
3417
3418 ast_channel_lock(chan);
3419 if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
3420 /* Obviously not a recall if the datastore isn't present */
3421 ast_channel_unlock(chan);
3422 return 0;
3423 }
3424
3425 recall_data = recall_datastore->data;
3426
3427 if (recall_data->ignore) {
3428 /* Though this is a recall, the call to this particular interface is not part of the
3429 * recall either because this is a call forward or because this is not the first
3430 * invocation of Dial during this call
3431 */
3432 ast_channel_unlock(chan);
3433 return 0;
3434 }
3435
3436 if (!recall_data->nested) {
3437 /* If the nested flag is not set, then this means that
3438 * the channel passed to this function is the caller making
3439 * the recall. This means that we shouldn't look through
3440 * the monitor tree for the channel because it shouldn't be
3441 * there. However, this is a recall though, so return true.
3442 */
3443 *core_id = recall_data->core_id;
3444 ast_channel_unlock(chan);
3445 return 1;
3446 }
3447
3448 if (ast_strlen_zero(monitor_type)) {
3449 /* If someone passed a NULL or empty monitor type, then it is clear
3450 * the channel they passed in was an incoming channel, and so searching
3451 * the list of dialed interfaces is not going to be helpful. Just return
3452 * false immediately.
3453 */
3454 ast_channel_unlock(chan);
3455 return 0;
3456 }
3457
3458 interface_tree = recall_data->interface_tree;
3459 ast_channel_get_device_name(chan, device_name, sizeof(device_name));
3460 /* We grab the value of the recall_data->core_id so that we
3461 * can unlock the channel before we start looking through the
3462 * interface list. That way we don't have to worry about a possible
3463 * clash between the channel lock and the monitor tree lock.
3464 */
3465 core_id_candidate = recall_data->core_id;
3466 ast_channel_unlock(chan);
3467
3468 /*
3469 * Now we need to find out if the channel device name
3470 * is in the list of interfaces in the called tree.
3471 */
3472 AST_LIST_LOCK(interface_tree);
3473 AST_LIST_TRAVERSE(interface_tree, device_monitor, next) {
3474 if (!strcmp(device_monitor->interface->device_name, device_name) &&
3475 !strcmp(device_monitor->interface->monitor_type, monitor_type)) {
3476 /* BOOM! Device is in the tree! We have a winner! */
3477 *core_id = core_id_candidate;
3478 AST_LIST_UNLOCK(interface_tree);
3479 return 1;
3480 }
3481 }
3482 AST_LIST_UNLOCK(interface_tree);
3483 return 0;
3484}
3485
3486struct ast_cc_monitor *ast_cc_get_monitor_by_recall_core_id(const int core_id, const char * const device_name)
3487{
3488 struct cc_core_instance *core_instance = find_cc_core_instance(core_id);
3489 struct ast_cc_monitor *monitor_iter;
3490
3491 if (!core_instance) {
3492 return NULL;
3493 }
3494
3495 AST_LIST_LOCK(core_instance->monitors);
3496 AST_LIST_TRAVERSE(core_instance->monitors, monitor_iter, next) {
3497 if (!strcmp(monitor_iter->interface->device_name, device_name)) {
3498 /* Found a monitor. */
3499 cc_ref(monitor_iter, "Hand the requester of the monitor a reference");
3500 break;
3501 }
3502 }
3503 AST_LIST_UNLOCK(core_instance->monitors);
3504 cc_unref(core_instance, "Done with core instance ref in ast_cc_get_monitor_by_recall_core_id");
3505 return monitor_iter;
3506}
3507
3508/*!
3509 * \internal
3510 * \brief uniquely append a dialstring to our CC_INTERFACES chanvar string.
3511 *
3512 * We will only append a string if it has not already appeared in our channel
3513 * variable earlier. We ensure that we don't erroneously match substrings by
3514 * adding an ampersand to the end of our potential dialstring and searching for
3515 * it plus the ampersand in our variable.
3516 *
3517 * It's important to note that once we have built the full CC_INTERFACES string,
3518 * there will be an extra ampersand at the end which must be stripped off by
3519 * the caller of this function.
3520 *
3521 * \param str An ast_str holding what we will add to CC_INTERFACES
3522 * \param dialstring A new dialstring to add
3523 */
3524static void cc_unique_append(struct ast_str **str, const char *dialstring)
3525{
3526 char dialstring_search[AST_CHANNEL_NAME + 1];
3527
3529 /* No dialstring to append. */
3530 return;
3531 }
3532 snprintf(dialstring_search, sizeof(dialstring_search), "%s%c", dialstring, '&');
3533 if (strstr(ast_str_buffer(*str), dialstring_search)) {
3534 return;
3535 }
3536 ast_str_append(str, 0, "%s", dialstring_search);
3537}
3538
3539/*!
3540 * \internal
3541 * \brief Build the CC_INTERFACES channel variable
3542 *
3543 * The method used is to traverse the child dialstrings in the
3544 * passed-in extension monitor, adding any that have the is_valid
3545 * flag set. Then, traverse the monitors, finding all children
3546 * of the starting extension monitor and adding their dialstrings
3547 * as well.
3548 *
3549 * \param starting_point The extension monitor that is the parent to all
3550 * monitors whose dialstrings should be added to CC_INTERFACES
3551 * \param str Where we will store CC_INTERFACES
3552 */
3553static void build_cc_interfaces_chanvar(struct ast_cc_monitor *starting_point, struct ast_str **str)
3554{
3555 struct extension_monitor_pvt *extension_pvt;
3556 struct extension_child_dialstring *child_dialstring;
3557 struct ast_cc_monitor *monitor_iter = starting_point;
3558 int top_level_id = starting_point->id;
3559 size_t length;
3560
3561 /* Init to an empty string. */
3562 ast_str_truncate(*str, 0);
3563
3564 /* First we need to take all of the is_valid child_dialstrings from
3565 * the extension monitor we found and add them to the CC_INTERFACES
3566 * chanvar
3567 */
3568 extension_pvt = starting_point->private_data;
3569 AST_LIST_TRAVERSE(&extension_pvt->child_dialstrings, child_dialstring, next) {
3570 if (child_dialstring->is_valid) {
3571 cc_unique_append(str, child_dialstring->original_dialstring);
3572 }
3573 }
3574
3575 /* And now we get the dialstrings from each of the device monitors */
3576 while ((monitor_iter = AST_LIST_NEXT(monitor_iter, next))) {
3577 if (monitor_iter->parent_id == top_level_id) {
3578 cc_unique_append(str, monitor_iter->dialstring);
3579 }
3580 }
3581
3582 /* str will have an extra '&' tacked onto the end of it, so we need
3583 * to get rid of that.
3584 */
3585 length = ast_str_strlen(*str);
3586 if (length) {
3587 ast_str_truncate(*str, length - 1);
3588 }
3589 if (length <= 1) {
3590 /* Nothing to recall? This should not happen. */
3591 ast_log(LOG_ERROR, "CC_INTERFACES is empty. starting device_name:'%s'\n",
3592 starting_point->interface->device_name);
3593 }
3594}
3595
3597{
3598 struct ast_datastore *recall_datastore;
3599 struct cc_monitor_tree *interface_tree;
3600 struct ast_cc_monitor *monitor;
3601 struct cc_recall_ds_data *recall_data;
3602 struct ast_str *str = ast_str_create(64);
3603 int core_id;
3604
3605 if (!str) {
3606 return -1;
3607 }
3608
3609 ast_channel_lock(chan);
3610 if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
3611 ast_channel_unlock(chan);
3612 ast_free(str);
3613 return -1;
3614 }
3615 recall_data = recall_datastore->data;
3616 interface_tree = recall_data->interface_tree;
3617 core_id = recall_data->core_id;
3618 ast_channel_unlock(chan);
3619
3620 AST_LIST_LOCK(interface_tree);
3621 monitor = AST_LIST_FIRST(interface_tree);
3623 AST_LIST_UNLOCK(interface_tree);
3624
3625 pbx_builtin_setvar_helper(chan, "CC_INTERFACES", ast_str_buffer(str));
3626 ast_log_dynamic_level(cc_logger_level, "Core %d: CC_INTERFACES set to %s\n",
3627 core_id, ast_str_buffer(str));
3628
3629 ast_free(str);
3630 return 0;
3631}
3632
3633int ast_set_cc_interfaces_chanvar(struct ast_channel *chan, const char * const extension)
3634{
3635 struct ast_datastore *recall_datastore;
3636 struct cc_monitor_tree *interface_tree;
3637 struct ast_cc_monitor *monitor_iter;
3638 struct cc_recall_ds_data *recall_data;
3639 struct ast_str *str = ast_str_create(64);
3640 int core_id;
3641
3642 if (!str) {
3643 return -1;
3644 }
3645
3646 ast_channel_lock(chan);
3647 if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
3648 ast_channel_unlock(chan);
3649 ast_free(str);
3650 return -1;
3651 }
3652 recall_data = recall_datastore->data;
3653 interface_tree = recall_data->interface_tree;
3654 core_id = recall_data->core_id;
3655 ast_channel_unlock(chan);
3656
3657 AST_LIST_LOCK(interface_tree);
3658 AST_LIST_TRAVERSE(interface_tree, monitor_iter, next) {
3659 if (!strcmp(monitor_iter->interface->device_name, extension)) {
3660 break;
3661 }
3662 }
3663
3664 if (!monitor_iter) {
3665 /* We couldn't find this extension. This may be because
3666 * we have been directed into an unexpected extension because
3667 * the admin has changed a CC_INTERFACES variable at some point.
3668 */
3669 AST_LIST_UNLOCK(interface_tree);
3670 ast_free(str);
3671 return -1;
3672 }
3673
3674 build_cc_interfaces_chanvar(monitor_iter, &str);
3675 AST_LIST_UNLOCK(interface_tree);
3676
3677 pbx_builtin_setvar_helper(chan, "CC_INTERFACES", ast_str_buffer(str));
3678 ast_log_dynamic_level(cc_logger_level, "Core %d: CC_INTERFACES set to %s\n",
3679 core_id, ast_str_buffer(str));
3680
3681 ast_free(str);
3682 return 0;
3683}
3684
3685void ast_ignore_cc(struct ast_channel *chan)
3686{
3687 struct ast_datastore *cc_datastore;
3688 struct ast_datastore *cc_recall_datastore;
3689 struct dialed_cc_interfaces *cc_interfaces;
3690 struct cc_recall_ds_data *recall_cc_data;
3691
3692 ast_channel_lock(chan);
3693 if ((cc_datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL))) {
3694 cc_interfaces = cc_datastore->data;
3695 cc_interfaces->ignore = 1;
3696 }
3697
3698 if ((cc_recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
3699 recall_cc_data = cc_recall_datastore->data;
3700 recall_cc_data->ignore = 1;
3701 }
3702 ast_channel_unlock(chan);
3703}
3704
3705static __attribute__((format(printf, 2, 3))) int cc_offer(const int core_id, const char * const debug, ...)
3706{
3707 va_list ap;
3708 int res;
3709
3710 va_start(ap, debug);
3712 va_end(ap);
3713 return res;
3714}
3715
3716int ast_cc_offer(struct ast_channel *caller_chan)
3717{
3718 int core_id;
3719 int res = -1;
3720 struct ast_datastore *datastore;
3721 struct dialed_cc_interfaces *cc_interfaces;
3722 char cc_is_offerable;
3723
3724 ast_channel_lock(caller_chan);
3725 if (!(datastore = ast_channel_datastore_find(caller_chan, &dialed_cc_interfaces_info, NULL))) {
3726 ast_channel_unlock(caller_chan);
3727 return res;
3728 }
3729
3730 cc_interfaces = datastore->data;
3731 cc_is_offerable = cc_interfaces->is_original_caller;
3732 core_id = cc_interfaces->core_id;
3733 ast_channel_unlock(caller_chan);
3734
3735 if (cc_is_offerable) {
3736 res = cc_offer(core_id, "CC offered to caller %s", ast_channel_name(caller_chan));
3737 }
3738 return res;
3739}
3740
3741int ast_cc_agent_accept_request(int core_id, const char * const debug, ...)
3742{
3743 va_list ap;
3744 int res;
3745
3746 va_start(ap, debug);
3748 va_end(ap);
3749 return res;
3750}
3751
3752int ast_cc_monitor_request_acked(int core_id, const char * const debug, ...)
3753{
3754 va_list ap;
3755 int res;
3756
3757 va_start(ap, debug);
3759 va_end(ap);
3760 return res;
3761}
3762
3763int ast_cc_monitor_callee_available(const int core_id, const char * const debug, ...)
3764{
3765 va_list ap;
3766 int res;
3767
3768 va_start(ap, debug);
3770 va_end(ap);
3771 return res;
3772}
3773
3774int ast_cc_agent_caller_busy(int core_id, const char * debug, ...)
3775{
3776 va_list ap;
3777 int res;
3778
3779 va_start(ap, debug);
3781 va_end(ap);
3782 return res;
3783}
3784
3785int ast_cc_agent_caller_available(int core_id, const char * const debug, ...)
3786{
3787 va_list ap;
3788 int res;
3789
3790 va_start(ap, debug);
3792 va_end(ap);
3793 return res;
3794}
3795
3796int ast_cc_agent_recalling(int core_id, const char * const debug, ...)
3797{
3798 va_list ap;
3799 int res;
3800
3801 va_start(ap, debug);
3803 va_end(ap);
3804 return res;
3805}
3806
3807int ast_cc_completed(struct ast_channel *chan, const char * const debug, ...)
3808{
3809 struct ast_datastore *recall_datastore;
3810 struct cc_recall_ds_data *recall_data;
3811 int core_id;
3812 va_list ap;
3813 int res;
3814
3815 ast_channel_lock(chan);
3816 if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
3817 /* Silly! Why did you call this function if there's no recall DS? */
3818 ast_channel_unlock(chan);
3819 return -1;
3820 }
3821 recall_data = recall_datastore->data;
3822 if (recall_data->nested || recall_data->ignore) {
3823 /* If this is being called from a nested Dial, it is too
3824 * early to determine if the recall has actually completed.
3825 * The outermost dial is the only one with the authority to
3826 * declare the recall to be complete.
3827 *
3828 * Similarly, if this function has been called when the
3829 * recall has progressed beyond the first dial, this is not
3830 * a legitimate time to declare the recall to be done. In fact,
3831 * that should have been done already.
3832 */
3833 ast_channel_unlock(chan);
3834 return -1;
3835 }
3836 core_id = recall_data->core_id;
3837 ast_channel_unlock(chan);
3838 va_start(ap, debug);
3840 va_end(ap);
3841 return res;
3842}
3843
3844int ast_cc_failed(int core_id, const char * const debug, ...)
3845{
3846 va_list ap;
3847 int res;
3848
3849 va_start(ap, debug);
3851 va_end(ap);
3852 return res;
3853}
3854
3856 const char *device_name;
3857 char *debug;
3859};
3860
3861static int cc_monitor_failed(void *data)
3862{
3863 struct ast_cc_monitor_failure_data *failure_data = data;
3864 struct cc_core_instance *core_instance;
3865 struct ast_cc_monitor *monitor_iter;
3866
3867 core_instance = find_cc_core_instance(failure_data->core_id);
3868 if (!core_instance) {
3869 /* Core instance no longer exists or invalid core_id. */
3871 "Core %d: Could not find core instance for device %s '%s'\n",
3872 failure_data->core_id, failure_data->device_name, failure_data->debug);
3873 ast_free((char *) failure_data->device_name);
3874 ast_free((char *) failure_data->debug);
3875 ast_free(failure_data);
3876 return -1;
3877 }
3878
3879 AST_LIST_LOCK(core_instance->monitors);
3880 AST_LIST_TRAVERSE_SAFE_BEGIN(core_instance->monitors, monitor_iter, next) {
3881 if (monitor_iter->interface->monitor_class == AST_CC_DEVICE_MONITOR) {
3882 if (!strcmp(monitor_iter->interface->device_name, failure_data->device_name)) {
3884 cc_extension_monitor_change_is_valid(core_instance, monitor_iter->parent_id,
3885 monitor_iter->interface->device_name, 1);
3886 monitor_iter->callbacks->cancel_available_timer(monitor_iter, &monitor_iter->available_timer_id);
3887 cc_publish_monitorfailed(monitor_iter->core_id, monitor_iter->interface->device_name);
3888 cc_unref(monitor_iter, "Monitor reported failure. Unref list's reference.");
3889 }
3890 }
3891 }
3893
3894 if (!has_device_monitors(core_instance)) {
3895 ast_cc_failed(core_instance->core_id, "All monitors have failed\n");
3896 }
3897 AST_LIST_UNLOCK(core_instance->monitors);
3898 cc_unref(core_instance, "Finished with core_instance in cc_monitor_failed\n");
3899
3900 ast_free((char *) failure_data->device_name);
3901 ast_free((char *) failure_data->debug);
3902 ast_free(failure_data);
3903 return 0;
3904}
3905
3906int ast_cc_monitor_failed(int core_id, const char *const monitor_name, const char * const debug, ...)
3907{
3908 struct ast_cc_monitor_failure_data *failure_data;
3909 int res;
3910 va_list ap;
3911
3912 if (!(failure_data = ast_calloc(1, sizeof(*failure_data)))) {
3913 return -1;
3914 }
3915
3916 if (!(failure_data->device_name = ast_strdup(monitor_name))) {
3917 ast_free(failure_data);
3918 return -1;
3919 }
3920
3921 va_start(ap, debug);
3922 if (ast_vasprintf(&failure_data->debug, debug, ap) == -1) {
3923 va_end(ap);
3924 ast_free((char *)failure_data->device_name);
3925 ast_free(failure_data);
3926 return -1;
3927 }
3928 va_end(ap);
3929
3930 failure_data->core_id = core_id;
3931
3933 if (res) {
3934 ast_free((char *)failure_data->device_name);
3935 ast_free((char *)failure_data->debug);
3936 ast_free(failure_data);
3937 }
3938 return res;
3939}
3940
3941static int cc_status_request(void *data)
3942{
3943 struct cc_core_instance *core_instance= data;
3944 int res;
3945
3946 res = core_instance->agent->callbacks->status_request(core_instance->agent);
3947 cc_unref(core_instance, "Status request finished. Unref core instance");
3948 return res;
3949}
3950
3952{
3953 int res;
3954 struct cc_core_instance *core_instance = find_cc_core_instance(core_id);
3955
3956 if (!core_instance) {
3957 return -1;
3958 }
3959
3961 if (res) {
3962 cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed");
3963 }
3964 return res;
3965}
3966
3967static int cc_stop_ringing(void *data)
3968{
3969 struct cc_core_instance *core_instance = data;
3970 int res = 0;
3971
3972 if (core_instance->agent->callbacks->stop_ringing) {
3973 res = core_instance->agent->callbacks->stop_ringing(core_instance->agent);
3974 }
3975 /* If an agent is being asked to stop ringing, then he needs to be prepared if for
3976 * whatever reason he needs to be called back again. The proper state to be in to
3977 * detect such a circumstance is the CC_ACTIVE state.
3978 *
3979 * We get to this state using the slightly unintuitive method of calling
3980 * ast_cc_monitor_request_acked because it gets us to the proper state.
3981 */
3982 ast_cc_monitor_request_acked(core_instance->core_id, "Agent %s asked to stop ringing. Be prepared to be recalled again.",
3983 core_instance->agent->device_name);
3984 cc_unref(core_instance, "Stop ringing finished. Unref core_instance");
3985 return res;
3986}
3987
3989{
3990 int res;
3991 struct cc_core_instance *core_instance = find_cc_core_instance(core_id);
3992
3993 if (!core_instance) {
3994 return -1;
3995 }
3996
3998 if (res) {
3999 cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed");
4000 }
4001 return res;
4002}
4003
4004static int cc_party_b_free(void *data)
4005{
4006 struct cc_core_instance *core_instance = data;
4007 int res = 0;
4008
4009 if (core_instance->agent->callbacks->party_b_free) {
4010 res = core_instance->agent->callbacks->party_b_free(core_instance->agent);
4011 }
4012 cc_unref(core_instance, "Party B free finished. Unref core_instance");
4013 return res;
4014}
4015
4017{
4018 int res;
4019 struct cc_core_instance *core_instance = find_cc_core_instance(core_id);
4020
4021 if (!core_instance) {
4022 return -1;
4023 }
4024
4026 if (res) {
4027 cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed");
4028 }
4029 return res;
4030}
4031
4035};
4036
4037static int cc_status_response(void *data)
4038{
4039 struct cc_status_response_args *args = data;
4040 struct cc_core_instance *core_instance = args->core_instance;
4041 struct ast_cc_monitor *monitor_iter;
4042 enum ast_device_state devstate = args->devstate;
4043
4044 ast_free(args);
4045
4046 AST_LIST_LOCK(core_instance->monitors);
4047 AST_LIST_TRAVERSE(core_instance->monitors, monitor_iter, next) {
4048 if (monitor_iter->interface->monitor_class == AST_CC_DEVICE_MONITOR &&
4049 monitor_iter->callbacks->status_response) {
4050 monitor_iter->callbacks->status_response(monitor_iter, devstate);
4051 }
4052 }
4053 AST_LIST_UNLOCK(core_instance->monitors);
4054 cc_unref(core_instance, "Status response finished. Unref core instance");
4055 return 0;
4056}
4057
4059{
4061 struct cc_core_instance *core_instance;
4062 int res;
4063
4064 args = ast_calloc(1, sizeof(*args));
4065 if (!args) {
4066 return -1;
4067 }
4068
4069 core_instance = find_cc_core_instance(core_id);
4070 if (!core_instance) {
4071 ast_free(args);
4072 return -1;
4073 }
4074
4075 args->core_instance = core_instance;
4076 args->devstate = devstate;
4077
4079 if (res) {
4080 cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed");
4081 ast_free(args);
4082 }
4083 return res;
4084}
4085
4086static int cc_build_payload(struct ast_channel *chan, struct ast_cc_config_params *cc_params,
4087 const char *monitor_type, const char * const device_name, const char * dialstring,
4088 enum ast_cc_service_type service, void *private_data, struct cc_control_payload *payload)
4089{
4090 struct ast_datastore *datastore;
4091 struct dialed_cc_interfaces *cc_interfaces;
4092 int dial_parent_id;
4093
4094 ast_channel_lock(chan);
4096 if (!datastore) {
4097 ast_channel_unlock(chan);
4098 return -1;
4099 }
4100 cc_interfaces = datastore->data;
4101 dial_parent_id = cc_interfaces->dial_parent_id;
4102 ast_channel_unlock(chan);
4103
4104 payload->monitor_type = monitor_type;
4105 payload->private_data = private_data;
4106 payload->service = service;
4107 ast_cc_copy_config_params(&payload->config_params, cc_params);
4109 ast_copy_string(payload->device_name, device_name, sizeof(payload->device_name));
4110 ast_copy_string(payload->dialstring, dialstring, sizeof(payload->dialstring));
4111 return 0;
4112}
4113
4114int ast_queue_cc_frame(struct ast_channel *chan, const char *monitor_type,
4115 const char * const dialstring, enum ast_cc_service_type service, void *private_data)
4116{
4117 struct ast_frame frame = {0,};
4118 char device_name[AST_CHANNEL_NAME];
4119 int retval;
4120 struct ast_cc_config_params *cc_params;
4121
4122 cc_params = ast_channel_get_cc_config_params(chan);
4123 if (!cc_params) {
4124 return -1;
4125 }
4126 ast_channel_get_device_name(chan, device_name, sizeof(device_name));
4127 if (ast_cc_monitor_count(device_name, monitor_type) >= ast_get_cc_max_monitors(cc_params)) {
4128 ast_log(LOG_NOTICE, "Not queuing a CC frame for device %s since it already has its maximum monitors allocated\n", device_name);
4129 return -1;
4130 }
4131
4132 if (ast_cc_build_frame(chan, cc_params, monitor_type, device_name, dialstring, service, private_data, &frame)) {
4133 /* Frame building failed. We can't use this. */
4134 return -1;
4135 }
4136 retval = ast_queue_frame(chan, &frame);
4137 ast_frfree(&frame);
4138 return retval;
4139}
4140
4141int ast_cc_build_frame(struct ast_channel *chan, struct ast_cc_config_params *cc_params,
4142 const char *monitor_type, const char * const device_name,
4143 const char * const dialstring, enum ast_cc_service_type service, void *private_data,
4144 struct ast_frame *frame)
4145{
4146 struct cc_control_payload *payload = ast_calloc(1, sizeof(*payload));
4147
4148 if (!payload) {
4149 return -1;
4150 }
4151 if (cc_build_payload(chan, cc_params, monitor_type, device_name, dialstring, service, private_data, payload)) {
4152 /* Something screwed up, we can't make a frame with this */
4153 ast_free(payload);
4154 return -1;
4155 }
4158 frame->data.ptr = payload;
4159 frame->datalen = sizeof(*payload);
4160 frame->mallocd = AST_MALLOCD_DATA;
4161 return 0;
4162}
4163
4164void ast_cc_call_failed(struct ast_channel *incoming, struct ast_channel *outgoing, const char * const dialstring)
4165{
4167 struct cc_control_payload payload;
4168 struct ast_cc_config_params *cc_params;
4169
4171 /* It doesn't make sense to try to offer CCBS to the caller if the reason for ast_call
4172 * failing is something other than busy or congestion
4173 */
4174 return;
4175 }
4176
4178 if (!cc_params) {
4179 return;
4180 }
4182 /* This sort of CCBS only works if using generic CC. For native, we would end up sending
4183 * a CC request for a non-existent call. The far end will reject this every time
4184 */
4185 return;
4186 }
4187
4188 ast_channel_get_device_name(outgoing, device_name, sizeof(device_name));
4189 if (cc_build_payload(outgoing, cc_params, AST_CC_GENERIC_MONITOR_TYPE, device_name,
4190 dialstring, AST_CC_CCBS, NULL, &payload)) {
4191 /* Something screwed up, we can't make a frame with this */
4192 return;
4193 }
4194 ast_handle_cc_control_frame(incoming, outgoing, &payload);
4195}
4196
4197void ast_cc_busy_interface(struct ast_channel *inbound, struct ast_cc_config_params *cc_params,
4198 const char *monitor_type, const char * const device_name, const char * const dialstring, void *private_data)
4199{
4200 struct cc_control_payload payload;
4201 if (cc_build_payload(inbound, cc_params, monitor_type, device_name, dialstring, AST_CC_CCBS, private_data, &payload)) {
4202 /* Something screwed up. Don't try to handle this payload */
4204 return;
4205 }
4206 ast_handle_cc_control_frame(inbound, NULL, &payload);
4207}
4208
4209int ast_cc_callback(struct ast_channel *inbound, const char * const tech, const char * const dest, ast_cc_callback_fn callback)
4210{
4211 const struct ast_channel_tech *chantech = ast_get_channel_tech(tech);
4212
4213 if (chantech && chantech->cc_callback) {
4214 chantech->cc_callback(inbound, dest, callback);
4215 }
4216
4217 return 0;
4218}
4219
4220static const char *ccreq_app = "CallCompletionRequest";
4221
4222static int ccreq_exec(struct ast_channel *chan, const char *data)
4223{
4224 struct cc_core_instance *core_instance;
4225 char device_name[AST_CHANNEL_NAME];
4226 unsigned long match_flags;
4227 int res;
4228
4229 ast_channel_get_device_name(chan, device_name, sizeof(device_name));
4230
4232 if (!(core_instance = ao2_t_callback_data(cc_core_instances, 0, match_agent, device_name, &match_flags, "Find core instance for CallCompletionRequest"))) {
4233 ast_log_dynamic_level(cc_logger_level, "Couldn't find a core instance for caller %s\n", device_name);
4234 pbx_builtin_setvar_helper(chan, "CC_REQUEST_RESULT", "FAIL");
4235 pbx_builtin_setvar_helper(chan, "CC_REQUEST_REASON", "NO_CORE_INSTANCE");
4236 return 0;
4237 }
4238
4239 ast_log_dynamic_level(cc_logger_level, "Core %d: Found core_instance for caller %s\n",
4240 core_instance->core_id, device_name);
4241
4242 if (strcmp(core_instance->agent->callbacks->type, "generic")) {
4243 ast_log_dynamic_level(cc_logger_level, "Core %d: CallCompletionRequest is only for generic agent types.\n",
4244 core_instance->core_id);
4245 pbx_builtin_setvar_helper(chan, "CC_REQUEST_RESULT", "FAIL");
4246 pbx_builtin_setvar_helper(chan, "CC_REQUEST_REASON", "NOT_GENERIC");
4247 cc_unref(core_instance, "Unref core_instance since CallCompletionRequest was called with native agent");
4248 return 0;
4249 }
4250
4252 ast_log_dynamic_level(cc_logger_level, "Core %d: CallCompletionRequest failed. Too many requests in the system\n",
4253 core_instance->core_id);
4254 ast_cc_failed(core_instance->core_id, "Too many CC requests\n");
4255 pbx_builtin_setvar_helper(chan, "CC_REQUEST_RESULT", "FAIL");
4256 pbx_builtin_setvar_helper(chan, "CC_REQUEST_REASON", "TOO_MANY_REQUESTS");
4257 cc_unref(core_instance, "Unref core_instance since too many CC requests");
4258 return 0;
4259 }
4260
4261 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);
4262 pbx_builtin_setvar_helper(chan, "CC_REQUEST_RESULT", res ? "FAIL" : "SUCCESS");
4263 if (res) {
4264 pbx_builtin_setvar_helper(chan, "CC_REQUEST_REASON", "UNSPECIFIED");
4265 }
4266
4267 cc_unref(core_instance, "Done with CallCompletionRequest");
4268 return 0;
4269}
4270
4271static const char *cccancel_app = "CallCompletionCancel";
4272
4273static int cccancel_exec(struct ast_channel *chan, const char *data)
4274{
4275 struct cc_core_instance *core_instance;
4276 char device_name[AST_CHANNEL_NAME];
4277 unsigned long match_flags;
4278 int res;
4279
4280 ast_channel_get_device_name(chan, device_name, sizeof(device_name));
4281
4283 if (!(core_instance = ao2_t_callback_data(cc_core_instances, 0, match_agent, device_name, &match_flags, "Find core instance for CallCompletionCancel"))) {
4284 ast_log_dynamic_level(cc_logger_level, "Cannot find CC transaction to cancel for caller %s\n", device_name);
4285 pbx_builtin_setvar_helper(chan, "CC_CANCEL_RESULT", "FAIL");
4286 pbx_builtin_setvar_helper(chan, "CC_CANCEL_REASON", "NO_CORE_INSTANCE");
4287 return 0;
4288 }
4289
4290 if (strcmp(core_instance->agent->callbacks->type, "generic")) {
4291 ast_log(LOG_WARNING, "CallCompletionCancel may only be used for calles with a generic agent\n");
4292 cc_unref(core_instance, "Unref core instance found during CallCompletionCancel");
4293 pbx_builtin_setvar_helper(chan, "CC_CANCEL_RESULT", "FAIL");
4294 pbx_builtin_setvar_helper(chan, "CC_CANCEL_REASON", "NOT_GENERIC");
4295 return 0;
4296 }
4297 res = ast_cc_failed(core_instance->core_id, "Call completion request Cancelled for core ID %d by caller %s",
4298 core_instance->core_id, device_name);
4299 cc_unref(core_instance, "Unref core instance found during CallCompletionCancel");
4300 pbx_builtin_setvar_helper(chan, "CC_CANCEL_RESULT", res ? "FAIL" : "SUCCESS");
4301 if (res) {
4302 pbx_builtin_setvar_helper(chan, "CC_CANCEL_REASON", "UNSPECIFIED");
4303 }
4304 return 0;
4305}
4306
4308 const char *device_name;
4309 const char *monitor_type;
4311};
4312
4313static int count_monitors_cb(void *obj, void *arg, int flags)
4314{
4315 struct cc_core_instance *core_instance = obj;
4316 struct count_monitors_cb_data *cb_data = arg;
4317 const char *device_name = cb_data->device_name;
4318 const char *monitor_type = cb_data->monitor_type;
4319 struct ast_cc_monitor *monitor_iter;
4320
4321 AST_LIST_LOCK(core_instance->monitors);
4322 AST_LIST_TRAVERSE(core_instance->monitors, monitor_iter, next) {
4323 if (!strcmp(monitor_iter->interface->device_name, device_name) &&
4324 !strcmp(monitor_iter->interface->monitor_type, monitor_type)) {
4325 cb_data->count++;
4326 break;
4327 }
4328 }
4329 AST_LIST_UNLOCK(core_instance->monitors);
4330 return 0;
4331}
4332
4333int ast_cc_monitor_count(const char * const name, const char * const type)
4334{
4335 struct count_monitors_cb_data data = {.device_name = name, .monitor_type = type,};
4336
4337 ao2_t_callback(cc_core_instances, OBJ_NODATA, count_monitors_cb, &data, "Counting agents");
4338 ast_log_dynamic_level(cc_logger_level, "Counted %d monitors\n", data.count);
4339 return data.count;
4340}
4341
4343{
4344 struct ast_config *cc_config;
4345 const char *cc_max_requests_str;
4346 struct ast_flags config_flags = {0,};
4347 char *endptr;
4348
4349 cc_config = ast_config_load2("ccss.conf", "ccss", config_flags);
4350 if (!cc_config || cc_config == CONFIG_STATUS_FILEINVALID) {
4351 ast_log(LOG_WARNING, "Could not find valid ccss.conf file. Using cc_max_requests default\n");
4353 return;
4354 }
4355
4356 if (!(cc_max_requests_str = ast_variable_retrieve(cc_config, "general", "cc_max_requests"))) {
4357 ast_config_destroy(cc_config);
4359 return;
4360 }
4361
4362 global_cc_max_requests = strtol(cc_max_requests_str, &endptr, 10);
4363
4364 if (!ast_strlen_zero(endptr)) {
4365 ast_log(LOG_WARNING, "Invalid input given for cc_max_requests. Using default\n");
4367 }
4368
4369 ast_config_destroy(cc_config);
4370 return;
4371}
4372
4373/*!
4374 * \internal
4375 * \brief helper function to parse and configure each devstate map
4376 */
4377static void initialize_cc_devstate_map_helper(struct ast_config *cc_config, enum cc_state state, const char *cc_setting)
4378{
4379 const char *cc_devstate_str;
4380 enum ast_device_state this_devstate;
4381
4382 if ((cc_devstate_str = ast_variable_retrieve(cc_config, "general", cc_setting))) {
4383 this_devstate = ast_devstate_val(cc_devstate_str);
4384 if (this_devstate != AST_DEVICE_UNKNOWN) {
4385 cc_state_to_devstate_map[state] = this_devstate;
4386 }
4387 }
4388}
4389
4390/*!
4391 * \internal
4392 * \brief initializes cc_state_to_devstate_map from ccss.conf
4393 *
4394 * \details
4395 * The cc_state_to_devstate_map[] is already initialized with all the
4396 * default values. This will update that structure with any changes
4397 * from the ccss.conf file. The configuration parameters in ccss.conf
4398 * should use any valid device state form that is recognized by
4399 * ast_devstate_val() function.
4400 */
4402{
4403 struct ast_config *cc_config;
4404 struct ast_flags config_flags = { 0, };
4405
4406 cc_config = ast_config_load2("ccss.conf", "ccss", config_flags);
4407 if (!cc_config || cc_config == CONFIG_STATUS_FILEINVALID) {
4409 "Could not find valid ccss.conf file. Using cc_[state]_devstate defaults\n");
4410 return;
4411 }
4412
4413 initialize_cc_devstate_map_helper(cc_config, CC_AVAILABLE, "cc_available_devstate");
4414 initialize_cc_devstate_map_helper(cc_config, CC_CALLER_OFFERED, "cc_caller_offered_devstate");
4415 initialize_cc_devstate_map_helper(cc_config, CC_CALLER_REQUESTED, "cc_caller_requested_devstate");
4416 initialize_cc_devstate_map_helper(cc_config, CC_ACTIVE, "cc_active_devstate");
4417 initialize_cc_devstate_map_helper(cc_config, CC_CALLEE_READY, "cc_callee_ready_devstate");
4418 initialize_cc_devstate_map_helper(cc_config, CC_CALLER_BUSY, "cc_caller_busy_devstate");
4419 initialize_cc_devstate_map_helper(cc_config, CC_RECALLING, "cc_recalling_devstate");
4420 initialize_cc_devstate_map_helper(cc_config, CC_COMPLETE, "cc_complete_devstate");
4421 initialize_cc_devstate_map_helper(cc_config, CC_FAILED, "cc_failed_devstate");
4422
4423 ast_config_destroy(cc_config);
4424}
4425
4426static void cc_cli_print_monitor_stats(struct ast_cc_monitor *monitor, int fd, int parent_id)
4427{
4428 struct ast_cc_monitor