Fri Feb 10 06:35:05 2012

Asterisk developer's documentation


ccss.h File Reference

Call Completion Supplementary Services API. More...

#include "asterisk.h"
#include "asterisk/linkedlists.h"
#include "asterisk/devicestate.h"

Include dependency graph for ccss.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ast_cc_agent
struct  ast_cc_agent_callbacks
struct  ast_cc_interface
 Structure with information about an outbound interface. More...
struct  ast_cc_monitor
struct  ast_cc_monitor_callbacks
 Callbacks defined by CC monitors. More...

Defines

#define ast_cc_config_params_init()   __ast_cc_config_params_init(__FILE__, __LINE__, __PRETTY_FUNCTION__)
 Allocate and initialize an ast_cc_config_params structure.
#define AST_CC_GENERIC_MONITOR_TYPE   "generic"

Typedefs

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)
 Callback made from ast_cc_callback for certain channel types.

Enumerations

enum  ast_cc_agent_flags { AST_CC_AGENT_SKIP_OFFER = (1 << 0) }
 agent flags that can alter core behavior More...
enum  ast_cc_agent_policies { AST_CC_AGENT_NEVER, AST_CC_AGENT_NATIVE, AST_CC_AGENT_GENERIC }
 The various possibilities for cc_agent_policy values. More...
enum  ast_cc_agent_response_reason { AST_CC_AGENT_RESPONSE_SUCCESS, AST_CC_AGENT_RESPONSE_FAILURE_INVALID, AST_CC_AGENT_RESPONSE_FAILURE_TOO_MANY }
enum  ast_cc_monitor_class { AST_CC_DEVICE_MONITOR, AST_CC_EXTENSION_MONITOR }
enum  ast_cc_monitor_policies { AST_CC_MONITOR_NEVER, AST_CC_MONITOR_NATIVE, AST_CC_MONITOR_GENERIC, AST_CC_MONITOR_ALWAYS }
 The various possibilities for cc_monitor_policy values. More...
enum  ast_cc_service_type { AST_CC_NONE, AST_CC_CCBS, AST_CC_CCNR, AST_CC_CCNL }

Functions

struct ast_cc_config_params__ast_cc_config_params_init (const char *file, int line, const char *function)
 Allocate and initialize an ast_cc_config_params structure.
int ast_cc_agent_accept_request (int core_id, const char *const debug,...)
 Accept inbound CC request.
struct ast_cc_agentast_cc_agent_callback (int flags, ao2_callback_fn *function, void *arg, const char *const type)
 Call a callback on all agents of a specific type.
int ast_cc_agent_caller_available (int core_id, const char *const debug,...)
 Indicate that a previously unavailable caller has become available.
int ast_cc_agent_caller_busy (int core_id, const char *const debug,...)
 Indicate that the caller is busy.
int ast_cc_agent_recalling (int core_id, const char *const debug,...)
 Tell the CC core that a caller is currently recalling.
int ast_cc_agent_register (const struct ast_cc_agent_callbacks *callbacks)
 Register a set of agent callbacks with the core.
int ast_cc_agent_set_interfaces_chanvar (struct ast_channel *chan)
 Set the first level CC_INTERFACES channel variable for a channel.
int ast_cc_agent_status_response (int core_id, enum ast_device_state devstate)
 Response with a caller's current status.
void ast_cc_agent_unregister (const struct ast_cc_agent_callbacks *callbacks)
 Unregister a set of agent callbacks with the core.
int ast_cc_available_timer_expire (const void *data)
 Scheduler callback for available timer expiration.
int ast_cc_build_frame (struct ast_channel *chan, struct ast_cc_config_params *cc_params, const char *monitor_type, const char *const device_name, const char *const dialstring, enum ast_cc_service_type service, void *private_data, struct ast_frame *frame)
 Create a CC Control frame.
void ast_cc_busy_interface (struct ast_channel *inbound, struct ast_cc_config_params *cc_params, const char *monitor_type, const char *const device_name, const char *const dialstring, void *private_data)
 Callback made from ast_cc_callback for certain channel types.
void ast_cc_call_failed (struct ast_channel *incoming, struct ast_channel *outgoing, const char *const dialstring)
 Make CCBS available in the case that ast_call fails.
int ast_cc_call_init (struct ast_channel *chan, int *ignore_cc)
 Start the CC process on a call.
int ast_cc_callback (struct ast_channel *inbound, const char *const tech, const char *const dest, ast_cc_callback_fn callback)
 Run a callback for potential matching destinations.
int ast_cc_completed (struct ast_channel *chan, const char *const debug,...)
 Indicate recall has been acknowledged.
void ast_cc_config_params_destroy (struct ast_cc_config_params *params)
 Free memory from CCSS configuration params.
void ast_cc_copy_config_params (struct ast_cc_config_params *dest, const struct ast_cc_config_params *src)
 copy CCSS configuration parameters from one structure to another
void ast_cc_default_config_params (struct ast_cc_config_params *params)
 Set the specified CC config params to default values.
void ast_cc_extension_monitor_add_dialstring (struct ast_channel *incoming, const char *const dialstring, const char *const device_name)
 Add a child dialstring to an extension monitor.
int ast_cc_failed (int core_id, const char *const debug,...)
 Indicate failure has occurred.
int ast_cc_get_current_core_id (struct ast_channel *chan)
 Get the core id for the current call.
struct ast_cc_monitorast_cc_get_monitor_by_recall_core_id (const int core_id, const char *const device_name)
 Get the associated monitor given the device name and core_id.
int ast_cc_get_param (struct ast_cc_config_params *params, const char *const name, char *buf, size_t buf_len)
 get a CCSS configuration parameter, given its name
int ast_cc_init (void)
 Initialize CCSS.
int ast_cc_is_config_param (const char *const name)
 Is this a CCSS configuration parameter?
int ast_cc_is_recall (struct ast_channel *chan, int *core_id, const char *const monitor_type)
 Decide if a call to a particular channel is a CC recall.
int ast_cc_monitor_callee_available (const int core_id, const char *const debug,...)
 Alert the core that a device being monitored has become available.
int ast_cc_monitor_count (const char *const name, const char *const type)
 Return the number of outstanding CC requests to a specific device.
int ast_cc_monitor_failed (int core_id, const char *const monitor_name, const char *const debug,...)
 Indicate that a failure has occurred on a specific monitor.
int ast_cc_monitor_party_b_free (int core_id)
 Alert a caller that though the callee has become free, the caller himself is not and may not call back.
int ast_cc_monitor_register (const struct ast_cc_monitor_callbacks *callbacks)
 Register a set of monitor callbacks with the core.
int ast_cc_monitor_request_acked (int core_id, const char *const debug,...)
 Indicate that an outbound entity has accepted our CC request.
int ast_cc_monitor_status_request (int core_id)
 Request the status of a caller or callers.
int ast_cc_monitor_stop_ringing (int core_id)
 Alert a caller to stop ringing.
void ast_cc_monitor_unregister (const struct ast_cc_monitor_callbacks *callbacks)
 Unregister a set of monitor callbacks with the core.
int ast_cc_offer (struct ast_channel *caller_chan)
 Offer CC to a caller.
int ast_cc_request_is_within_limits (void)
 Check if the incoming CC request is within the bounds set by the cc_max_requests configuration option.
int ast_cc_set_param (struct ast_cc_config_params *params, const char *const name, const char *value)
 set a CCSS configuration parameter, given its name
const char * ast_get_cc_agent_dialstring (struct ast_cc_config_params *config)
 Get the cc_agent_dialstring.
enum ast_cc_agent_policies ast_get_cc_agent_policy (struct ast_cc_config_params *config)
 Get the cc_agent_policy.
const char * ast_get_cc_callback_macro (struct ast_cc_config_params *config)
 Get the name of the callback_macro.
unsigned int ast_get_cc_max_agents (struct ast_cc_config_params *config)
 Get the cc_max_agents.
unsigned int ast_get_cc_max_monitors (struct ast_cc_config_params *config)
 Get the cc_max_monitors.
enum ast_cc_monitor_policies ast_get_cc_monitor_policy (struct ast_cc_config_params *config)
 Get the cc_monitor_policy.
unsigned int ast_get_cc_offer_timer (struct ast_cc_config_params *config)
 Get the cc_offer_timer.
unsigned int ast_get_cc_recall_timer (struct ast_cc_config_params *config)
 Get the cc_recall_timer.
unsigned int ast_get_ccbs_available_timer (struct ast_cc_config_params *config)
 Get the ccbs_available_timer.
unsigned int ast_get_ccnr_available_timer (struct ast_cc_config_params *config)
 Get the ccnr_available_timer.
void ast_handle_cc_control_frame (struct ast_channel *inbound, struct ast_channel *outbound, void *frame_data)
 Properly react to a CC control frame.
void ast_ignore_cc (struct ast_channel *chan)
 Mark the channel to ignore further CC activity.
int ast_queue_cc_frame (struct ast_channel *chan, const char *const monitor_type, const char *const dialstring, enum ast_cc_service_type service, void *private_data)
 Queue an AST_CONTROL_CC frame.
void ast_set_cc_agent_dialstring (struct ast_cc_config_params *config, const char *const value)
 Set the cc_agent_dialstring.
int ast_set_cc_agent_policy (struct ast_cc_config_params *config, enum ast_cc_agent_policies value)
 Set the cc_agent_policy.
void ast_set_cc_callback_macro (struct ast_cc_config_params *config, const char *const value)
 Set the callback_macro name.
int ast_set_cc_interfaces_chanvar (struct ast_channel *chan, const char *const extension)
 Set the CC_INTERFACES channel variable for a channel using an extension as a starting point.
void ast_set_cc_max_agents (struct ast_cc_config_params *config, unsigned int value)
 Set the cc_max_agents.
void ast_set_cc_max_monitors (struct ast_cc_config_params *config, unsigned int value)
 Set the cc_max_monitors.
int ast_set_cc_monitor_policy (struct ast_cc_config_params *config, enum ast_cc_monitor_policies value)
 Set the cc_monitor_policy.
void ast_set_cc_offer_timer (struct ast_cc_config_params *config, unsigned int value)
 Set the cc_offer_timer.
void ast_set_cc_recall_timer (struct ast_cc_config_params *config, unsigned int value)
 Set the cc_recall_timer.
void ast_set_ccbs_available_timer (struct ast_cc_config_params *config, unsigned int value)
 Set the ccbs_available_timer.
void ast_set_ccnr_available_timer (struct ast_cc_config_params *config, unsigned int value)
 Set the ccnr_available_timer.
int ast_setup_cc_recall_datastore (struct ast_channel *chan, const int core_id)
 Set up a CC recall datastore on a channel.


Detailed Description

Call Completion Supplementary Services API.

Author:
Mark Michelson <mmichelson@digium.com>

Definition in file ccss.h.


Define Documentation

 
#define ast_cc_config_params_init (  )     __ast_cc_config_params_init(__FILE__, __LINE__, __PRETTY_FUNCTION__)

Allocate and initialize an ast_cc_config_params structure.

Note:
Reasonable default values are chosen for the parameters upon allocation.
Return values:
NULL Unable to allocate the structure
non-NULL A pointer to the newly allocated and initialized structure

Definition at line 135 of file ccss.h.

Referenced by ast_channel_cc_params_init(), build_peer(), cc_agent_init(), cc_device_monitor_init(), channel_cc_params_copy(), dahdi_chan_conf_default(), duplicate_pseudo(), mkintf(), sip_alloc(), and temp_peer().

#define AST_CC_GENERIC_MONITOR_TYPE   "generic"

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

Definition at line 472 of file ccss.h.

Referenced by analog_call(), ast_cc_call_failed(), dahdi_cc_callback(), and sip_handle_cc().


Typedef Documentation

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)

Callback made from ast_cc_callback for certain channel types.

Since:
1.8
Parameters:
chan A channel involved in the call. What we want is on a datastore on both incoming and outgoing so either may be provided
cc_params The CC configuration parameters for the outbound target
monitor_type The type of monitor to use when CC is requested
device_name The name of the outbound target device.
dialstring The dial string used when calling this specific interface
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.
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.

Returns:
Nothing

Definition at line 1583 of file ccss.h.


Enumeration Type Documentation

agent flags that can alter core behavior

Enumerator:
AST_CC_AGENT_SKIP_OFFER 

Definition at line 59 of file ccss.h.

