Asterisk - The Open Source Telephony Project GIT-master-9647a4f
Loading...
Searching...
No Matches
Data Structures | Macros | Typedefs | Enumerations | Functions
ccss.h File Reference

Call Completion Supplementary Services API. More...

#include "asterisk.h"
#include "asterisk/linkedlists.h"
#include "asterisk/devicestate.h"
Include dependency graph for ccss.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

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

Macros

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

Typedefs

typedef void(* ast_cc_callback_fn) (struct ast_channel *chan, struct ast_cc_config_params *cc_params, const char *monitor_type, const char *const device_name, const char *const dialstring, void *private_data)
 Callback made from ast_cc_callback for certain channel types.
 

Enumerations

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

Functions

struct ast_cc_config_params__ast_cc_config_params_init (const char *file, int line, const char *function)
 Allocate and initialize an ast_cc_config_params structure.
 
int ast_cc_agent_accept_request (int core_id, const char *const debug,...)
 Accept inbound CC request.
 
struct ast_cc_agentast_cc_agent_callback (int flags, ao2_callback_fn *function, void *arg, const char *const type)
 Call a callback on all agents of a specific type.
 
int ast_cc_agent_caller_available (int core_id, const char *const debug,...)
 Indicate that a previously unavailable caller has become available.
 
int ast_cc_agent_caller_busy (int core_id, const char *const debug,...)
 Indicate that the caller is busy.
 
int ast_cc_agent_recalling (int core_id, const char *const debug,...)
 Tell the CC core that a caller is currently recalling.
 
int ast_cc_agent_register (const struct ast_cc_agent_callbacks *callbacks)
 Register a set of agent callbacks with the core.
 
int ast_cc_agent_set_interfaces_chanvar (struct ast_channel *chan)
 Set the first level CC_INTERFACES channel variable for a channel.
 
int ast_cc_agent_status_response (int core_id, enum ast_device_state devstate)
 Response with a caller's current status.
 
void ast_cc_agent_unregister (const struct ast_cc_agent_callbacks *callbacks)
 Unregister a set of agent callbacks with the core.
 
int ast_cc_available_timer_expire (const void *data)
 Scheduler callback for available timer expiration.
 
int ast_cc_build_frame (struct ast_channel *chan, struct ast_cc_config_params *cc_params, const char *monitor_type, const char *const device_name, const char *const dialstring, enum ast_cc_service_type service, void *private_data, struct ast_frame *frame)
 Create a CC Control frame.
 
void ast_cc_busy_interface (struct ast_channel *inbound, struct ast_cc_config_params *cc_params, const char *monitor_type, const char *const device_name, const char *const dialstring, void *private_data)
 Callback made from ast_cc_callback for certain channel types.
 
void ast_cc_call_failed (struct ast_channel *incoming, struct ast_channel *outgoing, const char *const dialstring)
 Make CCBS available in the case that ast_call fails.
 
int ast_cc_call_init (struct ast_channel *chan, int *ignore_cc)
 Start the CC process on a call.
 
int ast_cc_callback (struct ast_channel *inbound, const char *const tech, const char *const dest, ast_cc_callback_fn callback)
 Run a callback for potential matching destinations.
 
int ast_cc_completed (struct ast_channel *chan, const char *const debug,...)
 Indicate recall has been acknowledged.
 
void ast_cc_config_params_destroy (struct ast_cc_config_params *params)
 Free memory from CCSS configuration params.
 
void ast_cc_copy_config_params (struct ast_cc_config_params *dest, const struct ast_cc_config_params *src)
 copy CCSS configuration parameters from one structure to another
 
void ast_cc_default_config_params (struct ast_cc_config_params *params)
 Set the specified CC config params to default values.
 
void ast_cc_extension_monitor_add_dialstring (struct ast_channel *incoming, const char *const dialstring, const char *const device_name)
 Add a child dialstring to an extension monitor.
 
int ast_cc_failed (int core_id, const char *const debug,...)
 Indicate failure has occurred.
 
int ast_cc_get_current_core_id (struct ast_channel *chan)
 Get the core id for the current call.
 
struct ast_cc_monitorast_cc_get_monitor_by_recall_core_id (const int core_id, const char *const device_name)
 Get the associated monitor given the device name and core_id.
 
int ast_cc_get_param (struct ast_cc_config_params *params, const char *const name, char *buf, size_t buf_len)
 get a CCSS configuration parameter, given its name
 
int ast_cc_is_config_param (const char *const name)
 Is this a CCSS configuration parameter?
 
int ast_cc_is_enabled (void)
 Determine if CCSS is enabled.
 
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_sub (struct ast_cc_config_params *config)
 Get the name of the callback subroutine.
 
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_sub (struct ast_cc_config_params *config, const char *const value)
 Set the callback subroutine 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.
 
void ast_set_cc_max_agents (struct ast_cc_config_params *config, unsigned int value)
 Set the cc_max_agents.
 
void ast_set_cc_max_monitors (struct ast_cc_config_params *config, unsigned int value)
 Set the cc_max_monitors.
 
int ast_set_cc_monitor_policy (struct ast_cc_config_params *config, enum ast_cc_monitor_policies value)
 Set the cc_monitor_policy.
 
void ast_set_cc_offer_timer (struct ast_cc_config_params *config, unsigned int value)
 Set the cc_offer_timer.
 
void ast_set_cc_recall_timer (struct ast_cc_config_params *config, unsigned int value)
 Set the cc_recall_timer.
 
void ast_set_ccbs_available_timer (struct ast_cc_config_params *config, unsigned int value)
 Set the ccbs_available_timer.
 
void ast_set_ccnr_available_timer (struct ast_cc_config_params *config, unsigned int value)
 Set the ccnr_available_timer.
 
int ast_setup_cc_recall_datastore (struct ast_channel *chan, const int core_id)
 Set up a CC recall datastore on a channel.
 

Detailed Description

Call Completion Supplementary Services API.

Author
Mark Michelson mmich.nosp@m.elso.nosp@m.n@dig.nosp@m.ium..nosp@m.com

Definition in file ccss.h.

Macro Definition Documentation

◆ ast_cc_config_params_init

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

Allocate and initialize an ast_cc_config_params structure.

Note
Reasonable default values are chosen for the parameters upon allocation.
Return values
NULLUnable to allocate the structure
non-NULLA pointer to the newly allocated and initialized structure

Definition at line 135 of file ccss.h.

◆ AST_CC_GENERIC_MONITOR_TYPE

#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 455 of file ccss.h.

Typedef Documentation

◆ ast_cc_callback_fn

typedef void(* ast_cc_callback_fn) (struct ast_channel *chan, struct ast_cc_config_params *cc_params, const char *monitor_type, const char *const device_name, const char *const dialstring, void *private_data)

Callback made from ast_cc_callback for certain channel types.

Since
1.8
Parameters
chanA channel involved in the call. What we want is on a datastore on both incoming and outgoing so either may be provided
cc_paramsThe CC configuration parameters for the outbound target
monitor_typeThe type of monitor to use when CC is requested
device_nameThe name of the outbound target device.
dialstringThe dial string used when calling this specific interface
private_dataIf a native monitor is being used, and some channel-driver-specific private data has been allocated, then this parameter should contain a pointer to that data. If using a generic monitor, this parameter should remain NULL. Note that if this function should fail at some point, it is the responsibility of the caller to free the private data upon return.

For channel types that fail ast_request when the device is busy, we call into the channel driver with ast_cc_callback. This is the callback that is called in that case for each device found which could have been returned by ast_request.

Definition at line 1562 of file ccss.h.

Enumeration Type Documentation

◆ ast_cc_agent_flags

agent flags that can alter core behavior

Enumerator
AST_CC_AGENT_SKIP_OFFER 

Definition at line 59 of file ccss.h.

59 {
60 /* Some agent types allow for a caller to
61 * request CC without reaching the CC_CALLER_OFFERED
62 * state. In other words, the caller can request
63 * CC while he is still on the phone from the failed
64 * call. The generic agent is an agent which allows
65 * for this behavior.
66 */
67 AST_CC_AGENT_SKIP_OFFER = (1 << 0),
68};
@ AST_CC_AGENT_SKIP_OFFER
Definition ccss.h:67

◆ ast_cc_agent_policies

The various possibilities for cc_agent_policy values.

Since
1.8
Enumerator
AST_CC_AGENT_NEVER 

Never offer CCSS to the caller

AST_CC_AGENT_NATIVE 

Offer CCSS using native signaling

AST_CC_AGENT_GENERIC 

Use generic agent for caller

Definition at line 47 of file ccss.h.

47 {
48 /*! Never offer CCSS to the caller */
50 /*! Offer CCSS using native signaling */
52 /*! Use generic agent for caller */
54};
@ AST_CC_AGENT_NEVER
Definition ccss.h:49
@ AST_CC_AGENT_GENERIC
Definition ccss.h:53
@ AST_CC_AGENT_NATIVE
Definition ccss.h:51

◆ ast_cc_agent_response_reason

Enumerator
AST_CC_AGENT_RESPONSE_SUCCESS 

CC request accepted

AST_CC_AGENT_RESPONSE_FAILURE_INVALID 

CC request not allowed at this time. Invalid state transition.

AST_CC_AGENT_RESPONSE_FAILURE_TOO_MANY 

Too many CC requests in the system.

Definition at line 841 of file ccss.h.

841 {
842 /*! CC request accepted */
844 /*! CC request not allowed at this time. Invalid state transition. */
846 /*! Too many CC requests in the system. */
848};
@ AST_CC_AGENT_RESPONSE_FAILURE_INVALID
Definition ccss.h:845
@ AST_CC_AGENT_RESPONSE_SUCCESS
Definition ccss.h:843
@ AST_CC_AGENT_RESPONSE_FAILURE_TOO_MANY
Definition ccss.h:847

◆ ast_cc_monitor_class

Used to determine which type of monitor an ast_cc_device_monitor is.

Enumerator
AST_CC_DEVICE_MONITOR 
AST_CC_EXTENSION_MONITOR 

Definition at line 462 of file ccss.h.

462 {
465};
@ AST_CC_EXTENSION_MONITOR
Definition ccss.h:464
@ AST_CC_DEVICE_MONITOR
Definition ccss.h:463

◆ ast_cc_monitor_policies

The various possibilities for cc_monitor_policy values.

Since
1.8
Enumerator
AST_CC_MONITOR_NEVER 

Never accept CCSS offers from callee

AST_CC_MONITOR_NATIVE 
AST_CC_MONITOR_GENERIC 

Always use CCSS generic monitor for callee Note that if callee offers CCSS natively, we still will use a generic CCSS monitor if this is set

AST_CC_MONITOR_ALWAYS 

Accept native CCSS offers, but if no offer is present, use a generic CCSS monitor

Definition at line 74 of file ccss.h.

74 {
75 /*! Never accept CCSS offers from callee */
77 /* CCSS only available if callee offers it through signaling */
79 /*! Always use CCSS generic monitor for callee
80 * Note that if callee offers CCSS natively, we still
81 * will use a generic CCSS monitor if this is set
82 */
84 /*! Accept native CCSS offers, but if no offer is present,
85 * use a generic CCSS monitor
86 */
88};
@ AST_CC_MONITOR_NEVER
Definition ccss.h:76
@ AST_CC_MONITOR_ALWAYS
Definition ccss.h:87
@ AST_CC_MONITOR_NATIVE
Definition ccss.h:78
@ AST_CC_MONITOR_GENERIC
Definition ccss.h:83

◆ ast_cc_service_type

Enumerator
AST_CC_NONE 
AST_CC_CCBS 
AST_CC_CCNR 
AST_CC_CCNL 

Definition at line 32 of file ccss.h.

32 {
33 /* No Service available/requested */
35 /* Call Completion Busy Subscriber */
37 /* Call Completion No Response */
39 /* Call Completion Not Logged In (currently SIP only) */
41};
@ AST_CC_CCNL
Definition ccss.h:40
@ AST_CC_CCBS
Definition ccss.h:36
@ AST_CC_NONE
Definition ccss.h:34
@ AST_CC_CCNR
Definition ccss.h:38

Function Documentation

◆ __ast_cc_config_params_init()

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.

Note
Reasonable default values are chosen for the parameters upon allocation.
Return values
NULLUnable to allocate the structure
non-NULLA pointer to the newly allocated and initialized structure

Definition at line 699 of file ccss.c.

