Wed Jan 8 2020 09:49:59

Asterisk developer's documentation


ccss.h File Reference

Call Completion Supplementary Services API. More...

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

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. More...
 
#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. More...
 

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. More...
 
int ast_cc_agent_accept_request (int core_id, const char *const debug,...)
 Accept inbound CC request. More...
 
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. More...
 
int ast_cc_agent_caller_available (int core_id, const char *const debug,...)
 Indicate that a previously unavailable caller has become available. More...
 
int ast_cc_agent_caller_busy (int core_id, const char *const debug,...)
 Indicate that the caller is busy. More...
 
int ast_cc_agent_recalling (int core_id, const char *const debug,...)
 Tell the CC core that a caller is currently recalling. More...
 
int ast_cc_agent_register (const struct ast_cc_agent_callbacks *callbacks)
 Register a set of agent callbacks with the core. More...
 
int ast_cc_agent_set_interfaces_chanvar (struct ast_channel *chan)
 Set the first level CC_INTERFACES channel variable for a channel. More...
 
int ast_cc_agent_status_response (int core_id, enum ast_device_state devstate)
 Response with a caller's current status. More...
 
void ast_cc_agent_unregister (const struct ast_cc_agent_callbacks *callbacks)
 Unregister a set of agent callbacks with the core. More...
 
int ast_cc_available_timer_expire (const void *data)
 Scheduler callback for available timer expiration. More...
 
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. More...
 
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. More...
 
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. More...
 
int ast_cc_call_init (struct ast_channel *chan, int *ignore_cc)
 Start the CC process on a call. More...
 
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. More...
 
int ast_cc_completed (struct ast_channel *chan, const char *const debug,...)
 Indicate recall has been acknowledged. More...
 
void ast_cc_config_params_destroy (struct ast_cc_config_params *params)
 Free memory from CCSS configuration params. More...
 
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 More...
 
void ast_cc_default_config_params (struct ast_cc_config_params *params)
 Set the specified CC config params to default values. More...
 
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. More...
 
int ast_cc_failed (int core_id, const char *const debug,...)
 Indicate failure has occurred. More...
 
int ast_cc_get_current_core_id (struct ast_channel *chan)
 Get the core id for the current call. More...
 
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. More...
 
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 More...
 
int ast_cc_init (void)
 Initialize CCSS. More...
 
int ast_cc_is_config_param (const char *const name)
 Is this a CCSS configuration parameter? More...
 
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. More...
 
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. More...
 
int ast_cc_monitor_count (const char *const name, const char *const type)
 Return the number of outstanding CC requests to a specific device. More...
 
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. More...
 
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. More...
 
int ast_cc_monitor_register (const struct ast_cc_monitor_callbacks *callbacks)
 Register a set of monitor callbacks with the core. More...
 
int ast_cc_monitor_request_acked (int core_id, const char *const debug,...)
 Indicate that an outbound entity has accepted our CC request. More...
 
int ast_cc_monitor_status_request (int core_id)
 Request the status of a caller or callers. More...
 
int ast_cc_monitor_stop_ringing (int core_id)
 Alert a caller to stop ringing. More...
 
void ast_cc_monitor_unregister (const struct ast_cc_monitor_callbacks *callbacks)
 Unregister a set of monitor callbacks with the core. More...
 
int ast_cc_offer (struct ast_channel *caller_chan)
 Offer CC to a caller. More...
 
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. More...
 
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 More...
 
const char * ast_get_cc_agent_dialstring (struct ast_cc_config_params *config)
 Get the cc_agent_dialstring. More...
 
enum ast_cc_agent_policies ast_get_cc_agent_policy (struct ast_cc_config_params *config)
 Get the cc_agent_policy. More...
 
const char * ast_get_cc_callback_macro (struct ast_cc_config_params *config)
 Get the name of the callback_macro. More...
 
unsigned int ast_get_cc_max_agents (struct ast_cc_config_params *config)
 Get the cc_max_agents. More...
 
unsigned int ast_get_cc_max_monitors (struct ast_cc_config_params *config)
 Get the cc_max_monitors. More...
 
enum ast_cc_monitor_policies ast_get_cc_monitor_policy (struct ast_cc_config_params *config)
 Get the cc_monitor_policy. More...
 
unsigned int ast_get_cc_offer_timer (struct ast_cc_config_params *config)
 Get the cc_offer_timer. More...
 
unsigned int ast_get_cc_recall_timer (struct ast_cc_config_params *config)
 Get the cc_recall_timer. More...
 
unsigned int ast_get_ccbs_available_timer (struct ast_cc_config_params *config)
 Get the ccbs_available_timer. More...
 
unsigned int ast_get_ccnr_available_timer (struct ast_cc_config_params *config)
 Get the ccnr_available_timer. More...
 
void ast_handle_cc_control_frame (struct ast_channel *inbound, struct ast_channel *outbound, void *frame_data)
 Properly react to a CC control frame. More...
 
void ast_ignore_cc (struct ast_channel *chan)
 Mark the channel to ignore further CC activity. More...
 
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. More...
 
void ast_set_cc_agent_dialstring (struct ast_cc_config_params *config, const char *const value)
 Set the cc_agent_dialstring. More...
 
int ast_set_cc_agent_policy (struct ast_cc_config_params *config, enum ast_cc_agent_policies value)
 Set the cc_agent_policy. More...
 
void ast_set_cc_callback_macro (struct ast_cc_config_params *config, const char *const value)
 Set the callback_macro name. More...
 
int ast_set_cc_interfaces_chanvar (struct ast_channel *chan, const char *const extension)
 Set the CC_INTERFACES channel variable for a channel using an extension as a starting point. More...
 
void ast_set_cc_max_agents (struct ast_cc_config_params *config, unsigned int value)
 Set the cc_max_agents. More...
 
void ast_set_cc_max_monitors (struct ast_cc_config_params *config, unsigned int value)
 Set the cc_max_monitors. More...
 
int ast_set_cc_monitor_policy (struct ast_cc_config_params *config, enum ast_cc_monitor_policies value)
 Set the cc_monitor_policy. More...
 
void ast_set_cc_offer_timer (struct ast_cc_config_params *config, unsigned int value)
 Set the cc_offer_timer. More...
 
void ast_set_cc_recall_timer (struct ast_cc_config_params *config, unsigned int value)
 Set the cc_recall_timer. More...
 
void ast_set_ccbs_available_timer (struct ast_cc_config_params *config, unsigned int value)
 Set the ccbs_available_timer. More...
 
void ast_set_ccnr_available_timer (struct ast_cc_config_params *config, unsigned int value)
 Set the ccnr_available_timer. More...
 
int ast_setup_cc_recall_datastore (struct ast_channel *chan, const int core_id)
 Set up a CC recall datastore on a channel. More...
 

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

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

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

#define AST_CC_GENERIC_MONITOR_TYPE   "generic"

It is recommended that monitors use a pointer to an ast_cc_monitor_callbacks::type when creating an AST_CONTROL_CC frame. Since the generic monitor callbacks are opaque and channel drivers will wish to use that, this string is made globally available for all to use

Definition at line 472 of file ccss.h.

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

Typedef Documentation

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

Callback made from ast_cc_callback for certain channel types.

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

Returns
Nothing

Definition at line 1583 of file ccss.h.

Enumeration Type Documentation

agent flags that can alter core behavior

Enumerator
AST_CC_AGENT_SKIP_OFFER 

Definition at line 59 of file ccss.h.

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 };

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 };
Enumerator
AST_CC_AGENT_RESPONSE_SUCCESS 

CC request accepted

AST_CC_AGENT_RESPONSE_FAILURE_INVALID 

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

AST_CC_AGENT_RESPONSE_FAILURE_TOO_MANY 

Too many CC requests in the system.

Definition at line 861 of file ccss.h.

861  {
862  /*! CC request accepted */
864  /*! CC request not allowed at this time. Invalid state transition. */
866  /*! Too many CC requests in the system. */
868 };

Used to determine which type of monitor an ast_cc_device_monitor is.

Enumerator
AST_CC_DEVICE_MONITOR 
AST_CC_EXTENSION_MONITOR 

Definition at line 479 of file ccss.h.

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 };
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 };

Function Documentation

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 563 of file ccss.c.

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

564 {
565 #if defined(__AST_DEBUG_MALLOC)
566  struct ast_cc_config_params *params = __ast_malloc(sizeof(*params), file, line, function);
567 #else
568  struct ast_cc_config_params *params = ast_malloc(sizeof(*params));
569 #endif
570 
571  if (!params) {
572  return NULL;
573  }
574 
576  return params;
577 }
void * __ast_malloc(size_t size, const char *file, int lineno, const char *func)
void ast_cc_default_config_params(struct ast_cc_config_params *params)
Set the specified CC config params to default values.
Definition: ccss.c:558
#define ast_malloc(a)
Definition: astmm.h:91
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 3510 of file ccss.c.

References CC_CALLER_REQUESTED, and cc_request_state_change().

Referenced by ccreq_exec(), handle_cc_subscribe(), and sig_pri_handle_cis_subcmds().

3511 {
3512  va_list ap;
3513  int res;
3514 
3515  va_start(ap, debug);
3516  res = cc_request_state_change(CC_CALLER_REQUESTED, core_id, debug, ap);
3517  va_end(ap);
3518  return res;
3519 }
static int cc_request_state_change(enum cc_state state, const int core_id, const char *debug, va_list ap)
Definition: ccss.c:3062
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 446 of file ccss.c.

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

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

447 {
448  struct cc_callback_helper helper = {.function = function, .args = args, .type = type};
449  struct cc_core_instance *core_instance;
450  if ((core_instance = ao2_t_callback(cc_core_instances, flags, cc_agent_callback_helper, &helper,
451  "Calling provided agent callback function"))) {
452  struct ast_cc_agent *agent = cc_ref(core_instance->agent, "An outside entity needs the agent");
453  cc_unref(core_instance, "agent callback done with the core_instance");
454  return agent;
455  }
456  return NULL;
457 }
static void * cc_unref(void *obj, const char *debug)
Definition: ccss.c:140
static void * cc_ref(void *obj, const char *debug)
Definition: ccss.c:134
ao2_callback_fn * function
Definition: ccss.c:429
static struct @350 args
#define ao2_t_callback(c, flags, cb_fn, arg, tag)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
Definition: astobj2.h:909
static const char type[]
Definition: chan_nbs.c:57
static int cc_agent_callback_helper(void *obj, void *args, int flags)
Definition: ccss.c:434
static struct ao2_container * cc_core_instances
Definition: ccss.c:317
struct ast_cc_agent * agent
Definition: ccss.c:331
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 3554 of file ccss.c.

References CC_ACTIVE, and cc_request_state_change().