00059                         {
00060    /* Some agent types allow for a caller to
00061     * request CC without reaching the CC_CALLER_OFFERED
00062     * state. In other words, the caller can request
00063     * CC while he is still on the phone from the failed
00064     * call. The generic agent is an agent which allows
00065     * for this behavior.
00066     */
00067    AST_CC_AGENT_SKIP_OFFER = (1 << 0),
00068 };

The various possibilities for cc_agent_policy values.

Since:
1.8
Enumerator:
AST_CC_AGENT_NEVER  Never offer CCSS to the caller
AST_CC_AGENT_NATIVE  Offer CCSS using native signaling
AST_CC_AGENT_GENERIC  Use generic agent for caller

Definition at line 47 of file ccss.h.

00047                            {
00048    /*! Never offer CCSS to the caller */
00049    AST_CC_AGENT_NEVER,
00050    /*! Offer CCSS using native signaling */
00051    AST_CC_AGENT_NATIVE,
00052    /*! Use generic agent for caller */
00053    AST_CC_AGENT_GENERIC,
00054 };

Enumerator:
AST_CC_AGENT_RESPONSE_SUCCESS  CC request accepted
AST_CC_AGENT_RESPONSE_FAILURE_INVALID  CC request not allowed at this time. Invalid state transition.
AST_CC_AGENT_RESPONSE_FAILURE_TOO_MANY  Too many CC requests in the system.

Definition at line 861 of file ccss.h.

00861                                   {
00862    /*! CC request accepted */
00863    AST_CC_AGENT_RESPONSE_SUCCESS,
00864    /*! CC request not allowed at this time. Invalid state transition. */
00865    AST_CC_AGENT_RESPONSE_FAILURE_INVALID,
00866    /*! Too many CC requests in the system. */
00867    AST_CC_AGENT_RESPONSE_FAILURE_TOO_MANY,
00868 };

Used to determine which type of monitor an ast_cc_device_monitor is.

Enumerator:
AST_CC_DEVICE_MONITOR 
AST_CC_EXTENSION_MONITOR 

Definition at line 479 of file ccss.h.

00479                           {
00480    AST_CC_DEVICE_MONITOR,
00481    AST_CC_EXTENSION_MONITOR,
00482 };

The various possibilities for cc_monitor_policy values.

Since:
1.8
Enumerator:
AST_CC_MONITOR_NEVER  Never accept CCSS offers from callee
AST_CC_MONITOR_NATIVE 
AST_CC_MONITOR_GENERIC  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_ALWAYS  Accept native CCSS offers, but if no offer is present, use a generic CCSS monitor

Definition at line 74 of file ccss.h.

00074                              {
00075    /*! Never accept CCSS offers from callee */
00076    AST_CC_MONITOR_NEVER,
00077    /* CCSS only available if callee offers it through signaling */
00078    AST_CC_MONITOR_NATIVE,
00079    /*! Always use CCSS generic monitor for callee
00080     * Note that if callee offers CCSS natively, we still
00081     * will use a generic CCSS monitor if this is set
00082     */
00083    AST_CC_MONITOR_GENERIC,
00084    /*! Accept native CCSS offers, but if no offer is present,
00085     * use a generic CCSS monitor
00086     */
00087    AST_CC_MONITOR_ALWAYS,
00088 };

Enumerator:
AST_CC_NONE 
AST_CC_CCBS 
AST_CC_CCNR 
AST_CC_CCNL 

Definition at line 32 of file ccss.h.

00032                          {
00033    /* No Service available/requested */
00034    AST_CC_NONE,
00035    /* Call Completion Busy Subscriber */
00036    AST_CC_CCBS,
00037    /* Call Completion No Response */
00038    AST_CC_CCNR,
00039    /* Call Completion Not Logged In (currently SIP only) */
00040    AST_CC_CCNL,
00041 };


Function Documentation

struct ast_cc_config_params* __ast_cc_config_params_init ( const char *  file,
int  line,
const char *  function 
) [read]

Allocate and initialize an ast_cc_config_params structure.

Note:
Reasonable default values are chosen for the parameters upon allocation.
Return values:
NULL Unable to allocate the structure
non-NULL A pointer to the newly allocated and initialized structure

Definition at line 665 of file ccss.c.

References __ast_malloc(), ast_cc_default_config_params(), and ast_malloc.

00666 {
00667 #if defined(__AST_DEBUG_MALLOC)
00668    struct ast_cc_config_params *params = __ast_malloc(sizeof(*params), file, line, function);
00669 #else
00670    struct ast_cc_config_params *params = ast_malloc(sizeof(*params));
00671 #endif
00672 
00673    if (!params) {
00674       return NULL;
00675    }
00676 
00677    ast_cc_default_config_params(params);
00678    return params;
00679 }

int ast_cc_agent_accept_request ( int  core_id,
const char *const   debug,
  ... 
)

Accept inbound CC request.

Since:
1.8
When a caller requests CC, this function should be called to let the core know that the request has been accepted.

Parameters:
core_id core_id of the CC transaction
debug optional string to print for debugging purposes
Return values:
0 Success
-1 Failure

Definition at line 3616 of file ccss.c.

References CC_CALLER_REQUESTED, and cc_request_state_change().

Referenced by ccreq_exec(), and handle_cc_subscribe().

03617 {
03618    va_list ap;
03619    int res;
03620 
03621    va_start(ap, debug);
03622    res = cc_request_state_change(CC_CALLER_REQUESTED, core_id, debug, ap);
03623    va_end(ap);
03624    return res;
03625 }

struct ast_cc_agent* ast_cc_agent_callback ( int  flags,
ao2_callback_fn function,
void *  arg,
const char *const   type 
) [read]

Call a callback on all agents of a specific type.

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.
Parameters:
flags astobj2 search flags
function an ao2 callback function to call
arg the argument to the callback function
type The type of agents to call the callback on

Definition at line 443 of file ccss.c.

References cc_core_instance::agent, ao2_t_callback, cc_agent_callback_helper(), cc_ref(), cc_unref(), and cc_callback_helper::function.

Referenced by find_sip_cc_agent_by_notify_uri(), find_sip_cc_agent_by_original_callid(), and find_sip_cc_agent_by_subscribe_uri().

00444 {
00445    struct cc_callback_helper helper = {.function = function, .args = args, .type = type};
00446    struct cc_core_instance *core_instance;
00447    if ((core_instance = ao2_t_callback(cc_core_instances, flags, cc_agent_callback_helper, &helper,
00448                "Calling provided agent callback function"))) {
00449       struct ast_cc_agent *agent = cc_ref(core_instance->agent, "An outside entity needs the agent");
00450       cc_unref(core_instance, "agent callback done with the core_instance");
00451       return agent;
00452    }
00453    return NULL;
00454 }

int ast_cc_agent_caller_available ( int  core_id,
const char *const   debug,
  ... 
)

Indicate that a previously unavailable caller has become available.

Since:
1.8
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.

Parameters:
core_id core_id of the CC transaction
debug optional string to print for debugging purposes
Return values:
0 Success
-1 Failure

Definition at line 3660 of file ccss.c.

References CC_ACTIVE, and cc_request_state_change().

Referenced by generic_agent_devstate_cb().

03661 {
03662    va_list ap;
03663    int res;
03664 
03665    va_start(ap, debug);
03666    res = cc_request_state_change(CC_ACTIVE, core_id, debug, ap);
03667    va_end(ap);
03668    return res;
03669 }

int ast_cc_agent_caller_busy ( int  core_id,
const char *const   debug,
  ... 
)

Indicate that the caller is busy.

Since:
1.8
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.

Parameters:
core_id core_id of the CC transaction
debug optional string to print for debugging purposes
Return values:
0 Success
-1 Failure

Definition at line 3649 of file ccss.c.

References CC_CALLER_BUSY, and cc_request_state_change().

Referenced by cc_generic_agent_recall(), and sip_cc_agent_recall().

03650 {
03651    va_list ap;
03652    int res;
03653 
03654    va_start(ap, debug);
03655    res = cc_request_state_change(CC_CALLER_BUSY, core_id, debug, ap);
03656    va_end(ap);
03657    return res;
03658 }

int ast_cc_agent_recalling ( int  core_id,
const char *const   debug,
  ... 
)

Tell the CC core that a caller is currently recalling.

Since:
1.8
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.

Parameters:
core_id core_id of the CC transaction
debug optional string to print for debugging purposes
Return values:
0 Success
-1 Failure

Definition at line 3671 of file ccss.c.

References CC_RECALLING, and cc_request_state_change().

Referenced by generic_recall(), and get_destination().

03672 {
03673    va_list ap;
03674    int res;
03675 
03676    va_start(ap, debug);
03677    res = cc_request_state_change(CC_RECALLING, core_id, debug, ap);
03678    va_end(ap);
03679    return res;
03680 }

int ast_cc_agent_register ( const struct ast_cc_agent_callbacks callbacks  ) 

Register a set of agent callbacks with the core.

Since:
1.8
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.

Parameters:
callbacks The callbacks used by the agent implementation
Return values:
0 Successfully registered
-1 Failure to register

Definition at line 1052 of file ccss.c.

References ast_calloc, AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and cc_agent_backend::callbacks.

Referenced by ast_cc_init(), and load_module().

01053 {
01054    struct cc_agent_backend *backend = ast_calloc(1, sizeof(*backend));
01055 
01056    if (!backend) {
01057       return -1;
01058    }
01059 
01060    backend->callbacks = callbacks;
01061    AST_RWLIST_WRLOCK(&cc_agent_backends);
01062    AST_RWLIST_INSERT_TAIL(&cc_agent_backends, backend, next);
01063    AST_RWLIST_UNLOCK(&cc_agent_backends);
01064    return 0;
01065 }

int ast_cc_agent_set_interfaces_chanvar ( struct ast_channel chan  ) 

Set the first level CC_INTERFACES channel variable for a channel.

Since:
1.8
Note:
Implementers of protocol-specific CC agents should call this function after calling ast_setup_cc_recall_datastore.

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.

The CC_INTERFACES channel variable will have the interfaces that should be called back for a specific PBX instance.

Parameters:
chan The channel to set the CC_INTERFACES variable on

Definition at line 3471 of file ccss.c.

References ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_free, AST_LIST_FIRST, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log_dynamic_level, ast_str_buffer(), ast_str_create(), build_cc_interfaces_chanvar(), cc_recall_ds_data::core_id, ast_datastore::data, cc_recall_ds_data::interface_tree, monitor, pbx_builtin_setvar_helper(), and str.

Referenced by generic_recall(), and handle_request_invite().

03472 {
03473    struct ast_datastore *recall_datastore;
03474    struct cc_monitor_tree *interface_tree;
03475    struct ast_cc_monitor *monitor;
03476    struct cc_recall_ds_data *recall_data;
03477    struct ast_str *str = ast_str_create(64);
03478    int core_id;
03479 
03480    if (!str) {
03481       return -1;
03482    }
03483 
03484    ast_channel_lock(chan);
03485    if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
03486       ast_channel_unlock(chan);
03487       ast_free(str);
03488       return -1;
03489    }
03490    recall_data = recall_datastore->data;
03491    interface_tree = recall_data->interface_tree;
03492    core_id = recall_data->core_id;
03493    ast_channel_unlock(chan);
03494 
03495    AST_LIST_LOCK(interface_tree);
03496    monitor = AST_LIST_FIRST(interface_tree);
03497    build_cc_interfaces_chanvar(monitor, str);
03498    AST_LIST_UNLOCK(interface_tree);
03499 
03500    pbx_builtin_setvar_helper(chan, "CC_INTERFACES", ast_str_buffer(str));
03501    ast_log_dynamic_level(cc_logger_level, "Core %d: CC_INTERFACES set to %s\n",
03502          core_id, ast_str_buffer(str));
03503 
03504    ast_free(str);
03505    return 0;
03506 }

int ast_cc_agent_status_response ( int  core_id,
enum ast_device_state  devstate 
)

Response with a caller's current status.

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.

Parameters:
core_id The core ID of the CC transaction
devstate The current state of the caller to which the agent pertains
Return values:
0 Successfully responded with our status
-1 Failed to respond with our status

Definition at line 3936 of file ccss.c.

References args, ast_calloc, ast_free, ast_taskprocessor_push(), cc_status_response(), cc_unref(), cc_status_response_args::core_instance, cc_status_response_args::devstate, and find_cc_core_instance().