700{
701 struct ast_cc_config_params *params;
702
704
705 params = __ast_malloc(sizeof(*params), file, line, function);
706 if (!params) {
707 return NULL;
708 }
709
711 return params;
712}
void * __ast_malloc(size_t size, const char *file, int lineno, const char *func) attribute_malloc
Definition astmm.c:1628
void ast_cc_default_config_params(struct ast_cc_config_params *params)
Set the specified CC config params to default values.
Definition ccss.c:694
#define RETURN_IF_NOT_ENABLED(rc)
Definition ccss.c:120
#define NULL
Definition resample.c:96

References __ast_malloc(), ast_cc_default_config_params(), NULL, and RETURN_IF_NOT_ENABLED.

◆ ast_cc_agent_accept_request()

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

Accept inbound CC request.

Since
1.8

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

Parameters
core_idcore_id of the CC transaction
debugoptional string to print for debugging purposes
Return values
0Success
-1Failure

Definition at line 3807 of file ccss.c.

3808{
3809 va_list ap;
3810 int res;
3811
3813
3814 va_start(ap, debug);
3816 va_end(ap);
3817 return res;
3818}
@ CC_CALLER_REQUESTED
Definition ccss.c:203
static int cc_request_state_change(enum cc_state state, const int core_id, const char *debug, va_list ap)
Definition ccss.c:3346
static int debug
Global debug status.
Definition res_xmpp.c:570

References CC_CALLER_REQUESTED, cc_request_state_change(), dialed_cc_interfaces::core_id, debug, and RETURN_IF_NOT_ENABLED.

Referenced by ccreq_exec().

◆ ast_cc_agent_callback()

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

Call a callback on all agents of a specific type.

Since the container of CC core instances is private, and so are the items which the container contains, we have to provide an ao2_callback-like method so that a specific agent may be found or so that an operation can be made on all agents of a particular type. The first three arguments should be familiar to anyone who has used ao2_callback. The final argument is the type of agent you wish to have the callback called on.

Note
Since agents are refcounted, and this function returns a reference to the agent, it is imperative that you decrement the refcount of the agent once you have finished using it.
Parameters
flagsastobj2 search flags
functionan ao2 callback function to call
argthe argument to the callback function
typeThe type of agents to call the callback on

Definition at line 472 of file ccss.c.

473{
474 struct cc_callback_helper helper = {.function = function, .args = args, .type = type};
475 struct cc_core_instance *core_instance;
476
478
479 if ((core_instance = ao2_t_callback(cc_core_instances, flags, cc_agent_callback_helper, &helper,
480 "Calling provided agent callback function"))) {
481 struct ast_cc_agent *agent = cc_ref(core_instance->agent, "An outside entity needs the agent");
482 cc_unref(core_instance, "agent callback done with the core_instance");
483 return agent;
484 }
485 return NULL;
486}
#define ao2_t_callback(c, flags, cb_fn, arg, tag)
Definition astobj2.h:1696
static void * cc_unref(void *obj, const char *debug)
Definition ccss.c:165
static void * cc_ref(void *obj, const char *debug)
Definition ccss.c:159
static struct ao2_container * cc_core_instances
Definition ccss.c:342
static int cc_agent_callback_helper(void *obj, void *args, int flags)
Definition ccss.c:460
static const char type[]
static struct @519 args
ao2_callback_fn * function
Definition ccss.c:455
struct ast_cc_agent * agent
Definition ccss.c:356

References cc_core_instance::agent, ao2_t_callback, args, cc_agent_callback_helper(), cc_core_instances, cc_ref(), cc_unref(), cc_callback_helper::function, NULL, RETURN_IF_NOT_ENABLED, and type.

◆ ast_cc_agent_caller_available()

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

Indicate that a previously unavailable caller has become available.

Since
1.8

If a monitor is suspended due to a caller becoming unavailable, then this function should be called to indicate that the caller has become available.

Parameters
core_idcore_id of the CC transaction
debugoptional string to print for debugging purposes
Return values
0Success
-1Failure

Definition at line 3859 of file ccss.c.

3860{
3861 va_list ap;
3862 int res;
3863
3865
3866 va_start(ap, debug);
3867 res = cc_request_state_change(CC_ACTIVE, core_id, debug, ap);
3868 va_end(ap);
3869 return res;
3870}
@ CC_ACTIVE
Definition ccss.c:206

References CC_ACTIVE, cc_request_state_change(), dialed_cc_interfaces::core_id, debug, and RETURN_IF_NOT_ENABLED.

Referenced by generic_agent_devstate_cb().

◆ ast_cc_agent_caller_busy()

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

Indicate that the caller is busy.

Since
1.8

When the callee makes it known that he is available, the core will let the caller's channel driver know that it may attempt to let the caller know to attempt a recall. If the channel driver can detect, though, that the caller is busy, then the channel driver should call this function to let the CC core know.

Parameters
core_idcore_id of the CC transaction
debugoptional string to print for debugging purposes
Return values
0Success
-1Failure

Definition at line 3846 of file ccss.c.

3847{
3848 va_list ap;
3849 int res;
3850
3852
3853 va_start(ap, debug);
3854 res = cc_request_state_change(CC_CALLER_BUSY, core_id, debug, ap);
3855 va_end(ap);
3856 return res;
3857}
@ CC_CALLER_BUSY
Definition ccss.c:213

References CC_CALLER_BUSY, cc_request_state_change(), dialed_cc_interfaces::core_id, debug, and RETURN_IF_NOT_ENABLED.

Referenced by cc_generic_agent_recall().

◆ ast_cc_agent_recalling()

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

Tell the CC core that a caller is currently recalling.

Since
1.8

The main purpose of this is so that the core can alert the monitor to stop its available timer since the caller has begun its recall phase.

Parameters
core_idcore_id of the CC transaction
debugoptional string to print for debugging purposes
Return values
0Success
-1Failure

Definition at line 3872 of file ccss.c.

3873{
3874 va_list ap;
3875 int res;
3876
3878
3879 va_start(ap, debug);
3880 res = cc_request_state_change(CC_RECALLING, core_id, debug, ap);
3881 va_end(ap);
3882 return res;
3883}
@ CC_RECALLING
Definition ccss.c:217

References CC_RECALLING, cc_request_state_change(), dialed_cc_interfaces::core_id, debug, and RETURN_IF_NOT_ENABLED.

Referenced by generic_recall().

◆ ast_cc_agent_register()

int ast_cc_agent_register ( const struct ast_cc_agent_callbacks callbacks)

Register a set of agent callbacks with the core.

Since
1.8

This is made so that at agent creation time, the proper callbacks may be installed and the proper .init callback may be called for the monitor to establish private data.

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

Definition at line 1247 of file ccss.c.

1248{
1249 struct cc_agent_backend *backend;
1250
1252
1253 backend = ast_calloc(1, sizeof(*backend));
1254 if (!backend) {
1255 return -1;
1256 }
1257
1258 backend->callbacks = callbacks;
1262 return 0;
1263}
#define ast_calloc(num, len)
A wrapper for calloc()
Definition astmm.h:202
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition linkedlists.h:52
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
#define AST_RWLIST_INSERT_TAIL
struct @506 callbacks
const struct ast_cc_agent_callbacks * callbacks
Definition ccss.c:1242
struct cc_agent_backend * next
Definition ccss.c:1241

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

Referenced by load_module(), and load_module().

◆ ast_cc_agent_set_interfaces_chanvar()

int ast_cc_agent_set_interfaces_chanvar ( struct ast_channel chan)

Set the first level CC_INTERFACES channel variable for a channel.

Since
1.8
Note
Implementers of protocol-specific CC agents should call this function after calling ast_setup_cc_recall_datastore.
This function will lock the channel as well as the list of monitors stored on the channel's CC recall datastore, though neither are held at the same time. Callers of this function should be aware of potential lock ordering problems that may arise.

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

Parameters
chanThe channel to set the CC_INTERFACES variable on

Definition at line 3654 of file ccss.c.

3655{
3656 struct ast_datastore *recall_datastore;
3657 struct cc_monitor_tree *interface_tree;
3658 struct ast_cc_monitor *monitor;
3659 struct cc_recall_ds_data *recall_data;
3660 struct ast_str *str = ast_str_create(64);
3661 int core_id;
3662
3664
3665 if (!str) {
3666 return -1;
3667 }
3668
3669 ast_channel_lock(chan);
3670 if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
3671 ast_channel_unlock(chan);
3672 ast_free(str);
3673 return -1;
3674 }
3675 recall_data = recall_datastore->data;
3676 interface_tree = recall_data->interface_tree;
3677 core_id = recall_data->core_id;
3678 ast_channel_unlock(chan);
3679
3680 AST_LIST_LOCK(interface_tree);
3681 monitor = AST_LIST_FIRST(interface_tree);
3683 AST_LIST_UNLOCK(interface_tree);
3684
3685 pbx_builtin_setvar_helper(chan, "CC_INTERFACES", ast_str_buffer(str));
3686 ast_log_dynamic_level(cc_logger_level, "Core %d: CC_INTERFACES set to %s\n",
3687 core_id, ast_str_buffer(str));
3688
3689 ast_free(str);
3690 return 0;
3691}
const char * str
Definition app_jack.c:150
#define ast_free(a)
Definition astmm.h:180
static const struct ast_datastore_info recall_ds_info
Definition ccss.c:3417
static void build_cc_interfaces_chanvar(struct ast_cc_monitor *starting_point, struct ast_str **str)
Definition ccss.c:3611
static int cc_logger_level
Definition ccss.c:149
#define ast_channel_lock(chan)
Definition channel.h:2982
#define ast_channel_unlock(chan)
Definition channel.h:2983
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition channel.c:2389
#define ast_log_dynamic_level(level,...)
Send a log message to a dynamically registered log level.
#define AST_LIST_LOCK(head)
Locks a list.
Definition linkedlists.h:40
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition strings.h:659
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition strings.h:761
Structure for a data store object.
Definition datastore.h:64
void * data
Definition datastore.h:66
Support for dynamic strings.
Definition strings.h:623
The "tree" of interfaces that is dialed.
Definition ccss.c:339
struct cc_monitor_tree * interface_tree
Definition ccss.c:3393

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_logger_level, cc_recall_ds_data::core_id, ast_datastore::data, cc_recall_ds_data::interface_tree, NULL, pbx_builtin_setvar_helper(), recall_ds_info, RETURN_IF_NOT_ENABLED, and str.

Referenced by generic_recall().

◆ ast_cc_agent_status_response()

int ast_cc_agent_status_response ( int  core_id,
enum ast_device_state  devstate 
)

Response with a caller's current status.

When an ISDN PTMP monitor requests the caller's status, the agent must respond to the request using this function. For simplicity it is recommended that the devstate parameter be one of AST_DEVICE_INUSE or AST_DEVICE_NOT_INUSE.

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

Definition at line 4148 of file ccss.c.

4149{
4151 struct cc_core_instance *core_instance;
4152 int res;
4153
4155
4156 args = ast_calloc(1, sizeof(*args));
4157 if (!args) {
4158 return -1;
4159 }
4160
4161 core_instance = find_cc_core_instance(core_id);
4162 if (!core_instance) {
4163 ast_free(args);
4164 return -1;
4165 }
4166
4167 args->core_instance = core_instance;
4168 args->devstate = devstate;
4169
4171 if (res) {
4172 cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed");
4173 ast_free(args);
4174 }
4175 return res;
4176}
static struct ast_taskprocessor * cc_core_taskprocessor
Definition ccss.c:141
static struct cc_core_instance * find_cc_core_instance(const int core_id)
Definition ccss.c:447
static int cc_status_response(void *data)
Definition ccss.c:4127
int ast_taskprocessor_push(struct ast_taskprocessor *tps, int(*task_exe)(void *datap), void *datap) attribute_warn_unused_result
Push a task into the specified taskprocessor queue and signal the taskprocessor thread.

References args, ast_calloc, ast_free, ast_taskprocessor_push(), cc_core_taskprocessor, cc_status_response(), cc_unref(), cc_core_instance::core_id, find_cc_core_instance(), and RETURN_IF_NOT_ENABLED.

Referenced by cc_generic_agent_status_request().

◆ ast_cc_agent_unregister()

void ast_cc_agent_unregister ( const struct ast_cc_agent_callbacks callbacks)

Unregister a set of agent callbacks with the core.

Since
1.8

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

Parameters
callbacksThe callbacks used by the agent implementation

Definition at line 1265 of file ccss.c.

1266{
1267 struct cc_agent_backend *backend;
1268
1270
1273 if (backend->callbacks == callbacks) {
1275 ast_free(backend);
1276 break;
1277 }
1278 }
1281}
#define AST_RWLIST_REMOVE_CURRENT
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
#define AST_RWLIST_TRAVERSE_SAFE_END

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, callbacks, cc_agent_backend::next, and RETURN_IF_NOT_ENABLED.