Referenced by cc_esc_publish_handler(), generic_agent_devstate_cb(), and sig_pri_handle_cis_subcmds().

3555 {
3556  va_list ap;
3557  int res;
3558 
3559  va_start(ap, debug);
3560  res = cc_request_state_change(CC_ACTIVE, core_id, debug, ap);
3561  va_end(ap);
3562  return res;
3563 }
static int cc_request_state_change(enum cc_state state, const int core_id, const char *debug, va_list ap)
Definition: ccss.c:3062
unsigned int core_id
Definition: ccss.h:832
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 3543 of file ccss.c.

References CC_CALLER_BUSY, and cc_request_state_change().

Referenced by cc_esc_publish_handler(), cc_generic_agent_recall(), sig_pri_handle_cis_subcmds(), and sip_cc_agent_recall().

3544 {
3545  va_list ap;
3546  int res;
3547 
3548  va_start(ap, debug);
3549  res = cc_request_state_change(CC_CALLER_BUSY, core_id, debug, ap);
3550  va_end(ap);
3551  return res;
3552 }
static int cc_request_state_change(enum cc_state state, const int core_id, const char *debug, va_list ap)
Definition: ccss.c:3062
unsigned int core_id
Definition: ccss.h:832
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 3565 of file ccss.c.

References CC_RECALLING, and cc_request_state_change().

Referenced by generic_recall(), get_destination(), and sig_pri_handle_subcmds().

3566 {
3567  va_list ap;
3568  int res;
3569 
3570  va_start(ap, debug);
3571  res = cc_request_state_change(CC_RECALLING, core_id, debug, ap);
3572  va_end(ap);
3573  return res;
3574 }
static int cc_request_state_change(enum cc_state state, const int core_id, const char *debug, va_list ap)
Definition: ccss.c:3062
unsigned int core_id
Definition: ccss.h:832
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 950 of file ccss.c.

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

Referenced by ast_cc_init(), and load_module().

951 {
952  struct cc_agent_backend *backend = ast_calloc(1, sizeof(*backend));
953 
954  if (!backend) {
955  return -1;
956  }
957 
958  backend->callbacks = callbacks;
962  return 0;
963 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
struct cc_agent_backend * next
Definition: ccss.c:944
struct ast_cc_agent_callbacks * callbacks
Definition: ccss.c:945
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:726
#define ast_calloc(a, b)
Definition: astmm.h:82
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 3365 of file ccss.c.

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

Referenced by generic_recall(), handle_request_invite(), and sig_pri_handle_subcmds().

3366 {
3367  struct ast_datastore *recall_datastore;
3368  struct cc_monitor_tree *interface_tree;
3369  struct ast_cc_monitor *monitor;
3370  struct cc_recall_ds_data *recall_data;
3371  struct ast_str *str = ast_str_create(64);
3372  int core_id;
3373 
3374  if (!str) {
3375  return -1;
3376  }
3377 
3378  ast_channel_lock(chan);
3379  if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
3380  ast_channel_unlock(chan);
3381  ast_free(str);
3382  return -1;
3383  }
3384  recall_data = recall_datastore->data;
3385  interface_tree = recall_data->interface_tree;
3386  core_id = recall_data->core_id;
3387  ast_channel_unlock(chan);
3388 
3389  AST_LIST_LOCK(interface_tree);
3390  monitor = AST_LIST_FIRST(interface_tree);
3391  build_cc_interfaces_chanvar(monitor, &str);
3392  AST_LIST_UNLOCK(interface_tree);
3393 
3394  pbx_builtin_setvar_helper(chan, "CC_INTERFACES", ast_str_buffer(str));
3395  ast_log_dynamic_level(cc_logger_level, "Core %d: CC_INTERFACES set to %s\n",
3396  core_id, ast_str_buffer(str));
3397 
3398  ast_free(str);
3399  return 0;
3400 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
#define ast_log_dynamic_level(level,...)
Send a log message to a dynamically registered log level.
Definition: logger.h:229
static void build_cc_interfaces_chanvar(struct ast_cc_monitor *starting_point, struct ast_str **str)
Definition: ccss.c:3322
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
Structure for a data store object.
Definition: datastore.h:54
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:2604
const char * str
Definition: app_jack.c:144
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
static unsigned int monitor
Definition: chan_phone.c:108
The &quot;tree&quot; of interfaces that is dialed.
Definition: ccss.c:314
#define ast_channel_unlock(chan)
Definition: channel.h:2467
#define ast_free(a)
Definition: astmm.h:97
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...
Definition: pbx.c:10546
void * data
Definition: datastore.h:56
static struct ast_datastore_info recall_ds_info
Definition: ccss.c:3133
struct cc_monitor_tree * interface_tree
Definition: ccss.c:3109
static int cc_logger_level
Definition: ccss.c:124
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 3830 of file ccss.c.

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

Referenced by cc_generic_agent_status_request(), sig_pri_handle_cis_subcmds(), and sip_cc_agent_status_request().

3831 {
3832  struct cc_status_response_args *args;
3833  struct cc_core_instance *core_instance;
3834  int res;
3835 
3836  args = ast_calloc(1, sizeof(*args));
3837  if (!args) {
3838  return -1;
3839  }
3840 
3841  core_instance = find_cc_core_instance(core_id);
3842  if (!core_instance) {
3843  ast_free(args);
3844  return -1;
3845  }
3846 
3847  args->core_instance = core_instance;
3848  args->devstate = devstate;
3849 
3851  if (res) {
3852  cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed");
3853  ast_free(args);
3854  }
3855  return res;
3856 }
static void * cc_unref(void *obj, const char *debug)
Definition: ccss.c:140
int ast_taskprocessor_push(struct ast_taskprocessor *tps, int(*task_exe)(void *datap), void *datap)
Push a task into the specified taskprocessor queue and signal the taskprocessor thread.
static struct cc_core_instance * find_cc_core_instance(const int core_id)
Definition: ccss.c:421
static int cc_status_response(void *data)
Definition: ccss.c:3809
static struct @350 args
struct cc_core_instance * core_instance
Definition: ccss.c:3805
#define ast_free(a)
Definition: astmm.h:97
#define ast_calloc(a, b)
Definition: astmm.h:82
enum ast_device_state devstate
Definition: ccss.c:3806
static struct ast_taskprocessor * cc_core_taskprocessor
Definition: ccss.c:116
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
Return values
0Successfully unregistered
-1Failure to unregister

Definition at line 965 of file ccss.c.

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

Referenced by __unload_module(), cc_shutdown(), and unload_module().

966 {
967  struct cc_agent_backend *backend;
970  if (backend->callbacks == callbacks) {
972  ast_free(backend);
973  break;
974  }
975  }
978 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
struct cc_agent_backend * next
Definition: ccss.c:944
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:565
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:542
struct ast_cc_agent_callbacks * callbacks
Definition: ccss.c:945
#define ast_free(a)
Definition: astmm.h:97
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:602
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 1239 of file ccss.c.

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

Referenced by cc_generic_monitor_request_cc(), and sip_cc_monitor_request_cc().

1240 {
1241  struct ast_cc_monitor *monitor = (struct ast_cc_monitor *) data;
1242  int res;
1243  monitor->available_timer_id = -1;
1244  res = ast_cc_monitor_failed(monitor->core_id, monitor->interface->device_name, "Available timer expired for monitor");
1245  cc_unref(monitor, "Unref reference from scheduler\n");
1246  return res;
1247 }
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:3678
static void * cc_unref(void *obj, const char *debug)
Definition: ccss.c:140
int core_id
Definition: ccss.h:511
static unsigned int monitor
Definition: chan_phone.c:108
struct ast_cc_interface * interface
Definition: ccss.h:497
int available_timer_id
Definition: ccss.h:530
char device_name[1]
Definition: ccss.h:822
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 3913 of file ccss.c.

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

Referenced by ast_queue_cc_frame().

3917 {
3918  struct cc_control_payload *payload = ast_calloc(1, sizeof(*payload));
3919 
3920  if (!payload) {
3921  return -1;
3922  }
3923  if (cc_build_payload(chan, cc_params, monitor_type, device_name, dialstring, service, private_data, payload)) {
3924  /* Something screwed up, we can't make a frame with this */
3925  ast_free(payload);
3926  return -1;
3927  }
3928  frame->frametype = AST_FRAME_CONTROL;
3929  frame->subclass.integer = AST_CONTROL_CC;
3930  frame->data.ptr = payload;
3931  frame->datalen = sizeof(*payload);
3932  frame->mallocd = AST_MALLOCD_DATA;
3933  return 0;
3934 }
union ast_frame_subclass subclass
Definition: frame.h:146
The payload for an AST_CONTROL_CC frame.
Definition: ccss.c:212
void * private_data
Private data allocated by the callee.
Definition: ccss.c:247
void * ptr
Definition: frame.h:160
enum ast_cc_service_type service
Definition: chan_sip.c:821
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:3858
char device_name[AST_CHANNEL_NAME]
Name of device to be monitored.
Definition: ccss.c:283
char dialstring[AST_CHANNEL_NAME]
Recall dialstring.
Definition: ccss.c:295
int datalen
Definition: frame.h:148
#define ast_free(a)
Definition: astmm.h:97
int mallocd
Definition: frame.h:152
#define ast_calloc(a, b)
Definition: astmm.h:82
const char * monitor_type
The type of monitor to allocate.
Definition: ccss.c:230
enum ast_frame_type frametype
Definition: frame.h:144
union ast_frame::@172 data
#define AST_MALLOCD_DATA
Definition: frame.h:210
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 3969 of file ccss.c.

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

Referenced by dial_exec_full().

3971 {
3972  struct cc_control_payload payload;
3973  if (cc_build_payload(inbound, cc_params, monitor_type, device_name, dialstring, AST_CC_CCBS, private_data, &payload)) {
3974  /* Something screwed up. Don't try to handle this payload */
3976  return;
3977  }
3978  ast_handle_cc_control_frame(inbound, NULL, &payload);
3979 }
The payload for an AST_CONTROL_CC frame.
Definition: ccss.c:212
void * private_data
Private data allocated by the callee.
Definition: ccss.c:247
static void call_destructor_with_no_monitor(const char *const monitor_type, void *private_data)
Definition: ccss.c:1946
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:2048
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:3858
char device_name[AST_CHANNEL_NAME]
Name of device to be monitored.
Definition: ccss.c:283
char dialstring[AST_CHANNEL_NAME]
Recall dialstring.
Definition: ccss.c:295
const char * monitor_type
The type of monitor to allocate.
Definition: ccss.c:230
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 3936 of file ccss.c.

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

Referenced by dial_exec_full().

3937 {
3939  struct cc_control_payload payload;
3940  struct ast_cc_config_params *cc_params;
3941 
3942  if (outgoing->hangupcause != AST_CAUSE_BUSY && outgoing->hangupcause != AST_CAUSE_CONGESTION) {
3943  /* It doesn't make sense to try to offer CCBS to the caller if the reason for ast_call
3944  * failing is something other than busy or congestion
3945  */
3946  return;
3947  }
3948 
3949  cc_params = ast_channel_get_cc_config_params(outgoing);
3950  if (!cc_params) {
3951  return;
3952  }
3954  /* This sort of CCBS only works if using generic CC. For native, we would end up sending
3955  * a CC request for a non-existent call. The far end will reject this every time
3956  */
3957  return;
3958  }
3959 
3960  ast_channel_get_device_name(outgoing, device_name, sizeof(device_name));
3961  if (cc_build_payload(outgoing, cc_params, AST_CC_GENERIC_MONITOR_TYPE, device_name,
3962  dialstring, AST_CC_CCBS, NULL, &payload)) {
3963  /* Something screwed up, we can't make a frame with this */
3964  return;
3965  }
3966  ast_handle_cc_control_frame(incoming, outgoing, &payload);
3967 }
The payload for an AST_CONTROL_CC frame.
Definition: ccss.c:212
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:2048
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:3858
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:9754
enum ast_cc_monitor_policies ast_get_cc_monitor_policy(struct ast_cc_config_params *config)
Get the cc_monitor_policy.
Definition: ccss.c:763
char device_name[AST_CHANNEL_NAME]
Name of device to be monitored.
Definition: ccss.c:283
#define AST_CC_GENERIC_MONITOR_TYPE
Definition: ccss.h:472
#define AST_CHANNEL_NAME
Definition: channel.h:137
#define AST_CAUSE_BUSY
Definition: causes.h:148
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:9776
int hangupcause
Definition: channel.h:849
#define AST_CAUSE_CONGESTION
Definition: causes.h:152
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 2146 of file ccss.c.

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