Referenced by cc_generic_agent_status_request(), and sip_cc_agent_status_request().

03937 {
03938    struct cc_status_response_args *args;
03939    struct cc_core_instance *core_instance;
03940    int res;
03941 
03942    args = ast_calloc(1, sizeof(*args));
03943    if (!args) {
03944       return -1;
03945    }
03946 
03947    core_instance = find_cc_core_instance(core_id);
03948    if (!core_instance) {
03949       ast_free(args);
03950       return -1;
03951    }
03952 
03953    args->core_instance = core_instance;
03954    args->devstate = devstate;
03955 
03956    res = ast_taskprocessor_push(cc_core_taskprocessor, cc_status_response, args);
03957    if (res) {
03958       cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed");
03959       ast_free(args);
03960    }
03961    return res;
03962 }

void ast_cc_agent_unregister ( const struct ast_cc_agent_callbacks callbacks  ) 

Unregister a set of agent callbacks with the core.

Since:
1.8
If a module which makes use of a CC agent is unloaded, then it may unregister its agent callbacks with the core.

Parameters:
callbacks The callbacks used by the agent implementation
Return values:
0 Successfully unregistered
-1 Failure to unregister

Definition at line 1067 of file ccss.c.

References ast_free, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, cc_agent_backend::callbacks, and cc_monitor_backend::next.

Referenced by __unload_module(), and unload_module().

01068 {
01069    struct cc_agent_backend *backend;
01070    AST_RWLIST_WRLOCK(&cc_agent_backends);
01071    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&cc_agent_backends, backend, next) {
01072       if (backend->callbacks == callbacks) {
01073          AST_RWLIST_REMOVE_CURRENT(next);
01074          ast_free(backend);
01075          break;
01076       }
01077    }
01078    AST_RWLIST_TRAVERSE_SAFE_END;
01079    AST_RWLIST_UNLOCK(&cc_agent_backends);
01080 }

int ast_cc_available_timer_expire ( const void *  data  ) 

Scheduler callback for available timer expiration.

Since:
1.8
Note:
When arming the available timer from within a device monitor, you MUST use this function as the callback for the scheduler.
Parameters:
data A reference to the CC monitor on which the timer was running.

Definition at line 1335 of file ccss.c.

References ast_cc_monitor_failed(), ast_cc_monitor::available_timer_id, cc_unref(), ast_cc_monitor::core_id, ast_cc_interface::device_name, ast_cc_monitor::interface, and monitor.

Referenced by cc_generic_monitor_request_cc(), and sip_cc_monitor_request_cc().

01336 {
01337    struct ast_cc_monitor *monitor = (struct ast_cc_monitor *) data;
01338    int res;
01339    monitor->available_timer_id = -1;
01340    res = ast_cc_monitor_failed(monitor->core_id, monitor->interface->device_name, "Available timer expired for monitor");
01341    cc_unref(monitor, "Unref reference from scheduler\n");
01342    return res;
01343 }

int ast_cc_build_frame ( struct ast_channel chan,
struct ast_cc_config_params cc_params,
const char *  monitor_type,
const char *const   device_name,
const char *const   dialstring,
enum ast_cc_service_type  service,
void *  private_data,
struct ast_frame frame 
)

Create a CC Control frame.

Since:
1.8
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.