Referenced by __unload_module(), and unload_module().

◆ ast_cc_available_timer_expire()

int ast_cc_available_timer_expire ( const void *  data)

Scheduler callback for available timer expiration.

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

Definition at line 1523 of file ccss.c.

1524{
1525 struct ast_cc_monitor *monitor = (struct ast_cc_monitor *) data;
1526 int res;
1527
1529
1530 monitor->available_timer_id = -1;
1531 res = ast_cc_monitor_failed(monitor->core_id, monitor->interface->device_name, "Available timer expired for monitor");
1532 cc_unref(monitor, "Unref reference from scheduler\n");
1533 return res;
1534}
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.
Definition ccss.c:3988
char device_name[1]
Definition ccss.h:802
struct ast_cc_interface * interface
Definition ccss.h:480
int core_id
Definition ccss.h:494
int available_timer_id
Definition ccss.h:513

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 RETURN_IF_NOT_ENABLED.

Referenced by cc_generic_monitor_request_cc().

◆ ast_cc_build_frame()

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

Create a CC Control frame.

Since
1.8

chan_dahdi is weird. It doesn't seem to actually queue frames when it needs to tell an application something. Instead it wakes up, tells the application that it has data ready, and then based on set flags, creates the proper frame type. For chan_dahdi, we provide this function. It provides us the data we need, and we'll make its frame for it.

Parameters
chanA channel involved in the call. What we want is on a datastore on both incoming and outgoing so either may be provided
cc_paramsThe CC configuration parameters for the outbound target
monitor_typeThe type of monitor to use when CC is requested
device_nameThe name of the outbound target device.
dialstringThe dial string used when calling this specific interface
serviceWhat kind of CC service is being offered. (CCBS/CCNR/etc...)
private_dataIf 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]frameThe frame we will be returning to the caller. It is vital that ast_frame_free be called on this frame since the payload will be allocated on the heap.
Return values
-1Failure. At some point there was a failure. Do not attempt to use the frame in this case.
0Success

Definition at line 4235 of file ccss.c.

4239{
4240 struct cc_control_payload *payload;
4241
4243
4244 payload = ast_calloc(1, sizeof(*payload));
4245 if (!payload) {
4246 return -1;
4247 }
4248 if (cc_build_payload(chan, cc_params, monitor_type, device_name, dialstring, service, private_data, payload)) {
4249 /* Something screwed up, we can't make a frame with this */
4250 ast_free(payload);
4251 return -1;
4252 }
4255 frame->data.ptr = payload;
4256 frame->datalen = sizeof(*payload);
4257 frame->mallocd = AST_MALLOCD_DATA;
4258 return 0;
4259}
enum ast_cc_service_type service
Definition ccss.c:399
static int cc_build_payload(struct ast_channel *chan, struct ast_cc_config_params *cc_params, const char *monitor_type, const char *const device_name, const char *dialstring, enum ast_cc_service_type service, void *private_data, struct cc_control_payload *payload)
Definition ccss.c:4178
#define AST_MALLOCD_DATA
@ AST_FRAME_CONTROL
struct ast_frame_subclass subclass
enum ast_frame_type frametype
union ast_frame::@239 data
The payload for an AST_CONTROL_CC frame.
Definition ccss.c:237
const char * monitor_type
The type of monitor to allocate.
Definition ccss.c:255
char device_name[AST_CHANNEL_NAME]
Name of device to be monitored.
Definition ccss.c:308
char dialstring[AST_CHANNEL_NAME]
Recall dialstring.
Definition ccss.c:320
void * private_data
Private data allocated by the callee.
Definition ccss.c:272

References ast_calloc, AST_CONTROL_CC, AST_FRAME_CONTROL, ast_free, AST_MALLOCD_DATA, cc_build_payload(), ast_frame::data, ast_frame::datalen, cc_control_payload::device_name, cc_control_payload::dialstring, ast_frame::frametype, ast_frame_subclass::integer, ast_frame::mallocd, cc_control_payload::monitor_type, cc_control_payload::private_data, ast_frame::ptr, RETURN_IF_NOT_ENABLED, service, and ast_frame::subclass.

Referenced by ast_queue_cc_frame().

◆ ast_cc_busy_interface()

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

Callback made from ast_cc_callback for certain channel types.

Since
1.8
Parameters
inboundIncoming asterisk channel.
cc_paramsThe CC configuration parameters for the outbound target
monitor_typeThe type of monitor to use when CC is requested
device_nameThe name of the outbound target device.
dialstringThe dial string used when calling this specific interface
private_dataIf a native monitor is being used, and some channel-driver-specific private data has been allocated, then this parameter should contain a pointer to that data. If using a generic monitor, this parameter should remain NULL. Note that if this function should fail at some point, it is the responsibility of the caller to free the private data upon return.

For channel types that fail ast_request when the device is busy, we call into the channel driver with ast_cc_callback. This is the callback that is called in that case for each device found which could have been returned by ast_request.

This function creates a CC control frame payload, simulating the act of reading it from the nonexistent outgoing channel's frame queue. We then handle this simulated frame just as we would a normal CC frame which had actually been queued by the channel driver.

Definition at line 4296 of file ccss.c.

4298{
4299 struct cc_control_payload payload;
4300
4302
4303 if (cc_build_payload(inbound, cc_params, monitor_type, device_name, dialstring, AST_CC_CCBS, private_data, &payload)) {
4304 /* Something screwed up. Don't try to handle this payload */
4306 return;
4307 }
4308 ast_handle_cc_control_frame(inbound, NULL, &payload);
4309}
void ast_handle_cc_control_frame(struct ast_channel *inbound, struct ast_channel *outbound, void *frame_data)
Properly react to a CC control frame.
Definition ccss.c:2334
static void call_destructor_with_no_monitor(const char *const monitor_type, void *private_data)
Definition ccss.c:2233

References AST_CC_CCBS, ast_handle_cc_control_frame(), call_destructor_with_no_monitor(), cc_build_payload(), cc_control_payload::device_name, cc_control_payload::dialstring, cc_control_payload::monitor_type, NULL, cc_control_payload::private_data, and RETURN_IF_NOT_ENABLED.

Referenced by dial_exec_full().

◆ ast_cc_call_failed()

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

Make CCBS available in the case that ast_call fails.

Since
1.8

In some situations, notably if a call-limit is reached in SIP, ast_call will fail due to Asterisk's knowing that the desired device is currently busy. In such a situation, CCBS should be made available to the caller.

One caveat is that this may only be used if generic monitoring is being used. The reason is that since Asterisk determined that the device was busy without actually placing a call to it, the far end will have no idea what call we are requesting call completion for if we were to send a call completion request.

Definition at line 4261 of file ccss.c.

4262{
4263 char device_name[AST_CHANNEL_NAME];
4264 struct cc_control_payload payload;
4265 struct ast_cc_config_params *cc_params;
4266
4268
4270 /* It doesn't make sense to try to offer CCBS to the caller if the reason for ast_call
4271 * failing is something other than busy or congestion
4272 */
4273 return;
4274 }
4275
4277 if (!cc_params) {
4278 return;
4279 }
4281 /* This sort of CCBS only works if using generic CC. For native, we would end up sending
4282 * a CC request for a non-existent call. The far end will reject this every time
4283 */
4284 return;
4285 }
4286
4287 ast_channel_get_device_name(outgoing, device_name, sizeof(device_name));
4288 if (cc_build_payload(outgoing, cc_params, AST_CC_GENERIC_MONITOR_TYPE, device_name,
4289 dialstring, AST_CC_CCBS, NULL, &payload)) {
4290 /* Something screwed up, we can't make a frame with this */
4291 return;
4292 }
4293 ast_handle_cc_control_frame(incoming, outgoing, &payload);
4294}
#define AST_CAUSE_CONGESTION
Definition causes.h:153
#define AST_CAUSE_BUSY
Definition causes.h:149
enum ast_cc_monitor_policies ast_get_cc_monitor_policy(struct ast_cc_config_params *config)
Get the cc_monitor_policy.
Definition ccss.c:900
#define AST_CC_GENERIC_MONITOR_TYPE
Definition ccss.h:455
int ast_channel_get_device_name(struct ast_channel *chan, char *device_name, size_t name_buffer_length)
Get a device name given its channel structure.
Definition channel.c:10544
int ast_channel_hangupcause(const struct ast_channel *chan)
#define AST_CHANNEL_NAME
Definition channel.h:173
struct ast_cc_config_params * ast_channel_get_cc_config_params(struct ast_channel *chan)
Get the CCSS parameters from a channel.
Definition channel.c:10518

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_hangupcause(), AST_CHANNEL_NAME, ast_get_cc_monitor_policy(), ast_handle_cc_control_frame(), cc_build_payload(), cc_control_payload::device_name, NULL, and RETURN_IF_NOT_ENABLED.

Referenced by dial_exec_full().

◆ ast_cc_call_init()

int ast_cc_call_init ( struct ast_channel chan,
int *  ignore_cc 
)

Start the CC process on a call.

Since
1.8

Whenever a CC-capable application, such as Dial, wishes to engage in CC activity, it initiates the process by calling this function. If the CC core should discover that a previous application has called ast_ignore_cc on this channel or a "parent" channel, then the value of the ignore_cc integer passed in will be set nonzero.

The ignore_cc parameter is a convenience parameter. It can save an application the trouble of trying to call CC APIs when it knows that it should just ignore further attempts at CC actions.

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

Definition at line 2429 of file ccss.c.

2430{
2431 /* There are three situations to deal with here:
2432 *
2433 * 1. The channel does not have a dialed_cc_interfaces datastore on
2434 * it. This means that this is the first time that Dial has
2435 * been called. We need to create/initialize the datastore.
2436 *
2437 * 2. The channel does have a cc_interface datastore on it and
2438 * the "ignore" indicator is 0. This means that a Local channel
2439 * was called by a "parent" dial. We can check the datastore's
2440 * parent field to see who the root of this particular dial tree
2441 * is.
2442 *
2443 * 3. The channel does have a cc_interface datastore on it and
2444 * the "ignore" indicator is 1. This means that a second Dial call
2445 * is being made from an extension. In this case, we do not
2446 * want to make any additions/modifications to the datastore. We
2447 * will instead set a flag to indicate that CCSS is completely
2448 * disabled for this Dial attempt.
2449 */
2450
2451 struct ast_datastore *cc_interfaces_datastore;
2453 struct ast_cc_monitor *monitor;
2454 struct ast_cc_config_params *cc_params;
2455
2456 if (!global_enabled) {
2457 ast_debug(3, "CCSS disabled globally\n");
2458 *ignore_cc = 1;
2459 return 0;
2460 }
2461
2462 ast_channel_lock(chan);
2463
2464 cc_params = ast_channel_get_cc_config_params(chan);
2465 if (!cc_params) {
2466 ast_channel_unlock(chan);
2467 return -1;
2468 }
2469 if (ast_get_cc_agent_policy(cc_params) == AST_CC_AGENT_NEVER) {
2470 /* We can't offer CC to this caller anyway, so don't bother with CC on this call
2471 */
2472 *ignore_cc = 1;
2473 ast_channel_unlock(chan);
2474 ast_log_dynamic_level(cc_logger_level, "Agent policy for %s is 'never'. CC not possible\n", ast_channel_name(chan));
2475 return 0;
2476 }
2477
2478 if (!(cc_interfaces_datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL))) {
2479 /* Situation 1 has occurred */
2480 ast_channel_unlock(chan);
2481 return cc_interfaces_datastore_init(chan);
2482 }
2483 interfaces = cc_interfaces_datastore->data;
2484 ast_channel_unlock(chan);
2485
2486 if (interfaces->ignore) {
2487 /* Situation 3 has occurred */
2488 *ignore_cc = 1;
2489 ast_log_dynamic_level(cc_logger_level, "Datastore is present with ignore flag set. Ignoring CC offers on this call\n");
2490 return 0;
2491 }
2492
2493 /* Situation 2 has occurred */
2494 if (!(monitor = cc_extension_monitor_init(ast_channel_exten(chan),
2495 ast_channel_context(chan),
2496 interfaces->dial_parent_id))) {
2497 return -1;
2498 }
2499 monitor->core_id = interfaces->core_id;
2500 AST_LIST_LOCK(interfaces->interface_tree);
2501 cc_ref(monitor, "monitor tree's reference to the monitor");
2502 AST_LIST_INSERT_TAIL(interfaces->interface_tree, monitor, next);
2503 AST_LIST_UNLOCK(interfaces->interface_tree);
2504 interfaces->dial_parent_id = monitor->id;
2505 cc_unref(monitor, "Unref monitor's allocation reference");
2506 return 0;
2507}
static int global_enabled
Definition ccss.c:118
static const struct ast_datastore_info dialed_cc_interfaces_info
Definition ccss.c:2006
enum ast_cc_agent_policies ast_get_cc_agent_policy(struct ast_cc_config_params *config)
Get the cc_agent_policy.
Definition ccss.c:883
static struct ast_cc_monitor * cc_extension_monitor_init(const char *const exten, const char *const context, const unsigned int parent_id)
Definition ccss.c:2108
static int cc_interfaces_datastore_init(struct ast_channel *chan)
Definition ccss.c:2157
const char * ast_channel_name(const struct ast_channel *chan)
const char * ast_channel_context(const struct ast_channel *chan)
const char * ast_channel_exten(const struct ast_channel *chan)
static struct ao2_container * interfaces
Container for registered format interfaces.
Definition format.c:65
#define ast_debug(level,...)
Log a DEBUG message.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
unsigned int id
Definition ccss.h:485

