#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 | |
| struct ast_cc_config_params * | __ast_cc_config_params_init (const char *file, int line, const char *function) |
| Allocate and initialize an ast_cc_config_params structure. | |
| int | ast_cc_agent_accept_request (int core_id, const char *const debug,...) |
| Accept inbound CC request. | |
| struct ast_cc_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. | |
| 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. | |
| 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(), mkintf(), sip_alloc(), and temp_peer().
| #define AST_CC_GENERIC_MONITOR_TYPE "generic" |
It is recommended that monitors use a pointer to an ast_cc_monitor_callbacks::type when creating an AST_CONTROL_CC frame. Since the generic monitor callbacks are opaque and channel drivers will wish to use that, this string is made globally available for all to use
Definition at line 472 of file ccss.h.
Referenced by analog_call(), ast_cc_call_failed(), dahdi_cc_callback(), and sip_handle_cc().
| typedef 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 };
| AST_CC_AGENT_RESPONSE_SUCCESS | CC request accepted |
| AST_CC_AGENT_RESPONSE_FAILURE_INVALID | CC request not allowed at this time. Invalid state transition. |
| AST_CC_AGENT_RESPONSE_FAILURE_TOO_MANY | Too many CC requests in the system. |
Definition at line 861 of file ccss.h.
00861 { 00862 /*! CC request accepted */ 00863 AST_CC_AGENT_RESPONSE_SUCCESS, 00864 /*! CC request not allowed at this time. Invalid state transition. */ 00865 AST_CC_AGENT_RESPONSE_FAILURE_INVALID, 00866 /*! Too many CC requests in the system. */ 00867 AST_CC_AGENT_RESPONSE_FAILURE_TOO_MANY, 00868 };
| 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 | |||
| ) | [read] |
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 665 of file ccss.c.
References __ast_malloc(), ast_cc_default_config_params(), and ast_malloc.
00666 { 00667 #if defined(__AST_DEBUG_MALLOC) 00668 struct ast_cc_config_params *params = __ast_malloc(sizeof(*params), file, line, function); 00669 #else 00670 struct ast_cc_config_params *params = ast_malloc(sizeof(*params)); 00671 #endif 00672 00673 if (!params) { 00674 return NULL; 00675 } 00676 00677 ast_cc_default_config_params(params); 00678 return params; 00679 }
| int ast_cc_agent_accept_request | ( | int | core_id, | |
| const char *const | debug, | |||
| ... | ||||
| ) |
Accept inbound CC request.
| core_id | core_id of the CC transaction | |
| debug | optional string to print for debugging purposes |
| 0 | Success | |
| -1 | Failure |
Definition at line 3616 of file ccss.c.
References CC_CALLER_REQUESTED, and cc_request_state_change().
Referenced by ccreq_exec(), and handle_cc_subscribe().
03617 { 03618 va_list ap; 03619 int res; 03620 03621 va_start(ap, debug); 03622 res = cc_request_state_change(CC_CALLER_REQUESTED, core_id, debug, ap); 03623 va_end(ap); 03624 return res; 03625 }
| struct ast_cc_agent* ast_cc_agent_callback | ( | int | flags, | |
| ao2_callback_fn * | function, | |||
| void * | arg, | |||
| const char *const | type | |||
| ) | [read] |
Call a callback on all agents of a specific type.
Since the container of CC core instances is private, and so are the items which the container contains, we have to provide an ao2_callback-like method so that a specific agent may be found or so that an operation can be made on all agents of a particular type. The first three arguments should be familiar to anyone who has used ao2_callback. The final argument is the type of agent you wish to have the callback called on.
| flags | astobj2 search flags | |
| function | an ao2 callback function to call | |
| arg | the argument to the callback function | |
| type | The type of agents to call the callback on |
Definition at line 443 of file ccss.c.
References cc_core_instance::agent, ao2_t_callback, cc_agent_callback_helper(), cc_ref(), cc_unref(), and cc_callback_helper::function.
Referenced by find_sip_cc_agent_by_notify_uri(), find_sip_cc_agent_by_original_callid(), and find_sip_cc_agent_by_subscribe_uri().
00444 { 00445 struct cc_callback_helper helper = {.function = function, .args = args, .type = type}; 00446 struct cc_core_instance *core_instance; 00447 if ((core_instance = ao2_t_callback(cc_core_instances, flags, cc_agent_callback_helper, &helper, 00448 "Calling provided agent callback function"))) { 00449 struct ast_cc_agent *agent = cc_ref(core_instance->agent, "An outside entity needs the agent"); 00450 cc_unref(core_instance, "agent callback done with the core_instance"); 00451 return agent; 00452 } 00453 return NULL; 00454 }
| int ast_cc_agent_caller_available | ( | int | core_id, | |
| const char *const | debug, | |||
| ... | ||||
| ) |
Indicate that a previously unavailable caller has become available.
| core_id | core_id of the CC transaction | |
| debug | optional string to print for debugging purposes |
| 0 | Success | |
| -1 | Failure |
Definition at line 3660 of file ccss.c.
References CC_ACTIVE, and cc_request_state_change().
Referenced by generic_agent_devstate_cb().
03661 { 03662 va_list ap; 03663 int res; 03664 03665 va_start(ap, debug); 03666 res = cc_request_state_change(CC_ACTIVE, core_id, debug, ap); 03667 va_end(ap); 03668 return res; 03669 }
| int ast_cc_agent_caller_busy | ( | int | core_id, | |
| const char *const | debug, | |||
| ... | ||||
| ) |
Indicate that the caller is busy.
| core_id | core_id of the CC transaction | |
| debug | optional string to print for debugging purposes |
| 0 | Success | |
| -1 | Failure |
Definition at line 3649 of file ccss.c.
References CC_CALLER_BUSY, and cc_request_state_change().
Referenced by cc_generic_agent_recall(), and sip_cc_agent_recall().
03650 { 03651 va_list ap; 03652 int res; 03653 03654 va_start(ap, debug); 03655 res = cc_request_state_change(CC_CALLER_BUSY, core_id, debug, ap); 03656 va_end(ap); 03657 return res; 03658 }
| int ast_cc_agent_recalling | ( | int | core_id, | |
| const char *const | debug, | |||
| ... | ||||
| ) |
Tell the CC core that a caller is currently recalling.
| core_id | core_id of the CC transaction | |
| debug | optional string to print for debugging purposes |
| 0 | Success | |
| -1 | Failure |
Definition at line 3671 of file ccss.c.
References CC_RECALLING, and cc_request_state_change().
Referenced by generic_recall(), and get_destination().
03672 { 03673 va_list ap; 03674 int res; 03675 03676 va_start(ap, debug); 03677 res = cc_request_state_change(CC_RECALLING, core_id, debug, ap); 03678 va_end(ap); 03679 return res; 03680 }
| int ast_cc_agent_register | ( | const struct ast_cc_agent_callbacks * | callbacks | ) |
Register a set of agent callbacks with the core.
| callbacks | The callbacks used by the agent implementation |
| 0 | Successfully registered | |
| -1 | Failure to register |
Definition at line 1052 of file ccss.c.
References ast_calloc, AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and cc_agent_backend::callbacks.
Referenced by ast_cc_init(), and load_module().
01053 { 01054 struct cc_agent_backend *backend = ast_calloc(1, sizeof(*backend)); 01055 01056 if (!backend) { 01057 return -1; 01058 } 01059 01060 backend->callbacks = callbacks; 01061 AST_RWLIST_WRLOCK(&cc_agent_backends); 01062 AST_RWLIST_INSERT_TAIL(&cc_agent_backends, backend, next); 01063 AST_RWLIST_UNLOCK(&cc_agent_backends); 01064 return 0; 01065 }
| int ast_cc_agent_set_interfaces_chanvar | ( | struct ast_channel * | chan | ) |
Set the first level CC_INTERFACES channel variable for a channel.
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 3471 of file ccss.c.
References ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_free, AST_LIST_FIRST, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log_dynamic_level, ast_str_buffer(), ast_str_create(), build_cc_interfaces_chanvar(), cc_recall_ds_data::core_id, ast_datastore::data, cc_recall_ds_data::interface_tree, monitor, pbx_builtin_setvar_helper(), and str.
Referenced by generic_recall(), and handle_request_invite().
03472 { 03473 struct ast_datastore *recall_datastore; 03474 struct cc_monitor_tree *interface_tree; 03475 struct ast_cc_monitor *monitor; 03476 struct cc_recall_ds_data *recall_data; 03477 struct ast_str *str = ast_str_create(64); 03478 int core_id; 03479 03480 if (!str) { 03481 return -1; 03482 } 03483 03484 ast_channel_lock(chan); 03485 if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) { 03486 ast_channel_unlock(chan); 03487 ast_free(str); 03488 return -1; 03489 } 03490 recall_data = recall_datastore->data; 03491 interface_tree = recall_data->interface_tree; 03492 core_id = recall_data->core_id; 03493 ast_channel_unlock(chan); 03494 03495 AST_LIST_LOCK(interface_tree); 03496 monitor = AST_LIST_FIRST(interface_tree); 03497 build_cc_interfaces_chanvar(monitor, str); 03498 AST_LIST_UNLOCK(interface_tree); 03499 03500 pbx_builtin_setvar_helper(chan, "CC_INTERFACES", ast_str_buffer(str)); 03501 ast_log_dynamic_level(cc_logger_level, "Core %d: CC_INTERFACES set to %s\n", 03502 core_id, ast_str_buffer(str)); 03503 03504 ast_free(str); 03505 return 0; 03506 }
| int ast_cc_agent_status_response | ( | int | core_id, | |
| enum ast_device_state | devstate | |||
| ) |
Response with a caller's current status.
When an ISDN PTMP monitor requests the caller's status, the agent must respond to the request using this function. For simplicity it is recommended that the devstate parameter be one of AST_DEVICE_INUSE or AST_DEVICE_NOT_INUSE.
| 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 3936 of file ccss.c.
References args, ast_calloc, ast_free, ast_taskprocessor_push(), cc_status_response(), cc_unref(), cc_status_response_args::core_instance, cc_status_response_args::devstate, and find_cc_core_instance().
Referenced by cc_generic_agent_status_request(), and sip_cc_agent_status_request().
03937 { 03938 struct cc_status_response_args *args; 03939 struct cc_core_instance *core_instance; 03940 int res; 03941 03942 args = ast_calloc(1, sizeof(*args)); 03943 if (!args) { 03944 return -1; 03945 } 03946 03947 core_instance = find_cc_core_instance(core_id); 03948 if (!core_instance) { 03949 ast_free(args); 03950 return -1; 03951 } 03952 03953 args->core_instance = core_instance; 03954 args->devstate = devstate; 03955 03956 res = ast_taskprocessor_push(cc_core_taskprocessor, cc_status_response, args); 03957 if (res) { 03958 cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed"); 03959 ast_free(args); 03960 } 03961 return res; 03962 }
| void ast_cc_agent_unregister | ( | const struct ast_cc_agent_callbacks * | callbacks | ) |
Unregister a set of agent callbacks with the core.
| callbacks | The callbacks used by the agent implementation |
| 0 | Successfully unregistered | |
| -1 | Failure to unregister |
Definition at line 1067 of file ccss.c.
References ast_free, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, cc_agent_backend::callbacks, and cc_monitor_backend::next.
Referenced by __unload_module(), and unload_module().
01068 { 01069 struct cc_agent_backend *backend; 01070 AST_RWLIST_WRLOCK(&cc_agent_backends); 01071 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&cc_agent_backends, backend, next) { 01072 if (backend->callbacks == callbacks) { 01073 AST_RWLIST_REMOVE_CURRENT(next); 01074 ast_free(backend); 01075 break; 01076 } 01077 } 01078 AST_RWLIST_TRAVERSE_SAFE_END; 01079 AST_RWLIST_UNLOCK(&cc_agent_backends); 01080 }
| int ast_cc_available_timer_expire | ( | const void * | data | ) |
Scheduler callback for available timer expiration.
| data | A reference to the CC monitor on which the timer was running. |
Definition at line 1335 of file ccss.c.
References ast_cc_monitor_failed(), ast_cc_monitor::available_timer_id, cc_unref(), ast_cc_monitor::core_id, ast_cc_interface::device_name, ast_cc_monitor::interface, and monitor.
Referenced by cc_generic_monitor_request_cc(), and sip_cc_monitor_request_cc().
01336 { 01337 struct ast_cc_monitor *monitor = (struct ast_cc_monitor *) data; 01338 int res; 01339 monitor->available_timer_id = -1; 01340 res = ast_cc_monitor_failed(monitor->core_id, monitor->interface->device_name, "Available timer expired for monitor"); 01341 cc_unref(monitor, "Unref reference from scheduler\n"); 01342 return res; 01343 }
| int ast_cc_build_frame | ( | struct ast_channel * | chan, | |
| struct ast_cc_config_params * | cc_params, | |||
| const char * | monitor_type, | |||
| const char *const | device_name, | |||
| const char *const | dialstring, | |||
| enum ast_cc_service_type | service, | |||
| void * | private_data, | |||
| struct ast_frame * | frame | |||
| ) |
Create a CC Control frame.
| 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 4019 of file ccss.c.
References ast_calloc, AST_CONTROL_CC, AST_FRAME_CONTROL, ast_free, AST_MALLOCD_DATA, cc_build_payload(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, ast_frame_subclass::integer, ast_frame::mallocd, ast_frame::ptr, and ast_frame::subclass.
Referenced by ast_queue_cc_frame().
04023 { 04024 struct cc_control_payload *payload = ast_calloc(1, sizeof(*payload)); 04025 04026 if (!payload) { 04027 return -1; 04028 } 04029 if (cc_build_payload(chan, cc_params, monitor_type, device_name, dialstring, service, private_data, payload)) { 04030 /* Something screwed up, we can't make a frame with this */ 04031 ast_free(payload); 04032 return -1; 04033 } 04034 frame->frametype = AST_FRAME_CONTROL; 04035 frame->subclass.integer = AST_CONTROL_CC; 04036 frame->data.ptr = payload; 04037 frame->datalen = sizeof(*payload); 04038 frame->mallocd = AST_MALLOCD_DATA; 04039 return 0; 04040 }
| void ast_cc_busy_interface | ( | struct ast_channel * | inbound, | |
| struct ast_cc_config_params * | cc_params, | |||
| const char * | monitor_type, | |||
| const char *const | device_name, | |||
| const char *const | dialstring, | |||
| void * | private_data | |||
| ) |
Callback made from ast_cc_callback for certain channel types.
| 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 4075 of file ccss.c.
References AST_CC_CCBS, ast_handle_cc_control_frame(), call_destructor_with_no_monitor(), and cc_build_payload().
Referenced by dial_exec_full().
04077 { 04078 struct cc_control_payload payload; 04079 if (cc_build_payload(inbound, cc_params, monitor_type, device_name, dialstring, AST_CC_CCBS, private_data, &payload)) { 04080 /* Something screwed up. Don't try to handle this payload */ 04081 call_destructor_with_no_monitor(monitor_type, private_data); 04082 return; 04083 } 04084 ast_handle_cc_control_frame(inbound, NULL, &payload); 04085 }
| void ast_cc_call_failed | ( | struct ast_channel * | incoming, | |
| struct ast_channel * | outgoing, | |||
| const char *const | dialstring | |||
| ) |
Make CCBS available in the case that ast_call fails.
Definition at line 4042 of file ccss.c.
References AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CC_CCBS, AST_CC_GENERIC_MONITOR_TYPE, AST_CC_MONITOR_GENERIC, ast_channel_get_cc_config_params(), ast_channel_get_device_name(), AST_CHANNEL_NAME, ast_get_cc_monitor_policy(), ast_handle_cc_control_frame(), cc_build_payload(), and ast_channel::hangupcause.
Referenced by dial_exec_full().
04043 { 04044 char device_name[AST_CHANNEL_NAME]; 04045 struct cc_control_payload payload; 04046 struct ast_cc_config_params *cc_params; 04047 04048 if (outgoing->hangupcause != AST_CAUSE_BUSY && outgoing->hangupcause != AST_CAUSE_CONGESTION) { 04049 /* It doesn't make sense to try to offer CCBS to the caller if the reason for ast_call 04050 * failing is something other than busy or congestion 04051 */ 04052 return; 04053 } 04054 04055 cc_params = ast_channel_get_cc_config_params(outgoing); 04056 if (!cc_params) { 04057 return; 04058 } 04059 if (ast_get_cc_monitor_policy(cc_params) != AST_CC_MONITOR_GENERIC) { 04060 /* This sort of CCBS only works if using generic CC. For native, we would end up sending 04061 * a CC request for a non-existent call. The far end will reject this every time 04062 */ 04063 return; 04064 } 04065 04066 ast_channel_get_device_name(outgoing, device_name, sizeof(device_name)); 04067 if (cc_build_payload(outgoing, cc_params, AST_CC_GENERIC_MONITOR_TYPE, device_name, 04068 dialstring, AST_CC_CCBS, NULL, &payload)) { 04069 /* Something screwed up, we can't make a frame with this */ 04070 return; 04071 } 04072 ast_handle_cc_control_frame(incoming, outgoing, &payload); 04073 }
| int ast_cc_call_init | ( | struct ast_channel * | chan, | |
| int * | ignore_cc | |||
| ) |
Start the CC process on a call.
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 2242 of file ccss.c.
References AST_CC_AGENT_NEVER, ast_channel_datastore_find(), ast_channel_get_cc_config_params(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_get_cc_agent_policy(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log_dynamic_level, cc_extension_monitor_init(), cc_interfaces_datastore_init(), cc_ref(), cc_unref(), ast_channel::context, dialed_cc_interfaces::core_id, ast_cc_monitor::core_id, ast_datastore::data, dialed_cc_interfaces::dial_parent_id, ast_channel::exten, ast_cc_monitor::id, dialed_cc_interfaces::ignore, dialed_cc_interfaces::interface_tree, interfaces, ast_channel::macrocontext, ast_channel::macroexten, monitor, and S_OR.
Referenced by dial_exec_full().
02243 { 02244 /* There are three situations to deal with here: 02245 * 02246 * 1. The channel does not have a dialed_cc_interfaces datastore on 02247 * it. This means that this is the first time that Dial has 02248 * been called. We need to create/initialize the datastore. 02249 * 02250 * 2. The channel does have a cc_interface datastore on it and 02251 * the "ignore" indicator is 0. This means that a Local channel 02252 * was called by a "parent" dial. We can check the datastore's 02253 * parent field to see who the root of this particular dial tree 02254 * is. 02255 * 02256 * 3. The channel does have a cc_interface datastore on it and 02257 * the "ignore" indicator is 1. This means that a second Dial call 02258 * is being made from an extension. In this case, we do not 02259 * want to make any additions/modifications to the datastore. We 02260 * will instead set a flag to indicate that CCSS is completely 02261 * disabled for this Dial attempt. 02262 */ 02263 02264 struct ast_datastore *cc_interfaces_datastore; 02265 struct dialed_cc_interfaces *interfaces; 02266 struct ast_cc_monitor *monitor; 02267 struct ast_cc_config_params *cc_params; 02268 02269 ast_channel_lock(chan); 02270 02271 cc_params = ast_channel_get_cc_config_params(chan); 02272 if (!cc_params) { 02273 ast_channel_unlock(chan); 02274 return -1; 02275 } 02276 if (ast_get_cc_agent_policy(cc_params) == AST_CC_AGENT_NEVER) { 02277 /* We can't offer CC to this caller anyway, so don't bother with CC on this call 02278 */ 02279 *ignore_cc = 1; 02280 ast_channel_unlock(chan); 02281 ast_log_dynamic_level(cc_logger_level, "Agent policy for %s is 'never'. CC not possible\n", ast_channel_name(chan)); 02282 return 0; 02283 } 02284 02285 if (!(cc_interfaces_datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL))) { 02286 /* Situation 1 has occurred */ 02287 ast_channel_unlock(chan); 02288 return cc_interfaces_datastore_init(chan); 02289 } 02290 interfaces = cc_interfaces_datastore->data; 02291 ast_channel_unlock(chan); 02292 02293 if (interfaces->ignore) { 02294 /* Situation 3 has occurred */ 02295 *ignore_cc = 1; 02296 ast_log_dynamic_level(cc_logger_level, "Datastore is present with ignore flag set. Ignoring CC offers on this call\n"); 02297 return 0; 02298 } 02299 02300 /* Situation 2 has occurred */ 02301 if (!(monitor = cc_extension_monitor_init(S_OR(chan->macroexten, chan->exten), 02302 S_OR(chan->macrocontext, chan->context), interfaces->dial_parent_id))) { 02303 return -1; 02304 } 02305 monitor->core_id = interfaces->core_id; 02306 AST_LIST_LOCK(interfaces->interface_tree); 02307 cc_ref(monitor, "monitor tree's reference to the monitor"); 02308 AST_LIST_INSERT_TAIL(interfaces->interface_tree, monitor, next); 02309 AST_LIST_UNLOCK(interfaces->interface_tree); 02310 interfaces->dial_parent_id = monitor->id; 02311 cc_unref(monitor, "Unref monitor's allocation reference"); 02312 return 0; 02313 }
| int ast_cc_callback | ( | struct ast_channel * | inbound, | |
| const char *const | tech, | |||
| const char *const | dest, | |||
| ast_cc_callback_fn | callback | |||
| ) |
Run a callback for potential matching destinations.
| 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 4087 of file ccss.c.
References ast_get_channel_tech(), and ast_channel_tech::cc_callback.
Referenced by dial_exec_full().
04088 { 04089 const struct ast_channel_tech *chantech = ast_get_channel_tech(tech); 04090 04091 if (chantech && chantech->cc_callback) { 04092 chantech->cc_callback(inbound, dest, callback); 04093 } 04094 04095 return 0; 04096 }
| int ast_cc_completed | ( | struct ast_channel * | chan, | |
| const char *const | debug, | |||
| ... | ||||
| ) |
Indicate recall has been acknowledged.
| chan | The inbound channel making the CC recall | |
| debug | optional string to print for debugging purposes |
| 0 | Success | |
| -1 | Failure |
Definition at line 3682 of file ccss.c.
References ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, CC_COMPLETE, cc_request_state_change(), cc_recall_ds_data::core_id, ast_datastore::data, cc_recall_ds_data::ignore, and cc_recall_ds_data::nested.
Referenced by wait_for_answer().
03683 { 03684 struct ast_datastore *recall_datastore; 03685 struct cc_recall_ds_data *recall_data; 03686 int core_id; 03687 va_list ap; 03688 int res; 03689 03690 ast_channel_lock(chan); 03691 if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) { 03692 /* Silly! Why did you call this function if there's no recall DS? */ 03693 ast_channel_unlock(chan); 03694 return -1; 03695 } 03696 recall_data = recall_datastore->data; 03697 if (recall_data->nested || recall_data->ignore) { 03698 /* If this is being called from a nested Dial, it is too 03699 * early to determine if the recall has actually completed. 03700 * The outermost dial is the only one with the authority to 03701 * declare the recall to be complete. 03702 * 03703 * Similarly, if this function has been called when the 03704 * recall has progressed beyond the first dial, this is not 03705 * a legitimate time to declare the recall to be done. In fact, 03706 * that should have been done already. 03707 */ 03708 ast_channel_unlock(chan); 03709 return -1; 03710 } 03711 core_id = recall_data->core_id; 03712 ast_channel_unlock(chan); 03713 va_start(ap, debug); 03714 res = cc_request_state_change(CC_COMPLETE, core_id, debug, ap); 03715 va_end(ap); 03716 return res; 03717 }
| void ast_cc_config_params_destroy | ( | struct ast_cc_config_params * | params | ) |
Free memory from CCSS configuration params.
| params | Pointer to structure whose memory we need to free |
| void |
Definition at line 681 of file ccss.c.
References ast_free.
Referenced by __sip_destroy(), agent_destroy(), ast_channel_cc_params_init(), cc_interface_destroy(), channel_cc_params_destroy(), destroy_dahdi_pvt(), process_dahdi(), setup_dahdi(), and sip_destroy_peer().
00682 { 00683 ast_free(params); 00684 }
| void ast_cc_copy_config_params | ( | struct ast_cc_config_params * | dest, | |
| const struct ast_cc_config_params * | src | |||
| ) |
copy CCSS configuration parameters from one structure to another
| src | The structure from which data is copied | |
| dest | The structure to which data is copied |
Definition at line 843 of file ccss.c.
Referenced by ast_channel_cc_params_init(), cc_agent_init(), cc_build_payload(), cc_device_monitor_init(), channel_cc_params_copy(), check_peer_ok(), create_addr_from_peer(), dahdi_new(), deep_copy_dahdi_chan_conf(), duplicate_pseudo(), and mkintf().
| 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 660 of file ccss.c.
Referenced by __ast_cc_config_params_init().
00661 { 00662 *params = cc_default_params; 00663 }
| void ast_cc_extension_monitor_add_dialstring | ( | struct ast_channel * | incoming, | |
| const char *const | dialstring, | |||
| const char *const | device_name | |||
| ) |
Add a child dialstring to an extension monitor.
| 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 1831 of file ccss.c.
References ast_calloc, ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, extension_monitor_pvt::child_dialstrings, ast_datastore::data, extension_child_dialstring::device_name, dialed_cc_interfaces::dial_parent_id, ast_cc_monitor::id, id, dialed_cc_interfaces::interface_tree, extension_child_dialstring::is_valid, monitor, extension_child_dialstring::original_dialstring, and ast_cc_monitor::private_data.
Referenced by dial_exec_full().
01832 { 01833 struct ast_datastore *cc_datastore; 01834 struct dialed_cc_interfaces *cc_interfaces; 01835 struct ast_cc_monitor *monitor; 01836 struct extension_monitor_pvt *extension_pvt; 01837 struct extension_child_dialstring *child_dialstring; 01838 struct cc_monitor_tree *interface_tree; 01839 int id; 01840 01841 ast_channel_lock(incoming); 01842 if (!(cc_datastore = ast_channel_datastore_find(incoming, &dialed_cc_interfaces_info, NULL))) { 01843 ast_channel_unlock(incoming); 01844 return; 01845 } 01846 01847 cc_interfaces = cc_datastore->data; 01848 interface_tree = cc_interfaces->interface_tree; 01849 id = cc_interfaces->dial_parent_id; 01850 ast_channel_unlock(incoming); 01851 01852 AST_LIST_LOCK(interface_tree); 01853 AST_LIST_TRAVERSE(interface_tree, monitor, next) { 01854 if (monitor->id == id) { 01855 break; 01856 } 01857 } 01858 01859 if (!monitor) { 01860 AST_LIST_UNLOCK(interface_tree); 01861 return; 01862 } 01863 01864 extension_pvt = monitor->private_data; 01865 if (!(child_dialstring = ast_calloc(1, sizeof(*child_dialstring)))) { 01866 AST_LIST_UNLOCK(interface_tree); 01867 return; 01868 } 01869 ast_copy_string(child_dialstring->original_dialstring, dialstring, sizeof(child_dialstring->original_dialstring)); 01870 ast_copy_string(child_dialstring->device_name, device_name, sizeof(child_dialstring->device_name)); 01871 child_dialstring->is_valid = 1; 01872 AST_LIST_INSERT_TAIL(&extension_pvt->child_dialstrings, child_dialstring, next); 01873 AST_LIST_UNLOCK(interface_tree); 01874 }
| int ast_cc_failed | ( | int | core_id, | |
| const char *const | debug, | |||
| ... | ||||
| ) |
Indicate failure has occurred.
| core_id | core_id of the CC transaction | |
| debug | optional string to print for debugging purposes |
| 0 | Success | |
| -1 | Failure |
Definition at line 3719 of file ccss.c.
References CC_FAILED, and cc_request_state_change().
Referenced by cancel_available_timer(), cc_caller_offered(), cc_caller_requested(), cc_monitor_failed(), cccancel_exec(), ccreq_exec(), generic_recall(), handle_cc_subscribe(), kill_cores(), offer_timer_expire(), request_cc(), sip_offer_timer_expire(), suspend(), unsuspend(), and wait_for_answer().
03720 { 03721 va_list ap; 03722 int res; 03723 03724 va_start(ap, debug); 03725 res = cc_request_state_change(CC_FAILED, core_id, debug, ap); 03726 va_end(ap); 03727 return res; 03728 }
| int ast_cc_get_current_core_id | ( | struct ast_channel * | chan | ) |
Get the core id for the current call.
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 2320 of file ccss.c.
References ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, dialed_cc_interfaces::core_id, ast_datastore::data, and dialed_cc_interfaces::ignore.
Referenced by sip_handle_cc().
02321 { 02322 struct ast_datastore *datastore; 02323 struct dialed_cc_interfaces *cc_interfaces; 02324 int core_id_return; 02325 02326 ast_channel_lock(chan); 02327 if (!(datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL))) { 02328 ast_channel_unlock(chan); 02329 return -1; 02330 } 02331 02332 cc_interfaces = datastore->data; 02333 core_id_return = cc_interfaces->ignore ? -1 : cc_interfaces->core_id; 02334 ast_channel_unlock(chan); 02335 return core_id_return; 02336 02337 }
| struct ast_cc_monitor* ast_cc_get_monitor_by_recall_core_id | ( | const int | core_id, | |
| const char *const | device_name | |||
| ) | [read] |
Get the associated monitor given the device name and core_id.
| 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 3359 of file ccss.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, cc_ref(), cc_unref(), ast_cc_interface::device_name, find_cc_core_instance(), ast_cc_monitor::interface, and cc_core_instance::monitors.
Referenced by sip_call().
03360 { 03361 struct cc_core_instance *core_instance = find_cc_core_instance(core_id); 03362 struct ast_cc_monitor *monitor_iter; 03363 03364 if (!core_instance) { 03365 return NULL; 03366 } 03367 03368 AST_LIST_LOCK(core_instance->monitors); 03369 AST_LIST_TRAVERSE(core_instance->monitors, monitor_iter, next) { 03370 if (!strcmp(monitor_iter->interface->device_name, device_name)) { 03371 /* Found a monitor. */ 03372 cc_ref(monitor_iter, "Hand the requester of the monitor a reference"); 03373 break; 03374 } 03375 } 03376 AST_LIST_UNLOCK(core_instance->monitors); 03377 cc_unref(core_instance, "Done with core instance ref in ast_cc_get_monitor_by_recall_core_id"); 03378 return monitor_iter; 03379 }
| int ast_cc_get_param | ( | struct ast_cc_config_params * | params, | |
| const char *const | name, | |||
| char * | buf, | |||
| size_t | buf_len | |||
| ) |
get a CCSS configuration parameter, given its name
| 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 747 of file ccss.c.
References agent_policy_to_str(), ast_copy_string(), ast_get_cc_agent_dialstring(), ast_get_cc_agent_policy(), ast_get_cc_callback_macro(), ast_get_cc_max_agents(), ast_get_cc_max_monitors(), ast_get_cc_monitor_policy(), ast_get_cc_offer_timer(), ast_get_cc_recall_timer(), ast_get_ccbs_available_timer(), ast_get_ccnr_available_timer(), ast_log(), LOG_WARNING, monitor_policy_to_str(), and value.
Referenced by acf_cc_read().
00749 { 00750 const char *value = NULL; 00751 00752 if (!strcasecmp(name, "cc_callback_macro")) { 00753 value = ast_get_cc_callback_macro(params); 00754 } else if (!strcasecmp(name, "cc_agent_policy")) { 00755 value = agent_policy_to_str(ast_get_cc_agent_policy(params)); 00756 } else if (!strcasecmp(name, "cc_monitor_policy")) { 00757 value = monitor_policy_to_str(ast_get_cc_monitor_policy(params)); 00758 } else if (!strcasecmp(name, "cc_agent_dialstring")) { 00759 value = ast_get_cc_agent_dialstring(params); 00760 } 00761 if (value) { 00762 ast_copy_string(buf, value, buf_len); 00763 return 0; 00764 } 00765 00766 /* The rest of these are all ints of some sort and require some 00767 * snprintf-itude 00768 */ 00769 00770 if (!strcasecmp(name, "cc_offer_timer")) { 00771 snprintf(buf, buf_len, "%u", ast_get_cc_offer_timer(params)); 00772 } else if (!strcasecmp(name, "ccnr_available_timer")) { 00773 snprintf(buf, buf_len, "%u", ast_get_ccnr_available_timer(params)); 00774 } else if (!strcasecmp(name, "ccbs_available_timer")) { 00775 snprintf(buf, buf_len, "%u", ast_get_ccbs_available_timer(params)); 00776 } else if (!strcasecmp(name, "cc_max_agents")) { 00777 snprintf(buf, buf_len, "%u", ast_get_cc_max_agents(params)); 00778 } else if (!strcasecmp(name, "cc_max_monitors")) { 00779 snprintf(buf, buf_len, "%u", ast_get_cc_max_monitors(params)); 00780 } else if (!strcasecmp(name, "cc_recall_timer")) { 00781 snprintf(buf, buf_len, "%u", ast_get_cc_recall_timer(params)); 00782 } else { 00783 ast_log(LOG_WARNING, "%s is not a valid CC parameter. Ignoring.\n", name); 00784 return -1; 00785 } 00786 00787 return 0; 00788 }
| int ast_cc_init | ( | void | ) |
Initialize CCSS.
| 0 | Success | |
| nonzero | Failure |
Definition at line 4472 of file ccss.c.
References ao2_t_container_alloc, ARRAY_LEN, ast_cc_agent_register(), ast_cc_monitor_register(), ast_cli_register_multiple(), ast_devstate_prov_add(), ast_logger_register_level(), ast_register_application2(), ast_sched_context_create(), ast_sched_start_thread(), ast_taskprocessor_get(), cc_core_instance_cmp_fn(), cc_core_instance_hash_fn(), cccancel_exec(), ccreq_exec(), ccss_device_state(), generic_monitor_cbs, generic_monitor_cmp_fn(), generic_monitor_hash_fn(), generic_monitors, initialize_cc_devstate_map(), initialize_cc_max_requests(), and TPS_REF_DEFAULT.
Referenced by main().
04473 { 04474 int res; 04475 04476 if (!(cc_core_instances = ao2_t_container_alloc(CC_CORE_INSTANCES_BUCKETS, 04477 cc_core_instance_hash_fn, cc_core_instance_cmp_fn, 04478 "Create core instance container"))) { 04479 return -1; 04480 } 04481 if (!(generic_monitors = ao2_t_container_alloc(CC_CORE_INSTANCES_BUCKETS, 04482 generic_monitor_hash_fn, generic_monitor_cmp_fn, 04483 "Create generic monitor container"))) { 04484 return -1; 04485 } 04486 if (!(cc_core_taskprocessor = ast_taskprocessor_get("CCSS core", TPS_REF_DEFAULT))) { 04487 return -1; 04488 } 04489 if (!(cc_sched_context = ast_sched_context_create())) { 04490 return -1; 04491 } 04492 if (ast_sched_start_thread(cc_sched_context)) { 04493 return -1; 04494 } 04495 res = ast_register_application2(ccreq_app, ccreq_exec, NULL, NULL, NULL); 04496 res |= ast_register_application2(cccancel_app, cccancel_exec, NULL, NULL, NULL); 04497 res |= ast_cc_monitor_register(&generic_monitor_cbs); 04498 res |= ast_cc_agent_register(&generic_agent_callbacks); 04499 04500 ast_cli_register_multiple(cc_cli, ARRAY_LEN(cc_cli)); 04501 cc_logger_level = ast_logger_register_level(CC_LOGGER_LEVEL_NAME); 04502 dialed_cc_interface_counter = 1; 04503 initialize_cc_max_requests(); 04504 04505 /* Read the map and register the device state callback for generic agents */ 04506 initialize_cc_devstate_map(); 04507 res |= ast_devstate_prov_add("ccss", ccss_device_state); 04508 04509 return res; 04510 }
| int ast_cc_is_config_param | ( | const char *const | name | ) |
Is this a CCSS configuration parameter?
| 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 829 of file ccss.c.
Referenced by build_peer(), and process_dahdi().
00830 { 00831 return (!strcasecmp(name, "cc_agent_policy") || 00832 !strcasecmp(name, "cc_monitor_policy") || 00833 !strcasecmp(name, "cc_offer_timer") || 00834 !strcasecmp(name, "ccnr_available_timer") || 00835 !strcasecmp(name, "ccbs_available_timer") || 00836 !strcasecmp(name, "cc_max_agents") || 00837 !strcasecmp(name, "cc_max_monitors") || 00838 !strcasecmp(name, "cc_callback_macro") || 00839 !strcasecmp(name, "cc_agent_dialstring") || 00840 !strcasecmp(name, "cc_recall_timer")); 00841 }
| int ast_cc_is_recall | ( | struct ast_channel * | chan, | |
| int * | core_id, | |||
| const char *const | monitor_type | |||
| ) |
Decide if a call to a particular channel is a CC recall.
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 3278 of file ccss.c.
References ast_assert, ast_channel_datastore_find(), ast_channel_get_device_name(), ast_channel_lock, AST_CHANNEL_NAME, ast_channel_unlock, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), cc_recall_ds_data::core_id, ast_datastore::data, ast_cc_interface::device_name, cc_recall_ds_data::ignore, ast_cc_monitor::interface, cc_recall_ds_data::interface_tree, ast_cc_interface::monitor_type, and cc_recall_ds_data::nested.
Referenced by cc_core_init_instance(), sip_call(), and wait_for_answer().
03279 { 03280 struct ast_datastore *recall_datastore; 03281 struct cc_recall_ds_data *recall_data; 03282 struct cc_monitor_tree *interface_tree; 03283 char device_name[AST_CHANNEL_NAME]; 03284 struct ast_cc_monitor *device_monitor; 03285 int core_id_candidate; 03286 03287 ast_assert(core_id != NULL); 03288 03289 *core_id = -1; 03290 03291 ast_channel_lock(chan); 03292 if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) { 03293 /* Obviously not a recall if the datastore isn't present */ 03294 ast_channel_unlock(chan); 03295 return 0; 03296 } 03297 03298 recall_data = recall_datastore->data; 03299 03300 if (recall_data->ignore) { 03301 /* Though this is a recall, the call to this particular interface is not part of the 03302 * recall either because this is a call forward or because this is not the first 03303 * invocation of Dial during this call 03304 */ 03305 ast_channel_unlock(chan); 03306 return 0; 03307 } 03308 03309 if (!recall_data->nested) { 03310 /* If the nested flag is not set, then this means that 03311 * the channel passed to this function is the caller making 03312 * the recall. This means that we shouldn't look through 03313 * the monitor tree for the channel because it shouldn't be 03314 * there. However, this is a recall though, so return true. 03315 */ 03316 *core_id = recall_data->core_id; 03317 ast_channel_unlock(chan); 03318 return 1; 03319 } 03320 03321 if (ast_strlen_zero(monitor_type)) { 03322 /* If someone passed a NULL or empty monitor type, then it is clear 03323 * the channel they passed in was an incoming channel, and so searching 03324 * the list of dialed interfaces is not going to be helpful. Just return 03325 * false immediately. 03326 */ 03327 ast_channel_unlock(chan); 03328 return 0; 03329 } 03330 03331 interface_tree = recall_data->interface_tree; 03332 ast_channel_get_device_name(chan, device_name, sizeof(device_name)); 03333 /* We grab the value of the recall_data->core_id so that we 03334 * can unlock the channel before we start looking through the 03335 * interface list. That way we don't have to worry about a possible 03336 * clash between the channel lock and the monitor tree lock. 03337 */ 03338 core_id_candidate = recall_data->core_id; 03339 ast_channel_unlock(chan); 03340 03341 /* 03342 * Now we need to find out if the channel device name 03343 * is in the list of interfaces in the called tree. 03344 */ 03345 AST_LIST_LOCK(interface_tree); 03346 AST_LIST_TRAVERSE(interface_tree, device_monitor, next) { 03347 if (!strcmp(device_monitor->interface->device_name, device_name) && 03348 !strcmp(device_monitor->interface->monitor_type, monitor_type)) { 03349 /* BOOM! Device is in the tree! We have a winner! */ 03350 *core_id = core_id_candidate; 03351 AST_LIST_UNLOCK(interface_tree); 03352 return 1; 03353 } 03354 } 03355 AST_LIST_UNLOCK(interface_tree); 03356 return 0; 03357 }
| int ast_cc_monitor_callee_available | ( | const int | core_id, | |
| const char *const | debug, | |||
| ... | ||||
| ) |
Alert the core that a device being monitored has become available.
| core_id | The core ID of the corresponding CC transaction | |
| debug |
| 0 | Request successfully queued | |
| -1 | Request could not be queued |
Definition at line 3638 of file ccss.c.
References CC_CALLEE_READY, and cc_request_state_change().
Referenced by cc_generic_monitor_destructor(), cc_generic_monitor_suspend(), cc_generic_monitor_unsuspend(), generic_monitor_devstate_tp_cb(), and handle_cc_notify().
03639 { 03640 va_list ap; 03641 int res; 03642 03643 va_start(ap, debug); 03644 res = cc_request_state_change(CC_CALLEE_READY, core_id, debug, ap); 03645 va_end(ap); 03646 return res; 03647 }
| int ast_cc_monitor_count | ( | const char *const | name, | |
| const char *const | type | |||
| ) |
Return the number of outstanding CC requests to a specific device.
| name | The name of the monitored device | |
| type | The type of the monitored device (e.g. "generic") |
Definition at line 4211 of file ccss.c.
References ao2_t_callback, ast_log_dynamic_level, count_monitors_cb_data::count, count_monitors_cb(), count_monitors_cb_data::device_name, and OBJ_NODATA.
Referenced by ast_queue_cc_frame().
04212 { 04213 struct count_monitors_cb_data data = {.device_name = name, .monitor_type = type,}; 04214 04215 ao2_t_callback(cc_core_instances, OBJ_NODATA, count_monitors_cb, &data, "Counting agents"); 04216 ast_log_dynamic_level(cc_logger_level, "Counted %d monitors\n", data.count); 04217 return data.count; 04218 }
| int ast_cc_monitor_failed | ( | int | core_id, | |
| const char *const | monitor_name, | |||
| const char *const | debug, | |||
| ... | ||||
| ) |
Indicate that a failure has occurred on a specific monitor.
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 3784 of file ccss.c.
References ast_calloc, ast_free, ast_strdup, ast_taskprocessor_push(), ast_vasprintf, cc_monitor_failed(), ast_cc_monitor_failure_data::core_id, ast_cc_monitor_failure_data::debug, and ast_cc_monitor_failure_data::device_name.
Referenced by ast_cc_available_timer_expire(), cc_handle_publish_error(), and handle_response_subscribe().
03785 { 03786 struct ast_cc_monitor_failure_data *failure_data; 03787 int res; 03788 va_list ap; 03789 03790 if (!(failure_data = ast_calloc(1, sizeof(*failure_data)))) { 03791 return -1; 03792 } 03793 03794 if (!(failure_data->device_name = ast_strdup(monitor_name))) { 03795 ast_free(failure_data); 03796 return -1; 03797 } 03798 03799 va_start(ap, debug); 03800 if (ast_vasprintf(&failure_data->debug, debug, ap) == -1) { 03801 va_end(ap); 03802 ast_free((char *)failure_data->device_name); 03803 ast_free(failure_data); 03804 return -1; 03805 } 03806 va_end(ap); 03807 03808 failure_data->core_id = core_id; 03809 03810 res = ast_taskprocessor_push(cc_core_taskprocessor, cc_monitor_failed, failure_data); 03811 if (res) { 03812 ast_free((char *)failure_data->device_name); 03813 ast_free((char *)failure_data->debug); 03814 ast_free(failure_data); 03815 } 03816 return res; 03817 }
| int ast_cc_monitor_party_b_free | ( | int | core_id | ) |
Alert a caller that though the callee has become free, the caller himself is not and may not call back.
When an ISDN PTMP monitor senses that his monitored party has become available, he will request the status of the called party. If he determines that the caller is currently not available, then he will call this function so that an appropriate message is sent to the caller.
Yes, you just read that correctly. The callee asks the caller what his current status is, and if the caller is currently unavailable, the monitor must send him a message anyway. WTF?
This function results in the agent's party_b_free callback being called. It is most likely that you will not need to actually implement the party_b_free callback in an agent because it is not likely that you will need to or even want to send a caller a message indicating the callee's status if the caller himself is not also free.
| 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 3894 of file ccss.c.
References ast_taskprocessor_push(), cc_party_b_free(), cc_unref(), and find_cc_core_instance().
03895 { 03896 int res; 03897 struct cc_core_instance *core_instance = find_cc_core_instance(core_id); 03898 03899 if (!core_instance) { 03900 return -1; 03901 } 03902 03903 res = ast_taskprocessor_push(cc_core_taskprocessor, cc_party_b_free, core_instance); 03904 if (res) { 03905 cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed"); 03906 } 03907 return res; 03908 }
| int ast_cc_monitor_register | ( | const struct ast_cc_monitor_callbacks * | callbacks | ) |
Register a set of monitor callbacks with the core.
| callbacks | The callbacks used by the monitor implementation |
| 0 | Successfully registered | |
| -1 | Failure to register |
Definition at line 997 of file ccss.c.
References ast_calloc, AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and cc_monitor_backend::callbacks.
Referenced by ast_cc_init(), and load_module().
00998 { 00999 struct cc_monitor_backend *backend = ast_calloc(1, sizeof(*backend)); 01000 01001 if (!backend) { 01002 return -1; 01003 } 01004 01005 backend->callbacks = callbacks; 01006 01007 AST_RWLIST_WRLOCK(&cc_monitor_backends); 01008 AST_RWLIST_INSERT_TAIL(&cc_monitor_backends, backend, next); 01009 AST_RWLIST_UNLOCK(&cc_monitor_backends); 01010 return 0; 01011 }
| int ast_cc_monitor_request_acked | ( | int | core_id, | |
| const char *const | debug, | |||
| ... | ||||
| ) |
Indicate that an outbound entity has accepted our CC request.
| core_id | core_id of the CC transaction | |
| debug | optional string to print for debugging purposes |
| 0 | Success | |
| -1 | Failure |
Definition at line 3627 of file ccss.c.
References CC_ACTIVE, and cc_request_state_change().
Referenced by cc_generic_monitor_request_cc(), cc_stop_ringing(), and handle_cc_notify().
03628 { 03629 va_list ap; 03630 int res; 03631 03632 va_start(ap, debug); 03633 res = cc_request_state_change(CC_ACTIVE, core_id, debug, ap); 03634 va_end(ap); 03635 return res; 03636 }
| int ast_cc_monitor_status_request | ( | int | core_id | ) |
Request the status of a caller or callers.
The following are all functions which are required due to the unique case where Asterisk is acting as the NT side of an ISDN PTMP connection to the caller and as the TE side of an ISDN PTMP connection to the callee. In such a case, there are several times where the PTMP monitor needs information from the agent in order to formulate the appropriate messages to send.
When an ISDN PTMP monitor senses that the callee has become available, it needs to know the current status of the caller in order to determine the appropriate response to send to the caller. In order to do this, the monitor calls this function. Responses will arrive asynchronously.
| core_id | The core ID of the CC transaction |
| 0 | Successfully requested status | |
| -1 | Failed to request status |
Definition at line 3829 of file ccss.c.
References ast_taskprocessor_push(), cc_status_request(), cc_unref(), and find_cc_core_instance().
03830 { 03831 int res; 03832 struct cc_core_instance *core_instance = find_cc_core_instance(core_id); 03833 03834 if (!core_instance) { 03835 return -1; 03836 } 03837 03838 res = ast_taskprocessor_push(cc_core_taskprocessor, cc_status_request, core_instance); 03839 if (res) { 03840 cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed"); 03841 } 03842 return res; 03843 }
| int ast_cc_monitor_stop_ringing | ( | int | core_id | ) |
Alert a caller to stop ringing.
When an ISDN PTMP monitor becomes available, it is assumed that the agent will then cause the caller's phone to ring. In some cases, this is literally what happens. In other cases, it may be that the caller gets a visible indication on his phone that he may attempt to recall the callee. If multiple callers are recalled (since it may be possible to have a group of callers configured as a single party A), and one of those callers picks up his phone, then the ISDN PTMP monitor will alert the other callers to stop ringing. The agent's stop_ringing callback will be called, and it is up to the agent's driver to send an appropriate message to make his caller stop ringing.
| 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 3866 of file ccss.c.
References ast_taskprocessor_push(), cc_stop_ringing(), cc_unref(), and find_cc_core_instance().
03867 { 03868 int res; 03869 struct cc_core_instance *core_instance = find_cc_core_instance(core_id); 03870 03871 if (!core_instance) { 03872 return -1; 03873 } 03874 03875 res = ast_taskprocessor_push(cc_core_taskprocessor, cc_stop_ringing, core_instance); 03876 if (res) { 03877 cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed"); 03878 } 03879 return res; 03880 }
| void ast_cc_monitor_unregister | ( | const struct ast_cc_monitor_callbacks * | callbacks | ) |
Unregister a set of monitor callbacks with the core.
| callbacks | The callbacks used by the monitor implementation |
| 0 | Successfully unregistered | |
| -1 | Failure to unregister |
Definition at line 1030 of file ccss.c.
References ast_free, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, cc_monitor_backend::callbacks, and cc_monitor_backend::next.
Referenced by __unload_module(), and unload_module().
01031 { 01032 struct cc_monitor_backend *backend; 01033 AST_RWLIST_WRLOCK(&cc_monitor_backends); 01034 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&cc_monitor_backends, backend, next) { 01035 if (backend->callbacks == callbacks) { 01036 AST_RWLIST_REMOVE_CURRENT(next); 01037 ast_free(backend); 01038 break; 01039 } 01040 } 01041 AST_RWLIST_TRAVERSE_SAFE_END; 01042 AST_RWLIST_UNLOCK(&cc_monitor_backends); 01043 }
| int ast_cc_offer | ( | struct ast_channel * | caller_chan | ) |
Offer CC to a caller.
| caller_chan | The calling channel |
| -1 | Error | |
| 0 | Success |
Definition at line 3591 of file ccss.c.
References ast_channel_datastore_find(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, cc_offer(), dialed_cc_interfaces::core_id, cc_recall_ds_data::core_id, ast_datastore::data, and dialed_cc_interfaces::is_original_caller.
Referenced by ast_hangup().
03592 { 03593 int core_id; 03594 int res = -1; 03595 struct ast_datastore *datastore; 03596 struct dialed_cc_interfaces *cc_interfaces; 03597 char cc_is_offerable; 03598 03599 ast_channel_lock(caller_chan); 03600 if (!(datastore = ast_channel_datastore_find(caller_chan, &dialed_cc_interfaces_info, NULL))) { 03601 ast_channel_unlock(caller_chan); 03602 return res; 03603 } 03604 03605 cc_interfaces = datastore->data; 03606 cc_is_offerable = cc_interfaces->is_original_caller; 03607 core_id = cc_interfaces->core_id; 03608 ast_channel_unlock(caller_chan); 03609 03610 if (cc_is_offerable) { 03611 res = cc_offer(core_id, "CC offered to caller %s", ast_channel_name(caller_chan)); 03612 } 03613 return res; 03614 }
| int ast_cc_request_is_within_limits | ( | void | ) |
Check if the incoming CC request is within the bounds set by the cc_max_requests configuration option.
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.
Definition at line 2315 of file ccss.c.
Referenced by cc_caller_requested(), cc_interfaces_datastore_init(), and ccreq_exec().
02316 { 02317 return cc_request_count < global_cc_max_requests; 02318 }
| int ast_cc_set_param | ( | struct ast_cc_config_params * | params, | |
| const char *const | name, | |||
| const char * | value | |||
| ) |
set a CCSS configuration parameter, given its name
| 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 790 of file ccss.c.
References ast_log(), ast_set_cc_agent_dialstring(), ast_set_cc_agent_policy(), ast_set_cc_callback_macro(), ast_set_cc_max_agents(), ast_set_cc_max_monitors(), ast_set_cc_monitor_policy(), ast_set_cc_offer_timer(), ast_set_cc_recall_timer(), ast_set_ccbs_available_timer(), ast_set_ccnr_available_timer(), LOG_WARNING, str_to_agent_policy(), and str_to_monitor_policy().
Referenced by acf_cc_write(), build_peer(), and process_dahdi().
00792 { 00793 unsigned int value_as_uint; 00794 if (!strcasecmp(name, "cc_agent_policy")) { 00795 return ast_set_cc_agent_policy(params, str_to_agent_policy(value)); 00796 } else if (!strcasecmp(name, "cc_monitor_policy")) { 00797 return ast_set_cc_monitor_policy(params, str_to_monitor_policy(value)); 00798 } else if (!strcasecmp(name, "cc_agent_dialstring")) { 00799 ast_set_cc_agent_dialstring(params, value); 00800 } else if (!strcasecmp(name, "cc_callback_macro")) { 00801 ast_set_cc_callback_macro(params, value); 00802 return 0; 00803 } 00804 00805 if (!sscanf(value, "%30u", &value_as_uint) == 1) { 00806 return -1; 00807 } 00808 00809 if (!strcasecmp(name, "cc_offer_timer")) { 00810 ast_set_cc_offer_timer(params, value_as_uint); 00811 } else if (!strcasecmp(name, "ccnr_available_timer")) { 00812 ast_set_ccnr_available_timer(params, value_as_uint); 00813 } else if (!strcasecmp(name, "ccbs_available_timer")) { 00814 ast_set_ccbs_available_timer(params, value_as_uint); 00815 } else if (!strcasecmp(name, "cc_max_agents")) { 00816 ast_set_cc_max_agents(params, value_as_uint); 00817 } else if (!strcasecmp(name, "cc_max_monitors")) { 00818 ast_set_cc_max_monitors(params, value_as_uint); 00819 } else if (!strcasecmp(name, "cc_recall_timer")) { 00820 ast_set_cc_recall_timer(params, value_as_uint); 00821 } else { 00822 ast_log(LOG_WARNING, "%s is not a valid CC parameter. Ignoring.\n", name); 00823 return -1; 00824 } 00825 00826 return 0; 00827 }
| const char* ast_get_cc_agent_dialstring | ( | struct ast_cc_config_params * | config | ) |
Get the cc_agent_dialstring.
| config | The configuration to retrieve the cc_agent_dialstring from |
Definition at line 942 of file ccss.c.
References ast_cc_config_params::cc_agent_dialstring.
Referenced by ast_cc_get_param(), and generic_recall().
00943 { 00944 return config->cc_agent_dialstring; 00945 }
| enum ast_cc_agent_policies ast_get_cc_agent_policy | ( | struct ast_cc_config_params * | config | ) |
Get the cc_agent_policy.
| config | The configuration to retrieve the policy from |
Definition at line 848 of file ccss.c.
References ast_cc_config_params::cc_agent_policy.
Referenced by ast_cc_call_init(), ast_cc_get_param(), build_peer(), cc_core_init_instance(), and find_agent_callbacks().
00849 { 00850 return config->cc_agent_policy; 00851 }
| const char* ast_get_cc_callback_macro | ( | struct ast_cc_config_params * | config | ) |
Get the name of the callback_macro.
| config | The configuration to retrieve the callback_macro from |
Definition at line 976 of file ccss.c.
References ast_cc_config_params::cc_callback_macro.
Referenced by ast_cc_get_param(), and generic_recall().
00977 { 00978 return config->cc_callback_macro; 00979 }
| unsigned int ast_get_cc_max_agents | ( | struct ast_cc_config_params * | config | ) |
Get the cc_max_agents.
| config | The configuration to retrieve the cc_max_agents from |
Definition at line 956 of file ccss.c.
References ast_cc_config_params::cc_max_agents.
Referenced by ast_cc_get_param(), and cc_core_init_instance().
00957 { 00958 return config->cc_max_agents; 00959 }
| unsigned int ast_get_cc_max_monitors | ( | struct ast_cc_config_params * | config | ) |
Get the cc_max_monitors.
| config | The configuration to retrieve the cc_max_monitors from |
Definition at line 966 of file ccss.c.
References ast_cc_config_params::cc_max_monitors.
Referenced by ast_cc_get_param(), and ast_queue_cc_frame().
00967 { 00968 return config->cc_max_monitors; 00969 }
| enum ast_cc_monitor_policies ast_get_cc_monitor_policy | ( | struct ast_cc_config_params * | config | ) |
Get the cc_monitor_policy.
| config | The configuration to retrieve the cc_monitor_policy from |
Definition at line 865 of file ccss.c.
References ast_cc_config_params::cc_monitor_policy.
Referenced by analog_call(), ast_cc_call_failed(), ast_cc_get_param(), dahdi_cc_callback(), and sip_handle_cc().
00866 { 00867 return config->cc_monitor_policy; 00868 }
| unsigned int ast_get_cc_offer_timer | ( | struct ast_cc_config_params * | config | ) |
Get the cc_offer_timer.
| config | The configuration to retrieve the cc_offer_timer from |
Definition at line 882 of file ccss.c.
References ast_cc_config_params::cc_offer_timer.
Referenced by ast_cc_get_param(), cc_generic_agent_start_offer_timer(), and sip_cc_agent_start_offer_timer().
00883 { 00884 return config->cc_offer_timer; 00885 }
| unsigned int ast_get_cc_recall_timer | ( | struct ast_cc_config_params * | config | ) |
Get the cc_recall_timer.
| config | The configuration to retrieve the cc_recall_timer from |
Definition at line 912 of file ccss.c.
References ast_cc_config_params::cc_recall_timer.
Referenced by ast_cc_get_param(), and generic_recall().
00913 { 00914 return config->cc_recall_timer; 00915 }
| unsigned int ast_get_ccbs_available_timer | ( | struct ast_cc_config_params * | config | ) |
Get the ccbs_available_timer.
| config | The configuration to retrieve the ccbs_available_timer from |
Definition at line 927 of file ccss.c.
References ast_cc_config_params::ccbs_available_timer.
Referenced by ast_cc_get_param(), cc_generic_monitor_request_cc(), and sip_cc_monitor_request_cc().
00928 { 00929 return config->ccbs_available_timer; 00930 }
| unsigned int ast_get_ccnr_available_timer | ( | struct ast_cc_config_params * | config | ) |
Get the ccnr_available_timer.
| config | The configuration to retrieve the ccnr_available_timer from |
Definition at line 897 of file ccss.c.
References ast_cc_config_params::ccnr_available_timer.
Referenced by ast_cc_get_param(), cc_generic_monitor_request_cc(), and sip_cc_monitor_request_cc().
00898 { 00899 return config->ccnr_available_timer; 00900 }
| void ast_handle_cc_control_frame | ( | struct ast_channel * | inbound, | |
| struct ast_channel * | outbound, | |||
| void * | frame_data | |||
| ) |
Properly react to a CC control frame.
| inbound | The inbound channel | |
| outbound | The outbound channel (The one from which the CC frame was read) | |
| frame_data | The ast_frame's data.ptr field. |
| void | Unless we are ignoring CC for some reason, we will always call this function when we read an AST_CONTROL_CC frame from an outbound channel. |
If this is the first AST_CONTROL_CC frame that we have handled for this call, then we will also initialize the CC core for this call.
Definition at line 2144 of file ccss.c.
References ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, AST_CONTROL_CC, ast_indicate_data(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_log_dynamic_level, call_destructor_with_no_monitor(), cc_core_init_instance(), cc_device_monitor_init(), cc_extension_monitor_change_is_valid(), cc_ref(), cc_service_to_string(), cc_unref(), cc_core_instance::core_id, dialed_cc_interfaces::core_id, ast_datastore::data, ast_cc_interface::device_name, cc_control_payload::device_name, cc_control_payload::dialstring, ast_cc_monitor::dialstring, EVENT_FLAG_CC, find_cc_core_instance(), dialed_cc_interfaces::ignore, ast_cc_monitor::interface, dialed_cc_interfaces::interface_tree, dialed_cc_interfaces::is_original_caller, LOG_WARNING, manager_event, monitor, cc_control_payload::monitor_type, ast_cc_monitor::parent_id, cc_control_payload::private_data, and cc_control_payload::service.
Referenced by ast_cc_busy_interface(), ast_cc_call_failed(), and wait_for_answer().
02145 { 02146 char *device_name; 02147 char *dialstring; 02148 struct ast_cc_monitor *monitor; 02149 struct ast_datastore *cc_datastore; 02150 struct dialed_cc_interfaces *cc_interfaces; 02151 struct cc_control_payload *cc_data = frame_data; 02152 struct cc_core_instance *core_instance; 02153 02154 device_name = cc_data->device_name; 02155 dialstring = cc_data->dialstring; 02156 02157 ast_channel_lock(inbound); 02158 if (!(cc_datastore = ast_channel_datastore_find(inbound, &dialed_cc_interfaces_info, NULL))) { 02159 ast_log(LOG_WARNING, "Unable to retrieve CC datastore while processing CC frame from '%s'. CC services will be unavailable.\n", device_name); 02160 ast_channel_unlock(inbound); 02161 call_destructor_with_no_monitor(cc_data->monitor_type, cc_data->private_data); 02162 return; 02163 } 02164 02165 cc_interfaces = cc_datastore->data; 02166 02167 if (cc_interfaces->ignore) { 02168 ast_channel_unlock(inbound); 02169 call_destructor_with_no_monitor(cc_data->monitor_type, cc_data->private_data); 02170 return; 02171 } 02172 02173 if (!cc_interfaces->is_original_caller) { 02174 /* If the is_original_caller is not set on the *inbound* channel, then 02175 * it must be a local channel. As such, we do not want to create a core instance 02176 * or an agent for the local channel. Instead, we want to pass this along to the 02177 * other side of the local channel so that the original caller can benefit. 02178 */ 02179 ast_channel_unlock(inbound); 02180 ast_indicate_data(inbound, AST_CONTROL_CC, cc_data, sizeof(*cc_data)); 02181 return; 02182 } 02183 02184 core_instance = find_cc_core_instance(cc_interfaces->core_id); 02185 if (!core_instance) { 02186 core_instance = cc_core_init_instance(inbound, cc_interfaces->interface_tree, 02187 cc_interfaces->core_id, cc_data); 02188 if (!core_instance) { 02189 cc_interfaces->ignore = 1; 02190 ast_channel_unlock(inbound); 02191 call_destructor_with_no_monitor(cc_data->monitor_type, cc_data->private_data); 02192 return; 02193 } 02194 } 02195 02196 ast_channel_unlock(inbound); 02197 02198 /* Yeah this kind of sucks, but luckily most people 02199 * aren't dialing thousands of interfaces on every call 02200 * 02201 * This traversal helps us to not create duplicate monitors in 02202 * case a device queues multiple CC control frames. 02203 */ 02204 AST_LIST_LOCK(cc_interfaces->interface_tree); 02205 AST_LIST_TRAVERSE(cc_interfaces->interface_tree, monitor, next) { 02206 if (!strcmp(monitor->interface->device_name, device_name)) { 02207 ast_log_dynamic_level(cc_logger_level, "Core %d: Device %s sent us multiple CC control frames. Ignoring those beyond the first.\n", 02208 core_instance->core_id, device_name); 02209 AST_LIST_UNLOCK(cc_interfaces->interface_tree); 02210 cc_unref(core_instance, "Returning early from ast_handle_cc_control_frame. Unref core_instance"); 02211 call_destructor_with_no_monitor(cc_data->monitor_type, cc_data->private_data); 02212 return; 02213 } 02214 } 02215 AST_LIST_UNLOCK(cc_interfaces->interface_tree); 02216 02217 if (!(monitor = cc_device_monitor_init(device_name, dialstring, cc_data, core_instance->core_id))) { 02218 ast_log(LOG_WARNING, "Unable to create CC device interface for '%s'. CC services will be unavailable on this interface.\n", device_name); 02219 cc_unref(core_instance, "Returning early from ast_handle_cc_control_frame. Unref core_instance"); 02220 call_destructor_with_no_monitor(cc_data->monitor_type, cc_data->private_data); 02221 return; 02222 } 02223 02224 AST_LIST_LOCK(cc_interfaces->interface_tree); 02225 cc_ref(monitor, "monitor tree's reference to the monitor"); 02226 AST_LIST_INSERT_TAIL(cc_interfaces->interface_tree, monitor, next); 02227 AST_LIST_UNLOCK(cc_interfaces->interface_tree); 02228 02229 cc_extension_monitor_change_is_valid(core_instance, monitor->parent_id, monitor->interface->device_name, 0); 02230 02231 manager_event(EVENT_FLAG_CC, "CCAvailable", 02232 "CoreID: %d\r\n" 02233 "Callee: %s\r\n" 02234 "Service: %s\r\n", 02235 cc_interfaces->core_id, device_name, cc_service_to_string(cc_data->service) 02236 ); 02237 02238 cc_unref(core_instance, "Done with core_instance after handling CC control frame"); 02239 cc_unref(monitor, "Unref reference from allocating monitor"); 02240 }
| void ast_ignore_cc | ( | struct ast_channel * | chan | ) |
Mark the channel to ignore further CC activity.
| chan | The channel for which further CC processing should be ignored. |
| void |
Definition at line 3560 of file ccss.c.
References ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_datastore::data, cc_recall_ds_data::ignore, and dialed_cc_interfaces::ignore.
Referenced by dial_exec_full(), and do_forward().
03561 { 03562 struct ast_datastore *cc_datastore; 03563 struct ast_datastore *cc_recall_datastore; 03564 struct dialed_cc_interfaces *cc_interfaces; 03565 struct cc_recall_ds_data *recall_cc_data; 03566 03567 ast_channel_lock(chan); 03568 if ((cc_datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL))) { 03569 cc_interfaces = cc_datastore->data; 03570 cc_interfaces->ignore = 1; 03571 } 03572 03573 if ((cc_recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) { 03574 recall_cc_data = cc_recall_datastore->data; 03575 recall_cc_data->ignore = 1; 03576 } 03577 ast_channel_unlock(chan); 03578 }
| int ast_queue_cc_frame | ( | struct ast_channel * | chan, | |
| const char *const | monitor_type, | |||
| const char *const | dialstring, | |||
| enum ast_cc_service_type | service, | |||
| void * | private_data | |||
| ) |
Queue an AST_CONTROL_CC frame.
| 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 3992 of file ccss.c.
References ast_cc_build_frame(), ast_cc_monitor_count(), ast_channel_get_cc_config_params(), ast_channel_get_device_name(), AST_CHANNEL_NAME, ast_frfree, ast_get_cc_max_monitors(), ast_log(), ast_queue_frame(), and LOG_NOTICE.
Referenced by analog_call(), and sip_handle_cc().
03994 { 03995 struct ast_frame frame = {0,}; 03996 char device_name[AST_CHANNEL_NAME]; 03997 int retval; 03998 struct ast_cc_config_params *cc_params; 03999 04000 cc_params = ast_channel_get_cc_config_params(chan); 04001 if (!cc_params) { 04002 return -1; 04003 } 04004 ast_channel_get_device_name(chan, device_name, sizeof(device_name)); 04005 if (ast_cc_monitor_count(device_name, monitor_type) >= ast_get_cc_max_monitors(cc_params)) { 04006 ast_log(LOG_NOTICE, "Not queuing a CC frame for device %s since it already has its maximum monitors allocated\n", device_name); 04007 return -1; 04008 } 04009 04010 if (ast_cc_build_frame(chan, cc_params, monitor_type, device_name, dialstring, service, private_data, &frame)) { 04011 /* Frame building failed. We can't use this. */ 04012 return -1; 04013 } 04014 retval = ast_queue_frame(chan, &frame); 04015 ast_frfree(&frame); 04016 return retval; 04017 }
| void ast_set_cc_agent_dialstring | ( | struct ast_cc_config_params * | config, | |
| const char *const | value | |||
| ) |
Set the cc_agent_dialstring.
| 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 947 of file ccss.c.
References ast_copy_string(), ast_strlen_zero(), and ast_cc_config_params::cc_agent_dialstring.
Referenced by ast_cc_set_param().
00948 { 00949 if (ast_strlen_zero(value)) { 00950 config->cc_agent_dialstring[0] = '\0'; 00951 } else { 00952 ast_copy_string(config->cc_agent_dialstring, value, sizeof(config->cc_agent_dialstring)); 00953 } 00954 }
| int ast_set_cc_agent_policy | ( | struct ast_cc_config_params * | config, | |
| enum ast_cc_agent_policies | value | |||
| ) |
Set the cc_agent_policy.
| 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 853 of file ccss.c.
References AST_CC_AGENT_GENERIC, and ast_cc_config_params::cc_agent_policy.
Referenced by ast_cc_set_param(), and build_peer().
00854 { 00855 /* Screw C and its weak type checking for making me have to do this 00856 * validation at runtime. 00857 */ 00858 if (value < AST_CC_AGENT_NEVER || value > AST_CC_AGENT_GENERIC) { 00859 return -1; 00860 } 00861 config->cc_agent_policy = value; 00862 return 0; 00863 }
| void ast_set_cc_callback_macro | ( | struct ast_cc_config_params * | config, | |
| const char *const | value | |||
| ) |
Set the callback_macro name.
| config | The configuration to set the callback_macro on | |
| value | The new callback macro we want to change to |
| void |
Definition at line 981 of file ccss.c.
References ast_copy_string(), ast_strlen_zero(), and ast_cc_config_params::cc_callback_macro.
Referenced by ast_cc_set_param().
00982 { 00983 if (ast_strlen_zero(value)) { 00984 config->cc_callback_macro[0] = '\0'; 00985 } else { 00986 ast_copy_string(config->cc_callback_macro, value, sizeof(config->cc_callback_macro)); 00987 } 00988 }
| int ast_set_cc_interfaces_chanvar | ( | struct ast_channel * | chan, | |
| const char *const | extension | |||
| ) |
Set the CC_INTERFACES channel variable for a channel using an extension as a starting point.
| chan | The channel to set the CC_INTERFACES variable on | |
| extension | The name of the extension for which we're setting the variable. This should be in the form of "exten@context" |
Definition at line 3508 of file ccss.c.
References ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_free, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log_dynamic_level, ast_str_buffer(), ast_str_create(), build_cc_interfaces_chanvar(), cc_recall_ds_data::core_id, ast_datastore::data, ast_cc_interface::device_name, ast_cc_monitor::interface, cc_recall_ds_data::interface_tree, pbx_builtin_setvar_helper(), and str.
Referenced by local_call().
03509 { 03510 struct ast_datastore *recall_datastore; 03511 struct cc_monitor_tree *interface_tree; 03512 struct ast_cc_monitor *monitor_iter; 03513 struct cc_recall_ds_data *recall_data; 03514 struct ast_str *str = ast_str_create(64); 03515 int core_id; 03516 03517 if (!str) { 03518 return -1; 03519 } 03520 03521 ast_channel_lock(chan); 03522 if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) { 03523 ast_channel_unlock(chan); 03524 ast_free(str); 03525 return -1; 03526 } 03527 recall_data = recall_datastore->data; 03528 interface_tree = recall_data->interface_tree; 03529 core_id = recall_data->core_id; 03530 ast_channel_unlock(chan); 03531 03532 AST_LIST_LOCK(interface_tree); 03533 AST_LIST_TRAVERSE(interface_tree, monitor_iter, next) { 03534 if (!strcmp(monitor_iter->interface->device_name, extension)) { 03535 break; 03536 } 03537 } 03538 03539 if (!monitor_iter) { 03540 /* We couldn't find this extension. This may be because 03541 * we have been directed into an unexpected extension because 03542 * the admin has changed a CC_INTERFACES variable at some point. 03543 */ 03544 AST_LIST_UNLOCK(interface_tree); 03545 ast_free(str); 03546 return -1; 03547 } 03548 03549 build_cc_interfaces_chanvar(monitor_iter, str); 03550 AST_LIST_UNLOCK(interface_tree); 03551 03552 pbx_builtin_setvar_helper(chan, "CC_INTERFACES", ast_str_buffer(str)); 03553 ast_log_dynamic_level(cc_logger_level, "Core %d: CC_INTERFACES set to %s\n", 03554 core_id, ast_str_buffer(str)); 03555 03556 ast_free(str); 03557 return 0; 03558 }
| void ast_set_cc_max_agents | ( | struct ast_cc_config_params * | config, | |
| unsigned int | value | |||
| ) |
Set the cc_max_agents.
| 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 961 of file ccss.c.
References ast_cc_config_params::cc_max_agents.
Referenced by ast_cc_set_param().
00962 { 00963 config->cc_max_agents = value; 00964 }
| void ast_set_cc_max_monitors | ( | struct ast_cc_config_params * | config, | |
| unsigned int | value | |||
| ) |
Set the cc_max_monitors.
| 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 971 of file ccss.c.
References ast_cc_config_params::cc_max_monitors.
Referenced by ast_cc_set_param().
00972 { 00973 config->cc_max_monitors = value; 00974 }
| int ast_set_cc_monitor_policy | ( | struct ast_cc_config_params * | config, | |
| enum ast_cc_monitor_policies | value | |||
| ) |
Set the cc_monitor_policy.
| 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 870 of file ccss.c.
References AST_CC_MONITOR_ALWAYS, and ast_cc_config_params::cc_monitor_policy.
Referenced by ast_cc_set_param().
00871 { 00872 /* Screw C and its weak type checking for making me have to do this 00873 * validation at runtime. 00874 */ 00875 if (value < AST_CC_MONITOR_NEVER || value > AST_CC_MONITOR_ALWAYS) { 00876 return -1; 00877 } 00878 config->cc_monitor_policy = value; 00879 return 0; 00880 }
| void ast_set_cc_offer_timer | ( | struct ast_cc_config_params * | config, | |
| unsigned int | value | |||
| ) |
Set the cc_offer_timer.
| 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 887 of file ccss.c.
References ast_log(), ast_cc_config_params::cc_offer_timer, and LOG_WARNING.
Referenced by ast_cc_set_param().
00888 { 00889 /* 0 is an unreasonable value for any timer. Stick with the default */ 00890 if (value == 0) { 00891 ast_log(LOG_WARNING, "0 is an invalid value for cc_offer_timer. Retaining value as %u\n", config->cc_offer_timer); 00892 return; 00893 } 00894 config->cc_offer_timer = value; 00895 }
| void ast_set_cc_recall_timer | ( | struct ast_cc_config_params * | config, | |
| unsigned int | value | |||
| ) |
Set the cc_recall_timer.
| 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 917 of file ccss.c.
References ast_log(), ast_cc_config_params::cc_recall_timer, and LOG_WARNING.
Referenced by ast_cc_set_param().
00918 { 00919 /* 0 is an unreasonable value for any timer. Stick with the default */ 00920 if (value == 0) { 00921 ast_log(LOG_WARNING, "0 is an invalid value for ccnr_available_timer. Retaining value as %u\n", config->cc_recall_timer); 00922 return; 00923 } 00924 config->cc_recall_timer = value; 00925 }
| void ast_set_ccbs_available_timer | ( | struct ast_cc_config_params * | config, | |
| unsigned int | value | |||
| ) |
Set the ccbs_available_timer.
| 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 932 of file ccss.c.
References ast_log(), ast_cc_config_params::ccbs_available_timer, and LOG_WARNING.
Referenced by ast_cc_set_param().
00933 { 00934 /* 0 is an unreasonable value for any timer. Stick with the default */ 00935 if (value == 0) { 00936 ast_log(LOG_WARNING, "0 is an invalid value for ccbs_available_timer. Retaining value as %u\n", config->ccbs_available_timer); 00937 return; 00938 } 00939 config->ccbs_available_timer = value; 00940 }
| void ast_set_ccnr_available_timer | ( | struct ast_cc_config_params * | config, | |
| unsigned int | value | |||
| ) |
Set the ccnr_available_timer.
| 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 902 of file ccss.c.
References ast_log(), ast_cc_config_params::ccnr_available_timer, and LOG_WARNING.
Referenced by ast_cc_set_param().
00903 { 00904 /* 0 is an unreasonable value for any timer. Stick with the default */ 00905 if (value == 0) { 00906 ast_log(LOG_WARNING, "0 is an invalid value for ccnr_available_timer. Retaining value as %u\n", config->ccnr_available_timer); 00907 return; 00908 } 00909 config->ccnr_available_timer = value; 00910 }
| int ast_setup_cc_recall_datastore | ( | struct ast_channel * | chan, | |
| const int | core_id | |||
| ) |
Set up a CC recall datastore on a channel.
This function must be called by the implementer once it has been detected that an inbound call is a cc_recall. After allocating the channel, call this function, followed by ast_cc_set_cc_interfaces_chanvar. While it would be nice to be able to have the core do this automatically, it just cannot be done given the current architecture.
Definition at line 3245 of file ccss.c.
References ast_calloc, ast_channel_datastore_add(), ast_channel_lock, ast_channel_unlock, ast_datastore_alloc, ast_datastore_free(), ast_free, cc_ref(), cc_unref(), cc_recall_ds_data::core_id, ast_datastore::data, DATASTORE_INHERIT_FOREVER, find_cc_core_instance(), ast_datastore::inheritance, cc_recall_ds_data::interface_tree, and cc_core_instance::monitors.
Referenced by generic_recall(), and handle_request_invite().
03246 { 03247 struct ast_datastore *recall_datastore = ast_datastore_alloc(&recall_ds_info, NULL); 03248 struct cc_recall_ds_data *recall_data; 03249 struct cc_core_instance *core_instance; 03250 03251 if (!recall_datastore) { 03252 return -1; 03253 } 03254 03255 if (!(recall_data = ast_calloc(1, sizeof(*recall_data)))) { 03256 ast_datastore_free(recall_datastore); 03257 return -1; 03258 } 03259 03260 if (!(core_instance = find_cc_core_instance(core_id))) { 03261 ast_free(recall_data); 03262 ast_datastore_free(recall_datastore); 03263 return -1; 03264 } 03265 03266 recall_data->interface_tree = cc_ref(core_instance->monitors, 03267 "Bump refcount for monitor tree for recall datastore"); 03268 recall_data->core_id = core_id; 03269 recall_datastore->data = recall_data; 03270 recall_datastore->inheritance = DATASTORE_INHERIT_FOREVER; 03271 ast_channel_lock(chan); 03272 ast_channel_datastore_add(chan, recall_datastore); 03273 ast_channel_unlock(chan); 03274 cc_unref(core_instance, "Recall datastore set up. No need for core_instance ref"); 03275 return 0; 03276 }
1.5.6