Parameters:
chan A channel involved in the call. What we want is on a datastore on both incoming and outgoing so either may be provided
cc_params The CC configuration parameters for the outbound target
monitor_type The type of monitor to use when CC is requested
device_name The name of the outbound target device.
dialstring The dial string used when calling this specific interface
service What kind of CC service is being offered. (CCBS/CCNR/etc...)
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.
[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.
Return values:
-1 Failure. At some point there was a failure. Do not attempt to use the frame in this case.
0 Success

Definition at line 4019 of file ccss.c.

References ast_calloc, AST_CONTROL_CC, AST_FRAME_CONTROL, ast_free, AST_MALLOCD_DATA, cc_build_payload(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, ast_frame_subclass::integer, ast_frame::mallocd, ast_frame::ptr, and ast_frame::subclass.

Referenced by ast_queue_cc_frame().

04023 {
04024    struct cc_control_payload *payload = ast_calloc(1, sizeof(*payload));
04025 
04026    if (!payload) {
04027       return -1;
04028    }
04029    if (cc_build_payload(chan, cc_params, monitor_type, device_name, dialstring, service, private_data, payload)) {
04030       /* Something screwed up, we can't make a frame with this */
04031       ast_free(payload);
04032       return -1;
04033    }
04034    frame->frametype = AST_FRAME_CONTROL;
04035    frame->subclass.integer = AST_CONTROL_CC;
04036    frame->data.ptr = payload;
04037    frame->datalen = sizeof(*payload);
04038    frame->mallocd = AST_MALLOCD_DATA;
04039    return 0;
04040 }

void ast_cc_busy_interface ( struct ast_channel inbound,
struct ast_cc_config_params cc_params,
const char *  monitor_type,
const char *const   device_name,
const char *const   dialstring,
void *  private_data 
)

Callback made from ast_cc_callback for certain channel types.

Since:
1.8
Parameters:
inbound Incoming asterisk channel.
cc_params The CC configuration parameters for the outbound target
monitor_type The type of monitor to use when CC is requested
device_name The name of the outbound target device.
dialstring The dial string used when calling this specific interface
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.
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.

Definition at line 4075 of file ccss.c.

References AST_CC_CCBS, ast_handle_cc_control_frame(), call_destructor_with_no_monitor(), and cc_build_payload().

Referenced by dial_exec_full().

04077 {
04078    struct cc_control_payload payload;
04079    if (cc_build_payload(inbound, cc_params, monitor_type, device_name, dialstring, AST_CC_CCBS, private_data, &payload)) {
04080       /* Something screwed up. Don't try to handle this payload */
04081       call_destructor_with_no_monitor(monitor_type, private_data);
04082       return;
04083    }
04084    ast_handle_cc_control_frame(inbound, NULL, &payload);
04085 }

void ast_cc_call_failed ( struct ast_channel incoming,
struct ast_channel outgoing,
const char *const   dialstring 
)

Make CCBS available in the case that ast_call fails.

Since:
1.8 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.

Definition at line 4042 of file ccss.c.

References AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CC_CCBS, AST_CC_GENERIC_MONITOR_TYPE, AST_CC_MONITOR_GENERIC, ast_channel_get_cc_config_params(), ast_channel_get_device_name(), AST_CHANNEL_NAME, ast_get_cc_monitor_policy(), ast_handle_cc_control_frame(), cc_build_payload(), and ast_channel::hangupcause.

Referenced by dial_exec_full().

04043 {
04044    char device_name[AST_CHANNEL_NAME];
04045    struct cc_control_payload payload;
04046    struct ast_cc_config_params *cc_params;
04047 
04048    if (outgoing->hangupcause != AST_CAUSE_BUSY && outgoing->hangupcause != AST_CAUSE_CONGESTION) {
04049       /* It doesn't make sense to try to offer CCBS to the caller if the reason for ast_call
04050        * failing is something other than busy or congestion
04051        */
04052       return;
04053    }
04054 
04055    cc_params = ast_channel_get_cc_config_params(outgoing);
04056    if (!cc_params) {
04057       return;
04058    }
04059    if (ast_get_cc_monitor_policy(cc_params) != AST_CC_MONITOR_GENERIC) {
04060       /* This sort of CCBS only works if using generic CC. For native, we would end up sending
04061        * a CC request for a non-existent call. The far end will reject this every time
04062        */
04063       return;
04064    }
04065 
04066    ast_channel_get_device_name(outgoing, device_name, sizeof(device_name));
04067    if (cc_build_payload(outgoing, cc_params, AST_CC_GENERIC_MONITOR_TYPE, device_name,
04068       dialstring, AST_CC_CCBS, NULL, &payload)) {
04069       /* Something screwed up, we can't make a frame with this */
04070       return;
04071    }
04072    ast_handle_cc_control_frame(incoming, outgoing, &payload);
04073 }

int ast_cc_call_init ( struct ast_channel chan,
int *  ignore_cc 
)

Start the CC process on a call.

Since:
1.8
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.

Parameters:
chan The inbound channel calling the CC-capable application.
[out] ignore_cc Will be set non-zero if no further CC actions need to be taken
Return values:
0 Success
-1 Failure

Definition at line 2242 of file ccss.c.

References AST_CC_AGENT_NEVER, ast_channel_datastore_find(), ast_channel_get_cc_config_params(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_get_cc_agent_policy(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log_dynamic_level, cc_extension_monitor_init(), cc_interfaces_datastore_init(), cc_ref(), cc_unref(), ast_channel::context, dialed_cc_interfaces::core_id, ast_cc_monitor::core_id, ast_datastore::data, dialed_cc_interfaces::dial_parent_id, ast_channel::exten, ast_cc_monitor::id, dialed_cc_interfaces::ignore, dialed_cc_interfaces::interface_tree, interfaces, ast_channel::macrocontext, ast_channel::macroexten, monitor, and S_OR.

Referenced by dial_exec_full().

02243 {
02244    /* There are three situations to deal with here:
02245     *
02246     * 1. The channel does not have a dialed_cc_interfaces datastore on
02247     * it. This means that this is the first time that Dial has
02248     * been called. We need to create/initialize the datastore.
02249     *
02250     * 2. The channel does have a cc_interface datastore on it and
02251     * the "ignore" indicator is 0. This means that a Local channel
02252     * was called by a "parent" dial. We can check the datastore's
02253     * parent field to see who the root of this particular dial tree
02254     * is.
02255     *
02256     * 3. The channel does have a cc_interface datastore on it and
02257     * the "ignore" indicator is 1. This means that a second Dial call
02258     * is being made from an extension. In this case, we do not
02259     * want to make any additions/modifications to the datastore. We
02260     * will instead set a flag to indicate that CCSS is completely
02261     * disabled for this Dial attempt.
02262     */
02263 
02264    struct ast_datastore *cc_interfaces_datastore;
02265    struct dialed_cc_interfaces *interfaces;
02266    struct ast_cc_monitor *monitor;
02267    struct ast_cc_config_params *cc_params;
02268 
02269    ast_channel_lock(chan);
02270 
02271    cc_params = ast_channel_get_cc_config_params(chan);
02272    if (!cc_params) {
02273       ast_channel_unlock(chan);
02274       return -1;
02275    }
02276    if (ast_get_cc_agent_policy(cc_params) == AST_CC_AGENT_NEVER) {
02277       /* We can't offer CC to this caller anyway, so don't bother with CC on this call
02278        */
02279       *ignore_cc = 1;
02280       ast_channel_unlock(chan);
02281       ast_log_dynamic_level(cc_logger_level, "Agent policy for %s is 'never'. CC not possible\n", ast_channel_name(chan));
02282       return 0;
02283    }
02284 
02285    if (!(cc_interfaces_datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL))) {
02286       /* Situation 1 has occurred */
02287       ast_channel_unlock(chan);
02288       return cc_interfaces_datastore_init(chan);
02289    }
02290    interfaces = cc_interfaces_datastore->data;
02291    ast_channel_unlock(chan);
02292 
02293    if (interfaces->ignore) {
02294       /* Situation 3 has occurred */
02295       *ignore_cc = 1;
02296       ast_log_dynamic_level(cc_logger_level, "Datastore is present with ignore flag set. Ignoring CC offers on this call\n");
02297       return 0;
02298    }
02299 
02300    /* Situation 2 has occurred */
02301    if (!(monitor = cc_extension_monitor_init(S_OR(chan->macroexten, chan->exten),
02302          S_OR(chan->macrocontext, chan->context), interfaces->dial_parent_id))) {
02303       return -1;
02304    }
02305    monitor->core_id = interfaces->core_id;
02306    AST_LIST_LOCK(interfaces->interface_tree);
02307    cc_ref(monitor, "monitor tree's reference to the monitor");
02308    AST_LIST_INSERT_TAIL(interfaces->interface_tree, monitor, next);
02309    AST_LIST_UNLOCK(interfaces->interface_tree);
02310    interfaces->dial_parent_id = monitor->id;
02311    cc_unref(monitor, "Unref monitor's allocation reference");
02312    return 0;
02313 }

int ast_cc_callback ( struct ast_channel inbound,
const char *const   tech,
const char *const   dest,
ast_cc_callback_fn  callback 
)

Run a callback for potential matching destinations.

Since:
1.8
Note:
See the explanation in ast_channel_tech::cc_callback for more details.
Parameters:
inbound 
tech Channel technology to use
dest Channel/group/peer or whatever the specific technology uses
callback Function to call when a target is reached
Return values:
Always 0, I guess.

Definition at line 4087 of file ccss.c.

References ast_get_channel_tech(), and ast_channel_tech::cc_callback.

Referenced by dial_exec_full().

04088 {
04089    const struct ast_channel_tech *chantech = ast_get_channel_tech(tech);
04090 
04091    if (chantech && chantech->cc_callback) {
04092       chantech->cc_callback(inbound, dest, callback);
04093    }
04094 
04095    return 0;
04096 }

int ast_cc_completed ( struct ast_channel chan,
const char *const   debug,
  ... 
)

Indicate recall has been acknowledged.

Since:
1.8
When we receive confirmation that an endpoint has responded to our CC recall, we call this function.

Parameters:
chan The inbound channel making the CC recall
debug optional string to print for debugging purposes
Return values:
0 Success
-1 Failure

Definition at line 3682 of file ccss.c.

References ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, CC_COMPLETE, cc_request_state_change(), cc_recall_ds_data::core_id, ast_datastore::data, cc_recall_ds_data::ignore, and cc_recall_ds_data::nested.

Referenced by wait_for_answer().

03683 {
03684    struct ast_datastore *recall_datastore;
03685    struct cc_recall_ds_data *recall_data;
03686    int core_id;
03687    va_list ap;
03688    int res;
03689 
03690    ast_channel_lock(chan);
03691    if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
03692       /* Silly! Why did you call this function if there's no recall DS? */
03693       ast_channel_unlock(chan);
03694       return -1;
03695    }
03696    recall_data = recall_datastore->data;
03697    if (recall_data->nested || recall_data->ignore) {
03698       /* If this is being called from a nested Dial, it is too
03699        * early to determine if the recall has actually completed.
03700        * The outermost dial is the only one with the authority to
03701        * declare the recall to be complete.
03702        *
03703        * Similarly, if this function has been called when the
03704        * recall has progressed beyond the first dial, this is not
03705        * a legitimate time to declare the recall to be done. In fact,
03706        * that should have been done already.
03707        */
03708       ast_channel_unlock(chan);
03709       return -1;
03710    }
03711    core_id = recall_data->core_id;
03712    ast_channel_unlock(chan);
03713    va_start(ap, debug);
03714    res = cc_request_state_change(CC_COMPLETE, core_id, debug, ap);
03715    va_end(ap);
03716    return res;
03717 }

void ast_cc_config_params_destroy ( struct ast_cc_config_params params  ) 

Free memory from CCSS configuration params.

Note:
Just a call to ast_free for now...
Parameters:
params Pointer to structure whose memory we need to free
Return values:
void 

Definition at line 681 of file ccss.c.

References ast_free.

Referenced by __sip_destroy(), agent_destroy(), ast_channel_cc_params_init(), cc_interface_destroy(), channel_cc_params_destroy(), destroy_dahdi_pvt(), process_dahdi(), setup_dahdi(), and sip_destroy_peer().

00682 {
00683    ast_free(params);
00684 }

void ast_cc_copy_config_params ( struct ast_cc_config_params dest,
const struct ast_cc_config_params src 
)

copy CCSS configuration parameters from one structure to another

Since:
1.8
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.

Parameters:
src The structure from which data is copied
dest The structure to which data is copied
Returns:
Nothing

Definition at line 843 of file ccss.c.

Referenced by ast_channel_cc_params_init(), cc_agent_init(), cc_build_payload(), cc_device_monitor_init(), channel_cc_params_copy(), check_peer_ok(), create_addr_from_peer(), dahdi_new(), deep_copy_dahdi_chan_conf(), duplicate_pseudo(), and mkintf().

00844 {
00845    *dest = *src;
00846 }

void ast_cc_default_config_params ( struct ast_cc_config_params params  ) 

Set the specified CC config params to default values.

Since:
1.8
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.

Parameters:
params CC config params to set to default values.
Returns:
Nothing

Definition at line 660 of file ccss.c.

Referenced by __ast_cc_config_params_init().

00661 {
00662    *params = cc_default_params;
00663 }

void ast_cc_extension_monitor_add_dialstring ( struct ast_channel incoming,
const char *const   dialstring,
const char *const   device_name 
)

Add a child dialstring to an extension monitor.

Since:
1.8
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.

Parameters:
incoming The caller's channel
dialstring The dialstring used when requesting the outbound channel
device_name The device name associated with the requested outbound channel
Return values:
void 

Definition at line 1831 of file ccss.c.

References ast_calloc, ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, extension_monitor_pvt::child_dialstrings, ast_datastore::data, extension_child_dialstring::device_name, dialed_cc_interfaces::dial_parent_id, ast_cc_monitor::id, id, dialed_cc_interfaces::interface_tree, extension_child_dialstring::is_valid, monitor, extension_child_dialstring::original_dialstring, and ast_cc_monitor::private_data.

Referenced by dial_exec_full().

01832 {
01833    struct ast_datastore *cc_datastore;
01834    struct dialed_cc_interfaces *cc_interfaces;
01835    struct ast_cc_monitor *monitor;
01836    struct extension_monitor_pvt *extension_pvt;
01837    struct extension_child_dialstring *child_dialstring;
01838    struct cc_monitor_tree *interface_tree;
01839    int id;
01840 
01841    ast_channel_lock(incoming);
01842    if (!(cc_datastore = ast_channel_datastore_find(incoming, &dialed_cc_interfaces_info, NULL))) {
01843       ast_channel_unlock(incoming);
01844       return;
01845    }
01846 
01847    cc_interfaces = cc_datastore->data;
01848    interface_tree = cc_interfaces->interface_tree;
01849    id = cc_interfaces->dial_parent_id;
01850    ast_channel_unlock(incoming);
01851 
01852    AST_LIST_LOCK(interface_tree);
01853    AST_LIST_TRAVERSE(interface_tree, monitor, next) {
01854       if (monitor->id == id) {
01855          break;
01856       }
01857    }
01858 
01859    if (!monitor) {
01860       AST_LIST_UNLOCK(interface_tree);
01861       return;
01862    }
01863 
01864    extension_pvt = monitor->private_data;
01865    if (!(child_dialstring = ast_calloc(1, sizeof(*child_dialstring)))) {
01866       AST_LIST_UNLOCK(interface_tree);
01867       return;
01868    }
01869    ast_copy_string(child_dialstring->original_dialstring, dialstring, sizeof(child_dialstring->original_dialstring));
01870    ast_copy_string(child_dialstring->device_name, device_name, sizeof(child_dialstring->device_name));
01871    child_dialstring->is_valid = 1;
01872    AST_LIST_INSERT_TAIL(&extension_pvt->child_dialstrings, child_dialstring, next);
01873    AST_LIST_UNLOCK(interface_tree);
01874 }

int ast_cc_failed ( int  core_id,
const char *const   debug,
  ... 
)

Indicate failure has occurred.

Since:
1.8
If at any point a failure occurs, this is the function to call so that the core can initiate cleanup procedures.

Parameters:
core_id core_id of the CC transaction
debug optional string to print for debugging purposes
Return values:
0 Success
-1 Failure

Definition at line 3719 of file ccss.c.

References CC_FAILED, and cc_request_state_change().

Referenced by cancel_available_timer(), cc_caller_offered(), cc_caller_requested(), cc_monitor_failed(), cccancel_exec(), ccreq_exec(), generic_recall(), handle_cc_subscribe(), kill_cores(), offer_timer_expire(), request_cc(), sip_offer_timer_expire(), suspend(), unsuspend(), and wait_for_answer().

03720 {
03721    va_list ap;
03722    int res;
03723 
03724    va_start(ap, debug);
03725    res = cc_request_state_change(CC_FAILED, core_id, debug, ap);
03726    va_end(ap);
03727    return res;
03728 }

int ast_cc_get_current_core_id ( struct ast_channel chan  ) 

Get the core id for the current call.

Since:
1.8
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.

Parameters:
chan The channel from which to get the core_id.
Return values:
core_id on success
-1 Failure

Definition at line 2320 of file ccss.c.

References ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, dialed_cc_interfaces::core_id, ast_datastore::data, and dialed_cc_interfaces::ignore.

Referenced by sip_handle_cc().

02321 {
02322    struct ast_datastore *datastore;
02323    struct dialed_cc_interfaces *cc_interfaces;
02324    int core_id_return;
02325 
02326    ast_channel_lock(chan);
02327    if (!(datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL))) {
02328       ast_channel_unlock(chan);
02329       return -1;
02330    }
02331 
02332    cc_interfaces = datastore->data;
02333    core_id_return = cc_interfaces->ignore ? -1 : cc_interfaces->core_id;
02334    ast_channel_unlock(chan);
02335    return core_id_return;
02336 
02337 }

struct ast_cc_monitor* ast_cc_get_monitor_by_recall_core_id ( const int  core_id,
const char *const   device_name 
) [read]

Get the associated monitor given the device name and core_id.

Since:
1.8
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.
Parameters:
core_id The core ID to which this recall corresponds. This likely will have been obtained using the ast_cc_is_recall function
device_name Which device to find the monitor for.
Return values:
NULL Appropriate monitor does not exist
non-NULL The monitor to use for this recall

Definition at line 3359 of file ccss.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, cc_ref(), cc_unref(), ast_cc_interface::device_name, find_cc_core_instance(), ast_cc_monitor::interface, and cc_core_instance::monitors.

Referenced by sip_call().

03360 {
03361    struct cc_core_instance *core_instance = find_cc_core_instance(core_id);
03362    struct ast_cc_monitor *monitor_iter;
03363 
03364    if (!core_instance) {
03365       return NULL;
03366    }
03367 
03368    AST_LIST_LOCK(core_instance->monitors);
03369    AST_LIST_TRAVERSE(core_instance->monitors, monitor_iter, next) {
03370       if (!strcmp(monitor_iter->interface->device_name, device_name)) {
03371          /* Found a monitor. */
03372          cc_ref(monitor_iter, "Hand the requester of the monitor a reference");
03373          break;
03374       }
03375    }
03376    AST_LIST_UNLOCK(core_instance->monitors);
03377    cc_unref(core_instance, "Done with core instance ref in ast_cc_get_monitor_by_recall_core_id");
03378    return monitor_iter;
03379 }

int ast_cc_get_param ( struct ast_cc_config_params params,
const char *const   name,
char *  buf,
size_t  buf_len 
)

get a CCSS configuration parameter, given its name

Note:
Useful when reading input as a string, like from dialplan or manager.
Parameters:
params The CCSS configuration from which to get the value
name The name of the CCSS parameter we want
buf A preallocated buffer to hold the value
buf_len The size of buf
Return values:
0 Success
-1 Failure

Definition at line 747 of file ccss.c.

References agent_policy_to_str(), ast_copy_string(), ast_get_cc_agent_dialstring(), ast_get_cc_agent_policy(), ast_get_cc_callback_macro(), ast_get_cc_max_agents(), ast_get_cc_max_monitors(), ast_get_cc_monitor_policy(), ast_get_cc_offer_timer(), ast_get_cc_recall_timer(), ast_get_ccbs_available_timer(), ast_get_ccnr_available_timer(), ast_log(), LOG_WARNING, monitor_policy_to_str(), and value.

Referenced by acf_cc_read().

00749 {
00750    const char *value = NULL;
00751 
00752    if (!strcasecmp(name, "cc_callback_macro")) {
00753       value = ast_get_cc_callback_macro(params);
00754    } else if (!strcasecmp(name, "cc_agent_policy")) {
00755       value = agent_policy_to_str(ast_get_cc_agent_policy(params));
00756    } else if (!strcasecmp(name, "cc_monitor_policy")) {
00757       value = monitor_policy_to_str(ast_get_cc_monitor_policy(params));
00758    } else if (!strcasecmp(name, "cc_agent_dialstring")) {
00759       value = ast_get_cc_agent_dialstring(params);
00760    }
00761    if (value) {
00762       ast_copy_string(buf, value, buf_len);
00763       return 0;
00764    }
00765 
00766    /* The rest of these are all ints of some sort and require some
00767     * snprintf-itude
00768     */
00769 
00770    if (!strcasecmp(name, "cc_offer_timer")) {
00771       snprintf(buf, buf_len, "%u", ast_get_cc_offer_timer(params));
00772    } else if (!strcasecmp(name, "ccnr_available_timer")) {
00773       snprintf(buf, buf_len, "%u", ast_get_ccnr_available_timer(params));
00774    } else if (!strcasecmp(name, "ccbs_available_timer")) {
00775       snprintf(buf, buf_len, "%u", ast_get_ccbs_available_timer(params));
00776    } else if (!strcasecmp(name, "cc_max_agents")) {
00777       snprintf(buf, buf_len, "%u", ast_get_cc_max_agents(params));
00778    } else if (!strcasecmp(name, "cc_max_monitors")) {
00779       snprintf(buf, buf_len, "%u", ast_get_cc_max_monitors(params));
00780    } else if (!strcasecmp(name, "cc_recall_timer")) {
00781       snprintf(buf, buf_len, "%u", ast_get_cc_recall_timer(params));
00782    } else {
00783       ast_log(LOG_WARNING, "%s is not a valid CC parameter. Ignoring.\n", name);
00784       return -1;
00785    }
00786 
00787    return 0;
00788 }

int ast_cc_init ( void   ) 

Initialize CCSS.

Since:
1.8 Performs startup routines necessary for CC operation.
Return values:
0 Success
nonzero Failure

Definition at line 4472 of file ccss.c.

References ao2_t_container_alloc, ARRAY_LEN, ast_cc_agent_register(), ast_cc_monitor_register(), ast_cli_register_multiple(), ast_devstate_prov_add(), ast_logger_register_level(), ast_register_application2(), ast_sched_context_create(), ast_sched_start_thread(), ast_taskprocessor_get(), cc_core_instance_cmp_fn(), cc_core_instance_hash_fn(), cccancel_exec(), ccreq_exec(), ccss_device_state(), generic_monitor_cbs, generic_monitor_cmp_fn(), generic_monitor_hash_fn(), generic_monitors, initialize_cc_devstate_map(), initialize_cc_max_requests(), and TPS_REF_DEFAULT.

Referenced by main().

04473 {
04474    int res;
04475 
04476    if (!(cc_core_instances = ao2_t_container_alloc(CC_CORE_INSTANCES_BUCKETS,
04477                cc_core_instance_hash_fn, cc_core_instance_cmp_fn,
04478                "Create core instance container"))) {
04479       return -1;
04480    }
04481    if (!(generic_monitors = ao2_t_container_alloc(CC_CORE_INSTANCES_BUCKETS,
04482                generic_monitor_hash_fn, generic_monitor_cmp_fn,
04483                "Create generic monitor container"))) {
04484       return -1;
04485    }
04486    if (!(cc_core_taskprocessor = ast_taskprocessor_get("CCSS core", TPS_REF_DEFAULT))) {
04487       return -1;
04488    }
04489    if (!(cc_sched_context = ast_sched_context_create())) {
04490       return -1;
04491    }
04492    if (ast_sched_start_thread(cc_sched_context)) {
04493       return -1;
04494    }
04495    res = ast_register_application2(ccreq_app, ccreq_exec, NULL, NULL, NULL);
04496    res |= ast_register_application2(cccancel_app, cccancel_exec, NULL, NULL, NULL);
04497    res |= ast_cc_monitor_register(&generic_monitor_cbs);
04498    res |= ast_cc_agent_register(&generic_agent_callbacks);
04499 
04500    ast_cli_register_multiple(cc_cli, ARRAY_LEN(cc_cli));
04501    cc_logger_level = ast_logger_register_level(CC_LOGGER_LEVEL_NAME);
04502    dialed_cc_interface_counter = 1;
04503    initialize_cc_max_requests();
04504 
04505    /* Read the map and register the device state callback for generic agents */
04506    initialize_cc_devstate_map();
04507    res |= ast_devstate_prov_add("ccss", ccss_device_state);
04508 
04509    return res;
04510 }

int ast_cc_is_config_param ( const char *const   name  ) 

Is this a CCSS configuration parameter?

Since:
1.8
Parameters:
name Name of configuration option being parsed.
Return values:
1 Yes, this is a CCSS configuration parameter.
0 No, this is not a CCSS configuration parameter.

Definition at line 829 of file ccss.c.

Referenced by build_peer(), and process_dahdi().

00830 {
00831    return (!strcasecmp(name, "cc_agent_policy") ||
00832             !strcasecmp(name, "cc_monitor_policy") ||
00833             !strcasecmp(name, "cc_offer_timer") ||
00834             !strcasecmp(name, "ccnr_available_timer") ||
00835             !strcasecmp(name, "ccbs_available_timer") ||
00836             !strcasecmp(name, "cc_max_agents") ||
00837             !strcasecmp(name, "cc_max_monitors") ||
00838             !strcasecmp(name, "cc_callback_macro") ||
00839             !strcasecmp(name, "cc_agent_dialstring") ||
00840             !strcasecmp(name, "cc_recall_timer"));
00841 }

int ast_cc_is_recall ( struct ast_channel chan,
int *  core_id,
const char *const   monitor_type 
)

Decide if a call to a particular channel is a CC recall.

Since:
1.8
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.

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.

Parameters:
chan The channel to check
[out] core_id If this is a valid CC recall, the core_id of the failed call will be placed in this output parameter
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.
Return values:
0 Either this is not a recall or it is but this channel is not part of the recall
non-zero This is a recall and the channel in question is directly involved.

Definition at line 3278 of file ccss.c.

References ast_assert, ast_channel_datastore_find(), ast_channel_get_device_name(), ast_channel_lock, AST_CHANNEL_NAME, ast_channel_unlock, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), cc_recall_ds_data::core_id, ast_datastore::data, ast_cc_interface::device_name, cc_recall_ds_data::ignore, ast_cc_monitor::interface, cc_recall_ds_data::interface_tree, ast_cc_interface::monitor_type, and cc_recall_ds_data::nested.