References AST_CC_AGENT_NEVER, ast_channel_context(), ast_channel_datastore_find(), ast_channel_exten(), ast_channel_get_cc_config_params(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_debug, 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_logger_level, cc_ref(), cc_unref(), ast_cc_monitor::core_id, ast_datastore::data, dialed_cc_interfaces_info, global_enabled, ast_cc_monitor::id, interfaces, and NULL.

Referenced by dial_exec_full().

◆ ast_cc_callback()

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

Run a callback for potential matching destinations.

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

Definition at line 4311 of file ccss.c.

4312{
4313 const struct ast_channel_tech *chantech;
4314
4316
4317 chantech = ast_get_channel_tech(tech);
4318 if (chantech && chantech->cc_callback) {
4319 chantech->cc_callback(inbound, dest, callback);
4320 }
4321
4322 return 0;
4323}
const struct ast_channel_tech * ast_get_channel_tech(const char *name)
Get a channel technology structure by name.
Definition channel.c:592
static struct ast_channel * callback(struct ast_channelstorage_instance *driver, ao2_callback_data_fn *cb_fn, void *arg, void *data, int ao2_flags, int rdlock)
Structure to describe a channel "technology", ie a channel driver See for examples:
Definition channel.h:648
int(* cc_callback)(struct ast_channel *inbound, const char *dest, ast_cc_callback_fn callback)
Call a function with cc parameters as a function parameter.
Definition channel.h:847

References ast_get_channel_tech(), callback(), ast_channel_tech::cc_callback, and RETURN_IF_NOT_ENABLED.

Referenced by dial_exec_full().

◆ ast_cc_completed()

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

Indicate recall has been acknowledged.

Since
1.8

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

Parameters
chanThe inbound channel making the CC recall
debugoptional string to print for debugging purposes
Return values
0Success
-1Failure

Definition at line 3885 of file ccss.c.

3886{
3887 struct ast_datastore *recall_datastore;
3888 struct cc_recall_ds_data *recall_data;
3889 int core_id;
3890 va_list ap;
3891 int res;
3892
3894
3895 ast_channel_lock(chan);
3896 if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
3897 /* Silly! Why did you call this function if there's no recall DS? */
3898 ast_channel_unlock(chan);
3899 return -1;
3900 }
3901 recall_data = recall_datastore->data;
3902 if (recall_data->nested || recall_data->ignore) {
3903 /* If this is being called from a nested Dial, it is too
3904 * early to determine if the recall has actually completed.
3905 * The outermost dial is the only one with the authority to
3906 * declare the recall to be complete.
3907 *
3908 * Similarly, if this function has been called when the
3909 * recall has progressed beyond the first dial, this is not
3910 * a legitimate time to declare the recall to be done. In fact,
3911 * that should have been done already.
3912 */
3913 ast_channel_unlock(chan);
3914 return -1;
3915 }
3916 core_id = recall_data->core_id;
3917 ast_channel_unlock(chan);
3918 va_start(ap, debug);
3920 va_end(ap);
3921 return res;
3922}
@ CC_COMPLETE
Definition ccss.c:221

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, debug, cc_recall_ds_data::ignore, cc_recall_ds_data::nested, NULL, recall_ds_info, and RETURN_IF_NOT_ENABLED.

Referenced by wait_for_answer().

◆ ast_cc_config_params_destroy()

void ast_cc_config_params_destroy ( struct ast_cc_config_params params)

Free memory from CCSS configuration params.

Note
Just a call to ast_free for now...
Parameters
paramsPointer to structure whose memory we need to free

Definition at line 714 of file ccss.c.

715{
716 ast_free(params);
717}

References ast_free.

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

◆ ast_cc_copy_config_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

Since
1.8

For now, this is a simple memcpy, but this function is necessary since the size of an ast_cc_config_params structure is unknown outside of main/ccss.c. Also, this allows for easier expansion of the function in case it becomes more complex than just a memcpy.

Parameters
srcThe structure from which data is copied
destThe structure to which data is copied

Definition at line 876 of file ccss.c.

877{
878 if (dest && src) {
879 *dest = *src;
880 }
881}

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

◆ ast_cc_default_config_params()

void ast_cc_default_config_params ( struct ast_cc_config_params params)

Set the specified CC config params to default values.

Since
1.8

This is just like ast_cc_copy_config_params() and could be used in place of it if you need to set the config params to defaults instead. You are simply "copying" defaults into the destination.

Parameters
paramsCC config params to set to default values.

Definition at line 694 of file ccss.c.

695{
696 *params = cc_default_params;
697}
static const struct ast_cc_config_params cc_default_params
Definition ccss.c:681

References cc_default_params.

Referenced by __ast_cc_config_params_init().

◆ ast_cc_extension_monitor_add_dialstring()

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

Add a child dialstring to an extension monitor.

Since
1.8

Whenever we request a channel, the parent extension monitor needs to store the dialstring of the device requested. The reason is so that we can call the device back during the recall even if we are not monitoring the device.

Parameters
incomingThe caller's channel
dialstringThe dialstring used when requesting the outbound channel
device_nameThe device name associated with the requested outbound channel

Definition at line 2022 of file ccss.c.

2023{
2024 struct ast_datastore *cc_datastore;
2025 struct dialed_cc_interfaces *cc_interfaces;
2026 struct ast_cc_monitor *monitor;
2027 struct extension_monitor_pvt *extension_pvt;
2028 struct extension_child_dialstring *child_dialstring;
2029 struct cc_monitor_tree *interface_tree;
2030 int id;
2031
2033
2034 ast_channel_lock(incoming);
2035 if (!(cc_datastore = ast_channel_datastore_find(incoming, &dialed_cc_interfaces_info, NULL))) {
2036 ast_channel_unlock(incoming);
2037 return;
2038 }
2039
2040 cc_interfaces = cc_datastore->data;
2041 interface_tree = cc_interfaces->interface_tree;
2042 id = cc_interfaces->dial_parent_id;
2043 ast_channel_unlock(incoming);
2044
2045 AST_LIST_LOCK(interface_tree);
2046 AST_LIST_TRAVERSE(interface_tree, monitor, next) {
2047 if (monitor->id == id) {
2048 break;
2049 }
2050 }
2051
2052 if (!monitor) {
2053 AST_LIST_UNLOCK(interface_tree);
2054 return;
2055 }
2056
2057 extension_pvt = monitor->private_data;
2058 if (!(child_dialstring = ast_calloc(1, sizeof(*child_dialstring)))) {
2059 AST_LIST_UNLOCK(interface_tree);
2060 return;
2061 }
2062 ast_copy_string(child_dialstring->original_dialstring, dialstring, sizeof(child_dialstring->original_dialstring));
2063 ast_copy_string(child_dialstring->device_name, device_name, sizeof(child_dialstring->device_name));
2064 child_dialstring->is_valid = 1;
2065 AST_LIST_INSERT_TAIL(&extension_pvt->child_dialstrings, child_dialstring, next);
2066 AST_LIST_UNLOCK(interface_tree);
2067}
enum queue_result id
Definition app_queue.c:1771
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition strings.h:425
void * private_data
Data that is private to a monitor technology.
Definition ccss.h:527
struct cc_monitor_tree * interface_tree
Definition ccss.c:1946
unsigned int dial_parent_id
Definition ccss.c:1919
Data regarding an extension monitor's child's dialstrings.
Definition ccss.c:1777
char device_name[AST_CHANNEL_NAME]
The name of the device being dialed.
Definition ccss.c:1812
int is_valid
Is this structure valid for use in CC_INTERFACES?
Definition ccss.c:1827
char original_dialstring[AST_CHANNEL_NAME]
the original dialstring used to call a particular device
Definition ccss.c:1793
Private data for an extension monitor.
Definition ccss.c:1834
struct extension_monitor_pvt::@348 child_dialstrings

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, dialed_cc_interfaces_info, id, ast_cc_monitor::id, dialed_cc_interfaces::interface_tree, extension_child_dialstring::is_valid, NULL, extension_child_dialstring::original_dialstring, ast_cc_monitor::private_data, and RETURN_IF_NOT_ENABLED.

Referenced by dial_exec_full().

◆ ast_cc_failed()

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

Indicate failure has occurred.

Since
1.8

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

Parameters
core_idcore_id of the CC transaction
debugoptional string to print for debugging purposes
Return values
0Success
-1Failure

Definition at line 3924 of file ccss.c.

3925{
3926 va_list ap;
3927 int res;
3928
3930
3931 va_start(ap, debug);
3932 res = cc_request_state_change(CC_FAILED, core_id, debug, ap);
3933 va_end(ap);
3934 return res;
3935}
@ CC_FAILED
Definition ccss.c:226

References CC_FAILED, cc_request_state_change(), cc_recall_ds_data::core_id, debug, and RETURN_IF_NOT_ENABLED.

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

◆ ast_cc_get_current_core_id()

int ast_cc_get_current_core_id ( struct ast_channel chan)

Get the core id for the current call.

Since
1.8

The main use of this function is for channel drivers who queue an AST_CONTROL_CC frame. A channel driver may call this function in order to get the core_id for what may become a CC request. This way, when monitor functions are called which use a core_id as a means of identification, the channel driver will have saved this information.

The channel given to this function may be an inbound or outbound channel. Both will have the necessary info on it.

Parameters
chanThe channel from which to get the core_id.
Return values
core_idon success
-1Failure

Definition at line 2514 of file ccss.c.

2515{
2516 struct ast_datastore *datastore;
2517 struct dialed_cc_interfaces *cc_interfaces;
2518 int core_id_return;
2519
2521
2522 ast_channel_lock(chan);
2523 if (!(datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL))) {
2524 ast_channel_unlock(chan);
2525 return -1;
2526 }
2527
2528 cc_interfaces = datastore->data;
2529 core_id_return = cc_interfaces->ignore ? -1 : cc_interfaces->core_id;
2530 ast_channel_unlock(chan);
2531 return core_id_return;
2532
2533}

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

◆ ast_cc_get_monitor_by_recall_core_id()

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.

Since
1.8

The function ast_cc_is_recall is helpful for determining if a call to a specific channel is a recall. However, once you have determined that this is a recall, you will most likely need access to the private data within the associated monitor. This function is what one uses to get that monitor.

Note
This function locks the list of monitors that correspond to the core_id passed in. Be sure that you have no potential lock order issues when calling this function.
Parameters
core_idThe core ID to which this recall corresponds. This likely will have been obtained using the ast_cc_is_recall function
device_nameWhich device to find the monitor for.
Return values
NULLAppropriate monitor does not exist
non-NULLThe monitor to use for this recall

Definition at line 3542 of file ccss.c.

3543{
3544 struct cc_core_instance *core_instance = find_cc_core_instance(core_id);
3545 struct ast_cc_monitor *monitor_iter;
3546
3548
3549 if (!core_instance) {
3550 return NULL;
3551 }
3552
3553 AST_LIST_LOCK(core_instance->monitors);
3554 AST_LIST_TRAVERSE(core_instance->monitors, monitor_iter, next) {
3555 if (!strcmp(monitor_iter->interface->device_name, device_name)) {
3556 /* Found a monitor. */
3557 cc_ref(monitor_iter, "Hand the requester of the monitor a reference");
3558 break;
3559 }
3560 }
3561 AST_LIST_UNLOCK(core_instance->monitors);
3562 cc_unref(core_instance, "Done with core instance ref in ast_cc_get_monitor_by_recall_core_id");
3563 return monitor_iter;
3564}
struct ast_cc_monitor * next
Definition ccss.h:528
struct cc_monitor_tree * monitors
Definition ccss.c:360

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

◆ ast_cc_get_param()

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

get a CCSS configuration parameter, given its name

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

Definition at line 780 of file ccss.c.