Referenced by dial_exec_full().

2147 {
2148  /* There are three situations to deal with here:
2149  *
2150  * 1. The channel does not have a dialed_cc_interfaces datastore on
2151  * it. This means that this is the first time that Dial has
2152  * been called. We need to create/initialize the datastore.
2153  *
2154  * 2. The channel does have a cc_interface datastore on it and
2155  * the "ignore" indicator is 0. This means that a Local channel
2156  * was called by a "parent" dial. We can check the datastore's
2157  * parent field to see who the root of this particular dial tree
2158  * is.
2159  *
2160  * 3. The channel does have a cc_interface datastore on it and
2161  * the "ignore" indicator is 1. This means that a second Dial call
2162  * is being made from an extension. In this case, we do not
2163  * want to make any additions/modifications to the datastore. We
2164  * will instead set a flag to indicate that CCSS is completely
2165  * disabled for this Dial attempt.
2166  */
2167 
2168  struct ast_datastore *cc_interfaces_datastore;
2169  struct dialed_cc_interfaces *interfaces;
2170  struct ast_cc_monitor *monitor;
2171  struct ast_cc_config_params *cc_params;
2172 
2173  ast_channel_lock(chan);
2174 
2175  cc_params = ast_channel_get_cc_config_params(chan);
2176  if (!cc_params) {
2177  ast_channel_unlock(chan);
2178  return -1;
2179  }
2180  if (ast_get_cc_agent_policy(cc_params) == AST_CC_AGENT_NEVER) {
2181  /* We can't offer CC to this caller anyway, so don't bother with CC on this call
2182  */
2183  *ignore_cc = 1;
2184  ast_channel_unlock(chan);
2185  ast_log_dynamic_level(cc_logger_level, "Agent policy for %s is 'never'. CC not possible\n", chan->name);
2186  return 0;
2187  }
2188 
2189  if (!(cc_interfaces_datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL))) {
2190  /* Situation 1 has occurred */
2191  ast_channel_unlock(chan);
2192  return cc_interfaces_datastore_init(chan);
2193  }
2194  interfaces = cc_interfaces_datastore->data;
2195  ast_channel_unlock(chan);
2196 
2197  if (interfaces->ignore) {
2198  /* Situation 3 has occurred */
2199  *ignore_cc = 1;
2200  ast_log_dynamic_level(cc_logger_level, "Datastore is present with ignore flag set. Ignoring CC offers on this call\n");
2201  return 0;
2202  }
2203 
2204  /* Situation 2 has occurred */
2205  if (!(monitor = cc_extension_monitor_init(S_OR(chan->macroexten, chan->exten),
2206  S_OR(chan->macrocontext, chan->context), interfaces->dial_parent_id))) {
2207  return -1;
2208  }
2209  monitor->core_id = interfaces->core_id;
2210  AST_LIST_LOCK(interfaces->interface_tree);
2211  cc_ref(monitor, "monitor tree's reference to the monitor");
2212  AST_LIST_INSERT_TAIL(interfaces->interface_tree, monitor, next);
2213  AST_LIST_UNLOCK(interfaces->interface_tree);
2214  interfaces->dial_parent_id = monitor->id;
2215  cc_unref(monitor, "Unref monitor's allocation reference");
2216  return 0;
2217 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
unsigned int id
Definition: ccss.h:502
static void * cc_unref(void *obj, const char *debug)
Definition: ccss.c:140
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
static void * cc_ref(void *obj, const char *debug)
Definition: ccss.c:134
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
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:1819
#define ast_log_dynamic_level(level,...)
Send a log message to a dynamically registered log level.
Definition: logger.h:229
Structure for a data store object.
Definition: datastore.h:54
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:2604
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:9754
int core_id
Definition: ccss.h:511
static struct ast_datastore_info dialed_cc_interfaces_info
Definition: ccss.c:1719
static int cc_interfaces_datastore_init(struct ast_channel *chan)
Definition: ccss.c:1868
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
static unsigned int monitor
Definition: chan_phone.c:108
const ast_string_field name
Definition: channel.h:787
#define ast_channel_unlock(chan)
Definition: channel.h:2467
char macrocontext[AST_MAX_CONTEXT]
Definition: channel.h:870
struct cc_monitor_tree * interface_tree
Definition: ccss.c:1659
char macroexten[AST_MAX_EXTENSION]
Definition: channel.h:871
void * data
Definition: datastore.h:56
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
unsigned int dial_parent_id
Definition: ccss.c:1632
static int cc_logger_level
Definition: ccss.c:124
enum ast_cc_agent_policies ast_get_cc_agent_policy(struct ast_cc_config_params *config)
Get the cc_agent_policy.
Definition: ccss.c:746
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
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
Always0, I guess.

Definition at line 3981 of file ccss.c.

References ast_get_channel_tech(), and ast_channel_tech::cc_callback.

Referenced by dial_exec_full().

3982 {
3983  const struct ast_channel_tech *chantech = ast_get_channel_tech(tech);
3984 
3985  if (chantech && chantech->cc_callback) {
3986  chantech->cc_callback(inbound, dest, callback);
3987  }
3988 
3989  return 0;
3990 }
struct ast_channel_tech * ast_get_channel_tech(const char *name)
Get a channel technology structure by name.
Definition: channel.c:960
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:635
Structure to describe a channel &quot;technology&quot;, ie a channel driver See for examples: ...
Definition: channel.h:507
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 3576 of file ccss.c.

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

Referenced by wait_for_answer().

3577 {
3578  struct ast_datastore *recall_datastore;
3579  struct cc_recall_ds_data *recall_data;
3580  int core_id;
3581  va_list ap;
3582  int res;
3583 
3584  ast_channel_lock(chan);
3585  if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
3586  /* Silly! Why did you call this function if there's no recall DS? */
3587  ast_channel_unlock(chan);
3588  return -1;
3589  }
3590  recall_data = recall_datastore->data;
3591  if (recall_data->nested || recall_data->ignore) {
3592  /* If this is being called from a nested Dial, it is too
3593  * early to determine if the recall has actually completed.
3594  * The outermost dial is the only one with the authority to
3595  * declare the recall to be complete.
3596  *
3597  * Similarly, if this function has been called when the
3598  * recall has progressed beyond the first dial, this is not
3599  * a legitimate time to declare the recall to be done. In fact,
3600  * that should have been done already.
3601  */
3602  ast_channel_unlock(chan);
3603  return -1;
3604  }
3605  core_id = recall_data->core_id;
3606  ast_channel_unlock(chan);
3607  va_start(ap, debug);
3608  res = cc_request_state_change(CC_COMPLETE, core_id, debug, ap);
3609  va_end(ap);
3610  return res;
3611 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
Structure for a data store object.
Definition: datastore.h:54
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:2604
static int cc_request_state_change(enum cc_state state, const int core_id, const char *debug, va_list ap)
Definition: ccss.c:3062
#define ast_channel_unlock(chan)
Definition: channel.h:2467
void * data
Definition: datastore.h:56
static struct ast_datastore_info recall_ds_info
Definition: ccss.c:3133
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
Return values
void

Definition at line 579 of file ccss.c.

References ast_free.

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

580 {
581  ast_free(params);
582 }
#define ast_free(a)
Definition: astmm.h:97
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
Returns
Nothing

Definition at line 741 of file ccss.c.

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

742 {
743  *dest = *src;
744 }
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.
Returns
Nothing

Definition at line 558 of file ccss.c.

References cc_default_params.

Referenced by __ast_cc_config_params_init().

559 {
560  *params = cc_default_params;
561 }
static struct ast_cc_config_params cc_default_params
Definition: ccss.c:545
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
Return values
void

Definition at line 1735 of file ccss.c.

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

Referenced by dial_exec_full().

