Mon Jun 18 2012 03:55:23

Asterisk developer's documentation


ccss.c
Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2010, Digium, Inc.
00005  *
00006  * Mark Michelson <mmichelson@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  * \brief Call Completion Supplementary Services implementation
00021  * \author Mark Michelson <mmichelson@digium.com>
00022  */
00023 
00024 #include "asterisk.h"
00025 
00026 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 357940 $")
00027 
00028 #include "asterisk/astobj2.h"
00029 #include "asterisk/strings.h"
00030 #include "asterisk/ccss.h"
00031 #include "asterisk/channel.h"
00032 #include "asterisk/pbx.h"
00033 #include "asterisk/utils.h"
00034 #include "asterisk/taskprocessor.h"
00035 #include "asterisk/event.h"
00036 #include "asterisk/module.h"
00037 #include "asterisk/app.h"
00038 #include "asterisk/cli.h"
00039 #include "asterisk/manager.h"
00040 #include "asterisk/causes.h"
00041 
00042 /*** DOCUMENTATION
00043    <application name="CallCompletionRequest" language="en_US">
00044       <synopsis>
00045          Request call completion service for previous call
00046       </synopsis>
00047       <syntax />
00048       <description>
00049          <para>Request call completion service for a previously failed
00050          call attempt.</para>
00051          <para>This application sets the following channel variables:</para>
00052          <variablelist>
00053             <variable name="CC_REQUEST_RESULT">
00054                <para>This is the returned status of the request.</para>
00055                <value name="SUCCESS" />
00056                <value name="FAIL" />
00057             </variable>
00058             <variable name="CC_REQUEST_REASON">
00059                <para>This is the reason the request failed.</para>
00060                <value name="NO_CORE_INSTANCE" />
00061                <value name="NOT_GENERIC" />
00062                <value name="TOO_MANY_REQUESTS" />
00063                <value name="UNSPECIFIED" />
00064             </variable>
00065          </variablelist>
00066       </description>
00067    </application>
00068    <application name="CallCompletionCancel" language="en_US">
00069       <synopsis>
00070          Cancel call completion service
00071       </synopsis>
00072       <syntax />
00073       <description>
00074          <para>Cancel a Call Completion Request.</para>
00075          <para>This application sets the following channel variables:</para>
00076          <variablelist>
00077             <variable name="CC_CANCEL_RESULT">
00078                <para>This is the returned status of the cancel.</para>
00079                <value name="SUCCESS" />
00080                <value name="FAIL" />
00081             </variable>
00082             <variable name="CC_CANCEL_REASON">
00083                <para>This is the reason the cancel failed.</para>
00084                <value name="NO_CORE_INSTANCE" />
00085                <value name="NOT_GENERIC" />
00086                <value name="UNSPECIFIED" />
00087             </variable>
00088          </variablelist>
00089       </description>
00090    </application>
00091  ***/
00092 
00093 /* These are some file-scoped variables. It would be
00094  * nice to define them closer to their first usage, but since
00095  * they are used in many places throughout the file, defining
00096  * them here at the top is easiest.
00097  */
00098 
00099 /*!
00100  * The sched_thread ID used for all generic CC timeouts
00101  */
00102 static struct ast_sched_thread *cc_sched_thread;
00103 /*!
00104  * Counter used to create core IDs for CC calls. Each new
00105  * core ID is created by atomically adding 1 to the core_id_counter
00106  */
00107 static int core_id_counter;
00108 /*!
00109  * Taskprocessor from which all CC agent and monitor callbacks
00110  * are called.
00111  */
00112 static struct ast_taskprocessor *cc_core_taskprocessor;
00113 /*!
00114  * Name printed on all CC log messages.
00115  */
00116 static const char *CC_LOGGER_LEVEL_NAME = "CC";
00117 /*!
00118  * Logger level registered by the CC core.
00119  */
00120 static int cc_logger_level;
00121 /*!
00122  * Parsed configuration value for cc_max_requests
00123  */
00124 static unsigned int global_cc_max_requests;
00125 /*!
00126  * The current number of CC requests in the system
00127  */
00128 static int cc_request_count;
00129 
00130 static inline void *cc_ref(void *obj, const char *debug)
00131 {
00132    ao2_t_ref(obj, +1, debug);
00133    return obj;
00134 }
00135 
00136 static inline void *cc_unref(void *obj, const char *debug)
00137 {
00138    ao2_t_ref(obj, -1, debug);
00139    return NULL;
00140 }
00141 
00142 /*!
00143  * \since 1.8
00144  * \internal
00145  * \brief A structure for holding the configuration parameters
00146  * relating to CCSS
00147  */
00148 struct ast_cc_config_params {
00149    enum ast_cc_agent_policies cc_agent_policy;
00150    enum ast_cc_monitor_policies cc_monitor_policy;
00151    unsigned int cc_offer_timer;
00152    unsigned int ccnr_available_timer;
00153    unsigned int ccbs_available_timer;
00154    unsigned int cc_recall_timer;
00155    unsigned int cc_max_agents;
00156    unsigned int cc_max_monitors;
00157    char cc_callback_macro[AST_MAX_EXTENSION];
00158    char cc_agent_dialstring[AST_MAX_EXTENSION];
00159 };
00160 
00161 /*!
00162  * \since 1.8
00163  * \brief The states used in the CCSS core state machine
00164  *
00165  * For more information, see doc/CCSS_architecture.pdf
00166  */
00167 enum cc_state {
00168    /*! Entered when it is determined that CCSS may be used for the call */
00169    CC_AVAILABLE,
00170    /*! Entered when a CCSS agent has offered CCSS to a caller */
00171    CC_CALLER_OFFERED,
00172    /*! Entered when a CCSS agent confirms that a caller has
00173     * requested CCSS */
00174    CC_CALLER_REQUESTED,
00175    /*! Entered when a CCSS monitor confirms acknowledgment of an
00176     * outbound CCSS request */
00177    CC_ACTIVE,
00178    /*! Entered when a CCSS monitor alerts the core that the called party
00179     * has become available */
00180    CC_CALLEE_READY,
00181    /*! Entered when a CCSS agent alerts the core that the calling party
00182     * may not be recalled because he is unavailable
00183     */
00184    CC_CALLER_BUSY,
00185    /*! Entered when a CCSS agent alerts the core that the calling party
00186     * is attempting to recall the called party
00187     */
00188    CC_RECALLING,
00189    /*! Entered when an application alerts the core that the calling party's
00190     * recall attempt has had a call progress response indicated
00191     */
00192    CC_COMPLETE,
00193    /*! Entered any time that something goes wrong during the process, thus
00194     * resulting in the failure of the attempted CCSS transaction. Note also
00195     * that cancellations of CC are treated as failures.
00196     */
00197    CC_FAILED,
00198 };
00199 
00200 /*!
00201  * \brief The payload for an AST_CONTROL_CC frame
00202  *
00203  * \details
00204  * This contains all the necessary data regarding
00205  * a called device so that the CC core will be able
00206  * to allocate the proper monitoring resources.
00207  */
00208 struct cc_control_payload {
00209    /*!
00210     * \brief The type of monitor to allocate.
00211     *
00212     * \details
00213     * The type of monitor to allocate. This is a string which corresponds
00214     * to a set of monitor callbacks registered. Examples include "generic"
00215     * and "SIP"
00216     *
00217     * \note This really should be an array of characters in case this payload
00218     * is sent accross an IAX2 link.  However, this would not make too much sense
00219     * given this type may not be recognized by the other end.
00220     * Protection may be necessary to prevent it from being transmitted.
00221     *
00222     * In addition the following other problems are also possible:
00223     * 1) Endian issues with the integers/enums stored in the config_params.
00224     * 2) Alignment padding issues for the element types.
00225     */
00226    const char *monitor_type;
00227    /*!
00228     * \brief Private data allocated by the callee
00229     *
00230     * \details
00231     * All channel drivers that monitor endpoints will need to allocate
00232     * data that is not usable by the CC core. In most cases, some or all
00233     * of this data is allocated at the time that the channel driver offers
00234     * CC to the caller. There are many opportunities for failures to occur
00235     * between when a channel driver offers CC and when a monitor is actually
00236     * allocated to watch the endpoint. For this reason, the channel driver
00237     * must give the core a pointer to the private data that was allocated so
00238     * that the core can call back into the channel driver to destroy it if
00239     * a failure occurs. If no private data has been allocated at the time that
00240     * CC is offered, then it is perfectly acceptable to pass NULL for this
00241     * field.
00242     */
00243    void *private_data;
00244    /*!
00245     * \brief Service offered by the endpoint
00246     *
00247     * \details
00248     * This indicates the type of call completion service offered by the
00249     * endpoint. This data is not crucial to the machinations of the CC core,
00250     * but it is helpful for debugging purposes.
00251     */
00252    enum ast_cc_service_type service;
00253    /*!
00254     * \brief Configuration parameters used by this endpoint
00255     *
00256     * \details
00257     * Each time an endpoint offers call completion, it must provide its call
00258     * completion configuration parameters. This is because settings may be different
00259     * depending on the circumstances.
00260     */
00261    struct ast_cc_config_params config_params;
00262    /*!
00263     * \brief ID of parent extension
00264     *
00265     * \details
00266     * This is the only datum that the CC core derives on its own and is not
00267     * provided by the offerer of CC. This provides the core with information on
00268     * which extension monitor is the most immediate parent of this device.
00269     */
00270    int parent_interface_id;
00271    /*!
00272     * \brief Name of device to be monitored
00273     *
00274     * \details
00275     * The device name by which this monitored endpoint will be referred in the
00276     * CC core. It is highly recommended that this device name is derived by using
00277     * the function ast_channel_get_device_name.
00278     */
00279    char device_name[AST_CHANNEL_NAME];
00280    /*!
00281     * \brief Recall dialstring
00282     *
00283     * \details
00284     * Certain channel drivers (DAHDI in particular) will require that a special
00285     * dialstring be used to indicate that the outgoing call is to interpreted as
00286     * a CC recall. If the channel driver has such a requirement, then this is
00287     * where that special recall dialstring is placed. If no special dialstring
00288     * is to be used, then the channel driver must provide the original dialstring
00289     * used to call this endpoint.
00290     */
00291    char dialstring[AST_CHANNEL_NAME];
00292 };
00293 
00294 /*!
00295  * \brief The "tree" of interfaces that is dialed.
00296  *
00297  * \details
00298  * Though this is a linked list, it is logically treated
00299  * as a tree of monitors. Each monitor has an id and a parent_id
00300  * associated with it. The id is a unique ID for that monitor, and
00301  * the parent_id is the unique ID of the monitor's parent in the
00302  * tree. The tree is structured such that all of a parent's children
00303  * will appear after the parent in the tree. However, it cannot be
00304  * guaranteed exactly where after the parent the children are.
00305  *
00306  * The tree is reference counted since several threads may need
00307  * to use it, and it may last beyond the lifetime of a single
00308  * thread.
00309  */
00310 AST_LIST_HEAD(cc_monitor_tree, ast_cc_monitor);
00311 
00312 static const int CC_CORE_INSTANCES_BUCKETS = 17;
00313 static struct ao2_container *cc_core_instances;
00314 
00315 struct cc_core_instance {
00316    /*!
00317     * Unique identifier for this instance of the CC core.
00318     */
00319    int core_id;
00320    /*!
00321     * The current state for this instance of the CC core.
00322     */
00323    enum cc_state current_state;
00324    /*!
00325     * The CC agent in use for this call
00326     */
00327    struct ast_cc_agent *agent;
00328    /*!
00329     * Reference to the monitor tree formed during the initial call
00330     */
00331    struct cc_monitor_tree *monitors;
00332 };
00333 
00334 /*!
00335  * \internal
00336  * \brief Request that the core change states
00337  * \param state The state to which we wish to change
00338  * \param core_id The unique identifier for this instance of the CCSS core state machine
00339  * \param debug Optional message explaining the reason for the state change
00340  * \param ap varargs list
00341  * \retval 0 State change successfully queued
00342  * \retval -1 Unable to queue state change request
00343  */
00344 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);
00345 
00346 /*!
00347  * \internal
00348  * \brief create a new instance of the CC core and an agent for the calling channel
00349  *
00350  * This function will check to make sure that the incoming channel
00351  * is allowed to request CC by making sure that the incoming channel
00352  * has not exceeded its maximum number of allowed agents.
00353  *
00354  * Should that check pass, the core instance is created, and then the
00355  * agent for the channel.
00356  *
00357  * \param caller_chan The incoming channel for this particular call
00358  * \param called_tree A reference to the tree of called devices. The agent
00359  * will gain a reference to this tree as well
00360  * \param core_id The core_id that this core_instance will assume
00361  * \retval NULL Failed to create the core instance either due to memory allocation
00362  * errors or due to the agent count for the caller being too high
00363  * \retval non-NULL A reference to the newly created cc_core_instance
00364  */
00365 static struct cc_core_instance *cc_core_init_instance(struct ast_channel *caller_chan,
00366       struct cc_monitor_tree *called_tree, const int core_id, struct cc_control_payload *cc_data);
00367 
00368 static const struct {
00369    enum ast_cc_service_type service;
00370    const char *service_string;
00371 } cc_service_to_string_map[] = {
00372    {AST_CC_NONE, "NONE"},
00373    {AST_CC_CCBS, "CCBS"},
00374    {AST_CC_CCNR, "CCNR"},
00375    {AST_CC_CCNL, "CCNL"},
00376 };
00377 
00378 static const struct {
00379    enum cc_state state;
00380    const char *state_string;
00381 } cc_state_to_string_map[] = {
00382    {CC_AVAILABLE,          "CC is available"},
00383    {CC_CALLER_OFFERED,     "CC offered to caller"},
00384    {CC_CALLER_REQUESTED,   "CC requested by caller"},
00385    {CC_ACTIVE,             "CC accepted by callee"},
00386    {CC_CALLEE_READY,       "Callee has become available"},
00387    {CC_CALLER_BUSY,        "Callee was ready, but caller is now unavailable"},
00388    {CC_RECALLING,          "Caller is attempting to recall"},
00389    {CC_COMPLETE,           "Recall complete"},
00390    {CC_FAILED,             "CC has failed"},
00391 };
00392 
00393 static const char *cc_state_to_string(enum cc_state state)
00394 {
00395    return cc_state_to_string_map[state].state_string;
00396 }
00397 
00398 static const char *cc_service_to_string(enum ast_cc_service_type service)
00399 {
00400    return cc_service_to_string_map[service].service_string;
00401 }
00402 
00403 static int cc_core_instance_hash_fn(const void *obj, const int flags)
00404 {
00405    const struct cc_core_instance *core_instance = obj;
00406    return core_instance->core_id;
00407 }
00408 
00409 static int cc_core_instance_cmp_fn(void *obj, void *arg, int flags)
00410 {
00411    struct cc_core_instance *core_instance1 = obj;
00412    struct cc_core_instance *core_instance2 = arg;
00413 
00414    return core_instance1->core_id == core_instance2->core_id ? CMP_MATCH | CMP_STOP : 0;
00415 }
00416 
00417 static struct cc_core_instance *find_cc_core_instance(const int core_id)
00418 {
00419    struct cc_core_instance finder = {.core_id = core_id,};
00420 
00421    return ao2_t_find(cc_core_instances, &finder, OBJ_POINTER, "Finding a core_instance");
00422 }
00423 
00424 struct cc_callback_helper {
00425    ao2_callback_fn *function;
00426    void *args;
00427    const char *type;
00428 };
00429 
00430 static int cc_agent_callback_helper(void *obj, void *args, int flags)
00431 {
00432    struct cc_core_instance *core_instance = obj;
00433    struct cc_callback_helper *helper = args;
00434 
00435    if (strcmp(core_instance->agent->callbacks->type, helper->type)) {
00436       return 0;
00437    }
00438 
00439    return helper->function(core_instance->agent, helper->args, flags);
00440 }
00441 
00442 struct ast_cc_agent *ast_cc_agent_callback(int flags, ao2_callback_fn *function, void *args, const char * const type)
00443 {
00444    struct cc_callback_helper helper = {.function = function, .args = args, .type = type};
00445    struct cc_core_instance *core_instance;
00446    if ((core_instance = ao2_t_callback(cc_core_instances, flags, cc_agent_callback_helper, &helper,
00447                "Calling provided agent callback function"))) {
00448       struct ast_cc_agent *agent = cc_ref(core_instance->agent, "An outside entity needs the agent");
00449       cc_unref(core_instance, "agent callback done with the core_instance");
00450       return agent;
00451    }
00452    return NULL;
00453 }
00454 
00455 enum match_flags {
00456    /* Only match agents that have not yet
00457     * made a CC request
00458     */
00459    MATCH_NO_REQUEST = (1 << 0),
00460    /* Only match agents that have made
00461     * a CC request
00462     */
00463    MATCH_REQUEST = (1 << 1),
00464 };
00465 
00466 /* ao2_callbacks for cc_core_instances */
00467 
00468 /*!
00469  * \internal
00470  * \brief find a core instance based on its agent
00471  *
00472  * The match flags tell whether we wish to find core instances
00473  * that have a monitor or core instances that do not. Core instances
00474  * with no monitor are core instances for which a caller has not yet
00475  * requested CC. Core instances with a monitor are ones for which the
00476  * caller has requested CC.
00477  */
00478 static int match_agent(void *obj, void *arg, void *data, int flags)
00479 {
00480    struct cc_core_instance *core_instance = obj;
00481    const char *name = arg;
00482    unsigned long match_flags = *(unsigned long *)data;
00483    int possible_match = 0;
00484 
00485    if ((match_flags & MATCH_NO_REQUEST) && core_instance->current_state < CC_CALLER_REQUESTED) {
00486       possible_match = 1;
00487    }
00488 
00489    if ((match_flags & MATCH_REQUEST) && core_instance->current_state >= CC_CALLER_REQUESTED) {
00490       possible_match = 1;
00491    }
00492 
00493    if (!possible_match) {
00494       return 0;
00495    }
00496 
00497    if (!strcmp(core_instance->agent->device_name, name)) {
00498       return CMP_MATCH | CMP_STOP;
00499    }
00500    return 0;
00501 }
00502 
00503 struct count_agents_cb_data {
00504    int count;
00505    int core_id_exception;
00506 };
00507 
00508 /*!
00509  * \internal
00510  * \brief Count the number of agents a specific interface is using
00511  *
00512  * We're only concerned with the number of agents that have requested
00513  * CC, so we restrict our search to core instances which have a non-NULL
00514  * monitor pointer
00515  */
00516 static int count_agents_cb(void *obj, void *arg, void *data, int flags)
00517 {
00518    struct cc_core_instance *core_instance = obj;
00519    const char *name = arg;
00520    struct count_agents_cb_data *cb_data = data;
00521 
00522    if (cb_data->core_id_exception == core_instance->core_id) {
00523       ast_log_dynamic_level(cc_logger_level, "Found agent with core_id %d but not counting it toward total\n", core_instance->core_id);
00524       return 0;
00525    }
00526 
00527    if (core_instance->current_state >= CC_CALLER_REQUESTED && !strcmp(core_instance->agent->device_name, name)) {
00528       cb_data->count++;
00529    }
00530    return 0;
00531 }
00532 
00533 #define CC_OFFER_TIMER_DEFAULT         20    /* Seconds */
00534 #define CCNR_AVAILABLE_TIMER_DEFAULT   7200  /* Seconds */
00535 #define CCBS_AVAILABLE_TIMER_DEFAULT   4800  /* Seconds */
00536 #define CC_RECALL_TIMER_DEFAULT        20    /* Seconds */
00537 #define CC_MAX_AGENTS_DEFAULT       5
00538 #define CC_MAX_MONITORS_DEFAULT        5
00539 #define GLOBAL_CC_MAX_REQUESTS_DEFAULT 20
00540 
00541 static const struct ast_cc_config_params cc_default_params = {
00542    .cc_agent_policy = AST_CC_AGENT_NEVER,
00543    .cc_monitor_policy = AST_CC_MONITOR_NEVER,
00544    .cc_offer_timer = CC_OFFER_TIMER_DEFAULT,
00545    .ccnr_available_timer = CCNR_AVAILABLE_TIMER_DEFAULT,
00546    .ccbs_available_timer = CCBS_AVAILABLE_TIMER_DEFAULT,
00547    .cc_recall_timer = CC_RECALL_TIMER_DEFAULT,
00548    .cc_max_agents = CC_MAX_AGENTS_DEFAULT,
00549    .cc_max_monitors = CC_MAX_MONITORS_DEFAULT,
00550    .cc_callback_macro = "",
00551    .cc_agent_dialstring = "",
00552 };
00553 
00554 void ast_cc_default_config_params(struct ast_cc_config_params *params)
00555 {
00556    *params = cc_default_params;
00557 }
00558 
00559 struct ast_cc_config_params *__ast_cc_config_params_init(const char *file, int line, const char *function)
00560 {
00561 #if defined(__AST_DEBUG_MALLOC)
00562    struct ast_cc_config_params *params = __ast_malloc(sizeof(*params), file, line, function);
00563 #else
00564    struct ast_cc_config_params *params = ast_malloc(sizeof(*params));
00565 #endif
00566 
00567    if (!params) {
00568       return NULL;
00569    }
00570 
00571    ast_cc_default_config_params(params);
00572    return params;
00573 }
00574 
00575 void ast_cc_config_params_destroy(struct ast_cc_config_params *params)
00576 {
00577    ast_free(params);
00578 }
00579 
00580 static enum ast_cc_agent_policies str_to_agent_policy(const char * const value)
00581 {
00582    if (!strcasecmp(value, "never")) {
00583       return AST_CC_AGENT_NEVER;
00584    } else if (!strcasecmp(value, "native")) {
00585       return AST_CC_AGENT_NATIVE;
00586    } else if (!strcasecmp(value, "generic")) {
00587       return AST_CC_AGENT_GENERIC;
00588    } else {
00589       ast_log(LOG_WARNING, "%s is an invalid value for cc_agent_policy. Switching to 'never'\n", value);
00590       return AST_CC_AGENT_NEVER;
00591    }
00592 }
00593 
00594 static enum ast_cc_monitor_policies str_to_monitor_policy(const char * const value)
00595 {
00596    if (!strcasecmp(value, "never")) {
00597       return AST_CC_MONITOR_NEVER;
00598    } else if (!strcasecmp(value, "native")) {
00599       return AST_CC_MONITOR_NATIVE;
00600    } else if (!strcasecmp(value, "generic")) {
00601       return AST_CC_MONITOR_GENERIC;
00602    } else if (!strcasecmp(value, "always")) {
00603       return AST_CC_MONITOR_ALWAYS;
00604    } else {
00605       ast_log(LOG_WARNING, "%s is an invalid value for cc_monitor_policy. Switching to 'never'\n", value);
00606       return AST_CC_MONITOR_NEVER;
00607    }
00608 }
00609 
00610 static const char *agent_policy_to_str(enum ast_cc_agent_policies policy)
00611 {
00612    switch (policy) {
00613    case AST_CC_AGENT_NEVER:
00614       return "never";
00615    case AST_CC_AGENT_NATIVE:
00616       return "native";
00617    case AST_CC_AGENT_GENERIC:
00618       return "generic";
00619    default:
00620       /* This should never happen... */
00621       return "";
00622    }
00623 }
00624 
00625 static const char *monitor_policy_to_str(enum ast_cc_monitor_policies policy)
00626 {
00627    switch (policy) {
00628    case AST_CC_MONITOR_NEVER:
00629       return "never";
00630    case AST_CC_MONITOR_NATIVE:
00631       return "native";
00632    case AST_CC_MONITOR_GENERIC:
00633       return "generic";
00634    case AST_CC_MONITOR_ALWAYS:
00635       return "always";
00636    default:
00637       /* This should never happen... */
00638       return "";
00639    }
00640 }
00641 int ast_cc_get_param(struct ast_cc_config_params *params, const char * const name,
00642       char *buf, size_t buf_len)
00643 {
00644    const char *value = NULL;
00645 
00646    if (!strcasecmp(name, "cc_callback_macro")) {
00647       value = ast_get_cc_callback_macro(params);
00648    } else if (!strcasecmp(name, "cc_agent_policy")) {
00649       value = agent_policy_to_str(ast_get_cc_agent_policy(params));
00650    } else if (!strcasecmp(name, "cc_monitor_policy")) {
00651       value = monitor_policy_to_str(ast_get_cc_monitor_policy(params));
00652    } else if (!strcasecmp(name, "cc_agent_dialstring")) {
00653       value = ast_get_cc_agent_dialstring(params);
00654    }
00655    if (value) {
00656       ast_copy_string(buf, value, buf_len);
00657       return 0;
00658    }
00659 
00660    /* The rest of these are all ints of some sort and require some
00661     * snprintf-itude
00662     */
00663 
00664    if (!strcasecmp(name, "cc_offer_timer")) {
00665       snprintf(buf, buf_len, "%u", ast_get_cc_offer_timer(params));
00666    } else if (!strcasecmp(name, "ccnr_available_timer")) {
00667       snprintf(buf, buf_len, "%u", ast_get_ccnr_available_timer(params));
00668    } else if (!strcasecmp(name, "ccbs_available_timer")) {
00669       snprintf(buf, buf_len, "%u", ast_get_ccbs_available_timer(params));
00670    } else if (!strcasecmp(name, "cc_max_agents")) {
00671       snprintf(buf, buf_len, "%u", ast_get_cc_max_agents(params));
00672    } else if (!strcasecmp(name, "cc_max_monitors")) {
00673       snprintf(buf, buf_len, "%u", ast_get_cc_max_monitors(params));
00674    } else if (!strcasecmp(name, "cc_recall_timer")) {
00675       snprintf(buf, buf_len, "%u", ast_get_cc_recall_timer(params));
00676    } else {
00677       ast_log(LOG_WARNING, "%s is not a valid CC parameter. Ignoring.\n", name);
00678       return -1;
00679    }
00680 
00681    return 0;
00682 }
00683 
00684 int ast_cc_set_param(struct ast_cc_config_params *params, const char * const name,
00685       const char * const value)
00686 {
00687    unsigned int value_as_uint;
00688    if (!strcasecmp(name, "cc_agent_policy")) {
00689       return ast_set_cc_agent_policy(params, str_to_agent_policy(value));
00690    } else if (!strcasecmp(name, "cc_monitor_policy")) {
00691       return ast_set_cc_monitor_policy(params, str_to_monitor_policy(value));
00692    } else if (!strcasecmp(name, "cc_agent_dialstring")) {
00693       ast_set_cc_agent_dialstring(params, value);
00694    } else if (!strcasecmp(name, "cc_callback_macro")) {
00695       ast_set_cc_callback_macro(params, value);
00696       return 0;
00697    }
00698 
00699    if (!sscanf(value, "%30u", &value_as_uint) == 1) {
00700       return -1;
00701    }
00702 
00703    if (!strcasecmp(name, "cc_offer_timer")) {
00704       ast_set_cc_offer_timer(params, value_as_uint);
00705    } else if (!strcasecmp(name, "ccnr_available_timer")) {
00706       ast_set_ccnr_available_timer(params, value_as_uint);
00707    } else if (!strcasecmp(name, "ccbs_available_timer")) {
00708       ast_set_ccbs_available_timer(params, value_as_uint);
00709    } else if (!strcasecmp(name, "cc_max_agents")) {
00710       ast_set_cc_max_agents(params, value_as_uint);
00711    } else if (!strcasecmp(name, "cc_max_monitors")) {
00712       ast_set_cc_max_monitors(params, value_as_uint);
00713    } else if (!strcasecmp(name, "cc_recall_timer")) {
00714       ast_set_cc_recall_timer(params, value_as_uint);
00715    } else {
00716       ast_log(LOG_WARNING, "%s is not a valid CC parameter. Ignoring.\n", name);
00717       return -1;
00718    }
00719 
00720    return 0;
00721 }
00722 
00723 int ast_cc_is_config_param(const char * const name)
00724 {
00725    return (!strcasecmp(name, "cc_agent_policy") ||
00726             !strcasecmp(name, "cc_monitor_policy") ||
00727             !strcasecmp(name, "cc_offer_timer") ||
00728             !strcasecmp(name, "ccnr_available_timer") ||
00729             !strcasecmp(name, "ccbs_available_timer") ||
00730             !strcasecmp(name, "cc_max_agents") ||
00731             !strcasecmp(name, "cc_max_monitors") ||
00732             !strcasecmp(name, "cc_callback_macro") ||
00733             !strcasecmp(name, "cc_agent_dialstring") ||
00734             !strcasecmp(name, "cc_recall_timer"));
00735 }
00736 
00737 void ast_cc_copy_config_params(struct ast_cc_config_params *dest, const struct ast_cc_config_params *src)
00738 {
00739    *dest = *src;
00740 }
00741 
00742 enum ast_cc_agent_policies ast_get_cc_agent_policy(struct ast_cc_config_params *config)
00743 {
00744    return config->cc_agent_policy;
00745 }
00746 
00747 int ast_set_cc_agent_policy(struct ast_cc_config_params *config, enum ast_cc_agent_policies value)
00748 {
00749    /* Screw C and its weak type checking for making me have to do this
00750     * validation at runtime.
00751     */
00752    if (value < AST_CC_AGENT_NEVER || value > AST_CC_AGENT_GENERIC) {
00753       return -1;
00754    }
00755    config->cc_agent_policy = value;
00756    return 0;
00757 }
00758 
00759 enum ast_cc_monitor_policies ast_get_cc_monitor_policy(struct ast_cc_config_params *config)
00760 {
00761    return config->cc_monitor_policy;
00762 }
00763 
00764 int ast_set_cc_monitor_policy(struct ast_cc_config_params *config, enum ast_cc_monitor_policies value)
00765 {
00766    /* Screw C and its weak type checking for making me have to do this
00767     * validation at runtime.
00768     */
00769    if (value < AST_CC_MONITOR_NEVER || value > AST_CC_MONITOR_ALWAYS) {
00770       return -1;
00771    }
00772    config->cc_monitor_policy = value;
00773    return 0;
00774 }
00775 
00776 unsigned int ast_get_cc_offer_timer(struct ast_cc_config_params *config)
00777 {
00778    return config->cc_offer_timer;
00779 }
00780 
00781 void ast_set_cc_offer_timer(struct ast_cc_config_params *config, unsigned int value)
00782 {
00783    /* 0 is an unreasonable value for any timer. Stick with the default */
00784    if (value == 0) {
00785       ast_log(LOG_WARNING, "0 is an invalid value for cc_offer_timer. Retaining value as %u\n", config->cc_offer_timer);
00786       return;
00787    }
00788    config->cc_offer_timer = value;
00789 }
00790 
00791 unsigned int ast_get_ccnr_available_timer(struct ast_cc_config_params *config)
00792 {
00793    return config->ccnr_available_timer;
00794 }
00795 
00796 void ast_set_ccnr_available_timer(struct ast_cc_config_params *config, unsigned int value)
00797 {
00798    /* 0 is an unreasonable value for any timer. Stick with the default */
00799    if (value == 0) {
00800       ast_log(LOG_WARNING, "0 is an invalid value for ccnr_available_timer. Retaining value as %u\n", config->ccnr_available_timer);
00801       return;
00802    }
00803    config->ccnr_available_timer = value;
00804 }
00805 
00806 unsigned int ast_get_cc_recall_timer(struct ast_cc_config_params *config)
00807 {
00808    return config->cc_recall_timer;
00809 }
00810 
00811 void ast_set_cc_recall_timer(struct ast_cc_config_params *config, unsigned int value)
00812 {
00813    /* 0 is an unreasonable value for any timer. Stick with the default */
00814    if (value == 0) {
00815       ast_log(LOG_WARNING, "0 is an invalid value for ccnr_available_timer. Retaining value as %u\n", config->cc_recall_timer);
00816       return;
00817    }
00818    config->cc_recall_timer = value;
00819 }
00820 
00821 unsigned int ast_get_ccbs_available_timer(struct ast_cc_config_params *config)
00822 {
00823    return config->ccbs_available_timer;
00824 }
00825 
00826 void ast_set_ccbs_available_timer(struct ast_cc_config_params *config, unsigned int value)
00827 {
00828    /* 0 is an unreasonable value for any timer. Stick with the default */
00829    if (value == 0) {
00830       ast_log(LOG_WARNING, "0 is an invalid value for ccbs_available_timer. Retaining value as %u\n", config->ccbs_available_timer);
00831       return;
00832    }
00833    config->ccbs_available_timer = value;
00834 }
00835 
00836 const char *ast_get_cc_agent_dialstring(struct ast_cc_config_params *config)
00837 {
00838    return config->cc_agent_dialstring;
00839 }
00840 
00841 void ast_set_cc_agent_dialstring(struct ast_cc_config_params *config, const char *const value)
00842 {
00843    if (ast_strlen_zero(value)) {
00844       config->cc_agent_dialstring[0] = '\0';
00845    } else {
00846       ast_copy_string(config->cc_agent_dialstring, value, sizeof(config->cc_agent_dialstring));
00847    }
00848 }
00849 
00850 unsigned int ast_get_cc_max_agents(struct ast_cc_config_params *config)
00851 {
00852    return config->cc_max_agents;
00853 }
00854 
00855 void ast_set_cc_max_agents(struct ast_cc_config_params *config, unsigned int value)
00856 {
00857    config->cc_max_agents = value;
00858 }
00859 
00860 unsigned int ast_get_cc_max_monitors(struct ast_cc_config_params *config)
00861 {
00862    return config->cc_max_monitors;
00863 }
00864 
00865 void ast_set_cc_max_monitors(struct ast_cc_config_params *config, unsigned int value)
00866 {
00867    config->cc_max_monitors = value;
00868 }
00869 
00870 const char *ast_get_cc_callback_macro(struct ast_cc_config_params *config)
00871 {
00872    return config->cc_callback_macro;
00873 }
00874 
00875 void ast_set_cc_callback_macro(struct ast_cc_config_params *config, const char * const value)
00876 {
00877    if (ast_strlen_zero(value)) {
00878       config->cc_callback_macro[0] = '\0';
00879    } else {
00880       ast_copy_string(config->cc_callback_macro, value, sizeof(config->cc_callback_macro));
00881    }
00882 }
00883 
00884 struct cc_monitor_backend {
00885    AST_LIST_ENTRY(cc_monitor_backend) next;
00886    const struct ast_cc_monitor_callbacks *callbacks;
00887 };
00888 
00889 AST_RWLIST_HEAD_STATIC(cc_monitor_backends, cc_monitor_backend);
00890 
00891 int ast_cc_monitor_register(const struct ast_cc_monitor_callbacks *callbacks)
00892 {
00893    struct cc_monitor_backend *backend = ast_calloc(1, sizeof(*backend));
00894 
00895    if (!backend) {
00896       return -1;
00897    }
00898 
00899    backend->callbacks = callbacks;
00900 
00901    AST_RWLIST_WRLOCK(&cc_monitor_backends);
00902    AST_RWLIST_INSERT_TAIL(&cc_monitor_backends, backend, next);
00903    AST_RWLIST_UNLOCK(&cc_monitor_backends);
00904    return 0;
00905 }
00906 
00907 static const struct ast_cc_monitor_callbacks *find_monitor_callbacks(const char * const type)
00908 {
00909    struct cc_monitor_backend *backend;
00910    const struct ast_cc_monitor_callbacks *callbacks = NULL;
00911 
00912    AST_RWLIST_RDLOCK(&cc_monitor_backends);
00913    AST_RWLIST_TRAVERSE(&cc_monitor_backends, backend, next) {
00914       if (!strcmp(backend->callbacks->type, type)) {
00915          ast_log_dynamic_level(cc_logger_level, "Returning monitor backend %s\n", backend->callbacks->type);
00916          callbacks = backend->callbacks;
00917          break;
00918       }
00919    }
00920    AST_RWLIST_UNLOCK(&cc_monitor_backends);
00921    return callbacks;
00922 }
00923 
00924 void ast_cc_monitor_unregister(const struct ast_cc_monitor_callbacks *callbacks)
00925 {
00926    struct cc_monitor_backend *backend;
00927    AST_RWLIST_WRLOCK(&cc_monitor_backends);
00928    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&cc_monitor_backends, backend, next) {
00929       if (backend->callbacks == callbacks) {
00930          AST_RWLIST_REMOVE_CURRENT(next);
00931          ast_free(backend);
00932          break;
00933       }
00934    }
00935    AST_RWLIST_TRAVERSE_SAFE_END;
00936    AST_RWLIST_UNLOCK(&cc_monitor_backends);
00937 }
00938 
00939 struct cc_agent_backend {
00940    AST_LIST_ENTRY(cc_agent_backend) next;
00941    const struct ast_cc_agent_callbacks *callbacks;
00942 };
00943 
00944 AST_RWLIST_HEAD_STATIC(cc_agent_backends, cc_agent_backend);
00945 
00946 int ast_cc_agent_register(const struct ast_cc_agent_callbacks *callbacks)
00947 {
00948    struct cc_agent_backend *backend = ast_calloc(1, sizeof(*backend));
00949 
00950    if (!backend) {
00951       return -1;
00952    }
00953 
00954    backend->callbacks = callbacks;
00955    AST_RWLIST_WRLOCK(&cc_agent_backends);
00956    AST_RWLIST_INSERT_TAIL(&cc_agent_backends, backend, next);
00957    AST_RWLIST_UNLOCK(&cc_agent_backends);
00958    return 0;
00959 }
00960 
00961 void ast_cc_agent_unregister(const struct ast_cc_agent_callbacks *callbacks)
00962 {
00963    struct cc_agent_backend *backend;
00964    AST_RWLIST_WRLOCK(&cc_agent_backends);
00965    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&cc_agent_backends, backend, next) {
00966       if (backend->callbacks == callbacks) {
00967          AST_RWLIST_REMOVE_CURRENT(next);
00968          ast_free(backend);
00969          break;
00970       }
00971    }
00972    AST_RWLIST_TRAVERSE_SAFE_END;
00973    AST_RWLIST_UNLOCK(&cc_agent_backends);
00974 }
00975 
00976 static const struct ast_cc_agent_callbacks *find_agent_callbacks(struct ast_channel *chan)
00977 {
00978    struct cc_agent_backend *backend;
00979    const struct ast_cc_agent_callbacks *callbacks = NULL;
00980    struct ast_cc_config_params *cc_params;
00981    char type[32];
00982 
00983    cc_params = ast_channel_get_cc_config_params(chan);
00984    if (!cc_params) {
00985       return NULL;
00986    }
00987    switch (ast_get_cc_agent_policy(cc_params)) {
00988    case AST_CC_AGENT_GENERIC:
00989       ast_copy_string(type, "generic", sizeof(type));
00990       break;
00991    case AST_CC_AGENT_NATIVE:
00992       ast_channel_get_cc_agent_type(chan, type, sizeof(type));
00993       break;
00994    default:
00995       ast_log_dynamic_level(cc_logger_level, "Not returning agent callbacks since this channel is configured not to have a CC agent\n");
00996       return NULL;
00997    }
00998 
00999    AST_RWLIST_RDLOCK(&cc_agent_backends);
01000    AST_RWLIST_TRAVERSE(&cc_agent_backends, backend, next) {
01001       if (!strcmp(backend->callbacks->type, type)) {
01002          ast_log_dynamic_level(cc_logger_level, "Returning agent backend %s\n", backend->callbacks->type);
01003          callbacks = backend->callbacks;
01004          break;
01005       }
01006    }
01007    AST_RWLIST_UNLOCK(&cc_agent_backends);
01008    return callbacks;
01009 }
01010 
01011 /*!
01012  * \internal
01013  * \brief Determine if the given device state is considered available by generic CCSS.
01014  * \since 1.8
01015  *
01016  * \param state Device state to test.
01017  *
01018  * \return TRUE if the given device state is considered available by generic CCSS.
01019  */
01020 static int cc_generic_is_device_available(enum ast_device_state state)
01021 {
01022    return state == AST_DEVICE_NOT_INUSE || state == AST_DEVICE_UNKNOWN;
01023 }
01024 
01025 static int cc_generic_monitor_request_cc(struct ast_cc_monitor *monitor, int *available_timer_id);
01026 static int cc_generic_monitor_suspend(struct ast_cc_monitor *monitor);
01027 static int cc_generic_monitor_unsuspend(struct ast_cc_monitor *monitor);
01028 static int cc_generic_monitor_cancel_available_timer(struct ast_cc_monitor *monitor, int *sched_id);
01029 static void cc_generic_monitor_destructor(void *private_data);
01030 
01031 static struct ast_cc_monitor_callbacks generic_monitor_cbs = {
01032    .type = "generic",
01033    .request_cc = cc_generic_monitor_request_cc,
01034    .suspend = cc_generic_monitor_suspend,
01035    .unsuspend = cc_generic_monitor_unsuspend,
01036    .cancel_available_timer = cc_generic_monitor_cancel_available_timer,
01037    .destructor = cc_generic_monitor_destructor,
01038 };
01039 
01040 struct ao2_container *generic_monitors;
01041 
01042 struct generic_monitor_instance {
01043    int core_id;
01044    int is_suspended;
01045    int monitoring;
01046    AST_LIST_ENTRY(generic_monitor_instance) next;
01047 };
01048 
01049 struct generic_monitor_instance_list {
01050    const char *device_name;
01051    enum ast_device_state current_state;
01052    /* If there are multiple instances monitoring the
01053     * same device and one should fail, we need to know
01054     * whether to signal that the device can be recalled.
01055     * The problem is that the device state is not enough
01056     * to check. If a caller has requested CCNR, then the
01057     * fact that the device is available does not indicate
01058     * that the device is ready to be recalled. Instead, as
01059     * soon as one instance of the monitor becomes available
01060     * for a recall, we mark the entire list as being fit
01061     * for recall. If a CCNR request comes in, then we will
01062     * have to mark the list as unfit for recall since this
01063     * is a clear indicator that the person at the monitored
01064     * device has gone away and is actuall not fit to be
01065     * recalled
01066     */
01067    int fit_for_recall;
01068    struct ast_event_sub *sub;
01069    AST_LIST_HEAD_NOLOCK(, generic_monitor_instance) list;
01070 };
01071 
01072 /*!
01073  * \brief private data for generic device monitor
01074  */
01075 struct generic_monitor_pvt {
01076    /*!
01077     * We need the device name during destruction so we
01078     * can find the appropriate item to destroy.
01079     */
01080    const char *device_name;
01081    /*!
01082     * We need the core ID for similar reasons. Once we
01083     * find the appropriate item in our ao2_container, we
01084     * need to remove the appropriate cc_monitor from the
01085     * list of monitors.
01086     */
01087    int core_id;
01088 };
01089 
01090 static int generic_monitor_hash_fn(const void *obj, const int flags)
01091 {
01092    const struct generic_monitor_instance_list *generic_list = obj;
01093    return ast_str_hash(generic_list->device_name);
01094 }
01095 
01096 static int generic_monitor_cmp_fn(void *obj, void *arg, int flags)
01097 {
01098    const struct generic_monitor_instance_list *generic_list1 = obj;
01099    const struct generic_monitor_instance_list *generic_list2 = arg;
01100 
01101    return !strcmp(generic_list1->device_name, generic_list2->device_name) ? CMP_MATCH | CMP_STOP : 0;
01102 }
01103 
01104 static struct generic_monitor_instance_list *find_generic_monitor_instance_list(const char * const device_name)
01105 {
01106    struct generic_monitor_instance_list finder = {0};
01107    char *uppertech = ast_strdupa(device_name);
01108    ast_tech_to_upper(uppertech);
01109    finder.device_name = uppertech;
01110 
01111    return ao2_t_find(generic_monitors, &finder, OBJ_POINTER, "Finding generic monitor instance list");
01112 }
01113 
01114 static void generic_monitor_instance_list_destructor(void *obj)
01115 {
01116    struct generic_monitor_instance_list *generic_list = obj;
01117    struct generic_monitor_instance *generic_instance;
01118 
01119    generic_list->sub = ast_event_unsubscribe(generic_list->sub);
01120    while ((generic_instance = AST_LIST_REMOVE_HEAD(&generic_list->list, next))) {
01121       ast_free(generic_instance);
01122    }
01123    ast_free((char *)generic_list->device_name);
01124 }
01125 
01126 static void generic_monitor_devstate_cb(const struct ast_event *event, void *userdata);
01127 static struct generic_monitor_instance_list *create_new_generic_list(struct ast_cc_monitor *monitor)
01128 {
01129    struct generic_monitor_instance_list *generic_list = ao2_t_alloc(sizeof(*generic_list),
01130          generic_monitor_instance_list_destructor, "allocate generic monitor instance list");
01131    char * device_name;
01132 
01133    if (!generic_list) {
01134       return NULL;
01135    }
01136 
01137    if (!(device_name = ast_strdup(monitor->interface->device_name))) {
01138       cc_unref(generic_list, "Failed to strdup the monitor's device name");
01139       return NULL;
01140    }
01141    ast_tech_to_upper(device_name);
01142    generic_list->device_name = device_name;
01143 
01144    if (!(generic_list->sub = ast_event_subscribe(AST_EVENT_DEVICE_STATE,
01145       generic_monitor_devstate_cb, "Requesting CC", NULL,
01146       AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, monitor->interface->device_name,
01147       AST_EVENT_IE_STATE, AST_EVENT_IE_PLTYPE_EXISTS,
01148       AST_EVENT_IE_END))) {
01149       cc_unref(generic_list, "Failed to subscribe to device state");
01150       return NULL;
01151    }
01152    generic_list->current_state = ast_device_state(monitor->interface->device_name);
01153    ao2_t_link(generic_monitors, generic_list, "linking new generic monitor instance list");
01154    return generic_list;
01155 }
01156 
01157 struct generic_tp_cb_data {
01158    const char *device_name;
01159    enum ast_device_state new_state;
01160 };
01161 
01162 static int generic_monitor_devstate_tp_cb(void *data)
01163 {
01164    struct generic_tp_cb_data *gtcd = data;
01165    enum ast_device_state new_state = gtcd->new_state;
01166    enum ast_device_state previous_state = gtcd->new_state;
01167    const char *monitor_name = gtcd->device_name;
01168    struct generic_monitor_instance_list *generic_list;
01169    struct generic_monitor_instance *generic_instance;
01170 
01171    if (!(generic_list = find_generic_monitor_instance_list(monitor_name))) {
01172       /* The most likely cause for this is that we destroyed the monitor in the
01173        * time between subscribing to its device state and the time this executes.
01174        * Not really a big deal.
01175        */
01176       ast_free((char *) gtcd->device_name);
01177       ast_free(gtcd);
01178       return 0;
01179    }
01180 
01181    if (generic_list->current_state == new_state) {
01182       /* The device state hasn't actually changed, so we don't really care */
01183       cc_unref(generic_list, "Kill reference of generic list in devstate taskprocessor callback");
01184       ast_free((char *) gtcd->device_name);
01185       ast_free(gtcd);
01186       return 0;
01187    }
01188 
01189    previous_state = generic_list->current_state;
01190    generic_list->current_state = new_state;
01191 
01192    if (cc_generic_is_device_available(new_state) &&
01193          (previous_state == AST_DEVICE_INUSE || previous_state == AST_DEVICE_UNAVAILABLE ||
01194           previous_state == AST_DEVICE_BUSY)) {
01195       AST_LIST_TRAVERSE(&generic_list->list, generic_instance, next) {
01196          if (!generic_instance->is_suspended && generic_instance->monitoring) {
01197             generic_instance->monitoring = 0;
01198             generic_list->fit_for_recall = 1;
01199             ast_cc_monitor_callee_available(generic_instance->core_id, "Generic monitored party has become available");
01200             break;
01201          }
01202       }
01203    }
01204    cc_unref(generic_list, "Kill reference of generic list in devstate taskprocessor callback");
01205    ast_free((char *) gtcd->device_name);
01206    ast_free(gtcd);
01207    return 0;
01208 }
01209 
01210 static void generic_monitor_devstate_cb(const struct ast_event *event, void *userdata)
01211 {
01212    /* Wow, it's cool that we've picked up on a state change, but we really want
01213     * the actual work to be done in the core's taskprocessor execution thread
01214     * so that all monitor operations can be serialized. Locks?! We don't need
01215     * no steenkin' locks!
01216     */
01217    struct generic_tp_cb_data *gtcd = ast_calloc(1, sizeof(*gtcd));
01218 
01219    if (!gtcd) {
01220       return;
01221    }
01222 
01223    if (!(gtcd->device_name = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_DEVICE)))) {
01224       ast_free(gtcd);
01225       return;
01226    }
01227    gtcd->new_state = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE);
01228 
01229    if (ast_taskprocessor_push(cc_core_taskprocessor, generic_monitor_devstate_tp_cb, gtcd)) {
01230       ast_free((char *)gtcd->device_name);
01231       ast_free(gtcd);
01232    }
01233 }
01234 
01235 int ast_cc_available_timer_expire(const void *data)
01236 {
01237    struct ast_cc_monitor *monitor = (struct ast_cc_monitor *) data;
01238    int res;
01239    monitor->available_timer_id = -1;
01240    res = ast_cc_monitor_failed(monitor->core_id, monitor->interface->device_name, "Available timer expired for monitor");
01241    cc_unref(monitor, "Unref reference from scheduler\n");
01242    return res;
01243 }
01244 
01245 static int cc_generic_monitor_request_cc(struct ast_cc_monitor *monitor, int *available_timer_id)
01246 {
01247    struct generic_monitor_instance_list *generic_list;
01248    struct generic_monitor_instance *generic_instance;
01249    struct generic_monitor_pvt *gen_mon_pvt;
01250    enum ast_cc_service_type service = monitor->service_offered;
01251    int when;
01252 
01253    /* First things first. Native channel drivers will have their private data allocated
01254     * at the time that they tell the core that they can offer CC. Generic is quite a bit
01255     * different, and we wait until this point to allocate our private data.
01256     */
01257    if (!(gen_mon_pvt = ast_calloc(1, sizeof(*gen_mon_pvt)))) {
01258       return -1;
01259    }
01260 
01261    if (!(gen_mon_pvt->device_name = ast_strdup(monitor->interface->device_name))) {
01262       ast_free(gen_mon_pvt);
01263       return -1;
01264    }
01265 
01266    gen_mon_pvt->core_id = monitor->core_id;
01267 
01268    monitor->private_data = gen_mon_pvt;
01269 
01270    if (!(generic_list = find_generic_monitor_instance_list(monitor->interface->device_name))) {
01271       if (!(generic_list = create_new_generic_list(monitor))) {
01272          return -1;
01273       }
01274    }
01275 
01276    if (!(generic_instance = ast_calloc(1, sizeof(*generic_instance)))) {
01277       /* The generic monitor destructor will take care of the appropriate
01278        * deallocations
01279        */
01280       cc_unref(generic_list, "Generic monitor instance failed to allocate");
01281       return -1;
01282    }
01283    generic_instance->core_id = monitor->core_id;
01284    generic_instance->monitoring = 1;
01285    AST_LIST_INSERT_TAIL(&generic_list->list, generic_instance, next);
01286    when = service == AST_CC_CCBS ? ast_get_ccbs_available_timer(monitor->interface->config_params) :
01287       ast_get_ccnr_available_timer(monitor->interface->config_params);
01288 
01289    *available_timer_id = ast_sched_thread_add(cc_sched_thread, when * 1000,
01290          ast_cc_available_timer_expire, cc_ref(monitor, "Give the scheduler a monitor reference"));
01291    if (*available_timer_id == -1) {
01292       cc_unref(monitor, "Failed to schedule available timer. (monitor)");
01293       cc_unref(generic_list, "Failed to schedule available timer. (generic_list)");
01294       return -1;
01295    }
01296    /* If the new instance was created as CCNR, then that means this device is not currently
01297     * fit for recall even if it previously was.
01298     */
01299    if (service == AST_CC_CCNR || service == AST_CC_CCNL) {
01300       generic_list->fit_for_recall = 0;
01301    }
01302    ast_cc_monitor_request_acked(monitor->core_id, "Generic monitor for %s subscribed to device state.",
01303          monitor->interface->device_name);
01304    cc_unref(generic_list, "Finished with monitor instance reference in request cc callback");
01305    return 0;
01306 }
01307 
01308 static int cc_generic_monitor_suspend(struct ast_cc_monitor *monitor)
01309 {
01310    struct generic_monitor_instance_list *generic_list;
01311    struct generic_monitor_instance *generic_instance;
01312    enum ast_device_state state = ast_device_state(monitor->interface->device_name);
01313 
01314    if (!(generic_list = find_generic_monitor_instance_list(monitor->interface->device_name))) {
01315       return -1;
01316    }
01317 
01318    /* First we need to mark this particular monitor as being suspended. */
01319    AST_LIST_TRAVERSE(&generic_list->list, generic_instance, next) {
01320       if (generic_instance->core_id == monitor->core_id) {
01321          generic_instance->is_suspended = 1;
01322          break;
01323       }
01324    }
01325 
01326    /* If the device being suspended is currently in use, then we don't need to
01327     * take any further actions
01328     */
01329    if (!cc_generic_is_device_available(state)) {
01330       cc_unref(generic_list, "Device is in use. Nothing to do. Unref generic list.");
01331       return 0;
01332    }
01333 
01334    /* If the device is not in use, though, then it may be possible to report the
01335     * device's availability using a different monitor which is monitoring the
01336     * same device
01337     */
01338 
01339    AST_LIST_TRAVERSE(&generic_list->list, generic_instance, next) {
01340       if (!generic_instance->is_suspended) {
01341          ast_cc_monitor_callee_available(generic_instance->core_id, "Generic monitored party has become available");
01342          break;
01343       }
01344    }
01345    cc_unref(generic_list, "Done with generic list in suspend callback");
01346    return 0;
01347 }
01348 
01349 static int cc_generic_monitor_unsuspend(struct ast_cc_monitor *monitor)
01350 {
01351    struct generic_monitor_instance *generic_instance;
01352    struct generic_monitor_instance_list *generic_list = find_generic_monitor_instance_list(monitor->interface->device_name);
01353    enum ast_device_state state = ast_device_state(monitor->interface->device_name);
01354 
01355    if (!generic_list) {
01356       return -1;
01357    }
01358    /* If the device is currently available, we can immediately announce
01359     * its availability
01360     */
01361    if (cc_generic_is_device_available(state)) {
01362       ast_cc_monitor_callee_available(monitor->core_id, "Generic monitored party has become available");
01363    }
01364 
01365    /* In addition, we need to mark this generic_monitor_instance as not being suspended anymore */
01366    AST_LIST_TRAVERSE(&generic_list->list, generic_instance, next) {
01367       if (generic_instance->core_id == monitor->core_id) {
01368          generic_instance->is_suspended = 0;
01369          generic_instance->monitoring = 1;
01370          break;
01371       }
01372    }
01373    cc_unref(generic_list, "Done with generic list in cc_generic_monitor_unsuspend");
01374    return 0;
01375 }
01376 
01377 static int cc_generic_monitor_cancel_available_timer(struct ast_cc_monitor *monitor, int *sched_id)
01378 {
01379    ast_assert(sched_id != NULL);
01380 
01381    if (*sched_id == -1) {
01382       return 0;
01383    }
01384 
01385    ast_log_dynamic_level(cc_logger_level, "Core %d: Canceling generic monitor available timer for monitor %s\n",
01386          monitor->core_id, monitor->interface->device_name);
01387    if (!ast_sched_thread_del(cc_sched_thread, *sched_id)) {
01388       cc_unref(monitor, "Remove scheduler's reference to the monitor");
01389    }
01390    *sched_id = -1;
01391    return 0;
01392 }
01393 
01394 static void cc_generic_monitor_destructor(void *private_data)
01395 {
01396    struct generic_monitor_pvt *gen_mon_pvt = private_data;
01397    struct generic_monitor_instance_list *generic_list;
01398    struct generic_monitor_instance *generic_instance;
01399 
01400    if (!private_data) {
01401       /* If the private data is NULL, that means that the monitor hasn't even
01402        * been created yet, but that the destructor was called. While this sort
01403        * of behavior is useful for native monitors, with a generic one, there is
01404        * nothing in particular to do.
01405        */
01406       return;
01407    }
01408 
01409    ast_log_dynamic_level(cc_logger_level, "Core %d: Destroying generic monitor %s\n",
01410          gen_mon_pvt->core_id, gen_mon_pvt->device_name);
01411 
01412    if (!(generic_list = find_generic_monitor_instance_list(gen_mon_pvt->device_name))) {
01413       /* If there's no generic list, that means that the monitor is being destroyed
01414        * before we actually got to request CC. Not a biggie. Same in the situation
01415        * below if the list traversal should complete without finding an entry.
01416        */
01417       ast_free((char *)gen_mon_pvt->device_name);
01418       ast_free(gen_mon_pvt);
01419       return;
01420    }
01421 
01422    AST_LIST_TRAVERSE_SAFE_BEGIN(&generic_list->list, generic_instance, next) {
01423       if (generic_instance->core_id == gen_mon_pvt->core_id) {
01424          AST_LIST_REMOVE_CURRENT(next);
01425          ast_free(generic_instance);
01426          break;
01427       }
01428    }
01429    AST_LIST_TRAVERSE_SAFE_END;
01430 
01431    if (AST_LIST_EMPTY(&generic_list->list)) {
01432       /* No more monitors with this device name exist. Time to unlink this
01433        * list from the container
01434        */
01435       ao2_t_unlink(generic_monitors, generic_list, "Generic list is empty. Unlink it from the container");
01436    } else {
01437       /* There are still instances for this particular device. The situation
01438        * may be that we were attempting a CC recall and a failure occurred, perhaps
01439        * on the agent side. If a failure happens here and the device being monitored
01440        * is available, then we need to signal on the first unsuspended instance that
01441        * the device is available for recall.
01442        */
01443 
01444       /* First things first. We don't even want to consider this action if
01445        * the device in question isn't available right now.
01446        */
01447       if (generic_list->fit_for_recall
01448          && cc_generic_is_device_available(generic_list->current_state)) {
01449          AST_LIST_TRAVERSE(&generic_list->list, generic_instance, next) {
01450             if (!generic_instance->is_suspended && generic_instance->monitoring) {
01451                ast_cc_monitor_callee_available(generic_instance->core_id, "Signaling generic monitor "
01452                      "availability due to other instance's failure.");
01453                break;
01454             }
01455          }
01456       }
01457    }
01458    cc_unref(generic_list, "Done with generic list in generic monitor destructor");
01459    ast_free((char *)gen_mon_pvt->device_name);
01460    ast_free(gen_mon_pvt);
01461 }
01462 
01463 static void cc_interface_destroy(void *data)
01464 {
01465    struct ast_cc_interface *interface = data;
01466    ast_log_dynamic_level(cc_logger_level, "Destroying cc interface %s\n", interface->device_name);
01467    ast_cc_config_params_destroy(interface->config_params);
01468 }
01469 
01470 /*!
01471  * \brief Data regarding an extension monitor's child's dialstrings
01472  *
01473  * \details
01474  * In developing CCSS, we had most aspects of its operation finished,
01475  * but there was one looming problem that we had failed to get right.
01476  * In our design document, we stated that when a CC recall occurs, all
01477  * endpoints that had been dialed originally would be called back.
01478  * Unfortunately, our implementation only allowed for devices which had
01479  * active monitors to inhabit the CC_INTERFACES channel variable, thus
01480  * making the automated recall only call monitored devices.
01481  *
01482  * Devices that were not CC-capable, or devices which failed CC at some
01483  * point during the process would not make it into the CC_INTERFACES
01484  * channel variable. This struct is meant as a remedy for the problem.
01485  */
01486 struct extension_child_dialstring {
01487    /*!
01488     * \brief the original dialstring used to call a particular device
01489     *
01490     * \details
01491     * When someone dials a particular endpoint, the dialstring used in
01492     * the dialplan is copied into this buffer. What's important here is
01493     * that this is the ORIGINAL dialstring, not the dialstring saved on
01494     * a device monitor. The dialstring on a device monitor is what should
01495     * be used when recalling that device. The two dialstrings may not be
01496     * the same.
01497     *
01498     * By keeping a copy of the original dialstring used, we can fall back
01499     * to using it if the device either does not ever offer CC or if the
01500     * device at some point fails for some reason, such as a timer expiration.
01501     */
01502    char original_dialstring[AST_CHANNEL_NAME];
01503    /*!
01504     * \brief The name of the device being dialed
01505     *
01506     * \details
01507     * This serves mainly as a key when searching for a particular dialstring.
01508     * For instance, let's say that we have called device SIP/400@somepeer. This
01509     * device offers call completion, but then due to some unforeseen circumstance,
01510     * this device backs out and makes CC unavailable. When that happens, we need
01511     * to find the dialstring that corresponds to that device, and we use the
01512     * stored device name as a way to find it.
01513     *
01514     * \note There is one particular case where the device name stored here
01515     * will be empty. This is the case where we fail to request a channel, but we
01516     * still can make use of generic call completion. In such a case, since we never
01517     * were able to request the channel, we can't find what its device name is. In
01518     * this case, however, it is not important because the dialstring is guaranteed
01519     * to be the same both here and in the device monitor.
01520     */
01521    char device_name[AST_CHANNEL_NAME];
01522    /*!
01523     * \brief Is this structure valid for use in CC_INTERFACES?
01524     *
01525     * \details
01526     * When this structure is first created, all information stored here is planned
01527     * to be used, so we set the is_valid flag. However, if a device offers call
01528     * completion, it will potentially have its own dialstring to use for the recall,
01529     * so we find this structure and clear the is_valid flag. By clearing the is_valid
01530     * flag, we won't try to populate the CC_INTERFACES variable with the dialstring
01531     * stored in this struct. Now, if later, the device which had offered CC should fail,
01532     * perhaps due to a timer expiration, then we need to re-set the is_valid flag. This
01533     * way, we still will end up placing a call to the device again, and the dialstring
01534     * used will be the same as was originally used.
01535     */
01536    int is_valid;
01537    AST_LIST_ENTRY(extension_child_dialstring) next;
01538 };
01539 
01540 /*!
01541  * \brief Private data for an extension monitor
01542  */
01543 struct extension_monitor_pvt {
01544    AST_LIST_HEAD_NOLOCK(, extension_child_dialstring) child_dialstrings;
01545 };
01546 
01547 static void cc_extension_monitor_destructor(void *private_data)
01548 {
01549    struct extension_monitor_pvt *extension_pvt = private_data;
01550    struct extension_child_dialstring *child_dialstring;
01551 
01552    /* This shouldn't be possible, but I'm paranoid */
01553    if (!extension_pvt) {
01554       return;
01555    }
01556 
01557    while ((child_dialstring = AST_LIST_REMOVE_HEAD(&extension_pvt->child_dialstrings, next))) {
01558       ast_free(child_dialstring);
01559    }
01560    ast_free(extension_pvt);
01561 }
01562 
01563 static void cc_monitor_destroy(void *data)
01564 {
01565    struct ast_cc_monitor *monitor = data;
01566    /* During the monitor creation process, it is possible for this
01567     * function to be called prior to when callbacks are assigned
01568     * to the monitor. Also, extension monitors do not have callbacks
01569     * assigned to them, so we wouldn't want to segfault when we try
01570     * to destroy one of them.
01571     */
01572    ast_log_dynamic_level(cc_logger_level, "Core %d: Calling destructor for monitor %s\n",
01573          monitor->core_id, monitor->interface->device_name);
01574    if (monitor->interface->monitor_class == AST_CC_EXTENSION_MONITOR) {
01575       cc_extension_monitor_destructor(monitor->private_data);
01576    }
01577    if (monitor->callbacks) {
01578       monitor->callbacks->destructor(monitor->private_data);
01579    }
01580    cc_unref(monitor->interface, "Unreffing tree's reference to interface");
01581    ast_free(monitor->dialstring);
01582 }
01583 
01584 static void cc_interface_tree_destroy(void *data)
01585 {
01586    struct cc_monitor_tree *cc_interface_tree = data;
01587    struct ast_cc_monitor *monitor;
01588    while ((monitor = AST_LIST_REMOVE_HEAD(cc_interface_tree, next))) {
01589       if (monitor->callbacks) {
01590          monitor->callbacks->cancel_available_timer(monitor, &monitor->available_timer_id);
01591       }
01592       cc_unref(monitor, "Destroying all monitors");
01593    }
01594    AST_LIST_HEAD_DESTROY(cc_interface_tree);
01595 }
01596 
01597 /*!
01598  * This counter is used for assigning unique ids
01599  * to CC-enabled dialed interfaces.
01600  */
01601 static int dialed_cc_interface_counter;
01602 
01603 /*!
01604  * \internal
01605  * \brief data stored in CC datastore
01606  *
01607  * The datastore creates a list of interfaces that were
01608  * dialed, including both extensions and devices. In addition
01609  * to the intrinsic data of the tree, some extra information
01610  * is needed for use by app_dial.
01611  */
01612 struct dialed_cc_interfaces {
01613    /*!
01614     * This value serves a dual-purpose. When dial starts, if the
01615     * dialed_cc_interfaces datastore currently exists on the calling
01616     * channel, then the dial_parent_id will serve as a means of
01617     * letting the new extension cc_monitor we create know
01618     * who his parent is. This value will be the extension
01619     * cc_monitor that dialed the local channel that resulted
01620     * in the new Dial app being called.
01621     *
01622     * In addition, once an extension cc_monitor is created,
01623     * the dial_parent_id will be changed to the id of that newly
01624     * created interface. This way, device interfaces created from
01625     * receiving AST_CONTROL_CC frames can use this field to determine
01626     * who their parent extension interface should be.
01627     */
01628    unsigned int dial_parent_id;
01629    /*!
01630     * Identifier for the potential CC request that may be made
01631     * based on this call. Even though an instance of the core may
01632     * not be made (since the caller may not request CC), we allocate
01633     * a new core_id at the beginning of the call so that recipient
01634     * channel drivers can have the information handy just in case
01635     * the caller does end up requesting CC.
01636     */
01637    int core_id;
01638    /*!
01639     * When a new Dial application is started, and the datastore
01640     * already exists on the channel, we can determine if we
01641     * should be adding any new interface information to tree.
01642     */
01643    char ignore;
01644    /*!
01645     * When it comes time to offer CC to the caller, we only want to offer
01646     * it to the original incoming channel. For nested Dials and outbound
01647     * channels, it is incorrect to attempt such a thing. This flag indicates
01648     * if the channel to which this datastore is attached may be legally
01649     * offered CC when the call is finished.
01650     */
01651    char is_original_caller;
01652    /*!
01653     * Reference-counted "tree" of interfaces.
01654     */
01655    struct cc_monitor_tree *interface_tree;
01656 };
01657 
01658 /*!
01659  * \internal
01660  * \brief Destructor function for cc_interfaces datastore
01661  *
01662  * This function will free the actual datastore and drop
01663  * the refcount for the monitor tree by one. In cases
01664  * where CC can actually be used, this unref will not
01665  * result in the destruction of the monitor tree, because
01666  * the CC core will still have a reference.
01667  *
01668  * \param data The dialed_cc_interfaces struct to destroy
01669  */
01670 static void dialed_cc_interfaces_destroy(void *data)
01671 {
01672    struct dialed_cc_interfaces *cc_interfaces = data;
01673    cc_unref(cc_interfaces->interface_tree, "Unref dial's ref to monitor tree");
01674    ast_free(cc_interfaces);
01675 }
01676 
01677 /*!
01678  * \internal
01679  * \brief Duplicate callback for cc_interfaces datastore
01680  *
01681  * Integers are copied by value, but the monitor tree
01682  * is done via a shallow copy and a bump of the refcount.
01683  * This way, sub-Dials will be appending interfaces onto
01684  * the same list as this call to Dial.
01685  *
01686  * \param data The old dialed_cc_interfaces we want to copy
01687  * \retval NULL Could not allocate memory for new dialed_cc_interfaces
01688  * \retval non-NULL The new copy of the dialed_cc_interfaces
01689  */
01690 static void *dialed_cc_interfaces_duplicate(void *data)
01691 {
01692    struct dialed_cc_interfaces *old_cc_interfaces = data;
01693    struct dialed_cc_interfaces *new_cc_interfaces = ast_calloc(1, sizeof(*new_cc_interfaces));
01694    if (!new_cc_interfaces) {
01695       return NULL;
01696    }
01697    new_cc_interfaces->ignore = old_cc_interfaces->ignore;
01698    new_cc_interfaces->dial_parent_id = old_cc_interfaces->dial_parent_id;
01699    new_cc_interfaces->is_original_caller = 0;
01700    cc_ref(old_cc_interfaces->interface_tree, "New ref due to duplication of monitor tree");
01701    new_cc_interfaces->core_id = old_cc_interfaces->core_id;
01702    new_cc_interfaces->interface_tree = old_cc_interfaces->interface_tree;
01703    return new_cc_interfaces;
01704 }
01705 
01706 /*!
01707  * \internal
01708  * \brief information regarding the dialed_cc_interfaces datastore
01709  *
01710  * The dialed_cc_interfaces datastore is responsible for keeping track
01711  * of what CC-enabled interfaces have been dialed by the caller. For
01712  * more information regarding the actual structure of the tree, see
01713  * the documentation provided in include/asterisk/ccss.h
01714  */
01715 static const struct ast_datastore_info dialed_cc_interfaces_info = {
01716    .type = "Dial CC Interfaces",
01717    .duplicate = dialed_cc_interfaces_duplicate,
01718    .destroy = dialed_cc_interfaces_destroy,
01719 };
01720 
01721 static struct extension_monitor_pvt *extension_monitor_pvt_init(void)
01722 {
01723    struct extension_monitor_pvt *ext_pvt = ast_calloc(1, sizeof(*ext_pvt));
01724    if (!ext_pvt) {
01725       return NULL;
01726    }
01727    AST_LIST_HEAD_INIT_NOLOCK(&ext_pvt->child_dialstrings);
01728    return ext_pvt;
01729 }
01730 
01731 void ast_cc_extension_monitor_add_dialstring(struct ast_channel *incoming, const char * const dialstring, const char * const device_name)
01732 {
01733    struct ast_datastore *cc_datastore;
01734    struct dialed_cc_interfaces *cc_interfaces;
01735    struct ast_cc_monitor *monitor;
01736    struct extension_monitor_pvt *extension_pvt;
01737    struct extension_child_dialstring *child_dialstring;
01738    struct cc_monitor_tree *interface_tree;
01739    int id;
01740 
01741    ast_channel_lock(incoming);
01742    if (!(cc_datastore = ast_channel_datastore_find(incoming, &dialed_cc_interfaces_info, NULL))) {
01743       ast_channel_unlock(incoming);
01744       return;
01745    }
01746 
01747    cc_interfaces = cc_datastore->data;
01748    interface_tree = cc_interfaces->interface_tree;
01749    id = cc_interfaces->dial_parent_id;
01750    ast_channel_unlock(incoming);
01751 
01752    AST_LIST_LOCK(interface_tree);
01753    AST_LIST_TRAVERSE(interface_tree, monitor, next) {
01754       if (monitor->id == id) {
01755          break;
01756       }
01757    }
01758 
01759    if (!monitor) {
01760       AST_LIST_UNLOCK(interface_tree);
01761       return;
01762    }
01763 
01764    extension_pvt = monitor->private_data;
01765    if (!(child_dialstring = ast_calloc(1, sizeof(*child_dialstring)))) {
01766       AST_LIST_UNLOCK(interface_tree);
01767       return;
01768    }
01769    ast_copy_string(child_dialstring->original_dialstring, dialstring, sizeof(child_dialstring->original_dialstring));
01770    ast_copy_string(child_dialstring->device_name, device_name, sizeof(child_dialstring->device_name));
01771    child_dialstring->is_valid = 1;
01772    AST_LIST_INSERT_TAIL(&extension_pvt->child_dialstrings, child_dialstring, next);
01773    AST_LIST_UNLOCK(interface_tree);
01774 }
01775 
01776 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)
01777 {
01778    struct ast_cc_monitor *monitor_iter;
01779    struct extension_monitor_pvt *extension_pvt;
01780    struct extension_child_dialstring *child_dialstring;
01781 
01782    AST_LIST_TRAVERSE(core_instance->monitors, monitor_iter, next) {
01783       if (monitor_iter->id == parent_id) {
01784          break;
01785       }
01786    }
01787 
01788    if (!monitor_iter) {
01789       return;
01790    }
01791    extension_pvt = monitor_iter->private_data;
01792 
01793    AST_LIST_TRAVERSE(&extension_pvt->child_dialstrings, child_dialstring, next) {
01794       if (!strcmp(child_dialstring->device_name, device_name)) {
01795          child_dialstring->is_valid = is_valid;
01796          break;
01797       }
01798    }
01799 }
01800 
01801 /*!
01802  * \internal
01803  * \brief Allocate and initialize an "extension" interface for CC purposes
01804  *
01805  * When app_dial starts, this function is called in order to set up the
01806  * information about the extension in which this Dial is occurring. Any
01807  * devices dialed will have this particular cc_monitor as a parent.
01808  *
01809  * \param exten Extension from which Dial is occurring
01810  * \param context Context to which exten belongs
01811  * \param parent_id What should we set the parent_id of this interface to?
01812  * \retval NULL Memory allocation failure
01813  * \retval non-NULL The newly-created cc_monitor for the extension
01814  */
01815 static struct ast_cc_monitor *cc_extension_monitor_init(const char * const exten, const char * const context, const unsigned int parent_id)
01816 {
01817    struct ast_str *str = ast_str_alloca(2 * AST_MAX_EXTENSION);
01818    struct ast_cc_interface *cc_interface;
01819    struct ast_cc_monitor *monitor;
01820 
01821    ast_str_set(&str, 0, "%s@%s", exten, context);
01822 
01823    if (!(cc_interface = ao2_t_alloc(sizeof(*cc_interface) + ast_str_strlen(str), cc_interface_destroy,
01824                "Allocating new ast_cc_interface"))) {
01825       return NULL;
01826    }
01827 
01828    if (!(monitor = ao2_t_alloc(sizeof(*monitor), cc_monitor_destroy, "Allocating new ast_cc_monitor"))) {
01829       cc_unref(cc_interface, "failed to allocate the monitor, so unref the interface");
01830       return NULL;
01831    }
01832 
01833    if (!(monitor->private_data = extension_monitor_pvt_init())) {
01834       cc_unref(monitor, "Failed to initialize extension monitor private data. uref monitor");
01835       cc_unref(cc_interface, "Failed to initialize extension monitor private data. unref cc_interface");
01836    }
01837 
01838    monitor->id = ast_atomic_fetchadd_int(&dialed_cc_interface_counter, +1);
01839    monitor->parent_id = parent_id;
01840    cc_interface->monitor_type = "extension";
01841    cc_interface->monitor_class = AST_CC_EXTENSION_MONITOR;
01842    strcpy(cc_interface->device_name, ast_str_buffer(str));
01843    monitor->interface = cc_interface;
01844    ast_log_dynamic_level(cc_logger_level, "Created an extension cc interface for '%s' with id %d and parent %d\n", cc_interface->device_name, monitor->id, monitor->parent_id);
01845    return monitor;
01846 }
01847 
01848 /*!
01849  * \internal
01850  * \brief allocate dialed_cc_interfaces datastore and initialize fields
01851  *
01852  * This function is called when Situation 1 occurs in ast_cc_call_init.
01853  * See that function for more information on what Situation 1 is.
01854  *
01855  * In this particular case, we have to do a lot of memory allocation in order
01856  * to create the datastore, the data for the datastore, the tree of interfaces
01857  * that we'll be adding to, and the initial extension interface for this Dial
01858  * attempt.
01859  *
01860  * \param chan The channel onto which the datastore should be added.
01861  * \retval -1 An error occurred
01862  * \retval 0 Success
01863  */
01864 static int cc_interfaces_datastore_init(struct ast_channel *chan) {
01865    struct dialed_cc_interfaces *interfaces;
01866    struct ast_cc_monitor *monitor;
01867    struct ast_datastore *dial_cc_datastore;
01868 
01869    /*XXX This may be a bit controversial. In an attempt to not allocate
01870     * extra resources, I make sure that a future request will be within
01871     * limits. The problem here is that it is reasonable to think that
01872     * even if we're not within the limits at this point, we may be by
01873     * the time the requestor will have made his request. This may be
01874     * deleted at some point.
01875     */
01876    if (!ast_cc_request_is_within_limits()) {
01877       return 0;
01878    }
01879 
01880    if (!(interfaces = ast_calloc(1, sizeof(*interfaces)))) {
01881       return -1;
01882    }
01883 
01884    if (!(monitor = cc_extension_monitor_init(S_OR(chan->macroexten, chan->exten), S_OR(chan->macrocontext, chan->context), 0))) {
01885       ast_free(interfaces);
01886       return -1;
01887    }
01888 
01889    if (!(dial_cc_datastore = ast_datastore_alloc(&dialed_cc_interfaces_info, NULL))) {
01890       cc_unref(monitor, "Could not allocate the dialed interfaces datastore. Unreffing monitor");
01891       ast_free(interfaces);
01892       return -1;
01893    }
01894 
01895    if (!(interfaces->interface_tree = ao2_t_alloc(sizeof(*interfaces->interface_tree), cc_interface_tree_destroy,
01896                "Allocate monitor tree"))) {
01897       ast_datastore_free(dial_cc_datastore);
01898       cc_unref(monitor, "Could not allocate monitor tree on dialed interfaces datastore. Unreffing monitor");
01899       ast_free(interfaces);
01900       return -1;
01901    }
01902 
01903    /* Finally, all that allocation is done... */
01904    AST_LIST_HEAD_INIT(interfaces->interface_tree);
01905    AST_LIST_INSERT_TAIL(interfaces->interface_tree, monitor, next);
01906    cc_ref(monitor, "List's reference to extension monitor");
01907    dial_cc_datastore->data = interfaces;
01908    dial_cc_datastore->inheritance = DATASTORE_INHERIT_FOREVER;
01909    interfaces->dial_parent_id = monitor->id;
01910    interfaces->core_id = monitor->core_id = ast_atomic_fetchadd_int(&core_id_counter, +1);
01911    interfaces->is_original_caller = 1;
01912    ast_channel_lock(chan);
01913    ast_channel_datastore_add(chan, dial_cc_datastore);
01914    ast_channel_unlock(chan);
01915    cc_unref(monitor, "Unreffing allocation's reference");
01916    return 0;
01917 }
01918 
01919 /*!
01920  * \internal
01921  * \brief  Call a monitor's destructor before the monitor has been allocated
01922  * \since 1.8
01923  *
01924  * \param monitor_type The type of monitor callbacks to use when calling the destructor
01925  * \param private_data Data allocated by a channel driver that must be freed
01926  *
01927  * \details
01928  * I'll admit, this is a bit evil.
01929  *
01930  * When a channel driver determines that it can offer a call completion service to
01931  * a caller, it is very likely that the channel driver will need to allocate some
01932  * data so that when the time comes to request CC, the channel driver will have the
01933  * necessary data at hand.
01934  *
01935  * The problem is that there are many places where failures may occur before the monitor
01936  * has been properly allocated and had its callbacks assigned to it. If one of these
01937  * failures should occur, then we still need to let the channel driver know that it
01938  * must destroy the data that it allocated.
01939  *
01940  * \return Nothing
01941  */
01942 static void call_destructor_with_no_monitor(const char * const monitor_type, void *private_data)
01943 {
01944    const struct ast_cc_monitor_callbacks *monitor_callbacks = find_monitor_callbacks(monitor_type);
01945 
01946    if (!monitor_callbacks) {
01947       return;
01948    }
01949 
01950    monitor_callbacks->destructor(private_data);
01951 }
01952 
01953 /*!
01954  * \internal
01955  * \brief Allocate and intitialize a device cc_monitor
01956  *
01957  * For all intents and purposes, this is the same as
01958  * cc_extension_monitor_init, except that there is only
01959  * a single parameter used for naming the interface.
01960  *
01961  * This function is called when handling AST_CONTROL_CC frames.
01962  * The device has reported that CC is possible, so we add it
01963  * to the interface_tree.
01964  *
01965  * Note that it is not necessarily erroneous to add the same
01966  * device to the tree twice. If the same device is called by
01967  * two different extension during the same call, then
01968  * that is a legitimate situation. Of course, I'm pretty sure
01969  * the dialed_interfaces global datastore will not allow that
01970  * to happen anyway.
01971  *
01972  * \param device_name The name of the device being added to the tree
01973  * \param dialstring The dialstring used to dial the device being added
01974  * \param parent_id The parent of this new tree node.
01975  * \retval NULL Memory allocation failure
01976  * \retval non-NULL The new ast_cc_interface created.
01977  */
01978 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)
01979 {
01980    struct ast_cc_interface *cc_interface;
01981    struct ast_cc_monitor *monitor;
01982    size_t device_name_len = strlen(device_name);
01983    int parent_id = cc_data->parent_interface_id;
01984 
01985    if (!(cc_interface = ao2_t_alloc(sizeof(*cc_interface) + device_name_len, cc_interface_destroy,
01986                "Allocating new ast_cc_interface"))) {
01987       return NULL;
01988    }
01989 
01990    if (!(cc_interface->config_params = ast_cc_config_params_init())) {
01991       cc_unref(cc_interface, "Failed to allocate config params, unref interface");
01992       return NULL;
01993    }
01994 
01995    if (!(monitor = ao2_t_alloc(sizeof(*monitor), cc_monitor_destroy, "Allocating new ast_cc_monitor"))) {
01996       cc_unref(cc_interface, "Failed to allocate monitor, unref interface");
01997       return NULL;
01998    }
01999 
02000    if (!(monitor->dialstring = ast_strdup(dialstring))) {
02001       cc_unref(monitor, "Failed to copy dialable name. Unref monitor");
02002       cc_unref(cc_interface, "Failed to copy dialable name");
02003       return NULL;
02004    }
02005 
02006    if (!(monitor->callbacks = find_monitor_callbacks(cc_data->monitor_type))) {
02007       cc_unref(monitor, "Failed to find monitor callbacks. Unref monitor");
02008       cc_unref(cc_interface, "Failed to find monitor callbacks");
02009       return NULL;
02010    }
02011 
02012    strcpy(cc_interface->device_name, device_name);
02013    monitor->id = ast_atomic_fetchadd_int(&dialed_cc_interface_counter, +1);
02014    monitor->parent_id = parent_id;
02015    monitor->core_id = core_id;
02016    monitor->service_offered = cc_data->service;
02017    monitor->private_data = cc_data->private_data;
02018    cc_interface->monitor_type = cc_data->monitor_type;
02019    cc_interface->monitor_class = AST_CC_DEVICE_MONITOR;
02020    monitor->interface = cc_interface;
02021    monitor->available_timer_id = -1;
02022    ast_cc_copy_config_params(cc_interface->config_params, &cc_data->config_params);
02023    ast_log_dynamic_level(cc_logger_level, "Core %d: Created a device cc interface for '%s' with id %d and parent %d\n",
02024          monitor->core_id, cc_interface->device_name, monitor->id, monitor->parent_id);
02025    return monitor;
02026 }
02027 
02028 /*!
02029  * \details
02030  * Unless we are ignoring CC for some reason, we will always
02031  * call this function when we read an AST_CONTROL_CC frame
02032  * from an outbound channel.
02033  *
02034  * This function will call cc_device_monitor_init to
02035  * create the new cc_monitor for the device from which
02036  * we read the frame. In addition, the new device will be added
02037  * to the monitor tree on the dialed_cc_interfaces datastore
02038  * on the inbound channel.
02039  *
02040  * If this is the first AST_CONTROL_CC frame that we have handled
02041  * for this call, then we will also initialize the CC core for
02042  * this call.
02043  */
02044 void ast_handle_cc_control_frame(struct ast_channel *inbound, struct ast_channel *outbound, void *frame_data)
02045 {
02046    char *device_name;
02047    char *dialstring;
02048    struct ast_cc_monitor *monitor;
02049    struct ast_datastore *cc_datastore;
02050    struct dialed_cc_interfaces *cc_interfaces;
02051    struct cc_control_payload *cc_data = frame_data;
02052    struct cc_core_instance *core_instance;
02053 
02054    device_name = cc_data->device_name;
02055    dialstring = cc_data->dialstring;
02056 
02057    ast_channel_lock(inbound);
02058    if (!(cc_datastore = ast_channel_datastore_find(inbound, &dialed_cc_interfaces_info, NULL))) {
02059       ast_log(LOG_WARNING, "Unable to retrieve CC datastore while processing CC frame from '%s'. CC services will be unavailable.\n", device_name);
02060       ast_channel_unlock(inbound);
02061       call_destructor_with_no_monitor(cc_data->monitor_type, cc_data->private_data);
02062       return;
02063    }
02064 
02065    cc_interfaces = cc_datastore->data;
02066 
02067    if (cc_interfaces->ignore) {
02068       ast_channel_unlock(inbound);
02069       call_destructor_with_no_monitor(cc_data->monitor_type, cc_data->private_data);
02070       return;
02071    }
02072 
02073    if (!cc_interfaces->is_original_caller) {
02074       /* If the is_original_caller is not set on the *inbound* channel, then
02075        * it must be a local channel. As such, we do not want to create a core instance
02076        * or an agent for the local channel. Instead, we want to pass this along to the
02077        * other side of the local channel so that the original caller can benefit.
02078        */
02079       ast_channel_unlock(inbound);
02080       ast_indicate_data(inbound, AST_CONTROL_CC, cc_data, sizeof(*cc_data));
02081       return;
02082    }
02083 
02084    core_instance = find_cc_core_instance(cc_interfaces->core_id);
02085    if (!core_instance) {
02086       core_instance = cc_core_init_instance(inbound, cc_interfaces->interface_tree,
02087          cc_interfaces->core_id, cc_data);
02088       if (!core_instance) {
02089          cc_interfaces->ignore = 1;
02090          ast_channel_unlock(inbound);
02091          call_destructor_with_no_monitor(cc_data->monitor_type, cc_data->private_data);
02092          return;
02093       }
02094    }
02095 
02096    ast_channel_unlock(inbound);
02097 
02098    /* Yeah this kind of sucks, but luckily most people
02099     * aren't dialing thousands of interfaces on every call
02100     *
02101     * This traversal helps us to not create duplicate monitors in
02102     * case a device queues multiple CC control frames.
02103     */
02104    AST_LIST_LOCK(cc_interfaces->interface_tree);
02105    AST_LIST_TRAVERSE(cc_interfaces->interface_tree, monitor, next) {
02106       if (!strcmp(monitor->interface->device_name, device_name)) {
02107          ast_log_dynamic_level(cc_logger_level, "Core %d: Device %s sent us multiple CC control frames. Ignoring those beyond the first.\n",
02108                core_instance->core_id, device_name);
02109          AST_LIST_UNLOCK(cc_interfaces->interface_tree);
02110          cc_unref(core_instance, "Returning early from ast_handle_cc_control_frame. Unref core_instance");
02111          call_destructor_with_no_monitor(cc_data->monitor_type, cc_data->private_data);
02112          return;
02113       }
02114    }
02115    AST_LIST_UNLOCK(cc_interfaces->interface_tree);
02116 
02117    if (!(monitor = cc_device_monitor_init(device_name, dialstring, cc_data, core_instance->core_id))) {
02118       ast_log(LOG_WARNING, "Unable to create CC device interface for '%s'. CC services will be unavailable on this interface.\n", device_name);
02119       cc_unref(core_instance, "Returning early from ast_handle_cc_control_frame. Unref core_instance");
02120       call_destructor_with_no_monitor(cc_data->monitor_type, cc_data->private_data);
02121       return;
02122    }
02123 
02124    AST_LIST_LOCK(cc_interfaces->interface_tree);
02125    cc_ref(monitor, "monitor tree's reference to the monitor");
02126    AST_LIST_INSERT_TAIL(cc_interfaces->interface_tree, monitor, next);
02127    AST_LIST_UNLOCK(cc_interfaces->interface_tree);
02128 
02129    cc_extension_monitor_change_is_valid(core_instance, monitor->parent_id, monitor->interface->device_name, 0);
02130 
02131    manager_event(EVENT_FLAG_CC, "CCAvailable",
02132       "CoreID: %d\r\n"
02133       "Callee: %s\r\n"
02134       "Service: %s\r\n",
02135       cc_interfaces->core_id, device_name, cc_service_to_string(cc_data->service)
02136    );
02137 
02138    cc_unref(core_instance, "Done with core_instance after handling CC control frame");
02139    cc_unref(monitor, "Unref reference from allocating monitor");
02140 }
02141 
02142 int ast_cc_call_init(struct ast_channel *chan, int *ignore_cc)
02143 {
02144    /* There are three situations to deal with here:
02145     *
02146     * 1. The channel does not have a dialed_cc_interfaces datastore on
02147     * it. This means that this is the first time that Dial has
02148     * been called. We need to create/initialize the datastore.
02149     *
02150     * 2. The channel does have a cc_interface datastore on it and
02151     * the "ignore" indicator is 0. This means that a Local channel
02152     * was called by a "parent" dial. We can check the datastore's
02153     * parent field to see who the root of this particular dial tree
02154     * is.
02155     *
02156     * 3. The channel does have a cc_interface datastore on it and
02157     * the "ignore" indicator is 1. This means that a second Dial call
02158     * is being made from an extension. In this case, we do not
02159     * want to make any additions/modifications to the datastore. We
02160     * will instead set a flag to indicate that CCSS is completely
02161     * disabled for this Dial attempt.
02162     */
02163 
02164    struct ast_datastore *cc_interfaces_datastore;
02165    struct dialed_cc_interfaces *interfaces;
02166    struct ast_cc_monitor *monitor;
02167    struct ast_cc_config_params *cc_params;
02168 
02169    ast_channel_lock(chan);
02170 
02171    cc_params = ast_channel_get_cc_config_params(chan);
02172    if (!cc_params) {
02173       ast_channel_unlock(chan);
02174       return -1;
02175    }
02176    if (ast_get_cc_agent_policy(cc_params) == AST_CC_AGENT_NEVER) {
02177       /* We can't offer CC to this caller anyway, so don't bother with CC on this call
02178        */
02179       *ignore_cc = 1;
02180       ast_channel_unlock(chan);
02181       ast_log_dynamic_level(cc_logger_level, "Agent policy for %s is 'never'. CC not possible\n", chan->name);
02182       return 0;
02183    }
02184 
02185    if (!(cc_interfaces_datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL))) {
02186       /* Situation 1 has occurred */
02187       ast_channel_unlock(chan);
02188       return cc_interfaces_datastore_init(chan);
02189    }
02190    interfaces = cc_interfaces_datastore->data;
02191    ast_channel_unlock(chan);
02192 
02193    if (interfaces->ignore) {
02194       /* Situation 3 has occurred */
02195       *ignore_cc = 1;
02196       ast_log_dynamic_level(cc_logger_level, "Datastore is present with ignore flag set. Ignoring CC offers on this call\n");
02197       return 0;
02198    }
02199 
02200    /* Situation 2 has occurred */
02201    if (!(monitor = cc_extension_monitor_init(S_OR(chan->macroexten, chan->exten),
02202          S_OR(chan->macrocontext, chan->context), interfaces->dial_parent_id))) {
02203       return -1;
02204    }
02205    monitor->core_id = interfaces->core_id;
02206    AST_LIST_LOCK(interfaces->interface_tree);
02207    cc_ref(monitor, "monitor tree's reference to the monitor");
02208    AST_LIST_INSERT_TAIL(interfaces->interface_tree, monitor, next);
02209    AST_LIST_UNLOCK(interfaces->interface_tree);
02210    interfaces->dial_parent_id = monitor->id;
02211    cc_unref(monitor, "Unref monitor's allocation reference");
02212    return 0;
02213 }
02214 
02215 int ast_cc_request_is_within_limits(void)
02216 {
02217    return cc_request_count < global_cc_max_requests;
02218 }
02219 
02220 int ast_cc_get_current_core_id(struct ast_channel *chan)
02221 {
02222    struct ast_datastore *datastore;
02223    struct dialed_cc_interfaces *cc_interfaces;
02224    int core_id_return;
02225 
02226    ast_channel_lock(chan);
02227    if (!(datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL))) {
02228       ast_channel_unlock(chan);
02229       return -1;
02230    }
02231 
02232    cc_interfaces = datastore->data;
02233    core_id_return = cc_interfaces->ignore ? -1 : cc_interfaces->core_id;
02234    ast_channel_unlock(chan);
02235    return core_id_return;
02236 
02237 }
02238 
02239 static long count_agents(const char * const caller, const int core_id_exception)
02240 {
02241    struct count_agents_cb_data data = {.core_id_exception = core_id_exception,};
02242 
02243    ao2_t_callback_data(cc_core_instances, OBJ_NODATA, count_agents_cb, (char *)caller, &data, "Counting agents");
02244    ast_log_dynamic_level(cc_logger_level, "Counted %d agents\n", data.count);
02245    return data.count;
02246 }
02247 
02248 static void kill_duplicate_offers(char *caller)
02249 {
02250    unsigned long match_flags = MATCH_NO_REQUEST;
02251    struct ao2_iterator *dups_iter;
02252 
02253    /*
02254     * Must remove the ref that was in cc_core_instances outside of
02255     * the container lock to prevent deadlock.
02256     */
02257    dups_iter = ao2_t_callback_data(cc_core_instances, OBJ_MULTIPLE | OBJ_UNLINK,
02258       match_agent, caller, &match_flags, "Killing duplicate offers");
02259    if (dups_iter) {
02260       /* Now actually unref any duplicate offers by simply destroying the iterator. */
02261       ao2_iterator_destroy(dups_iter);
02262    }
02263 }
02264 
02265 static void check_callback_sanity(const struct ast_cc_agent_callbacks *callbacks)
02266 {
02267    ast_assert(callbacks->init != NULL);
02268    ast_assert(callbacks->start_offer_timer != NULL);
02269    ast_assert(callbacks->stop_offer_timer != NULL);
02270    ast_assert(callbacks->respond != NULL);
02271    ast_assert(callbacks->status_request != NULL);
02272    ast_assert(callbacks->start_monitoring != NULL);
02273    ast_assert(callbacks->callee_available != NULL);
02274    ast_assert(callbacks->destructor != NULL);
02275 }
02276 
02277 static void agent_destroy(void *data)
02278 {
02279    struct ast_cc_agent *agent = data;
02280 
02281    if (agent->callbacks) {
02282       agent->callbacks->destructor(agent);
02283    }
02284    ast_cc_config_params_destroy(agent->cc_params);
02285 }
02286 
02287 static struct ast_cc_agent *cc_agent_init(struct ast_channel *caller_chan,
02288       const char * const caller_name, const int core_id,
02289       struct cc_monitor_tree *interface_tree)
02290 {
02291    struct ast_cc_agent *agent;
02292    struct ast_cc_config_params *cc_params;
02293 
02294    if (!(agent = ao2_t_alloc(sizeof(*agent) + strlen(caller_name), agent_destroy,
02295                "Allocating new ast_cc_agent"))) {
02296       return NULL;
02297    }
02298 
02299    agent->core_id = core_id;
02300    strcpy(agent->device_name, caller_name);
02301 
02302    cc_params = ast_channel_get_cc_config_params(caller_chan);
02303    if (!cc_params) {
02304       cc_unref(agent, "Could not get channel config params.");
02305       return NULL;
02306    }
02307    if (!(agent->cc_params = ast_cc_config_params_init())) {
02308       cc_unref(agent, "Could not init agent config params.");
02309       return NULL;
02310    }
02311    ast_cc_copy_config_params(agent->cc_params, cc_params);
02312 
02313    if (!(agent->callbacks = find_agent_callbacks(caller_chan))) {
02314       cc_unref(agent, "Could not find agent callbacks.");
02315       return NULL;
02316    }
02317    check_callback_sanity(agent->callbacks);
02318 
02319    if (agent->callbacks->init(agent, caller_chan)) {
02320       cc_unref(agent, "Agent init callback failed.");
02321       return NULL;
02322    }
02323    ast_log_dynamic_level(cc_logger_level, "Core %d: Created an agent for caller %s\n",
02324          agent->core_id, agent->device_name);
02325    return agent;
02326 }
02327 
02328 /* Generic agent callbacks */
02329 static int cc_generic_agent_init(struct ast_cc_agent *agent, struct ast_channel *chan);
02330 static int cc_generic_agent_start_offer_timer(struct ast_cc_agent *agent);
02331 static int cc_generic_agent_stop_offer_timer(struct ast_cc_agent *agent);
02332 static void cc_generic_agent_respond(struct ast_cc_agent *agent, enum ast_cc_agent_response_reason reason);
02333 static int cc_generic_agent_status_request(struct ast_cc_agent *agent);
02334 static int cc_generic_agent_stop_ringing(struct ast_cc_agent *agent);
02335 static int cc_generic_agent_start_monitoring(struct ast_cc_agent *agent);
02336 static int cc_generic_agent_recall(struct ast_cc_agent *agent);
02337 static void cc_generic_agent_destructor(struct ast_cc_agent *agent);
02338 
02339 static struct ast_cc_agent_callbacks generic_agent_callbacks = {
02340    .type = "generic",
02341    .init = cc_generic_agent_init,
02342    .start_offer_timer = cc_generic_agent_start_offer_timer,
02343    .stop_offer_timer = cc_generic_agent_stop_offer_timer,
02344    .respond = cc_generic_agent_respond,
02345    .status_request = cc_generic_agent_status_request,
02346    .stop_ringing = cc_generic_agent_stop_ringing,
02347    .start_monitoring = cc_generic_agent_start_monitoring,
02348    .callee_available = cc_generic_agent_recall,
02349    .destructor = cc_generic_agent_destructor,
02350 };
02351 
02352 struct cc_generic_agent_pvt {
02353    /*!
02354     * Subscription to device state
02355     *
02356     * Used in the CC_CALLER_BUSY state. The
02357     * generic agent will subscribe to the
02358     * device state of the caller in order to
02359     * determine when we may move on
02360     */
02361    struct ast_event_sub *sub;
02362    /*!
02363     * Scheduler id of offer timer.
02364     */
02365    int offer_timer_id;
02366    /*!
02367     * Caller ID number
02368     *
02369     * When we re-call the caller, we need
02370     * to provide this information to
02371     * ast_request_and_dial so that the
02372     * information will be present in the
02373     * call to the callee
02374     */
02375    char cid_num[AST_CHANNEL_NAME];
02376    /*!
02377     * Caller ID name
02378     *
02379     * See the description of cid_num.
02380     * The same applies here, except this
02381     * is the caller's name.
02382     */
02383    char cid_name[AST_CHANNEL_NAME];
02384    /*!
02385     * Extension dialed
02386     *
02387     * The original extension dialed. This is used
02388     * so that when performing a recall, we can
02389     * call the proper extension.
02390     */
02391    char exten[AST_CHANNEL_NAME];
02392    /*!
02393     * Context dialed
02394     *
02395     * The original context dialed. This is used
02396     * so that when performaing a recall, we can
02397     * call into the proper context
02398     */
02399    char context[AST_CHANNEL_NAME];
02400 };
02401 
02402 static int cc_generic_agent_init(struct ast_cc_agent *agent, struct ast_channel *chan)
02403 {
02404    struct cc_generic_agent_pvt *generic_pvt = ast_calloc(1, sizeof(*generic_pvt));
02405 
02406    if (!generic_pvt) {
02407       return -1;
02408    }
02409 
02410    generic_pvt->offer_timer_id = -1;
02411    if (chan->caller.id.number.valid && chan->caller.id.number.str) {
02412       ast_copy_string(generic_pvt->cid_num, chan->caller.id.number.str, sizeof(generic_pvt->cid_num));
02413    }
02414    if (chan->caller.id.name.valid && chan->caller.id.name.str) {
02415       ast_copy_string(generic_pvt->cid_name, chan->caller.id.name.str, sizeof(generic_pvt->cid_name));
02416    }
02417    ast_copy_string(generic_pvt->exten, S_OR(chan->macroexten, chan->exten), sizeof(generic_pvt->exten));
02418    ast_copy_string(generic_pvt->context, S_OR(chan->macrocontext, chan->context), sizeof(generic_pvt->context));
02419    agent->private_data = generic_pvt;
02420    ast_set_flag(agent, AST_CC_AGENT_SKIP_OFFER);
02421    return 0;
02422 }
02423 
02424 static int offer_timer_expire(const void *data)
02425 {
02426    struct ast_cc_agent *agent = (struct ast_cc_agent *) data;
02427    struct cc_generic_agent_pvt *agent_pvt = agent->private_data;
02428    ast_log_dynamic_level(cc_logger_level, "Core %d: Queuing change request because offer timer has expired.\n",
02429          agent->core_id);
02430    agent_pvt->offer_timer_id = -1;
02431    ast_cc_failed(agent->core_id, "Generic agent %s offer timer expired", agent->device_name);
02432    cc_unref(agent, "Remove scheduler's reference to the agent");
02433    return 0;
02434 }
02435 
02436 static int cc_generic_agent_start_offer_timer(struct ast_cc_agent *agent)
02437 {
02438    int when;
02439    int sched_id;
02440    struct cc_generic_agent_pvt *generic_pvt = agent->private_data;
02441 
02442    ast_assert(cc_sched_thread != NULL);
02443    ast_assert(agent->cc_params != NULL);
02444 
02445    when = ast_get_cc_offer_timer(agent->cc_params) * 1000;
02446    ast_log_dynamic_level(cc_logger_level, "Core %d: About to schedule offer timer expiration for %d ms\n",
02447          agent->core_id, when);
02448    if ((sched_id = ast_sched_thread_add(cc_sched_thread, when, offer_timer_expire, cc_ref(agent, "Give scheduler an agent ref"))) == -1) {
02449       return -1;
02450    }
02451    generic_pvt->offer_timer_id = sched_id;
02452    return 0;
02453 }
02454 
02455 static int cc_generic_agent_stop_offer_timer(struct ast_cc_agent *agent)
02456 {
02457    struct cc_generic_agent_pvt *generic_pvt = agent->private_data;
02458 
02459    if (generic_pvt->offer_timer_id != -1) {
02460       if (!ast_sched_thread_del(cc_sched_thread, generic_pvt->offer_timer_id)) {
02461          cc_unref(agent, "Remove scheduler's reference to the agent");
02462       }
02463       generic_pvt->offer_timer_id = -1;
02464    }
02465    return 0;
02466 }
02467 
02468 static void cc_generic_agent_respond(struct ast_cc_agent *agent, enum ast_cc_agent_response_reason reason)
02469 {
02470    /* The generic agent doesn't have to do anything special to
02471     * acknowledge a CC request. Just return.
02472     */
02473    return;
02474 }
02475 
02476 static int cc_generic_agent_status_request(struct ast_cc_agent *agent)
02477 {
02478    ast_cc_agent_status_response(agent->core_id, ast_device_state(agent->device_name));
02479    return 0;
02480 }
02481 
02482 static int cc_generic_agent_stop_ringing(struct ast_cc_agent *agent)
02483 {
02484    struct ast_channel *recall_chan = ast_channel_get_by_name_prefix(agent->device_name, strlen(agent->device_name));
02485 
02486    if (!recall_chan) {
02487       return 0;
02488    }
02489 
02490    ast_softhangup(recall_chan, AST_SOFTHANGUP_EXPLICIT);
02491    return 0;
02492 }
02493 
02494 static int generic_agent_devstate_unsubscribe(void *data)
02495 {
02496    struct ast_cc_agent *agent = data;
02497    struct cc_generic_agent_pvt *generic_pvt = agent->private_data;
02498 
02499    if (generic_pvt->sub != NULL) {
02500       generic_pvt->sub = ast_event_unsubscribe(generic_pvt->sub);
02501    }
02502    cc_unref(agent, "Done unsubscribing from devstate");
02503    return 0;
02504 }
02505 
02506 static void generic_agent_devstate_cb(const struct ast_event *event, void *userdata)
02507 {
02508    struct ast_cc_agent *agent = userdata;
02509    enum ast_device_state new_state;
02510 
02511    new_state = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE);
02512    if (!cc_generic_is_device_available(new_state)) {
02513       /* Not interested in this new state of the device.  It is still busy. */
02514       return;
02515    }
02516 
02517    /* We can't unsubscribe from device state events here because it causes a deadlock */
02518    if (ast_taskprocessor_push(cc_core_taskprocessor, generic_agent_devstate_unsubscribe,
02519          cc_ref(agent, "ref agent for device state unsubscription"))) {
02520       cc_unref(agent, "Unref agent unsubscribing from devstate failed");
02521    }
02522    ast_cc_agent_caller_available(agent->core_id, "%s is no longer busy", agent->device_name);
02523 }
02524 
02525 static int cc_generic_agent_start_monitoring(struct ast_cc_agent *agent)
02526 {
02527    struct cc_generic_agent_pvt *generic_pvt = agent->private_data;
02528    struct ast_str *str = ast_str_alloca(128);
02529 
02530    ast_assert(generic_pvt->sub == NULL);
02531    ast_str_set(&str, 0, "Agent monitoring %s device state since it is busy\n",
02532       agent->device_name);
02533 
02534    if (!(generic_pvt->sub = ast_event_subscribe(AST_EVENT_DEVICE_STATE,
02535       generic_agent_devstate_cb, ast_str_buffer(str), agent,
02536       AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, agent->device_name,
02537       AST_EVENT_IE_STATE, AST_EVENT_IE_PLTYPE_EXISTS,
02538       AST_EVENT_IE_END))) {
02539       return -1;
02540    }
02541    return 0;
02542 }
02543 
02544 static void *generic_recall(void *data)
02545 {
02546    struct ast_cc_agent *agent = data;
02547    struct cc_generic_agent_pvt *generic_pvt = agent->private_data;
02548    const char *interface = S_OR(ast_get_cc_agent_dialstring(agent->cc_params), ast_strdupa(agent->device_name));
02549    const char *tech;
02550    char *target;
02551    int reason;
02552    struct ast_channel *chan;
02553    const char *callback_macro = ast_get_cc_callback_macro(agent->cc_params);
02554    unsigned int recall_timer = ast_get_cc_recall_timer(agent->cc_params) * 1000;
02555 
02556    tech = interface;
02557    if ((target = strchr(interface, '/'))) {
02558       *target++ = '\0';
02559    }
02560    if (!(chan = ast_request_and_dial(tech, AST_FORMAT_SLINEAR, NULL, target, recall_timer, &reason, generic_pvt->cid_num, generic_pvt->cid_name))) {
02561       /* Hmm, no channel. Sucks for you, bud.
02562        */
02563       ast_log_dynamic_level(cc_logger_level, "Core %d: Failed to call back %s for reason %d\n",
02564             agent->core_id, agent->device_name, reason);
02565       ast_cc_failed(agent->core_id, "Failed to call back device %s/%s", tech, target);
02566       return NULL;
02567    }
02568    
02569    /* We have a channel. It's time now to set up the datastore of recalled CC interfaces.
02570     * This will be a common task for all recall functions. If it were possible, I'd have
02571     * the core do it automatically, but alas I cannot. Instead, I will provide a public
02572     * function to do so.
02573     */
02574    ast_setup_cc_recall_datastore(chan, agent->core_id);
02575    ast_cc_agent_set_interfaces_chanvar(chan);
02576 
02577    ast_copy_string(chan->exten, generic_pvt->exten, sizeof(chan->exten));
02578    ast_copy_string(chan->context, generic_pvt->context, sizeof(chan->context));
02579    chan->priority = 1;
02580 
02581    pbx_builtin_setvar_helper(chan, "CC_EXTEN", generic_pvt->exten);
02582    pbx_builtin_setvar_helper(chan, "CC_CONTEXT", generic_pvt->context);
02583 
02584    if (!ast_strlen_zero(callback_macro)) {
02585       ast_log_dynamic_level(cc_logger_level, "Core %d: There's a callback macro configured for agent %s\n",
02586             agent->core_id, agent->device_name);
02587       if (ast_app_run_macro(NULL, chan, callback_macro, NULL)) {
02588          ast_cc_failed(agent->core_id, "Callback macro to %s failed. Maybe a hangup?", agent->device_name);
02589          ast_hangup(chan);
02590          return NULL;
02591       }
02592    }
02593    ast_cc_agent_recalling(agent->core_id, "Generic agent %s is recalling", agent->device_name);
02594    ast_pbx_start(chan);
02595    return NULL;
02596 }
02597 
02598 static int cc_generic_agent_recall(struct ast_cc_agent *agent)
02599 {
02600    pthread_t clotho;
02601    enum ast_device_state current_state = ast_device_state(agent->device_name);
02602 
02603    if (!cc_generic_is_device_available(current_state)) {
02604       /* We can't try to contact the device right now because he's not available
02605        * Let the core know he's busy.
02606        */
02607       ast_cc_agent_caller_busy(agent->core_id, "Generic agent caller %s is busy", agent->device_name);
02608       return 0;
02609    }
02610    ast_pthread_create_detached_background(&clotho, NULL, generic_recall, agent);
02611    return 0;
02612 }
02613 
02614 static void cc_generic_agent_destructor(struct ast_cc_agent *agent)
02615 {
02616    struct cc_generic_agent_pvt *agent_pvt = agent->private_data;
02617 
02618    if (!agent_pvt) {
02619       /* The agent constructor probably failed. */
02620       return;
02621    }
02622 
02623    cc_generic_agent_stop_offer_timer(agent);
02624    if (agent_pvt->sub) {
02625       agent_pvt->sub = ast_event_unsubscribe(agent_pvt->sub);
02626    }
02627 
02628    ast_free(agent_pvt);
02629 }
02630 
02631 static void cc_core_instance_destructor(void *data)
02632 {
02633    struct cc_core_instance *core_instance = data;
02634    ast_log_dynamic_level(cc_logger_level, "Core %d: Destroying core instance\n", core_instance->core_id);
02635    if (core_instance->agent) {
02636       cc_unref(core_instance->agent, "Core instance is done with the agent now");
02637    }
02638    if (core_instance->monitors) {
02639       core_instance->monitors = cc_unref(core_instance->monitors, "Core instance is done with interface list");
02640    }
02641 }
02642 
02643 static struct cc_core_instance *cc_core_init_instance(struct ast_channel *caller_chan,
02644       struct cc_monitor_tree *called_tree, const int core_id, struct cc_control_payload *cc_data)
02645 {
02646    char caller[AST_CHANNEL_NAME];
02647    struct cc_core_instance *core_instance;
02648    struct ast_cc_config_params *cc_params;
02649    long agent_count;
02650    int recall_core_id;
02651 
02652    ast_channel_get_device_name(caller_chan, caller, sizeof(caller));
02653    cc_params = ast_channel_get_cc_config_params(caller_chan);
02654    if (!cc_params) {
02655       ast_log_dynamic_level(cc_logger_level, "Could not get CC parameters for %s\n",
02656          caller);
02657       return NULL;
02658    }
02659    /* First, we need to kill off other pending CC offers from caller. If the caller is going
02660     * to request a CC service, it may only be for the latest call he made.
02661     */
02662    if (ast_get_cc_agent_policy(cc_params) == AST_CC_AGENT_GENERIC) {
02663       kill_duplicate_offers(caller);
02664    }
02665 
02666    ast_cc_is_recall(caller_chan, &recall_core_id, NULL);
02667    agent_count = count_agents(caller, recall_core_id);
02668    if (agent_count >= ast_get_cc_max_agents(cc_params)) {
02669       ast_log_dynamic_level(cc_logger_level, "Caller %s already has the maximum number of agents configured\n", caller);
02670       return NULL;
02671    }
02672 
02673    /* Generic agents can only have a single outstanding CC request per caller. */
02674    if (agent_count > 0 && ast_get_cc_agent_policy(cc_params) == AST_CC_AGENT_GENERIC) {
02675       ast_log_dynamic_level(cc_logger_level, "Generic agents can only have a single outstanding request\n");
02676       return NULL;
02677    }
02678 
02679    /* Next, we need to create the core instance for this call */
02680    if (!(core_instance = ao2_t_alloc(sizeof(*core_instance), cc_core_instance_destructor, "Creating core instance for CC"))) {
02681       return NULL;
02682    }
02683 
02684    core_instance->core_id = core_id;
02685    if (!(core_instance->agent = cc_agent_init(caller_chan, caller, core_instance->core_id, called_tree))) {
02686       cc_unref(core_instance, "Couldn't allocate agent, unref core_instance");
02687       return NULL;
02688    }
02689 
02690    core_instance->monitors = cc_ref(called_tree, "Core instance getting ref to monitor tree");
02691 
02692    ao2_t_link(cc_core_instances, core_instance, "Link core instance into container");
02693 
02694    return core_instance;
02695 }
02696 
02697 struct cc_state_change_args {
02698    struct cc_core_instance *core_instance;/*!< Holds reference to core instance. */
02699    enum cc_state state;
02700    int core_id;
02701    char debug[1];
02702 };
02703 
02704 static int is_state_change_valid(enum cc_state current_state, const enum cc_state new_state, struct ast_cc_agent *agent)
02705 {
02706    int is_valid = 0;
02707    switch (new_state) {
02708    case CC_AVAILABLE:
02709       ast_log_dynamic_level(cc_logger_level, "Core %d: Asked to change to state %d? That should never happen.\n",
02710             agent->core_id, new_state);
02711       break;
02712    case CC_CALLER_OFFERED:
02713       if (current_state == CC_AVAILABLE) {
02714          is_valid = 1;
02715       }
02716       break;
02717    case CC_CALLER_REQUESTED:
02718       if (current_state == CC_CALLER_OFFERED ||
02719             (current_state == CC_AVAILABLE && ast_test_flag(agent, AST_CC_AGENT_SKIP_OFFER))) {
02720          is_valid = 1;
02721       }
02722       break;
02723    case CC_ACTIVE:
02724       if (current_state == CC_CALLER_REQUESTED || current_state == CC_CALLER_BUSY) {
02725          is_valid = 1;
02726       }
02727       break;
02728    case CC_CALLEE_READY:
02729       if (current_state == CC_ACTIVE) {
02730          is_valid = 1;
02731       }
02732       break;
02733    case CC_CALLER_BUSY:
02734       if (current_state == CC_CALLEE_READY) {
02735          is_valid = 1;
02736       }
02737       break;
02738    case CC_RECALLING:
02739       if (current_state == CC_CALLEE_READY) {
02740          is_valid = 1;
02741       }
02742       break;
02743    case CC_COMPLETE:
02744       if (current_state == CC_RECALLING) {
02745          is_valid = 1;
02746       }
02747       break;
02748    case CC_FAILED:
02749       is_valid = 1;
02750       break;
02751    default:
02752       ast_log_dynamic_level(cc_logger_level, "Core %d: Asked to change to unknown state %d\n",
02753             agent->core_id, new_state);
02754       break;
02755    }
02756 
02757    return is_valid;
02758 }
02759 
02760 static int cc_available(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
02761 {
02762    /* This should never happen... */
02763    ast_log(LOG_WARNING, "Someone requested to change to CC_AVAILABLE? Ignoring.\n");
02764    return -1;
02765 }
02766 
02767 static int cc_caller_offered(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
02768 {
02769    if (core_instance->agent->callbacks->start_offer_timer(core_instance->agent)) {
02770       ast_cc_failed(core_instance->core_id, "Failed to start the offer timer for %s\n",
02771             core_instance->agent->device_name);
02772       return -1;
02773    }
02774    manager_event(EVENT_FLAG_CC, "CCOfferTimerStart",
02775       "CoreID: %d\r\n"
02776       "Caller: %s\r\n"
02777       "Expires: %u\r\n",
02778       core_instance->core_id, core_instance->agent->device_name, core_instance->agent->cc_params->cc_offer_timer);
02779    ast_log_dynamic_level(cc_logger_level, "Core %d: Started the offer timer for the agent %s!\n",
02780          core_instance->core_id, core_instance->agent->device_name);
02781    return 0;
02782 }
02783 
02784 /*!
02785  * \brief check if the core instance has any device monitors
02786  *
02787  * In any case where we end up removing a device monitor from the
02788  * list of device monitors, it is important to see what the state
02789  * of the list is afterwards. If we find that we only have extension
02790  * monitors left, then no devices are actually being monitored.
02791  * In such a case, we need to declare that CC has failed for this
02792  * call. This function helps those cases to determine if they should
02793  * declare failure.
02794  *
02795  * \param core_instance The core instance we are checking for the existence
02796  * of device monitors
02797  * \retval 0 No device monitors exist on this core_instance
02798  * \retval 1 There is still at least 1 device monitor remaining
02799  */
02800 static int has_device_monitors(struct cc_core_instance *core_instance)
02801 {
02802    struct ast_cc_monitor *iter;
02803    int res = 0;
02804 
02805    AST_LIST_TRAVERSE(core_instance->monitors, iter, next) {
02806       if (iter->interface->monitor_class == AST_CC_DEVICE_MONITOR) {
02807          res = 1;
02808          break;
02809       }
02810    }
02811 
02812    return res;
02813 }
02814 
02815 static void request_cc(struct cc_core_instance *core_instance)
02816 {
02817    struct ast_cc_monitor *monitor_iter;
02818    AST_LIST_LOCK(core_instance->monitors);
02819    AST_LIST_TRAVERSE_SAFE_BEGIN(core_instance->monitors, monitor_iter, next) {
02820       if (monitor_iter->interface->monitor_class == AST_CC_DEVICE_MONITOR) {
02821          if (monitor_iter->callbacks->request_cc(monitor_iter, &monitor_iter->available_timer_id)) {
02822             AST_LIST_REMOVE_CURRENT(next);
02823             cc_extension_monitor_change_is_valid(core_instance, monitor_iter->parent_id,
02824                   monitor_iter->interface->device_name, 1);
02825             cc_unref(monitor_iter, "request_cc failed. Unref list's reference to monitor");
02826          } else {
02827             manager_event(EVENT_FLAG_CC, "CCRequested",
02828                "CoreID: %d\r\n"
02829                "Caller: %s\r\n"
02830                "Callee: %s\r\n",
02831                core_instance->core_id, core_instance->agent->device_name, monitor_iter->interface->device_name);
02832          }
02833       }
02834    }
02835    AST_LIST_TRAVERSE_SAFE_END;
02836 
02837    if (!has_device_monitors(core_instance)) {
02838       ast_cc_failed(core_instance->core_id, "All device monitors failed to request CC");
02839    }
02840    AST_LIST_UNLOCK(core_instance->monitors);
02841 }
02842 
02843 static int cc_caller_requested(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
02844 {
02845    if (!ast_cc_request_is_within_limits()) {
02846       ast_log(LOG_WARNING, "Cannot request CC since there is no more room for requests\n");
02847       core_instance->agent->callbacks->respond(core_instance->agent,
02848          AST_CC_AGENT_RESPONSE_FAILURE_TOO_MANY);
02849       ast_cc_failed(core_instance->core_id, "Too many requests in the system");
02850       return -1;
02851    }
02852    core_instance->agent->callbacks->stop_offer_timer(core_instance->agent);
02853    request_cc(core_instance);
02854    return 0;
02855 }
02856 
02857 static void unsuspend(struct cc_core_instance *core_instance)
02858 {
02859    struct ast_cc_monitor *monitor_iter;
02860    AST_LIST_LOCK(core_instance->monitors);
02861    AST_LIST_TRAVERSE_SAFE_BEGIN(core_instance->monitors, monitor_iter, next) {
02862       if (monitor_iter->interface->monitor_class == AST_CC_DEVICE_MONITOR) {
02863          if (monitor_iter->callbacks->unsuspend(monitor_iter)) {
02864             AST_LIST_REMOVE_CURRENT(next);
02865             cc_extension_monitor_change_is_valid(core_instance, monitor_iter->parent_id,
02866                   monitor_iter->interface->device_name, 1);
02867             cc_unref(monitor_iter, "unsuspend failed. Unref list's reference to monitor");
02868          }
02869       }
02870    }
02871    AST_LIST_TRAVERSE_SAFE_END;
02872 
02873    if (!has_device_monitors(core_instance)) {
02874       ast_cc_failed(core_instance->core_id, "All device monitors failed to unsuspend CC");
02875    }
02876    AST_LIST_UNLOCK(core_instance->monitors);
02877 }
02878 
02879 static int cc_active(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
02880 {
02881    /* Either
02882     * 1. Callee accepted CC request, call agent's ack callback.
02883     * 2. Caller became available, call agent's stop_monitoring callback and
02884     *    call monitor's unsuspend callback.
02885     */
02886    if (previous_state == CC_CALLER_REQUESTED) {
02887       core_instance->agent->callbacks->respond(core_instance->agent,
02888          AST_CC_AGENT_RESPONSE_SUCCESS);
02889       manager_event(EVENT_FLAG_CC, "CCRequestAcknowledged",
02890          "CoreID: %d\r\n"
02891          "Caller: %s\r\n",
02892          core_instance->core_id, core_instance->agent->device_name);
02893    } else if (previous_state == CC_CALLER_BUSY) {
02894       manager_event(EVENT_FLAG_CC, "CCCallerStopMonitoring",
02895          "CoreID: %d\r\n"
02896          "Caller: %s\r\n",
02897          core_instance->core_id, core_instance->agent->device_name);
02898       unsuspend(core_instance);
02899    }
02900    /* Not possible for previous_state to be anything else due to the is_state_change_valid check at the beginning */
02901    return 0;
02902 }
02903 
02904 static int cc_callee_ready(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
02905 {
02906    core_instance->agent->callbacks->callee_available(core_instance->agent);
02907    return 0;
02908 }
02909 
02910 static void suspend(struct cc_core_instance *core_instance)
02911 {
02912    struct ast_cc_monitor *monitor_iter;
02913    AST_LIST_LOCK(core_instance->monitors);
02914    AST_LIST_TRAVERSE_SAFE_BEGIN(core_instance->monitors, monitor_iter, next) {
02915       if (monitor_iter->interface->monitor_class == AST_CC_DEVICE_MONITOR) {
02916          if (monitor_iter->callbacks->suspend(monitor_iter)) {
02917             AST_LIST_REMOVE_CURRENT(next);
02918             cc_extension_monitor_change_is_valid(core_instance, monitor_iter->parent_id,
02919                   monitor_iter->interface->device_name, 1);
02920             cc_unref(monitor_iter, "suspend failed. Unref list's reference to monitor");
02921          }
02922       }
02923    }
02924    AST_LIST_TRAVERSE_SAFE_END;
02925 
02926    if (!has_device_monitors(core_instance)) {
02927       ast_cc_failed(core_instance->core_id, "All device monitors failed to suspend CC");
02928    }
02929    AST_LIST_UNLOCK(core_instance->monitors);
02930 }
02931 
02932 static int cc_caller_busy(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
02933 {
02934    /* Callee was available, but caller was busy, call agent's begin_monitoring callback
02935     * and call monitor's suspend callback.
02936     */
02937    suspend(core_instance);
02938    core_instance->agent->callbacks->start_monitoring(core_instance->agent);
02939    manager_event(EVENT_FLAG_CC, "CCCallerStartMonitoring",
02940       "CoreID: %d\r\n"
02941       "Caller: %s\r\n",
02942       core_instance->core_id, core_instance->agent->device_name);
02943    return 0;
02944 }
02945 
02946 static void cancel_available_timer(struct cc_core_instance *core_instance)
02947 {
02948    struct ast_cc_monitor *monitor_iter;
02949    AST_LIST_LOCK(core_instance->monitors);
02950    AST_LIST_TRAVERSE_SAFE_BEGIN(core_instance->monitors, monitor_iter, next) {
02951       if (monitor_iter->interface->monitor_class == AST_CC_DEVICE_MONITOR) {
02952          if (monitor_iter->callbacks->cancel_available_timer(monitor_iter, &monitor_iter->available_timer_id)) {
02953             AST_LIST_REMOVE_CURRENT(next);
02954             cc_extension_monitor_change_is_valid(core_instance, monitor_iter->parent_id,
02955                   monitor_iter->interface->device_name, 1);
02956             cc_unref(monitor_iter, "cancel_available_timer failed. Unref list's reference to monitor");
02957          }
02958       }
02959    }
02960    AST_LIST_TRAVERSE_SAFE_END;
02961 
02962    if (!has_device_monitors(core_instance)) {
02963       ast_cc_failed(core_instance->core_id, "All device monitors failed to cancel their available timers");
02964    }
02965    AST_LIST_UNLOCK(core_instance->monitors);
02966 }
02967 
02968 static int cc_recalling(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
02969 {
02970    /* Both caller and callee are available, call agent's recall callback
02971     */
02972    cancel_available_timer(core_instance);
02973    manager_event(EVENT_FLAG_CC, "CCCallerRecalling",
02974       "CoreID: %d\r\n"
02975       "Caller: %s\r\n",
02976       core_instance->core_id, core_instance->agent->device_name);
02977    return 0;
02978 }
02979 
02980 static int cc_complete(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
02981 {
02982    /* Recall has made progress, call agent and monitor destructor functions
02983     */
02984    manager_event(EVENT_FLAG_CC, "CCRecallComplete",
02985       "CoreID: %d\r\n"
02986       "Caller: %s\r\n",
02987       core_instance->core_id, core_instance->agent->device_name);
02988    ao2_t_unlink(cc_core_instances, core_instance, "Unlink core instance since CC recall has completed");
02989    return 0;
02990 }
02991 
02992 static int cc_failed(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
02993 {
02994    manager_event(EVENT_FLAG_CC, "CCFailure",
02995       "CoreID: %d\r\n"
02996       "Caller: %s\r\n"
02997       "Reason: %s\r\n",
02998       core_instance->core_id, core_instance->agent->device_name, args->debug);
02999    ao2_t_unlink(cc_core_instances, core_instance, "Unlink core instance since CC failed");
03000    return 0;
03001 }
03002 
03003 static int (* const state_change_funcs [])(struct cc_core_instance *, struct cc_state_change_args *, enum cc_state previous_state) = {
03004    [CC_AVAILABLE] = cc_available,
03005    [CC_CALLER_OFFERED] = cc_caller_offered,
03006    [CC_CALLER_REQUESTED] = cc_caller_requested,
03007    [CC_ACTIVE] = cc_active,
03008    [CC_CALLEE_READY] = cc_callee_ready,
03009    [CC_CALLER_BUSY] = cc_caller_busy,
03010    [CC_RECALLING] = cc_recalling,
03011    [CC_COMPLETE] = cc_complete,
03012    [CC_FAILED] = cc_failed,
03013 };
03014 
03015 static int cc_do_state_change(void *datap)
03016 {
03017    struct cc_state_change_args *args = datap;
03018    struct cc_core_instance *core_instance;
03019    enum cc_state previous_state;
03020    int res;
03021 
03022    ast_log_dynamic_level(cc_logger_level, "Core %d: State change to %d requested. Reason: %s\n",
03023          args->core_id, args->state, args->debug);
03024 
03025    core_instance = args->core_instance;
03026 
03027    if (!is_state_change_valid(core_instance->current_state, args->state, core_instance->agent)) {
03028       ast_log_dynamic_level(cc_logger_level, "Core %d: Invalid state change requested. Cannot go from %s to %s\n",
03029             args->core_id, cc_state_to_string(core_instance->current_state), cc_state_to_string(args->state));
03030       if (args->state == CC_CALLER_REQUESTED) {
03031          /*
03032           * For out-of-order requests, we need to let the requester know that
03033           * we can't handle the request now.
03034           */
03035          core_instance->agent->callbacks->respond(core_instance->agent,
03036             AST_CC_AGENT_RESPONSE_FAILURE_INVALID);
03037       }
03038       ast_free(args);
03039       cc_unref(core_instance, "Unref core instance from when it was found earlier");
03040       return -1;
03041    }
03042 
03043    /* We can change to the new state now. */
03044    previous_state = core_instance->current_state;
03045    core_instance->current_state = args->state;
03046    res = state_change_funcs[core_instance->current_state](core_instance, args, previous_state);
03047 
03048    ast_free(args);
03049    cc_unref(core_instance, "Unref since state change has completed"); /* From ao2_find */
03050    return res;
03051 }
03052 
03053 static int cc_request_state_change(enum cc_state state, const int core_id, const char *debug, va_list ap)
03054 {
03055    int res;
03056    int debuglen;
03057    char dummy[1];
03058    va_list aq;
03059    struct cc_core_instance *core_instance;
03060    struct cc_state_change_args *args;
03061    /* This initial call to vsnprintf is simply to find what the
03062     * size of the string needs to be
03063     */
03064    va_copy(aq, ap);
03065    /* We add 1 to the result since vsnprintf's return does not
03066     * include the terminating null byte
03067     */
03068    debuglen = vsnprintf(dummy, sizeof(dummy), debug, aq) + 1;
03069    va_end(aq);
03070 
03071    if (!(args = ast_calloc(1, sizeof(*args) + debuglen))) {
03072       return -1;
03073    }
03074 
03075    core_instance = find_cc_core_instance(core_id);
03076    if (!core_instance) {
03077       ast_log_dynamic_level(cc_logger_level, "Core %d: Unable to find core instance.\n",
03078          core_id);
03079       ast_free(args);
03080       return -1;
03081    }
03082 
03083    args->core_instance = core_instance;
03084    args->state = state;
03085    args->core_id = core_id;
03086    vsnprintf(args->debug, debuglen, debug, ap);
03087 
03088    res = ast_taskprocessor_push(cc_core_taskprocessor, cc_do_state_change, args);
03089    if (res) {
03090       cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed");
03091       ast_free(args);
03092    }
03093    return res;
03094 }
03095 
03096 struct cc_recall_ds_data {
03097    int core_id;
03098    char ignore;
03099    char nested;
03100    struct cc_monitor_tree *interface_tree;
03101 };
03102 
03103 static void *cc_recall_ds_duplicate(void *data)
03104 {
03105    struct cc_recall_ds_data *old_data = data;
03106    struct cc_recall_ds_data *new_data = ast_calloc(1, sizeof(*new_data));
03107 
03108    if (!new_data) {
03109       return NULL;
03110    }
03111    new_data->interface_tree = cc_ref(old_data->interface_tree, "Bump refcount of monitor tree for recall datastore duplicate");
03112    new_data->core_id = old_data->core_id;
03113    new_data->nested = 1;
03114    return new_data;
03115 }
03116 
03117 static void cc_recall_ds_destroy(void *data)
03118 {
03119    struct cc_recall_ds_data *recall_data = data;
03120    recall_data->interface_tree = cc_unref(recall_data->interface_tree, "Unref recall monitor tree");
03121    ast_free(recall_data);
03122 }
03123 
03124 static struct ast_datastore_info recall_ds_info = {
03125    .type = "cc_recall",
03126    .duplicate = cc_recall_ds_duplicate,
03127    .destroy = cc_recall_ds_destroy,
03128 };
03129 
03130 int ast_setup_cc_recall_datastore(struct ast_channel *chan, const int core_id)
03131 {
03132    struct ast_datastore *recall_datastore = ast_datastore_alloc(&recall_ds_info, NULL);
03133    struct cc_recall_ds_data *recall_data;
03134    struct cc_core_instance *core_instance;
03135 
03136    if (!recall_datastore) {
03137       return -1;
03138    }
03139 
03140    if (!(recall_data = ast_calloc(1, sizeof(*recall_data)))) {
03141       ast_datastore_free(recall_datastore);
03142       return -1;
03143    }
03144 
03145    if (!(core_instance = find_cc_core_instance(core_id))) {
03146       ast_free(recall_data);
03147       ast_datastore_free(recall_datastore);
03148       return -1;
03149    }
03150 
03151    recall_data->interface_tree = cc_ref(core_instance->monitors,
03152          "Bump refcount for monitor tree for recall datastore");
03153    recall_data->core_id = core_id;
03154    recall_datastore->data = recall_data;
03155    recall_datastore->inheritance = DATASTORE_INHERIT_FOREVER;
03156    ast_channel_lock(chan);
03157    ast_channel_datastore_add(chan, recall_datastore);
03158    ast_channel_unlock(chan);
03159    cc_unref(core_instance, "Recall datastore set up. No need for core_instance ref");
03160    return 0;
03161 }
03162 
03163 int ast_cc_is_recall(struct ast_channel *chan, int *core_id, const char * const monitor_type)
03164 {
03165    struct ast_datastore *recall_datastore;
03166    struct cc_recall_ds_data *recall_data;
03167    struct cc_monitor_tree *interface_tree;
03168    char device_name[AST_CHANNEL_NAME];
03169    struct ast_cc_monitor *device_monitor;
03170    int core_id_candidate;
03171 
03172    ast_assert(core_id != NULL);
03173 
03174    *core_id = -1;
03175 
03176    ast_channel_lock(chan);
03177    if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
03178       /* Obviously not a recall if the datastore isn't present */
03179       ast_channel_unlock(chan);
03180       return 0;
03181    }
03182 
03183    recall_data = recall_datastore->data;
03184 
03185    if (recall_data->ignore) {
03186       /* Though this is a recall, the call to this particular interface is not part of the
03187        * recall either because this is a call forward or because this is not the first
03188        * invocation of Dial during this call
03189        */
03190       ast_channel_unlock(chan);
03191       return 0;
03192    }
03193 
03194    if (!recall_data->nested) {
03195       /* If the nested flag is not set, then this means that
03196        * the channel passed to this function is the caller making
03197        * the recall. This means that we shouldn't look through
03198        * the monitor tree for the channel because it shouldn't be
03199        * there. However, this is a recall though, so return true.
03200        */
03201       *core_id = recall_data->core_id;
03202       ast_channel_unlock(chan);
03203       return 1;
03204    }
03205 
03206    if (ast_strlen_zero(monitor_type)) {
03207       /* If someone passed a NULL or empty monitor type, then it is clear
03208        * the channel they passed in was an incoming channel, and so searching
03209        * the list of dialed interfaces is not going to be helpful. Just return
03210        * false immediately.
03211        */
03212       ast_channel_unlock(chan);
03213       return 0;
03214    }
03215 
03216    interface_tree = recall_data->interface_tree;
03217    ast_channel_get_device_name(chan, device_name, sizeof(device_name));
03218    /* We grab the value of the recall_data->core_id so that we
03219     * can unlock the channel before we start looking through the
03220     * interface list. That way we don't have to worry about a possible
03221     * clash between the channel lock and the monitor tree lock.
03222     */
03223    core_id_candidate = recall_data->core_id;
03224    ast_channel_unlock(chan);
03225 
03226    /*
03227     * Now we need to find out if the channel device name
03228     * is in the list of interfaces in the called tree.
03229     */
03230    AST_LIST_LOCK(interface_tree);
03231    AST_LIST_TRAVERSE(interface_tree, device_monitor, next) {
03232       if (!strcmp(device_monitor->interface->device_name, device_name) &&
03233             !strcmp(device_monitor->interface->monitor_type, monitor_type)) {
03234          /* BOOM! Device is in the tree! We have a winner! */
03235          *core_id = core_id_candidate;
03236          AST_LIST_UNLOCK(interface_tree);
03237          return 1;
03238       }
03239    }
03240    AST_LIST_UNLOCK(interface_tree);
03241    return 0;
03242 }
03243 
03244 struct ast_cc_monitor *ast_cc_get_monitor_by_recall_core_id(const int core_id, const char * const device_name)
03245 {
03246    struct cc_core_instance *core_instance = find_cc_core_instance(core_id);
03247    struct ast_cc_monitor *monitor_iter;
03248 
03249    if (!core_instance) {
03250       return NULL;
03251    }
03252 
03253    AST_LIST_LOCK(core_instance->monitors);
03254    AST_LIST_TRAVERSE(core_instance->monitors, monitor_iter, next) {
03255       if (!strcmp(monitor_iter->interface->device_name, device_name)) {
03256          /* Found a monitor. */
03257          cc_ref(monitor_iter, "Hand the requester of the monitor a reference");
03258          break;
03259       }
03260    }
03261    AST_LIST_UNLOCK(core_instance->monitors);
03262    cc_unref(core_instance, "Done with core instance ref in ast_cc_get_monitor_by_recall_core_id");
03263    return monitor_iter;
03264 }
03265 
03266 /*!
03267  * \internal
03268  * \brief uniquely append a dialstring to our CC_INTERFACES chanvar string.
03269  *
03270  * We will only append a string if it has not already appeared in our channel
03271  * variable earlier. We ensure that we don't erroneously match substrings by
03272  * adding an ampersand to the end of our potential dialstring and searching for
03273  * it plus the ampersand in our variable.
03274  *
03275  * It's important to note that once we have built the full CC_INTERFACES string,
03276  * there will be an extra ampersand at the end which must be stripped off by
03277  * the caller of this function.
03278  *
03279  * \param str An ast_str holding what we will add to CC_INTERFACES
03280  * \param dialstring A new dialstring to add
03281  * \retval void
03282  */
03283 static void cc_unique_append(struct ast_str *str, const char *dialstring)
03284 {
03285    char dialstring_search[AST_CHANNEL_NAME];
03286 
03287    if (ast_strlen_zero(dialstring)) {
03288       /* No dialstring to append. */
03289       return;
03290    }
03291    snprintf(dialstring_search, sizeof(dialstring_search), "%s%c", dialstring, '&');
03292    if (strstr(ast_str_buffer(str), dialstring_search)) {
03293       return;
03294    }
03295    ast_str_append(&str, 0, "%s", dialstring_search);
03296 }
03297 
03298 /*!
03299  * \internal
03300  * \brief Build the CC_INTERFACES channel variable
03301  *
03302  * The method used is to traverse the child dialstrings in the
03303  * passed-in extension monitor, adding any that have the is_valid
03304  * flag set. Then, traverse the monitors, finding all children
03305  * of the starting extension monitor and adding their dialstrings
03306  * as well.
03307  *
03308  * \param starting_point The extension monitor that is the parent to all
03309  * monitors whose dialstrings should be added to CC_INTERFACES
03310  * \param str Where we will store CC_INTERFACES
03311  * \retval void
03312  */
03313 static void build_cc_interfaces_chanvar(struct ast_cc_monitor *starting_point, struct ast_str *str)
03314 {
03315    struct extension_monitor_pvt *extension_pvt;
03316    struct extension_child_dialstring *child_dialstring;
03317    struct ast_cc_monitor *monitor_iter = starting_point;
03318    int top_level_id = starting_point->id;
03319    size_t length;
03320 
03321    /* Init to an empty string. */
03322    ast_str_truncate(str, 0);
03323 
03324    /* First we need to take all of the is_valid child_dialstrings from
03325     * the extension monitor we found and add them to the CC_INTERFACES
03326     * chanvar
03327     */
03328    extension_pvt = starting_point->private_data;
03329    AST_LIST_TRAVERSE(&extension_pvt->child_dialstrings, child_dialstring, next) {
03330       if (child_dialstring->is_valid) {
03331          cc_unique_append(str, child_dialstring->original_dialstring);
03332       }
03333    }
03334 
03335    /* And now we get the dialstrings from each of the device monitors */
03336    while ((monitor_iter = AST_LIST_NEXT(monitor_iter, next))) {
03337       if (monitor_iter->parent_id == top_level_id) {
03338          cc_unique_append(str, monitor_iter->dialstring);
03339       }
03340    }
03341 
03342    /* str will have an extra '&' tacked onto the end of it, so we need
03343     * to get rid of that.
03344     */
03345    length = ast_str_strlen(str);
03346    if (length) {
03347       ast_str_truncate(str, length - 1);
03348    }
03349    if (length <= 1) {
03350       /* Nothing to recall?  This should not happen. */
03351       ast_log(LOG_ERROR, "CC_INTERFACES is empty. starting device_name:'%s'\n",
03352          starting_point->interface->device_name);
03353    }
03354 }
03355 
03356 int ast_cc_agent_set_interfaces_chanvar(struct ast_channel *chan)
03357 {
03358    struct ast_datastore *recall_datastore;
03359    struct cc_monitor_tree *interface_tree;
03360    struct ast_cc_monitor *monitor;
03361    struct cc_recall_ds_data *recall_data;
03362    struct ast_str *str = ast_str_create(64);
03363    int core_id;
03364 
03365    if (!str) {
03366       return -1;
03367    }
03368 
03369    ast_channel_lock(chan);
03370    if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
03371       ast_channel_unlock(chan);
03372       ast_free(str);
03373       return -1;
03374    }
03375    recall_data = recall_datastore->data;
03376    interface_tree = recall_data->interface_tree;
03377    core_id = recall_data->core_id;
03378    ast_channel_unlock(chan);
03379 
03380    AST_LIST_LOCK(interface_tree);
03381    monitor = AST_LIST_FIRST(interface_tree);
03382    build_cc_interfaces_chanvar(monitor, str);
03383    AST_LIST_UNLOCK(interface_tree);
03384 
03385    pbx_builtin_setvar_helper(chan, "CC_INTERFACES", ast_str_buffer(str));
03386    ast_log_dynamic_level(cc_logger_level, "Core %d: CC_INTERFACES set to %s\n",
03387          core_id, ast_str_buffer(str));
03388 
03389    ast_free(str);
03390    return 0;
03391 }
03392 
03393 int ast_set_cc_interfaces_chanvar(struct ast_channel *chan, const char * const extension)
03394 {
03395    struct ast_datastore *recall_datastore;
03396    struct cc_monitor_tree *interface_tree;
03397    struct ast_cc_monitor *monitor_iter;
03398    struct cc_recall_ds_data *recall_data;
03399    struct ast_str *str = ast_str_create(64);
03400    int core_id;
03401 
03402    if (!str) {
03403       return -1;
03404    }
03405 
03406    ast_channel_lock(chan);
03407    if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
03408       ast_channel_unlock(chan);
03409       ast_free(str);
03410       return -1;
03411    }
03412    recall_data = recall_datastore->data;
03413    interface_tree = recall_data->interface_tree;
03414    core_id = recall_data->core_id;
03415    ast_channel_unlock(chan);
03416 
03417    AST_LIST_LOCK(interface_tree);
03418    AST_LIST_TRAVERSE(interface_tree, monitor_iter, next) {
03419       if (!strcmp(monitor_iter->interface->device_name, extension)) {
03420          break;
03421       }
03422    }
03423 
03424    if (!monitor_iter) {
03425       /* We couldn't find this extension. This may be because
03426        * we have been directed into an unexpected extension because
03427        * the admin has changed a CC_INTERFACES variable at some point.
03428        */
03429       AST_LIST_UNLOCK(interface_tree);
03430       ast_free(str);
03431       return -1;
03432    }
03433 
03434    build_cc_interfaces_chanvar(monitor_iter, str);
03435    AST_LIST_UNLOCK(interface_tree);
03436 
03437    pbx_builtin_setvar_helper(chan, "CC_INTERFACES", ast_str_buffer(str));
03438    ast_log_dynamic_level(cc_logger_level, "Core %d: CC_INTERFACES set to %s\n",
03439          core_id, ast_str_buffer(str));
03440 
03441    ast_free(str);
03442    return 0;
03443 }
03444 
03445 void ast_ignore_cc(struct ast_channel *chan)
03446 {
03447    struct ast_datastore *cc_datastore;
03448    struct ast_datastore *cc_recall_datastore;
03449    struct dialed_cc_interfaces *cc_interfaces;
03450    struct cc_recall_ds_data *recall_cc_data;
03451 
03452    ast_channel_lock(chan);
03453    if ((cc_datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL))) {
03454       cc_interfaces = cc_datastore->data;
03455       cc_interfaces->ignore = 1;
03456    }
03457 
03458    if ((cc_recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
03459       recall_cc_data = cc_recall_datastore->data;
03460       recall_cc_data->ignore = 1;
03461    }
03462    ast_channel_unlock(chan);
03463 }
03464 
03465 static __attribute__((format(printf, 2, 3))) int cc_offer(const int core_id, const char * const debug, ...)
03466 {
03467    va_list ap;
03468    int res;
03469 
03470    va_start(ap, debug);
03471    res = cc_request_state_change(CC_CALLER_OFFERED, core_id, debug, ap);
03472    va_end(ap);
03473    return res;
03474 }
03475 
03476 int ast_cc_offer(struct ast_channel *caller_chan)
03477 {
03478    int core_id;
03479    int res = -1;
03480    struct ast_datastore *datastore;
03481    struct dialed_cc_interfaces *cc_interfaces;
03482    char cc_is_offerable;
03483 
03484    ast_channel_lock(caller_chan);
03485    if (!(datastore = ast_channel_datastore_find(caller_chan, &dialed_cc_interfaces_info, NULL))) {
03486       ast_channel_unlock(caller_chan);
03487       return res;
03488    }
03489 
03490    cc_interfaces = datastore->data;
03491    cc_is_offerable = cc_interfaces->is_original_caller;
03492    core_id = cc_interfaces->core_id;
03493    ast_channel_unlock(caller_chan);
03494 
03495    if (cc_is_offerable) {
03496       res = cc_offer(core_id, "CC offered to caller %s", caller_chan->name);
03497    }
03498    return res;
03499 }
03500 
03501 int ast_cc_agent_accept_request(int core_id, const char * const debug, ...)
03502 {
03503    va_list ap;
03504    int res;
03505 
03506    va_start(ap, debug);
03507    res = cc_request_state_change(CC_CALLER_REQUESTED, core_id, debug, ap);
03508    va_end(ap);
03509    return res;
03510 }
03511 
03512 int ast_cc_monitor_request_acked(int core_id, const char * const debug, ...)
03513 {
03514    va_list ap;
03515    int res;
03516 
03517    va_start(ap, debug);
03518    res = cc_request_state_change(CC_ACTIVE, core_id, debug, ap);
03519    va_end(ap);
03520    return res;
03521 }
03522 
03523 int ast_cc_monitor_callee_available(const int core_id, const char * const debug, ...)
03524 {
03525    va_list ap;
03526    int res;
03527 
03528    va_start(ap, debug);
03529    res = cc_request_state_change(CC_CALLEE_READY, core_id, debug, ap);
03530    va_end(ap);
03531    return res;
03532 }
03533 
03534 int ast_cc_agent_caller_busy(int core_id, const char * debug, ...)
03535 {
03536    va_list ap;
03537    int res;
03538 
03539    va_start(ap, debug);
03540    res = cc_request_state_change(CC_CALLER_BUSY, core_id, debug, ap);
03541    va_end(ap);
03542    return res;
03543 }
03544 
03545 int ast_cc_agent_caller_available(int core_id, const char * const debug, ...)
03546 {
03547    va_list ap;
03548    int res;
03549 
03550    va_start(ap, debug);
03551    res = cc_request_state_change(CC_ACTIVE, core_id, debug, ap);
03552    va_end(ap);
03553    return res;
03554 }
03555 
03556 int ast_cc_agent_recalling(int core_id, const char * const debug, ...)
03557 {
03558    va_list ap;
03559    int res;
03560 
03561    va_start(ap, debug);
03562    res = cc_request_state_change(CC_RECALLING, core_id, debug, ap);
03563    va_end(ap);
03564    return res;
03565 }
03566 
03567 int ast_cc_completed(struct ast_channel *chan, const char * const debug, ...)
03568 {
03569    struct ast_datastore *recall_datastore;
03570    struct cc_recall_ds_data *recall_data;
03571    int core_id;
03572    va_list ap;
03573    int res;
03574 
03575    ast_channel_lock(chan);
03576    if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
03577       /* Silly! Why did you call this function if there's no recall DS? */
03578       ast_channel_unlock(chan);
03579       return -1;
03580    }
03581    recall_data = recall_datastore->data;
03582    if (recall_data->nested || recall_data->ignore) {
03583       /* If this is being called from a nested Dial, it is too
03584        * early to determine if the recall has actually completed.
03585        * The outermost dial is the only one with the authority to
03586        * declare the recall to be complete.
03587        *
03588        * Similarly, if this function has been called when the
03589        * recall has progressed beyond the first dial, this is not
03590        * a legitimate time to declare the recall to be done. In fact,
03591        * that should have been done already.
03592        */
03593       ast_channel_unlock(chan);
03594       return -1;
03595    }
03596    core_id = recall_data->core_id;
03597    ast_channel_unlock(chan);
03598    va_start(ap, debug);
03599    res = cc_request_state_change(CC_COMPLETE, core_id, debug, ap);
03600    va_end(ap);
03601    return res;
03602 }
03603 
03604 int ast_cc_failed(int core_id, const char * const debug, ...)
03605 {
03606    va_list ap;
03607    int res;
03608 
03609    va_start(ap, debug);
03610    res = cc_request_state_change(CC_FAILED, core_id, debug, ap);
03611    va_end(ap);
03612    return res;
03613 }
03614 
03615 struct ast_cc_monitor_failure_data {
03616    const char *device_name;
03617    char *debug;
03618    int core_id;
03619 };
03620 
03621 static int cc_monitor_failed(void *data)
03622 {
03623    struct ast_cc_monitor_failure_data *failure_data = data;
03624    struct cc_core_instance *core_instance;
03625    struct ast_cc_monitor *monitor_iter;
03626 
03627    core_instance = find_cc_core_instance(failure_data->core_id);
03628    if (!core_instance) {
03629       /* Core instance no longer exists or invalid core_id. */
03630       ast_log_dynamic_level(cc_logger_level,
03631          "Core %d: Could not find core instance for device %s '%s'\n",
03632          failure_data->core_id, failure_data->device_name, failure_data->debug);
03633       ast_free((char *) failure_data->device_name);
03634       ast_free((char *) failure_data->debug);
03635       ast_free(failure_data);
03636       return -1;
03637    }
03638 
03639    AST_LIST_LOCK(core_instance->monitors);
03640    AST_LIST_TRAVERSE_SAFE_BEGIN(core_instance->monitors, monitor_iter, next) {
03641       if (monitor_iter->interface->monitor_class == AST_CC_DEVICE_MONITOR) {
03642          if (!strcmp(monitor_iter->interface->device_name, failure_data->device_name)) {
03643             AST_LIST_REMOVE_CURRENT(next);
03644             cc_extension_monitor_change_is_valid(core_instance, monitor_iter->parent_id,
03645                   monitor_iter->interface->device_name, 1);
03646             monitor_iter->callbacks->cancel_available_timer(monitor_iter, &monitor_iter->available_timer_id);
03647             manager_event(EVENT_FLAG_CC, "CCMonitorFailed",
03648                "CoreID: %d\r\n"
03649                "Callee: %s\r\n",
03650                monitor_iter->core_id, monitor_iter->interface->device_name);
03651             cc_unref(monitor_iter, "Monitor reported failure. Unref list's reference.");
03652          }
03653       }
03654    }
03655    AST_LIST_TRAVERSE_SAFE_END;
03656 
03657    if (!has_device_monitors(core_instance)) {
03658       ast_cc_failed(core_instance->core_id, "All monitors have failed\n");
03659    }
03660    AST_LIST_UNLOCK(core_instance->monitors);
03661    cc_unref(core_instance, "Finished with core_instance in cc_monitor_failed\n");
03662 
03663    ast_free((char *) failure_data->device_name);
03664    ast_free((char *) failure_data->debug);
03665    ast_free(failure_data);
03666    return 0;
03667 }
03668 
03669 int ast_cc_monitor_failed(int core_id, const char *const monitor_name, const char * const debug, ...)
03670 {
03671    struct ast_cc_monitor_failure_data *failure_data;
03672    int res;
03673    va_list ap;
03674 
03675    if (!(failure_data = ast_calloc(1, sizeof(*failure_data)))) {
03676       return -1;
03677    }
03678 
03679    if (!(failure_data->device_name = ast_strdup(monitor_name))) {
03680       ast_free(failure_data);
03681       return -1;
03682    }
03683 
03684    va_start(ap, debug);
03685    if (ast_vasprintf(&failure_data->debug, debug, ap) == -1) {
03686       va_end(ap);
03687       ast_free((char *)failure_data->device_name);
03688       ast_free(failure_data);
03689       return -1;
03690    }
03691    va_end(ap);
03692 
03693    failure_data->core_id = core_id;
03694 
03695    res = ast_taskprocessor_push(cc_core_taskprocessor, cc_monitor_failed, failure_data);
03696    if (res) {
03697       ast_free((char *)failure_data->device_name);
03698       ast_free((char *)failure_data->debug);
03699       ast_free(failure_data);
03700    }
03701    return res;
03702 }
03703 
03704 static int cc_status_request(void *data)
03705 {
03706    struct cc_core_instance *core_instance= data;
03707    int res;
03708 
03709    res = core_instance->agent->callbacks->status_request(core_instance->agent);
03710    cc_unref(core_instance, "Status request finished. Unref core instance");
03711    return res;
03712 }
03713 
03714 int ast_cc_monitor_status_request(int core_id)
03715 {
03716    int res;
03717    struct cc_core_instance *core_instance = find_cc_core_instance(core_id);
03718 
03719    if (!core_instance) {
03720       return -1;
03721    }
03722 
03723    res = ast_taskprocessor_push(cc_core_taskprocessor, cc_status_request, core_instance);
03724    if (res) {
03725       cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed");
03726    }
03727    return res;
03728 }
03729 
03730 static int cc_stop_ringing(void *data)
03731 {
03732    struct cc_core_instance *core_instance = data;
03733    int res = 0;
03734 
03735    if (core_instance->agent->callbacks->stop_ringing) {
03736       res = core_instance->agent->callbacks->stop_ringing(core_instance->agent);
03737    }
03738    /* If an agent is being asked to stop ringing, then he needs to be prepared if for
03739     * whatever reason he needs to be called back again. The proper state to be in to
03740     * detect such a circumstance is the CC_ACTIVE state.
03741     *
03742     * We get to this state using the slightly unintuitive method of calling
03743     * ast_cc_monitor_request_acked because it gets us to the proper state.
03744     */
03745    ast_cc_monitor_request_acked(core_instance->core_id, "Agent %s asked to stop ringing. Be prepared to be recalled again.",
03746          core_instance->agent->device_name);
03747    cc_unref(core_instance, "Stop ringing finished. Unref core_instance");
03748    return res;
03749 }
03750 
03751 int ast_cc_monitor_stop_ringing(int core_id)
03752 {
03753    int res;
03754    struct cc_core_instance *core_instance = find_cc_core_instance(core_id);
03755 
03756    if (!core_instance) {
03757       return -1;
03758    }
03759 
03760    res = ast_taskprocessor_push(cc_core_taskprocessor, cc_stop_ringing, core_instance);
03761    if (res) {
03762       cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed");
03763    }
03764    return res;
03765 }
03766 
03767 static int cc_party_b_free(void *data)
03768 {
03769    struct cc_core_instance *core_instance = data;
03770    int res = 0;
03771 
03772    if (core_instance->agent->callbacks->party_b_free) {
03773       res = core_instance->agent->callbacks->party_b_free(core_instance->agent);
03774    }
03775    cc_unref(core_instance, "Party B free finished. Unref core_instance");
03776    return res;
03777 }
03778 
03779 int ast_cc_monitor_party_b_free(int core_id)
03780 {
03781    int res;
03782    struct cc_core_instance *core_instance = find_cc_core_instance(core_id);
03783 
03784    if (!core_instance) {
03785       return -1;
03786    }
03787 
03788    res = ast_taskprocessor_push(cc_core_taskprocessor, cc_party_b_free, core_instance);
03789    if (res) {
03790       cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed");
03791    }
03792    return res;
03793 }
03794 
03795 struct cc_status_response_args {
03796    struct cc_core_instance *core_instance;
03797    enum ast_device_state devstate;
03798 };
03799 
03800 static int cc_status_response(void *data)
03801 {
03802    struct cc_status_response_args *args = data;
03803    struct cc_core_instance *core_instance = args->core_instance;
03804    struct ast_cc_monitor *monitor_iter;
03805    enum ast_device_state devstate = args->devstate;
03806 
03807    ast_free(args);
03808 
03809    AST_LIST_LOCK(core_instance->monitors);
03810    AST_LIST_TRAVERSE(core_instance->monitors, monitor_iter, next) {
03811       if (monitor_iter->interface->monitor_class == AST_CC_DEVICE_MONITOR &&
03812             monitor_iter->callbacks->status_response) {
03813          monitor_iter->callbacks->status_response(monitor_iter, devstate);
03814       }
03815    }
03816    AST_LIST_UNLOCK(core_instance->monitors);
03817    cc_unref(core_instance, "Status response finished. Unref core instance");
03818    return 0;
03819 }
03820 
03821 int ast_cc_agent_status_response(int core_id, enum ast_device_state devstate)
03822 {
03823    struct cc_status_response_args *args;
03824    struct cc_core_instance *core_instance;
03825    int res;
03826 
03827    args = ast_calloc(1, sizeof(*args));
03828    if (!args) {
03829       return -1;
03830    }
03831 
03832    core_instance = find_cc_core_instance(core_id);
03833    if (!core_instance) {
03834       ast_free(args);
03835       return -1;
03836    }
03837 
03838    args->core_instance = core_instance;
03839    args->devstate = devstate;
03840 
03841    res = ast_taskprocessor_push(cc_core_taskprocessor, cc_status_response, args);
03842    if (res) {
03843       cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed");
03844       ast_free(args);
03845    }
03846    return res;
03847 }
03848 
03849 static int cc_build_payload(struct ast_channel *chan, struct ast_cc_config_params *cc_params,
03850    const char *monitor_type, const char * const device_name, const char * dialstring,
03851    enum ast_cc_service_type service, void *private_data, struct cc_control_payload *payload)
03852 {
03853    struct ast_datastore *datastore;
03854    struct dialed_cc_interfaces *cc_interfaces;
03855    int dial_parent_id;
03856 
03857    ast_channel_lock(chan);
03858    datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL);
03859    if (!datastore) {
03860       ast_channel_unlock(chan);
03861       return -1;
03862    }
03863    cc_interfaces = datastore->data;
03864    dial_parent_id = cc_interfaces->dial_parent_id;
03865    ast_channel_unlock(chan);
03866 
03867    payload->monitor_type = monitor_type;
03868    payload->private_data = private_data;
03869    payload->service = service;
03870    ast_cc_copy_config_params(&payload->config_params, cc_params);
03871    payload->parent_interface_id = dial_parent_id;
03872    ast_copy_string(payload->device_name, device_name, sizeof(payload->device_name));
03873    ast_copy_string(payload->dialstring, dialstring, sizeof(payload->dialstring));
03874    return 0;
03875 }
03876 
03877 int ast_queue_cc_frame(struct ast_channel *chan, const char *monitor_type,
03878       const char * const dialstring, enum ast_cc_service_type service, void *private_data)
03879 {
03880    struct ast_frame frame = {0,};
03881    char device_name[AST_CHANNEL_NAME];
03882    int retval;
03883    struct ast_cc_config_params *cc_params;
03884 
03885    cc_params = ast_channel_get_cc_config_params(chan);
03886    if (!cc_params) {
03887       return -1;
03888    }
03889    ast_channel_get_device_name(chan, device_name, sizeof(device_name));
03890    if (ast_cc_monitor_count(device_name, monitor_type) >= ast_get_cc_max_monitors(cc_params)) {
03891       ast_log(LOG_NOTICE, "Not queuing a CC frame for device %s since it already has its maximum monitors allocated\n", device_name);
03892       return -1;
03893    }
03894 
03895    if (ast_cc_build_frame(chan, cc_params, monitor_type, device_name, dialstring, service, private_data, &frame)) {
03896       /* Frame building failed. We can't use this. */
03897       return -1;
03898    }
03899    retval = ast_queue_frame(chan, &frame);
03900    ast_frfree(&frame);
03901    return retval;
03902 }
03903 
03904 int ast_cc_build_frame(struct ast_channel *chan, struct ast_cc_config_params *cc_params,
03905    const char *monitor_type, const char * const device_name,
03906    const char * const dialstring, enum ast_cc_service_type service, void *private_data,
03907    struct ast_frame *frame)
03908 {
03909    struct cc_control_payload *payload = ast_calloc(1, sizeof(*payload));
03910 
03911    if (!payload) {
03912       return -1;
03913    }
03914    if (cc_build_payload(chan, cc_params, monitor_type, device_name, dialstring, service, private_data, payload)) {
03915       /* Something screwed up, we can't make a frame with this */
03916       ast_free(payload);
03917       return -1;
03918    }
03919    frame->frametype = AST_FRAME_CONTROL;
03920    frame->subclass.integer = AST_CONTROL_CC;
03921    frame->data.ptr = payload;
03922    frame->datalen = sizeof(*payload);
03923    frame->mallocd = AST_MALLOCD_DATA;
03924    return 0;
03925 }
03926 
03927 void ast_cc_call_failed(struct ast_channel *incoming, struct ast_channel *outgoing, const char * const dialstring)
03928 {
03929    char device_name[AST_CHANNEL_NAME];
03930    struct cc_control_payload payload;
03931    struct ast_cc_config_params *cc_params;
03932 
03933    if (outgoing->hangupcause != AST_CAUSE_BUSY && outgoing->hangupcause != AST_CAUSE_CONGESTION) {
03934       /* It doesn't make sense to try to offer CCBS to the caller if the reason for ast_call
03935        * failing is something other than busy or congestion
03936        */
03937       return;
03938    }
03939 
03940    cc_params = ast_channel_get_cc_config_params(outgoing);
03941    if (!cc_params) {
03942       return;
03943    }
03944    if (ast_get_cc_monitor_policy(cc_params) != AST_CC_MONITOR_GENERIC) {
03945       /* This sort of CCBS only works if using generic CC. For native, we would end up sending
03946        * a CC request for a non-existent call. The far end will reject this every time
03947        */
03948       return;
03949    }
03950 
03951    ast_channel_get_device_name(outgoing, device_name, sizeof(device_name));
03952    if (cc_build_payload(outgoing, cc_params, AST_CC_GENERIC_MONITOR_TYPE, device_name,
03953       dialstring, AST_CC_CCBS, NULL, &payload)) {
03954       /* Something screwed up, we can't make a frame with this */
03955       return;
03956    }
03957    ast_handle_cc_control_frame(incoming, outgoing, &payload);
03958 }
03959 
03960 void ast_cc_busy_interface(struct ast_channel *inbound, struct ast_cc_config_params *cc_params,
03961    const char *monitor_type, const char * const device_name, const char * const dialstring, void *private_data)
03962 {
03963    struct cc_control_payload payload;
03964    if (cc_build_payload(inbound, cc_params, monitor_type, device_name, dialstring, AST_CC_CCBS, private_data, &payload)) {
03965       /* Something screwed up. Don't try to handle this payload */
03966       call_destructor_with_no_monitor(monitor_type, private_data);
03967       return;
03968    }
03969    ast_handle_cc_control_frame(inbound, NULL, &payload);
03970 }
03971 
03972 int ast_cc_callback(struct ast_channel *inbound, const char * const tech, const char * const dest, ast_cc_callback_fn callback)
03973 {
03974    const struct ast_channel_tech *chantech = ast_get_channel_tech(tech);
03975 
03976    if (chantech && chantech->cc_callback) {
03977       chantech->cc_callback(inbound, dest, callback);
03978    }
03979 
03980    return 0;
03981 }
03982 
03983 static const char *ccreq_app = "CallCompletionRequest";
03984 
03985 static int ccreq_exec(struct ast_channel *chan, const char *data)
03986 {
03987    struct cc_core_instance *core_instance;
03988    char device_name[AST_CHANNEL_NAME];
03989    unsigned long match_flags;
03990    int res;
03991 
03992    ast_channel_get_device_name(chan, device_name, sizeof(device_name));
03993 
03994    match_flags = MATCH_NO_REQUEST;
03995    if (!(core_instance = ao2_t_callback_data(cc_core_instances, 0, match_agent, device_name, &match_flags, "Find core instance for CallCompletionRequest"))) {
03996       ast_log_dynamic_level(cc_logger_level, "Couldn't find a core instance for caller %s\n", device_name);
03997       pbx_builtin_setvar_helper(chan, "CC_REQUEST_RESULT", "FAIL");
03998       pbx_builtin_setvar_helper(chan, "CC_REQUEST_REASON", "NO_CORE_INSTANCE");
03999       return 0;
04000    }
04001 
04002    ast_log_dynamic_level(cc_logger_level, "Core %d: Found core_instance for caller %s\n",
04003          core_instance->core_id, device_name);
04004 
04005    if (strcmp(core_instance->agent->callbacks->type, "generic")) {
04006       ast_log_dynamic_level(cc_logger_level, "Core %d: CallCompletionRequest is only for generic agent types.\n",
04007             core_instance->core_id);
04008       pbx_builtin_setvar_helper(chan, "CC_REQUEST_RESULT", "FAIL");
04009       pbx_builtin_setvar_helper(chan, "CC_REQUEST_REASON", "NOT_GENERIC");
04010       cc_unref(core_instance, "Unref core_instance since CallCompletionRequest was called with native agent");
04011       return 0;
04012    }
04013 
04014    if (!ast_cc_request_is_within_limits()) {
04015       ast_log_dynamic_level(cc_logger_level, "Core %d: CallCompletionRequest failed. Too many requests in the system\n",
04016             core_instance->core_id);
04017       ast_cc_failed(core_instance->core_id, "Too many CC requests\n");
04018       pbx_builtin_setvar_helper(chan, "CC_REQUEST_RESULT", "FAIL");
04019       pbx_builtin_setvar_helper(chan, "CC_REQUEST_REASON", "TOO_MANY_REQUESTS");
04020       cc_unref(core_instance, "Unref core_instance since too many CC requests");
04021       return 0;
04022    }
04023 
04024    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);
04025    pbx_builtin_setvar_helper(chan, "CC_REQUEST_RESULT", res ? "FAIL" : "SUCCESS");
04026    if (res) {
04027       pbx_builtin_setvar_helper(chan, "CC_REQUEST_REASON", "UNSPECIFIED");
04028    }
04029 
04030    cc_unref(core_instance, "Done with CallCompletionRequest");
04031    return 0;
04032 }
04033 
04034 static const char *cccancel_app = "CallCompletionCancel";
04035 
04036 static int cccancel_exec(struct ast_channel *chan, const char *data)
04037 {
04038    struct cc_core_instance *core_instance;
04039    char device_name[AST_CHANNEL_NAME];
04040    unsigned long match_flags;
04041    int res;
04042 
04043    ast_channel_get_device_name(chan, device_name, sizeof(device_name));
04044 
04045    match_flags = MATCH_REQUEST;
04046    if (!(core_instance = ao2_t_callback_data(cc_core_instances, 0, match_agent, device_name, &match_flags, "Find core instance for CallCompletionCancel"))) {
04047       ast_log_dynamic_level(cc_logger_level, "Cannot find CC transaction to cancel for caller %s\n", device_name);
04048       pbx_builtin_setvar_helper(chan, "CC_CANCEL_RESULT", "FAIL");
04049       pbx_builtin_setvar_helper(chan, "CC_CANCEL_REASON", "NO_CORE_INSTANCE");
04050       return 0;
04051    }
04052 
04053    if (strcmp(core_instance->agent->callbacks->type, "generic")) {
04054       ast_log(LOG_WARNING, "CallCompletionCancel may only be used for calles with a generic agent\n");
04055       cc_unref(core_instance, "Unref core instance found during CallCompletionCancel");
04056       pbx_builtin_setvar_helper(chan, "CC_CANCEL_RESULT", "FAIL");
04057       pbx_builtin_setvar_helper(chan, "CC_CANCEL_REASON", "NOT_GENERIC");
04058       return 0;
04059    }
04060    res = ast_cc_failed(core_instance->core_id, "Call completion request Cancelled for core ID %d by caller %s",
04061          core_instance->core_id, device_name);
04062    cc_unref(core_instance, "Unref core instance found during CallCompletionCancel");
04063    pbx_builtin_setvar_helper(chan, "CC_CANCEL_RESULT", res ? "FAIL" : "SUCCESS");
04064    if (res) {
04065       pbx_builtin_setvar_helper(chan, "CC_CANCEL_REASON", "UNSPECIFIED");
04066    }
04067    return 0;
04068 }
04069 
04070 struct count_monitors_cb_data {
04071    const char *device_name;
04072    const char *monitor_type;
04073    int count;
04074 };
04075 
04076 static int count_monitors_cb(void *obj, void *arg, int flags)
04077 {
04078    struct cc_core_instance *core_instance = obj;
04079    struct count_monitors_cb_data *cb_data = arg;
04080    const char *device_name = cb_data->device_name;
04081    const char *monitor_type = cb_data->monitor_type;
04082    struct ast_cc_monitor *monitor_iter;
04083 
04084    AST_LIST_LOCK(core_instance->monitors);
04085    AST_LIST_TRAVERSE(core_instance->monitors, monitor_iter, next) {
04086       if (!strcmp(monitor_iter->interface->device_name, device_name) &&
04087             !strcmp(monitor_iter->interface->monitor_type, monitor_type)) {
04088          cb_data->count++;
04089          break;
04090       }
04091    }
04092    AST_LIST_UNLOCK(core_instance->monitors);
04093    return 0;
04094 }
04095 
04096 int ast_cc_monitor_count(const char * const name, const char * const type)
04097 {
04098    struct count_monitors_cb_data data = {.device_name = name, .monitor_type = type,};
04099 
04100    ao2_t_callback(cc_core_instances, OBJ_NODATA, count_monitors_cb, &data, "Counting agents");
04101    ast_log_dynamic_level(cc_logger_level, "Counted %d monitors\n", data.count);
04102    return data.count;
04103 }
04104 
04105 static void initialize_cc_max_requests(void)
04106 {
04107    struct ast_config *cc_config;
04108    const char *cc_max_requests_str;
04109    struct ast_flags config_flags = {0,};
04110    char *endptr;
04111 
04112    cc_config = ast_config_load2("ccss.conf", "ccss", config_flags);
04113    if (!cc_config || cc_config == CONFIG_STATUS_FILEINVALID) {
04114       ast_log(LOG_WARNING, "Could not find valid ccss.conf file. Using cc_max_requests default\n");
04115       global_cc_max_requests = GLOBAL_CC_MAX_REQUESTS_DEFAULT;
04116       return;
04117    }
04118 
04119    if (!(cc_max_requests_str = ast_variable_retrieve(cc_config, "general", "cc_max_requests"))) {
04120       ast_config_destroy(cc_config);
04121       global_cc_max_requests = GLOBAL_CC_MAX_REQUESTS_DEFAULT;
04122       return;
04123    }
04124 
04125    global_cc_max_requests = strtol(cc_max_requests_str, &endptr, 10);
04126 
04127    if (!ast_strlen_zero(endptr)) {
04128       ast_log(LOG_WARNING, "Invalid input given for cc_max_requests. Using default\n");
04129       global_cc_max_requests = GLOBAL_CC_MAX_REQUESTS_DEFAULT;
04130    }
04131 
04132    ast_config_destroy(cc_config);
04133    return;
04134 }
04135 
04136 static void cc_cli_print_monitor_stats(struct ast_cc_monitor *monitor, int fd, int parent_id)
04137 {
04138    struct ast_cc_monitor *child_monitor_iter = monitor;
04139    if (!monitor) {
04140       return;
04141    }
04142 
04143    ast_cli(fd, "\t\t|-->%s", monitor->interface->device_name);
04144    if (monitor->interface->monitor_class == AST_CC_DEVICE_MONITOR) {
04145       ast_cli(fd, "(%s)", cc_service_to_string(monitor->service_offered));
04146    }
04147    ast_cli(fd, "\n");
04148 
04149    while ((child_monitor_iter = AST_LIST_NEXT(child_monitor_iter, next))) {
04150       if (child_monitor_iter->parent_id == monitor->id) {
04151          cc_cli_print_monitor_stats(child_monitor_iter, fd, child_monitor_iter->id);
04152       }
04153    }
04154 }
04155 
04156 static int print_stats_cb(void *obj, void *arg, int flags)
04157 {
04158    int *cli_fd = arg;
04159    struct cc_core_instance *core_instance = obj;
04160 
04161    ast_cli(*cli_fd, "%d\t\t%s\t\t%s\n", core_instance->core_id, core_instance->agent->device_name,
04162          cc_state_to_string(core_instance->current_state));
04163    AST_LIST_LOCK(core_instance->monitors);
04164    cc_cli_print_monitor_stats(AST_LIST_FIRST(core_instance->monitors), *cli_fd, 0);
04165    AST_LIST_UNLOCK(core_instance->monitors);
04166    return 0;
04167 }
04168 
04169 static int cc_cli_output_status(void *data)
04170 {
04171    int *cli_fd = data;
04172    int count = ao2_container_count(cc_core_instances);
04173 
04174    if (!count) {
04175       ast_cli(*cli_fd, "There are currently no active call completion transactions\n");
04176    } else {
04177       ast_cli(*cli_fd, "%d Call completion transactions\n", count);
04178       ast_cli(*cli_fd, "Core ID\t\tCaller\t\t\t\tStatus\n");
04179       ast_cli(*cli_fd, "----------------------------------------------------------------------------\n");
04180       ao2_t_callback(cc_core_instances, OBJ_NODATA, print_stats_cb, cli_fd, "Printing stats to CLI");
04181    }
04182    ast_free(cli_fd);
04183    return 0;
04184 }
04185 
04186 static char *handle_cc_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
04187 {
04188    int *cli_fd;
04189 
04190    switch (cmd) {
04191    case CLI_INIT:
04192       e->command = "cc report status";
04193       e->usage =
04194          "Usage: cc report status\n"
04195          "       Report the current status of any ongoing CC transactions\n";
04196       return NULL;
04197    case CLI_GENERATE:
04198       return NULL;
04199    }
04200 
04201    if (a->argc != 3) {
04202       return CLI_SHOWUSAGE;
04203    }
04204 
04205    cli_fd = ast_malloc(sizeof(*cli_fd));
04206    if (!cli_fd) {
04207       return CLI_FAILURE;
04208    }
04209 
04210    *cli_fd = a->fd;
04211 
04212    if (ast_taskprocessor_push(cc_core_taskprocessor, cc_cli_output_status, cli_fd)) {
04213       ast_free(cli_fd);
04214       return CLI_FAILURE;
04215    }
04216    return CLI_SUCCESS;
04217 }
04218 
04219 static int kill_cores(void *obj, void *arg, int flags)
04220 {
04221    int *core_id = arg;
04222    struct cc_core_instance *core_instance = obj;
04223 
04224    if (!core_id || (core_instance->core_id == *core_id)) {
04225       ast_cc_failed(core_instance->core_id, "CC transaction canceled administratively\n");
04226    }
04227    return 0;
04228 }
04229 
04230 static char *complete_core_id(const char *line, const char *word, int pos, int state)
04231 {
04232    int which = 0;
04233    int wordlen = strlen(word);
04234    char *ret = NULL;
04235    struct ao2_iterator core_iter = ao2_iterator_init(cc_core_instances, 0);
04236    struct cc_core_instance *core_instance;
04237 
04238    for (; (core_instance = ao2_t_iterator_next(&core_iter, "Next core instance"));
04239          cc_unref(core_instance, "CLI tab completion iteration")) {
04240       char core_id_str[20];
04241       snprintf(core_id_str, sizeof(core_id_str), "%d", core_instance->core_id);
04242       if (!strncmp(word, core_id_str, wordlen) && ++which > state) {
04243          ret = ast_strdup(core_id_str);
04244          cc_unref(core_instance, "Found a matching core ID for CLI tab-completion");
04245          break;
04246       }
04247    }
04248    ao2_iterator_destroy(&core_iter);
04249 
04250    return ret;
04251 }
04252 
04253 static char *handle_cc_kill(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
04254 {
04255    static const char * const option[] = { "core", "all", NULL };
04256 
04257    switch (cmd) {
04258    case CLI_INIT:
04259       e->command = "cc cancel";
04260       e->usage =
04261          "Usage: cc cancel can be used in two ways.\n"
04262          "       1. 'cc cancel core [core ID]' will cancel the CC transaction with\n"
04263          "          core ID equal to the specified core ID.\n"
04264          "       2. 'cc cancel all' will cancel all active CC transactions.\n";
04265       return NULL;
04266    case CLI_GENERATE:
04267       if (a->pos == 2) {
04268          return ast_cli_complete(a->word, option, a->n);
04269       }
04270       if (a->pos == 3) {
04271          return complete_core_id(a->line, a->word, a->pos, a->n);
04272       }
04273       return NULL;
04274    }
04275 
04276    if (a->argc == 4) {
04277       int core_id;
04278       char *endptr;
04279       if (strcasecmp(a->argv[2], "core")) {
04280          return CLI_SHOWUSAGE;
04281       }
04282       core_id = strtol(a->argv[3], &endptr, 10);
04283       if ((errno != 0 && core_id == 0) || (endptr == a->argv[3])) {
04284          return CLI_SHOWUSAGE;
04285       }
04286       ao2_t_callback(cc_core_instances, OBJ_NODATA, kill_cores, &core_id, "CLI Killing Core Id");
04287    } else if (a->argc == 3) {
04288       if (strcasecmp(a->argv[2], "all")) {
04289          return CLI_SHOWUSAGE;
04290       }
04291       ao2_t_callback(cc_core_instances, OBJ_NODATA, kill_cores, NULL, "CLI Killing all CC cores");
04292    } else {
04293       return CLI_SHOWUSAGE;
04294    }
04295 
04296    return CLI_SUCCESS;
04297 }
04298 
04299 static struct ast_cli_entry cc_cli[] = {
04300    AST_CLI_DEFINE(handle_cc_status, "Reports CC stats"),
04301    AST_CLI_DEFINE(handle_cc_kill, "Kill a CC transaction"),
04302 };
04303 
04304 int ast_cc_init(void)
04305 {
04306    int res;
04307 
04308    if (!(cc_core_instances = ao2_t_container_alloc(CC_CORE_INSTANCES_BUCKETS,
04309                cc_core_instance_hash_fn, cc_core_instance_cmp_fn,
04310                "Create core instance container"))) {
04311       return -1;
04312    }
04313    if (!(generic_monitors = ao2_t_container_alloc(CC_CORE_INSTANCES_BUCKETS,
04314                generic_monitor_hash_fn, generic_monitor_cmp_fn,
04315                "Create generic monitor container"))) {
04316       return -1;
04317    }
04318    if (!(cc_core_taskprocessor = ast_taskprocessor_get("CCSS core", TPS_REF_DEFAULT))) {
04319       return -1;
04320    }
04321    if (!(cc_sched_thread = ast_sched_thread_create())) {
04322       return -1;
04323    }
04324    res = ast_register_application2(ccreq_app, ccreq_exec, NULL, NULL, NULL);
04325    res |= ast_register_application2(cccancel_app, cccancel_exec, NULL, NULL, NULL);
04326    res |= ast_cc_monitor_register(&generic_monitor_cbs);
04327    res |= ast_cc_agent_register(&generic_agent_callbacks);
04328    ast_cli_register_multiple(cc_cli, ARRAY_LEN(cc_cli));
04329    cc_logger_level = ast_logger_register_level(CC_LOGGER_LEVEL_NAME);
04330    dialed_cc_interface_counter = 1;
04331    initialize_cc_max_requests();
04332    return res;
04333 }