782{
783 const char *value = NULL;
784
785 if (!strcasecmp(name, "cc_callback_sub")) {
787 } else if (!strcasecmp(name, "cc_agent_policy")) {
789 } else if (!strcasecmp(name, "cc_monitor_policy")) {
791 } else if (!strcasecmp(name, "cc_agent_dialstring")) {
793 }
794 if (value) {
795 ast_copy_string(buf, value, buf_len);
796 return 0;
797 }
798
799 /* The rest of these are all ints of some sort and require some
800 * snprintf-itude
801 */
802
803 if (!strcasecmp(name, "cc_offer_timer")) {
804 snprintf(buf, buf_len, "%u", ast_get_cc_offer_timer(params));
805 } else if (!strcasecmp(name, "ccnr_available_timer")) {
806 snprintf(buf, buf_len, "%u", ast_get_ccnr_available_timer(params));
807 } else if (!strcasecmp(name, "ccbs_available_timer")) {
808 snprintf(buf, buf_len, "%u", ast_get_ccbs_available_timer(params));
809 } else if (!strcasecmp(name, "cc_max_agents")) {
810 snprintf(buf, buf_len, "%u", ast_get_cc_max_agents(params));
811 } else if (!strcasecmp(name, "cc_max_monitors")) {
812 snprintf(buf, buf_len, "%u", ast_get_cc_max_monitors(params));
813 } else if (!strcasecmp(name, "cc_recall_timer")) {
814 snprintf(buf, buf_len, "%u", ast_get_cc_recall_timer(params));
815 } else {
816 ast_log(LOG_WARNING, "%s is not a valid CC parameter. Ignoring.\n", name);
817 return -1;
818 }
819
820 return 0;
821}
#define ast_log
Definition astobj2.c:42
unsigned int ast_get_cc_recall_timer(struct ast_cc_config_params *config)
Get the cc_recall_timer.
Definition ccss.c:947
static const char * agent_policy_to_str(enum ast_cc_agent_policies policy)
Definition ccss.c:749
unsigned int ast_get_cc_offer_timer(struct ast_cc_config_params *config)
Get the cc_offer_timer.
Definition ccss.c:917
unsigned int ast_get_ccbs_available_timer(struct ast_cc_config_params *config)
Get the ccbs_available_timer.
Definition ccss.c:962
unsigned int ast_get_ccnr_available_timer(struct ast_cc_config_params *config)
Get the ccnr_available_timer.
Definition ccss.c:932
unsigned int ast_get_cc_max_agents(struct ast_cc_config_params *config)
Get the cc_max_agents.
Definition ccss.c:991
const char * ast_get_cc_callback_sub(struct ast_cc_config_params *config)
Get the name of the callback subroutine.
Definition ccss.c:1011
unsigned int ast_get_cc_max_monitors(struct ast_cc_config_params *config)
Get the cc_max_monitors.
Definition ccss.c:1001
static const char * monitor_policy_to_str(enum ast_cc_monitor_policies policy)
Definition ccss.c:764
const char * ast_get_cc_agent_dialstring(struct ast_cc_config_params *config)
Get the cc_agent_dialstring.
Definition ccss.c:977
char buf[BUFSIZE]
Definition eagi_proxy.c:66
static const char name[]
Definition format_mp3.c:68
#define LOG_WARNING
int value
Definition syslog.c:37

References agent_policy_to_str(), ast_copy_string(), ast_get_cc_agent_dialstring(), ast_get_cc_agent_policy(), ast_get_cc_callback_sub(), 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, buf, LOG_WARNING, monitor_policy_to_str(), name, NULL, and value.

Referenced by acf_cc_read().

◆ ast_cc_is_config_param()

int ast_cc_is_config_param ( const char *const  name)

Is this a CCSS configuration parameter?

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

Definition at line 862 of file ccss.c.

863{
864 return (!strcasecmp(name, "cc_agent_policy") ||
865 !strcasecmp(name, "cc_monitor_policy") ||
866 !strcasecmp(name, "cc_offer_timer") ||
867 !strcasecmp(name, "ccnr_available_timer") ||
868 !strcasecmp(name, "ccbs_available_timer") ||
869 !strcasecmp(name, "cc_max_agents") ||
870 !strcasecmp(name, "cc_max_monitors") ||
871 !strcasecmp(name, "cc_callback_sub") ||
872 !strcasecmp(name, "cc_agent_dialstring") ||
873 !strcasecmp(name, "cc_recall_timer"));
874}

References name.

Referenced by process_dahdi().

◆ ast_cc_is_enabled()

int ast_cc_is_enabled ( void  )

Determine if CCSS is enabled.

Since
23.2.0
22.8.0
20.18.0
Return values
0Not enabled.
1Enabled

Definition at line 4540 of file ccss.c.

4541{
4542 return global_enabled;
4543}

References global_enabled.

Referenced by ast_channel_get_cc_config_params(), ast_unreal_call_setup(), ast_unreal_new_channels(), and local_call().

◆ ast_cc_is_recall()

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

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

Since
1.8

When a CC recall happens, it is important on the called side to know that the call is a CC recall and not a normal call. This function will determine first if the call in question is a CC recall. Then it will determine based on the chan parameter if the channel is being called is being recalled.

As a quick example, let's say a call is placed to SIP/1000 and SIP/1000 is currently on the phone. The caller requests CCBS. SIP/1000 finishes his call, and so the caller attempts to recall. Now, the dialplan administrator has set up this second call so that not only is SIP/1000 called, but also SIP/2000 is called. If SIP/1000's channel were passed to this function, the return value would be non-zero, but if SIP/2000's channel were passed into this function, then the return would be 0 since SIP/2000 was not one of the original devices dialed.

Note
This function may be called on a calling channel as well to determine if it is part of a CC recall.
This function will lock the channel as well as the list of monitors on the channel datastore, though the locks are not held at the same time. Be sure that you have no potential lock order issues here.
Parameters
chanThe channel to check
[out]core_idIf this is a valid CC recall, the core_id of the failed call will be placed in this output parameter
monitor_typeClarify which type of monitor type we are looking for if this is happening on a called channel. For incoming channels, this parameter is not used.
Return values
0Either this is not a recall or it is but this channel is not part of the recall
non-zeroThis is a recall and the channel in question is directly involved.

Definition at line 3459 of file ccss.c.

3460{
3461 struct ast_datastore *recall_datastore;
3462 struct cc_recall_ds_data *recall_data;
3463 struct cc_monitor_tree *interface_tree;
3464 char device_name[AST_CHANNEL_NAME];
3465 struct ast_cc_monitor *device_monitor;
3466 int core_id_candidate;
3467
3469
3471
3472 *core_id = -1;
3473
3474 ast_channel_lock(chan);
3475 if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
3476 /* Obviously not a recall if the datastore isn't present */
3477 ast_channel_unlock(chan);
3478 return 0;
3479 }
3480
3481 recall_data = recall_datastore->data;
3482
3483 if (recall_data->ignore) {
3484 /* Though this is a recall, the call to this particular interface is not part of the
3485 * recall either because this is a call forward or because this is not the first
3486 * invocation of Dial during this call
3487 */
3488 ast_channel_unlock(chan);
3489 return 0;
3490 }
3491
3492 if (!recall_data->nested) {
3493 /* If the nested flag is not set, then this means that
3494 * the channel passed to this function is the caller making
3495 * the recall. This means that we shouldn't look through
3496 * the monitor tree for the channel because it shouldn't be
3497 * there. However, this is a recall though, so return true.
3498 */
3499 *core_id = recall_data->core_id;
3500 ast_channel_unlock(chan);
3501 return 1;
3502 }
3503
3504 if (ast_strlen_zero(monitor_type)) {
3505 /* If someone passed a NULL or empty monitor type, then it is clear
3506 * the channel they passed in was an incoming channel, and so searching
3507 * the list of dialed interfaces is not going to be helpful. Just return
3508 * false immediately.
3509 */
3510 ast_channel_unlock(chan);
3511 return 0;
3512 }
3513
3514 interface_tree = recall_data->interface_tree;
3515 ast_channel_get_device_name(chan, device_name, sizeof(device_name));
3516 /* We grab the value of the recall_data->core_id so that we
3517 * can unlock the channel before we start looking through the
3518 * interface list. That way we don't have to worry about a possible
3519 * clash between the channel lock and the monitor tree lock.
3520 */
3521 core_id_candidate = recall_data->core_id;
3522 ast_channel_unlock(chan);
3523
3524 /*
3525 * Now we need to find out if the channel device name
3526 * is in the list of interfaces in the called tree.
3527 */
3528 AST_LIST_LOCK(interface_tree);
3529 AST_LIST_TRAVERSE(interface_tree, device_monitor, next) {
3530 if (!strcmp(device_monitor->interface->device_name, device_name) &&
3531 !strcmp(device_monitor->interface->monitor_type, monitor_type)) {
3532 /* BOOM! Device is in the tree! We have a winner! */
3533 *core_id = core_id_candidate;
3534 AST_LIST_UNLOCK(interface_tree);
3535 return 1;
3536 }
3537 }
3538 AST_LIST_UNLOCK(interface_tree);
3539 return 0;
3540}
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition strings.h:65
const char * monitor_type
The type of monitor that should be used for this interface.
Definition ccss.h:793
#define ast_assert(a)
Definition utils.h:779

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(), ast_cc_monitor::core_id, cc_recall_ds_data::core_id, ast_datastore::data, ast_cc_interface::device_name, cc_recall_ds_data::ignore, ast_cc_monitor::interface, cc_recall_ds_data::interface_tree, ast_cc_interface::monitor_type, cc_recall_ds_data::nested, ast_cc_monitor::next, NULL, recall_ds_info, and RETURN_IF_NOT_ENABLED.

Referenced by cc_core_init_instance(), and wait_for_answer().

◆ ast_cc_monitor_callee_available()

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

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

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

Definition at line 3833 of file ccss.c.

3834{
3835 va_list ap;
3836 int res;
3837
3839
3840 va_start(ap, debug);
3841 res = cc_request_state_change(CC_CALLEE_READY, core_id, debug, ap);
3842 va_end(ap);
3843 return res;
3844}
@ CC_CALLEE_READY
Definition ccss.c:209

References CC_CALLEE_READY, cc_request_state_change(), dialed_cc_interfaces::core_id, debug, and RETURN_IF_NOT_ENABLED.

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

◆ ast_cc_monitor_count()

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

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

Since
1.8
Note
This function will lock the list of monitors stored on every instance of the CC core. Callers of this function should be aware of this and avoid any potential lock ordering problems.
Parameters
nameThe name of the monitored device
typeThe type of the monitored device (e.g. "generic")
Returns
The number of CC requests for the monitor

Definition at line 4438 of file ccss.c.

4439{
4440 struct count_monitors_cb_data data = {.device_name = name, .monitor_type = type,};
4441
4443
4444 ao2_t_callback(cc_core_instances, OBJ_NODATA, count_monitors_cb, &data, "Counting agents");
4445 ast_log_dynamic_level(cc_logger_level, "Counted %d monitors\n", data.count);
4446 return data.count;
4447}
@ OBJ_NODATA
Definition astobj2.h:1044
static int count_monitors_cb(void *obj, void *arg, int flags)
Definition ccss.c:4418
const char * device_name
Definition ccss.c:4413

References ao2_t_callback, ast_log_dynamic_level, cc_core_instances, cc_logger_level, count_monitors_cb_data::count, count_monitors_cb(), count_monitors_cb_data::device_name, name, OBJ_NODATA, RETURN_IF_NOT_ENABLED, and type.

Referenced by ast_queue_cc_frame().

◆ ast_cc_monitor_failed()

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

Indicate that a failure has occurred on a specific monitor.

Since
1.8

If a monitor should detect that a failure has occurred when communicating with its endpoint, then ast_cc_monitor_failed should be called. The big difference between ast_cc_monitor_failed and ast_cc_failed is that ast_cc_failed indicates a global failure for a CC transaction, where as ast_cc_monitor_failed is localized to a particular monitor. When ast_cc_failed is called, the entire CC transaction is torn down. When ast_cc_monitor_failed is called, only the monitor on which the failure occurred is pruned from the tree of monitors.

If there are no more devices left to monitor when this function is called, then the core will fail the CC transaction globally.

Parameters
core_idThe core ID for the CC transaction
monitor_nameThe name of the monitor on which the failure occurred
debugA debug message to print to the CC log

Definition at line 3988 of file ccss.c.

