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