Wed Jan 8 2020 09:49:42

Asterisk developer's documentation


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