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