1736 {
1737  struct ast_datastore *cc_datastore;
1738  struct dialed_cc_interfaces *cc_interfaces;
1739  struct ast_cc_monitor *monitor;
1740  struct extension_monitor_pvt *extension_pvt;
1741  struct extension_child_dialstring *child_dialstring;
1742  struct cc_monitor_tree *interface_tree;
1743  int id;
1744 
1745  ast_channel_lock(incoming);
1746  if (!(cc_datastore = ast_channel_datastore_find(incoming, &dialed_cc_interfaces_info, NULL))) {
1747  ast_channel_unlock(incoming);
1748  return;
1749  }
1750 
1751  cc_interfaces = cc_datastore->data;
1752  interface_tree = cc_interfaces->interface_tree;
1753  id = cc_interfaces->dial_parent_id;
1754  ast_channel_unlock(incoming);
1755 
1756  AST_LIST_LOCK(interface_tree);
1757  AST_LIST_TRAVERSE(interface_tree, monitor, next) {
1758  if (monitor->id == id) {
1759  break;
1760  }
1761  }
1762 
1763  if (!monitor) {
1764  AST_LIST_UNLOCK(interface_tree);
1765  return;
1766  }
1767 
1768  extension_pvt = monitor->private_data;
1769  if (!(child_dialstring = ast_calloc(1, sizeof(*child_dialstring)))) {
1770  AST_LIST_UNLOCK(interface_tree);
1771  return;
1772  }
1773  ast_copy_string(child_dialstring->original_dialstring, dialstring, sizeof(child_dialstring->original_dialstring));
1774  ast_copy_string(child_dialstring->device_name, device_name, sizeof(child_dialstring->device_name));
1775  child_dialstring->is_valid = 1;
1776  AST_LIST_INSERT_TAIL(&extension_pvt->child_dialstrings, child_dialstring, next);
1777  AST_LIST_UNLOCK(interface_tree);
1778 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
unsigned int id
Definition: ccss.h:502
int is_valid
Is this structure valid for use in CC_INTERFACES?
Definition: ccss.c:1540
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
Structure for a data store object.
Definition: datastore.h:54
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:2604
static struct ast_datastore_info dialed_cc_interfaces_info
Definition: ccss.c:1719
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
char device_name[AST_CHANNEL_NAME]
The name of the device being dialed.
Definition: ccss.c:1525
struct extension_monitor_pvt::@235 child_dialstrings
static unsigned int monitor
Definition: chan_phone.c:108
The &quot;tree&quot; of interfaces that is dialed.
Definition: ccss.c:314
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_channel_unlock(chan)
Definition: channel.h:2467
struct cc_monitor_tree * interface_tree
Definition: ccss.c:1659
void * data
Definition: datastore.h:56
char original_dialstring[AST_CHANNEL_NAME]
the original dialstring used to call a particular device
Definition: ccss.c:1506
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
Data regarding an extension monitor&#39;s child&#39;s dialstrings.
Definition: ccss.c:1490
Private data for an extension monitor.
Definition: ccss.c:1547
enum queue_result id
Definition: app_queue.c:1090
void * private_data
Data that is private to a monitor technology.
Definition: ccss.h:544
unsigned int dial_parent_id
Definition: ccss.c:1632
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 3613 of file ccss.c.

References CC_FAILED, and cc_request_state_change().

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

3614 {
3615  va_list ap;
3616  int res;
3617 
3618  va_start(ap, debug);
3619  res = cc_request_state_change(CC_FAILED, core_id, debug, ap);
3620  va_end(ap);
3621  return res;
3622 }
static int cc_request_state_change(enum cc_state state, const int core_id, const char *debug, va_list ap)
Definition: ccss.c:3062
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 2224 of file ccss.c.

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

Referenced by sig_pri_cc_available(), sig_pri_cc_generic_check(), and sip_handle_cc().

2225 {
2226  struct ast_datastore *datastore;
2227  struct dialed_cc_interfaces *cc_interfaces;
2228  int core_id_return;
2229 
2230  ast_channel_lock(chan);
2231  if (!(datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL))) {
2232  ast_channel_unlock(chan);
2233  return -1;
2234  }
2235 
2236  cc_interfaces = datastore->data;
2237  core_id_return = cc_interfaces->ignore ? -1 : cc_interfaces->core_id;
2238  ast_channel_unlock(chan);
2239  return core_id_return;
2240 
2241 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
Structure for a data store object.
Definition: datastore.h:54
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:2604
static struct ast_datastore_info dialed_cc_interfaces_info
Definition: ccss.c:1719
#define ast_channel_unlock(chan)
Definition: channel.h:2467
void * data
Definition: datastore.h:56
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 3253 of file ccss.c.

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

Referenced by sig_pri_call(), sig_pri_cc_generic_check(), and sip_call().

3254 {
3255  struct cc_core_instance *core_instance = find_cc_core_instance(core_id);
3256  struct ast_cc_monitor *monitor_iter;
3257 
3258  if (!core_instance) {
3259  return NULL;
3260  }
3261 
3262  AST_LIST_LOCK(core_instance->monitors);
3263  AST_LIST_TRAVERSE(core_instance->monitors, monitor_iter, next) {
3264  if (!strcmp(monitor_iter->interface->device_name, device_name)) {
3265  /* Found a monitor. */
3266  cc_ref(monitor_iter, "Hand the requester of the monitor a reference");
3267  break;
3268  }
3269  }
3270  AST_LIST_UNLOCK(core_instance->monitors);
3271  cc_unref(core_instance, "Done with core instance ref in ast_cc_get_monitor_by_recall_core_id");
3272  return monitor_iter;
3273 }
struct cc_monitor_tree * monitors
Definition: ccss.c:335
struct ast_cc_monitor * next
Definition: ccss.h:545
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
static void * cc_unref(void *obj, const char *debug)
Definition: ccss.c:140
static struct cc_core_instance * find_cc_core_instance(const int core_id)
Definition: ccss.c:421
static void * cc_ref(void *obj, const char *debug)
Definition: ccss.c:134
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct ast_cc_interface * interface
Definition: ccss.h:497
char device_name[1]
Definition: ccss.h:822
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 645 of file ccss.c.

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

Referenced by acf_cc_read().

647 {
648  const char *value = NULL;
649 
650  if (!strcasecmp(name, "cc_callback_macro")) {
651  value = ast_get_cc_callback_macro(params);
652  } else if (!strcasecmp(name, "cc_agent_policy")) {
654  } else if (!strcasecmp(name, "cc_monitor_policy")) {
656  } else if (!strcasecmp(name, "cc_agent_dialstring")) {
657  value = ast_get_cc_agent_dialstring(params);
658  }
659  if (value) {
660  ast_copy_string(buf, value, buf_len);
661  return 0;
662  }
663 
664  /* The rest of these are all ints of some sort and require some
665  * snprintf-itude
666  */
667 
668  if (!strcasecmp(name, "cc_offer_timer")) {
669  snprintf(buf, buf_len, "%u", ast_get_cc_offer_timer(params));
670  } else if (!strcasecmp(name, "ccnr_available_timer")) {
671  snprintf(buf, buf_len, "%u", ast_get_ccnr_available_timer(params));
672  } else if (!strcasecmp(name, "ccbs_available_timer")) {
673  snprintf(buf, buf_len, "%u", ast_get_ccbs_available_timer(params));
674  } else if (!strcasecmp(name, "cc_max_agents")) {
675  snprintf(buf, buf_len, "%u", ast_get_cc_max_agents(params));
676  } else if (!strcasecmp(name, "cc_max_monitors")) {
677  snprintf(buf, buf_len, "%u", ast_get_cc_max_monitors(params));
678  } else if (!strcasecmp(name, "cc_recall_timer")) {
679  snprintf(buf, buf_len, "%u", ast_get_cc_recall_timer(params));
680  } else {
681  ast_log(LOG_WARNING, "%s is not a valid CC parameter. Ignoring.\n", name);
682  return -1;
683  }
684 
685  return 0;
686 }
unsigned int ast_get_cc_max_monitors(struct ast_cc_config_params *config)
Get the cc_max_monitors.
Definition: ccss.c:864
#define LOG_WARNING
Definition: logger.h:144
unsigned int ast_get_cc_recall_timer(struct ast_cc_config_params *config)
Get the cc_recall_timer.
Definition: ccss.c:810
static const char * monitor_policy_to_str(enum ast_cc_monitor_policies policy)
Definition: ccss.c:629
int value
Definition: syslog.c:39
unsigned int ast_get_cc_max_agents(struct ast_cc_config_params *config)
Get the cc_max_agents.
Definition: ccss.c:854
enum ast_cc_monitor_policies ast_get_cc_monitor_policy(struct ast_cc_config_params *config)
Get the cc_monitor_policy.
Definition: ccss.c:763
unsigned int ast_get_ccbs_available_timer(struct ast_cc_config_params *config)
Get the ccbs_available_timer.
Definition: ccss.c:825
unsigned int ast_get_ccnr_available_timer(struct ast_cc_config_params *config)
Get the ccnr_available_timer.
Definition: ccss.c:795
const char * ast_get_cc_agent_dialstring(struct ast_cc_config_params *config)
Get the cc_agent_dialstring.
Definition: ccss.c:840
const char * ast_get_cc_callback_macro(struct ast_cc_config_params *config)
Get the name of the callback_macro.
Definition: ccss.c:874
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char name[]
unsigned int ast_get_cc_offer_timer(struct ast_cc_config_params *config)
Get the cc_offer_timer.
Definition: ccss.c:780
static const char * agent_policy_to_str(enum ast_cc_agent_policies policy)
Definition: ccss.c:614
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
enum ast_cc_agent_policies ast_get_cc_agent_policy(struct ast_cc_config_params *config)
Get the cc_agent_policy.
Definition: ccss.c:746
int ast_cc_init ( void  )

Initialize CCSS.

Since
1.8 Performs startup routines necessary for CC operation.
Return values
0Success
nonzeroFailure

Definition at line 4340 of file ccss.c.

References ao2_t_container_alloc, ARRAY_LEN, ast_cc_agent_register(), ast_cc_monitor_register(), ast_cli_register_multiple(), ast_logger_register_level(), ast_register_application2(), ast_register_atexit(), ast_sched_thread_create(), ast_taskprocessor_get(), cc_core_instance_cmp_fn(), cc_core_instance_hash_fn(), cc_shutdown(), cccancel_exec(), ccreq_exec(), generic_monitor_cbs, generic_monitor_cmp_fn(), generic_monitor_hash_fn(), generic_monitors, initialize_cc_max_requests(), and TPS_REF_DEFAULT.

Referenced by main().

4341 {
4342  int res;
4343 
4346  "Create core instance container"))) {
4347  return -1;
4348  }
4351  "Create generic monitor container"))) {
4352  return -1;
4353  }
4355  return -1;
4356  }
4358  return -1;
4359  }
4360  res = ast_register_application2(ccreq_app, ccreq_exec, NULL, NULL, NULL);
4361  res |= ast_register_application2(cccancel_app, cccancel_exec, NULL, NULL, NULL);
4369  return res;
4370 }
int ast_cc_agent_register(const struct ast_cc_agent_callbacks *callbacks)
Register a set of agent callbacks with the core.
Definition: ccss.c:950
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
struct ast_sched_thread * ast_sched_thread_create(void)
Create a scheduler with a dedicated thread.
Definition: sched.c:167
static int dialed_cc_interface_counter
Definition: ccss.c:1605
static const int CC_CORE_INSTANCES_BUCKETS
Definition: ccss.c:316
struct ast_taskprocessor * ast_taskprocessor_get(const char *name, enum ast_tps_options create)
Get a reference to a taskprocessor with the specified name and create the taskprocessor if necessary...
static struct ast_sched_thread * cc_sched_thread
Definition: ccss.c:106
return a reference to a taskprocessor, create one if it does not exist
Definition: taskprocessor.h:58
static const char * ccreq_app
Definition: ccss.c:3992
#define ao2_t_container_alloc(arg1, arg2, arg3, arg4)
Allocate and initialize a container with the desired number of buckets.
Definition: astobj2.h:733
static const char * CC_LOGGER_LEVEL_NAME
Definition: ccss.c:120
static int generic_monitor_cmp_fn(void *obj, void *arg, int flags)
Definition: ccss.c:1100
int ast_cc_monitor_register(const struct ast_cc_monitor_callbacks *callbacks)
Register a set of monitor callbacks with the core.
Definition: ccss.c:895
static int cccancel_exec(struct ast_channel *chan, const char *data)
Definition: ccss.c:4045
static int generic_monitor_hash_fn(const void *obj, const int flags)
Definition: ccss.c:1094
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
Definition: asterisk.c:998
static struct ast_cli_entry cc_cli[]
Definition: ccss.c:4308
int ast_logger_register_level(const char *name)
Register a new logger level.
Definition: logger.c:1627
static int ccreq_exec(struct ast_channel *chan, const char *data)
Definition: ccss.c:3994
struct ao2_container * generic_monitors
Definition: ccss.c:1044
static struct ast_cc_agent_callbacks generic_agent_callbacks
Definition: ccss.c:2343
static int cc_core_instance_cmp_fn(void *obj, void *arg, int flags)
Definition: ccss.c:413
static void initialize_cc_max_requests(void)
Definition: ccss.c:4114
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
static struct ao2_container * cc_core_instances
Definition: ccss.c:317
int ast_register_application2(const char *app, int(*execute)(struct ast_channel *, const char *), const char *synopsis, const char *description, void *mod)
Register an application.
Definition: pbx.c:6344
static struct ast_cc_monitor_callbacks generic_monitor_cbs
Definition: ccss.c:1035
static const char * cccancel_app
Definition: ccss.c:4043
static int cc_logger_level
Definition: ccss.c:124
static int cc_core_instance_hash_fn(const void *obj, const int flags)
Definition: ccss.c:407
static void cc_shutdown(void)
Definition: ccss.c:4313
static struct ast_taskprocessor * cc_core_taskprocessor
Definition: ccss.c:116
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 727 of file ccss.c.

