mirror of https://github.com/asterisk/asterisk
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1582 lines
55 KiB
1582 lines
55 KiB
/*
|
|
* Asterisk -- An open source telephony toolkit.
|
|
*
|
|
* Copyright (C) 1999 - 2010, Digium, Inc.
|
|
*
|
|
* Mark Michelson <mmichelson@digium.com>
|
|
*
|
|
* See http://www.asterisk.org for more information about
|
|
* the Asterisk project. Please do not directly contact
|
|
* any of the maintainers of this project for assistance;
|
|
* the project provides a web site, mailing lists and IRC
|
|
* channels for your use.
|
|
*
|
|
* This program is free software, distributed under the terms of
|
|
* the GNU General Public License Version 2. See the LICENSE file
|
|
* at the top of the source tree.
|
|
*/
|
|
|
|
/*! \file
|
|
* \brief Call Completion Supplementary Services API
|
|
* \author Mark Michelson <mmichelson@digium.com>
|
|
*/
|
|
|
|
#ifndef _ASTERISK_CCSS_H
|
|
#define _ASTERISK_CCSS_H
|
|
|
|
#include "asterisk.h"
|
|
|
|
#include "asterisk/linkedlists.h"
|
|
#include "asterisk/devicestate.h"
|
|
|
|
enum ast_cc_service_type {
|
|
/* No Service available/requested */
|
|
AST_CC_NONE,
|
|
/* Call Completion Busy Subscriber */
|
|
AST_CC_CCBS,
|
|
/* Call Completion No Response */
|
|
AST_CC_CCNR,
|
|
/* Call Completion Not Logged In (currently SIP only) */
|
|
AST_CC_CCNL,
|
|
};
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief The various possibilities for cc_agent_policy values
|
|
*/
|
|
enum ast_cc_agent_policies {
|
|
/*! Never offer CCSS to the caller */
|
|
AST_CC_AGENT_NEVER,
|
|
/*! Offer CCSS using native signaling */
|
|
AST_CC_AGENT_NATIVE,
|
|
/*! Use generic agent for caller */
|
|
AST_CC_AGENT_GENERIC,
|
|
};
|
|
|
|
/*!
|
|
* \brief agent flags that can alter core behavior
|
|
*/
|
|
enum ast_cc_agent_flags {
|
|
/* Some agent types allow for a caller to
|
|
* request CC without reaching the CC_CALLER_OFFERED
|
|
* state. In other words, the caller can request
|
|
* CC while he is still on the phone from the failed
|
|
* call. The generic agent is an agent which allows
|
|
* for this behavior.
|
|
*/
|
|
AST_CC_AGENT_SKIP_OFFER = (1 << 0),
|
|
};
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief The various possibilities for cc_monitor_policy values
|
|
*/
|
|
enum ast_cc_monitor_policies {
|
|
/*! Never accept CCSS offers from callee */
|
|
AST_CC_MONITOR_NEVER,
|
|
/* CCSS only available if callee offers it through signaling */
|
|
AST_CC_MONITOR_NATIVE,
|
|
/*! Always use CCSS generic monitor for callee
|
|
* Note that if callee offers CCSS natively, we still
|
|
* will use a generic CCSS monitor if this is set
|
|
*/
|
|
AST_CC_MONITOR_GENERIC,
|
|
/*! Accept native CCSS offers, but if no offer is present,
|
|
* use a generic CCSS monitor
|
|
*/
|
|
AST_CC_MONITOR_ALWAYS,
|
|
};
|
|
|
|
/* Forward declaration. Struct is in main/ccss.c */
|
|
struct ast_cc_config_params;
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Queue an AST_CONTROL_CC frame
|
|
*
|
|
* \note
|
|
* Since this function calls ast_queue_frame, the channel will be
|
|
* locked during the course of this function.
|
|
*
|
|
* \param chan The channel onto which to queue the frame
|
|
* \param monitor_type The type of monitor to use when CC is requested
|
|
* \param dialstring The dial string used to call the device
|
|
* \param service The type of CC service the device is willing to offer
|
|
* \param private_data If a native monitor is being used, and some channel-driver-specific private
|
|
* data has been allocated, then this parameter should contain a pointer to that data. If using a generic
|
|
* monitor, this parameter should remain NULL. Note that if this function should fail at some point,
|
|
* it is the responsibility of the caller to free the private data upon return.
|
|
* \retval 0 Success
|
|
* \retval -1 Error
|
|
*/
|
|
int ast_queue_cc_frame(struct ast_channel *chan, const char * const monitor_type,
|
|
const char * const dialstring, enum ast_cc_service_type service, void *private_data);
|
|
|
|
/*!
|
|
* \brief Allocate and initialize an ast_cc_config_params structure
|
|
*
|
|
* \note
|
|
* Reasonable default values are chosen for the parameters upon allocation.
|
|
*
|
|
* \retval NULL Unable to allocate the structure
|
|
* \retval non-NULL A pointer to the newly allocated and initialized structure
|
|
*/
|
|
struct ast_cc_config_params *__ast_cc_config_params_init(const char *file, int line, const char *function);
|
|
|
|
/*!
|
|
* \brief Allocate and initialize an ast_cc_config_params structure
|
|
*
|
|
* \note
|
|
* Reasonable default values are chosen for the parameters upon allocation.
|
|
*
|
|
* \retval NULL Unable to allocate the structure
|
|
* \retval non-NULL A pointer to the newly allocated and initialized structure
|
|
*/
|
|
#define ast_cc_config_params_init() __ast_cc_config_params_init(__FILE__, __LINE__, __PRETTY_FUNCTION__)
|
|
|
|
/*!
|
|
* \brief Free memory from CCSS configuration params
|
|
*
|
|
* \note
|
|
* Just a call to ast_free for now...
|
|
*
|
|
* \param params Pointer to structure whose memory we need to free
|
|
*/
|
|
void ast_cc_config_params_destroy(struct ast_cc_config_params *params);
|
|
|
|
/*!
|
|
* \brief set a CCSS configuration parameter, given its name
|
|
*
|
|
* \note
|
|
* Useful when parsing config files when used in conjunction
|
|
* with ast_ccss_is_cc_config_param.
|
|
*
|
|
* \param params The parameter structure to set the value on
|
|
* \param name The name of the cc parameter
|
|
* \param value The value of the parameter
|
|
* \retval 0 Success
|
|
* \retval -1 Failure
|
|
*/
|
|
int ast_cc_set_param(struct ast_cc_config_params *params, const char * const name,
|
|
const char * value);
|
|
|
|
/*!
|
|
* \brief get a CCSS configuration parameter, given its name
|
|
*
|
|
* \note
|
|
* Useful when reading input as a string, like from dialplan or
|
|
* manager.
|
|
*
|
|
* \param params The CCSS configuration from which to get the value
|
|
* \param name The name of the CCSS parameter we want
|
|
* \param buf A preallocated buffer to hold the value
|
|
* \param buf_len The size of buf
|
|
* \retval 0 Success
|
|
* \retval -1 Failure
|
|
*/
|
|
int ast_cc_get_param(struct ast_cc_config_params *params, const char * const name,
|
|
char *buf, size_t buf_len);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Is this a CCSS configuration parameter?
|
|
* \param name Name of configuration option being parsed.
|
|
* \retval 1 Yes, this is a CCSS configuration parameter.
|
|
* \retval 0 No, this is not a CCSS configuration parameter.
|
|
*/
|
|
int ast_cc_is_config_param(const char * const name);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Set the specified CC config params to default values.
|
|
*
|
|
* \details
|
|
* This is just like ast_cc_copy_config_params() and could be used in place
|
|
* of it if you need to set the config params to defaults instead.
|
|
* You are simply "copying" defaults into the destination.
|
|
*
|
|
* \param params CC config params to set to default values.
|
|
*/
|
|
void ast_cc_default_config_params(struct ast_cc_config_params *params);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief copy CCSS configuration parameters from one structure to another
|
|
*
|
|
* \details
|
|
* For now, this is a simple memcpy, but this function is necessary since
|
|
* the size of an ast_cc_config_params structure is unknown outside of
|
|
* main/ccss.c. Also, this allows for easier expansion of the function in
|
|
* case it becomes more complex than just a memcpy.
|
|
*
|
|
* \param src The structure from which data is copied
|
|
* \param dest The structure to which data is copied
|
|
*/
|
|
void ast_cc_copy_config_params(struct ast_cc_config_params *dest, const struct ast_cc_config_params *src);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Get the cc_agent_policy
|
|
* \param config The configuration to retrieve the policy from
|
|
* \return The current cc_agent_policy for this configuration
|
|
*/
|
|
enum ast_cc_agent_policies ast_get_cc_agent_policy(struct ast_cc_config_params *config);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Set the cc_agent_policy
|
|
* \param config The configuration to set the cc_agent_policy on
|
|
* \param value The new cc_agent_policy we want to change to
|
|
* \retval 0 Success
|
|
* \retval -1 Failure (likely due to bad input)
|
|
*/
|
|
int ast_set_cc_agent_policy(struct ast_cc_config_params *config, enum ast_cc_agent_policies value);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Get the cc_monitor_policy
|
|
* \param config The configuration to retrieve the cc_monitor_policy from
|
|
* \return The cc_monitor_policy retrieved from the configuration
|
|
*/
|
|
enum ast_cc_monitor_policies ast_get_cc_monitor_policy(struct ast_cc_config_params *config);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Set the cc_monitor_policy
|
|
* \param config The configuration to set the cc_monitor_policy on
|
|
* \param value The new cc_monitor_policy we want to change to
|
|
* \retval 0 Success
|
|
* \retval -1 Failure (likely due to bad input)
|
|
*/
|
|
int ast_set_cc_monitor_policy(struct ast_cc_config_params *config, enum ast_cc_monitor_policies value);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Get the cc_offer_timer
|
|
* \param config The configuration to retrieve the cc_offer_timer from
|
|
* \return The cc_offer_timer from this configuration
|
|
*/
|
|
unsigned int ast_get_cc_offer_timer(struct ast_cc_config_params *config);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Set the cc_offer_timer
|
|
* \param config The configuration to set the cc_offer_timer on
|
|
* \param value The new cc_offer_timer we want to change to
|
|
*/
|
|
void ast_set_cc_offer_timer(struct ast_cc_config_params *config, unsigned int value);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Get the ccnr_available_timer
|
|
* \param config The configuration to retrieve the ccnr_available_timer from
|
|
* \return The ccnr_available_timer from this configuration
|
|
*/
|
|
unsigned int ast_get_ccnr_available_timer(struct ast_cc_config_params *config);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Set the ccnr_available_timer
|
|
* \param config The configuration to set the ccnr_available_timer on
|
|
* \param value The new ccnr_available_timer we want to change to
|
|
*/
|
|
void ast_set_ccnr_available_timer(struct ast_cc_config_params *config, unsigned int value);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Get the cc_recall_timer
|
|
* \param config The configuration to retrieve the cc_recall_timer from
|
|
* \return The cc_recall_timer from this configuration
|
|
*/
|
|
unsigned int ast_get_cc_recall_timer(struct ast_cc_config_params *config);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Set the cc_recall_timer
|
|
* \param config The configuration to set the cc_recall_timer on
|
|
* \param value The new cc_recall_timer we want to change to
|
|
*/
|
|
void ast_set_cc_recall_timer(struct ast_cc_config_params *config, unsigned int value);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Get the ccbs_available_timer
|
|
* \param config The configuration to retrieve the ccbs_available_timer from
|
|
* \return The ccbs_available_timer from this configuration
|
|
*/
|
|
unsigned int ast_get_ccbs_available_timer(struct ast_cc_config_params *config);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Set the ccbs_available_timer
|
|
* \param config The configuration to set the ccbs_available_timer on
|
|
* \param value The new ccbs_available_timer we want to change to
|
|
*/
|
|
void ast_set_ccbs_available_timer(struct ast_cc_config_params *config, unsigned int value);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Get the cc_agent_dialstring
|
|
* \param config The configuration to retrieve the cc_agent_dialstring from
|
|
* \return The cc_agent_dialstring from this configuration
|
|
*/
|
|
const char *ast_get_cc_agent_dialstring(struct ast_cc_config_params *config);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Set the cc_agent_dialstring
|
|
* \param config The configuration to set the cc_agent_dialstring on
|
|
* \param value The new cc_agent_dialstring we want to change to
|
|
*/
|
|
void ast_set_cc_agent_dialstring(struct ast_cc_config_params *config, const char *const value);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Get the cc_max_agents
|
|
* \param config The configuration to retrieve the cc_max_agents from
|
|
* \return The cc_max_agents from this configuration
|
|
*/
|
|
unsigned int ast_get_cc_max_agents(struct ast_cc_config_params *config);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Set the cc_max_agents
|
|
* \param config The configuration to set the cc_max_agents on
|
|
* \param value The new cc_max_agents we want to change to
|
|
*/
|
|
void ast_set_cc_max_agents(struct ast_cc_config_params *config, unsigned int value);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Get the cc_max_monitors
|
|
* \param config The configuration to retrieve the cc_max_monitors from
|
|
* \return The cc_max_monitors from this configuration
|
|
*/
|
|
unsigned int ast_get_cc_max_monitors(struct ast_cc_config_params *config);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Set the cc_max_monitors
|
|
* \param config The configuration to set the cc_max_monitors on
|
|
* \param value The new cc_max_monitors we want to change to
|
|
*/
|
|
void ast_set_cc_max_monitors(struct ast_cc_config_params *config, unsigned int value);
|
|
|
|
/*!
|
|
* \since 11
|
|
* \brief Get the name of the callback subroutine
|
|
* \param config The configuration to retrieve the callback_sub from
|
|
* \return The callback_sub name
|
|
*/
|
|
const char *ast_get_cc_callback_sub(struct ast_cc_config_params *config);
|
|
|
|
/*!
|
|
* \since 11
|
|
* \brief Set the callback subroutine name
|
|
* \param config The configuration to set the callback_sub on
|
|
* \param value The new callback subroutine we want to change to
|
|
*/
|
|
void ast_set_cc_callback_sub(struct ast_cc_config_params *config, const char * const value);
|
|
|
|
/* END CONFIGURATION FUNCTIONS */
|
|
|
|
/* BEGIN AGENT/MONITOR REGISTRATION API */
|
|
|
|
struct ast_cc_monitor_callbacks;
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Register a set of monitor callbacks with the core
|
|
*
|
|
* \details
|
|
* This is made so that at monitor creation time, the proper callbacks
|
|
* may be installed and the proper .init callback may be called for the
|
|
* monitor to establish private data.
|
|
*
|
|
* \param callbacks The callbacks used by the monitor implementation
|
|
* \retval 0 Successfully registered
|
|
* \retval -1 Failure to register
|
|
*/
|
|
int ast_cc_monitor_register(const struct ast_cc_monitor_callbacks *callbacks);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Unregister a set of monitor callbacks with the core
|
|
*
|
|
* \details
|
|
* If a module which makes use of a CC monitor is unloaded, then it may
|
|
* unregister its monitor callbacks with the core.
|
|
*
|
|
* \param callbacks The callbacks used by the monitor implementation
|
|
*/
|
|
void ast_cc_monitor_unregister(const struct ast_cc_monitor_callbacks *callbacks);
|
|
|
|
struct ast_cc_agent_callbacks;
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Register a set of agent callbacks with the core
|
|
*
|
|
* \details
|
|
* This is made so that at agent creation time, the proper callbacks
|
|
* may be installed and the proper .init callback may be called for the
|
|
* monitor to establish private data.
|
|
*
|
|
* \param callbacks The callbacks used by the agent implementation
|
|
* \retval 0 Successfully registered
|
|
* \retval -1 Failure to register
|
|
*/
|
|
int ast_cc_agent_register(const struct ast_cc_agent_callbacks *callbacks);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Unregister a set of agent callbacks with the core
|
|
*
|
|
* \details
|
|
* If a module which makes use of a CC agent is unloaded, then it may
|
|
* unregister its agent callbacks with the core.
|
|
*
|
|
* \param callbacks The callbacks used by the agent implementation
|
|
*/
|
|
void ast_cc_agent_unregister(const struct ast_cc_agent_callbacks *callbacks);
|
|
|
|
/* END AGENT/MONITOR REGISTRATION API */
|
|
|
|
/* BEGIN SECTION ON MONITORS AND MONITOR CALLBACKS */
|
|
|
|
/*!
|
|
* It is recommended that monitors use a pointer to
|
|
* an ast_cc_monitor_callbacks::type when creating
|
|
* an AST_CONTROL_CC frame. Since the generic monitor
|
|
* callbacks are opaque and channel drivers will wish
|
|
* to use that, this string is made globally available
|
|
* for all to use
|
|
*/
|
|
#define AST_CC_GENERIC_MONITOR_TYPE "generic"
|
|
|
|
/*!
|
|
* Used to determine which type
|
|
* of monitor an ast_cc_device_monitor
|
|
* is.
|
|
*/
|
|
enum ast_cc_monitor_class {
|
|
AST_CC_DEVICE_MONITOR,
|
|
AST_CC_EXTENSION_MONITOR,
|
|
};
|
|
|
|
/*!
|
|
* \internal
|
|
* \brief An item in a CC interface tree.
|
|
*
|
|
* These are the individual items in an interface tree.
|
|
* The key difference between this structure and the ast_cc_interface
|
|
* is that this structure contains data which is intrinsic to the item's
|
|
* placement in the tree, such as who its parent is.
|
|
*/
|
|
struct ast_cc_monitor {
|
|
/*!
|
|
* Information regarding the interface.
|
|
*/
|
|
struct ast_cc_interface *interface;
|
|
/*!
|
|
* Every interface has an id that uniquely identifies it. It is
|
|
* formed by incrementing a counter.
|
|
*/
|
|
unsigned int id;
|
|
/*!
|
|
* The ID of this monitor's parent. If this monitor is at the
|
|
* top of the tree, then his parent will be 0.
|
|
*/
|
|
unsigned int parent_id;
|
|
/*!
|
|
* The instance of the CC core to which this monitor belongs
|
|
*/
|
|
int core_id;
|
|
/*!
|
|
* The type of call completion service offered by a device.
|
|
*/
|
|
enum ast_cc_service_type service_offered;
|
|
/*!
|
|
* \brief Name that should be used to recall specified interface
|
|
*
|
|
* \details
|
|
* When issuing a CC recall, some technologies will require
|
|
* that a name other than the device name is dialed. For instance,
|
|
* with SIP, a specific URI will be used which sip will be able
|
|
* to recognize as being a CC recall. Similarly, ISDN will need a specific
|
|
* dial string to know that the call is a recall.
|
|
*/
|
|
char *dialstring;
|
|
/*!
|
|
* The ID of the available timer used by the current monitor
|
|
*/
|
|
int available_timer_id;
|
|
/*!
|
|
* Monitor callbacks
|
|
*/
|
|
const struct ast_cc_monitor_callbacks *callbacks;
|
|
/*!
|
|
* \brief Data that is private to a monitor technology
|
|
*
|
|
* Most channel drivers that implement CC monitors will have to
|
|
* allocate data that the CC core does not care about but which
|
|
* is vital to the operation of the monitor. This data is stored
|
|
* in this pointer so that the channel driver may use it as
|
|
* needed
|
|
*/
|
|
void *private_data;
|
|
AST_LIST_ENTRY(ast_cc_monitor) next;
|
|
};
|
|
|
|
/*!
|
|
* \brief Callbacks defined by CC monitors
|
|
*
|
|
* \note
|
|
* Every callback is called with the list of monitors locked. There
|
|
* are several public API calls that also will try to lock this lock.
|
|
* These public functions have a note in their doxygen stating so.
|
|
* As such, pay attention to the lock order you establish in these callbacks
|
|
* to ensure that you do not violate the lock order when calling
|
|
* the functions in this file with lock order notices.
|
|
*/
|
|
struct ast_cc_monitor_callbacks {
|
|
/*!
|
|
* \brief Type of monitor the callbacks belong to.
|
|
*
|
|
* \note
|
|
* Examples include "generic" and "SIP"
|
|
*/
|
|
const char *type;
|
|
/*!
|
|
* \brief Request CCSS.
|
|
*
|
|
* \param monitor CC core monitor control.
|
|
* \param available_timer_id The scheduler ID for the available timer.
|
|
* Will never be NULL for a device monitor.
|
|
*
|
|
* \details
|
|
* Perform whatever steps are necessary in order to request CC.
|
|
* In addition, the monitor implementation is responsible for
|
|
* starting the available timer in this callback.
|
|
*
|
|
* \retval 0 on success
|
|
* \retval -1 on failure.
|
|
*/
|
|
int (*request_cc)(struct ast_cc_monitor *monitor, int *available_timer_id);
|
|
/*!
|
|
* \brief Suspend monitoring.
|
|
*
|
|
* \param monitor CC core monitor control.
|
|
*
|
|
* \details
|
|
* Implementers must perform the necessary steps to suspend
|
|
* monitoring.
|
|
*
|
|
* \retval 0 on success
|
|
* \retval -1 on failure.
|
|
*/
|
|
int (*suspend)(struct ast_cc_monitor *monitor);
|
|
/*!
|
|
* \brief Status response to an ast_cc_monitor_status_request().
|
|
*
|
|
* \param monitor CC core monitor control.
|
|
* \param devstate Current status of a Party A device.
|
|
*
|
|
* \details
|
|
* Alert a monitor as to the status of the agent for which
|
|
* the monitor had previously requested a status request.
|
|
*
|
|
* \note Zero or more responses may come as a result.
|
|
*
|
|
* \retval 0 on success
|
|
* \retval -1 on failure.
|
|
*/
|
|
int (*status_response)(struct ast_cc_monitor *monitor, enum ast_device_state devstate);
|
|
/*!
|
|
* \brief Unsuspend monitoring.
|
|
*
|
|
* \param monitor CC core monitor control.
|
|
*
|
|
* \details
|
|
* Perform the necessary steps to unsuspend monitoring.
|
|
*
|
|
* \retval 0 on success
|
|
* \retval -1 on failure.
|
|
*/
|
|
int (*unsuspend)(struct ast_cc_monitor *monitor);
|
|
/*!
|
|
* \brief Cancel the running available timer.
|
|
*
|
|
* \param monitor CC core monitor control.
|
|
* \param sched_id Available timer scheduler id to cancel.
|
|
* Will never be NULL for a device monitor.
|
|
*
|
|
* \details
|
|
* In most cases, this function will likely consist of just a
|
|
* call to AST_SCHED_DEL. It might have been possible to do this
|
|
* within the core, but unfortunately the mixture of sched_thread
|
|
* and sched usage in Asterisk prevents such usage.
|
|
*
|
|
* \retval 0 on success
|
|
* \retval -1 on failure.
|
|
*/
|
|
int (*cancel_available_timer)(struct ast_cc_monitor *monitor, int *sched_id);
|
|
/*!
|
|
* \brief Destroy private data on the monitor.
|
|
*
|
|
* \param private_data The private data pointer from the monitor.
|
|
*
|
|
* \details
|
|
* Implementers of this callback are responsible for destroying
|
|
* all heap-allocated data in the monitor's private_data pointer, including
|
|
* the private_data itself.
|
|
*/
|
|
void (*destructor)(void *private_data);
|
|
};
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Scheduler callback for available timer expiration
|
|
*
|
|
* \note
|
|
* When arming the available timer from within a device monitor, you MUST
|
|
* use this function as the callback for the scheduler.
|
|
*
|
|
* \param data A reference to the CC monitor on which the timer was running.
|
|
*/
|
|
int ast_cc_available_timer_expire(const void *data);
|
|
|
|
/* END SECTION ON MONITORS AND MONITOR CALLBACKS */
|
|
|
|
/* BEGIN API FOR IN-CALL CC HANDLING */
|
|
|
|
/*!
|
|
* \since 1.8
|
|
*
|
|
* \brief Mark the channel to ignore further CC activity.
|
|
*
|
|
* \details
|
|
* When a CC-capable application, such as Dial, has finished
|
|
* with all CC processing for a channel and knows that any further
|
|
* CC processing should be ignored, this function should be called.
|
|
*
|
|
* \param chan The channel for which further CC processing should be ignored.
|
|
*/
|
|
void ast_ignore_cc(struct ast_channel *chan);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
*
|
|
* \brief Properly react to a CC control frame.
|
|
*
|
|
* \details
|
|
* When a CC-capable application, such as Dial, receives a frame
|
|
* of type AST_CONTROL_CC, then it may call this function in order
|
|
* to have the device which sent the frame added to the tree of interfaces
|
|
* which is kept on the inbound channel.
|
|
*
|
|
* \param inbound The inbound channel
|
|
* \param outbound The outbound channel (The one from which the CC frame was read)
|
|
* \param frame_data The ast_frame's data.ptr field.
|
|
*/
|
|
void ast_handle_cc_control_frame(struct ast_channel *inbound, struct ast_channel *outbound, void *frame_data);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
*
|
|
* \brief Start the CC process on a call.
|
|
*
|
|
* \details
|
|
* Whenever a CC-capable application, such as Dial, wishes to
|
|
* engage in CC activity, it initiates the process by calling this
|
|
* function. If the CC core should discover that a previous application
|
|
* has called ast_ignore_cc on this channel or a "parent" channel, then
|
|
* the value of the ignore_cc integer passed in will be set nonzero.
|
|
*
|
|
* The ignore_cc parameter is a convenience parameter. It can save an
|
|
* application the trouble of trying to call CC APIs when it knows that
|
|
* it should just ignore further attempts at CC actions.
|
|
*
|
|
* \param chan The inbound channel calling the CC-capable application.
|
|
* \param[out] ignore_cc Will be set non-zero if no further CC actions need to be taken
|
|
* \retval 0 Success
|
|
* \retval -1 Failure
|
|
*/
|
|
int ast_cc_call_init(struct ast_channel *chan, int *ignore_cc);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
*
|
|
* \brief Add a child dialstring to an extension monitor
|
|
*
|
|
* Whenever we request a channel, the parent extension monitor needs
|
|
* to store the dialstring of the device requested. The reason is so
|
|
* that we can call the device back during the recall even if we are
|
|
* not monitoring the device.
|
|
*
|
|
* \param incoming The caller's channel
|
|
* \param dialstring The dialstring used when requesting the outbound channel
|
|
* \param device_name The device name associated with the requested outbound channel
|
|
*/
|
|
void ast_cc_extension_monitor_add_dialstring(struct ast_channel *incoming, const char * const dialstring, const char * const device_name);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Check if the incoming CC request is within the bounds
|
|
* set by the cc_max_requests configuration option
|
|
*
|
|
* \details
|
|
* It is recommended that an entity which receives an incoming
|
|
* CC request calls this function before calling
|
|
* ast_cc_agent_accept_request. This way, immediate feedback can be
|
|
* given to the caller about why his request was rejected.
|
|
*
|
|
* If this is not called and a state change to CC_CALLER_REQUESTED
|
|
* is made, then the core will still not allow for the request
|
|
* to succeed. However, if done this way, it may not be obvious
|
|
* to the requestor why the request failed.
|
|
*
|
|
* \retval 0 Not within the limits. Fail.
|
|
* \retval non-zero Within the limits. Success.
|
|
*/
|
|
int ast_cc_request_is_within_limits(void);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Get the core id for the current call
|
|
*
|
|
* \details
|
|
* The main use of this function is for channel drivers
|
|
* who queue an AST_CONTROL_CC frame. A channel driver may
|
|
* call this function in order to get the core_id for what
|
|
* may become a CC request. This way, when monitor functions
|
|
* are called which use a core_id as a means of identification,
|
|
* the channel driver will have saved this information.
|
|
*
|
|
* The channel given to this function may be an inbound or outbound
|
|
* channel. Both will have the necessary info on it.
|
|
*
|
|
* \param chan The channel from which to get the core_id.
|
|
* \retval core_id on success
|
|
* \retval -1 Failure
|
|
*/
|
|
int ast_cc_get_current_core_id(struct ast_channel *chan);
|
|
|
|
/* END API FOR IN-CALL CC HANDLING */
|
|
|
|
/*!
|
|
* \brief Structure with information about an outbound interface
|
|
*
|
|
* \details
|
|
* This structure is first created when an outbound interface indicates that
|
|
* it is capable of accepting a CC request. It is stored in a "tree" on a datastore on
|
|
* the caller's channel. Once an agent structure is created, the agent gains
|
|
* a reference to the tree of interfaces. If CC is requested, then the
|
|
* interface tree on the agent is converted into a tree of monitors. Each
|
|
* monitor will contain a pointer to an individual ast_cc_interface. Finally,
|
|
* the tree of interfaces is also present on a second datastore during a
|
|
* CC recall so that the CC_INTERFACES channel variable may be properly
|
|
* populated.
|
|
*/
|
|
struct ast_cc_interface {
|
|
/* What class of monitor is being offered here
|
|
*/
|
|
enum ast_cc_monitor_class monitor_class;
|
|
/*!
|
|
* \brief The type of monitor that should be used for this interface
|
|
*
|
|
* \details
|
|
* This will be something like "extension" "generic" or "SIP".
|
|
* This should point to a static const char *, so there is
|
|
* no reason to make a new copy.
|
|
*/
|
|
const char *monitor_type;
|
|
/*!
|
|
* The configuration parameters used for this interface
|
|
*/
|
|
struct ast_cc_config_params *config_params;
|
|
/* The name of the interface/extension. local channels will
|
|
* have 'exten@context' for a name. Other channel types will
|
|
* have 'tech/device' for a name.
|
|
*/
|
|
char device_name[1];
|
|
};
|
|
|
|
/* BEGIN STRUCTURES FOR AGENTS */
|
|
|
|
struct ast_cc_agent {
|
|
/*!
|
|
* Which instance of the core state machine does this
|
|
* agent pertain to?
|
|
*/
|
|
unsigned int core_id;
|
|
/*!
|
|
* Callback functions needed for specific agent
|
|
* implementations
|
|
*/
|
|
const struct ast_cc_agent_callbacks *callbacks;
|
|
/*!
|
|
* Configuration parameters that affect this
|
|
* agent's operation.
|
|
*/
|
|
struct ast_cc_config_params *cc_params;
|
|
/*!
|
|
* \brief Flags for agent operation
|
|
*
|
|
* \details
|
|
* There are some attributes of certain agent types
|
|
* that can alter the behavior of certain CC functions.
|
|
* For a list of these flags, see the ast_cc_agent_flags
|
|
* enum
|
|
*/
|
|
unsigned int flags;
|
|
/*! Data specific to agent implementation */
|
|
void *private_data;
|
|
/*! The name of the device which this agent
|
|
* represents/communicates with
|
|
*/
|
|
char device_name[1];
|
|
};
|
|
|
|
enum ast_cc_agent_response_reason {
|
|
/*! CC request accepted */
|
|
AST_CC_AGENT_RESPONSE_SUCCESS,
|
|
/*! CC request not allowed at this time. Invalid state transition. */
|
|
AST_CC_AGENT_RESPONSE_FAILURE_INVALID,
|
|
/*! Too many CC requests in the system. */
|
|
AST_CC_AGENT_RESPONSE_FAILURE_TOO_MANY,
|
|
};
|
|
|
|
struct ast_cc_agent_callbacks {
|
|
/*!
|
|
* \brief Type of agent the callbacks belong to.
|
|
*
|
|
* \note
|
|
* Examples are "SIP" "ISDN" and "generic"
|
|
*/
|
|
const char *type;
|
|
/*!
|
|
* \brief CC agent initialization.
|
|
*
|
|
* \param agent CC core agent control.
|
|
* \param chan Original channel the agent will attempt to recall.
|
|
*
|
|
* \details
|
|
* This callback is called when the CC core
|
|
* is initialized. Agents should allocate
|
|
* any private data necessary for the
|
|
* call and assign it to the private_data
|
|
* on the agent. Additionally, if any ast_cc_agent_flags
|
|
* are pertinent to the specific agent type, they should
|
|
* be set in this function as well.
|
|
*
|
|
* \retval 0 on success.
|
|
* \retval -1 on error.
|
|
*/
|
|
int (*init)(struct ast_cc_agent *agent, struct ast_channel *chan);
|
|
/*!
|
|
* \brief Start the offer timer.
|
|
*
|
|
* \param agent CC core agent control.
|
|
*
|
|
* \details
|
|
* This is called by the core when the caller hangs up after
|
|
* a call for which CC may be requested. The agent should
|
|
* begin the timer as configured.
|
|
*
|
|
* The primary reason why this functionality is left to
|
|
* the specific agent implementations is due to the differing
|
|
* use of schedulers throughout the code. Some channel drivers
|
|
* may already have a scheduler context they wish to use, and
|
|
* amongst those, some may use the ast_sched API while others
|
|
* may use the ast_sched_thread API, which are incompatible.
|
|
*
|
|
* \retval 0 on success.
|
|
* \retval -1 on error.
|
|
*/
|
|
int (*start_offer_timer)(struct ast_cc_agent *agent);
|
|
/*!
|
|
* \brief Stop the offer timer.
|
|
*
|
|
* \param agent CC core agent control.
|
|
*
|
|
* \details
|
|
* This callback is called by the CC core when the caller
|
|
* has requested CC.
|
|
*
|
|
* \retval 0 on success.
|
|
* \retval -1 on error.
|
|
*/
|
|
int (*stop_offer_timer)(struct ast_cc_agent *agent);
|
|
/*!
|
|
* \brief Respond to a CC request.
|
|
*
|
|
* \param agent CC core agent control.
|
|
* \param reason CC request response status.
|
|
*
|
|
* \details
|
|
* When the core receives knowledge that a called
|
|
* party has accepted a CC request, it will call
|
|
* this callback. The core may also call this
|
|
* if there is some error when attempting to process
|
|
* the incoming CC request.
|
|
*
|
|
* The duty of this is to issue a propper response to a
|
|
* CC request from the caller by acknowledging receipt
|
|
* of that request or rejecting it.
|
|
*/
|
|
void (*respond)(struct ast_cc_agent *agent, enum ast_cc_agent_response_reason reason);
|
|
/*!
|
|
* \brief Request the status of the agent's device.
|
|
*
|
|
* \param agent CC core agent control.
|
|
*
|
|
* \details
|
|
* Asynchronous request for the status of any caller
|
|
* which may be a valid caller for the CC transaction.
|
|
* Status responses should be made using the
|
|
* ast_cc_status_response function.
|
|
*
|
|
* \retval 0 on success.
|
|
* \retval -1 on error.
|
|
*/
|
|
int (*status_request)(struct ast_cc_agent *agent);
|
|
/*!
|
|
* \brief Request for an agent's phone to stop ringing.
|
|
*
|
|
* \param agent CC core agent control.
|
|
*
|
|
* \details
|
|
* The usefulness of this is quite limited. The only specific
|
|
* known case for this is if Asterisk requests CC over an ISDN
|
|
* PTMP link as the TE side. If other phones are in the same
|
|
* recall group as the Asterisk server, and one of those phones
|
|
* picks up the recall notice, then Asterisk will receive a
|
|
* "stop ringing" notification from the NT side of the PTMP
|
|
* link. This indication needs to be passed to the phone
|
|
* on the other side of the Asterisk server which originally
|
|
* placed the call so that it will stop ringing. Since the
|
|
* phone may be of any type, it is necessary to have a callback
|
|
* that the core can know about.
|
|
*
|
|
* \retval 0 on success.
|
|
* \retval -1 on error.
|
|
*/
|
|
int (*stop_ringing)(struct ast_cc_agent *agent);
|
|
/*!
|
|
* \brief Let the caller know that the callee has become free
|
|
* but that the caller cannot attempt to call back because
|
|
* he is either busy or there is congestion on his line.
|
|
*
|
|
* \param agent CC core agent control.
|
|
*
|
|
* \details
|
|
* This is something that really only affects a scenario where
|
|
* a phone places a call over ISDN PTMP to Asterisk, who then
|
|
* connects over PTMP again to the ISDN network. For most agent
|
|
* types, there is no need to implement this callback at all
|
|
* because they don't really need to actually do anything in
|
|
* this situation. If you're having trouble understanding what
|
|
* the purpose of this callback is, then you can be safe simply
|
|
* not implementing it.
|
|
*
|
|
* \retval 0 on success.
|
|
* \retval -1 on error.
|
|
*/
|
|
int (*party_b_free)(struct ast_cc_agent *agent);
|
|
/*!
|
|
* \brief Begin monitoring a busy device.
|
|
*
|
|
* \param agent CC core agent control.
|
|
*
|
|
* \details
|
|
* The core will call this callback if the callee becomes
|
|
* available but the caller has reported that he is busy.
|
|
* The agent should begin monitoring the caller's device.
|
|
* When the caller becomes available again, the agent should
|
|
* call ast_cc_agent_caller_available.
|
|
*
|
|
* \retval 0 on success.
|
|
* \retval -1 on error.
|
|
*/
|
|
int (*start_monitoring)(struct ast_cc_agent *agent);
|
|
/*!
|
|
* \brief Alert the caller that it is time to try recalling.
|
|
*
|
|
* \param agent CC core agent control.
|
|
*
|
|
* \details
|
|
* The core will call this function when it receives notice
|
|
* that a monitored party has become available.
|
|
*
|
|
* The agent's job is to send a message to the caller to
|
|
* notify it of such a change. If the agent is able to
|
|
* discern that the caller is currently unavailable, then
|
|
* the agent should react by calling the ast_cc_caller_unavailable
|
|
* function.
|
|
*
|
|
* \retval 0 on success.
|
|
* \retval -1 on error.
|
|
*/
|
|
int (*callee_available)(struct ast_cc_agent *agent);
|
|
/*!
|
|
* \brief Destroy private data on the agent.
|
|
*
|
|
* \param agent CC core agent control.
|
|
*
|
|
* \details
|
|
* The core will call this function upon completion
|
|
* or failure of CC.
|
|
*
|
|
* \note
|
|
* The agent private_data pointer may be NULL if the agent
|
|
* constructor failed.
|
|
*/
|
|
void (*destructor)(struct ast_cc_agent *agent);
|
|
};
|
|
|
|
/*!
|
|
* \brief Call a callback on all agents of a specific type
|
|
*
|
|
* \details
|
|
* Since the container of CC core instances is private, and so
|
|
* are the items which the container contains, we have to provide
|
|
* an ao2_callback-like method so that a specific agent may be
|
|
* found or so that an operation can be made on all agents of
|
|
* a particular type. The first three arguments should be familiar
|
|
* to anyone who has used ao2_callback. The final argument is the
|
|
* type of agent you wish to have the callback called on.
|
|
*
|
|
* \note Since agents are refcounted, and this function returns
|
|
* a reference to the agent, it is imperative that you decrement
|
|
* the refcount of the agent once you have finished using it.
|
|
*
|
|
* \param flags astobj2 search flags
|
|
* \param function an ao2 callback function to call
|
|
* \param arg the argument to the callback function
|
|
* \param type The type of agents to call the callback on
|
|
*/
|
|
struct ast_cc_agent *ast_cc_agent_callback(int flags, ao2_callback_fn *function, void *arg, const char * const type);
|
|
|
|
/* END STRUCTURES FOR AGENTS */
|
|
|
|
/* BEGIN STATE CHANGE API */
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Offer CC to a caller
|
|
*
|
|
* \details
|
|
* This function is called from ast_hangup if the caller is
|
|
* eligible to be offered call completion service.
|
|
*
|
|
* \param caller_chan The calling channel
|
|
* \retval -1 Error
|
|
* \retval 0 Success
|
|
*/
|
|
int ast_cc_offer(struct ast_channel *caller_chan);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Accept inbound CC request
|
|
*
|
|
* \details
|
|
* When a caller requests CC, this function should be called to let
|
|
* the core know that the request has been accepted.
|
|
*
|
|
* \param core_id core_id of the CC transaction
|
|
* \param debug optional string to print for debugging purposes
|
|
* \retval 0 Success
|
|
* \retval -1 Failure
|
|
*/
|
|
int __attribute__((format(printf, 2, 3))) ast_cc_agent_accept_request(int core_id, const char * const debug, ...);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Indicate that an outbound entity has accepted our CC request
|
|
*
|
|
* \details
|
|
* When we receive confirmation that an outbound device has accepted the
|
|
* CC request we sent it, this function must be called.
|
|
*
|
|
* \param core_id core_id of the CC transaction
|
|
* \param debug optional string to print for debugging purposes
|
|
* \retval 0 Success
|
|
* \retval -1 Failure
|
|
*/
|
|
int __attribute__((format(printf, 2, 3))) ast_cc_monitor_request_acked(int core_id, const char * const debug, ...);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Indicate that the caller is busy
|
|
*
|
|
* \details
|
|
* When the callee makes it known that he is available, the core
|
|
* will let the caller's channel driver know that it may attempt
|
|
* to let the caller know to attempt a recall. If the channel
|
|
* driver can detect, though, that the caller is busy, then
|
|
* the channel driver should call this function to let the CC
|
|
* core know.
|
|
*
|
|
* \param core_id core_id of the CC transaction
|
|
* \param debug optional string to print for debugging purposes
|
|
* \retval 0 Success
|
|
* \retval -1 Failure
|
|
*/
|
|
int __attribute__((format(printf, 2, 3))) ast_cc_agent_caller_busy(int core_id, const char * const debug, ...);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Indicate that a previously unavailable caller has become available
|
|
*
|
|
* \details
|
|
* If a monitor is suspended due to a caller becoming unavailable, then this
|
|
* function should be called to indicate that the caller has become available.
|
|
*
|
|
* \param core_id core_id of the CC transaction
|
|
* \param debug optional string to print for debugging purposes
|
|
* \retval 0 Success
|
|
* \retval -1 Failure
|
|
*/
|
|
int __attribute__((format(printf, 2, 3))) ast_cc_agent_caller_available(int core_id, const char * const debug, ...);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Tell the CC core that a caller is currently recalling
|
|
*
|
|
* \details
|
|
* The main purpose of this is so that the core can alert the monitor
|
|
* to stop its available timer since the caller has begun its recall
|
|
* phase.
|
|
*
|
|
* \param core_id core_id of the CC transaction
|
|
* \param debug optional string to print for debugging purposes
|
|
* \retval 0 Success
|
|
* \retval -1 Failure
|
|
*/
|
|
int __attribute__((format(printf, 2, 3))) ast_cc_agent_recalling(int core_id, const char * const debug, ...);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Indicate recall has been acknowledged
|
|
*
|
|
* \details
|
|
* When we receive confirmation that an endpoint has responded to our
|
|
* CC recall, we call this function.
|
|
*
|
|
* \param chan The inbound channel making the CC recall
|
|
* \param debug optional string to print for debugging purposes
|
|
* \retval 0 Success
|
|
* \retval -1 Failure
|
|
*/
|
|
int __attribute__((format(printf, 2, 3))) ast_cc_completed(struct ast_channel *chan, const char * const debug, ...);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Indicate failure has occurred
|
|
*
|
|
* \details
|
|
* If at any point a failure occurs, this is the function to call
|
|
* so that the core can initiate cleanup procedures.
|
|
*
|
|
* \param core_id core_id of the CC transaction
|
|
* \param debug optional string to print for debugging purposes
|
|
* \retval 0 Success
|
|
* \retval -1 Failure
|
|
*/
|
|
int __attribute__((format(printf, 2, 3))) ast_cc_failed(int core_id, const char * const debug, ...);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Indicate that a failure has occurred on a specific monitor
|
|
*
|
|
* \details
|
|
* If a monitor should detect that a failure has occurred when communicating
|
|
* with its endpoint, then ast_cc_monitor_failed should be called. The big
|
|
* difference between ast_cc_monitor_failed and ast_cc_failed is that ast_cc_failed
|
|
* indicates a global failure for a CC transaction, where as ast_cc_monitor_failed
|
|
* is localized to a particular monitor. When ast_cc_failed is called, the entire
|
|
* CC transaction is torn down. When ast_cc_monitor_failed is called, only the
|
|
* monitor on which the failure occurred is pruned from the tree of monitors.
|
|
*
|
|
* If there are no more devices left to monitor when this function is called,
|
|
* then the core will fail the CC transaction globally.
|
|
*
|
|
* \param core_id The core ID for the CC transaction
|
|
* \param monitor_name The name of the monitor on which the failure occurred
|
|
* \param debug A debug message to print to the CC log
|
|
*/
|
|
int __attribute__((format(printf, 3, 4))) ast_cc_monitor_failed(int core_id, const char * const monitor_name, const char * const debug, ...);
|
|
|
|
/* END STATE CHANGE API */
|
|
|
|
/*!
|
|
* The following are all functions which are required due to the unique
|
|
* case where Asterisk is acting as the NT side of an ISDN PTMP
|
|
* connection to the caller and as the TE side of an ISDN PTMP connection
|
|
* to the callee. In such a case, there are several times where the
|
|
* PTMP monitor needs information from the agent in order to formulate
|
|
* the appropriate messages to send.
|
|
*/
|
|
|
|
/*!
|
|
* \brief Request the status of a caller or callers.
|
|
*
|
|
* \details
|
|
* When an ISDN PTMP monitor senses that the callee has become
|
|
* available, it needs to know the current status of the caller
|
|
* in order to determine the appropriate response to send to
|
|
* the caller. In order to do this, the monitor calls this function.
|
|
* Responses will arrive asynchronously.
|
|
*
|
|
* \note Zero or more responses may come as a result.
|
|
*
|
|
* \param core_id The core ID of the CC transaction
|
|
*
|
|
* \retval 0 Successfully requested status
|
|
* \retval -1 Failed to request status
|
|
*/
|
|
int ast_cc_monitor_status_request(int core_id);
|
|
|
|
/*!
|
|
* \brief Response with a caller's current status
|
|
*
|
|
* \details
|
|
* When an ISDN PTMP monitor requests the caller's status, the
|
|
* agent must respond to the request using this function. For
|
|
* simplicity it is recommended that the devstate parameter
|
|
* be one of AST_DEVICE_INUSE or AST_DEVICE_NOT_INUSE.
|
|
*
|
|
* \param core_id The core ID of the CC transaction
|
|
* \param devstate The current state of the caller to which the agent pertains
|
|
* \retval 0 Successfully responded with our status
|
|
* \retval -1 Failed to respond with our status
|
|
*/
|
|
int ast_cc_agent_status_response(int core_id, enum ast_device_state devstate);
|
|
|
|
/*!
|
|
* \brief Alert a caller to stop ringing
|
|
*
|
|
* \details
|
|
* When an ISDN PTMP monitor becomes available, it is assumed
|
|
* that the agent will then cause the caller's phone to ring. In
|
|
* some cases, this is literally what happens. In other cases, it may
|
|
* be that the caller gets a visible indication on his phone that he
|
|
* may attempt to recall the callee. If multiple callers are recalled
|
|
* (since it may be possible to have a group of callers configured as
|
|
* a single party A), and one of those callers picks up his phone, then
|
|
* the ISDN PTMP monitor will alert the other callers to stop ringing.
|
|
* The agent's stop_ringing callback will be called, and it is up to the
|
|
* agent's driver to send an appropriate message to make his caller
|
|
* stop ringing.
|
|
*
|
|
* \param core_id The core ID of the CC transaction
|
|
* \retval 0 Successfully requested for the phone to stop ringing
|
|
* \retval -1 Could not request for the phone to stop ringing
|
|
*/
|
|
int ast_cc_monitor_stop_ringing(int core_id);
|
|
|
|
/*!
|
|
* \brief Alert a caller that though the callee has become free, the caller
|
|
* himself is not and may not call back.
|
|
*
|
|
* \details
|
|
* When an ISDN PTMP monitor senses that his monitored party has become
|
|
* available, he will request the status of the called party. If he determines
|
|
* that the caller is currently not available, then he will call this function
|
|
* so that an appropriate message is sent to the caller.
|
|
*
|
|
* Yes, you just read that correctly. The callee asks the caller what his
|
|
* current status is, and if the caller is currently unavailable, the monitor
|
|
* must send him a message anyway. WTF?
|
|
*
|
|
* This function results in the agent's party_b_free callback being called.
|
|
* It is most likely that you will not need to actually implement the
|
|
* party_b_free callback in an agent because it is not likely that you will
|
|
* need to or even want to send a caller a message indicating the callee's
|
|
* status if the caller himself is not also free.
|
|
*
|
|
* \param core_id The core ID of the CC transaction
|
|
* \retval 0 Successfully alerted the core that party B is free
|
|
* \retval -1 Could not alert the core that party B is free
|
|
*/
|
|
int ast_cc_monitor_party_b_free(int core_id);
|
|
|
|
/* BEGIN API FOR USE WITH/BY MONITORS */
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Return the number of outstanding CC requests to a specific device
|
|
*
|
|
* \note
|
|
* This function will lock the list of monitors stored on every instance of
|
|
* the CC core. Callers of this function should be aware of this and avoid
|
|
* any potential lock ordering problems.
|
|
*
|
|
* \param name The name of the monitored device
|
|
* \param type The type of the monitored device (e.g. "generic")
|
|
* \return The number of CC requests for the monitor
|
|
*/
|
|
int ast_cc_monitor_count(const char * const name, const char * const type);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Alert the core that a device being monitored has become available.
|
|
*
|
|
* \note
|
|
* The code in the core will take care of making sure that the information gets passed
|
|
* up the ladder correctly.
|
|
*
|
|
* \par core_id The core ID of the corresponding CC transaction
|
|
* \par debug
|
|
* \retval 0 Request successfully queued
|
|
* \retval -1 Request could not be queued
|
|
*/
|
|
int __attribute__((format(printf, 2, 3))) ast_cc_monitor_callee_available(const int core_id, const char * const debug, ...);
|
|
|
|
/* END API FOR USE WITH/BY MONITORS */
|
|
|
|
/* BEGIN API TO BE USED ON CC RECALL */
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Set up a CC recall datastore on a channel
|
|
*
|
|
* \details
|
|
* Implementers of protocol-specific CC agents will need to call this
|
|
* function in order for the channel to have the necessary interfaces
|
|
* to recall.
|
|
*
|
|
* This function must be called by the implementer once it has been detected
|
|
* that an inbound call is a cc_recall. After allocating the channel, call this
|
|
* function, followed by ast_cc_set_cc_interfaces_chanvar. While it would be nice to
|
|
* be able to have the core do this automatically, it just cannot be done given
|
|
* the current architecture.
|
|
*/
|
|
int ast_setup_cc_recall_datastore(struct ast_channel *chan, const int core_id);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Decide if a call to a particular channel is a CC recall
|
|
*
|
|
* \details
|
|
* When a CC recall happens, it is important on the called side to
|
|
* know that the call is a CC recall and not a normal call. This function
|
|
* will determine first if the call in question is a CC recall. Then it
|
|
* will determine based on the chan parameter if the channel is being
|
|
* called is being recalled.
|
|
*
|
|
* As a quick example, let's say a call is placed to SIP/1000 and SIP/1000
|
|
* is currently on the phone. The caller requests CCBS. SIP/1000 finishes
|
|
* his call, and so the caller attempts to recall. Now, the dialplan
|
|
* administrator has set up this second call so that not only is SIP/1000
|
|
* called, but also SIP/2000 is called. If SIP/1000's channel were passed
|
|
* to this function, the return value would be non-zero, but if SIP/2000's
|
|
* channel were passed into this function, then the return would be 0 since
|
|
* SIP/2000 was not one of the original devices dialed.
|
|
*
|
|
* \note
|
|
* This function may be called on a calling channel as well to
|
|
* determine if it is part of a CC recall.
|
|
*
|
|
* \note
|
|
* This function will lock the channel as well as the list of monitors
|
|
* on the channel datastore, though the locks are not held at the same time. Be
|
|
* sure that you have no potential lock order issues here.
|
|
*
|
|
* \param chan The channel to check
|
|
* \param[out] core_id If this is a valid CC recall, the core_id of the failed call
|
|
* will be placed in this output parameter
|
|
* \param monitor_type Clarify which type of monitor type we are looking for if this
|
|
* is happening on a called channel. For incoming channels, this parameter is not used.
|
|
* \retval 0 Either this is not a recall or it is but this channel is not part of the recall
|
|
* \retval non-zero This is a recall and the channel in question is directly involved.
|
|
*/
|
|
int ast_cc_is_recall(struct ast_channel *chan, int *core_id, const char * const monitor_type);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Get the associated monitor given the device name and core_id
|
|
*
|
|
* \details
|
|
* The function ast_cc_is_recall is helpful for determining if a call to
|
|
* a specific channel is a recall. However, once you have determined that
|
|
* this is a recall, you will most likely need access to the private data
|
|
* within the associated monitor. This function is what one uses to get
|
|
* that monitor.
|
|
*
|
|
* \note
|
|
* This function locks the list of monitors that correspond to the core_id
|
|
* passed in. Be sure that you have no potential lock order issues when
|
|
* calling this function.
|
|
*
|
|
* \param core_id The core ID to which this recall corresponds. This likely will
|
|
* have been obtained using the ast_cc_is_recall function
|
|
* \param device_name Which device to find the monitor for.
|
|
*
|
|
* \retval NULL Appropriate monitor does not exist
|
|
* \retval non-NULL The monitor to use for this recall
|
|
*/
|
|
struct ast_cc_monitor *ast_cc_get_monitor_by_recall_core_id(const int core_id, const char * const device_name);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Set the first level CC_INTERFACES channel variable for a channel.
|
|
*
|
|
* \note
|
|
* Implementers of protocol-specific CC agents should call this function after
|
|
* calling ast_setup_cc_recall_datastore.
|
|
*
|
|
* \note
|
|
* This function will lock the channel as well as the list of monitors stored
|
|
* on the channel's CC recall datastore, though neither are held at the same
|
|
* time. Callers of this function should be aware of potential lock ordering
|
|
* problems that may arise.
|
|
*
|
|
* \details
|
|
* The CC_INTERFACES channel variable will have the interfaces that should be
|
|
* called back for a specific PBX instance.
|
|
*
|
|
* \param chan The channel to set the CC_INTERFACES variable on
|
|
*/
|
|
int ast_cc_agent_set_interfaces_chanvar(struct ast_channel *chan);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Set the CC_INTERFACES channel variable for a channel using an
|
|
* \verbatim extension@context \endverbatim as a starting point
|
|
*
|
|
* \details
|
|
* The CC_INTERFACES channel variable will have the interfaces
|
|
* that should be called back for a specific PBX instance. This
|
|
* version of the function is used mainly by local channels,
|
|
* wherein we need to set CC_INTERFACES based on an extension
|
|
* and context that appear in the middle of the tree of dialed
|
|
* interfaces.
|
|
*
|
|
* \note
|
|
* This function will lock the channel as well as the list of monitors stored
|
|
* on the channel's CC recall datastore, though neither are held at the same
|
|
* time. Callers of this function should be aware of potential lock ordering
|
|
* problems that may arise.
|
|
*
|
|
* \param chan The channel to set the CC_INTERFACES variable on
|
|
* \param extension The name of the extension for which we're setting the variable.
|
|
* This should be in the form of \verbatim exten@context \endverbatim
|
|
*/
|
|
int ast_set_cc_interfaces_chanvar(struct ast_channel *chan, const char * const extension);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Make CCBS available in the case that ast_call fails
|
|
*
|
|
* In some situations, notably if a call-limit is reached in SIP, ast_call will fail
|
|
* due to Asterisk's knowing that the desired device is currently busy. In such a situation,
|
|
* CCBS should be made available to the caller.
|
|
*
|
|
* One caveat is that this may only be used if generic monitoring is being used. The reason
|
|
* is that since Asterisk determined that the device was busy without actually placing a call to it,
|
|
* the far end will have no idea what call we are requesting call completion for if we were to send
|
|
* a call completion request.
|
|
*/
|
|
void ast_cc_call_failed(struct ast_channel *incoming, struct ast_channel *outgoing, const char * const dialstring);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Callback made from ast_cc_callback for certain channel types
|
|
*
|
|
* \param inbound Incoming asterisk channel.
|
|
* \param cc_params The CC configuration parameters for the outbound target
|
|
* \param monitor_type The type of monitor to use when CC is requested
|
|
* \param device_name The name of the outbound target device.
|
|
* \param dialstring The dial string used when calling this specific interface
|
|
* \param private_data If a native monitor is being used, and some channel-driver-specific private
|
|
* data has been allocated, then this parameter should contain a pointer to that data. If using a generic
|
|
* monitor, this parameter should remain NULL. Note that if this function should fail at some point,
|
|
* it is the responsibility of the caller to free the private data upon return.
|
|
*
|
|
* \details
|
|
* For channel types that fail ast_request when the device is busy, we call into the
|
|
* channel driver with ast_cc_callback. This is the callback that is called in that
|
|
* case for each device found which could have been returned by ast_request.
|
|
*
|
|
* This function creates a CC control frame payload, simulating the act of reading
|
|
* it from the nonexistent outgoing channel's frame queue. We then handle this
|
|
* simulated frame just as we would a normal CC frame which had actually been queued
|
|
* by the channel driver.
|
|
*/
|
|
void ast_cc_busy_interface(struct ast_channel *inbound, struct ast_cc_config_params *cc_params,
|
|
const char *monitor_type, const char * const device_name, const char * const dialstring, void *private_data);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Create a CC Control frame
|
|
*
|
|
* \details
|
|
* chan_dahdi is weird. It doesn't seem to actually queue frames when it needs to tell
|
|
* an application something. Instead it wakes up, tells the application that it has data
|
|
* ready, and then based on set flags, creates the proper frame type. For chan_dahdi, we
|
|
* provide this function. It provides us the data we need, and we'll make its frame for it.
|
|
*
|
|
* \param chan A channel involved in the call. What we want is on a datastore on both incoming
|
|
* and outgoing so either may be provided
|
|
* \param cc_params The CC configuration parameters for the outbound target
|
|
* \param monitor_type The type of monitor to use when CC is requested
|
|
* \param device_name The name of the outbound target device.
|
|
* \param dialstring The dial string used when calling this specific interface
|
|
* \param service What kind of CC service is being offered. (CCBS/CCNR/etc...)
|
|
* \param private_data If a native monitor is being used, and some channel-driver-specific private
|
|
* data has been allocated, then this parameter should contain a pointer to that data. If using a generic
|
|
* monitor, this parameter should remain NULL. Note that if this function should fail at some point,
|
|
* it is the responsibility of the caller to free the private data upon return.
|
|
* \param[out] frame The frame we will be returning to the caller. It is vital that ast_frame_free be
|
|
* called on this frame since the payload will be allocated on the heap.
|
|
* \retval -1 Failure. At some point there was a failure. Do not attempt to use the frame in this case.
|
|
* \retval 0 Success
|
|
*/
|
|
int ast_cc_build_frame(struct ast_channel *chan, struct ast_cc_config_params *cc_params,
|
|
const char *monitor_type, const char * const device_name,
|
|
const char * const dialstring, enum ast_cc_service_type service, void *private_data,
|
|
struct ast_frame *frame);
|
|
|
|
|
|
/*!
|
|
* \brief Callback made from ast_cc_callback for certain channel types
|
|
* \since 1.8
|
|
*
|
|
* \param chan A channel involved in the call. What we want is on a datastore on both incoming and outgoing so either may be provided
|
|
* \param cc_params The CC configuration parameters for the outbound target
|
|
* \param monitor_type The type of monitor to use when CC is requested
|
|
* \param device_name The name of the outbound target device.
|
|
* \param dialstring The dial string used when calling this specific interface
|
|
* \param private_data If a native monitor is being used, and some channel-driver-specific private
|
|
* data has been allocated, then this parameter should contain a pointer to that data. If using a generic
|
|
* monitor, this parameter should remain NULL. Note that if this function should fail at some point,
|
|
* it is the responsibility of the caller to free the private data upon return.
|
|
*
|
|
* \details
|
|
* For channel types that fail ast_request when the device is busy, we call into the
|
|
* channel driver with ast_cc_callback. This is the callback that is called in that
|
|
* case for each device found which could have been returned by ast_request.
|
|
*/
|
|
typedef void (*ast_cc_callback_fn)(struct ast_channel *chan, struct ast_cc_config_params *cc_params,
|
|
const char *monitor_type, const char * const device_name, const char * const dialstring, void *private_data);
|
|
|
|
/*!
|
|
* \since 1.8
|
|
* \brief Run a callback for potential matching destinations.
|
|
*
|
|
* \note
|
|
* See the explanation in ast_channel_tech::cc_callback for more
|
|
* details.
|
|
*
|
|
* \param inbound
|
|
* \param tech Channel technology to use
|
|
* \param dest Channel/group/peer or whatever the specific technology uses
|
|
* \param callback Function to call when a target is reached
|
|
* \retval 0 Always, I guess.
|
|
*/
|
|
int ast_cc_callback(struct ast_channel *inbound, const char * const tech, const char * const dest, ast_cc_callback_fn callback);
|
|
|
|
#endif /* _ASTERISK_CCSS_H */
|