3989{
3990 struct ast_cc_monitor_failure_data *failure_data;
3991 int res;
3992 va_list ap;
3993
3995
3996 if (!(failure_data = ast_calloc(1, sizeof(*failure_data)))) {
3997 return -1;
3998 }
3999
4000 if (!(failure_data->device_name = ast_strdup(monitor_name))) {
4001 ast_free(failure_data);
4002 return -1;
4003 }
4004
4005 va_start(ap, debug);
4006 if (ast_vasprintf(&failure_data->debug, debug, ap) == -1) {
4007 va_end(ap);
4008 ast_free((char *)failure_data->device_name);
4009 ast_free(failure_data);
4010 return -1;
4011 }
4012 va_end(ap);
4013
4014 failure_data->core_id = core_id;
4015
4017 if (res) {
4018 ast_free((char *)failure_data->device_name);
4019 ast_free((char *)failure_data->debug);
4020 ast_free(failure_data);
4021 }
4022 return res;
4023}
#define ast_strdup(str)
A wrapper for strdup()
Definition astmm.h:241
#define ast_vasprintf(ret, fmt, ap)
A wrapper for vasprintf()
Definition astmm.h:278
static int cc_monitor_failed(void *data)
Definition ccss.c:3943
const char * device_name
Definition ccss.c:3938

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

Referenced by ast_cc_available_timer_expire().

◆ ast_cc_monitor_party_b_free()

int ast_cc_monitor_party_b_free ( int  core_id)

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

When an ISDN PTMP monitor senses that his monitored party has become available, he will request the status of the called party. If he determines that the caller is currently not available, then he will call this function so that an appropriate message is sent to the caller.

Yes, you just read that correctly. The callee asks the caller what his current status is, and if the caller is currently unavailable, the monitor must send him a message anyway. WTF?

This function results in the agent's party_b_free callback being called. It is most likely that you will not need to actually implement the party_b_free callback in an agent because it is not likely that you will need to or even want to send a caller a message indicating the callee's status if the caller himself is not also free.

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

Definition at line 4104 of file ccss.c.

4105{
4106 int res;
4107 struct cc_core_instance *core_instance = find_cc_core_instance(core_id);
4108
4110
4111 if (!core_instance) {
4112 return -1;
4113 }
4114
4116 if (res) {
4117 cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed");
4118 }
4119 return res;
4120}
static int cc_party_b_free(void *data)
Definition ccss.c:4092

References ast_taskprocessor_push(), cc_core_taskprocessor, cc_party_b_free(), cc_unref(), cc_core_instance::core_id, find_cc_core_instance(), and RETURN_IF_NOT_ENABLED.

◆ ast_cc_monitor_register()

int ast_cc_monitor_register ( const struct ast_cc_monitor_callbacks callbacks)

Register a set of monitor callbacks with the core.

Since
1.8

This is made so that at monitor creation time, the proper callbacks may be installed and the proper .init callback may be called for the monitor to establish private data.

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

Definition at line 1186 of file ccss.c.

1187{
1188 struct cc_monitor_backend *backend;
1189
1191
1192 backend = ast_calloc(1, sizeof(*backend));
1193 if (!backend) {
1194 return -1;
1195 }
1196
1197 backend->callbacks = callbacks;
1198
1202 return 0;
1203}
const struct ast_cc_monitor_callbacks * callbacks
Definition ccss.c:1181
struct cc_monitor_backend * next
Definition ccss.c:1180

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

Referenced by load_module(), and load_module().

◆ ast_cc_monitor_request_acked()

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

Indicate that an outbound entity has accepted our CC request.

Since
1.8

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

Parameters
core_idcore_id of the CC transaction
debugoptional string to print for debugging purposes
Return values
0Success
-1Failure

Definition at line 3820 of file ccss.c.

3821{
3822 va_list ap;
3823 int res;
3824
3826
3827 va_start(ap, debug);
3828 res = cc_request_state_change(CC_ACTIVE, core_id, debug, ap);
3829 va_end(ap);
3830 return res;
3831}

References CC_ACTIVE, cc_request_state_change(), dialed_cc_interfaces::core_id, debug, and RETURN_IF_NOT_ENABLED.

Referenced by cc_generic_monitor_request_cc(), and cc_stop_ringing().

◆ ast_cc_monitor_status_request()

int ast_cc_monitor_status_request ( int  core_id)

Request the status of a caller or callers.

The following are all functions which are required due to the unique case where Asterisk is acting as the NT side of an ISDN PTMP connection to the caller and as the TE side of an ISDN PTMP connection to the callee. In such a case, there are several times where the PTMP monitor needs information from the agent in order to formulate the appropriate messages to send.

When an ISDN PTMP monitor senses that the callee has become available, it needs to know the current status of the caller in order to determine the appropriate response to send to the caller. In order to do this, the monitor calls this function. Responses will arrive asynchronously.

Note
Zero or more responses may come as a result.
Parameters
core_idThe core ID of the CC transaction
Return values
0Successfully requested status
-1Failed to request status

Definition at line 4035 of file ccss.c.

4036{
4037 int res;
4038 struct cc_core_instance *core_instance = find_cc_core_instance(core_id);
4039
4041
4042 if (!core_instance) {
4043 return -1;
4044 }
4045
4047 if (res) {
4048 cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed");
4049 }
4050 return res;
4051}
static int cc_status_request(void *data)
Definition ccss.c:4025

References ast_taskprocessor_push(), cc_core_taskprocessor, cc_status_request(), cc_unref(), cc_core_instance::core_id, find_cc_core_instance(), and RETURN_IF_NOT_ENABLED.

◆ ast_cc_monitor_stop_ringing()

int ast_cc_monitor_stop_ringing ( int  core_id)

Alert a caller to stop ringing.

When an ISDN PTMP monitor becomes available, it is assumed that the agent will then cause the caller's phone to ring. In some cases, this is literally what happens. In other cases, it may be that the caller gets a visible indication on his phone that he may attempt to recall the callee. If multiple callers are recalled (since it may be possible to have a group of callers configured as a single party A), and one of those callers picks up his phone, then the ISDN PTMP monitor will alert the other callers to stop ringing. The agent's stop_ringing callback will be called, and it is up to the agent's driver to send an appropriate message to make his caller stop ringing.

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

Definition at line 4074 of file ccss.c.

4075{
4076 int res;
4077 struct cc_core_instance *core_instance = find_cc_core_instance(core_id);
4078
4080
4081 if (!core_instance) {
4082 return -1;
4083 }
4084
4086 if (res) {
4087 cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed");
4088 }
4089 return res;
4090}
static int cc_stop_ringing(void *data)
Definition ccss.c:4053

References ast_taskprocessor_push(), cc_core_taskprocessor, cc_stop_ringing(), cc_unref(), cc_core_instance::core_id, find_cc_core_instance(), and RETURN_IF_NOT_ENABLED.

◆ ast_cc_monitor_unregister()

void ast_cc_monitor_unregister ( const struct ast_cc_monitor_callbacks callbacks)

Unregister a set of monitor callbacks with the core.

Since
1.8

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

Parameters
callbacksThe callbacks used by the monitor implementation

Definition at line 1222 of file ccss.c.

1223{
1224 struct cc_monitor_backend *backend;
1225
1227
1230 if (backend->callbacks == callbacks) {
1232 ast_free(backend);
1233 break;
1234 }
1235 }
1238}

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, callbacks, cc_monitor_backend::next, and RETURN_IF_NOT_ENABLED.

Referenced by __unload_module(), and unload_module().

◆ ast_cc_offer()

int ast_cc_offer ( struct ast_channel caller_chan)

Offer CC to a caller.

Since
1.8

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

Parameters
caller_chanThe calling channel
Return values
-1Error
0Success

Definition at line 3780 of file ccss.c.

3781{
3782 int core_id;
3783 int res = -1;
3784 struct ast_datastore *datastore;
3785 struct dialed_cc_interfaces *cc_interfaces;
3786 char cc_is_offerable;
3787
3789
3790 ast_channel_lock(caller_chan);
3791 if (!(datastore = ast_channel_datastore_find(caller_chan, &dialed_cc_interfaces_info, NULL))) {
3792 ast_channel_unlock(caller_chan);
3793 return res;
3794 }
3795
3796 cc_interfaces = datastore->data;
3797 cc_is_offerable = cc_interfaces->is_original_caller;
3798 core_id = cc_interfaces->core_id;
3799 ast_channel_unlock(caller_chan);
3800
3801 if (cc_is_offerable) {
3802 res = cc_offer(core_id, "CC offered to caller %s", ast_channel_name(caller_chan));
3803 }
3804 return res;
3805}
static int cc_offer(const int core_id, const char *const debug,...)
Definition ccss.c:3769
char is_original_caller
Definition ccss.c:1942

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, dialed_cc_interfaces_info, dialed_cc_interfaces::is_original_caller, NULL, and RETURN_IF_NOT_ENABLED.

Referenced by ast_hangup().

◆ ast_cc_request_is_within_limits()

int ast_cc_request_is_within_limits ( void  )

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

Since
1.8

It is recommended that an entity which receives an incoming CC request calls this function before calling ast_cc_agent_accept_request. This way, immediate feedback can be given to the caller about why his request was rejected.

If this is not called and a state change to CC_CALLER_REQUESTED is made, then the core will still not allow for the request to succeed. However, if done this way, it may not be obvious to the requestor why the request failed.

Return values
0Not within the limits. Fail.
non-zeroWithin the limits. Success.

Definition at line 2509 of file ccss.c.

2510{
2512}
static unsigned int global_cc_max_requests
Definition ccss.c:153
static int cc_request_count
Definition ccss.c:157

References cc_request_count, and global_cc_max_requests.

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

◆ ast_cc_set_param()

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

set a CCSS configuration parameter, given its name

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

Definition at line 823 of file ccss.c.

825{
826 unsigned int value_as_uint;
827 if (!strcasecmp(name, "cc_agent_policy")) {
829 } else if (!strcasecmp(name, "cc_monitor_policy")) {
831 } else if (!strcasecmp(name, "cc_agent_dialstring")) {
833 } else if (!strcasecmp(name, "cc_callback_sub")) {
835 return 0;
836 }
837
838 if (sscanf(value, "%30u", &value_as_uint) != 1) {
839 return -1;
840 }
841
842 if (!strcasecmp(name, "cc_offer_timer")) {
843 ast_set_cc_offer_timer(params, value_as_uint);
844 } else if (!strcasecmp(name, "ccnr_available_timer")) {
845 ast_set_ccnr_available_timer(params, value_as_uint);
846 } else if (!strcasecmp(name, "ccbs_available_timer")) {
847 ast_set_ccbs_available_timer(params, value_as_uint);
848 } else if (!strcasecmp(name, "cc_max_agents")) {
849 ast_set_cc_max_agents(params, value_as_uint);
850 } else if (!strcasecmp(name, "cc_max_monitors")) {
851 ast_set_cc_max_monitors(params, value_as_uint);
852 } else if (!strcasecmp(name, "cc_recall_timer")) {
853 ast_set_cc_recall_timer(params, value_as_uint);
854 } else {
855 ast_log(LOG_WARNING, "%s is not a valid CC parameter. Ignoring.\n", name);
856 return -1;
857 }
858
859 return 0;
860}
int ast_set_cc_agent_policy(struct ast_cc_config_params *config, enum ast_cc_agent_policies value)
Set the cc_agent_policy.
Definition ccss.c:888
void ast_set_cc_max_monitors(struct ast_cc_config_params *config, unsigned int value)
Set the cc_max_monitors.
Definition ccss.c:1006
void ast_set_ccbs_available_timer(struct ast_cc_config_params *config, unsigned int value)
Set the ccbs_available_timer.
Definition ccss.c:967
void ast_set_cc_callback_sub(struct ast_cc_config_params *config, const char *const value)
Set the callback subroutine name.
Definition ccss.c:1016
void ast_set_cc_agent_dialstring(struct ast_cc_config_params *config, const char *const value)
Set the cc_agent_dialstring.
Definition ccss.c:982
void ast_set_cc_offer_timer(struct ast_cc_config_params *config, unsigned int value)
Set the cc_offer_timer.
Definition ccss.c:922
void ast_set_cc_max_agents(struct ast_cc_config_params *config, unsigned int value)
Set the cc_max_agents.
Definition ccss.c:996
static enum ast_cc_monitor_policies str_to_monitor_policy(const char *const value)
Definition ccss.c:733
void ast_set_ccnr_available_timer(struct ast_cc_config_params *config, unsigned int value)
Set the ccnr_available_timer.
Definition ccss.c:937
static enum ast_cc_agent_policies str_to_agent_policy(const char *const value)
Definition ccss.c:719
int ast_set_cc_monitor_policy(struct ast_cc_config_params *config, enum ast_cc_monitor_policies value)
Set the cc_monitor_policy.
Definition ccss.c:905
void ast_set_cc_recall_timer(struct ast_cc_config_params *config, unsigned int value)
Set the cc_recall_timer.
Definition ccss.c:952