Referenced by build_peer(), and process_dahdi().

728 {
729  return (!strcasecmp(name, "cc_agent_policy") ||
730  !strcasecmp(name, "cc_monitor_policy") ||
731  !strcasecmp(name, "cc_offer_timer") ||
732  !strcasecmp(name, "ccnr_available_timer") ||
733  !strcasecmp(name, "ccbs_available_timer") ||
734  !strcasecmp(name, "cc_max_agents") ||
735  !strcasecmp(name, "cc_max_monitors") ||
736  !strcasecmp(name, "cc_callback_macro") ||
737  !strcasecmp(name, "cc_agent_dialstring") ||
738  !strcasecmp(name, "cc_recall_timer"));
739 }
static const char name[]
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 3172 of file ccss.c.

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

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

3173 {
3174  struct ast_datastore *recall_datastore;
3175  struct cc_recall_ds_data *recall_data;
3176  struct cc_monitor_tree *interface_tree;
3177  char device_name[AST_CHANNEL_NAME];
3178  struct ast_cc_monitor *device_monitor;
3179  int core_id_candidate;
3180 
3181  ast_assert(core_id != NULL);
3182 
3183  *core_id = -1;
3184 
3185  ast_channel_lock(chan);
3186  if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
3187  /* Obviously not a recall if the datastore isn't present */
3188  ast_channel_unlock(chan);
3189  return 0;
3190  }
3191 
3192  recall_data = recall_datastore->data;
3193 
3194  if (recall_data->ignore) {
3195  /* Though this is a recall, the call to this particular interface is not part of the
3196  * recall either because this is a call forward or because this is not the first
3197  * invocation of Dial during this call
3198  */
3199  ast_channel_unlock(chan);
3200  return 0;
3201  }
3202 
3203  if (!recall_data->nested) {
3204  /* If the nested flag is not set, then this means that
3205  * the channel passed to this function is the caller making
3206  * the recall. This means that we shouldn't look through
3207  * the monitor tree for the channel because it shouldn't be
3208  * there. However, this is a recall though, so return true.
3209  */
3210  *core_id = recall_data->core_id;
3211  ast_channel_unlock(chan);
3212  return 1;
3213  }
3214 
3215  if (ast_strlen_zero(monitor_type)) {
3216  /* If someone passed a NULL or empty monitor type, then it is clear
3217  * the channel they passed in was an incoming channel, and so searching
3218  * the list of dialed interfaces is not going to be helpful. Just return
3219  * false immediately.
3220  */
3221  ast_channel_unlock(chan);
3222  return 0;
3223  }
3224 
3225  interface_tree = recall_data->interface_tree;
3226  ast_channel_get_device_name(chan, device_name, sizeof(device_name));
3227  /* We grab the value of the recall_data->core_id so that we
3228  * can unlock the channel before we start looking through the
3229  * interface list. That way we don't have to worry about a possible
3230  * clash between the channel lock and the monitor tree lock.
3231  */
3232  core_id_candidate = recall_data->core_id;
3233  ast_channel_unlock(chan);
3234 
3235  /*
3236  * Now we need to find out if the channel device name
3237  * is in the list of interfaces in the called tree.
3238  */
3239  AST_LIST_LOCK(interface_tree);
3240  AST_LIST_TRAVERSE(interface_tree, device_monitor, next) {
3241  if (!strcmp(device_monitor->interface->device_name, device_name) &&
3242  !strcmp(device_monitor->interface->monitor_type, monitor_type)) {
3243  /* BOOM! Device is in the tree! We have a winner! */
3244  *core_id = core_id_candidate;
3245  AST_LIST_UNLOCK(interface_tree);
3246  return 1;
3247  }
3248  }
3249  AST_LIST_UNLOCK(interface_tree);
3250  return 0;
3251 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
struct ast_cc_monitor * next
Definition: ccss.h:545
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define ast_assert(a)
Definition: utils.h:738
Structure for a data store object.
Definition: datastore.h:54
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:2604
int core_id
Definition: ccss.h:511
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
The &quot;tree&quot; of interfaces that is dialed.
Definition: ccss.c:314
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_channel_unlock(chan)
Definition: channel.h:2467
#define AST_CHANNEL_NAME
Definition: channel.h:137
const char * monitor_type
The type of monitor that should be used for this interface.
Definition: ccss.h:813
struct ast_cc_interface * interface
Definition: ccss.h:497
void * data
Definition: datastore.h:56
static struct ast_datastore_info recall_ds_info
Definition: ccss.c:3133
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:9776
struct cc_monitor_tree * interface_tree
Definition: ccss.c:3109
char device_name[1]
Definition: ccss.h:822
int ast_cc_monitor_callee_available ( const int  core_id,
const char *const  debug,
  ... 
)

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

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

Definition at line 3532 of file ccss.c.

References CC_CALLEE_READY, and cc_request_state_change().

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

3533 {
3534  va_list ap;
3535  int res;
3536 
3537  va_start(ap, debug);
3538  res = cc_request_state_change(CC_CALLEE_READY, core_id, debug, ap);
3539  va_end(ap);
3540  return res;
3541 }
int core_id
Definition: ccss.h:511
static int cc_request_state_change(enum cc_state state, const int core_id, const char *debug, va_list ap)
Definition: ccss.c:3062
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 4105 of file ccss.c.

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

Referenced by ast_queue_cc_frame().

4106 {
4107  struct count_monitors_cb_data data = {.device_name = name, .monitor_type = type,};
4108 
4109  ao2_t_callback(cc_core_instances, OBJ_NODATA, count_monitors_cb, &data, "Counting agents");
4110  ast_log_dynamic_level(cc_logger_level, "Counted %d monitors\n", data.count);
4111  return data.count;
4112 }
#define ast_log_dynamic_level(level,...)
Send a log message to a dynamically registered log level.
Definition: logger.h:229
static int count_monitors_cb(void *obj, void *arg, int flags)
Definition: ccss.c:4085
#define ao2_t_callback(c, flags, cb_fn, arg, tag)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
Definition: astobj2.h:909
static const char name[]
static const char type[]
Definition: chan_nbs.c:57
static struct ao2_container * cc_core_instances
Definition: ccss.c:317
static int cc_logger_level
Definition: ccss.c:124
const char * device_name
Definition: ccss.c:4080
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
Returns
void

Definition at line 3678 of file ccss.c.

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

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

3679 {
3680  struct ast_cc_monitor_failure_data *failure_data;
3681  int res;
3682  va_list ap;
3683 
3684  if (!(failure_data = ast_calloc(1, sizeof(*failure_data)))) {
3685  return -1;
3686  }
3687 
3688  if (!(failure_data->device_name = ast_strdup(monitor_name))) {
3689  ast_free(failure_data);
3690  return -1;
3691  }
3692 
3693  va_start(ap, debug);
3694  if (ast_vasprintf(&failure_data->debug, debug, ap) == -1) {
3695  va_end(ap);
3696  ast_free((char *)failure_data->device_name);
3697  ast_free(failure_data);
3698  return -1;
3699  }
3700  va_end(ap);
3701 
3702  failure_data->core_id = core_id;
3703 
3705  if (res) {
3706  ast_free((char *)failure_data->device_name);
3707  ast_free((char *)failure_data->debug);
3708  ast_free(failure_data);
3709  }
3710  return res;
3711 }
#define ast_strdup(a)
Definition: astmm.h:109
#define ast_vasprintf(a, b, c)
Definition: astmm.h:127
int ast_taskprocessor_push(struct ast_taskprocessor *tps, int(*task_exe)(void *datap), void *datap)
Push a task into the specified taskprocessor queue and signal the taskprocessor thread.
const char * device_name
Definition: ccss.c:3625
static int cc_monitor_failed(void *data)
Definition: ccss.c:3630
#define ast_free(a)
Definition: astmm.h:97
#define ast_calloc(a, b)
Definition: astmm.h:82
static struct ast_taskprocessor * cc_core_taskprocessor
Definition: ccss.c:116
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 3788 of file ccss.c.

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

Referenced by sig_pri_handle_cis_subcmds().

