#include "asterisk.h"
#include "asterisk/linkedlists.h"
#include "asterisk/devicestate.h"
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 | |
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. | |
ast_cc_agent * | ast_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. | |
ast_cc_monitor * | ast_cc_get_monitor_by_recall_core_id (const int core_id, const char *const device_name) |
Get the associated monitor given the device name and core_id. | |
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. |
Definition in file ccss.h.
#define ast_cc_config_params_init | ( | ) | __ast_cc_config_params_init(__FILE__, __LINE__, __PRETTY_FUNCTION__) |
Allocate and initialize an ast_cc_config_params structure.
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(), 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(), sig_pri_cc_available(), sig_pri_cc_generic_check(), and sip_handle_cc().
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.
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. |
enum ast_cc_agent_flags |
agent flags that can alter core behavior
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.
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 };
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 };
enum ast_cc_monitor_class |
Used to determine which type of monitor an ast_cc_device_monitor is.
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.
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 };
enum ast_cc_service_type |
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 };
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.
NULL | Unable to allocate the structure | |
non-NULL | A pointer to the newly allocated and initialized structure |
Definition at line 563 of file ccss.c.
References __ast_malloc(), ast_cc_default_config_params(), and ast_malloc.
00564 { 00565 #if defined(__AST_DEBUG_MALLOC) 00566 struct ast_cc_config_params *params = __ast_malloc(sizeof(*params), file, line, function); 00567 #else 00568 struct ast_cc_config_params *params = ast_malloc(sizeof(*params)); 00569 #endif 00570 00571 if (!params) { 00572 return NULL; 00573 } 00574 00575 ast_cc_default_config_params(params); 00576 return params; 00577 }
int ast_cc_agent_accept_request | ( | int | core_id, | |
const char *const | debug, | |||
... | ||||
) |
Accept inbound CC request.
core_id | core_id of the CC transaction | |
debug | optional string to print for debugging purposes |
0 | Success | |
-1 | Failure |
Definition at line 3510 of file ccss.c.
References CC_CALLER_REQUESTED, and cc_request_state_change().
Referenced by ccreq_exec(), handle_cc_subscribe(), and sig_pri_handle_cis_subcmds().
03511 { 03512 va_list ap; 03513 int res; 03514 03515 va_start(ap, debug); 03516 res = cc_request_state_change(CC_CALLER_REQUESTED, core_id, debug, ap); 03517 va_end(ap); 03518 return res; 03519 }
struct ast_cc_agent* ast_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.
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.
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 446 of file ccss.c.
References cc_core_instance::agent, ao2_t_callback, cc_agent_callback_helper(), cc_core_instances, 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(), find_sip_cc_agent_by_subscribe_uri(), and sig_pri_find_cc_agent_by_cc_id().
00447 { 00448 struct cc_callback_helper helper = {.function = function, .args = args, .type = type}; 00449 struct cc_core_instance *core_instance; 00450 if ((core_instance = ao2_t_callback(cc_core_instances, flags, cc_agent_callback_helper, &helper, 00451 "Calling provided agent callback function"))) { 00452 struct ast_cc_agent *agent = cc_ref(core_instance->agent, "An outside entity needs the agent"); 00453 cc_unref(core_instance, "agent callback done with the core_instance"); 00454 return agent; 00455 } 00456 return NULL; 00457 }
int ast_cc_agent_caller_available | ( | int | core_id, | |
const char *const | debug, | |||
... | ||||
) |
Indicate that a previously unavailable caller has become available.
core_id | core_id of the CC transaction | |
debug | optional string to print for debugging purposes |
0 | Success | |
-1 | Failure |
Definition at line 3554 of file ccss.c.
References CC_ACTIVE, and cc_request_state_change().
Referenced by cc_esc_publish_handler(), generic_agent_devstate_cb(), and sig_pri_handle_cis_subcmds().
03555 { 03556 va_list ap; 03557 int res; 03558 03559 va_start(ap, debug); 03560 res = cc_request_state_change(CC_ACTIVE, core_id, debug, ap); 03561 va_end(ap); 03562 return res; 03563 }
int ast_cc_agent_caller_busy | ( | int | core_id, | |
const char *const | debug, | |||
... | ||||
) |
Indicate that the caller is busy.
core_id | core_id of the CC transaction | |
debug | optional string to print for debugging purposes |
0 | Success | |
-1 | Failure |
Definition at line 3543 of file ccss.c.
References CC_CALLER_BUSY, and cc_request_state_change().
Referenced by cc_esc_publish_handler(), cc_generic_agent_recall(), sig_pri_handle_cis_subcmds(), and sip_cc_agent_recall().
03544 { 03545 va_list ap; 03546 int res; 03547 03548 va_start(ap, debug); 03549 res = cc_request_state_change(CC_CALLER_BUSY, core_id, debug, ap); 03550 va_end(ap); 03551 return res; 03552 }
int ast_cc_agent_recalling | ( | int | core_id, | |
const char *const | debug, | |||
... | ||||
) |
Tell the CC core that a caller is currently recalling.
core_id | core_id of the CC transaction | |
debug | optional string to print for debugging purposes |
0 | Success | |
-1 | Failure |
Definition at line 3565 of file ccss.c.
References CC_RECALLING, and cc_request_state_change().
Referenced by generic_recall(), get_destination(), and sig_pri_handle_subcmds().
03566 { 03567 va_list ap; 03568 int res; 03569 03570 va_start(ap, debug); 03571 res = cc_request_state_change(CC_RECALLING, core_id, debug, ap); 03572 va_end(ap); 03573 return res; 03574 }
int ast_cc_agent_register | ( | const struct ast_cc_agent_callbacks * | callbacks | ) |
Register a set of agent callbacks with the core.
callbacks | The callbacks used by the agent implementation |
0 | Successfully registered | |
-1 | Failure to register |
Definition at line 950 of file ccss.c.
References ast_calloc, AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and cc_monitor_backend::next.
Referenced by ast_cc_init(), and load_module().
00951 { 00952 struct cc_agent_backend *backend = ast_calloc(1, sizeof(*backend)); 00953 00954 if (!backend) { 00955 return -1; 00956 } 00957 00958 backend->callbacks = callbacks; 00959 AST_RWLIST_WRLOCK(&cc_agent_backends); 00960 AST_RWLIST_INSERT_TAIL(&cc_agent_backends, backend, next); 00961 AST_RWLIST_UNLOCK(&cc_agent_backends); 00962 return 0; 00963 }
int ast_cc_agent_set_interfaces_chanvar | ( | struct ast_channel * | chan | ) |
Set the first level CC_INTERFACES channel variable for a channel.
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.
chan | The channel to set the CC_INTERFACES variable on |
Definition at line 3365 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(), recall_ds_info, and str.
Referenced by generic_recall(), handle_request_invite(), and sig_pri_handle_subcmds().
03366 { 03367 struct ast_datastore *recall_datastore; 03368 struct cc_monitor_tree *interface_tree; 03369 struct ast_cc_monitor *monitor; 03370 struct cc_recall_ds_data *recall_data; 03371 struct ast_str *str = ast_str_create(64); 03372 int core_id; 03373 03374 if (!str) { 03375 return -1; 03376 } 03377 03378 ast_channel_lock(chan); 03379 if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) { 03380 ast_channel_unlock(chan); 03381 ast_free(str); 03382 return -1; 03383 } 03384 recall_data = recall_datastore->data; 03385 interface_tree = recall_data->interface_tree; 03386 core_id = recall_data->core_id; 03387 ast_channel_unlock(chan); 03388 03389 AST_LIST_LOCK(interface_tree); 03390 monitor = AST_LIST_FIRST(interface_tree); 03391 build_cc_interfaces_chanvar(monitor, str); 03392 AST_LIST_UNLOCK(interface_tree); 03393 03394 pbx_builtin_setvar_helper(chan, "CC_INTERFACES", ast_str_buffer(str)); 03395 ast_log_dynamic_level(cc_logger_level, "Core %d: CC_INTERFACES set to %s\n", 03396 core_id, ast_str_buffer(str)); 03397 03398 ast_free(str); 03399 return 0; 03400 }
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.
core_id | The core ID of the CC transaction | |
devstate | The current state of the caller to which the agent pertains |
0 | Successfully responded with our status | |
-1 | Failed to respond with our status |
Definition at line 3830 of file ccss.c.
References args, ast_calloc, ast_free, ast_taskprocessor_push(), cc_core_taskprocessor, cc_status_response(), cc_unref(), and find_cc_core_instance().
Referenced by cc_generic_agent_status_request(), sig_pri_handle_cis_subcmds(), and sip_cc_agent_status_request().
03831 { 03832 struct cc_status_response_args *args; 03833 struct cc_core_instance *core_instance; 03834 int res; 03835 03836 args = ast_calloc(1, sizeof(*args)); 03837 if (!args) { 03838 return -1; 03839 } 03840 03841 core_instance = find_cc_core_instance(core_id); 03842 if (!core_instance) { 03843 ast_free(args); 03844 return -1; 03845 } 03846 03847 args->core_instance = core_instance; 03848 args->devstate = devstate; 03849 03850 res = ast_taskprocessor_push(cc_core_taskprocessor, cc_status_response, args); 03851 if (res) { 03852 cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed"); 03853 ast_free(args); 03854 } 03855 return res; 03856 }
void ast_cc_agent_unregister | ( | const struct ast_cc_agent_callbacks * | callbacks | ) |
Unregister a set of agent callbacks with the core.
callbacks | The callbacks used by the agent implementation |
0 | Successfully unregistered | |
-1 | Failure to unregister |
Definition at line 965 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, cc_monitor_backend::callbacks, and cc_monitor_backend::next.
Referenced by __unload_module().
00966 { 00967 struct cc_agent_backend *backend; 00968 AST_RWLIST_WRLOCK(&cc_agent_backends); 00969 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&cc_agent_backends, backend, next) { 00970 if (backend->callbacks == callbacks) { 00971 AST_RWLIST_REMOVE_CURRENT(next); 00972 ast_free(backend); 00973 break; 00974 } 00975 } 00976 AST_RWLIST_TRAVERSE_SAFE_END; 00977 AST_RWLIST_UNLOCK(&cc_agent_backends); 00978 }
int ast_cc_available_timer_expire | ( | const void * | data | ) |
Scheduler callback for available timer expiration.
data | A reference to the CC monitor on which the timer was running. |
Definition at line 1239 of file ccss.c.
References ast_cc_monitor_failed(), cc_unref(), and monitor.
Referenced by cc_generic_monitor_request_cc(), and sip_cc_monitor_request_cc().
01240 { 01241 struct ast_cc_monitor *monitor = (struct ast_cc_monitor *) data; 01242 int res; 01243 monitor->available_timer_id = -1; 01244 res = ast_cc_monitor_failed(monitor->core_id, monitor->interface->device_name, "Available timer expired for monitor"); 01245 cc_unref(monitor, "Unref reference from scheduler\n"); 01246 return res; 01247 }
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.
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. |
-1 | Failure. At some point there was a failure. Do not attempt to use the frame in this case. | |
0 | Success |
Definition at line 3913 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().
03917 { 03918 struct cc_control_payload *payload = ast_calloc(1, sizeof(*payload)); 03919 03920 if (!payload) { 03921 return -1; 03922 } 03923 if (cc_build_payload(chan, cc_params, monitor_type, device_name, dialstring, service, private_data, payload)) { 03924 /* Something screwed up, we can't make a frame with this */ 03925 ast_free(payload); 03926 return -1; 03927 } 03928 frame->frametype = AST_FRAME_CONTROL; 03929 frame->subclass.integer = AST_CONTROL_CC; 03930 frame->data.ptr = payload; 03931 frame->datalen = sizeof(*payload); 03932 frame->mallocd = AST_MALLOCD_DATA; 03933 return 0; 03934 }
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.
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. |
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 3969 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().
03971 { 03972 struct cc_control_payload payload; 03973 if (cc_build_payload(inbound, cc_params, monitor_type, device_name, dialstring, AST_CC_CCBS, private_data, &payload)) { 03974 /* Something screwed up. Don't try to handle this payload */ 03975 call_destructor_with_no_monitor(monitor_type, private_data); 03976 return; 03977 } 03978 ast_handle_cc_control_frame(inbound, NULL, &payload); 03979 }
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.
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 3936 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().
03937 { 03938 char device_name[AST_CHANNEL_NAME]; 03939 struct cc_control_payload payload; 03940 struct ast_cc_config_params *cc_params; 03941 03942 if (outgoing->hangupcause != AST_CAUSE_BUSY && outgoing->hangupcause != AST_CAUSE_CONGESTION) { 03943 /* It doesn't make sense to try to offer CCBS to the caller if the reason for ast_call 03944 * failing is something other than busy or congestion 03945 */ 03946 return; 03947 } 03948 03949 cc_params = ast_channel_get_cc_config_params(outgoing); 03950 if (!cc_params) { 03951 return; 03952 } 03953 if (ast_get_cc_monitor_policy(cc_params) != AST_CC_MONITOR_GENERIC) { 03954 /* This sort of CCBS only works if using generic CC. For native, we would end up sending 03955 * a CC request for a non-existent call. The far end will reject this every time 03956 */ 03957 return; 03958 } 03959 03960 ast_channel_get_device_name(outgoing, device_name, sizeof(device_name)); 03961 if (cc_build_payload(outgoing, cc_params, AST_CC_GENERIC_MONITOR_TYPE, device_name, 03962 dialstring, AST_CC_CCBS, NULL, &payload)) { 03963 /* Something screwed up, we can't make a frame with this */ 03964 return; 03965 } 03966 ast_handle_cc_control_frame(incoming, outgoing, &payload); 03967 }
int ast_cc_call_init | ( | struct ast_channel * | chan, | |
int * | ignore_cc | |||
) |
Start the CC process on a call.
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.
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 |
0 | Success | |
-1 | Failure |
Definition at line 2146 of file ccss.c.
References AST_CC_AGENT_NEVER, ast_channel_datastore_find(), ast_channel_get_cc_config_params(), ast_channel_lock, 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_datastore::data, dialed_cc_interfaces::dial_parent_id, dialed_cc_interfaces_info, ast_channel::exten, dialed_cc_interfaces::ignore, dialed_cc_interfaces::interface_tree, ast_channel::macrocontext, ast_channel::macroexten, monitor, ast_channel::name, cc_monitor_backend::next, and S_OR.
Referenced by dial_exec_full().
02147 { 02148 /* There are three situations to deal with here: 02149 * 02150 * 1. The channel does not have a dialed_cc_interfaces datastore on 02151 * it. This means that this is the first time that Dial has 02152 * been called. We need to create/initialize the datastore. 02153 * 02154 * 2. The channel does have a cc_interface datastore on it and 02155 * the "ignore" indicator is 0. This means that a Local channel 02156 * was called by a "parent" dial. We can check the datastore's 02157 * parent field to see who the root of this particular dial tree 02158 * is. 02159 * 02160 * 3. The channel does have a cc_interface datastore on it and 02161 * the "ignore" indicator is 1. This means that a second Dial call 02162 * is being made from an extension. In this case, we do not 02163 * want to make any additions/modifications to the datastore. We 02164 * will instead set a flag to indicate that CCSS is completely 02165 * disabled for this Dial attempt. 02166 */ 02167 02168 struct ast_datastore *cc_interfaces_datastore; 02169 struct dialed_cc_interfaces *interfaces; 02170 struct ast_cc_monitor *monitor; 02171 struct ast_cc_config_params *cc_params; 02172 02173 ast_channel_lock(chan); 02174 02175 cc_params = ast_channel_get_cc_config_params(chan); 02176 if (!cc_params) { 02177 ast_channel_unlock(chan); 02178 return -1; 02179 } 02180 if (ast_get_cc_agent_policy(cc_params) == AST_CC_AGENT_NEVER) { 02181 /* We can't offer CC to this caller anyway, so don't bother with CC on this call 02182 */ 02183 *ignore_cc = 1; 02184 ast_channel_unlock(chan); 02185 ast_log_dynamic_level(cc_logger_level, "Agent policy for %s is 'never'. CC not possible\n", chan->name); 02186 return 0; 02187 } 02188 02189 if (!(cc_interfaces_datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL))) { 02190 /* Situation 1 has occurred */ 02191 ast_channel_unlock(chan); 02192 return cc_interfaces_datastore_init(chan); 02193 } 02194 interfaces = cc_interfaces_datastore->data; 02195 ast_channel_unlock(chan); 02196 02197 if (interfaces->ignore) { 02198 /* Situation 3 has occurred */ 02199 *ignore_cc = 1; 02200 ast_log_dynamic_level(cc_logger_level, "Datastore is present with ignore flag set. Ignoring CC offers on this call\n"); 02201 return 0; 02202 } 02203 02204 /* Situation 2 has occurred */ 02205 if (!(monitor = cc_extension_monitor_init(S_OR(chan->macroexten, chan->exten), 02206 S_OR(chan->macrocontext, chan->context), interfaces->dial_parent_id))) { 02207 return -1; 02208 } 02209 monitor->core_id = interfaces->core_id; 02210 AST_LIST_LOCK(interfaces->interface_tree); 02211 cc_ref(monitor, "monitor tree's reference to the monitor"); 02212 AST_LIST_INSERT_TAIL(interfaces->interface_tree, monitor, next); 02213 AST_LIST_UNLOCK(interfaces->interface_tree); 02214 interfaces->dial_parent_id = monitor->id; 02215 cc_unref(monitor, "Unref monitor's allocation reference"); 02216 return 0; 02217 }
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.
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 |
Always | 0, I guess. |
Definition at line 3981 of file ccss.c.
References ast_get_channel_tech(), and ast_channel_tech::cc_callback.
Referenced by dial_exec_full().
03982 { 03983 const struct ast_channel_tech *chantech = ast_get_channel_tech(tech); 03984 03985 if (chantech && chantech->cc_callback) { 03986 chantech->cc_callback(inbound, dest, callback); 03987 } 03988 03989 return 0; 03990 }
int ast_cc_completed | ( | struct ast_channel * | chan, | |
const char *const | debug, | |||
... | ||||
) |
Indicate recall has been acknowledged.
chan | The inbound channel making the CC recall | |
debug | optional string to print for debugging purposes |
0 | Success | |
-1 | Failure |
Definition at line 3576 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, cc_recall_ds_data::nested, and recall_ds_info.
03577 { 03578 struct ast_datastore *recall_datastore; 03579 struct cc_recall_ds_data *recall_data; 03580 int core_id; 03581 va_list ap; 03582 int res; 03583 03584 ast_channel_lock(chan); 03585 if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) { 03586 /* Silly! Why did you call this function if there's no recall DS? */ 03587 ast_channel_unlock(chan); 03588 return -1; 03589 } 03590 recall_data = recall_datastore->data; 03591 if (recall_data->nested || recall_data->ignore) { 03592 /* If this is being called from a nested Dial, it is too 03593 * early to determine if the recall has actually completed. 03594 * The outermost dial is the only one with the authority to 03595 * declare the recall to be complete. 03596 * 03597 * Similarly, if this function has been called when the 03598 * recall has progressed beyond the first dial, this is not 03599 * a legitimate time to declare the recall to be done. In fact, 03600 * that should have been done already. 03601 */ 03602 ast_channel_unlock(chan); 03603 return -1; 03604 } 03605 core_id = recall_data->core_id; 03606 ast_channel_unlock(chan); 03607 va_start(ap, debug); 03608 res = cc_request_state_change(CC_COMPLETE, core_id, debug, ap); 03609 va_end(ap); 03610 return res; 03611 }
void ast_cc_config_params_destroy | ( | struct ast_cc_config_params * | params | ) |
Free memory from CCSS configuration params.
params | Pointer to structure whose memory we need to free |
void |
Definition at line 579 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(), setup_dahdi(), and sip_destroy_peer().
00580 { 00581 ast_free(params); 00582 }
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
src | The structure from which data is copied | |
dest | The structure to which data is copied |
Definition at line 741 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(), and duplicate_pseudo().
void ast_cc_default_config_params | ( | struct ast_cc_config_params * | params | ) |
Set the specified CC config params to default values.
params | CC config params to set to default values. |
Definition at line 558 of file ccss.c.
References cc_default_params.
Referenced by __ast_cc_config_params_init().
00559 { 00560 *params = cc_default_params; 00561 }
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.
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 |
void |
Definition at line 1735 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, dialed_cc_interfaces::dial_parent_id, dialed_cc_interfaces_info, id, dialed_cc_interfaces::interface_tree, monitor, and cc_monitor_backend::next.
Referenced by dial_exec_full().
01736 { 01737 struct ast_datastore *cc_datastore; 01738 struct dialed_cc_interfaces *cc_interfaces; 01739 struct ast_cc_monitor *monitor; 01740 struct extension_monitor_pvt *extension_pvt; 01741 struct extension_child_dialstring *child_dialstring; 01742 struct cc_monitor_tree *interface_tree; 01743 int id; 01744 01745 ast_channel_lock(incoming); 01746 if (!(cc_datastore = ast_channel_datastore_find(incoming, &dialed_cc_interfaces_info, NULL))) { 01747 ast_channel_unlock(incoming); 01748 return; 01749 } 01750 01751 cc_interfaces = cc_datastore->data; 01752 interface_tree = cc_interfaces->interface_tree; 01753 id = cc_interfaces->dial_parent_id; 01754 ast_channel_unlock(incoming); 01755 01756 AST_LIST_LOCK(interface_tree); 01757 AST_LIST_TRAVERSE(interface_tree, monitor, next) { 01758 if (monitor->id == id) { 01759 break; 01760 } 01761 } 01762 01763 if (!monitor) { 01764 AST_LIST_UNLOCK(interface_tree); 01765 return; 01766 } 01767 01768 extension_pvt = monitor->private_data; 01769 if (!(child_dialstring = ast_calloc(1, sizeof(*child_dialstring)))) { 01770 AST_LIST_UNLOCK(interface_tree); 01771 return; 01772 } 01773 ast_copy_string(child_dialstring->original_dialstring, dialstring, sizeof(child_dialstring->original_dialstring)); 01774 ast_copy_string(child_dialstring->device_name, device_name, sizeof(child_dialstring->device_name)); 01775 child_dialstring->is_valid = 1; 01776 AST_LIST_INSERT_TAIL(&extension_pvt->child_dialstrings, child_dialstring, next); 01777 AST_LIST_UNLOCK(interface_tree); 01778 }
int ast_cc_failed | ( | int | core_id, | |
const char *const | debug, | |||
... | ||||
) |
Indicate failure has occurred.
core_id | core_id of the CC transaction | |
debug | optional string to print for debugging purposes |
0 | Success | |
-1 | Failure |
Definition at line 3613 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(), sig_pri_cc_agent_req_rsp(), sig_pri_cc_link_canceled(), sig_pri_handle_cis_subcmds(), sip_offer_timer_expire(), suspend(), unsuspend(), and wait_for_answer().
03614 { 03615 va_list ap; 03616 int res; 03617 03618 va_start(ap, debug); 03619 res = cc_request_state_change(CC_FAILED, core_id, debug, ap); 03620 va_end(ap); 03621 return res; 03622 }
int ast_cc_get_current_core_id | ( | struct ast_channel * | chan | ) |
Get the core id for the current call.
The channel given to this function may be an inbound or outbound channel. Both will have the necessary info on it.
chan | The channel from which to get the core_id. |
core_id | on success | |
-1 | Failure |
Definition at line 2224 of file ccss.c.
References ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, dialed_cc_interfaces::core_id, ast_datastore::data, dialed_cc_interfaces_info, and dialed_cc_interfaces::ignore.
Referenced by sig_pri_cc_available(), sig_pri_cc_generic_check(), and sip_handle_cc().
02225 { 02226 struct ast_datastore *datastore; 02227 struct dialed_cc_interfaces *cc_interfaces; 02228 int core_id_return; 02229 02230 ast_channel_lock(chan); 02231 if (!(datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL))) { 02232 ast_channel_unlock(chan); 02233 return -1; 02234 } 02235 02236 cc_interfaces = datastore->data; 02237 core_id_return = cc_interfaces->ignore ? -1 : cc_interfaces->core_id; 02238 ast_channel_unlock(chan); 02239 return core_id_return; 02240 02241 }
struct ast_cc_monitor* ast_cc_get_monitor_by_recall_core_id | ( | const int | core_id, | |
const char *const | device_name | |||
) |
Get the associated monitor given the device name and core_id.
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. |
NULL | Appropriate monitor does not exist | |
non-NULL | The monitor to use for this recall |
Definition at line 3253 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, cc_core_instance::monitors, and cc_monitor_backend::next.
Referenced by sig_pri_call(), sig_pri_cc_generic_check(), and sip_call().
03254 { 03255 struct cc_core_instance *core_instance = find_cc_core_instance(core_id); 03256 struct ast_cc_monitor *monitor_iter; 03257 03258 if (!core_instance) { 03259 return NULL; 03260 } 03261 03262 AST_LIST_LOCK(core_instance->monitors); 03263 AST_LIST_TRAVERSE(core_instance->monitors, monitor_iter, next) { 03264 if (!strcmp(monitor_iter->interface->device_name, device_name)) { 03265 /* Found a monitor. */ 03266 cc_ref(monitor_iter, "Hand the requester of the monitor a reference"); 03267 break; 03268 } 03269 } 03270 AST_LIST_UNLOCK(core_instance->monitors); 03271 cc_unref(core_instance, "Done with core instance ref in ast_cc_get_monitor_by_recall_core_id"); 03272 return monitor_iter; 03273 }
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
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 |
0 | Success | |
-1 | Failure |
Definition at line 645 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().
00647 { 00648 const char *value = NULL; 00649 00650 if (!strcasecmp(name, "cc_callback_macro")) { 00651 value = ast_get_cc_callback_macro(params); 00652 } else if (!strcasecmp(name, "cc_agent_policy")) { 00653 value = agent_policy_to_str(ast_get_cc_agent_policy(params)); 00654 } else if (!strcasecmp(name, "cc_monitor_policy")) { 00655 value = monitor_policy_to_str(ast_get_cc_monitor_policy(params)); 00656 } else if (!strcasecmp(name, "cc_agent_dialstring")) { 00657 value = ast_get_cc_agent_dialstring(params); 00658 } 00659 if (value) { 00660 ast_copy_string(buf, value, buf_len); 00661 return 0; 00662 } 00663 00664 /* The rest of these are all ints of some sort and require some 00665 * snprintf-itude 00666 */ 00667 00668 if (!strcasecmp(name, "cc_offer_timer")) { 00669 snprintf(buf, buf_len, "%u", ast_get_cc_offer_timer(params)); 00670 } else if (!strcasecmp(name, "ccnr_available_timer")) { 00671 snprintf(buf, buf_len, "%u", ast_get_ccnr_available_timer(params)); 00672 } else if (!strcasecmp(name, "ccbs_available_timer")) { 00673 snprintf(buf, buf_len, "%u", ast_get_ccbs_available_timer(params)); 00674 } else if (!strcasecmp(name, "cc_max_agents")) { 00675 snprintf(buf, buf_len, "%u", ast_get_cc_max_agents(params)); 00676 } else if (!strcasecmp(name, "cc_max_monitors")) { 00677 snprintf(buf, buf_len, "%u", ast_get_cc_max_monitors(params)); 00678 } else if (!strcasecmp(name, "cc_recall_timer")) { 00679 snprintf(buf, buf_len, "%u", ast_get_cc_recall_timer(params)); 00680 } else { 00681 ast_log(LOG_WARNING, "%s is not a valid CC parameter. Ignoring.\n", name); 00682 return -1; 00683 } 00684 00685 return 0; 00686 }
int ast_cc_init | ( | void | ) |
Initialize CCSS.
0 | Success | |
nonzero | Failure |
Definition at line 4313 of file ccss.c.
References ao2_t_container_alloc, ARRAY_LEN, ast_cc_agent_register(), ast_cc_monitor_register(), ast_cli_register_multiple(), ast_logger_register_level(), ast_register_application2(), ast_sched_thread_create(), ast_taskprocessor_get(), cc_cli, cc_core_instance_cmp_fn(), cc_core_instance_hash_fn(), cc_core_instances, cc_core_taskprocessor, cc_sched_thread, cccancel_exec(), ccreq_exec(), generic_agent_callbacks, generic_monitor_cbs, generic_monitor_cmp_fn(), generic_monitor_hash_fn(), generic_monitors, initialize_cc_max_requests(), and TPS_REF_DEFAULT.
Referenced by main().
04314 { 04315 int res; 04316 04317 if (!(cc_core_instances = ao2_t_container_alloc(CC_CORE_INSTANCES_BUCKETS, 04318 cc_core_instance_hash_fn, cc_core_instance_cmp_fn, 04319 "Create core instance container"))) { 04320 return -1; 04321 } 04322 if (!(generic_monitors = ao2_t_container_alloc(CC_CORE_INSTANCES_BUCKETS, 04323 generic_monitor_hash_fn, generic_monitor_cmp_fn, 04324 "Create generic monitor container"))) { 04325 return -1; 04326 } 04327 if (!(cc_core_taskprocessor = ast_taskprocessor_get("CCSS core", TPS_REF_DEFAULT))) { 04328 return -1; 04329 } 04330 if (!(cc_sched_thread = ast_sched_thread_create())) { 04331 return -1; 04332 } 04333 res = ast_register_application2(ccreq_app, ccreq_exec, NULL, NULL, NULL); 04334 res |= ast_register_application2(cccancel_app, cccancel_exec, NULL, NULL, NULL); 04335 res |= ast_cc_monitor_register(&generic_monitor_cbs); 04336 res |= ast_cc_agent_register(&generic_agent_callbacks); 04337 ast_cli_register_multiple(cc_cli, ARRAY_LEN(cc_cli)); 04338 cc_logger_level = ast_logger_register_level(CC_LOGGER_LEVEL_NAME); 04339 dialed_cc_interface_counter = 1; 04340 initialize_cc_max_requests(); 04341 return res; 04342 }
int ast_cc_is_config_param | ( | const char *const | name | ) |
Is this a CCSS configuration parameter?
name | Name of configuration option being parsed. |
1 | Yes, this is a CCSS configuration parameter. | |
0 | No, this is not a CCSS configuration parameter. |
Definition at line 727 of file ccss.c.
Referenced by build_peer().
00728 { 00729 return (!strcasecmp(name, "cc_agent_policy") || 00730 !strcasecmp(name, "cc_monitor_policy") || 00731 !strcasecmp(name, "cc_offer_timer") || 00732 !strcasecmp(name, "ccnr_available_timer") || 00733 !strcasecmp(name, "ccbs_available_timer") || 00734 !strcasecmp(name, "cc_max_agents") || 00735 !strcasecmp(name, "cc_max_monitors") || 00736 !strcasecmp(name, "cc_callback_macro") || 00737 !strcasecmp(name, "cc_agent_dialstring") || 00738 !strcasecmp(name, "cc_recall_timer")); 00739 }
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.
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.
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.
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. |
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 3172 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, cc_recall_ds_data::nested, cc_monitor_backend::next, and recall_ds_info.
Referenced by cc_core_init_instance(), sig_pri_call(), sip_call(), and wait_for_answer().
03173 { 03174 struct ast_datastore *recall_datastore; 03175 struct cc_recall_ds_data *recall_data; 03176 struct cc_monitor_tree *interface_tree; 03177 char device_name[AST_CHANNEL_NAME]; 03178 struct ast_cc_monitor *device_monitor; 03179 int core_id_candidate; 03180 03181 ast_assert(core_id != NULL); 03182 03183 *core_id = -1; 03184 03185 ast_channel_lock(chan); 03186 if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) { 03187 /* Obviously not a recall if the datastore isn't present */ 03188 ast_channel_unlock(chan); 03189 return 0; 03190 } 03191 03192 recall_data = recall_datastore->data; 03193 03194 if (recall_data->ignore) { 03195 /* Though this is a recall, the call to this particular interface is not part of the 03196 * recall either because this is a call forward or because this is not the first 03197 * invocation of Dial during this call 03198 */ 03199 ast_channel_unlock(chan); 03200 return 0; 03201 } 03202 03203 if (!recall_data->nested) { 03204 /* If the nested flag is not set, then this means that 03205 * the channel passed to this function is the caller making 03206 * the recall. This means that we shouldn't look through 03207 * the monitor tree for the channel because it shouldn't be 03208 * there. However, this is a recall though, so return true. 03209 */ 03210 *core_id = recall_data->core_id; 03211 ast_channel_unlock(chan); 03212 return 1; 03213 } 03214 03215 if (ast_strlen_zero(monitor_type)) { 03216 /* If someone passed a NULL or empty monitor type, then it is clear 03217 * the channel they passed in was an incoming channel, and so searching 03218 * the list of dialed interfaces is not going to be helpful. Just return 03219 * false immediately. 03220 */ 03221 ast_channel_unlock(chan); 03222 return 0; 03223 } 03224 03225 interface_tree = recall_data->interface_tree; 03226 ast_channel_get_device_name(chan, device_name, sizeof(device_name)); 03227 /* We grab the value of the recall_data->core_id so that we 03228 * can unlock the channel before we start looking through the 03229 * interface list. That way we don't have to worry about a possible 03230 * clash between the channel lock and the monitor tree lock. 03231 */ 03232 core_id_candidate = recall_data->core_id; 03233 ast_channel_unlock(chan); 03234 03235 /* 03236 * Now we need to find out if the channel device name 03237 * is in the list of interfaces in the called tree. 03238 */ 03239 AST_LIST_LOCK(interface_tree); 03240 AST_LIST_TRAVERSE(interface_tree, device_monitor, next) { 03241 if (!strcmp(device_monitor->interface->device_name, device_name) && 03242 !strcmp(device_monitor->interface->monitor_type, monitor_type)) { 03243 /* BOOM! Device is in the tree! We have a winner! */ 03244 *core_id = core_id_candidate; 03245 AST_LIST_UNLOCK(interface_tree); 03246 return 1; 03247 } 03248 } 03249 AST_LIST_UNLOCK(interface_tree); 03250 return 0; 03251 }
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.
core_id | The core ID of the corresponding CC transaction | |
debug |
0 | Request successfully queued | |
-1 | Request could not be queued |
Definition at line 3532 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(), handle_cc_notify(), and sig_pri_handle_cis_subcmds().
03533 { 03534 va_list ap; 03535 int res; 03536 03537 va_start(ap, debug); 03538 res = cc_request_state_change(CC_CALLEE_READY, core_id, debug, ap); 03539 va_end(ap); 03540 return res; 03541 }
int ast_cc_monitor_count | ( | const char *const | name, | |
const char *const | type | |||
) |
Return the number of outstanding CC requests to a specific device.
name | The name of the monitored device | |
type | The type of the monitored device (e.g. "generic") |
Definition at line 4105 of file ccss.c.
References ao2_t_callback, ast_log_dynamic_level, cc_core_instances, count_monitors_cb_data::count, count_monitors_cb(), count_monitors_cb_data::device_name, and OBJ_NODATA.
Referenced by ast_queue_cc_frame().
04106 { 04107 struct count_monitors_cb_data data = {.device_name = name, .monitor_type = type,}; 04108 04109 ao2_t_callback(cc_core_instances, OBJ_NODATA, count_monitors_cb, &data, "Counting agents"); 04110 ast_log_dynamic_level(cc_logger_level, "Counted %d monitors\n", data.count); 04111 return data.count; 04112 }
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.
If there are no more devices left to monitor when this function is called, then the core will fail the CC transaction globally.
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 |
Definition at line 3678 of file ccss.c.
References ast_calloc, ast_free, ast_strdup, ast_taskprocessor_push(), ast_vasprintf, cc_core_taskprocessor, and cc_monitor_failed().
Referenced by ast_cc_available_timer_expire(), cc_handle_publish_error(), handle_response_subscribe(), sig_pri_cc_link_canceled(), and sig_pri_handle_cis_subcmds().
03679 { 03680 struct ast_cc_monitor_failure_data *failure_data; 03681 int res; 03682 va_list ap; 03683 03684 if (!(failure_data = ast_calloc(1, sizeof(*failure_data)))) { 03685 return -1; 03686 } 03687 03688 if (!(failure_data->device_name = ast_strdup(monitor_name))) { 03689 ast_free(failure_data); 03690 return -1; 03691 } 03692 03693 va_start(ap, debug); 03694 if (ast_vasprintf(&failure_data->debug, debug, ap) == -1) { 03695 va_end(ap); 03696 ast_free((char *)failure_data->device_name); 03697 ast_free(failure_data); 03698 return -1; 03699 } 03700 va_end(ap); 03701 03702 failure_data->core_id = core_id; 03703 03704 res = ast_taskprocessor_push(cc_core_taskprocessor, cc_monitor_failed, failure_data); 03705 if (res) { 03706 ast_free((char *)failure_data->device_name); 03707 ast_free((char *)failure_data->debug); 03708 ast_free(failure_data); 03709 } 03710 return res; 03711 }
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.
core_id | The core ID of the CC transaction |
0 | Successfully alerted the core that party B is free | |
-1 | Could not alert the core that party B is free |
Definition at line 3788 of file ccss.c.
References ast_taskprocessor_push(), cc_core_taskprocessor, cc_party_b_free(), cc_unref(), and find_cc_core_instance().
Referenced by sig_pri_handle_cis_subcmds().
03789 { 03790 int res; 03791 struct cc_core_instance *core_instance = find_cc_core_instance(core_id); 03792 03793 if (!core_instance) { 03794 return -1; 03795 } 03796 03797 res = ast_taskprocessor_push(cc_core_taskprocessor, cc_party_b_free, core_instance); 03798 if (res) { 03799 cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed"); 03800 } 03801 return res; 03802 }
int ast_cc_monitor_register | ( | const struct ast_cc_monitor_callbacks * | callbacks | ) |
Register a set of monitor callbacks with the core.
callbacks | The callbacks used by the monitor implementation |
0 | Successfully registered | |
-1 | Failure to register |
Definition at line 895 of file ccss.c.
References ast_calloc, AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and cc_monitor_backend::next.
Referenced by ast_cc_init(), and load_module().
00896 { 00897 struct cc_monitor_backend *backend = ast_calloc(1, sizeof(*backend)); 00898 00899 if (!backend) { 00900 return -1; 00901 } 00902 00903 backend->callbacks = callbacks; 00904 00905 AST_RWLIST_WRLOCK(&cc_monitor_backends); 00906 AST_RWLIST_INSERT_TAIL(&cc_monitor_backends, backend, next); 00907 AST_RWLIST_UNLOCK(&cc_monitor_backends); 00908 return 0; 00909 }
int ast_cc_monitor_request_acked | ( | int | core_id, | |
const char *const | debug, | |||
... | ||||
) |
Indicate that an outbound entity has accepted our CC request.
core_id | core_id of the CC transaction | |
debug | optional string to print for debugging purposes |
0 | Success | |
-1 | Failure |
Definition at line 3521 of file ccss.c.
References CC_ACTIVE, and cc_request_state_change().
Referenced by cc_generic_monitor_request_cc(), cc_stop_ringing(), handle_cc_notify(), and sig_pri_handle_cis_subcmds().
03522 { 03523 va_list ap; 03524 int res; 03525 03526 va_start(ap, debug); 03527 res = cc_request_state_change(CC_ACTIVE, core_id, debug, ap); 03528 va_end(ap); 03529 return res; 03530 }
int ast_cc_monitor_status_request | ( | int | core_id | ) |
Request the status of a caller or callers.
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.
core_id | The core ID of the CC transaction |
0 | Successfully requested status | |
-1 | Failed to request status |
Definition at line 3723 of file ccss.c.
References ast_taskprocessor_push(), cc_core_taskprocessor, cc_status_request(), cc_unref(), and find_cc_core_instance().
Referenced by sig_pri_handle_cis_subcmds().
03724 { 03725 int res; 03726 struct cc_core_instance *core_instance = find_cc_core_instance(core_id); 03727 03728 if (!core_instance) { 03729 return -1; 03730 } 03731 03732 res = ast_taskprocessor_push(cc_core_taskprocessor, cc_status_request, core_instance); 03733 if (res) { 03734 cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed"); 03735 } 03736 return res; 03737 }
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.
core_id | The core ID of the CC transaction |
0 | Successfully requested for the phone to stop ringing | |
-1 | Could not request for the phone to stop ringing |
Definition at line 3760 of file ccss.c.
References ast_taskprocessor_push(), cc_core_taskprocessor, cc_stop_ringing(), cc_unref(), and find_cc_core_instance().
Referenced by sig_pri_handle_cis_subcmds().
03761 { 03762 int res; 03763 struct cc_core_instance *core_instance = find_cc_core_instance(core_id); 03764 03765 if (!core_instance) { 03766 return -1; 03767 } 03768 03769 res = ast_taskprocessor_push(cc_core_taskprocessor, cc_stop_ringing, core_instance); 03770 if (res) { 03771 cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed"); 03772 } 03773 return res; 03774 }
void ast_cc_monitor_unregister | ( | const struct ast_cc_monitor_callbacks * | callbacks | ) |
Unregister a set of monitor callbacks with the core.
callbacks | The callbacks used by the monitor implementation |
0 | Successfully unregistered | |
-1 | Failure to unregister |
Definition at line 928 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().
00929 { 00930 struct cc_monitor_backend *backend; 00931 AST_RWLIST_WRLOCK(&cc_monitor_backends); 00932 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&cc_monitor_backends, backend, next) { 00933 if (backend->callbacks == callbacks) { 00934 AST_RWLIST_REMOVE_CURRENT(next); 00935 ast_free(backend); 00936 break; 00937 } 00938 } 00939 AST_RWLIST_TRAVERSE_SAFE_END; 00940 AST_RWLIST_UNLOCK(&cc_monitor_backends); 00941 }
int ast_cc_offer | ( | struct ast_channel * | caller_chan | ) |
Offer CC to a caller.
caller_chan | The calling channel |
-1 | Error | |
0 | Success |
Definition at line 3485 of file ccss.c.
References ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, cc_offer(), cc_recall_ds_data::core_id, dialed_cc_interfaces::core_id, ast_datastore::data, dialed_cc_interfaces_info, dialed_cc_interfaces::is_original_caller, and ast_channel::name.
Referenced by ast_hangup().
03486 { 03487 int core_id; 03488 int res = -1; 03489 struct ast_datastore *datastore; 03490 struct dialed_cc_interfaces *cc_interfaces; 03491 char cc_is_offerable; 03492 03493 ast_channel_lock(caller_chan); 03494 if (!(datastore = ast_channel_datastore_find(caller_chan, &dialed_cc_interfaces_info, NULL))) { 03495 ast_channel_unlock(caller_chan); 03496 return res; 03497 } 03498 03499 cc_interfaces = datastore->data; 03500 cc_is_offerable = cc_interfaces->is_original_caller; 03501 core_id = cc_interfaces->core_id; 03502 ast_channel_unlock(caller_chan); 03503 03504 if (cc_is_offerable) { 03505 res = cc_offer(core_id, "CC offered to caller %s", caller_chan->name); 03506 } 03507 return res; 03508 }
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.
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.
0 | Not within the limits. Fail. | |
non-zero | Within the limits. Success. |
Definition at line 2219 of file ccss.c.
Referenced by cc_caller_requested(), cc_interfaces_datastore_init(), ccreq_exec(), and sig_pri_handle_cis_subcmds().
02220 { 02221 return cc_request_count < global_cc_max_requests; 02222 }
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
params | The parameter structure to set the value on | |
name | The name of the cc parameter | |
value | The value of the parameter |
0 | Success | |
-1 | Failure |
Definition at line 688 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(), and build_peer().
00690 { 00691 unsigned int value_as_uint; 00692 if (!strcasecmp(name, "cc_agent_policy")) { 00693 return ast_set_cc_agent_policy(params, str_to_agent_policy(value)); 00694 } else if (!strcasecmp(name, "cc_monitor_policy")) { 00695 return ast_set_cc_monitor_policy(params, str_to_monitor_policy(value)); 00696 } else if (!strcasecmp(name, "cc_agent_dialstring")) { 00697 ast_set_cc_agent_dialstring(params, value); 00698 } else if (!strcasecmp(name, "cc_callback_macro")) { 00699 ast_set_cc_callback_macro(params, value); 00700 return 0; 00701 } 00702 00703 if (!sscanf(value, "%30u", &value_as_uint) == 1) { 00704 return -1; 00705 } 00706 00707 if (!strcasecmp(name, "cc_offer_timer")) { 00708 ast_set_cc_offer_timer(params, value_as_uint); 00709 } else if (!strcasecmp(name, "ccnr_available_timer")) { 00710 ast_set_ccnr_available_timer(params, value_as_uint); 00711 } else if (!strcasecmp(name, "ccbs_available_timer")) { 00712 ast_set_ccbs_available_timer(params, value_as_uint); 00713 } else if (!strcasecmp(name, "cc_max_agents")) { 00714 ast_set_cc_max_agents(params, value_as_uint); 00715 } else if (!strcasecmp(name, "cc_max_monitors")) { 00716 ast_set_cc_max_monitors(params, value_as_uint); 00717 } else if (!strcasecmp(name, "cc_recall_timer")) { 00718 ast_set_cc_recall_timer(params, value_as_uint); 00719 } else { 00720 ast_log(LOG_WARNING, "%s is not a valid CC parameter. Ignoring.\n", name); 00721 return -1; 00722 } 00723 00724 return 0; 00725 }
const char* ast_get_cc_agent_dialstring | ( | struct ast_cc_config_params * | config | ) |
Get the cc_agent_dialstring.
config | The configuration to retrieve the cc_agent_dialstring from |
Definition at line 840 of file ccss.c.
References config.
Referenced by ast_cc_get_param(), and generic_recall().
00841 { 00842 return config->cc_agent_dialstring; 00843 }
enum ast_cc_agent_policies ast_get_cc_agent_policy | ( | struct ast_cc_config_params * | config | ) |
Get the cc_agent_policy.
config | The configuration to retrieve the policy from |
Definition at line 746 of file ccss.c.
References config.
Referenced by ast_cc_call_init(), ast_cc_get_param(), build_peer(), cc_core_init_instance(), and find_agent_callbacks().
00747 { 00748 return config->cc_agent_policy; 00749 }
const char* ast_get_cc_callback_macro | ( | struct ast_cc_config_params * | config | ) |
Get the name of the callback_macro.
config | The configuration to retrieve the callback_macro from |
Definition at line 874 of file ccss.c.
References config.
Referenced by ast_cc_get_param(), and generic_recall().
00875 { 00876 return config->cc_callback_macro; 00877 }
unsigned int ast_get_cc_max_agents | ( | struct ast_cc_config_params * | config | ) |
Get the cc_max_agents.
config | The configuration to retrieve the cc_max_agents from |
Definition at line 854 of file ccss.c.
References config.
Referenced by ast_cc_get_param(), and cc_core_init_instance().
00855 { 00856 return config->cc_max_agents; 00857 }
unsigned int ast_get_cc_max_monitors | ( | struct ast_cc_config_params * | config | ) |
Get the cc_max_monitors.
config | The configuration to retrieve the cc_max_monitors from |
Definition at line 864 of file ccss.c.
References config.
Referenced by ast_cc_get_param(), and ast_queue_cc_frame().
00865 { 00866 return config->cc_max_monitors; 00867 }
enum ast_cc_monitor_policies ast_get_cc_monitor_policy | ( | struct ast_cc_config_params * | config | ) |
Get the cc_monitor_policy.
config | The configuration to retrieve the cc_monitor_policy from |
Definition at line 763 of file ccss.c.
References config.
Referenced by analog_call(), ast_cc_call_failed(), ast_cc_get_param(), dahdi_cc_callback(), sig_pri_cc_available(), sig_pri_cc_generic_check(), and sip_handle_cc().
00764 { 00765 return config->cc_monitor_policy; 00766 }
unsigned int ast_get_cc_offer_timer | ( | struct ast_cc_config_params * | config | ) |
Get the cc_offer_timer.
config | The configuration to retrieve the cc_offer_timer from |
Definition at line 780 of file ccss.c.
References config.
Referenced by ast_cc_get_param(), cc_generic_agent_start_offer_timer(), and sip_cc_agent_start_offer_timer().
00781 { 00782 return config->cc_offer_timer; 00783 }
unsigned int ast_get_cc_recall_timer | ( | struct ast_cc_config_params * | config | ) |
Get the cc_recall_timer.
config | The configuration to retrieve the cc_recall_timer from |
Definition at line 810 of file ccss.c.
References config.
Referenced by ast_cc_get_param(), and generic_recall().
00811 { 00812 return config->cc_recall_timer; 00813 }
unsigned int ast_get_ccbs_available_timer | ( | struct ast_cc_config_params * | config | ) |
Get the ccbs_available_timer.
config | The configuration to retrieve the ccbs_available_timer from |
Definition at line 825 of file ccss.c.
References config.
Referenced by ast_cc_get_param(), cc_generic_monitor_request_cc(), and sip_cc_monitor_request_cc().
00826 { 00827 return config->ccbs_available_timer; 00828 }
unsigned int ast_get_ccnr_available_timer | ( | struct ast_cc_config_params * | config | ) |
Get the ccnr_available_timer.
config | The configuration to retrieve the ccnr_available_timer from |
Definition at line 795 of file ccss.c.
References config.
Referenced by ast_cc_get_param(), cc_generic_monitor_request_cc(), and sip_cc_monitor_request_cc().
00796 { 00797 return config->ccnr_available_timer; 00798 }
void ast_handle_cc_control_frame | ( | struct ast_channel * | inbound, | |
struct ast_channel * | outbound, | |||
void * | frame_data | |||
) |
Properly react to a CC control frame.
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 2048 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(), dialed_cc_interfaces::core_id, cc_core_instance::core_id, ast_datastore::data, cc_control_payload::device_name, dialed_cc_interfaces_info, ast_cc_monitor::dialstring, cc_control_payload::dialstring, EVENT_FLAG_CC, find_cc_core_instance(), dialed_cc_interfaces::ignore, dialed_cc_interfaces::interface_tree, dialed_cc_interfaces::is_original_caller, LOG_WARNING, manager_event, monitor, cc_control_payload::monitor_type, cc_monitor_backend::next, cc_control_payload::private_data, and cc_control_payload::service.
Referenced by ast_cc_busy_interface(), and ast_cc_call_failed().
02049 { 02050 char *device_name; 02051 char *dialstring; 02052 struct ast_cc_monitor *monitor; 02053 struct ast_datastore *cc_datastore; 02054 struct dialed_cc_interfaces *cc_interfaces; 02055 struct cc_control_payload *cc_data = frame_data; 02056 struct cc_core_instance *core_instance; 02057 02058 device_name = cc_data->device_name; 02059 dialstring = cc_data->dialstring; 02060 02061 ast_channel_lock(inbound); 02062 if (!(cc_datastore = ast_channel_datastore_find(inbound, &dialed_cc_interfaces_info, NULL))) { 02063 ast_log(LOG_WARNING, "Unable to retrieve CC datastore while processing CC frame from '%s'. CC services will be unavailable.\n", device_name); 02064 ast_channel_unlock(inbound); 02065 call_destructor_with_no_monitor(cc_data->monitor_type, cc_data->private_data); 02066 return; 02067 } 02068 02069 cc_interfaces = cc_datastore->data; 02070 02071 if (cc_interfaces->ignore) { 02072 ast_channel_unlock(inbound); 02073 call_destructor_with_no_monitor(cc_data->monitor_type, cc_data->private_data); 02074 return; 02075 } 02076 02077 if (!cc_interfaces->is_original_caller) { 02078 /* If the is_original_caller is not set on the *inbound* channel, then 02079 * it must be a local channel. As such, we do not want to create a core instance 02080 * or an agent for the local channel. Instead, we want to pass this along to the 02081 * other side of the local channel so that the original caller can benefit. 02082 */ 02083 ast_channel_unlock(inbound); 02084 ast_indicate_data(inbound, AST_CONTROL_CC, cc_data, sizeof(*cc_data)); 02085 return; 02086 } 02087 02088 core_instance = find_cc_core_instance(cc_interfaces->core_id); 02089 if (!core_instance) { 02090 core_instance = cc_core_init_instance(inbound, cc_interfaces->interface_tree, 02091 cc_interfaces->core_id, cc_data); 02092 if (!core_instance) { 02093 cc_interfaces->ignore = 1; 02094 ast_channel_unlock(inbound); 02095 call_destructor_with_no_monitor(cc_data->monitor_type, cc_data->private_data); 02096 return; 02097 } 02098 } 02099 02100 ast_channel_unlock(inbound); 02101 02102 /* Yeah this kind of sucks, but luckily most people 02103 * aren't dialing thousands of interfaces on every call 02104 * 02105 * This traversal helps us to not create duplicate monitors in 02106 * case a device queues multiple CC control frames. 02107 */ 02108 AST_LIST_LOCK(cc_interfaces->interface_tree); 02109 AST_LIST_TRAVERSE(cc_interfaces->interface_tree, monitor, next) { 02110 if (!strcmp(monitor->interface->device_name, device_name)) { 02111 ast_log_dynamic_level(cc_logger_level, "Core %d: Device %s sent us multiple CC control frames. Ignoring those beyond the first.\n", 02112 core_instance->core_id, device_name); 02113 AST_LIST_UNLOCK(cc_interfaces->interface_tree); 02114 cc_unref(core_instance, "Returning early from ast_handle_cc_control_frame. Unref core_instance"); 02115 call_destructor_with_no_monitor(cc_data->monitor_type, cc_data->private_data); 02116 return; 02117 } 02118 } 02119 AST_LIST_UNLOCK(cc_interfaces->interface_tree); 02120 02121 if (!(monitor = cc_device_monitor_init(device_name, dialstring, cc_data, core_instance->core_id))) { 02122 ast_log(LOG_WARNING, "Unable to create CC device interface for '%s'. CC services will be unavailable on this interface.\n", device_name); 02123 cc_unref(core_instance, "Returning early from ast_handle_cc_control_frame. Unref core_instance"); 02124 call_destructor_with_no_monitor(cc_data->monitor_type, cc_data->private_data); 02125 return; 02126 } 02127 02128 AST_LIST_LOCK(cc_interfaces->interface_tree); 02129 cc_ref(monitor, "monitor tree's reference to the monitor"); 02130 AST_LIST_INSERT_TAIL(cc_interfaces->interface_tree, monitor, next); 02131 AST_LIST_UNLOCK(cc_interfaces->interface_tree); 02132 02133 cc_extension_monitor_change_is_valid(core_instance, monitor->parent_id, monitor->interface->device_name, 0); 02134 02135 manager_event(EVENT_FLAG_CC, "CCAvailable", 02136 "CoreID: %d\r\n" 02137 "Callee: %s\r\n" 02138 "Service: %s\r\n", 02139 cc_interfaces->core_id, device_name, cc_service_to_string(cc_data->service) 02140 ); 02141 02142 cc_unref(core_instance, "Done with core_instance after handling CC control frame"); 02143 cc_unref(monitor, "Unref reference from allocating monitor"); 02144 }
void ast_ignore_cc | ( | struct ast_channel * | chan | ) |
Mark the channel to ignore further CC activity.
chan | The channel for which further CC processing should be ignored. |
void |
Definition at line 3454 of file ccss.c.
References ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_datastore::data, dialed_cc_interfaces_info, dialed_cc_interfaces::ignore, cc_recall_ds_data::ignore, and recall_ds_info.
Referenced by dial_exec_full(), and do_forward().
03455 { 03456 struct ast_datastore *cc_datastore; 03457 struct ast_datastore *cc_recall_datastore; 03458 struct dialed_cc_interfaces *cc_interfaces; 03459 struct cc_recall_ds_data *recall_cc_data; 03460 03461 ast_channel_lock(chan); 03462 if ((cc_datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL))) { 03463 cc_interfaces = cc_datastore->data; 03464 cc_interfaces->ignore = 1; 03465 } 03466 03467 if ((cc_recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) { 03468 recall_cc_data = cc_recall_datastore->data; 03469 recall_cc_data->ignore = 1; 03470 } 03471 ast_channel_unlock(chan); 03472 }
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.
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. |
0 | Success | |
-1 | Error |
Definition at line 3886 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(), sig_pri_cc_available(), sig_pri_cc_generic_check(), and sip_handle_cc().
03888 { 03889 struct ast_frame frame = {0,}; 03890 char device_name[AST_CHANNEL_NAME]; 03891 int retval; 03892 struct ast_cc_config_params *cc_params; 03893 03894 cc_params = ast_channel_get_cc_config_params(chan); 03895 if (!cc_params) { 03896 return -1; 03897 } 03898 ast_channel_get_device_name(chan, device_name, sizeof(device_name)); 03899 if (ast_cc_monitor_count(device_name, monitor_type) >= ast_get_cc_max_monitors(cc_params)) { 03900 ast_log(LOG_NOTICE, "Not queuing a CC frame for device %s since it already has its maximum monitors allocated\n", device_name); 03901 return -1; 03902 } 03903 03904 if (ast_cc_build_frame(chan, cc_params, monitor_type, device_name, dialstring, service, private_data, &frame)) { 03905 /* Frame building failed. We can't use this. */ 03906 return -1; 03907 } 03908 retval = ast_queue_frame(chan, &frame); 03909 ast_frfree(&frame); 03910 return retval; 03911 }
void ast_set_cc_agent_dialstring | ( | struct ast_cc_config_params * | config, | |
const char *const | value | |||
) |
Set the cc_agent_dialstring.
config | The configuration to set the cc_agent_dialstring on | |
value | The new cc_agent_dialstring we want to change to |
void |
Definition at line 845 of file ccss.c.
References ast_copy_string(), ast_strlen_zero(), and config.
Referenced by ast_cc_set_param().
00846 { 00847 if (ast_strlen_zero(value)) { 00848 config->cc_agent_dialstring[0] = '\0'; 00849 } else { 00850 ast_copy_string(config->cc_agent_dialstring, value, sizeof(config->cc_agent_dialstring)); 00851 } 00852 }
int ast_set_cc_agent_policy | ( | struct ast_cc_config_params * | config, | |
enum ast_cc_agent_policies | value | |||
) |
Set the cc_agent_policy.
config | The configuration to set the cc_agent_policy on | |
value | The new cc_agent_policy we want to change to |
0 | Success | |
-1 | Failure (likely due to bad input) |
Definition at line 751 of file ccss.c.
References AST_CC_AGENT_GENERIC, and config.
Referenced by ast_cc_set_param(), and build_peer().
00752 { 00753 /* Screw C and its weak type checking for making me have to do this 00754 * validation at runtime. 00755 */ 00756 if (value < AST_CC_AGENT_NEVER || value > AST_CC_AGENT_GENERIC) { 00757 return -1; 00758 } 00759 config->cc_agent_policy = value; 00760 return 0; 00761 }
void ast_set_cc_callback_macro | ( | struct ast_cc_config_params * | config, | |
const char *const | value | |||
) |
Set the callback_macro name.
config | The configuration to set the callback_macro on | |
value | The new callback macro we want to change to |
void |
Definition at line 879 of file ccss.c.
References ast_copy_string(), ast_strlen_zero(), and config.
Referenced by ast_cc_set_param().
00880 { 00881 if (ast_strlen_zero(value)) { 00882 config->cc_callback_macro[0] = '\0'; 00883 } else { 00884 ast_copy_string(config->cc_callback_macro, value, sizeof(config->cc_callback_macro)); 00885 } 00886 }
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.
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 3402 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, cc_monitor_backend::next, pbx_builtin_setvar_helper(), recall_ds_info, and str.
Referenced by local_call().
03403 { 03404 struct ast_datastore *recall_datastore; 03405 struct cc_monitor_tree *interface_tree; 03406 struct ast_cc_monitor *monitor_iter; 03407 struct cc_recall_ds_data *recall_data; 03408 struct ast_str *str = ast_str_create(64); 03409 int core_id; 03410 03411 if (!str) { 03412 return -1; 03413 } 03414 03415 ast_channel_lock(chan); 03416 if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) { 03417 ast_channel_unlock(chan); 03418 ast_free(str); 03419 return -1; 03420 } 03421 recall_data = recall_datastore->data; 03422 interface_tree = recall_data->interface_tree; 03423 core_id = recall_data->core_id; 03424 ast_channel_unlock(chan); 03425 03426 AST_LIST_LOCK(interface_tree); 03427 AST_LIST_TRAVERSE(interface_tree, monitor_iter, next) { 03428 if (!strcmp(monitor_iter->interface->device_name, extension)) { 03429 break; 03430 } 03431 } 03432 03433 if (!monitor_iter) { 03434 /* We couldn't find this extension. This may be because 03435 * we have been directed into an unexpected extension because 03436 * the admin has changed a CC_INTERFACES variable at some point. 03437 */ 03438 AST_LIST_UNLOCK(interface_tree); 03439 ast_free(str); 03440 return -1; 03441 } 03442 03443 build_cc_interfaces_chanvar(monitor_iter, str); 03444 AST_LIST_UNLOCK(interface_tree); 03445 03446 pbx_builtin_setvar_helper(chan, "CC_INTERFACES", ast_str_buffer(str)); 03447 ast_log_dynamic_level(cc_logger_level, "Core %d: CC_INTERFACES set to %s\n", 03448 core_id, ast_str_buffer(str)); 03449 03450 ast_free(str); 03451 return 0; 03452 }
void ast_set_cc_max_agents | ( | struct ast_cc_config_params * | config, | |
unsigned int | value | |||
) |
Set the cc_max_agents.
config | The configuration to set the cc_max_agents on | |
value | The new cc_max_agents we want to change to |
void |
Definition at line 859 of file ccss.c.
References config.
Referenced by ast_cc_set_param().
void ast_set_cc_max_monitors | ( | struct ast_cc_config_params * | config, | |
unsigned int | value | |||
) |
Set the cc_max_monitors.
config | The configuration to set the cc_max_monitors on | |
value | The new cc_max_monitors we want to change to |
void |
Definition at line 869 of file ccss.c.
References config.
Referenced by ast_cc_set_param().
int ast_set_cc_monitor_policy | ( | struct ast_cc_config_params * | config, | |
enum ast_cc_monitor_policies | value | |||
) |
Set the cc_monitor_policy.
config | The configuration to set the cc_monitor_policy on | |
value | The new cc_monitor_policy we want to change to |
0 | Success | |
-1 | Failure (likely due to bad input) |
Definition at line 768 of file ccss.c.
References AST_CC_MONITOR_ALWAYS, and config.
Referenced by ast_cc_set_param().
00769 { 00770 /* Screw C and its weak type checking for making me have to do this 00771 * validation at runtime. 00772 */ 00773 if (value < AST_CC_MONITOR_NEVER || value > AST_CC_MONITOR_ALWAYS) { 00774 return -1; 00775 } 00776 config->cc_monitor_policy = value; 00777 return 0; 00778 }
void ast_set_cc_offer_timer | ( | struct ast_cc_config_params * | config, | |
unsigned int | value | |||
) |
Set the cc_offer_timer.
config | The configuration to set the cc_offer_timer on | |
value | The new cc_offer_timer we want to change to |
void |
Definition at line 785 of file ccss.c.
References ast_log(), config, and LOG_WARNING.
Referenced by ast_cc_set_param().
00786 { 00787 /* 0 is an unreasonable value for any timer. Stick with the default */ 00788 if (value == 0) { 00789 ast_log(LOG_WARNING, "0 is an invalid value for cc_offer_timer. Retaining value as %u\n", config->cc_offer_timer); 00790 return; 00791 } 00792 config->cc_offer_timer = value; 00793 }
void ast_set_cc_recall_timer | ( | struct ast_cc_config_params * | config, | |
unsigned int | value | |||
) |
Set the cc_recall_timer.
config | The configuration to set the cc_recall_timer on | |
value | The new cc_recall_timer we want to change to |
void |
Definition at line 815 of file ccss.c.
References ast_log(), config, and LOG_WARNING.
Referenced by ast_cc_set_param().
00816 { 00817 /* 0 is an unreasonable value for any timer. Stick with the default */ 00818 if (value == 0) { 00819 ast_log(LOG_WARNING, "0 is an invalid value for ccnr_available_timer. Retaining value as %u\n", config->cc_recall_timer); 00820 return; 00821 } 00822 config->cc_recall_timer = value; 00823 }
void ast_set_ccbs_available_timer | ( | struct ast_cc_config_params * | config, | |
unsigned int | value | |||
) |
Set the ccbs_available_timer.
config | The configuration to set the ccbs_available_timer on | |
value | The new ccbs_available_timer we want to change to |
void |
Definition at line 830 of file ccss.c.
References ast_log(), config, and LOG_WARNING.
Referenced by ast_cc_set_param().
00831 { 00832 /* 0 is an unreasonable value for any timer. Stick with the default */ 00833 if (value == 0) { 00834 ast_log(LOG_WARNING, "0 is an invalid value for ccbs_available_timer. Retaining value as %u\n", config->ccbs_available_timer); 00835 return; 00836 } 00837 config->ccbs_available_timer = value; 00838 }
void ast_set_ccnr_available_timer | ( | struct ast_cc_config_params * | config, | |
unsigned int | value | |||
) |
Set the ccnr_available_timer.
config | The configuration to set the ccnr_available_timer on | |
value | The new ccnr_available_timer we want to change to |
void |
Definition at line 800 of file ccss.c.
References ast_log(), config, and LOG_WARNING.
Referenced by ast_cc_set_param().
00801 { 00802 /* 0 is an unreasonable value for any timer. Stick with the default */ 00803 if (value == 0) { 00804 ast_log(LOG_WARNING, "0 is an invalid value for ccnr_available_timer. Retaining value as %u\n", config->ccnr_available_timer); 00805 return; 00806 } 00807 config->ccnr_available_timer = value; 00808 }
int ast_setup_cc_recall_datastore | ( | struct ast_channel * | chan, | |
const int | core_id | |||
) |
Set up a CC recall datastore on a channel.
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 3139 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(), ast_datastore::data, DATASTORE_INHERIT_FOREVER, find_cc_core_instance(), ast_datastore::inheritance, cc_core_instance::monitors, and recall_ds_info.
Referenced by generic_recall(), handle_request_invite(), and sig_pri_handle_subcmds().
03140 { 03141 struct ast_datastore *recall_datastore = ast_datastore_alloc(&recall_ds_info, NULL); 03142 struct cc_recall_ds_data *recall_data; 03143 struct cc_core_instance *core_instance; 03144 03145 if (!recall_datastore) { 03146 return -1; 03147 } 03148 03149 if (!(recall_data = ast_calloc(1, sizeof(*recall_data)))) { 03150 ast_datastore_free(recall_datastore); 03151 return -1; 03152 } 03153 03154 if (!(core_instance = find_cc_core_instance(core_id))) { 03155 ast_free(recall_data); 03156 ast_datastore_free(recall_datastore); 03157 return -1; 03158 } 03159 03160 recall_data->interface_tree = cc_ref(core_instance->monitors, 03161 "Bump refcount for monitor tree for recall datastore"); 03162 recall_data->core_id = core_id; 03163 recall_datastore->data = recall_data; 03164 recall_datastore->inheritance = DATASTORE_INHERIT_FOREVER; 03165 ast_channel_lock(chan); 03166 ast_channel_datastore_add(chan, recall_datastore); 03167 ast_channel_unlock(chan); 03168 cc_unref(core_instance, "Recall datastore set up. No need for core_instance ref"); 03169 return 0; 03170 }