References ast_log, ast_set_cc_agent_dialstring(), ast_set_cc_agent_policy(), ast_set_cc_callback_sub(), 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, name, str_to_agent_policy(), str_to_monitor_policy(), and value.

Referenced by acf_cc_write(), and process_dahdi().

◆ ast_get_cc_agent_dialstring()

const char * ast_get_cc_agent_dialstring ( struct ast_cc_config_params config)

Get the cc_agent_dialstring.

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

Definition at line 977 of file ccss.c.

978{
979 return config->cc_agent_dialstring;
980}
static const char config[]

References config.

Referenced by ast_cc_get_param(), and generic_recall().

◆ ast_get_cc_agent_policy()

enum ast_cc_agent_policies ast_get_cc_agent_policy ( struct ast_cc_config_params config)

Get the cc_agent_policy.

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

Definition at line 883 of file ccss.c.

884{
885 return config->cc_agent_policy;
886}

References ast_cc_config_params::cc_agent_policy, and config.

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

◆ ast_get_cc_callback_sub()

const char * ast_get_cc_callback_sub ( struct ast_cc_config_params config)

Get the name of the callback subroutine.

Since
11
Parameters
configThe configuration to retrieve the callback_sub from
Returns
The callback_sub name

Definition at line 1011 of file ccss.c.

1012{
1013 return config->cc_callback_sub;
1014}

References config.

Referenced by ast_cc_get_param(), and generic_recall().

◆ ast_get_cc_max_agents()

unsigned int ast_get_cc_max_agents ( struct ast_cc_config_params config)

Get the cc_max_agents.

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

Definition at line 991 of file ccss.c.

992{
993 return config->cc_max_agents;
994}

References config.

Referenced by ast_cc_get_param(), and cc_core_init_instance().

◆ ast_get_cc_max_monitors()

unsigned int ast_get_cc_max_monitors ( struct ast_cc_config_params config)

Get the cc_max_monitors.

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

Definition at line 1001 of file ccss.c.

1002{
1003 return config->cc_max_monitors;
1004}

References config.

Referenced by ast_cc_get_param(), and ast_queue_cc_frame().

◆ ast_get_cc_monitor_policy()

enum ast_cc_monitor_policies ast_get_cc_monitor_policy ( struct ast_cc_config_params config)

Get the cc_monitor_policy.

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

Definition at line 900 of file ccss.c.

901{
902 return config->cc_monitor_policy;
903}

References config.

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

◆ ast_get_cc_offer_timer()

unsigned int ast_get_cc_offer_timer ( struct ast_cc_config_params config)

Get the cc_offer_timer.

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

Definition at line 917 of file ccss.c.

918{
919 return config->cc_offer_timer;
920}

References config.

Referenced by ast_cc_get_param(), and cc_generic_agent_start_offer_timer().

◆ ast_get_cc_recall_timer()

unsigned int ast_get_cc_recall_timer ( struct ast_cc_config_params config)

Get the cc_recall_timer.

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

Definition at line 947 of file ccss.c.

948{
949 return config->cc_recall_timer;
950}

References config.

Referenced by ast_cc_get_param(), and generic_recall().

◆ ast_get_ccbs_available_timer()

unsigned int ast_get_ccbs_available_timer ( struct ast_cc_config_params config)

Get the ccbs_available_timer.

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

Definition at line 962 of file ccss.c.

963{
964 return config->ccbs_available_timer;
965}

References config.

Referenced by ast_cc_get_param(), and cc_generic_monitor_request_cc().

◆ ast_get_ccnr_available_timer()

unsigned int ast_get_ccnr_available_timer ( struct ast_cc_config_params config)

Get the ccnr_available_timer.

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

Definition at line 932 of file ccss.c.

933{
934 return config->ccnr_available_timer;
935}

References config.

Referenced by ast_cc_get_param(), and cc_generic_monitor_request_cc().

◆ ast_handle_cc_control_frame()

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

Properly react to a CC control frame.

Since
1.8

When a CC-capable application, such as Dial, receives a frame of type AST_CONTROL_CC, then it may call this function in order to have the device which sent the frame added to the tree of interfaces which is kept on the inbound channel.

Parameters
inboundThe inbound channel
outboundThe outbound channel (The one from which the CC frame was read)
frame_dataThe ast_frame's data.ptr field.

Unless we are ignoring CC for some reason, we will always call this function when we read an AST_CONTROL_CC frame from an outbound channel.

This function will call cc_device_monitor_init to create the new cc_monitor for the device from which we read the frame. In addition, the new device will be added to the monitor tree on the dialed_cc_interfaces datastore on the inbound channel.

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

Definition at line 2334 of file ccss.c.

2335{
2336 char *device_name;
2337 char *dialstring;
2338 struct ast_cc_monitor *monitor;
2339 struct ast_datastore *cc_datastore;
2340 struct dialed_cc_interfaces *cc_interfaces;
2341 struct cc_control_payload *cc_data = frame_data;
2342 struct cc_core_instance *core_instance;
2343
2345
2346 device_name = cc_data->device_name;
2347 dialstring = cc_data->dialstring;
2348
2349 ast_channel_lock(inbound);
2350 if (!(cc_datastore = ast_channel_datastore_find(inbound, &dialed_cc_interfaces_info, NULL))) {
2351 ast_log(LOG_WARNING, "Unable to retrieve CC datastore while processing CC frame from '%s'. CC services will be unavailable.\n", device_name);
2352 ast_channel_unlock(inbound);
2354 return;
2355 }
2356
2357 cc_interfaces = cc_datastore->data;
2358
2359 if (cc_interfaces->ignore) {
2360 ast_channel_unlock(inbound);
2362 return;
2363 }
2364
2365 if (!cc_interfaces->is_original_caller) {
2366 /* If the is_original_caller is not set on the *inbound* channel, then
2367 * it must be a local channel. As such, we do not want to create a core instance
2368 * or an agent for the local channel. Instead, we want to pass this along to the
2369 * other side of the local channel so that the original caller can benefit.
2370 */
2371 ast_channel_unlock(inbound);
2372 ast_indicate_data(inbound, AST_CONTROL_CC, cc_data, sizeof(*cc_data));
2373 return;
2374 }
2375
2376 core_instance = find_cc_core_instance(cc_interfaces->core_id);
2377 if (!core_instance) {
2378 core_instance = cc_core_init_instance(inbound, cc_interfaces->interface_tree,
2379 cc_interfaces->core_id, cc_data);
2380 if (!core_instance) {
2381 cc_interfaces->ignore = 1;
2382 ast_channel_unlock(inbound);
2384 return;
2385 }
2386 }
2387
2388 ast_channel_unlock(inbound);
2389
2390 /* Yeah this kind of sucks, but luckily most people
2391 * aren't dialing thousands of interfaces on every call
2392 *
2393 * This traversal helps us to not create duplicate monitors in
2394 * case a device queues multiple CC control frames.
2395 */
2396 AST_LIST_LOCK(cc_interfaces->interface_tree);
2397 AST_LIST_TRAVERSE(cc_interfaces->interface_tree, monitor, next) {
2398 if (!strcmp(monitor->interface->device_name, device_name)) {
2399 ast_log_dynamic_level(cc_logger_level, "Core %d: Device %s sent us multiple CC control frames. Ignoring those beyond the first.\n",
2400 core_instance->core_id, device_name);
2401 AST_LIST_UNLOCK(cc_interfaces->interface_tree);
2402 cc_unref(core_instance, "Returning early from ast_handle_cc_control_frame. Unref core_instance");
2404 return;
2405 }
2406 }
2407 AST_LIST_UNLOCK(cc_interfaces->interface_tree);
2408
2409 if (!(monitor = cc_device_monitor_init(device_name, dialstring, cc_data, core_instance->core_id))) {
2410 ast_log(LOG_WARNING, "Unable to create CC device interface for '%s'. CC services will be unavailable on this interface.\n", device_name);
2411 cc_unref(core_instance, "Returning early from ast_handle_cc_control_frame. Unref core_instance");
2413 return;
2414 }
2415
2416 AST_LIST_LOCK(cc_interfaces->interface_tree);
2417 cc_ref(monitor, "monitor tree's reference to the monitor");
2418 AST_LIST_INSERT_TAIL(cc_interfaces->interface_tree, monitor, next);
2419 AST_LIST_UNLOCK(cc_interfaces->interface_tree);
2420
2421 cc_extension_monitor_change_is_valid(core_instance, monitor->parent_id, monitor->interface->device_name, 0);
2422
2423 cc_publish_available(cc_interfaces->core_id, device_name, cc_service_to_string(cc_data->service));
2424
2425 cc_unref(core_instance, "Done with core_instance after handling CC control frame");
2426 cc_unref(monitor, "Unref reference from allocating monitor");
2427}
static void cc_publish_available(int core_id, const char *callee, const char *service)
Definition ccss.c:1065
static struct cc_core_instance * cc_core_init_instance(struct ast_channel *caller_chan, struct cc_monitor_tree *called_tree, const int core_id, struct cc_control_payload *cc_data)
Definition ccss.c:2958
static struct ast_cc_monitor * cc_device_monitor_init(const char *const device_name, const char *const dialstring, const struct cc_control_payload *cc_data, int core_id)
Definition ccss.c:2268
static void cc_extension_monitor_change_is_valid(struct cc_core_instance *core_instance, unsigned int parent_id, const char *const device_name, int is_valid)
Definition ccss.c:2069
static const char * cc_service_to_string(enum ast_cc_service_type service)
Definition ccss.c:428
int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, size_t datalen)
Indicates condition of channel, with payload.
Definition channel.c:4648
unsigned int parent_id
Definition ccss.h:490
enum ast_cc_service_type service
Service offered by the endpoint.
Definition ccss.c:281

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_logger_level, cc_publish_available(), 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, dialed_cc_interfaces_info, ast_cc_monitor::dialstring, cc_control_payload::dialstring, 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, cc_control_payload::monitor_type, NULL, ast_cc_monitor::parent_id, cc_control_payload::private_data, RETURN_IF_NOT_ENABLED, and cc_control_payload::service.

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

◆ ast_ignore_cc()

void ast_ignore_cc ( struct ast_channel chan)

Mark the channel to ignore further CC activity.

Since
1.8

When a CC-capable application, such as Dial, has finished with all CC processing for a channel and knows that any further CC processing should be ignored, this function should be called.

Parameters
chanThe channel for which further CC processing should be ignored.

Definition at line 3747 of file ccss.c.

3748{
3749 struct ast_datastore *cc_datastore;
3750 struct ast_datastore *cc_recall_datastore;
3751 struct dialed_cc_interfaces *cc_interfaces;
3752 struct cc_recall_ds_data *recall_cc_data;
3753
3755
3756 ast_channel_lock(chan);
3757 if ((cc_datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL))) {
3758 cc_interfaces = cc_datastore->data;
3759 cc_interfaces->ignore = 1;
3760 }
3761
3762 if ((cc_recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
3763 recall_cc_data = cc_recall_datastore->data;
3764 recall_cc_data->ignore = 1;
3765 }
3766 ast_channel_unlock(chan);
3767}

References ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_datastore::data, dialed_cc_interfaces_info, dialed_cc_interfaces::ignore, cc_recall_ds_data::ignore, NULL, recall_ds_info, and RETURN_IF_NOT_ENABLED.

Referenced by dial_exec_full(), and do_forward().

◆ ast_queue_cc_frame()

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

Queue an AST_CONTROL_CC frame.

Since
1.8
Note
Since this function calls ast_queue_frame, the channel will be locked during the course of this function.
Parameters
chanThe channel onto which to queue the frame
monitor_typeThe type of monitor to use when CC is requested
dialstringThe dial string used to call the device
serviceThe type of CC service the device is willing to offer
private_dataIf a native monitor is being used, and some channel-driver-specific private data has been allocated, then this parameter should contain a pointer to that data. If using a generic monitor, this parameter should remain NULL. Note that if this function should fail at some point, it is the responsibility of the caller to free the private data upon return.
Return values
0Success
-1Error

Definition at line 4206 of file ccss.c.