Referenced by cc_core_init_instance(), sip_call(), and wait_for_answer().

03279 {
03280    struct ast_datastore *recall_datastore;
03281    struct cc_recall_ds_data *recall_data;
03282    struct cc_monitor_tree *interface_tree;
03283    char device_name[AST_CHANNEL_NAME];
03284    struct ast_cc_monitor *device_monitor;
03285    int core_id_candidate;
03286 
03287    ast_assert(core_id != NULL);
03288 
03289    *core_id = -1;
03290 
03291    ast_channel_lock(chan);
03292    if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
03293       /* Obviously not a recall if the datastore isn't present */
03294       ast_channel_unlock(chan);
03295       return 0;
03296    }
03297 
03298    recall_data = recall_datastore->data;
03299 
03300    if (recall_data->ignore) {
03301       /* Though this is a recall, the call to this particular interface is not part of the
03302        * recall either because this is a call forward or because this is not the first
03303        * invocation of Dial during this call
03304        */
03305       ast_channel_unlock(chan);
03306       return 0;
03307    }
03308 
03309    if (!recall_data->nested) {
03310       /* If the nested flag is not set, then this means that
03311        * the channel passed to this function is the caller making
03312        * the recall. This means that we shouldn't look through
03313        * the monitor tree for the channel because it shouldn't be
03314        * there. However, this is a recall though, so return true.
03315        */
03316       *core_id = recall_data->core_id;
03317       ast_channel_unlock(chan);
03318       return 1;
03319    }
03320 
03321    if (ast_strlen_zero(monitor_type)) {
03322       /* If someone passed a NULL or empty monitor type, then it is clear
03323        * the channel they passed in was an incoming channel, and so searching
03324        * the list of dialed interfaces is not going to be helpful. Just return
03325        * false immediately.
03326        */
03327       ast_channel_unlock(chan);
03328       return 0;
03329    }
03330 
03331    interface_tree = recall_data->interface_tree;
03332    ast_channel_get_device_name(chan, device_name, sizeof(device_name));
03333    /* We grab the value of the recall_data->core_id so that we
03334     * can unlock the channel before we start looking through the
03335     * interface list. That way we don't have to worry about a possible
03336     * clash between the channel lock and the monitor tree lock.
03337     */
03338    core_id_candidate = recall_data->core_id;
03339    ast_channel_unlock(chan);
03340 
03341    /*
03342     * Now we need to find out if the channel device name
03343     * is in the list of interfaces in the called tree.
03344     */
03345    AST_LIST_LOCK(interface_tree);
03346    AST_LIST_TRAVERSE(interface_tree, device_monitor, next) {
03347       if (!strcmp(device_monitor->interface->device_name, device_name) &&
03348             !strcmp(device_monitor->interface->monitor_type, monitor_type)) {
03349          /* BOOM! Device is in the tree! We have a winner! */
03350          *core_id = core_id_candidate;
03351          AST_LIST_UNLOCK(interface_tree);
03352          return 1;
03353       }
03354    }
03355    AST_LIST_UNLOCK(interface_tree);
03356    return 0;
03357 }

int ast_cc_monitor_callee_available ( const int  core_id,
const char *const   debug,
  ... 
)

Alert the core that a device being monitored has become available.

Since:
1.8
Note:
The code in the core will take care of making sure that the information gets passed up the ladder correctly.
Parameters:
core_id The core ID of the corresponding CC transaction
debug 
Return values:
0 Request successfully queued
-1 Request could not be queued

Definition at line 3638 of file ccss.c.

References CC_CALLEE_READY, and cc_request_state_change().

Referenced by cc_generic_monitor_destructor(), cc_generic_monitor_suspend(), cc_generic_monitor_unsuspend(), generic_monitor_devstate_tp_cb(), and handle_cc_notify().

03639 {
03640    va_list ap;
03641    int res;
03642 
03643    va_start(ap, debug);
03644    res = cc_request_state_change(CC_CALLEE_READY, core_id, debug, ap);
03645    va_end(ap);
03646    return res;
03647 }

int ast_cc_monitor_count ( const char *const   name,
const char *const   type 
)

Return the number of outstanding CC requests to a specific device.

Since:
1.8
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.
Parameters:
name The name of the monitored device
type The type of the monitored device (e.g. "generic")
Returns:
The number of CC requests for the monitor

Definition at line 4211 of file ccss.c.

References ao2_t_callback, ast_log_dynamic_level, count_monitors_cb_data::count, count_monitors_cb(), count_monitors_cb_data::device_name, and OBJ_NODATA.

Referenced by ast_queue_cc_frame().

04212 {
04213    struct count_monitors_cb_data data = {.device_name = name, .monitor_type = type,};
04214 
04215    ao2_t_callback(cc_core_instances, OBJ_NODATA, count_monitors_cb, &data, "Counting agents");
04216    ast_log_dynamic_level(cc_logger_level, "Counted %d monitors\n", data.count);
04217    return data.count;
04218 }

int ast_cc_monitor_failed ( int  core_id,
const char *const   monitor_name,
const char *const   debug,
  ... 
)

Indicate that a failure has occurred on a specific monitor.

Since:
1.8
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.

Parameters:
core_id The core ID for the CC transaction
monitor_name The name of the monitor on which the failure occurred
debug A debug message to print to the CC log
Returns:
void

Definition at line 3784 of file ccss.c.

References ast_calloc, ast_free, ast_strdup, ast_taskprocessor_push(), ast_vasprintf, cc_monitor_failed(), ast_cc_monitor_failure_data::core_id, ast_cc_monitor_failure_data::debug, and ast_cc_monitor_failure_data::device_name.

Referenced by ast_cc_available_timer_expire(), cc_handle_publish_error(), and handle_response_subscribe().

03785 {
03786    struct ast_cc_monitor_failure_data *failure_data;
03787    int res;
03788    va_list ap;
03789 
03790    if (!(failure_data = ast_calloc(1, sizeof(*failure_data)))) {
03791       return -1;
03792    }
03793 
03794    if (!(failure_data->device_name = ast_strdup(monitor_name))) {
03795       ast_free(failure_data);
03796       return -1;
03797    }
03798 
03799    va_start(ap, debug);
03800    if (ast_vasprintf(&failure_data->debug, debug, ap) == -1) {
03801       va_end(ap);
03802       ast_free((char *)failure_data->device_name);
03803       ast_free(failure_data);
03804       return -1;
03805    }
03806    va_end(ap);
03807 
03808    failure_data->core_id = core_id;
03809 
03810    res = ast_taskprocessor_push(cc_core_taskprocessor, cc_monitor_failed, failure_data);
03811    if (res) {
03812       ast_free((char *)failure_data->device_name);
03813       ast_free((char *)failure_data->debug);
03814       ast_free(failure_data);
03815    }
03816    return res;
03817 }