3789 {
3790  int res;
3791  struct cc_core_instance *core_instance = find_cc_core_instance(core_id);
3792 
3793  if (!core_instance) {
3794  return -1;
3795  }
3796 
3798  if (res) {
3799  cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed");
3800  }
3801  return res;
3802 }
static void * cc_unref(void *obj, const char *debug)
Definition: ccss.c:140
int ast_taskprocessor_push(struct ast_taskprocessor *tps, int(*task_exe)(void *datap), void *datap)
Push a task into the specified taskprocessor queue and signal the taskprocessor thread.
static struct cc_core_instance * find_cc_core_instance(const int core_id)
Definition: ccss.c:421
static int cc_party_b_free(void *data)
Definition: ccss.c:3776
static struct ast_taskprocessor * cc_core_taskprocessor
Definition: ccss.c:116
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 895 of file ccss.c.

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

Referenced by ast_cc_init(), and load_module().

896 {
897  struct cc_monitor_backend *backend = ast_calloc(1, sizeof(*backend));
898 
899  if (!backend) {
900  return -1;
901  }
902 
903  backend->callbacks = callbacks;
904 
908  return 0;
909 }
struct ast_cc_monitor_callbacks * callbacks
Definition: ccss.c:890
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
struct cc_monitor_backend * next
Definition: ccss.c:889
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:726
#define ast_calloc(a, b)
Definition: astmm.h:82
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 3521 of file ccss.c.

References CC_ACTIVE, and cc_request_state_change().

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

3522 {
3523  va_list ap;
3524  int res;
3525 
3526  va_start(ap, debug);
3527  res = cc_request_state_change(CC_ACTIVE, core_id, debug, ap);
3528  va_end(ap);
3529  return res;
3530 }
static int cc_request_state_change(enum cc_state state, const int core_id, const char *debug, va_list ap)
Definition: ccss.c:3062
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 3723 of file ccss.c.

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

Referenced by sig_pri_handle_cis_subcmds().

3724 {
3725  int res;
3726  struct cc_core_instance *core_instance = find_cc_core_instance(core_id);
3727 
3728  if (!core_instance) {
3729  return -1;
3730  }
3731 
3733  if (res) {
3734  cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed");
3735  }
3736  return res;
3737 }
static void * cc_unref(void *obj, const char *debug)
Definition: ccss.c:140
int ast_taskprocessor_push(struct ast_taskprocessor *tps, int(*task_exe)(void *datap), void *datap)
Push a task into the specified taskprocessor queue and signal the taskprocessor thread.
static struct cc_core_instance * find_cc_core_instance(const int core_id)
Definition: ccss.c:421
static int cc_status_request(void *data)
Definition: ccss.c:3713
static struct ast_taskprocessor * cc_core_taskprocessor
Definition: ccss.c:116
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 3760 of file ccss.c.

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

Referenced by sig_pri_handle_cis_subcmds().

3761 {
3762  int res;
3763  struct cc_core_instance *core_instance = find_cc_core_instance(core_id);
3764 
3765  if (!core_instance) {
3766  return -1;
3767  }
3768 
3770  if (res) {
3771  cc_unref(core_instance, "Unref core instance. ast_taskprocessor_push failed");
3772  }
3773  return res;
3774 }
static void * cc_unref(void *obj, const char *debug)
Definition: ccss.c:140
int ast_taskprocessor_push(struct ast_taskprocessor *tps, int(*task_exe)(void *datap), void *datap)
Push a task into the specified taskprocessor queue and signal the taskprocessor thread.
static struct cc_core_instance * find_cc_core_instance(const int core_id)
Definition: ccss.c:421
static int cc_stop_ringing(void *data)
Definition: ccss.c:3739
static struct ast_taskprocessor * cc_core_taskprocessor
Definition: ccss.c:116
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
Return values
0Successfully unregistered
-1Failure to unregister

Definition at line 928 of file ccss.c.

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

Referenced by __unload_module(), cc_shutdown(), and unload_module().

929 {
930  struct cc_monitor_backend *backend;
933  if (backend->callbacks == callbacks) {
935  ast_free(backend);
936  break;
937  }
938  }
941 }
struct ast_cc_monitor_callbacks * callbacks
Definition: ccss.c:890
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:565
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:542
#define ast_free(a)
Definition: astmm.h:97
struct cc_monitor_backend * next
Definition: ccss.c:889
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:602
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 3485 of file ccss.c.

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

Referenced by ast_hangup().