4208{
4209 struct ast_frame frame = {0,};
4210 char device_name[AST_CHANNEL_NAME];
4211 int retval;
4212 struct ast_cc_config_params *cc_params;
4213
4215
4216 cc_params = ast_channel_get_cc_config_params(chan);
4217 if (!cc_params) {
4218 return -1;
4219 }
4220 ast_channel_get_device_name(chan, device_name, sizeof(device_name));
4221 if (ast_cc_monitor_count(device_name, monitor_type) >= ast_get_cc_max_monitors(cc_params)) {
4222 ast_log(LOG_NOTICE, "Not queuing a CC frame for device %s since it already has its maximum monitors allocated\n", device_name);
4223 return -1;
4224 }
4225
4226 if (ast_cc_build_frame(chan, cc_params, monitor_type, device_name, dialstring, service, private_data, &frame)) {
4227 /* Frame building failed. We can't use this. */
4228 return -1;
4229 }
4230 retval = ast_queue_frame(chan, &frame);
4231 ast_frfree(&frame);
4232 return retval;
4233}
int ast_cc_monitor_count(const char *const name, const char *const type)
Return the number of outstanding CC requests to a specific device.
Definition ccss.c:4438
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.
Definition ccss.c:4235
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
Definition channel.c:1170
#define ast_frfree(fr)
#define LOG_NOTICE
Data structure associated with a single frame of data.

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(), LOG_NOTICE, RETURN_IF_NOT_ENABLED, and service.

Referenced by analog_call().

◆ ast_set_cc_agent_dialstring()

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

Set the cc_agent_dialstring.

Since
1.8
Parameters
configThe configuration to set the cc_agent_dialstring on
valueThe new cc_agent_dialstring we want to change to

Definition at line 982 of file ccss.c.

983{
984 if (ast_strlen_zero(value)) {
985 config->cc_agent_dialstring[0] = '\0';
986 } else {
987 ast_copy_string(config->cc_agent_dialstring, value, sizeof(config->cc_agent_dialstring));
988 }
989}

References ast_copy_string(), ast_strlen_zero(), config, and value.

Referenced by ast_cc_set_param().

◆ ast_set_cc_agent_policy()

int ast_set_cc_agent_policy ( struct ast_cc_config_params config,
enum ast_cc_agent_policies  value 
)

Set the cc_agent_policy.

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

Definition at line 888 of file ccss.c.

889{
890 /* Screw C and its weak type checking for making me have to do this
891 * validation at runtime.
892 */
893 if (value < AST_CC_AGENT_NEVER || value > AST_CC_AGENT_GENERIC) {
894 return -1;
895 }
896 config->cc_agent_policy = value;
897 return 0;
898}

References AST_CC_AGENT_GENERIC, config, and value.

Referenced by ast_cc_set_param().

◆ ast_set_cc_callback_sub()

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

Set the callback subroutine name.

Since
11
Parameters
configThe configuration to set the callback_sub on
valueThe new callback subroutine we want to change to

Definition at line 1016 of file ccss.c.

1017{
1018 if (ast_strlen_zero(value)) {
1019 config->cc_callback_sub[0] = '\0';
1020 } else {
1021 ast_copy_string(config->cc_callback_sub, value, sizeof(config->cc_callback_sub));
1022 }
1023}

References ast_copy_string(), ast_strlen_zero(), config, and value.

Referenced by ast_cc_set_param().

◆ ast_set_cc_interfaces_chanvar()

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.

Since
1.8
extension@context 
as a starting point

The CC_INTERFACES channel variable will have the interfaces that should be called back for a specific PBX instance. This version of the function is used mainly by local channels, wherein we need to set CC_INTERFACES based on an extension and context that appear in the middle of the tree of dialed interfaces.

Note
This function will lock the channel as well as the list of monitors stored on the channel's CC recall datastore, though neither are held at the same time. Callers of this function should be aware of potential lock ordering problems that may arise.
Parameters
chanThe channel to set the CC_INTERFACES variable on
extensionThe name of the extension for which we're setting the variable. This should be in the form of
exten@context 

Definition at line 3693 of file ccss.c.

3694{
3695 struct ast_datastore *recall_datastore;
3696 struct cc_monitor_tree *interface_tree;
3697 struct ast_cc_monitor *monitor_iter;
3698 struct cc_recall_ds_data *recall_data;
3699 struct ast_str *str = ast_str_create(64);
3700 int core_id;
3701
3703
3704 if (!str) {
3705 return -1;
3706 }
3707
3708 ast_channel_lock(chan);
3709 if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
3710 ast_channel_unlock(chan);
3711 ast_free(str);
3712 return -1;
3713 }
3714 recall_data = recall_datastore->data;
3715 interface_tree = recall_data->interface_tree;
3716 core_id = recall_data->core_id;
3717 ast_channel_unlock(chan);
3718
3719 AST_LIST_LOCK(interface_tree);
3720 AST_LIST_TRAVERSE(interface_tree, monitor_iter, next) {
3721 if (!strcmp(monitor_iter->interface->device_name, extension)) {
3722 break;
3723 }
3724 }
3725
3726 if (!monitor_iter) {
3727 /* We couldn't find this extension. This may be because
3728 * we have been directed into an unexpected extension because
3729 * the admin has changed a CC_INTERFACES variable at some point.
3730 */
3731 AST_LIST_UNLOCK(interface_tree);
3732 ast_free(str);
3733 return -1;
3734 }
3735
3736 build_cc_interfaces_chanvar(monitor_iter, &str);
3737 AST_LIST_UNLOCK(interface_tree);
3738
3739 pbx_builtin_setvar_helper(chan, "CC_INTERFACES", ast_str_buffer(str));
3740 ast_log_dynamic_level(cc_logger_level, "Core %d: CC_INTERFACES set to %s\n",
3741 core_id, ast_str_buffer(str));
3742
3743 ast_free(str);
3744 return 0;
3745}
structure to hold extensions

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_logger_level, cc_recall_ds_data::core_id, ast_datastore::data, ast_cc_interface::device_name, ast_cc_monitor::interface, cc_recall_ds_data::interface_tree, NULL, pbx_builtin_setvar_helper(), recall_ds_info, RETURN_IF_NOT_ENABLED, and str.

Referenced by local_call().

◆ ast_set_cc_max_agents()

void ast_set_cc_max_agents ( struct ast_cc_config_params config,
unsigned int  value 
)

Set the cc_max_agents.

Since
1.8
Parameters
configThe configuration to set the cc_max_agents on
valueThe new cc_max_agents we want to change to

Definition at line 996 of file ccss.c.

997{
998 config->cc_max_agents = value;
999}

References config, and value.

Referenced by ast_cc_set_param().

◆ ast_set_cc_max_monitors()

void ast_set_cc_max_monitors ( struct ast_cc_config_params config,
unsigned int  value 
)

Set the cc_max_monitors.

Since
1.8
Parameters
configThe configuration to set the cc_max_monitors on
valueThe new cc_max_monitors we want to change to

Definition at line 1006 of file ccss.c.

1007{
1008 config->cc_max_monitors = value;
1009}

References config, and value.

Referenced by ast_cc_set_param().

◆ ast_set_cc_monitor_policy()

int ast_set_cc_monitor_policy ( struct ast_cc_config_params config,
enum ast_cc_monitor_policies  value 
)

Set the cc_monitor_policy.

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

Definition at line 905 of file ccss.c.

906{
907 /* Screw C and its weak type checking for making me have to do this
908 * validation at runtime.
909 */
910 if (value < AST_CC_MONITOR_NEVER || value > AST_CC_MONITOR_ALWAYS) {
911 return -1;
912 }
913 config->cc_monitor_policy = value;
914 return 0;
915}

References AST_CC_MONITOR_ALWAYS, config, and value.

Referenced by ast_cc_set_param().

◆ ast_set_cc_offer_timer()

void ast_set_cc_offer_timer ( struct ast_cc_config_params config,
unsigned int  value 
)

Set the cc_offer_timer.

Since
1.8
Parameters
configThe configuration to set the cc_offer_timer on
valueThe new cc_offer_timer we want to change to

Definition at line 922 of file ccss.c.

923{
924 /* 0 is an unreasonable value for any timer. Stick with the default */
925 if (value == 0) {
926 ast_log(LOG_WARNING, "0 is an invalid value for cc_offer_timer. Retaining value as %u\n", config->cc_offer_timer);
927 return;
928 }
929 config->cc_offer_timer = value;
930}

References ast_log, config, LOG_WARNING, and value.

Referenced by ast_cc_set_param().

◆ ast_set_cc_recall_timer()

void ast_set_cc_recall_timer ( struct ast_cc_config_params config,
unsigned int  value 
)

Set the cc_recall_timer.

Since
1.8
Parameters
configThe configuration to set the cc_recall_timer on
valueThe new cc_recall_timer we want to change to

Definition at line 952 of file ccss.c.

953{
954 /* 0 is an unreasonable value for any timer. Stick with the default */
955 if (value == 0) {
956 ast_log(LOG_WARNING, "0 is an invalid value for ccnr_available_timer. Retaining value as %u\n", config->cc_recall_timer);
957 return;
958 }
959 config->cc_recall_timer = value;
960}

References ast_log, config, LOG_WARNING, and value.

Referenced by ast_cc_set_param().

◆ ast_set_ccbs_available_timer()

void ast_set_ccbs_available_timer ( struct ast_cc_config_params config,
unsigned int  value 
)

Set the ccbs_available_timer.

Since
1.8
Parameters
configThe configuration to set the ccbs_available_timer on
valueThe new ccbs_available_timer we want to change to

Definition at line 967 of file ccss.c.

968{
969 /* 0 is an unreasonable value for any timer. Stick with the default */
970 if (value == 0) {
971 ast_log(LOG_WARNING, "0 is an invalid value for ccbs_available_timer. Retaining value as %u\n", config->ccbs_available_timer);
972 return;
973 }
974 config->ccbs_available_timer = value;
975}

References ast_log, config, LOG_WARNING, and value.

Referenced by ast_cc_set_param().

◆ ast_set_ccnr_available_timer()

void ast_set_ccnr_available_timer ( struct ast_cc_config_params config,
unsigned int  value 
)

Set the ccnr_available_timer.

Since
1.8
Parameters
configThe configuration to set the ccnr_available_timer on
valueThe new ccnr_available_timer we want to change to

Definition at line 937 of file ccss.c.

938{
939 /* 0 is an unreasonable value for any timer. Stick with the default */
940 if (value == 0) {
941 ast_log(LOG_WARNING, "0 is an invalid value for ccnr_available_timer. Retaining value as %u\n", config->ccnr_available_timer);
942 return;
943 }
944 config->ccnr_available_timer = value;
945}

References ast_log, config, LOG_WARNING, and value.

Referenced by ast_cc_set_param().

◆ ast_setup_cc_recall_datastore()

int ast_setup_cc_recall_datastore ( struct ast_channel chan,
const int  core_id 
)

Set up a CC recall datastore on a channel.

Since
1.8

Implementers of protocol-specific CC agents will need to call this function in order for the channel to have the necessary interfaces to recall.

This function must be called by the implementer once it has been detected that an inbound call is a cc_recall. After allocating the channel, call this function, followed by ast_cc_set_cc_interfaces_chanvar. While it would be nice to be able to have the core do this automatically, it just cannot be done given the current architecture.

Definition at line 3423 of file ccss.c.

3424{
3425 struct ast_datastore *recall_datastore;
3426 struct cc_recall_ds_data *recall_data;
3427 struct cc_core_instance *core_instance;
3428
3430
3431 recall_datastore = ast_datastore_alloc(&recall_ds_info, NULL);
3432 if (!recall_datastore) {
3433 return -1;
3434 }
3435
3436 if (!(recall_data = ast_calloc(1, sizeof(*recall_data)))) {
3437 ast_datastore_free(recall_datastore);
3438 return -1;
3439 }
3440
3441 if (!(core_instance = find_cc_core_instance(core_id))) {
3442 ast_free(recall_data);
3443 ast_datastore_free(recall_datastore);
3444 return -1;
3445 }
3446
3447 recall_data->interface_tree = cc_ref(core_instance->monitors,
3448 "Bump refcount for monitor tree for recall datastore");
3449 recall_data->core_id = core_id;
3450 recall_datastore->data = recall_data;
3451 recall_datastore->inheritance = DATASTORE_INHERIT_FOREVER;
3452 ast_channel_lock(chan);
3453 ast_channel_datastore_add(chan, recall_datastore);
3454 ast_channel_unlock(chan);
3455 cc_unref(core_instance, "Recall datastore set up. No need for core_instance ref");
3456 return 0;
3457}
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition channel.c:2375
#define DATASTORE_INHERIT_FOREVER
Definition channel.h:194
#define ast_datastore_alloc(info, uid)
Definition datastore.h:85
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition datastore.c:68
unsigned int inheritance
Definition datastore.h:69

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_core_instance::core_id, 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, cc_core_instance::monitors, NULL, recall_ds_info, and RETURN_IF_NOT_ENABLED.

Referenced by generic_recall().