int ast_cc_monitor_party_b_free ( int  core_id  ) 

Alert a caller that though the callee has become free, the caller himself is not and may not call back.

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.

Parameters:
core_id The core ID of the CC transaction
Return values:
0 Successfully alerted the core that party B is free
-1 Could not alert the core that party B is free

Definition at line 3894 of file ccss.c.

References ast_taskprocessor_push(), cc_party_b_free(), cc_unref(), and find_cc_core_instance().

03895 {
03896    int res;
03897    struct cc_core_instance *core_instance = find_cc_core_instance(core_id);
03898 
03899    if (!core_instance) {
03900       return -1;
03901    }
03902 
03903    res = ast_taskprocessor_push(cc_core_taskprocessor, cc_party_b_free, core_instance);
03904    if (res) {
03905       cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed");
03906    }
03907    return res;
03908 }

int ast_cc_monitor_register ( const struct ast_cc_monitor_callbacks callbacks  ) 

Register a set of monitor callbacks with the core.

Since:
1.8
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.

Parameters:
callbacks The callbacks used by the monitor implementation
Return values:
0 Successfully registered
-1 Failure to register

Definition at line 997 of file ccss.c.

References ast_calloc, AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and cc_monitor_backend::callbacks.

Referenced by ast_cc_init(), and load_module().

00998 {
00999    struct cc_monitor_backend *backend = ast_calloc(1, sizeof(*backend));
01000 
01001    if (!backend) {
01002       return -1;
01003    }
01004 
01005    backend->callbacks = callbacks;
01006 
01007    AST_RWLIST_WRLOCK(&cc_monitor_backends);
01008    AST_RWLIST_INSERT_TAIL(&cc_monitor_backends, backend, next);
01009    AST_RWLIST_UNLOCK(&cc_monitor_backends);
01010    return 0;
01011 }

int ast_cc_monitor_request_acked ( int  core_id,
const char *const   debug,
  ... 
)

Indicate that an outbound entity has accepted our CC request.

Since:
1.8
When we receive confirmation that an outbound device has accepted the CC request we sent it, this function must be called.

Parameters:
core_id core_id of the CC transaction
debug optional string to print for debugging purposes
Return values:
0 Success
-1 Failure

Definition at line 3627 of file ccss.c.

References CC_ACTIVE, and cc_request_state_change().

Referenced by cc_generic_monitor_request_cc(), cc_stop_ringing(), and handle_cc_notify().

03628 {
03629    va_list ap;
03630    int res;
03631 
03632    va_start(ap, debug);
03633    res = cc_request_state_change(CC_ACTIVE, core_id, debug, ap);
03634    va_end(ap);
03635    return res;
03636 }

int ast_cc_monitor_status_request ( int  core_id  ) 

Request the status of a caller or callers.

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.

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.
Parameters:
core_id The core ID of the CC transaction
Return values:
0 Successfully requested status
-1 Failed to request status

Definition at line 3829 of file ccss.c.

References ast_taskprocessor_push(), cc_status_request(), cc_unref(), and find_cc_core_instance().

03830 {
03831    int res;
03832    struct cc_core_instance *core_instance = find_cc_core_instance(core_id);
03833 
03834    if (!core_instance) {
03835       return -1;
03836    }
03837 
03838    res = ast_taskprocessor_push(cc_core_taskprocessor, cc_status_request, core_instance);
03839    if (res) {
03840       cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed");
03841    }
03842    return res;
03843 }

int ast_cc_monitor_stop_ringing ( int  core_id  ) 

Alert a caller to stop ringing.

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.

Parameters:
core_id The core ID of the CC transaction
Return values:
0 Successfully requested for the phone to stop ringing
-1 Could not request for the phone to stop ringing

Definition at line 3866 of file ccss.c.

References ast_taskprocessor_push(), cc_stop_ringing(), cc_unref(), and find_cc_core_instance().

03867 {
03868    int res;
03869    struct cc_core_instance *core_instance = find_cc_core_instance(core_id);
03870 
03871    if (!core_instance) {
03872       return -1;
03873    }
03874 
03875    res = ast_taskprocessor_push(cc_core_taskprocessor, cc_stop_ringing, core_instance);
03876    if (res) {
03877       cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed");
03878    }
03879    return res;
03880 }

void ast_cc_monitor_unregister ( const struct ast_cc_monitor_callbacks callbacks  ) 

Unregister a set of monitor callbacks with the core.

Since:
1.8
If a module which makes use of a CC monitor is unloaded, then it may unregister its monitor callbacks with the core.

Parameters:
callbacks The callbacks used by the monitor implementation
Return values:
0 Successfully unregistered
-1 Failure to unregister

Definition at line 1030 of file ccss.c.

References ast_free, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, cc_monitor_backend::callbacks, and cc_monitor_backend::next.

Referenced by __unload_module(), and unload_module().

01031 {
01032    struct cc_monitor_backend *backend;
01033    AST_RWLIST_WRLOCK(&cc_monitor_backends);
01034    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&cc_monitor_backends, backend, next) {
01035       if (backend->callbacks == callbacks) {
01036          AST_RWLIST_REMOVE_CURRENT(next);
01037          ast_free(backend);
01038          break;
01039       }
01040    }
01041    AST_RWLIST_TRAVERSE_SAFE_END;
01042    AST_RWLIST_UNLOCK(&cc_monitor_backends);
01043 }

int ast_cc_offer ( struct ast_channel caller_chan  ) 

Offer CC to a caller.

Since:
1.8
This function is called from ast_hangup if the caller is eligible to be offered call completion service.

Parameters:
caller_chan The calling channel
Return values:
-1 Error
0 Success

Definition at line 3591 of file ccss.c.