3486 {
3487  int core_id;
3488  int res = -1;
3489  struct ast_datastore *datastore;
3490  struct dialed_cc_interfaces *cc_interfaces;
3491  char cc_is_offerable;
3492 
3493  ast_channel_lock(caller_chan);
3494  if (!(datastore = ast_channel_datastore_find(caller_chan, &dialed_cc_interfaces_info, NULL))) {
3495  ast_channel_unlock(caller_chan);
3496  return res;
3497  }
3498 
3499  cc_interfaces = datastore->data;
3500  cc_is_offerable = cc_interfaces->is_original_caller;
3501  core_id = cc_interfaces->core_id;
3502  ast_channel_unlock(caller_chan);
3503 
3504  if (cc_is_offerable) {
3505  res = cc_offer(core_id, "CC offered to caller %s", caller_chan->name);
3506  }
3507  return res;
3508 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
Structure for a data store object.
Definition: datastore.h:54
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:2604
char is_original_caller
Definition: ccss.c:1655
static struct ast_datastore_info dialed_cc_interfaces_info
Definition: ccss.c:1719
const ast_string_field name
Definition: channel.h:787
#define ast_channel_unlock(chan)
Definition: channel.h:2467
static int cc_offer(const int core_id, const char *const debug,...)
Definition: ccss.c:3474
void * data
Definition: datastore.h:56
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 2219 of file ccss.c.

References global_cc_max_requests.

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

2220 {
2222 }
static unsigned int global_cc_max_requests
Definition: ccss.c:128
static int cc_request_count
Definition: ccss.c:132
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 688 of file ccss.c.

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

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

690 {
691  unsigned int value_as_uint;
692  if (!strcasecmp(name, "cc_agent_policy")) {
694  } else if (!strcasecmp(name, "cc_monitor_policy")) {
696  } else if (!strcasecmp(name, "cc_agent_dialstring")) {
698  } else if (!strcasecmp(name, "cc_callback_macro")) {
700  return 0;
701  }
702 
703  if (!sscanf(value, "%30u", &value_as_uint) == 1) {
704  return -1;
705  }
706 
707  if (!strcasecmp(name, "cc_offer_timer")) {
708  ast_set_cc_offer_timer(params, value_as_uint);
709  } else if (!strcasecmp(name, "ccnr_available_timer")) {
710  ast_set_ccnr_available_timer(params, value_as_uint);
711  } else if (!strcasecmp(name, "ccbs_available_timer")) {
712  ast_set_ccbs_available_timer(params, value_as_uint);
713  } else if (!strcasecmp(name, "cc_max_agents")) {
714  ast_set_cc_max_agents(params, value_as_uint);
715  } else if (!strcasecmp(name, "cc_max_monitors")) {
716  ast_set_cc_max_monitors(params, value_as_uint);
717  } else if (!strcasecmp(name, "cc_recall_timer")) {
718  ast_set_cc_recall_timer(params, value_as_uint);
719  } else {
720  ast_log(LOG_WARNING, "%s is not a valid CC parameter. Ignoring.\n", name);
721  return -1;
722  }
723 
724  return 0;
725 }
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:751
static enum ast_cc_monitor_policies str_to_monitor_policy(const char *const value)
Definition: ccss.c:598
#define LOG_WARNING
Definition: logger.h:144
void ast_set_cc_max_monitors(struct ast_cc_config_params *config, unsigned int value)
Set the cc_max_monitors.
Definition: ccss.c:869
void ast_set_ccnr_available_timer(struct ast_cc_config_params *config, unsigned int value)
Set the ccnr_available_timer.
Definition: ccss.c:800
int value
Definition: syslog.c:39
void ast_set_cc_offer_timer(struct ast_cc_config_params *config, unsigned int value)
Set the cc_offer_timer.
Definition: ccss.c:785
void ast_set_cc_callback_macro(struct ast_cc_config_params *config, const char *const value)
Set the callback_macro name.
Definition: ccss.c:879
static enum ast_cc_agent_policies str_to_agent_policy(const char *const value)
Definition: ccss.c:584
void ast_set_cc_recall_timer(struct ast_cc_config_params *config, unsigned int value)
Set the cc_recall_timer.
Definition: ccss.c:815
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char name[]
void ast_set_ccbs_available_timer(struct ast_cc_config_params *config, unsigned int value)
Set the ccbs_available_timer.
Definition: ccss.c:830
void ast_set_cc_max_agents(struct ast_cc_config_params *config, unsigned int value)
Set the cc_max_agents.
Definition: ccss.c:859
void ast_set_cc_agent_dialstring(struct ast_cc_config_params *config, const char *const value)
Set the cc_agent_dialstring.
Definition: ccss.c:845
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:768
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 840 of file ccss.c.

References ast_cc_config_params::cc_agent_dialstring.

Referenced by ast_cc_get_param().

841 {
842  return config->cc_agent_dialstring;
843 }
char cc_agent_dialstring[AST_MAX_EXTENSION]
Definition: ccss.c:162
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 746 of file ccss.c.

References ast_cc_config_params::cc_agent_policy.

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

747 {
748  return config->cc_agent_policy;
749 }
enum ast_cc_agent_policies cc_agent_policy
Definition: ccss.c:153
const char* ast_get_cc_callback_macro ( struct ast_cc_config_params config)

Get the name of the callback_macro.

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

Definition at line 874 of file ccss.c.

References ast_cc_config_params::cc_callback_macro.

Referenced by ast_cc_get_param(), and generic_recall().

875 {
876  return config->cc_callback_macro;
877 }
char cc_callback_macro[AST_MAX_EXTENSION]
Definition: ccss.c:161
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 854 of file ccss.c.

References ast_cc_config_params::cc_max_agents.

Referenced by ast_cc_get_param(), and cc_core_init_instance().

855 {
856  return config->cc_max_agents;
857 }
unsigned int cc_max_agents
Definition: ccss.c:159
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 864 of file ccss.c.

References ast_cc_config_params::cc_max_monitors.

Referenced by ast_cc_get_param(), and ast_queue_cc_frame().

865 {
866  return config->cc_max_monitors;
867 }
unsigned int cc_max_monitors
Definition: ccss.c:160
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 763 of file ccss.c.

References ast_cc_config_params::cc_monitor_policy.

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

764 {
765  return config->cc_monitor_policy;
766 }
enum ast_cc_monitor_policies cc_monitor_policy
Definition: ccss.c:154
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 780 of file ccss.c.

References ast_cc_config_params::cc_offer_timer.

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

781 {
782  return config->cc_offer_timer;
783 }
unsigned int cc_offer_timer
Definition: ccss.c:155
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 810 of file ccss.c.

References ast_cc_config_params::cc_recall_timer.

Referenced by ast_cc_get_param(), and generic_recall().

811 {
812  return config->cc_recall_timer;
813 }
unsigned int cc_recall_timer
Definition: ccss.c:158
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 825 of file ccss.c.

References ast_cc_config_params::ccbs_available_timer.

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

826 {
827  return config->ccbs_available_timer;
828 }
unsigned int ccbs_available_timer
Definition: ccss.c:157
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 795 of file ccss.c.

References ast_cc_config_params::ccnr_available_timer.

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

796 {
797  return config->ccnr_available_timer;
798 }
unsigned int ccnr_available_timer
Definition: ccss.c:156
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.
Return values
voidUnless we are ignoring CC for some reason, we will always call this function when we read an AST_CONTROL_CC frame from an outbound channel.

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

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

Definition at line 2048 of file ccss.c.

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

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

2049 {
2050  char *device_name;
2051  char *dialstring;
2052  struct ast_cc_monitor *monitor;
2053  struct ast_datastore *cc_datastore;
2054  struct dialed_cc_interfaces *cc_interfaces;
2055  struct cc_control_payload *cc_data = frame_data;
2056  struct cc_core_instance *core_instance;
2057 
2058  device_name = cc_data->device_name;
2059  dialstring = cc_data->dialstring;
2060 
2061  ast_channel_lock(inbound);
2062  if (!(cc_datastore = ast_channel_datastore_find(inbound, &dialed_cc_interfaces_info, NULL))) {
2063  ast_log(LOG_WARNING, "Unable to retrieve CC datastore while processing CC frame from '%s'. CC services will be unavailable.\n", device_name);
2064  ast_channel_unlock(inbound);
2066  return;
2067  }
2068 
2069  cc_interfaces = cc_datastore->data;
2070 
2071  if (cc_interfaces->ignore) {
2072  ast_channel_unlock(inbound);
2074  return;
2075  }
2076 
2077  if (!cc_interfaces->is_original_caller) {
2078  /* If the is_original_caller is not set on the *inbound* channel, then
2079  * it must be a local channel. As such, we do not want to create a core instance
2080  * or an agent for the local channel. Instead, we want to pass this along to the
2081  * other side of the local channel so that the original caller can benefit.
2082  */
2083  ast_channel_unlock(inbound);
2084  ast_indicate_data(inbound, AST_CONTROL_CC, cc_data, sizeof(*cc_data));
2085  return;
2086  }
2087 
2088  core_instance = find_cc_core_instance(cc_interfaces->core_id);
2089  if (!core_instance) {
2090  core_instance = cc_core_init_instance(inbound, cc_interfaces->interface_tree,
2091  cc_interfaces->core_id, cc_data);
2092  if (!core_instance) {
2093  cc_interfaces->ignore = 1;
2094  ast_channel_unlock(inbound);
2096  return;
2097  }
2098  }
2099 
2100  ast_channel_unlock(inbound);
2101 
2102  /* Yeah this kind of sucks, but luckily most people
2103  * aren't dialing thousands of interfaces on every call
2104  *
2105  * This traversal helps us to not create duplicate monitors in
2106  * case a device queues multiple CC control frames.
2107  */
2108  AST_LIST_LOCK(cc_interfaces->interface_tree);
2109  AST_LIST_TRAVERSE(cc_interfaces->interface_tree, monitor, next) {
2110  if (!strcmp(monitor->interface->device_name, device_name)) {
2111  ast_log_dynamic_level(cc_logger_level, "Core %d: Device %s sent us multiple CC control frames. Ignoring those beyond the first.\n",
2112  core_instance->core_id, device_name);
2113  AST_LIST_UNLOCK(cc_interfaces->interface_tree);
2114  cc_unref(core_instance, "Returning early from ast_handle_cc_control_frame. Unref core_instance");
2116  return;
2117  }
2118  }
2119  AST_LIST_UNLOCK(cc_interfaces->interface_tree);
2120 
2121  if (!(monitor = cc_device_monitor_init(device_name, dialstring, cc_data, core_instance->core_id))) {
2122  ast_log(LOG_WARNING, "Unable to create CC device interface for '%s'. CC services will be unavailable on this interface.\n", device_name);
2123  cc_unref(core_instance, "Returning early from ast_handle_cc_control_frame. Unref core_instance");
2125  return;
2126  }
2127 
2128  AST_LIST_LOCK(cc_interfaces->interface_tree);
2129  cc_ref(monitor, "monitor tree's reference to the monitor");
2130  AST_LIST_INSERT_TAIL(cc_interfaces->interface_tree, monitor, next);
2131  AST_LIST_UNLOCK(cc_interfaces->interface_tree);
2132 
2133  cc_extension_monitor_change_is_valid(core_instance, monitor->parent_id, monitor->interface->device_name, 0);
2134 
2135  manager_event(EVENT_FLAG_CC, "CCAvailable",
2136  "CoreID: %d\r\n"
2137  "Callee: %s\r\n"
2138  "Service: %s\r\n",
2139  cc_interfaces->core_id, device_name, cc_service_to_string(cc_data->service)
2140  );
2141 
2142  cc_unref(core_instance, "Done with core_instance after handling CC control frame");
2143  cc_unref(monitor, "Unref reference from allocating monitor");
2144 }
static const char * cc_service_to_string(enum ast_cc_service_type service)
Definition: ccss.c:402
#define ast_channel_lock(chan)
Definition: channel.h:2466
The payload for an AST_CONTROL_CC frame.
Definition: ccss.c:212
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
void * private_data
Private data allocated by the callee.
Definition: ccss.c:247
static void * cc_unref(void *obj, const char *debug)
Definition: ccss.c:140
static struct cc_core_instance * find_cc_core_instance(const int core_id)
Definition: ccss.c:421
#define LOG_WARNING
Definition: logger.h:144
static void * cc_ref(void *obj, const char *debug)
Definition: ccss.c:134
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
static void call_destructor_with_no_monitor(const char *const monitor_type, void *private_data)
Definition: ccss.c:1946
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:4447
#define ast_log_dynamic_level(level,...)
Send a log message to a dynamically registered log level.
Definition: logger.h:229
Structure for a data store object.
Definition: datastore.h:54
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:1780
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:2604
#define EVENT_FLAG_CC
Definition: manager.h:86
unsigned int parent_id
Definition: ccss.h:507
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:1982
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:2652
char device_name[AST_CHANNEL_NAME]
Name of device to be monitored.
Definition: ccss.c:283
char dialstring[AST_CHANNEL_NAME]
Recall dialstring.
Definition: ccss.c:295
char is_original_caller
Definition: ccss.c:1655
static struct ast_datastore_info dialed_cc_interfaces_info
Definition: ccss.c:1719
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
static unsigned int monitor
Definition: chan_phone.c:108
enum ast_cc_service_type service
Service offered by the endpoint.
Definition: ccss.c:256
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_channel_unlock(chan)
Definition: channel.h:2467
struct ast_cc_interface * interface
Definition: ccss.h:497
struct cc_monitor_tree * interface_tree
Definition: ccss.c:1659
void * data
Definition: datastore.h:56
const char * monitor_type
The type of monitor to allocate.
Definition: ccss.c:230
char device_name[1]
Definition: ccss.h:822
static int cc_logger_level
Definition: ccss.c:124
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:219
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.
Return values
void

Definition at line 3454 of file ccss.c.

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

Referenced by dial_exec_full(), and do_forward().

3455 {
3456  struct ast_datastore *cc_datastore;
3457  struct ast_datastore *cc_recall_datastore;
3458  struct dialed_cc_interfaces *cc_interfaces;
3459  struct cc_recall_ds_data *recall_cc_data;
3460 
3461  ast_channel_lock(chan);
3462  if ((cc_datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL))) {
3463  cc_interfaces = cc_datastore->data;
3464  cc_interfaces->ignore = 1;
3465  }
3466 
3467  if ((cc_recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
3468  recall_cc_data = cc_recall_datastore->data;
3469  recall_cc_data->ignore = 1;
3470  }
3471  ast_channel_unlock(chan);
3472 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
Structure for a data store object.
Definition: datastore.h:54
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:2604
static struct ast_datastore_info dialed_cc_interfaces_info
Definition: ccss.c:1719
#define ast_channel_unlock(chan)
Definition: channel.h:2467
void * data
Definition: datastore.h:56
static struct ast_datastore_info recall_ds_info
Definition: ccss.c:3133
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 3886 of file ccss.c.

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

Referenced by analog_call(), sig_pri_cc_available(), sig_pri_cc_generic_check(), and sip_handle_cc().

3888 {
3889  struct ast_frame frame = {0,};
3890  char device_name[AST_CHANNEL_NAME];
3891  int retval;
3892  struct ast_cc_config_params *cc_params;
3893 
3894  cc_params = ast_channel_get_cc_config_params(chan);
3895  if (!cc_params) {
3896  return -1;
3897  }
3898  ast_channel_get_device_name(chan, device_name, sizeof(device_name));
3899  if (ast_cc_monitor_count(device_name, monitor_type) >= ast_get_cc_max_monitors(cc_params)) {
3900  ast_log(LOG_NOTICE, "Not queuing a CC frame for device %s since it already has its maximum monitors allocated\n", device_name);
3901  return -1;
3902  }
3903 
3904  if (ast_cc_build_frame(chan, cc_params, monitor_type, device_name, dialstring, service, private_data, &frame)) {
3905  /* Frame building failed. We can't use this. */
3906  return -1;
3907  }
3908  retval = ast_queue_frame(chan, &frame);
3909  ast_frfree(&frame);
3910  return retval;
3911 }
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:4105
unsigned int ast_get_cc_max_monitors(struct ast_cc_config_params *config)
Get the cc_max_monitors.
Definition: ccss.c:864
enum ast_cc_service_type service
Definition: chan_sip.c:821
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:9754
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:3913
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1558
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
#define AST_CHANNEL_NAME
Definition: channel.h:137
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:9776
Data structure associated with a single frame of data.
Definition: frame.h:142
#define ast_frfree(fr)
Definition: frame.h:583
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
Return values
void

Definition at line 845 of file ccss.c.

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

Referenced by ast_cc_set_param().

846 {
847  if (ast_strlen_zero(value)) {
848  config->cc_agent_dialstring[0] = '\0';
849  } else {
851  }
852 }
int value
Definition: syslog.c:39
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
char cc_agent_dialstring[AST_MAX_EXTENSION]
Definition: ccss.c:162
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 751 of file ccss.c.

References AST_CC_AGENT_GENERIC, ast_cc_config_params::cc_agent_policy, and value.

Referenced by ast_cc_set_param(), and build_peer().

752 {
753  /* Screw C and its weak type checking for making me have to do this
754  * validation at runtime.
755  */
756  if (value < AST_CC_AGENT_NEVER || value > AST_CC_AGENT_GENERIC) {
757  return -1;
758  }
759  config->cc_agent_policy = value;
760  return 0;
761 }
enum ast_cc_agent_policies cc_agent_policy
Definition: ccss.c:153
int value
Definition: syslog.c:39
void ast_set_cc_callback_macro ( struct ast_cc_config_params config,
const char *const  value 
)

Set the callback_macro name.

Since
1.8
Parameters
configThe configuration to set the callback_macro on
valueThe new callback macro we want to change to
Return values
void

Definition at line 879 of file ccss.c.

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

Referenced by ast_cc_set_param().

880 {
881  if (ast_strlen_zero(value)) {
882  config->cc_callback_macro[0] = '\0';
883  } else {
884  ast_copy_string(config->cc_callback_macro, value, sizeof(config->cc_callback_macro));
885  }
886 }
int value
Definition: syslog.c:39
char cc_callback_macro[AST_MAX_EXTENSION]
Definition: ccss.c:161
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
int ast_set_cc_interfaces_chanvar ( struct ast_channel chan,
const char *const  extension 
)

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

Since
1.8

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

Note
This function will lock the channel as well as the list of monitors stored on the channel's CC recall datastore, though neither are held at the same time. Callers of this function should be aware of potential lock ordering problems that may arise.
Parameters
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 3402 of file ccss.c.

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

Referenced by local_call().

3403 {
3404  struct ast_datastore *recall_datastore;
3405  struct cc_monitor_tree *interface_tree;
3406  struct ast_cc_monitor *monitor_iter;
3407  struct cc_recall_ds_data *recall_data;
3408  struct ast_str *str = ast_str_create(64);
3409  int core_id;
3410 
3411  if (!str) {
3412  return -1;
3413  }
3414 
3415  ast_channel_lock(chan);
3416  if (!(recall_datastore = ast_channel_datastore_find(chan, &recall_ds_info, NULL))) {
3417  ast_channel_unlock(chan);
3418  ast_free(str);
3419  return -1;
3420  }
3421  recall_data = recall_datastore->data;
3422  interface_tree = recall_data->interface_tree;
3423  core_id = recall_data->core_id;
3424  ast_channel_unlock(chan);
3425 
3426  AST_LIST_LOCK(interface_tree);
3427  AST_LIST_TRAVERSE(interface_tree, monitor_iter, next) {
3428  if (!strcmp(monitor_iter->interface->device_name, extension)) {
3429  break;
3430  }
3431  }
3432 
3433  if (!monitor_iter) {
3434  /* We couldn't find this extension. This may be because
3435  * we have been directed into an unexpected extension because
3436  * the admin has changed a CC_INTERFACES variable at some point.
3437  */
3438  AST_LIST_UNLOCK(interface_tree);
3439  ast_free(str);
3440  return -1;
3441  }
3442 
3443  build_cc_interfaces_chanvar(monitor_iter, &str);
3444  AST_LIST_UNLOCK(interface_tree);
3445 
3446  pbx_builtin_setvar_helper(chan, "CC_INTERFACES", ast_str_buffer(str));
3447  ast_log_dynamic_level(cc_logger_level, "Core %d: CC_INTERFACES set to %s\n",
3448  core_id, ast_str_buffer(str));
3449 
3450  ast_free(str);
3451  return 0;
3452 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
#define ast_log_dynamic_level(level,...)
Send a log message to a dynamically registered log level.
Definition: logger.h:229
static void build_cc_interfaces_chanvar(struct ast_cc_monitor *starting_point, struct ast_str **str)
Definition: ccss.c:3322
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
Structure for a data store object.
Definition: datastore.h:54
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:2604
const char * str
Definition: app_jack.c:144
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
The &quot;tree&quot; of interfaces that is dialed.
Definition: ccss.c:314
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_channel_unlock(chan)
Definition: channel.h:2467
#define ast_free(a)
Definition: astmm.h:97
struct ast_cc_interface * interface
Definition: ccss.h:497
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...
Definition: pbx.c:10546
void * data
Definition: datastore.h:56
static struct ast_datastore_info recall_ds_info
Definition: ccss.c:3133
struct cc_monitor_tree * interface_tree
Definition: ccss.c:3109
char device_name[1]
Definition: ccss.h:822
static int cc_logger_level
Definition: ccss.c:124
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
Return values
void

Definition at line 859 of file ccss.c.

References ast_cc_config_params::cc_max_agents, and value.

Referenced by ast_cc_set_param().

860 {
861  config->cc_max_agents = value;
862 }
int value
Definition: syslog.c:39
unsigned int cc_max_agents
Definition: ccss.c:159
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
Return values
void

Definition at line 869 of file ccss.c.

References ast_cc_config_params::cc_max_monitors, and value.

Referenced by ast_cc_set_param().

870 {
871  config->cc_max_monitors = value;
872 }
int value
Definition: syslog.c:39
unsigned int cc_max_monitors
Definition: ccss.c:160
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 768 of file ccss.c.

References AST_CC_MONITOR_ALWAYS, ast_cc_config_params::cc_monitor_policy, and value.

Referenced by ast_cc_set_param().

769 {
770  /* Screw C and its weak type checking for making me have to do this
771  * validation at runtime.
772  */
773  if (value < AST_CC_MONITOR_NEVER || value > AST_CC_MONITOR_ALWAYS) {
774  return -1;
775  }
776  config->cc_monitor_policy = value;
777  return 0;
778 }
int value
Definition: syslog.c:39
enum ast_cc_monitor_policies cc_monitor_policy
Definition: ccss.c:154
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
Return values
void

Definition at line 785 of file ccss.c.

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

Referenced by ast_cc_set_param().

786 {
787  /* 0 is an unreasonable value for any timer. Stick with the default */
788  if (value == 0) {
789  ast_log(LOG_WARNING, "0 is an invalid value for cc_offer_timer. Retaining value as %u\n", config->cc_offer_timer);
790  return;
791  }
792  config->cc_offer_timer = value;
793 }
#define LOG_WARNING
Definition: logger.h:144
int value
Definition: syslog.c:39
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
unsigned int cc_offer_timer
Definition: ccss.c:155
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
Return values
void

Definition at line 815 of file ccss.c.

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

Referenced by ast_cc_set_param().

816 {
817  /* 0 is an unreasonable value for any timer. Stick with the default */
818  if (value == 0) {
819  ast_log(LOG_WARNING, "0 is an invalid value for ccnr_available_timer. Retaining value as %u\n", config->cc_recall_timer);
820  return;
821  }
822  config->cc_recall_timer = value;
823 }
#define LOG_WARNING
Definition: logger.h:144
unsigned int cc_recall_timer
Definition: ccss.c:158
int value
Definition: syslog.c:39
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
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
Return values
void

Definition at line 830 of file ccss.c.

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

Referenced by ast_cc_set_param().

831 {
832  /* 0 is an unreasonable value for any timer. Stick with the default */
833  if (value == 0) {
834  ast_log(LOG_WARNING, "0 is an invalid value for ccbs_available_timer. Retaining value as %u\n", config->ccbs_available_timer);
835  return;
836  }
837  config->ccbs_available_timer = value;
838 }
#define LOG_WARNING
Definition: logger.h:144
int value
Definition: syslog.c:39
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
unsigned int ccbs_available_timer
Definition: ccss.c:157
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
Return values
void

Definition at line 800 of file ccss.c.

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

Referenced by ast_cc_set_param().

801 {
802  /* 0 is an unreasonable value for any timer. Stick with the default */
803  if (value == 0) {
804  ast_log(LOG_WARNING, "0 is an invalid value for ccnr_available_timer. Retaining value as %u\n", config->ccnr_available_timer);
805  return;
806  }
807  config->ccnr_available_timer = value;
808 }
#define LOG_WARNING
Definition: logger.h:144
unsigned int ccnr_available_timer
Definition: ccss.c:156
int value
Definition: syslog.c:39
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
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 3139 of file ccss.c.

References ast_calloc, ast_channel_datastore_add(), ast_channel_lock, ast_channel_unlock, ast_datastore_alloc(), ast_datastore_free(), ast_free, cc_ref(), cc_unref(), 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, and cc_core_instance::monitors.

Referenced by generic_recall(), handle_request_invite(), and sig_pri_handle_subcmds().

3140 {
3141  struct ast_datastore *recall_datastore = ast_datastore_alloc(&recall_ds_info, NULL);
3142  struct cc_recall_ds_data *recall_data;
3143  struct cc_core_instance *core_instance;
3144 
3145  if (!recall_datastore) {
3146  return -1;
3147  }
3148 
3149  if (!(recall_data = ast_calloc(1, sizeof(*recall_data)))) {
3150  ast_datastore_free(recall_datastore);
3151  return -1;
3152  }
3153 
3154  if (!(core_instance = find_cc_core_instance(core_id))) {
3155  ast_free(recall_data);
3156  ast_datastore_free(recall_datastore);
3157  return -1;
3158  }
3159 
3160  recall_data->interface_tree = cc_ref(core_instance->monitors,
3161  "Bump refcount for monitor tree for recall datastore");
3162  recall_data->core_id = core_id;
3163  recall_datastore->data = recall_data;
3164  recall_datastore->inheritance = DATASTORE_INHERIT_FOREVER;
3165  ast_channel_lock(chan);
3166  ast_channel_datastore_add(chan, recall_datastore);
3167  ast_channel_unlock(chan);
3168  cc_unref(core_instance, "Recall datastore set up. No need for core_instance ref");
3169  return 0;
3170 }
struct cc_monitor_tree * monitors
Definition: ccss.c:335
#define ast_channel_lock(chan)
Definition: channel.h:2466
static void * cc_unref(void *obj, const char *debug)
Definition: ccss.c:140
static struct cc_core_instance * find_cc_core_instance(const int core_id)
Definition: ccss.c:421
static void * cc_ref(void *obj, const char *debug)
Definition: ccss.c:134
Structure for a data store object.
Definition: datastore.h:54
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:65
struct ast_datastore * ast_datastore_alloc(const struct ast_datastore_info *info, const char *uid)
Definition: datastore.c:98
#define ast_channel_unlock(chan)
Definition: channel.h:2467
#define ast_free(a)
Definition: astmm.h:97
#define DATASTORE_INHERIT_FOREVER
Definition: channel.h:156
unsigned int inheritance
Definition: datastore.h:58
void * data
Definition: datastore.h:56
#define ast_calloc(a, b)
Definition: astmm.h:82
static struct ast_datastore_info recall_ds_info
Definition: ccss.c:3133
struct cc_monitor_tree * interface_tree
Definition: ccss.c:3109
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2590