References ast_channel_datastore_find(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, cc_offer(), dialed_cc_interfaces::core_id, cc_recall_ds_data::core_id, ast_datastore::data, and dialed_cc_interfaces::is_original_caller.

Referenced by ast_hangup().

03592 {
03593    int core_id;
03594    int res = -1;
03595    struct ast_datastore *datastore;
03596    struct dialed_cc_interfaces *cc_interfaces;
03597    char cc_is_offerable;
03598 
03599    ast_channel_lock(caller_chan);
03600    if (!(datastore = ast_channel_datastore_find(caller_chan, &dialed_cc_interfaces_info, NULL))) {
03601       ast_channel_unlock(caller_chan);
03602       return res;
03603    }
03604 
03605    cc_interfaces = datastore->data;
03606    cc_is_offerable = cc_interfaces->is_original_caller;
03607    core_id = cc_interfaces->core_id;
03608    ast_channel_unlock(caller_chan);
03609 
03610    if (cc_is_offerable) {
03611       res = cc_offer(core_id, "CC offered to caller %s", ast_channel_name(caller_chan));
03612    }
03613    return res;
03614 }

int ast_cc_request_is_within_limits ( void   ) 

Check if the incoming CC request is within the bounds set by the cc_max_requests configuration option.

Since:
1.8
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.

Return values:
0 Not within the limits. Fail.
non-zero Within the limits. Success.

Definition at line 2315 of file ccss.c.

Referenced by cc_caller_requested(), cc_interfaces_datastore_init(), and ccreq_exec().

02316 {
02317    return cc_request_count < global_cc_max_requests;
02318 }

int ast_cc_set_param ( struct ast_cc_config_params params,
const char *const   name,
const char *  value 
)

set a CCSS configuration parameter, given its name

Note:
Useful when parsing config files when used in conjunction with ast_ccss_is_cc_config_param.
Parameters:
params The parameter structure to set the value on
name The name of the cc parameter
value The value of the parameter
Return values:
0 Success
-1 Failure

Definition at line 790 of file ccss.c.

References ast_log(), ast_set_cc_agent_dialstring(), ast_set_cc_agent_policy(), ast_set_cc_callback_macro(), ast_set_cc_max_agents(), ast_set_cc_max_monitors(), ast_set_cc_monitor_policy(), ast_set_cc_offer_timer(), ast_set_cc_recall_timer(), ast_set_ccbs_available_timer(), ast_set_ccnr_available_timer(), LOG_WARNING, str_to_agent_policy(), and str_to_monitor_policy().

Referenced by acf_cc_write(), build_peer(), and process_dahdi().

00792 {
00793    unsigned int value_as_uint;
00794    if (!strcasecmp(name, "cc_agent_policy")) {
00795       return ast_set_cc_agent_policy(params, str_to_agent_policy(value));
00796    } else if (!strcasecmp(name, "cc_monitor_policy")) {
00797       return ast_set_cc_monitor_policy(params, str_to_monitor_policy(value));
00798    } else if (!strcasecmp(name, "cc_agent_dialstring")) {
00799       ast_set_cc_agent_dialstring(params, value);
00800    } else if (!strcasecmp(name, "cc_callback_macro")) {
00801       ast_set_cc_callback_macro(params, value);
00802       return 0;
00803    }
00804 
00805    if (!sscanf(value, "%30u", &value_as_uint) == 1) {
00806       return -1;
00807    }
00808 
00809    if (!strcasecmp(name, "cc_offer_timer")) {
00810       ast_set_cc_offer_timer(params, value_as_uint);
00811    } else if (!strcasecmp(name, "ccnr_available_timer")) {
00812       ast_set_ccnr_available_timer(params, value_as_uint);
00813    } else if (!strcasecmp(name, "ccbs_available_timer")) {
00814       ast_set_ccbs_available_timer(params, value_as_uint);
00815    } else if (!strcasecmp(name, "cc_max_agents")) {
00816       ast_set_cc_max_agents(params, value_as_uint);
00817    } else if (!strcasecmp(name, "cc_max_monitors")) {
00818       ast_set_cc_max_monitors(params, value_as_uint);
00819    } else if (!strcasecmp(name, "cc_recall_timer")) {
00820       ast_set_cc_recall_timer(params, value_as_uint);
00821    } else {
00822       ast_log(LOG_WARNING, "%s is not a valid CC parameter. Ignoring.\n", name);
00823       return -1;
00824    }
00825 
00826    return 0;
00827 }

const char* ast_get_cc_agent_dialstring ( struct ast_cc_config_params config  ) 

Get the cc_agent_dialstring.

Since:
1.8
Parameters:
config The configuration to retrieve the cc_agent_dialstring from
Returns:
The cc_agent_dialstring from this configuration

Definition at line 942 of file ccss.c.

References ast_cc_config_params::cc_agent_dialstring.

Referenced by ast_cc_get_param(), and generic_recall().

00943 {
00944    return config->cc_agent_dialstring;
00945 }

enum ast_cc_agent_policies ast_get_cc_agent_policy ( struct ast_cc_config_params config  ) 

Get the cc_agent_policy.

Since:
1.8
Parameters:
config The configuration to retrieve the policy from
Returns:
The current cc_agent_policy for this configuration

Definition at line 848 of file ccss.c.

References ast_cc_config_params::cc_agent_policy.

Referenced by ast_cc_call_init(), ast_cc_get_param(), build_peer(), cc_core_init_instance(), and find_agent_callbacks().

00849 {
00850    return config->cc_agent_policy;
00851 }

const char* ast_get_cc_callback_macro ( struct ast_cc_config_params config  ) 

Get the name of the callback_macro.

Since:
1.8
Parameters:
config The configuration to retrieve the callback_macro from
Returns:
The callback_macro name

Definition at line 976 of file ccss.c.

References ast_cc_config_params::cc_callback_macro.

Referenced by ast_cc_get_param(), and generic_recall().

00977 {
00978    return config->cc_callback_macro;
00979 }

unsigned int ast_get_cc_max_agents ( struct ast_cc_config_params config  ) 

Get the cc_max_agents.

Since:
1.8
Parameters:
config The configuration to retrieve the cc_max_agents from
Returns:
The cc_max_agents from this configuration

Definition at line 956 of file ccss.c.

References ast_cc_config_params::cc_max_agents.

Referenced by ast_cc_get_param(), and cc_core_init_instance().

00957 {
00958    return config->cc_max_agents;
00959 }

unsigned int ast_get_cc_max_monitors ( struct ast_cc_config_params config  ) 

Get the cc_max_monitors.

Since:
1.8
Parameters:
config The configuration to retrieve the cc_max_monitors from
Returns:
The cc_max_monitors from this configuration

Definition at line 966 of file ccss.c.

References ast_cc_config_params::cc_max_monitors.

Referenced by ast_cc_get_param(), and ast_queue_cc_frame().

00967 {
00968    return config->cc_max_monitors;
00969 }

enum ast_cc_monitor_policies ast_get_cc_monitor_policy ( struct ast_cc_config_params config  ) 

Get the cc_monitor_policy.

Since:
1.8
Parameters:
config The configuration to retrieve the cc_monitor_policy from
Returns:
The cc_monitor_policy retrieved from the configuration

Definition at line 865 of file ccss.c.

References ast_cc_config_params::cc_monitor_policy.

Referenced by analog_call(), ast_cc_call_failed(), ast_cc_get_param(), dahdi_cc_callback(), and sip_handle_cc().

00866 {
00867    return config->cc_monitor_policy;
00868 }

unsigned int ast_get_cc_offer_timer ( struct ast_cc_config_params config  ) 

Get the cc_offer_timer.

Since:
1.8
Parameters:
config The configuration to retrieve the cc_offer_timer from
Returns:
The cc_offer_timer from this configuration

Definition at line 882 of file ccss.c.

References ast_cc_config_params::cc_offer_timer.

Referenced by ast_cc_get_param(), cc_generic_agent_start_offer_timer(), and sip_cc_agent_start_offer_timer().

00883 {
00884    return config->cc_offer_timer;
00885 }

unsigned int ast_get_cc_recall_timer ( struct ast_cc_config_params config  ) 

Get the cc_recall_timer.

Since:
1.8
Parameters:
config The configuration to retrieve the cc_recall_timer from
Returns:
The cc_recall_timer from this configuration

Definition at line 912 of file ccss.c.

References ast_cc_config_params::cc_recall_timer.

Referenced by ast_cc_get_param(), and generic_recall().

00913 {
00914    return config->cc_recall_timer;
00915 }

unsigned int ast_get_ccbs_available_timer ( struct ast_cc_config_params config  ) 

Get the ccbs_available_timer.

Since:
1.8
Parameters:
config The configuration to retrieve the ccbs_available_timer from
Returns:
The ccbs_available_timer from this configuration

Definition at line 927 of file ccss.c.

References ast_cc_config_params::ccbs_available_timer.

Referenced by ast_cc_get_param(), cc_generic_monitor_request_cc(), and sip_cc_monitor_request_cc().

00928 {
00929    return config->ccbs_available_timer;
00930 }

unsigned int ast_get_ccnr_available_timer ( struct ast_cc_config_params config  ) 

Get the ccnr_available_timer.

Since:
1.8
Parameters:
config The configuration to retrieve the ccnr_available_timer from
Returns:
The ccnr_available_timer from this configuration

Definition at line 897 of file ccss.c.

References ast_cc_config_params::ccnr_available_timer.

Referenced by ast_cc_get_param(), cc_generic_monitor_request_cc(), and sip_cc_monitor_request_cc().

00898 {
00899    return config->ccnr_available_timer;
00900 }

void ast_handle_cc_control_frame ( struct ast_channel inbound,
struct ast_channel outbound,
void *  frame_data 
)

Properly react to a CC control frame.

Since:
1.8
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.

Parameters:
inbound The inbound channel
outbound The outbound channel (The one from which the CC frame was read)
frame_data The ast_frame's data.ptr field.
Return values:
void Unless we are ignoring CC for some reason, we will always call this function when we read an AST_CONTROL_CC frame from an outbound channel.
This function will call cc_device_monitor_init to create the new cc_monitor for the device from which we read the frame. In addition, the new device will be added to the monitor tree on the dialed_cc_interfaces datastore on the inbound channel.

If this is the first AST_CONTROL_CC frame that we have handled for this call, then we will also initialize the CC core for this call.

Definition at line 2144 of file ccss.c.

References ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, AST_CONTROL_CC, ast_indicate_data(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_log_dynamic_level, call_destructor_with_no_monitor(), cc_core_init_instance(), cc_device_monitor_init(), cc_extension_monitor_change_is_valid(), cc_ref(), cc_service_to_string(), cc_unref(), cc_core_instance::core_id, dialed_cc_interfaces::core_id, ast_datastore::data, ast_cc_interface::device_name, cc_control_payload::device_name, cc_control_payload::dialstring, ast_cc_monitor::dialstring, EVENT_FLAG_CC, find_cc_core_instance(), dialed_cc_interfaces::ignore, ast_cc_monitor::interface, dialed_cc_interfaces::interface_tree, dialed_cc_interfaces::is_original_caller, LOG_WARNING, manager_event, monitor, cc_control_payload::monitor_type, ast_cc_monitor::parent_id, cc_control_payload::private_data, and cc_control_payload::service.

Referenced by ast_cc_busy_interface(), ast_cc_call_failed(), and wait_for_answer().

02145 {
02146    char *device_name;
02147    char *dialstring;
02148    struct ast_cc_monitor *monitor;
02149    struct ast_datastore *cc_datastore;
02150    struct dialed_cc_interfaces *cc_interfaces;
02151    struct cc_control_payload *cc_data = frame_data;
02152    struct cc_core_instance *core_instance;
02153 
02154    device_name = cc_data->device_name;
02155    dialstring = cc_data->dialstring;
02156 
02157    ast_channel_lock(inbound);
02158    if (!(cc_datastore = ast_channel_datastore_find(inbound, &dialed_cc_interfaces_info, NULL))) {
02159       ast_log(LOG_WARNING, "Unable to retrieve CC datastore while processing CC frame from '%s'. CC services will be unavailable.\n", device_name);
02160       ast_channel_unlock(inbound);
02161       call_destructor_with_no_monitor(cc_data->monitor_type, cc_data->private_data);
02162       return;
02163    }
02164 
02165    cc_interfaces = cc_datastore->data;
02166 
02167    if (cc_interfaces->ignore) {
02168       ast_channel_unlock(inbound);
02169       call_destructor_with_no_monitor(cc_data->monitor_type, cc_data->private_data);
02170       return;
02171    }
02172 
02173    if (!cc_interfaces->is_original_caller) {
02174       /* If the is_original_caller is not set on the *inbound* channel, then
02175        * it must be a local channel. As such, we do not want to create a core instance
02176        * or an agent for the local channel. Instead, we want to pass this along to the
02177        * other side of the local channel so that the original caller can benefit.
02178        */
02179       ast_channel_unlock(inbound);
02180       ast_indicate_data(inbound, AST_CONTROL_CC, cc_data, sizeof(*cc_data));
02181       return;
02182    }
02183 
02184    core_instance = find_cc_core_instance(cc_interfaces->core_id);
02185    if (!core_instance) {
02186       core_instance = cc_core_init_instance(inbound, cc_interfaces->interface_tree,
02187          cc_interfaces->core_id, cc_data);
02188       if (!core_instance) {
02189          cc_interfaces->ignore = 1;
02190          ast_channel_unlock(inbound);
02191          call_destructor_with_no_monitor(cc_data->monitor_type, cc_data->private_data);
02192          return;
02193       }
02194    }
02195 
02196    ast_channel_unlock(inbound);
02197 
02198    /* Yeah this kind of sucks, but luckily most people
02199     * aren't dialing thousands of interfaces on every call
02200     *
02201     * This traversal helps us to not create duplicate monitors in
02202     * case a device queues multiple CC control frames.
02203     */
02204    AST_LIST_LOCK(cc_interfaces->interface_tree);
02205    AST_LIST_TRAVERSE(cc_interfaces->interface_tree, monitor, next) {
02206       if (!strcmp(monitor->interface->device_name, device_name)) {
02207          ast_log_dynamic_level(cc_logger_level, "Core %d: Device %s sent us multiple CC control frames. Ignoring those beyond the first.\n",
02208                core_instance->core_id, device_name);
02209          AST_LIST_UNLOCK(cc_interfaces->interface_tree);
02210          cc_unref(core_instance, "Returning early from ast_handle_cc_control_frame. Unref core_instance");
02211          call_destructor_with_no_monitor(cc_data->monitor_type, cc_data->private_data);
02212          return;
02213       }
02214    }
02215    AST_LIST_UNLOCK(cc_interfaces->interface_tree);
02216 
02217    if (!(monitor = cc_device_monitor_init(device_name, dialstring, cc_data, core_instance->core_id))) {
02218       ast_log(LOG_WARNING, "Unable to create CC device interface for '%s'. CC services will be unavailable on this interface.\n", device_name);
02219       cc_unref(core_instance, "Returning early from ast_handle_cc_control_frame. Unref core_instance");
02220       call_destructor_with_no_monitor(cc_data->monitor_type, cc_data->private_data);
02221       return;
02222    }
02223 
02224    AST_LIST_LOCK(cc_interfaces->interface_tree);
02225    cc_ref(monitor, "monitor tree's reference to the monitor");
02226    AST_LIST_INSERT_TAIL(cc_interfaces->interface_tree, monitor, next);
02227    AST_LIST_UNLOCK(cc_interfaces->interface_tree);
02228 
02229    cc_extension_monitor_change_is_valid(core_instance, monitor->parent_id, monitor->interface->device_name, 0);
02230 
02231    manager_event(EVENT_FLAG_CC, "CCAvailable",
02232       "CoreID: %d\r\n"
02233       "Callee: %s\r\n"
02234       "Service: %s\r\n",
02235       cc_interfaces->core_id, device_name, cc_service_to_string(cc_data->service)
02236    );
02237 
02238    cc_unref(core_instance, "Done with core_instance after handling CC control frame");
02239    cc_unref(monitor, "Unref reference from allocating monitor");
02240 }

void ast_ignore_cc ( struct ast_channel chan  ) 

Mark the channel to ignore further CC activity.

Since:
1.8
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.

Parameters:
chan The channel for which further CC processing should be ignored.
Return values:
void 

Definition at line 3560 of file ccss.c.

References ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_datastore::data, cc_recall_ds_data::ignore, and dialed_cc_interfaces::ignore.

Referenced by dial_exec_full(), and do_forward().

03561 {
03562    struct ast_datastore *cc_datastore;
03563    struct ast_datastore *cc_recall_datastore;
03564    struct dialed_cc_interfaces *cc_interfaces;
03565    struct cc_recall_ds_data *recall_cc_data;
03566 
03567    ast_channel_lock(chan);
03568    if ((cc_datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL))) {
03569       cc_interfaces = cc_datastore->data;
03570       cc_interfaces->ignore = 1;
03571    }
03572 
03573    if ((cc_recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
03574       recall_cc_data = cc_recall_datastore->data;
03575       recall_cc_data->ignore = 1;
03576    }
03577    ast_channel_unlock(chan);
03578 }

int ast_queue_cc_frame ( struct ast_channel chan,
const char *const   monitor_type,
const char *const   dialstring,
enum ast_cc_service_type  service,
void *  private_data 
)

Queue an AST_CONTROL_CC frame.

Since:
1.8
Note:
Since this function calls ast_queue_frame, the channel will be locked during the course of this function.
Parameters:
chan The channel onto which to queue the frame
monitor_type The type of monitor to use when CC is requested
dialstring The dial string used to call the device
service The type of CC service the device is willing to offer
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.
Return values:
0 Success
-1 Error

Definition at line 3992 of file ccss.c.

References ast_cc_build_frame(), ast_cc_monitor_count(), ast_channel_get_cc_config_params(), ast_channel_get_device_name(), AST_CHANNEL_NAME, ast_frfree, ast_get_cc_max_monitors(), ast_log(), ast_queue_frame(), and LOG_NOTICE.

Referenced by analog_call(), and sip_handle_cc().

03994 {
03995    struct ast_frame frame = {0,};
03996    char device_name[AST_CHANNEL_NAME];
03997    int retval;
03998    struct ast_cc_config_params *cc_params;
03999 
04000    cc_params = ast_channel_get_cc_config_params(chan);
04001    if (!cc_params) {
04002       return -1;
04003    }
04004    ast_channel_get_device_name(chan, device_name, sizeof(device_name));
04005    if (ast_cc_monitor_count(device_name, monitor_type) >= ast_get_cc_max_monitors(cc_params)) {
04006       ast_log(LOG_NOTICE, "Not queuing a CC frame for device %s since it already has its maximum monitors allocated\n", device_name);
04007       return -1;
04008    }
04009 
04010    if (ast_cc_build_frame(chan, cc_params, monitor_type, device_name, dialstring, service, private_data, &frame)) {
04011       /* Frame building failed. We can't use this. */
04012       return -1;
04013    }
04014    retval = ast_queue_frame(chan, &frame);
04015    ast_frfree(&frame);
04016    return retval;
04017 }

void ast_set_cc_agent_dialstring ( struct ast_cc_config_params config,
const char *const   value 
)

Set the cc_agent_dialstring.

Since:
1.8
Parameters:
config The configuration to set the cc_agent_dialstring on
value The new cc_agent_dialstring we want to change to
Return values:
void 

Definition at line 947 of file ccss.c.

References ast_copy_string(), ast_strlen_zero(), and ast_cc_config_params::cc_agent_dialstring.

Referenced by ast_cc_set_param().

00948 {
00949    if (ast_strlen_zero(value)) {
00950       config->cc_agent_dialstring[0] = '\0';
00951    } else {
00952       ast_copy_string(config->cc_agent_dialstring, value, sizeof(config->cc_agent_dialstring));
00953    }
00954 }

int ast_set_cc_agent_policy ( struct ast_cc_config_params config,
enum ast_cc_agent_policies  value 
)

Set the cc_agent_policy.

Since:
1.8
Parameters:
config The configuration to set the cc_agent_policy on
value The new cc_agent_policy we want to change to
Return values:
0 Success
-1 Failure (likely due to bad input)

Definition at line 853 of file ccss.c.

References AST_CC_AGENT_GENERIC, and ast_cc_config_params::cc_agent_policy.

Referenced by ast_cc_set_param(), and build_peer().

00854 {
00855    /* Screw C and its weak type checking for making me have to do this
00856     * validation at runtime.
00857     */
00858    if (value < AST_CC_AGENT_NEVER || value > AST_CC_AGENT_GENERIC) {
00859       return -1;
00860    }
00861    config->cc_agent_policy = value;
00862    return 0;
00863 }

void ast_set_cc_callback_macro ( struct ast_cc_config_params config,
const char *const   value 
)

Set the callback_macro name.

Since:
1.8
Parameters:
config The configuration to set the callback_macro on
value The new callback macro we want to change to
Return values:
void 

Definition at line 981 of file ccss.c.

References ast_copy_string(), ast_strlen_zero(), and ast_cc_config_params::cc_callback_macro.

Referenced by ast_cc_set_param().

00982 {
00983    if (ast_strlen_zero(value)) {
00984       config->cc_callback_macro[0] = '\0';
00985    } else {
00986       ast_copy_string(config->cc_callback_macro, value, sizeof(config->cc_callback_macro));
00987    }
00988 }

int ast_set_cc_interfaces_chanvar ( struct ast_channel chan,
const char *const   extension 
)

Set the CC_INTERFACES channel variable for a channel using an extension as a starting point.

Since:
1.8
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 chan_local, 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.
Parameters:
chan The channel to set the CC_INTERFACES variable on
extension The name of the extension for which we're setting the variable. This should be in the form of "exten@context"

Definition at line 3508 of file ccss.c.

References ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_free, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log_dynamic_level, ast_str_buffer(), ast_str_create(), build_cc_interfaces_chanvar(), cc_recall_ds_data::core_id, ast_datastore::data, ast_cc_interface::device_name, ast_cc_monitor::interface, cc_recall_ds_data::interface_tree, pbx_builtin_setvar_helper(), and str.

Referenced by local_call().

03509 {
03510    struct ast_datastore *recall_datastore;
03511    struct cc_monitor_tree *interface_tree;
03512    struct ast_cc_monitor *monitor_iter;
03513    struct cc_recall_ds_data *recall_data;
03514    struct ast_str *str = ast_str_create(64);
03515    int core_id;
03516 
03517    if (!str) {
03518       return -1;
03519    }
03520 
03521    ast_channel_lock(chan);
03522    if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
03523       ast_channel_unlock(chan);
03524       ast_free(str);
03525       return -1;
03526    }
03527    recall_data = recall_datastore->data;
03528    interface_tree = recall_data->interface_tree;
03529    core_id = recall_data->core_id;
03530    ast_channel_unlock(chan);
03531 
03532    AST_LIST_LOCK(interface_tree);
03533    AST_LIST_TRAVERSE(interface_tree, monitor_iter, next) {
03534       if (!strcmp(monitor_iter->interface->device_name, extension)) {
03535          break;
03536       }
03537    }
03538 
03539    if (!monitor_iter) {
03540       /* We couldn't find this extension. This may be because
03541        * we have been directed into an unexpected extension because
03542        * the admin has changed a CC_INTERFACES variable at some point.
03543        */
03544       AST_LIST_UNLOCK(interface_tree);
03545       ast_free(str);
03546       return -1;
03547    }
03548 
03549    build_cc_interfaces_chanvar(monitor_iter, str);
03550    AST_LIST_UNLOCK(interface_tree);
03551 
03552    pbx_builtin_setvar_helper(chan, "CC_INTERFACES", ast_str_buffer(str));
03553    ast_log_dynamic_level(cc_logger_level, "Core %d: CC_INTERFACES set to %s\n",
03554          core_id, ast_str_buffer(str));
03555 
03556    ast_free(str);
03557    return 0;
03558 }

void ast_set_cc_max_agents ( struct ast_cc_config_params config,
unsigned int  value 
)

Set the cc_max_agents.

Since:
1.8
Parameters:
config The configuration to set the cc_max_agents on
value The new cc_max_agents we want to change to
Return values:
void 

Definition at line 961 of file ccss.c.

References ast_cc_config_params::cc_max_agents.

Referenced by ast_cc_set_param().

00962 {
00963    config->cc_max_agents = value;
00964 }

void ast_set_cc_max_monitors ( struct ast_cc_config_params config,
unsigned int  value 
)

Set the cc_max_monitors.

Since:
1.8
Parameters:
config The configuration to set the cc_max_monitors on
value The new cc_max_monitors we want to change to
Return values:
void 

Definition at line 971 of file ccss.c.

References ast_cc_config_params::cc_max_monitors.

Referenced by ast_cc_set_param().

00972 {
00973    config->cc_max_monitors = value;
00974 }

int ast_set_cc_monitor_policy ( struct ast_cc_config_params config,
enum ast_cc_monitor_policies  value 
)

Set the cc_monitor_policy.

Since:
1.8
Parameters:
config The configuration to set the cc_monitor_policy on
value The new cc_monitor_policy we want to change to
Return values:
0 Success
-1 Failure (likely due to bad input)

Definition at line 870 of file ccss.c.

References AST_CC_MONITOR_ALWAYS, and ast_cc_config_params::cc_monitor_policy.

Referenced by ast_cc_set_param().

00871 {
00872    /* Screw C and its weak type checking for making me have to do this
00873     * validation at runtime.
00874     */
00875    if (value < AST_CC_MONITOR_NEVER || value > AST_CC_MONITOR_ALWAYS) {
00876       return -1;
00877    }
00878    config->cc_monitor_policy = value;
00879    return 0;
00880 }

void ast_set_cc_offer_timer ( struct ast_cc_config_params config,
unsigned int  value 
)

Set the cc_offer_timer.

Since:
1.8
Parameters:
config The configuration to set the cc_offer_timer on
value The new cc_offer_timer we want to change to
Return values:
void 

Definition at line 887 of file ccss.c.

References ast_log(), ast_cc_config_params::cc_offer_timer, and LOG_WARNING.

Referenced by ast_cc_set_param().

00888 {
00889    /* 0 is an unreasonable value for any timer. Stick with the default */
00890    if (value == 0) {
00891       ast_log(LOG_WARNING, "0 is an invalid value for cc_offer_timer. Retaining value as %u\n", config->cc_offer_timer);
00892       return;
00893    }
00894    config->cc_offer_timer = value;
00895 }

void ast_set_cc_recall_timer ( struct ast_cc_config_params config,
unsigned int  value 
)

Set the cc_recall_timer.

Since:
1.8
Parameters:
config The configuration to set the cc_recall_timer on
value The new cc_recall_timer we want to change to
Return values:
void 

Definition at line 917 of file ccss.c.

References ast_log(), ast_cc_config_params::cc_recall_timer, and LOG_WARNING.

Referenced by ast_cc_set_param().

00918 {
00919    /* 0 is an unreasonable value for any timer. Stick with the default */
00920    if (value == 0) {
00921       ast_log(LOG_WARNING, "0 is an invalid value for ccnr_available_timer. Retaining value as %u\n", config->cc_recall_timer);
00922       return;
00923    }
00924    config->cc_recall_timer = value;
00925 }

void ast_set_ccbs_available_timer ( struct ast_cc_config_params config,
unsigned int  value 
)

Set the ccbs_available_timer.

Since:
1.8
Parameters:
config The configuration to set the ccbs_available_timer on
value The new ccbs_available_timer we want to change to
Return values:
void 

Definition at line 932 of file ccss.c.

References ast_log(), ast_cc_config_params::ccbs_available_timer, and LOG_WARNING.

Referenced by ast_cc_set_param().

00933 {
00934    /* 0 is an unreasonable value for any timer. Stick with the default */
00935    if (value == 0) {
00936       ast_log(LOG_WARNING, "0 is an invalid value for ccbs_available_timer. Retaining value as %u\n", config->ccbs_available_timer);
00937       return;
00938    }
00939    config->ccbs_available_timer = value;
00940 }

void ast_set_ccnr_available_timer ( struct ast_cc_config_params config,
unsigned int  value 
)

Set the ccnr_available_timer.

Since:
1.8
Parameters:
config The configuration to set the ccnr_available_timer on
value The new ccnr_available_timer we want to change to
Return values:
void 

Definition at line 902 of file ccss.c.

References ast_log(), ast_cc_config_params::ccnr_available_timer, and LOG_WARNING.

Referenced by ast_cc_set_param().

00903 {
00904    /* 0 is an unreasonable value for any timer. Stick with the default */
00905    if (value == 0) {
00906       ast_log(LOG_WARNING, "0 is an invalid value for ccnr_available_timer. Retaining value as %u\n", config->ccnr_available_timer);
00907       return;
00908    }
00909    config->ccnr_available_timer = value;
00910 }

int ast_setup_cc_recall_datastore ( struct ast_channel chan,
const int  core_id 
)

Set up a CC recall datastore on a channel.

Since:
1.8
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.

Definition at line 3245 of file ccss.c.

References ast_calloc, ast_channel_datastore_add(), ast_channel_lock, ast_channel_unlock, ast_datastore_alloc, ast_datastore_free(), ast_free, cc_ref(), cc_unref(), cc_recall_ds_data::core_id, ast_datastore::data, DATASTORE_INHERIT_FOREVER, find_cc_core_instance(), ast_datastore::inheritance, cc_recall_ds_data::interface_tree, and cc_core_instance::monitors.

Referenced by generic_recall(), and handle_request_invite().

03246 {
03247    struct ast_datastore *recall_datastore = ast_datastore_alloc(&recall_ds_info, NULL);
03248    struct cc_recall_ds_data *recall_data;
03249    struct cc_core_instance *core_instance;
03250 
03251    if (!recall_datastore) {
03252       return -1;
03253    }
03254 
03255    if (!(recall_data = ast_calloc(1, sizeof(*recall_data)))) {
03256       ast_datastore_free(recall_datastore);
03257       return -1;
03258    }
03259 
03260    if (!(core_instance = find_cc_core_instance(core_id))) {
03261       ast_free(recall_data);
03262       ast_datastore_free(recall_datastore);
03263       return -1;
03264    }
03265 
03266    recall_data->interface_tree = cc_ref(core_instance->monitors,
03267          "Bump refcount for monitor tree for recall datastore");
03268    recall_data->core_id = core_id;
03269    recall_datastore->data = recall_data;
03270    recall_datastore->inheritance = DATASTORE_INHERIT_FOREVER;
03271    ast_channel_lock(chan);
03272    ast_channel_datastore_add(chan, recall_datastore);
03273    ast_channel_unlock(chan);
03274    cc_unref(core_instance, "Recall datastore set up. No need for core_instance ref");
03275    return 0;
03276 }


Generated on Fri Feb 10 06:35:05 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6