channel.c File Reference

Channel Management. More...

#include "asterisk.h"
#include "asterisk/_private.h"
#include <sys/time.h>
#include <signal.h>
#include <math.h>
#include "asterisk/paths.h"
#include "asterisk/pbx.h"
#include "asterisk/frame.h"
#include "asterisk/mod_format.h"
#include "asterisk/sched.h"
#include "asterisk/channel.h"
#include "asterisk/musiconhold.h"
#include "asterisk/say.h"
#include "asterisk/file.h"
#include "asterisk/cli.h"
#include "asterisk/translate.h"
#include "asterisk/manager.h"
#include "asterisk/chanvars.h"
#include "asterisk/linkedlists.h"
#include "asterisk/indications.h"
#include "asterisk/monitor.h"
#include "asterisk/causes.h"
#include "asterisk/callerid.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/app.h"
#include "asterisk/transcap.h"
#include "asterisk/devicestate.h"
#include "asterisk/threadstorage.h"
#include "asterisk/slinfactory.h"
#include "asterisk/audiohook.h"
#include "asterisk/framehook.h"
#include "asterisk/timing.h"
#include "asterisk/autochan.h"
#include "asterisk/stringfields.h"
#include "asterisk/global_datastores.h"
#include "asterisk/data.h"
#include "asterisk/channel_internal.h"
#include "asterisk/features.h"
#include "asterisk/bridge.h"
#include "asterisk/test.h"
#include "asterisk/stasis_channels.h"

Include dependency graph for channel.c:

Go to the source code of this file.

Data Structures

struct  ast_channel_iterator
struct  ast_epoll_data
struct  ast_party_id_ies
struct  ast_party_name_ies
struct  ast_party_number_ies
struct  ast_party_redirecting_reason_ies
struct  ast_party_subaddress_ies
struct  ast_silence_generator
struct  backends
 the list of registered channel types More...
struct  causes_map
 map AST_CAUSE's to readable string representations More...
struct  chanlist
 List of channel drivers. More...
struct  channelvars
struct  manager_channel_variable
 List of channel variables to append to all channel-related events. More...
struct  namedgroup_member
 Named group member structure. More...
struct  plc_ds
struct  set_format_access
struct  suppress_data
struct  tonepair_def
struct  tonepair_state

Defines

#define AST_DEFAULT_EMULATE_DTMF_DURATION   100
#define AST_MIN_DTMF_GAP   45
#define DEFAULT_AMA_FLAGS   AST_AMA_DOCUMENTATION
#define FORMAT   "%-15.15s %-40.40s %-13.13s %-13.13s %-13.13s %-13.13s\n"
#define NUM_CHANNEL_BUCKETS   1567
#define STATE2STR_BUFSIZE   32

Enumerations

enum  {
  AST_CONNECTED_LINE_NUMBER, AST_CONNECTED_LINE_NAME, AST_CONNECTED_LINE_NUMBER_PLAN, AST_CONNECTED_LINE_ID_PRESENTATION,
  AST_CONNECTED_LINE_SOURCE, AST_CONNECTED_LINE_SUBADDRESS, AST_CONNECTED_LINE_SUBADDRESS_TYPE, AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN,
  AST_CONNECTED_LINE_SUBADDRESS_VALID, AST_CONNECTED_LINE_TAG, AST_CONNECTED_LINE_VERSION, AST_CONNECTED_LINE_NAME_VALID,
  AST_CONNECTED_LINE_NAME_CHAR_SET, AST_CONNECTED_LINE_NAME_PRESENTATION, AST_CONNECTED_LINE_NUMBER_VALID, AST_CONNECTED_LINE_NUMBER_PRESENTATION,
  AST_CONNECTED_LINE_PRIV_NUMBER, AST_CONNECTED_LINE_PRIV_NUMBER_PLAN, AST_CONNECTED_LINE_PRIV_NUMBER_VALID, AST_CONNECTED_LINE_PRIV_NUMBER_PRESENTATION,
  AST_CONNECTED_LINE_PRIV_NAME, AST_CONNECTED_LINE_PRIV_NAME_VALID, AST_CONNECTED_LINE_PRIV_NAME_CHAR_SET, AST_CONNECTED_LINE_PRIV_NAME_PRESENTATION,
  AST_CONNECTED_LINE_PRIV_SUBADDRESS, AST_CONNECTED_LINE_PRIV_SUBADDRESS_TYPE, AST_CONNECTED_LINE_PRIV_SUBADDRESS_ODD_EVEN, AST_CONNECTED_LINE_PRIV_SUBADDRESS_VALID,
  AST_CONNECTED_LINE_PRIV_TAG
}
 Element identifiers for connected line indication frame data. More...
enum  {
  AST_REDIRECTING_FROM_NUMBER, AST_REDIRECTING_FROM_NAME, AST_REDIRECTING_FROM_NUMBER_PLAN, AST_REDIRECTING_FROM_ID_PRESENTATION,
  AST_REDIRECTING_TO_NUMBER, AST_REDIRECTING_TO_NAME, AST_REDIRECTING_TO_NUMBER_PLAN, AST_REDIRECTING_TO_ID_PRESENTATION,
  AST_REDIRECTING_REASON_CODE, AST_REDIRECTING_COUNT, AST_REDIRECTING_FROM_SUBADDRESS, AST_REDIRECTING_FROM_SUBADDRESS_TYPE,
  AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_FROM_SUBADDRESS_VALID, AST_REDIRECTING_TO_SUBADDRESS, AST_REDIRECTING_TO_SUBADDRESS_TYPE,
  AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_TO_SUBADDRESS_VALID, AST_REDIRECTING_FROM_TAG, AST_REDIRECTING_TO_TAG,
  AST_REDIRECTING_VERSION, AST_REDIRECTING_FROM_NAME_VALID, AST_REDIRECTING_FROM_NAME_CHAR_SET, AST_REDIRECTING_FROM_NAME_PRESENTATION,
  AST_REDIRECTING_FROM_NUMBER_VALID, AST_REDIRECTING_FROM_NUMBER_PRESENTATION, AST_REDIRECTING_TO_NAME_VALID, AST_REDIRECTING_TO_NAME_CHAR_SET,
  AST_REDIRECTING_TO_NAME_PRESENTATION, AST_REDIRECTING_TO_NUMBER_VALID, AST_REDIRECTING_TO_NUMBER_PRESENTATION, AST_REDIRECTING_ORIG_NUMBER,
  AST_REDIRECTING_ORIG_NUMBER_VALID, AST_REDIRECTING_ORIG_NUMBER_PLAN, AST_REDIRECTING_ORIG_NUMBER_PRESENTATION, AST_REDIRECTING_ORIG_NAME,
  AST_REDIRECTING_ORIG_NAME_VALID, AST_REDIRECTING_ORIG_NAME_CHAR_SET, AST_REDIRECTING_ORIG_NAME_PRESENTATION, AST_REDIRECTING_ORIG_SUBADDRESS,
  AST_REDIRECTING_ORIG_SUBADDRESS_TYPE, AST_REDIRECTING_ORIG_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_ORIG_SUBADDRESS_VALID, AST_REDIRECTING_ORIG_TAG,
  AST_REDIRECTING_ORIG_REASON_CODE, AST_REDIRECTING_PRIV_TO_NUMBER, AST_REDIRECTING_PRIV_TO_NUMBER_PLAN, AST_REDIRECTING_PRIV_TO_NUMBER_VALID,
  AST_REDIRECTING_PRIV_TO_NUMBER_PRESENTATION, AST_REDIRECTING_PRIV_TO_NAME, AST_REDIRECTING_PRIV_TO_NAME_VALID, AST_REDIRECTING_PRIV_TO_NAME_CHAR_SET,
  AST_REDIRECTING_PRIV_TO_NAME_PRESENTATION, AST_REDIRECTING_PRIV_TO_SUBADDRESS, AST_REDIRECTING_PRIV_TO_SUBADDRESS_TYPE, AST_REDIRECTING_PRIV_TO_SUBADDRESS_ODD_EVEN,
  AST_REDIRECTING_PRIV_TO_SUBADDRESS_VALID, AST_REDIRECTING_PRIV_TO_TAG, AST_REDIRECTING_PRIV_FROM_NUMBER, AST_REDIRECTING_PRIV_FROM_NUMBER_PLAN,
  AST_REDIRECTING_PRIV_FROM_NUMBER_VALID, AST_REDIRECTING_PRIV_FROM_NUMBER_PRESENTATION, AST_REDIRECTING_PRIV_FROM_NAME, AST_REDIRECTING_PRIV_FROM_NAME_VALID,
  AST_REDIRECTING_PRIV_FROM_NAME_CHAR_SET, AST_REDIRECTING_PRIV_FROM_NAME_PRESENTATION, AST_REDIRECTING_PRIV_FROM_SUBADDRESS, AST_REDIRECTING_PRIV_FROM_SUBADDRESS_TYPE,
  AST_REDIRECTING_PRIV_FROM_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_PRIV_FROM_SUBADDRESS_VALID, AST_REDIRECTING_PRIV_FROM_TAG, AST_REDIRECTING_PRIV_ORIG_NUMBER,
  AST_REDIRECTING_PRIV_ORIG_NUMBER_VALID, AST_REDIRECTING_PRIV_ORIG_NUMBER_PLAN, AST_REDIRECTING_PRIV_ORIG_NUMBER_PRESENTATION, AST_REDIRECTING_PRIV_ORIG_NAME,
  AST_REDIRECTING_PRIV_ORIG_NAME_VALID, AST_REDIRECTING_PRIV_ORIG_NAME_CHAR_SET, AST_REDIRECTING_PRIV_ORIG_NAME_PRESENTATION, AST_REDIRECTING_PRIV_ORIG_SUBADDRESS,
  AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_TYPE, AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_VALID, AST_REDIRECTING_PRIV_ORIG_TAG,
  AST_REDIRECTING_REASON_STR, AST_REDIRECTING_ORIG_REASON_STR
}
 Element identifiers for redirecting indication frame data. More...
enum  DtmfDirection { DTMF_RECEIVED, DTMF_SENT }

Functions

int __ast_answer (struct ast_channel *chan, unsigned int delay)
 Answer a channel, with a selectable delay before returning.
static void __ast_change_name_nolink (struct ast_channel *chan, const char *newname)
 this function simply changes the name of the channel and issues a manager_event with out unlinking and linking the channel from the ao2_container. This should only be used when the channel has already been unlinked from the ao2_container.
struct ast_channel__ast_channel_alloc (int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, enum ama_flags amaflag, struct ast_endpoint *endpoint, const char *file, int line, const char *function, const char *name_fmt,...)
 Create a channel structure.
static struct ast_channel
*attribute_malloc 
__ast_channel_alloc_ap (int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, enum ama_flags amaflag, struct ast_endpoint *endpoint, const char *file, int line, const char *function, const char *name_fmt, va_list ap)
 Create a new channel structure.
static int __ast_queue_frame (struct ast_channel *chan, struct ast_frame *fin, int head, struct ast_frame *after)
static struct ast_frame__ast_read (struct ast_channel *chan, int dropaudio)
struct ast_channel__ast_request_and_dial (const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int timeout, int *outstate, const char *cid_num, const char *cid_name, struct outgoing_helper *oh)
 Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it.
static void __fini_backends (void)
static void __fini_channelvars (void)
static void __init_backends (void)
static void __init_channelvars (void)
static void __init_state2str_threadbuf (void)
static void adjust_frame_for_plc (struct ast_channel *chan, struct ast_frame *frame, struct ast_datastore *datastore)
static void apply_plc (struct ast_channel *chan, struct ast_frame *frame)
int ast_activate_generator (struct ast_channel *chan, struct ast_generator *gen, void *params)
int ast_active_channels (void)
 returns number of active/allocated channels
int ast_answer (struct ast_channel *chan)
 Answer a channel.
int ast_auto_answer (struct ast_channel *chan)
 Answer a channel, if it's not already answered.
int ast_call (struct ast_channel *chan, const char *addr, int timeout)
 Make a call.
struct ast_channelast_call_forward (struct ast_channel *caller, struct ast_channel *orig, int *timeout, struct ast_format_cap *cap, struct outgoing_helper *oh, int *outstate)
 Forwards a call to a new channel specified by the original channel's call_forward str. If possible, the new forwarded channel is created and returned while the original one is terminated.
const char * ast_cause2str (int cause)
 Gives the string form of a given hangup cause.
void ast_change_name (struct ast_channel *chan, const char *newname)
 Change channel name.
const char * ast_channel_amaflags2string (enum ama_flags flag)
 Convert the enum representation of an AMA flag to a string representation.
struct ast_channelast_channel_bridge_peer (struct ast_channel *chan)
 Get the channel's bridge peer only if the bridge is two-party.
static int ast_channel_by_exten_cb (void *obj, void *arg, void *data, int flags)
static int ast_channel_by_name_cb (void *obj, void *arg, void *data, int flags)
static int ast_channel_by_uniqueid_cb (void *obj, void *arg, void *data, int flags)
struct ast_channelast_channel_callback (ao2_callback_data_fn *cb_fn, void *arg, void *data, int ao2_flags)
 Call a function with every active channel.
int ast_channel_cc_params_init (struct ast_channel *chan, const struct ast_cc_config_params *base_params)
 Set up datastore with CCSS parameters for a channel.
void ast_channel_clear_softhangup (struct ast_channel *chan, int flag)
 Clear a set of softhangup flags from a channel.
static int ast_channel_cmp_cb (void *obj, void *arg, int flags)
int ast_channel_cmpwhentohangup (struct ast_channel *chan, time_t offset)
 Compare a offset with the settings of when to hang a channel up.
int ast_channel_cmpwhentohangup_tv (struct ast_channel *chan, struct timeval offset)
 Compare a offset with when to hangup channel.
int ast_channel_connected_line_macro (struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *connected_info, int is_caller, int is_frame)
 Run a connected line interception macro and update a channel's connected line information.
int ast_channel_connected_line_sub (struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *connected_info, int is_frame)
 Run a connected line interception subroutine and update a channel's connected line information.
int ast_channel_datastore_add (struct ast_channel *chan, struct ast_datastore *datastore)
 Add a datastore to a channel.
struct ast_datastoreast_channel_datastore_alloc (const struct ast_datastore_info *info, const char *uid)
 Create a channel data store object.
struct ast_datastoreast_channel_datastore_find (struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
 Find a datastore on a channel.
int ast_channel_datastore_free (struct ast_datastore *datastore)
 Free a channel data store object.
int ast_channel_datastore_inherit (struct ast_channel *from, struct ast_channel *to)
 Inherit datastores from a parent to a child.
int ast_channel_datastore_remove (struct ast_channel *chan, struct ast_datastore *datastore)
 Remove a datastore from a channel.
int ast_channel_defer_dtmf (struct ast_channel *chan)
 Set defer DTMF flag on channel.
static void ast_channel_destructor (void *obj)
 Free a channel structure.
int ast_channel_early_bridge (struct ast_channel *c0, struct ast_channel *c1)
 Bridge two channels together (early).
void ast_channel_end_dtmf (struct ast_channel *chan, char digit, struct timeval start, const char *why)
 Simulate a DTMF end on a broken bridge channel.
int ast_channel_feature_hooks_append (struct ast_channel *chan, struct ast_bridge_features *features)
 Appends to the channel-attached features a channel has access to upon being bridged.
struct ast_bridge_featuresast_channel_feature_hooks_get (struct ast_channel *chan)
 Gets the channel-attached features a channel has access to upon being bridged.
int ast_channel_feature_hooks_replace (struct ast_channel *chan, struct ast_bridge_features *features)
 Sets the channel-attached features a channel has access to upon being bridged.
struct ast_bridgeast_channel_get_bridge (const struct ast_channel *chan)
 Get the bridge associated with a channel.
struct ast_bridge_channelast_channel_get_bridge_channel (struct ast_channel *chan)
 Get a reference to the channel's bridge pointer.
struct ast_channelast_channel_get_by_exten (const char *exten, const char *context)
 Find a channel by extension and context.
struct ast_channelast_channel_get_by_name (const char *name)
 Find a channel by name.
struct ast_channelast_channel_get_by_name_prefix (const char *name, size_t name_len)
 Find a channel by a name prefix.
int ast_channel_get_cc_agent_type (struct ast_channel *chan, char *agent_type, size_t size)
 Find the appropriate CC agent type to use given a channel.
struct ast_cc_config_paramsast_channel_get_cc_config_params (struct ast_channel *chan)
 Get the CCSS parameters from a channel.
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.
int ast_channel_get_duration (struct ast_channel *chan)
 Obtain how long the channel since the channel was created.
struct varsheadast_channel_get_manager_vars (struct ast_channel *chan)
 Gets the variables for a given channel, as specified by ast_channel_set_manager_vars().
int ast_channel_get_up_time (struct ast_channel *chan)
 Obtain how long it has been since the channel was answered.
struct varsheadast_channel_get_vars (struct ast_channel *chan)
 Gets the variables for a given channel, as set using pbx_builtin_setvar_helper().
void ast_channel_hangupcause_hash_set (struct ast_channel *chan, const struct ast_control_pvt_cause_code *cause_code, int datalen)
 Sets the HANGUPCAUSE hash and optionally the SIP_CAUSE hash on the given channel.
int ast_channel_has_audio_frame_or_monitor (struct ast_channel *chan)
 Check if the channel has active audiohooks, active framehooks, or a monitor.
int ast_channel_has_hook_requiring_audio (struct ast_channel *chan)
 Check if the channel has any active hooks that require audio.
int ast_channel_has_manager_vars (void)
 Return whether or not any manager variables have been set.
static int ast_channel_hash_cb (const void *obj, const int flags)
void ast_channel_inherit_variables (const struct ast_channel *parent, struct ast_channel *child)
 Inherits channel variable from parent to child channel.
int ast_channel_is_bridged (const struct ast_channel *chan)
 Determine if a channel is in a bridge.
int ast_channel_is_leaving_bridge (struct ast_channel *chan)
 Determine if a channel is leaving a bridge, but not hung up.
struct ast_channel_iteratorast_channel_iterator_all_new (void)
 Create a new channel iterator.
struct ast_channel_iteratorast_channel_iterator_by_exten_new (const char *exten, const char *context)
 Create a new channel iterator based on extension.
struct ast_channel_iteratorast_channel_iterator_by_name_new (const char *name, size_t name_len)
 Create a new channel iterator based on name.
struct ast_channel_iteratorast_channel_iterator_destroy (struct ast_channel_iterator *i)
 Destroy a channel iterator.
struct ast_channelast_channel_iterator_next (struct ast_channel_iterator *i)
 Get the next channel for a channel iterator.
int ast_channel_make_compatible (struct ast_channel *chan, struct ast_channel *peer)
 Make the frame formats of two channels compatible.
static int ast_channel_make_compatible_helper (struct ast_channel *from, struct ast_channel *to)
 Set up translation from one channel to another.
int ast_channel_move (struct ast_channel *dest, struct ast_channel *source)
 Move a channel from its current location to a new location.
void ast_channel_name_to_dial_string (char *channel_name)
 Removes the trailing identifiers from a channel name string.
int ast_channel_queryoption (struct ast_channel *chan, int option, void *data, int *datalen, int block)
 Checks the value of an option.
void ast_channel_queue_connected_line_update (struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
 Queue a connected line update frame on a channel.
void ast_channel_queue_redirecting_update (struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
 Queue a redirecting update frame on a channel.
const char * ast_channel_reason2str (int reason)
 return an english explanation of the code returned thru __ast_request_and_dial's 'outstate' argument
int ast_channel_redirecting_macro (struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *redirecting_info, int is_caller, int is_frame)
 Run a redirecting interception macro and update a channel's redirecting information.
int ast_channel_redirecting_sub (struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *redirecting_info, int is_frame)
 Run a redirecting interception subroutine and update a channel's redirecting information.
int ast_channel_register (const struct ast_channel_tech *tech)
 Register a new telephony channel in Asterisk.
struct ast_channelast_channel_release (struct ast_channel *chan)
 Unlink and release reference to a channel.
void ast_channel_req_accountcodes (struct ast_channel *chan, const struct ast_channel *requestor, enum ast_channel_requestor_relationship relationship)
 Setup new channel accountcodes from the requestor channel after ast_request().
void ast_channel_req_accountcodes_precious (struct ast_channel *chan, const struct ast_channel *requestor, enum ast_channel_requestor_relationship relationship)
 Setup new channel accountcodes from the requestor channel after ast_request().
int ast_channel_sendhtml (struct ast_channel *chan, int subclass, const char *data, int datalen)
 Sends HTML on given channel Send HTML or URL on link.
int ast_channel_sendurl (struct ast_channel *chan, const char *url)
 Sends a URL on a given link Send URL on link.
void ast_channel_set_caller (struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
 Set the caller id information in the Asterisk channel.
void ast_channel_set_caller_event (struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
 Set the caller id information in the Asterisk channel and generate an AMI event if the caller id name or number changed.
void ast_channel_set_connected_line (struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
 Set the connected line information in the Asterisk channel.
void ast_channel_set_fd (struct ast_channel *chan, int which, int fd)
void ast_channel_set_manager_vars (size_t varc, char **vars)
 Sets the variables to be stored in the manager_vars field of all snapshots.
void ast_channel_set_redirecting (struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
 Set the redirecting id information in the Asterisk channel.
int ast_channel_setoption (struct ast_channel *chan, int option, void *data, int datalen, int block)
 Sets an option on a channel.
void ast_channel_setwhentohangup (struct ast_channel *chan, time_t offset)
 Set when to hang a channel up.
void ast_channel_setwhentohangup_tv (struct ast_channel *chan, struct timeval offset)
 Set when to hangup channel.
static int ast_channel_softhangup_cb (void *obj, void *arg, int flags)
void ast_channel_softhangup_withcause_locked (struct ast_channel *chan, int causecode)
 Lock the given channel, then request softhangup on the channel with the given causecode.
struct ast_silence_generatorast_channel_start_silence_generator (struct ast_channel *chan)
 Starts a silence generator on the given channel.
void ast_channel_stop_silence_generator (struct ast_channel *chan, struct ast_silence_generator *state)
 Stops a previously-started silence generator on the given channel.
enum ama_flags ast_channel_string2amaflag (const char *flag)
 Convert a string to a detail record AMA flag.
int ast_channel_supports_html (struct ast_channel *chan)
 Checks for HTML support on a channel.
int ast_channel_suppress (struct ast_channel *chan, unsigned int direction, enum ast_frame_type frametype)
 Suppress passing of a frame type on a channel.
void ast_channel_undefer_dtmf (struct ast_channel *chan)
 Unset defer DTMF flag on channel.
void ast_channel_unlink (struct ast_channel *chan)
 Remove a channel from the global channels container.
void ast_channel_unregister (const struct ast_channel_tech *tech)
 Unregister channel driver.
int ast_channel_unsuppress (struct ast_channel *chan, unsigned int direction, enum ast_frame_type frametype)
 Stop suppressing of a frame type on a channel.
void ast_channel_update_connected_line (struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
 Indicate that the connected line information has changed.
void ast_channel_update_redirecting (struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
 Indicate that the redirecting id has changed.
struct ast_channelast_channel_yank (struct ast_channel *yankee)
 Gain control of a channel in the system.
void ast_channels_init (void)
struct ast_variableast_channeltype_list (void)
 return an ast_variable list of channeltypes
int ast_check_hangup (struct ast_channel *chan)
 Checks to see if a channel is needing hang up.
int ast_check_hangup_locked (struct ast_channel *chan)
int ast_connected_line_build_data (unsigned char *data, size_t datalen, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
 Build the connected line information data frame.
void ast_connected_line_copy_from_caller (struct ast_party_connected_line *dest, const struct ast_party_caller *src)
 Copy the caller information to the connected line information.
void ast_connected_line_copy_to_caller (struct ast_party_caller *dest, const struct ast_party_connected_line *src)
 Copy the connected line information to the caller information.
int ast_connected_line_parse_data (const unsigned char *data, size_t datalen, struct ast_party_connected_line *connected)
 Parse connected line indication frame data.
void ast_deactivate_generator (struct ast_channel *chan)
struct ast_channelast_dummy_channel_alloc (void)
 Create a fake channel structure.
static void ast_dummy_channel_destructor (void *obj)
 Free a dummy channel structure.
struct ast_channel_techast_get_channel_tech (const char *name)
 Get handle to channel driver based on name.
ast_group_t ast_get_group (const char *s)
struct ast_namedgroups * ast_get_namedgroups (const char *s)
 Create an ast_namedgroups set with group names from comma separated string.
void ast_hangup (struct ast_channel *chan)
 Hangup a channel.
int ast_indicate (struct ast_channel *chan, int condition)
 Indicates condition of channel.
int ast_indicate_data (struct ast_channel *chan, int _condition, const void *data, size_t datalen)
 Indicates condition of channel, with payload.
void ast_install_music_functions (int(*start_ptr)(struct ast_channel *, const char *, const char *), void(*stop_ptr)(struct ast_channel *), void(*cleanup_ptr)(struct ast_channel *))
int ast_is_deferrable_frame (const struct ast_frame *frame)
 Should we keep this frame for later?
void ast_moh_cleanup (struct ast_channel *chan)
int ast_moh_start (struct ast_channel *chan, const char *mclass, const char *interpclass)
 Turn on music on hold on a given channel.
void ast_moh_stop (struct ast_channel *chan)
 Turn off music on hold on a given channel.
int ast_namedgroups_intersect (struct ast_namedgroups *a, struct ast_namedgroups *b)
 Return TRUE if group a and b contain at least one common groupname.
void ast_party_caller_copy (struct ast_party_caller *dest, const struct ast_party_caller *src)
 Copy the source caller information to the destination caller.
void ast_party_caller_free (struct ast_party_caller *doomed)
 Destroy the caller party contents.
void ast_party_caller_init (struct ast_party_caller *init)
 Initialize the given caller structure.
void ast_party_caller_set (struct ast_party_caller *dest, const struct ast_party_caller *src, const struct ast_set_party_caller *update)
 Set the caller information based on another caller source.
void ast_party_caller_set_init (struct ast_party_caller *init, const struct ast_party_caller *guide)
 Initialize the given caller structure using the given guide for a set update operation.
void ast_party_connected_line_collect_caller (struct ast_party_connected_line *connected, struct ast_party_caller *caller)
 Collect the caller party information into a connected line structure.
void ast_party_connected_line_copy (struct ast_party_connected_line *dest, const struct ast_party_connected_line *src)
 Copy the source connected line information to the destination connected line.
void ast_party_connected_line_free (struct ast_party_connected_line *doomed)
 Destroy the connected line information contents.
void ast_party_connected_line_init (struct ast_party_connected_line *init)
 Initialize the given connected line structure.
void ast_party_connected_line_set (struct ast_party_connected_line *dest, const struct ast_party_connected_line *src, const struct ast_set_party_connected_line *update)
 Set the connected line information based on another connected line source.
void ast_party_connected_line_set_init (struct ast_party_connected_line *init, const struct ast_party_connected_line *guide)
 Initialize the given connected line structure using the given guide for a set update operation.
void ast_party_dialed_copy (struct ast_party_dialed *dest, const struct ast_party_dialed *src)
 Copy the source dialed party information to the destination dialed party.
void ast_party_dialed_free (struct ast_party_dialed *doomed)
 Destroy the dialed party contents.
void ast_party_dialed_init (struct ast_party_dialed *init)
 Initialize the given dialed structure.
void ast_party_dialed_set (struct ast_party_dialed *dest, const struct ast_party_dialed *src)
 Set the dialed information based on another dialed source.
void ast_party_dialed_set_init (struct ast_party_dialed *init, const struct ast_party_dialed *guide)
 Initialize the given dialed structure using the given guide for a set update operation.
void ast_party_id_copy (struct ast_party_id *dest, const struct ast_party_id *src)
 Copy the source party id information to the destination party id.
void ast_party_id_free (struct ast_party_id *doomed)
 Destroy the party id contents.
void ast_party_id_init (struct ast_party_id *init)
 Initialize the given party id structure.
void ast_party_id_invalidate (struct ast_party_id *id)
 Invalidate all components of the given party id.
struct ast_party_id ast_party_id_merge (struct ast_party_id *base, struct ast_party_id *overlay)
 Merge a given party id into another given party id.
void ast_party_id_merge_copy (struct ast_party_id *dest, struct ast_party_id *base, struct ast_party_id *overlay)
 Copy a merge of a given party id into another given party id to a given destination party id.
int ast_party_id_presentation (const struct ast_party_id *id)
 Determine the overall presentation value for the given party.
void ast_party_id_reset (struct ast_party_id *id)
 Destroy and initialize the given party id structure.
void ast_party_id_set (struct ast_party_id *dest, const struct ast_party_id *src, const struct ast_set_party_id *update)
 Set the source party id information into the destination party id.
void ast_party_id_set_init (struct ast_party_id *init, const struct ast_party_id *guide)
 Initialize the given party id structure using the given guide for a set update operation.
void ast_party_name_copy (struct ast_party_name *dest, const struct ast_party_name *src)
 Copy the source party name information to the destination party name.
void ast_party_name_free (struct ast_party_name *doomed)
 Destroy the party name contents.
void ast_party_name_init (struct ast_party_name *init)
 Initialize the given name structure.
void ast_party_name_set (struct ast_party_name *dest, const struct ast_party_name *src)
 Set the source party name information into the destination party name.
void ast_party_name_set_init (struct ast_party_name *init, const struct ast_party_name *guide)
 Initialize the given party name structure using the given guide for a set update operation.
void ast_party_number_copy (struct ast_party_number *dest, const struct ast_party_number *src)
 Copy the source party number information to the destination party number.
void ast_party_number_free (struct ast_party_number *doomed)
 Destroy the party number contents.
void ast_party_number_init (struct ast_party_number *init)
 Initialize the given number structure.
void ast_party_number_set (struct ast_party_number *dest, const struct ast_party_number *src)
 Set the source party number information into the destination party number.
void ast_party_number_set_init (struct ast_party_number *init, const struct ast_party_number *guide)
 Initialize the given party number structure using the given guide for a set update operation.
void ast_party_redirecting_copy (struct ast_party_redirecting *dest, const struct ast_party_redirecting *src)
 Copy the source redirecting information to the destination redirecting.
void ast_party_redirecting_free (struct ast_party_redirecting *doomed)
 Destroy the redirecting information contents.
void ast_party_redirecting_init (struct ast_party_redirecting *init)
 Initialize the given redirecting structure.
void ast_party_redirecting_reason_copy (struct ast_party_redirecting_reason *dest, const struct ast_party_redirecting_reason *src)
 Copy the source redirecting reason information to the destination redirecting reason.
void ast_party_redirecting_reason_free (struct ast_party_redirecting_reason *doomed)
 Destroy the redirecting reason contents.
void ast_party_redirecting_reason_init (struct ast_party_redirecting_reason *init)
 Initialize the given redirecting reason structure.
void ast_party_redirecting_reason_set (struct ast_party_redirecting_reason *dest, const struct ast_party_redirecting_reason *src)
 Set the redirecting reason information based on another redirecting reason source.
void ast_party_redirecting_reason_set_init (struct ast_party_redirecting_reason *init, const struct ast_party_redirecting_reason *guide)
 Initialize the given redirecting reason structure using the given guide for a set update operation.
void ast_party_redirecting_set (struct ast_party_redirecting *dest, const struct ast_party_redirecting *src, const struct ast_set_party_redirecting *update)
 Set the redirecting information based on another redirecting source.
void ast_party_redirecting_set_init (struct ast_party_redirecting *init, const struct ast_party_redirecting *guide)
 Initialize the given redirecting id structure using the given guide for a set update operation.
void ast_party_subaddress_copy (struct ast_party_subaddress *dest, const struct ast_party_subaddress *src)
 Copy the source party subaddress information to the destination party subaddress.
void ast_party_subaddress_free (struct ast_party_subaddress *doomed)
 Destroy the party subaddress contents.
void ast_party_subaddress_init (struct ast_party_subaddress *init)
 Initialize the given subaddress structure.
void ast_party_subaddress_set (struct ast_party_subaddress *dest, const struct ast_party_subaddress *src)
 Set the source party subaddress information into the destination party subaddress.
void ast_party_subaddress_set_init (struct ast_party_subaddress *init, const struct ast_party_subaddress *guide)
 Initialize the given party subaddress structure using the given guide for a set update operation.
int ast_plc_reload (void)
 Reload genericplc configuration value from codecs.conf.
void ast_poll_channel_add (struct ast_channel *chan0, struct ast_channel *chan1)
void ast_poll_channel_del (struct ast_channel *chan0, struct ast_channel *chan1)
int ast_pre_call (struct ast_channel *chan, const char *sub_args)
 Execute a Gosub call on the channel before a call is placed.
char * ast_print_group (char *buf, int buflen, ast_group_t group)
 Print call group and pickup group ---.
char * ast_print_namedgroups (struct ast_str **buf, struct ast_namedgroups *group)
 Print named call groups and named pickup groups.
int ast_prod (struct ast_channel *chan)
 Send empty audio to prime a channel driver.
int ast_queue_control (struct ast_channel *chan, enum ast_control_frame_type control)
 Queue a control frame.
int ast_queue_control_data (struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
 Queue a control frame with payload.
int ast_queue_frame (struct ast_channel *chan, struct ast_frame *fin)
 Queue one or more frames to a channel's frame queue.
int ast_queue_frame_head (struct ast_channel *chan, struct ast_frame *fin)
 Queue one or more frames to the head of a channel's frame queue.
int ast_queue_hangup (struct ast_channel *chan)
 Queue a hangup frame for channel.
int ast_queue_hangup_with_cause (struct ast_channel *chan, int cause)
 Queue a hangup frame for channel.
int ast_queue_hold (struct ast_channel *chan, const char *musicclass)
 Queue a hold frame.
int ast_queue_unhold (struct ast_channel *chan)
 Queue an unhold frame.
int ast_raw_answer (struct ast_channel *chan)
 Answer a channel.
struct ast_frameast_read (struct ast_channel *chan)
 Reads a frame.
static void ast_read_generator_actions (struct ast_channel *chan, struct ast_frame *f)
struct ast_frameast_read_noaudio (struct ast_channel *chan)
 Reads a frame, returning AST_FRAME_NULL frame if audio.
int ast_readstring (struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders)
 Reads multiple digits.
int ast_readstring_full (struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders, int audiofd, int ctrlfd)
int ast_recvchar (struct ast_channel *chan, int timeout)
 Receives a text character from a channel.
char * ast_recvtext (struct ast_channel *chan, int timeout)
 Receives a text string from a channel Read a string of text from a channel.
int ast_redirecting_build_data (unsigned char *data, size_t datalen, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
 Build the redirecting id data frame.
int ast_redirecting_parse_data (const unsigned char *data, size_t datalen, struct ast_party_redirecting *redirecting)
 Parse redirecting indication frame data.
struct ast_namedgroups * ast_ref_namedgroups (struct ast_namedgroups *groups)
struct ast_channelast_request (const char *type, struct ast_format_cap *request_cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int *cause)
 Requests a channel.
struct ast_channelast_request_and_dial (const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int timeout, int *outstate, const char *cidnum, const char *cidname)
 Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it.
int ast_safe_sleep (struct ast_channel *chan, int ms)
 Wait, look for hangups.
int ast_safe_sleep_conditional (struct ast_channel *chan, int timeout_ms, int(*cond)(void *), void *data)
 Wait, look for hangups and condition arg.
int ast_say_character_str (struct ast_channel *chan, const char *str, const char *ints, const char *lang, enum ast_say_case_sensitivity sensitivity)
 function to pronounce character and phonetic strings
int ast_say_digit_str (struct ast_channel *chan, const char *str, const char *ints, const char *lang)
 says digits of a string
int ast_say_digits (struct ast_channel *chan, int num, const char *ints, const char *lang)
 says digits
int ast_say_digits_full (struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
 Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable.
int ast_say_enumeration (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options)
 says an enumeration
int ast_say_number (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options)
 says a number
int ast_say_phonetic_str (struct ast_channel *chan, const char *str, const char *ints, const char *lang)
int ast_senddigit (struct ast_channel *chan, char digit, unsigned int duration)
 Send a DTMF digit to a channel.
int ast_senddigit_begin (struct ast_channel *chan, char digit)
 Send a DTMF digit to a channel.
int ast_senddigit_end (struct ast_channel *chan, char digit, unsigned int duration)
 Send a DTMF digit to a channel.
int ast_sendtext (struct ast_channel *chan, const char *text)
 Sends text to a channel.
void ast_set_callerid (struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani)
 Set caller ID number, name and ANI and generate AMI event.
void ast_set_hangupsource (struct ast_channel *chan, const char *source, int force)
 Set the source of the hangup in this channel and it's bridge.
void ast_set_party_id_all (struct ast_set_party_id *update_id)
 Set the update marker to update all information of a corresponding party id.
int ast_set_read_format (struct ast_channel *chan, struct ast_format *format)
 Sets read format on channel chan.
int ast_set_read_format_from_cap (struct ast_channel *chan, struct ast_format_cap *cap)
 Sets read format on channel chan from capabilities Set read format for channel to whichever component of "format" is best.
int ast_set_read_format_path (struct ast_channel *chan, struct ast_format *raw_format, struct ast_format *core_format)
 Set specific read path on channel.
void ast_set_variables (struct ast_channel *chan, struct ast_variable *vars)
 adds a list of channel variables to a channel
int ast_set_write_format (struct ast_channel *chan, struct ast_format *format)
 Sets write format on channel chan.
int ast_set_write_format_from_cap (struct ast_channel *chan, struct ast_format_cap *cap)
 Sets write format on channel chan Set write format for channel to whichever component of "format" is best.
int ast_setstate (struct ast_channel *chan, enum ast_channel_state state)
 Change the state of a channel.
int ast_settimeout (struct ast_channel *c, unsigned int rate, int(*func)(const void *data), void *data)
 Enable or disable timer ticks for a channel.
int ast_settimeout_full (struct ast_channel *c, unsigned int rate, int(*func)(const void *data), void *data, unsigned int is_ao2_obj)
int ast_softhangup (struct ast_channel *chan, int cause)
 Softly hangup a channel, lock.
void ast_softhangup_all (void)
 Soft hangup all active channels.
int ast_softhangup_nolock (struct ast_channel *chan, int cause)
 Softly hangup a channel, don't lock.
const char * ast_state2str (enum ast_channel_state state)
 Gives the string form of a given channel state.
int ast_str2cause (const char *name)
 Convert a symbolic hangup cause to number.
int ast_tonepair (struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
int ast_tonepair_start (struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
void ast_tonepair_stop (struct ast_channel *chan)
int ast_transfer (struct ast_channel *chan, char *dest)
 Transfer a call to dest, if the channel supports transfer.
char * ast_transfercapability2str (int transfercapability)
 Gives the string form of a given transfer capability.
int ast_undestroyed_channels (void)
void ast_uninstall_music_functions (void)
struct ast_namedgroups * ast_unref_namedgroups (struct ast_namedgroups *groups)
int ast_waitfor (struct ast_channel *c, int ms)
 Wait for input on a channel.
struct ast_channelast_waitfor_n (struct ast_channel **c, int n, int *ms)
 Waits for input on a group of channels Wait for input on an array of channels for a given # of milliseconds.
int ast_waitfor_n_fd (int *fds, int n, int *ms, int *exception)
 Wait for x amount of time on a file descriptor to have input.
struct ast_channelast_waitfor_nandfds (struct ast_channel **c, int n, int *fds, int nfds, int *exception, int *outfd, int *ms)
 Wait for x amount of time on a file descriptor to have input.
int ast_waitfordigit (struct ast_channel *c, int ms)
 Waits for a digit.
int ast_waitfordigit_full (struct ast_channel *c, int timeout_ms, int audiofd, int cmdfd)
 Wait for a digit Same as ast_waitfordigit() with audio fd for outputting read audio and ctrlfd to monitor for reading.
int ast_write (struct ast_channel *chan, struct ast_frame *fr)
 Write a frame to a channel This function writes the given frame to the indicated channel.
int ast_write_video (struct ast_channel *chan, struct ast_frame *fr)
 Write video frame to a channel This function writes the given frame to the indicated channel.
static int calc_monitor_jump (int samples, int sample_rate, int seek_rate)
 calculates the number of samples to jump forward with in a monitor stream.
static void call_forward_inherit (struct ast_channel *new_chan, struct ast_channel *parent, struct ast_channel *orig)
static void * channel_cc_params_copy (void *data)
static void channel_cc_params_destroy (void *data)
static void channel_do_masquerade (struct ast_channel *original, struct ast_channel *clonechan)
 Masquerade a channel.
static int channel_feature_hooks_set_full (struct ast_channel *chan, struct ast_bridge_features *features, int replace)
static void channel_req_accountcodes (struct ast_channel *chan, const struct ast_channel *requestor, enum ast_channel_requestor_relationship relationship, int precious)
const char * channelreloadreason2txt (enum channelreloadreason reason)
 Convert enum channelreloadreason to text string for manager event.
static void channels_shutdown (void)
static void clone_variables (struct ast_channel *original, struct ast_channel *clonechan)
 Clone channel variables from 'clone' channel into 'original' channel.
static char * complete_channeltypes (struct ast_cli_args *a)
static struct stasis_messagecreate_channel_snapshot_message (struct ast_channel *channel)
static int data_channels_provider_handler (const struct ast_data_search *search, struct ast_data *root)
static int data_channeltypes_provider_handler (const struct ast_data_search *search, struct ast_data *data_root)
static void deactivate_generator_nolock (struct ast_channel *chan)
static int deactivate_silence_generator (struct ast_channel *chan)
static void destroy_hooks (struct ast_channel *chan)
static const char * dtmf_direction_to_string (enum DtmfDirection direction)
static void features_destroy (void *obj)
static void free_channelvars (void)
static void free_translation (struct ast_channel *clonechan)
static int generator_force (const void *data)
static void generator_write_format_change (struct ast_channel *chan)
static void handle_cause (int cause, int *outstate)
static char * handle_cli_core_show_channeltype (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show details about a channel driver - CLI command.
static char * handle_cli_core_show_channeltypes (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show channel types - CLI command.
static int indicate_connected_line (struct ast_channel *chan, const void *data, size_t datalen)
static int indicate_redirecting (struct ast_channel *chan, const void *data, size_t datalen)
static int attribute_const is_visible_indication (enum ast_control_frame_type condition)
static struct ast_framekill_exception (struct ast_channel *chan)
static int kill_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
static int kill_hangup (struct ast_channel *chan)
static struct ast_framekill_read (struct ast_channel *chan)
static int kill_write (struct ast_channel *chan, struct ast_frame *frame)
static int namedgroup_cmp_cb (void *obj, void *arg, int flags)
 Comparison function used for named group container.
static int namedgroup_hash_cb (const void *obj, const int flags)
 Hashing function used for named group container.
static int namedgroup_match (void *obj, void *arg, int flags)
static int party_id_build_data (unsigned char *data, size_t datalen, const struct ast_party_id *id, const char *label, const struct ast_party_id_ies *ies, const struct ast_set_party_id *update)
static int party_name_build_data (unsigned char *data, size_t datalen, const struct ast_party_name *name, const char *label, const struct ast_party_name_ies *ies)
static int party_number_build_data (unsigned char *data, size_t datalen, const struct ast_party_number *number, const char *label, const struct ast_party_number_ies *ies)
static int party_subaddress_build_data (unsigned char *data, size_t datalen, const struct ast_party_subaddress *subaddress, const char *label, const struct ast_party_subaddress_ies *ies)
static void plc_ds_destroy (void *data)
static void prnt_channel_key (void *v_obj, void *where, ao2_prnt_fn *prnt)
static void publish_cache_clear (struct ast_channel *chan)
static void queue_dtmf_readq (struct ast_channel *chan, struct ast_frame *f)
static int redirecting_reason_build_data (unsigned char *data, size_t datalen, const struct ast_party_redirecting_reason *reason, const char *label, const struct ast_party_redirecting_reason_ies *ies)
static void send_dtmf_begin_event (struct ast_channel *chan, enum DtmfDirection direction, const char digit)
static void send_dtmf_end_event (struct ast_channel *chan, enum DtmfDirection direction, const char digit, long duration_ms)
static int set_format (struct ast_channel *chan, struct ast_format_cap *cap_set, const int direction)
static int set_security_requirements (const struct ast_channel *requestor, struct ast_channel *out)
static int should_skip_dtmf (struct ast_channel *chan)
 Determine whether or not we should ignore DTMF in the readq.
static void * silence_generator_alloc (struct ast_channel *chan, void *data)
static int silence_generator_generate (struct ast_channel *chan, void *data, int len, int samples)
static void silence_generator_release (struct ast_channel *chan, void *data)
static void suppress_datastore_destroy_cb (void *data)
static void suppress_framehook_destroy_cb (void *data)
static struct ast_framesuppress_framehook_event_cb (struct ast_channel *chan, struct ast_frame *frame, enum ast_framehook_event event, void *data)
static void suppress_framehook_fixup_cb (void *data, int framehook_id, struct ast_channel *old_chan, struct ast_channel *new_chan)
static struct ast_datastore_infosuppress_get_datastore_information (enum ast_frame_type frametype)
static void * tonepair_alloc (struct ast_channel *chan, void *params)
static int tonepair_generator (struct ast_channel *chan, void *data, int len, int samples)
static void tonepair_release (struct ast_channel *chan, void *params)
static void varshead_dtor (void *obj)
 Destructor for lists of variables.

Variables

struct ast_channel_tech ast_kill_tech
 Kill the channel channel driver technology descriptor.
static void(* ast_moh_cleanup_ptr )(struct ast_channel *) = NULL
static int(* ast_moh_start_ptr )(struct ast_channel *, const char *, const char *) = NULL
static void(* ast_moh_stop_ptr )(struct ast_channel *) = NULL
static struct ast_datastore_info bridge_features_info
static struct causes_map causes []
static struct ast_datastore_info cc_channel_datastore_info
static int chancount
static ast_mutex_t channel_move_lock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 }
static struct ast_data_entry channel_providers []
static struct ao2_containerchannels
 All active channels on the system.
static struct ast_data_handler channels_provider
static struct ast_data_handler channeltypes_provider
static struct ast_cli_entry cli_channel []
unsigned long global_fin
unsigned long global_fout
static struct ast_channel_tech null_tech
static struct ast_datastore_info plc_ds_info
static struct set_format_access set_format_access_read
static struct set_format_access set_format_access_write
static struct ast_generator silence_generator
static struct ast_threadstorage state2str_threadbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_state2str_threadbuf , .custom_init = NULL , }
static struct ast_datastore_info suppress_datastore_voice
static struct ast_channel_tech surrogate_tech
 Channel technology used to extract a channel from a running application. The channel created with this technology will be immediately hung up - most external applications won't ever want to see this.
static struct ast_generator tonepair


Detailed Description

Channel Management.

Author:
Mark Spencer <markster@digium.com>

Definition in file channel.c.


Define Documentation

#define AST_DEFAULT_EMULATE_DTMF_DURATION   100

Default amount of time to use when emulating a digit as a begin and end 100ms

Definition at line 112 of file channel.c.

Referenced by __ast_read(), and ast_senddigit().

#define AST_MIN_DTMF_GAP   45

Minimum amount of time between the end of the last digit and the beginning of a new one - 45ms

Definition at line 118 of file channel.c.

Referenced by __ast_read(), and should_skip_dtmf().

#define DEFAULT_AMA_FLAGS   AST_AMA_DOCUMENTATION

Definition at line 114 of file channel.c.

Referenced by __ast_channel_alloc_ap(), and ast_channel_string2amaflag().

#define FORMAT   "%-15.15s %-40.40s %-13.13s %-13.13s %-13.13s %-13.13s\n"

#define NUM_CHANNEL_BUCKETS   1567

Definition at line 132 of file channel.c.

Referenced by ast_channels_init().

#define STATE2STR_BUFSIZE   32

Definition at line 108 of file channel.c.

Referenced by ast_state2str().


Enumeration Type Documentation

anonymous enum

Element identifiers for connected line indication frame data.

Note:
Only add to the end of this enum.
Enumerator:
AST_CONNECTED_LINE_NUMBER 
AST_CONNECTED_LINE_NAME 
AST_CONNECTED_LINE_NUMBER_PLAN 
AST_CONNECTED_LINE_ID_PRESENTATION 
AST_CONNECTED_LINE_SOURCE 
AST_CONNECTED_LINE_SUBADDRESS 
AST_CONNECTED_LINE_SUBADDRESS_TYPE 
AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN 
AST_CONNECTED_LINE_SUBADDRESS_VALID 
AST_CONNECTED_LINE_TAG 
AST_CONNECTED_LINE_VERSION 
AST_CONNECTED_LINE_NAME_VALID 
AST_CONNECTED_LINE_NAME_CHAR_SET 
AST_CONNECTED_LINE_NAME_PRESENTATION 
AST_CONNECTED_LINE_NUMBER_VALID 
AST_CONNECTED_LINE_NUMBER_PRESENTATION 
AST_CONNECTED_LINE_PRIV_NUMBER 
AST_CONNECTED_LINE_PRIV_NUMBER_PLAN 
AST_CONNECTED_LINE_PRIV_NUMBER_VALID 
AST_CONNECTED_LINE_PRIV_NUMBER_PRESENTATION 
AST_CONNECTED_LINE_PRIV_NAME 
AST_CONNECTED_LINE_PRIV_NAME_VALID 
AST_CONNECTED_LINE_PRIV_NAME_CHAR_SET 
AST_CONNECTED_LINE_PRIV_NAME_PRESENTATION 
AST_CONNECTED_LINE_PRIV_SUBADDRESS 
AST_CONNECTED_LINE_PRIV_SUBADDRESS_TYPE 
AST_CONNECTED_LINE_PRIV_SUBADDRESS_ODD_EVEN 
AST_CONNECTED_LINE_PRIV_SUBADDRESS_VALID 
AST_CONNECTED_LINE_PRIV_TAG 

Definition at line 8398 of file channel.c.

anonymous enum

Element identifiers for redirecting indication frame data.

Note:
Only add to the end of this enum.
Enumerator:
AST_REDIRECTING_FROM_NUMBER 
AST_REDIRECTING_FROM_NAME 
AST_REDIRECTING_FROM_NUMBER_PLAN 
AST_REDIRECTING_FROM_ID_PRESENTATION 
AST_REDIRECTING_TO_NUMBER 
AST_REDIRECTING_TO_NAME 
AST_REDIRECTING_TO_NUMBER_PLAN 
AST_REDIRECTING_TO_ID_PRESENTATION 
AST_REDIRECTING_REASON_CODE 
AST_REDIRECTING_COUNT 
AST_REDIRECTING_FROM_SUBADDRESS 
AST_REDIRECTING_FROM_SUBADDRESS_TYPE 
AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN 
AST_REDIRECTING_FROM_SUBADDRESS_VALID 
AST_REDIRECTING_TO_SUBADDRESS 
AST_REDIRECTING_TO_SUBADDRESS_TYPE 
AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN 
AST_REDIRECTING_TO_SUBADDRESS_VALID 
AST_REDIRECTING_FROM_TAG 
AST_REDIRECTING_TO_TAG 
AST_REDIRECTING_VERSION 
AST_REDIRECTING_FROM_NAME_VALID 
AST_REDIRECTING_FROM_NAME_CHAR_SET 
AST_REDIRECTING_FROM_NAME_PRESENTATION 
AST_REDIRECTING_FROM_NUMBER_VALID 
AST_REDIRECTING_FROM_NUMBER_PRESENTATION 
AST_REDIRECTING_TO_NAME_VALID 
AST_REDIRECTING_TO_NAME_CHAR_SET 
AST_REDIRECTING_TO_NAME_PRESENTATION 
AST_REDIRECTING_TO_NUMBER_VALID 
AST_REDIRECTING_TO_NUMBER_PRESENTATION 
AST_REDIRECTING_ORIG_NUMBER 
AST_REDIRECTING_ORIG_NUMBER_VALID 
AST_REDIRECTING_ORIG_NUMBER_PLAN 
AST_REDIRECTING_ORIG_NUMBER_PRESENTATION 
AST_REDIRECTING_ORIG_NAME 
AST_REDIRECTING_ORIG_NAME_VALID 
AST_REDIRECTING_ORIG_NAME_CHAR_SET 
AST_REDIRECTING_ORIG_NAME_PRESENTATION 
AST_REDIRECTING_ORIG_SUBADDRESS 
AST_REDIRECTING_ORIG_SUBADDRESS_TYPE 
AST_REDIRECTING_ORIG_SUBADDRESS_ODD_EVEN 
AST_REDIRECTING_ORIG_SUBADDRESS_VALID 
AST_REDIRECTING_ORIG_TAG 
AST_REDIRECTING_ORIG_REASON_CODE 
AST_REDIRECTING_PRIV_TO_NUMBER 
AST_REDIRECTING_PRIV_TO_NUMBER_PLAN 
AST_REDIRECTING_PRIV_TO_NUMBER_VALID 
AST_REDIRECTING_PRIV_TO_NUMBER_PRESENTATION 
AST_REDIRECTING_PRIV_TO_NAME 
AST_REDIRECTING_PRIV_TO_NAME_VALID 
AST_REDIRECTING_PRIV_TO_NAME_CHAR_SET 
AST_REDIRECTING_PRIV_TO_NAME_PRESENTATION 
AST_REDIRECTING_PRIV_TO_SUBADDRESS 
AST_REDIRECTING_PRIV_TO_SUBADDRESS_TYPE 
AST_REDIRECTING_PRIV_TO_SUBADDRESS_ODD_EVEN 
AST_REDIRECTING_PRIV_TO_SUBADDRESS_VALID 
AST_REDIRECTING_PRIV_TO_TAG 
AST_REDIRECTING_PRIV_FROM_NUMBER 
AST_REDIRECTING_PRIV_FROM_NUMBER_PLAN 
AST_REDIRECTING_PRIV_FROM_NUMBER_VALID 
AST_REDIRECTING_PRIV_FROM_NUMBER_PRESENTATION 
AST_REDIRECTING_PRIV_FROM_NAME 
AST_REDIRECTING_PRIV_FROM_NAME_VALID 
AST_REDIRECTING_PRIV_FROM_NAME_CHAR_SET 
AST_REDIRECTING_PRIV_FROM_NAME_PRESENTATION 
AST_REDIRECTING_PRIV_FROM_SUBADDRESS 
AST_REDIRECTING_PRIV_FROM_SUBADDRESS_TYPE 
AST_REDIRECTING_PRIV_FROM_SUBADDRESS_ODD_EVEN 
AST_REDIRECTING_PRIV_FROM_SUBADDRESS_VALID 
AST_REDIRECTING_PRIV_FROM_TAG 
AST_REDIRECTING_PRIV_ORIG_NUMBER 
AST_REDIRECTING_PRIV_ORIG_NUMBER_VALID 
AST_REDIRECTING_PRIV_ORIG_NUMBER_PLAN 
AST_REDIRECTING_PRIV_ORIG_NUMBER_PRESENTATION 
AST_REDIRECTING_PRIV_ORIG_NAME 
AST_REDIRECTING_PRIV_ORIG_NAME_VALID 
AST_REDIRECTING_PRIV_ORIG_NAME_CHAR_SET 
AST_REDIRECTING_PRIV_ORIG_NAME_PRESENTATION 
AST_REDIRECTING_PRIV_ORIG_SUBADDRESS 
AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_TYPE 
AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_ODD_EVEN 
AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_VALID 
AST_REDIRECTING_PRIV_ORIG_TAG 
AST_REDIRECTING_REASON_STR 
AST_REDIRECTING_ORIG_REASON_STR 

Definition at line 8872 of file channel.c.

08872      {
08873    AST_REDIRECTING_FROM_NUMBER,
08874    AST_REDIRECTING_FROM_NAME,
08875    AST_REDIRECTING_FROM_NUMBER_PLAN,
08876    AST_REDIRECTING_FROM_ID_PRESENTATION,/* Combined number and name presentation. */
08877    AST_REDIRECTING_TO_NUMBER,
08878    AST_REDIRECTING_TO_NAME,
08879    AST_REDIRECTING_TO_NUMBER_PLAN,
08880    AST_REDIRECTING_TO_ID_PRESENTATION,/* Combined number and name presentation. */
08881    AST_REDIRECTING_REASON_CODE,
08882    AST_REDIRECTING_COUNT,
08883    AST_REDIRECTING_FROM_SUBADDRESS,
08884    AST_REDIRECTING_FROM_SUBADDRESS_TYPE,
08885    AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN,
08886    AST_REDIRECTING_FROM_SUBADDRESS_VALID,
08887    AST_REDIRECTING_TO_SUBADDRESS,
08888    AST_REDIRECTING_TO_SUBADDRESS_TYPE,
08889    AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN,
08890    AST_REDIRECTING_TO_SUBADDRESS_VALID,
08891    AST_REDIRECTING_FROM_TAG,
08892    AST_REDIRECTING_TO_TAG,
08893    AST_REDIRECTING_VERSION,
08894    /*
08895     * No more party id combined number and name presentation values
08896     * need to be created.
08897     */
08898    AST_REDIRECTING_FROM_NAME_VALID,
08899    AST_REDIRECTING_FROM_NAME_CHAR_SET,
08900    AST_REDIRECTING_FROM_NAME_PRESENTATION,
08901    AST_REDIRECTING_FROM_NUMBER_VALID,
08902    AST_REDIRECTING_FROM_NUMBER_PRESENTATION,
08903    AST_REDIRECTING_TO_NAME_VALID,
08904    AST_REDIRECTING_TO_NAME_CHAR_SET,
08905    AST_REDIRECTING_TO_NAME_PRESENTATION,
08906    AST_REDIRECTING_TO_NUMBER_VALID,
08907    AST_REDIRECTING_TO_NUMBER_PRESENTATION,
08908    AST_REDIRECTING_ORIG_NUMBER,
08909    AST_REDIRECTING_ORIG_NUMBER_VALID,
08910    AST_REDIRECTING_ORIG_NUMBER_PLAN,
08911    AST_REDIRECTING_ORIG_NUMBER_PRESENTATION,
08912    AST_REDIRECTING_ORIG_NAME,
08913    AST_REDIRECTING_ORIG_NAME_VALID,
08914    AST_REDIRECTING_ORIG_NAME_CHAR_SET,
08915    AST_REDIRECTING_ORIG_NAME_PRESENTATION,
08916    AST_REDIRECTING_ORIG_SUBADDRESS,
08917    AST_REDIRECTING_ORIG_SUBADDRESS_TYPE,
08918    AST_REDIRECTING_ORIG_SUBADDRESS_ODD_EVEN,
08919    AST_REDIRECTING_ORIG_SUBADDRESS_VALID,
08920    AST_REDIRECTING_ORIG_TAG,
08921    AST_REDIRECTING_ORIG_REASON_CODE,
08922    AST_REDIRECTING_PRIV_TO_NUMBER,
08923    AST_REDIRECTING_PRIV_TO_NUMBER_PLAN,
08924    AST_REDIRECTING_PRIV_TO_NUMBER_VALID,
08925    AST_REDIRECTING_PRIV_TO_NUMBER_PRESENTATION,
08926    AST_REDIRECTING_PRIV_TO_NAME,
08927    AST_REDIRECTING_PRIV_TO_NAME_VALID,
08928    AST_REDIRECTING_PRIV_TO_NAME_CHAR_SET,
08929    AST_REDIRECTING_PRIV_TO_NAME_PRESENTATION,
08930    AST_REDIRECTING_PRIV_TO_SUBADDRESS,
08931    AST_REDIRECTING_PRIV_TO_SUBADDRESS_TYPE,
08932    AST_REDIRECTING_PRIV_TO_SUBADDRESS_ODD_EVEN,
08933    AST_REDIRECTING_PRIV_TO_SUBADDRESS_VALID,
08934    AST_REDIRECTING_PRIV_TO_TAG,
08935    AST_REDIRECTING_PRIV_FROM_NUMBER,
08936    AST_REDIRECTING_PRIV_FROM_NUMBER_PLAN,
08937    AST_REDIRECTING_PRIV_FROM_NUMBER_VALID,
08938    AST_REDIRECTING_PRIV_FROM_NUMBER_PRESENTATION,
08939    AST_REDIRECTING_PRIV_FROM_NAME,
08940    AST_REDIRECTING_PRIV_FROM_NAME_VALID,
08941    AST_REDIRECTING_PRIV_FROM_NAME_CHAR_SET,
08942    AST_REDIRECTING_PRIV_FROM_NAME_PRESENTATION,
08943    AST_REDIRECTING_PRIV_FROM_SUBADDRESS,
08944    AST_REDIRECTING_PRIV_FROM_SUBADDRESS_TYPE,
08945    AST_REDIRECTING_PRIV_FROM_SUBADDRESS_ODD_EVEN,
08946    AST_REDIRECTING_PRIV_FROM_SUBADDRESS_VALID,
08947    AST_REDIRECTING_PRIV_FROM_TAG,
08948    AST_REDIRECTING_PRIV_ORIG_NUMBER,
08949    AST_REDIRECTING_PRIV_ORIG_NUMBER_VALID,
08950    AST_REDIRECTING_PRIV_ORIG_NUMBER_PLAN,
08951    AST_REDIRECTING_PRIV_ORIG_NUMBER_PRESENTATION,
08952    AST_REDIRECTING_PRIV_ORIG_NAME,
08953    AST_REDIRECTING_PRIV_ORIG_NAME_VALID,
08954    AST_REDIRECTING_PRIV_ORIG_NAME_CHAR_SET,
08955    AST_REDIRECTING_PRIV_ORIG_NAME_PRESENTATION,
08956    AST_REDIRECTING_PRIV_ORIG_SUBADDRESS,
08957    AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_TYPE,
08958    AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_ODD_EVEN,
08959    AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_VALID,
08960    AST_REDIRECTING_PRIV_ORIG_TAG,
08961    AST_REDIRECTING_REASON_STR,
08962    AST_REDIRECTING_ORIG_REASON_STR,
08963 };

Enumerator:
DTMF_RECEIVED 
DTMF_SENT 

Definition at line 3540 of file channel.c.

03540                    {
03541    DTMF_RECEIVED,
03542    DTMF_SENT
03543 };


Function Documentation

int __ast_answer ( struct ast_channel chan,
unsigned int  delay 
)

Answer a channel, with a selectable delay before returning.

Parameters:
chan channel to answer
delay maximum amount of time to wait for incoming media
This function answers a channel and handles all necessary call setup functions.

Note:
The channel passed does not need to be locked, but is locked by the function when needed.

This function will wait up to 'delay' milliseconds for media to arrive on the channel before returning to the caller, so that the caller can properly assume the channel is 'ready' for media flow. If 'delay' is less than 500, the function will wait up to 500 milliseconds.

Return values:
0 on success
non-zero on failure

Definition at line 2739 of file channel.c.

References ast_channel_lock, ast_channel_name(), ast_channel_unlock, AST_CONTROL_HANGUP, ast_debug, AST_FRAME_BRIDGE_ACTION, AST_FRAME_BRIDGE_ACTION_SYNC, AST_FRAME_CNG, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_HTML, AST_FRAME_IAX, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_frisolate(), AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_HEAD_NOLOCK, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_HEAD, ast_log, ast_queue_frame_head(), ast_raw_answer(), ast_read(), ast_remaining_ms(), AST_STATE_RING, AST_STATE_RINGING, ast_tvnow(), ast_waitfor(), errno, frames, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, MAX, and ast_frame::subclass.

Referenced by ast_answer(), pbx_builtin_answer(), and pbx_builtin_incomplete().

02740 {
02741    int res = 0;
02742    enum ast_channel_state old_state;
02743 
02744    old_state = ast_channel_state(chan);
02745    if ((res = ast_raw_answer(chan))) {
02746       return res;
02747    }
02748 
02749    switch (old_state) {
02750    case AST_STATE_RINGING:
02751    case AST_STATE_RING:
02752       /* wait for media to start flowing, but don't wait any longer
02753        * than 'delay' or 500 milliseconds, whichever is longer
02754        */
02755       do {
02756          AST_LIST_HEAD_NOLOCK(, ast_frame) frames;
02757          struct ast_frame *cur;
02758          struct ast_frame *new_frame;
02759          int timeout_ms = MAX(delay, 500);
02760          unsigned int done = 0;
02761          struct timeval start;
02762 
02763          AST_LIST_HEAD_INIT_NOLOCK(&frames);
02764 
02765          start = ast_tvnow();
02766          for (;;) {
02767             int ms = ast_remaining_ms(start, timeout_ms);
02768             ms = ast_waitfor(chan, ms);
02769             if (ms < 0) {
02770                ast_log(LOG_WARNING, "Error condition occurred when polling channel %s for a voice frame: %s\n", ast_channel_name(chan), strerror(errno));
02771                res = -1;
02772                break;
02773             }
02774             if (ms == 0) {
02775                ast_debug(2, "Didn't receive a media frame from %s within %u ms of answering. Continuing anyway\n", ast_channel_name(chan), MAX(delay, 500));
02776                break;
02777             }
02778             cur = ast_read(chan);
02779             if (!cur || ((cur->frametype == AST_FRAME_CONTROL) &&
02780                     (cur->subclass.integer == AST_CONTROL_HANGUP))) {
02781                if (cur) {
02782                   ast_frfree(cur);
02783                }
02784                res = -1;
02785                ast_debug(2, "Hangup of channel %s detected in answer routine\n", ast_channel_name(chan));
02786                break;
02787             }
02788 
02789             if ((new_frame = ast_frisolate(cur)) != cur) {
02790                ast_frfree(cur);
02791             }
02792 
02793             AST_LIST_INSERT_HEAD(&frames, new_frame, frame_list);
02794 
02795             /* if a specific delay period was requested, continue
02796              * until that delay has passed. don't stop just because
02797              * incoming media has arrived.
02798              */
02799             if (delay) {
02800                continue;
02801             }
02802 
02803             switch (new_frame->frametype) {
02804                /* all of these frametypes qualify as 'media' */
02805             case AST_FRAME_VOICE:
02806             case AST_FRAME_VIDEO:
02807             case AST_FRAME_TEXT:
02808             case AST_FRAME_DTMF_BEGIN:
02809             case AST_FRAME_DTMF_END:
02810             case AST_FRAME_IMAGE:
02811             case AST_FRAME_HTML:
02812             case AST_FRAME_MODEM:
02813                done = 1;
02814                break;
02815             case AST_FRAME_CONTROL:
02816             case AST_FRAME_IAX:
02817             case AST_FRAME_BRIDGE_ACTION:
02818             case AST_FRAME_BRIDGE_ACTION_SYNC:
02819             case AST_FRAME_NULL:
02820             case AST_FRAME_CNG:
02821                break;
02822             }
02823 
02824             if (done) {
02825                break;
02826             }
02827          }
02828 
02829          ast_channel_lock(chan);
02830          while ((cur = AST_LIST_REMOVE_HEAD(&frames, frame_list))) {
02831             if (res == 0) {
02832                ast_queue_frame_head(chan, cur);
02833             }
02834             ast_frfree(cur);
02835          }
02836          ast_channel_unlock(chan);
02837       } while (0);
02838       break;
02839    default:
02840       break;
02841    }
02842 
02843    return res;
02844 }

static void __ast_change_name_nolink ( struct ast_channel chan,
const char *  newname 
) [static]

this function simply changes the name of the channel and issues a manager_event with out unlinking and linking the channel from the ao2_container. This should only be used when the channel has already been unlinked from the ao2_container.

Definition at line 6398 of file channel.c.

References ast_channel_name(), ast_channel_name_set(), ast_channel_uniqueid(), ast_manager_event, and EVENT_FLAG_CALL.

Referenced by ast_change_name().

06399 {
06400    /*** DOCUMENTATION
06401       <managerEventInstance>
06402          <synopsis>Raised when the name of a channel is changed.</synopsis>
06403       </managerEventInstance>
06404    ***/
06405    ast_manager_event(chan, EVENT_FLAG_CALL, "Rename",
06406       "Channel: %s\r\n"
06407       "Newname: %s\r\n"
06408       "Uniqueid: %s\r\n",
06409       ast_channel_name(chan), newname, ast_channel_uniqueid(chan));
06410    ast_channel_name_set(chan, newname);
06411 }

struct ast_channel* __ast_channel_alloc ( int  needqueue,
int  state,
const char *  cid_num,
const char *  cid_name,
const char *  acctcode,
const char *  exten,
const char *  context,
const struct ast_assigned_ids assignedids,
const struct ast_channel requestor,
enum ama_flags  amaflag,
struct ast_endpoint endpoint,
const char *  file,
int  line,
const char *  function,
const char *  name_fmt,
  ... 
) [read]

Create a channel structure.

Since:
1.8
Return values:
NULL failure
non-NULL successfully allocated channel
Note:
Absolutely _NO_ channel locks should be held before calling this function.

By default, new channels are set to the "s" extension and "default" context.

Since 12.0.0 this function returns with the newly created channel locked.

Definition at line 968 of file channel.c.

References __ast_channel_alloc_ap(), and result.

00975 {
00976    va_list ap;
00977    struct ast_channel *result;
00978 
00979    va_start(ap, name_fmt);
00980    result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context,
00981                assignedids, requestor, amaflag, endpoint, file, line, function, name_fmt, ap);
00982    va_end(ap);
00983 
00984    return result;
00985 }

static struct ast_channel* attribute_malloc __ast_channel_alloc_ap ( int  needqueue,
int  state,
const char *  cid_num,
const char *  cid_name,
const char *  acctcode,
const char *  exten,
const char *  context,
const struct ast_assigned_ids assignedids,
const struct ast_channel requestor,
enum ama_flags  amaflag,
struct ast_endpoint endpoint,
const char *  file,
int  line,
const char *  function,
const char *  name_fmt,
va_list  ap 
) [static, read]

Create a new channel structure.

Definition at line 776 of file channel.c.

References ao2_link, ao2_ref, AST_ALERT_FD, AST_AMA_NONE, ast_atomic_fetchadd_int(), ast_channel_amaflags_set(), ast_channel_autochans(), ast_channel_caller(), ast_channel_connected(), ast_channel_connected_indicated(), ast_channel_context_set(), ast_channel_creationtime_set(), ast_channel_datastores(), ast_channel_destructor(), ast_channel_dialed(), ast_channel_epfd_set(), ast_channel_exten_set(), ast_channel_fin_set(), ast_channel_fout_set(), ast_channel_hold_state_set(), ast_channel_internal_alert_readfd(), ast_channel_internal_alertpipe_clear(), ast_channel_internal_alertpipe_init(), ast_channel_internal_alloc, ast_channel_internal_fd_clear_all(), ast_channel_internal_finalize(), ast_channel_internal_setup_topics(), ast_channel_lock, ast_channel_name(), ast_channel_name_set(), ast_channel_nativeformats_set(), ast_channel_priority_set(), ast_channel_redirecting(), ast_channel_sched_set(), ast_channel_set_fd(), ast_channel_set_rawreadformat(), ast_channel_set_rawwriteformat(), ast_channel_set_readformat(), ast_channel_set_writeformat(), ast_channel_stage_snapshot(), ast_channel_stage_snapshot_done(), ast_channel_state_set(), ast_channel_streamid_set(), ast_channel_tech_set(), ast_channel_timer(), ast_channel_timer_set(), ast_channel_timingfd(), ast_channel_timingfd_set(), ast_channel_unref, ast_channel_varshead(), AST_CONTROL_UNHOLD, ast_defaultlanguage, ast_endpoint_add_channel(), ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_none, ast_get_channel_tech(), AST_LIST_HEAD_INIT_NOLOCK, ast_log, ast_party_caller_init(), ast_party_connected_line_init(), ast_party_dialed_init(), ast_party_redirecting_init(), ast_pbx_hangup_handler_init(), ast_sched_context_create(), ast_shutting_down(), ast_strdup, ast_strdupa, ast_strlen_zero, ast_timer_fd(), ast_timer_get_name(), ast_timer_open(), AST_TIMING_FD, ast_tvnow(), channels, DEFAULT_AMA_FLAGS, ast_party_caller::id, LOG_WARNING, name, ast_party_id::name, NULL, null_tech, ast_party_id::number, S_OR, ast_party_number::str, ast_party_name::str, chanlist::tech, timer, tmp(), ast_party_number::valid, and ast_party_name::valid.

Referenced by __ast_channel_alloc().

00781 {
00782    struct ast_channel *tmp;
00783    struct varshead *headp;
00784    char *tech = "", *tech2 = NULL;
00785    struct ast_format_cap *nativeformats;
00786    struct ast_sched_context *schedctx;
00787    struct ast_timer *timer;
00788    struct timeval now;
00789    const struct ast_channel_tech *channel_tech;
00790 
00791    /* If shutting down, don't allocate any new channels */
00792    if (ast_shutting_down()) {
00793       ast_log(LOG_WARNING, "Channel allocation failed: Refusing due to active shutdown\n");
00794       return NULL;
00795    }
00796 
00797    if (!(tmp = ast_channel_internal_alloc(ast_channel_destructor, assignedids, requestor))) {
00798       /* Channel structure allocation failure. */
00799       return NULL;
00800    }
00801 
00802    ast_channel_stage_snapshot(tmp);
00803 
00804    if (!(nativeformats = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
00805       /* format capabilities structure allocation failure */
00806       return ast_channel_unref(tmp);
00807    }
00808    ast_format_cap_append(nativeformats, ast_format_none, 0);
00809    ast_channel_nativeformats_set(tmp, nativeformats);
00810    ao2_ref(nativeformats, -1);
00811 
00812    ast_channel_set_rawwriteformat(tmp, ast_format_none);
00813    ast_channel_set_rawreadformat(tmp, ast_format_none);
00814    ast_channel_set_writeformat(tmp, ast_format_none);
00815    ast_channel_set_readformat(tmp, ast_format_none);
00816 
00817    /*
00818     * Init file descriptors to unopened state so
00819     * the destructor can know not to close them.
00820     */
00821    ast_channel_timingfd_set(tmp, -1);
00822    ast_channel_internal_alertpipe_clear(tmp);
00823    ast_channel_internal_fd_clear_all(tmp);
00824 
00825 #ifdef HAVE_EPOLL
00826    ast_channel_epfd_set(tmp, epoll_create(25));
00827 #endif
00828 
00829    if (!(schedctx = ast_sched_context_create())) {
00830       ast_log(LOG_WARNING, "Channel allocation failed: Unable to create schedule context\n");
00831       return ast_channel_unref(tmp);
00832    }
00833    ast_channel_sched_set(tmp, schedctx);
00834 
00835    ast_party_dialed_init(ast_channel_dialed(tmp));
00836    ast_party_caller_init(ast_channel_caller(tmp));
00837    ast_party_connected_line_init(ast_channel_connected(tmp));
00838    ast_party_connected_line_init(ast_channel_connected_indicated(tmp));
00839    ast_party_redirecting_init(ast_channel_redirecting(tmp));
00840 
00841    if (cid_name) {
00842       ast_channel_caller(tmp)->id.name.valid = 1;
00843       ast_channel_caller(tmp)->id.name.str = ast_strdup(cid_name);
00844       if (!ast_channel_caller(tmp)->id.name.str) {
00845          return ast_channel_unref(tmp);
00846       }
00847    }
00848    if (cid_num) {
00849       ast_channel_caller(tmp)->id.number.valid = 1;
00850       ast_channel_caller(tmp)->id.number.str = ast_strdup(cid_num);
00851       if (!ast_channel_caller(tmp)->id.number.str) {
00852          return ast_channel_unref(tmp);
00853       }
00854    }
00855 
00856    if ((timer = ast_timer_open())) {
00857       ast_channel_timer_set(tmp, timer);
00858       if (strcmp(ast_timer_get_name(ast_channel_timer(tmp)), "timerfd")) {
00859          needqueue = 0;
00860       }
00861       ast_channel_timingfd_set(tmp, ast_timer_fd(ast_channel_timer(tmp)));
00862    }
00863 
00864    if (needqueue && ast_channel_internal_alertpipe_init(tmp)) {
00865       return ast_channel_unref(tmp);
00866    }
00867 
00868    /* Always watch the alertpipe */
00869    ast_channel_set_fd(tmp, AST_ALERT_FD, ast_channel_internal_alert_readfd(tmp));
00870    /* And timing pipe */
00871    ast_channel_set_fd(tmp, AST_TIMING_FD, ast_channel_timingfd(tmp));
00872 
00873    /* Initial state */
00874    ast_channel_state_set(tmp, state);
00875    ast_channel_hold_state_set(tmp, AST_CONTROL_UNHOLD);
00876 
00877    ast_channel_streamid_set(tmp, -1);
00878 
00879    ast_channel_fin_set(tmp, global_fin);
00880    ast_channel_fout_set(tmp, global_fout);
00881 
00882    now = ast_tvnow();
00883    ast_channel_creationtime_set(tmp, &now);
00884 
00885    ast_channel_internal_setup_topics(tmp);
00886 
00887    if (!ast_strlen_zero(name_fmt)) {
00888       char *slash, *slash2;
00889       /* Almost every channel is calling this function, and setting the name via the ast_string_field_build() call.
00890        * And they all use slightly different formats for their name string.
00891        * This means, to set the name here, we have to accept variable args, and call the string_field_build from here.
00892        * This means, that the stringfields must have a routine that takes the va_lists directly, and
00893        * uses them to build the string, instead of forming the va_lists internally from the vararg ... list.
00894        * This new function was written so this can be accomplished.
00895        */
00896       ast_channel_name_build_va(tmp, name_fmt, ap);
00897       tech = ast_strdupa(ast_channel_name(tmp));
00898       if ((slash = strchr(tech, '/'))) {
00899          if ((slash2 = strchr(slash + 1, '/'))) {
00900             tech2 = slash + 1;
00901             *slash2 = '\0';
00902          }
00903          *slash = '\0';
00904       }
00905    } else {
00906       /*
00907        * Start the string with '-' so it becomes an empty string
00908        * in the destructor.
00909        */
00910       ast_channel_name_set(tmp, "-**Unknown**");
00911    }
00912 
00913    if (amaflag != AST_AMA_NONE) {
00914       ast_channel_amaflags_set(tmp, amaflag);
00915    } else {
00916       ast_channel_amaflags_set(tmp, DEFAULT_AMA_FLAGS);
00917    }
00918 
00919    if (!ast_strlen_zero(acctcode)) {
00920       ast_channel_accountcode_set(tmp, acctcode);
00921    }
00922    ast_channel_language_set(tmp, ast_defaultlanguage);
00923 
00924    ast_channel_context_set(tmp, S_OR(context, "default"));
00925    ast_channel_exten_set(tmp, S_OR(exten, "s"));
00926    ast_channel_priority_set(tmp, 1);
00927 
00928    headp = ast_channel_varshead(tmp);
00929    AST_LIST_HEAD_INIT_NOLOCK(headp);
00930 
00931    ast_pbx_hangup_handler_init(tmp);
00932    AST_LIST_HEAD_INIT_NOLOCK(ast_channel_datastores(tmp));
00933    AST_LIST_HEAD_INIT_NOLOCK(ast_channel_autochans(tmp));
00934 
00935    channel_tech = ast_get_channel_tech(tech);
00936    if (!channel_tech && !ast_strlen_zero(tech2)) {
00937       channel_tech = ast_get_channel_tech(tech2);
00938    }
00939    if (channel_tech) {
00940       ast_channel_tech_set(tmp, channel_tech);
00941    } else {
00942       ast_channel_tech_set(tmp, &null_tech);
00943    }
00944 
00945    ast_channel_internal_finalize(tmp);
00946 
00947    ast_atomic_fetchadd_int(&chancount, +1);
00948 
00949    /* You might scream "locking inversion" at seeing this but it is actually perfectly fine.
00950     * Since the channel was just created nothing can know about it yet or even acquire it.
00951     */
00952    ast_channel_lock(tmp);
00953 
00954    ao2_link(channels, tmp);
00955 
00956    if (endpoint) {
00957       ast_endpoint_add_channel(endpoint, tmp);
00958    }
00959 
00960    /*
00961     * And now, since the channel structure is built, and has its name, let
00962     * the world know of its existance
00963     */
00964    ast_channel_stage_snapshot_done(tmp);
00965    return tmp;
00966 }

static int __ast_queue_frame ( struct ast_channel chan,
struct ast_frame fin,
int  head,
struct ast_frame after 
) [static]

Definition at line 1028 of file channel.c.

References ast_channel_alert_writable(), ast_channel_alert_write(), ast_channel_blocker(), ast_channel_flags(), ast_channel_lock, ast_channel_name(), ast_channel_readq(), ast_channel_timer(), ast_channel_timingfd(), ast_channel_unlock, AST_CONTROL_END_OF_Q, AST_CONTROL_HANGUP, AST_FLAG_BLOCKING, AST_FRAME_CONTROL, AST_FRAME_NULL, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frdup(), ast_frfree, AST_LIST_APPEND_LIST, AST_LIST_FIRST, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_HEAD_NOLOCK, AST_LIST_INSERT_LIST_AFTER, AST_LIST_INSERT_TAIL, AST_LIST_LAST, AST_LIST_NEXT, AST_LIST_REMOVE, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log, ast_test_flag, ast_timer_enable_continuous(), errno, f, frames, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, NULL, and ast_frame::subclass.

Referenced by __ast_read(), ast_queue_frame(), and ast_queue_frame_head().

01029 {
01030    struct ast_frame *f;
01031    struct ast_frame *cur;
01032    unsigned int new_frames = 0;
01033    unsigned int new_voice_frames = 0;
01034    unsigned int queued_frames = 0;
01035    unsigned int queued_voice_frames = 0;
01036    AST_LIST_HEAD_NOLOCK(,ast_frame) frames;
01037 
01038    ast_channel_lock(chan);
01039 
01040    /*
01041     * Check the last frame on the queue if we are queuing the new
01042     * frames after it.
01043     */
01044    cur = AST_LIST_LAST(ast_channel_readq(chan));
01045    if (cur && cur->frametype == AST_FRAME_CONTROL && !head && (!after || after == cur)) {
01046       switch (cur->subclass.integer) {
01047       case AST_CONTROL_END_OF_Q:
01048          if (fin->frametype == AST_FRAME_CONTROL
01049             && fin->subclass.integer == AST_CONTROL_HANGUP) {
01050             /*
01051              * Destroy the end-of-Q marker frame so we can queue the hangup
01052              * frame in its place.
01053              */
01054             AST_LIST_REMOVE(ast_channel_readq(chan), cur, frame_list);
01055             ast_frfree(cur);
01056 
01057             /*
01058              * This has degenerated to a normal queue append anyway.  Since
01059              * we just destroyed the last frame in the queue we must make
01060              * sure that "after" is NULL or bad things will happen.
01061              */
01062             after = NULL;
01063             break;
01064          }
01065          /* Fall through */
01066       case AST_CONTROL_HANGUP:
01067          /* Don't queue anything. */
01068          ast_channel_unlock(chan);
01069          return 0;
01070       default:
01071          break;
01072       }
01073    }
01074 
01075    /* Build copies of all the new frames and count them */
01076    AST_LIST_HEAD_INIT_NOLOCK(&frames);
01077    for (cur = fin; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
01078       if (!(f = ast_frdup(cur))) {
01079          if (AST_LIST_FIRST(&frames)) {
01080             ast_frfree(AST_LIST_FIRST(&frames));
01081          }
01082          ast_channel_unlock(chan);
01083          return -1;
01084       }
01085 
01086       AST_LIST_INSERT_TAIL(&frames, f, frame_list);
01087       new_frames++;
01088       if (f->frametype == AST_FRAME_VOICE) {
01089          new_voice_frames++;
01090       }
01091    }
01092 
01093    /* Count how many frames exist on the queue */
01094    AST_LIST_TRAVERSE(ast_channel_readq(chan), cur, frame_list) {
01095       queued_frames++;
01096       if (cur->frametype == AST_FRAME_VOICE) {
01097          queued_voice_frames++;
01098       }
01099    }
01100 
01101    if ((queued_frames + new_frames > 128 || queued_voice_frames + new_voice_frames > 96)) {
01102       int count = 0;
01103       ast_log(LOG_WARNING, "Exceptionally long %squeue length queuing to %s\n", queued_frames + new_frames > 128 ? "" : "voice ", ast_channel_name(chan));
01104       AST_LIST_TRAVERSE_SAFE_BEGIN(ast_channel_readq(chan), cur, frame_list) {
01105          /* Save the most recent frame */
01106          if (!AST_LIST_NEXT(cur, frame_list)) {
01107             break;
01108          } else if (cur->frametype == AST_FRAME_VOICE || cur->frametype == AST_FRAME_VIDEO || cur->frametype == AST_FRAME_NULL) {
01109             if (++count > 64) {
01110                break;
01111             }
01112             AST_LIST_REMOVE_CURRENT(frame_list);
01113             ast_frfree(cur);
01114          }
01115       }
01116       AST_LIST_TRAVERSE_SAFE_END;
01117    }
01118 
01119    if (after) {
01120       AST_LIST_INSERT_LIST_AFTER(ast_channel_readq(chan), &frames, after, frame_list);
01121    } else {
01122       if (head) {
01123          AST_LIST_APPEND_LIST(&frames, ast_channel_readq(chan), frame_list);
01124          AST_LIST_HEAD_INIT_NOLOCK(ast_channel_readq(chan));
01125       }
01126       AST_LIST_APPEND_LIST(ast_channel_readq(chan), &frames, frame_list);
01127    }
01128 
01129    if (ast_channel_alert_writable(chan)) {
01130       if (ast_channel_alert_write(chan)) {
01131          ast_log(LOG_WARNING, "Unable to write to alert pipe on %s (qlen = %u): %s!\n",
01132             ast_channel_name(chan), queued_frames, strerror(errno));
01133       }
01134    } else if (ast_channel_timingfd(chan) > -1) {
01135       ast_timer_enable_continuous(ast_channel_timer(chan));
01136    } else if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_BLOCKING)) {
01137       pthread_kill(ast_channel_blocker(chan), SIGURG);
01138    }
01139 
01140    ast_channel_unlock(chan);
01141 
01142    return 0;
01143 }

static struct ast_frame* __ast_read ( struct ast_channel chan,
int  dropaudio 
) [static, read]

Todo:
XXX It is possible to write a digit to the audiohook twice if the digit was originally read while the channel was in autoservice.

Definition at line 3702 of file channel.c.

References __ast_queue_frame(), ast_control_read_action_payload::action, ao2_ref, AST_ALERT_READ_FATAL, ast_audiohook_detach_list(), AST_AUDIOHOOK_DIRECTION_READ, ast_audiohook_write_list(), ast_audiohook_write_list_empty(), ast_channel_alert_write(), ast_channel_audiohooks(), ast_channel_audiohooks_set(), ast_channel_blocker_set(), ast_channel_connected(), ast_channel_connected_line_macro(), ast_channel_connected_line_sub(), ast_channel_dtmf_digit_to_emulate(), ast_channel_dtmf_digit_to_emulate_set(), ast_channel_dtmf_tv(), ast_channel_dtmf_tv_set(), ast_channel_dtmff(), ast_channel_emulate_dtmf_duration(), ast_channel_emulate_dtmf_duration_set(), ast_channel_fd_isset(), ast_channel_fdno(), ast_channel_fdno_set(), ast_channel_fin(), ast_channel_fin_set(), ast_channel_flags(), ast_channel_framehooks(), ast_channel_generator(), ast_channel_generatordata(), ast_channel_generatordata_set(), ast_channel_hangupcause_set(), ast_channel_insmpl(), ast_channel_insmpl_set(), ast_channel_internal_alert_read(), ast_channel_is_bridged(), ast_channel_lock, ast_channel_monitor(), ast_channel_music_state(), ast_channel_name(), ast_channel_outsmpl(), ast_channel_rawreadformat(), ast_channel_readformat(), ast_channel_readq(), ast_channel_readtrans(), ast_channel_softhangup_internal_flag(), ast_channel_softhangup_internal_flag_add(), ast_channel_tech(), ast_channel_timer(), ast_channel_timingdata(), ast_channel_timingfd(), ast_channel_timingfunc(), ast_channel_unlock, ast_check_hangup(), ast_clear_flag, ast_connected_line_parse_data(), AST_CONTROL_ANSWER, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_END_OF_Q, AST_CONTROL_HANGUP, AST_CONTROL_READ_ACTION, ast_deactivate_generator(), ast_debug, AST_DEFAULT_EMULATE_DTMF_DURATION, AST_FLAG_DEFER_DTMF, AST_FLAG_EMULATE_DTMF, AST_FLAG_END_DTMF_ONLY, AST_FLAG_EXCEPTION, AST_FLAG_IN_DTMF, AST_FLAG_OUTGOING, AST_FLAG_TIMINGDATA_IS_AO2_OBJ, AST_FLAG_ZOMBIE, ast_format_cache_is_slinear(), ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_format_get_sample_rate(), AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_frame_dump(), AST_FRAME_NULL, AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO, AST_FRAME_VOICE, ast_framehook_list_read_event(), ast_frfree, AST_GENERATOR_FD, ast_indicate_data(), AST_JITTERBUFFER_FD, AST_LIST_EMPTY, AST_LIST_FIRST, AST_LIST_LAST, AST_LIST_NEXT, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log, AST_MIN_DTMF_GAP, AST_MONITOR_RUNNING, ast_null_frame, ast_party_connected_line_copy(), ast_party_connected_line_free(), ast_party_connected_line_init(), ast_queue_control(), ast_queue_frame(), ast_queue_frame_head(), ast_read_generator_actions(), ast_seekstream(), ast_set_flag, ast_set_read_format_path(), ast_setstate(), AST_SOFTHANGUP_DEV, AST_STATE_UP, ast_test_flag, ast_timer_ack(), ast_timer_disable_continuous(), ast_timer_get_event(), ast_timer_set_rate(), AST_TIMING_EVENT_CONTINUOUS, AST_TIMING_EVENT_EXPIRED, AST_TIMING_FD, ast_translate(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), ast_writestream(), calc_monitor_jump(), ast_frame::data, DEBUGCHAN_FLAG, ast_generator::digit, digit, DTMF_RECEIVED, ast_channel_tech::exception, ast_channel_monitor::format, ast_frame_subclass::format, FRAMECOUNT_INC, ast_frame::frametype, func, ast_generator::generate, ast_frame_subclass::integer, ast_frame::len, LOG_DTMF, LOG_ERROR, LOG_WARNING, NULL, option_dtmfminduration, ast_control_read_action_payload::payload, ast_control_read_action_payload::payload_size, ast_frame::ptr, queue_dtmf_readq(), ast_channel_tech::read, ast_frame::samples, SEEK_FORCECUR, send_dtmf_begin_event(), send_dtmf_end_event(), should_skip_dtmf(), ast_frame::subclass, tmp(), and ast_frame::uint32.

Referenced by ast_read(), and ast_read_noaudio().

03703 {
03704    struct ast_frame *f = NULL;   /* the return value */
03705    int prestate;
03706    int cause = 0;
03707 
03708    /* this function is very long so make sure there is only one return
03709     * point at the end (there are only two exceptions to this).
03710     */
03711    ast_channel_lock(chan);
03712 
03713    /* Stop if we're a zombie or need a soft hangup */
03714    if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
03715       if (ast_channel_generator(chan))
03716          ast_deactivate_generator(chan);
03717 
03718       /*
03719        * It is possible for chan->_softhangup to be set and there
03720        * still be control frames that need to be read.  Instead of
03721        * just going to 'done' in the case of ast_check_hangup(), we
03722        * need to queue the end-of-Q frame so that it can mark the end
03723        * of the read queue.  If there are frames to be read,
03724        * ast_queue_control() will be called repeatedly, but will only
03725        * queue the first end-of-Q frame.
03726        */
03727       if (ast_channel_softhangup_internal_flag(chan)) {
03728          ast_queue_control(chan, AST_CONTROL_END_OF_Q);
03729       } else {
03730          goto done;
03731       }
03732    } else {
03733 #ifdef AST_DEVMODE
03734       /*
03735        * The ast_waitfor() code records which of the channel's file
03736        * descriptors reported that data is available.  In theory,
03737        * ast_read() should only be called after ast_waitfor() reports
03738        * that a channel has data available for reading.  However,
03739        * there still may be some edge cases throughout the code where
03740        * ast_read() is called improperly.  This can potentially cause
03741        * problems, so if this is a developer build, make a lot of
03742        * noise if this happens so that it can be addressed.
03743        *
03744        * One of the potential problems is blocking on a dead channel.
03745        */
03746       if (ast_channel_fdno(chan) == -1) {
03747          ast_log(LOG_ERROR,
03748             "ast_read() on chan '%s' called with no recorded file descriptor.\n",
03749             ast_channel_name(chan));
03750       }
03751 #endif
03752    }
03753 
03754    prestate = ast_channel_state(chan);
03755 
03756    if (ast_channel_timingfd(chan) > -1 && ast_channel_fdno(chan) == AST_TIMING_FD) {
03757       enum ast_timer_event res;
03758 
03759       ast_clear_flag(ast_channel_flags(chan), AST_FLAG_EXCEPTION);
03760 
03761       res = ast_timer_get_event(ast_channel_timer(chan));
03762 
03763       switch (res) {
03764       case AST_TIMING_EVENT_EXPIRED:
03765          if (ast_timer_ack(ast_channel_timer(chan), 1) < 0) {
03766             ast_log(LOG_ERROR, "Failed to acknoweldge timer in ast_read\n");
03767             goto done;
03768          }
03769 
03770          if (ast_channel_timingfunc(chan)) {
03771             /* save a copy of func/data before unlocking the channel */
03772             ast_timing_func_t func = ast_channel_timingfunc(chan);
03773             void *data = ast_channel_timingdata(chan);
03774             int got_ref = 0;
03775             if (data && ast_test_flag(ast_channel_flags(chan), AST_FLAG_TIMINGDATA_IS_AO2_OBJ)) {
03776                ao2_ref(data, 1);
03777                got_ref = 1;
03778             }
03779             ast_channel_fdno_set(chan, -1);
03780             ast_channel_unlock(chan);
03781             func(data);
03782             if (got_ref) {
03783                ao2_ref(data, -1);
03784             }
03785          } else {
03786             ast_timer_set_rate(ast_channel_timer(chan), 0);
03787             ast_channel_fdno_set(chan, -1);
03788             ast_channel_unlock(chan);
03789          }
03790 
03791          /* cannot 'goto done' because the channel is already unlocked */
03792          return &ast_null_frame;
03793 
03794       case AST_TIMING_EVENT_CONTINUOUS:
03795          if (AST_LIST_EMPTY(ast_channel_readq(chan)) ||
03796             !AST_LIST_NEXT(AST_LIST_FIRST(ast_channel_readq(chan)), frame_list)) {
03797             ast_timer_disable_continuous(ast_channel_timer(chan));
03798          }
03799          break;
03800       }
03801 
03802    } else if (ast_channel_fd_isset(chan, AST_GENERATOR_FD) && ast_channel_fdno(chan) == AST_GENERATOR_FD) {
03803       /* if the AST_GENERATOR_FD is set, call the generator with args
03804        * set to -1 so it can do whatever it needs to.
03805        */
03806       void *tmp = ast_channel_generatordata(chan);
03807       ast_channel_generatordata_set(chan, NULL);     /* reset to let ast_write get through */
03808       ast_channel_generator(chan)->generate(chan, tmp, -1, -1);
03809       ast_channel_generatordata_set(chan, tmp);
03810       f = &ast_null_frame;
03811       ast_channel_fdno_set(chan, -1);
03812       goto done;
03813    } else if (ast_channel_fd_isset(chan, AST_JITTERBUFFER_FD) && ast_channel_fdno(chan) == AST_JITTERBUFFER_FD) {
03814       ast_clear_flag(ast_channel_flags(chan), AST_FLAG_EXCEPTION);
03815    }
03816 
03817    /* Read and ignore anything on the alertpipe, but read only
03818       one sizeof(blah) per frame that we send from it */
03819    if (ast_channel_internal_alert_read(chan) == AST_ALERT_READ_FATAL) {
03820       f = &ast_null_frame;
03821       goto done;
03822    }
03823 
03824    /* Check for pending read queue */
03825    if (!AST_LIST_EMPTY(ast_channel_readq(chan))) {
03826       int skip_dtmf = should_skip_dtmf(chan);
03827 
03828       AST_LIST_TRAVERSE_SAFE_BEGIN(ast_channel_readq(chan), f, frame_list) {
03829          /* We have to be picky about which frame we pull off of the readq because
03830           * there are cases where we want to leave DTMF frames on the queue until
03831           * some later time. */
03832 
03833          if ( (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && skip_dtmf) {
03834             continue;
03835          }
03836 
03837          AST_LIST_REMOVE_CURRENT(frame_list);
03838          break;
03839       }
03840       AST_LIST_TRAVERSE_SAFE_END;
03841 
03842       if (!f) {
03843          /* There were no acceptable frames on the readq. */
03844          f = &ast_null_frame;
03845          ast_channel_alert_write(chan);
03846       }
03847 
03848       /* Interpret hangup and end-of-Q frames to return NULL */
03849       /* XXX why not the same for frames from the channel ? */
03850       if (f->frametype == AST_FRAME_CONTROL) {
03851          switch (f->subclass.integer) {
03852          case AST_CONTROL_HANGUP:
03853             ast_channel_softhangup_internal_flag_add(chan, AST_SOFTHANGUP_DEV);
03854             cause = f->data.uint32;
03855             /* Fall through */
03856          case AST_CONTROL_END_OF_Q:
03857             ast_frfree(f);
03858             f = NULL;
03859             break;
03860          default:
03861             break;
03862          }
03863       }
03864    } else {
03865       ast_channel_blocker_set(chan, pthread_self());
03866       if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_EXCEPTION)) {
03867          if (ast_channel_tech(chan)->exception)
03868             f = ast_channel_tech(chan)->exception(chan);
03869          else {
03870             ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", ast_channel_name(chan));
03871             f = &ast_null_frame;
03872          }
03873          /* Clear the exception flag */
03874          ast_clear_flag(ast_channel_flags(chan), AST_FLAG_EXCEPTION);
03875       } else if (ast_channel_tech(chan) && ast_channel_tech(chan)->read)
03876          f = ast_channel_tech(chan)->read(chan);
03877       else
03878          ast_log(LOG_WARNING, "No read routine on channel %s\n", ast_channel_name(chan));
03879    }
03880 
03881    /* Perform the framehook read event here. After the frame enters the framehook list
03882     * there is no telling what will happen, <insert mad scientist laugh here>!!! */
03883    f = ast_framehook_list_read_event(ast_channel_framehooks(chan), f);
03884 
03885    /*
03886     * Reset the recorded file descriptor that triggered this read so that we can
03887     * easily detect when ast_read() is called without properly using ast_waitfor().
03888     */
03889    ast_channel_fdno_set(chan, -1);
03890 
03891    if (f) {
03892       struct ast_frame *readq_tail = AST_LIST_LAST(ast_channel_readq(chan));
03893       struct ast_control_read_action_payload *read_action_payload;
03894       struct ast_party_connected_line connected;
03895 
03896       /* if the channel driver returned more than one frame, stuff the excess
03897          into the readq for the next ast_read call
03898       */
03899       if (AST_LIST_NEXT(f, frame_list)) {
03900          ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list));
03901          ast_frfree(AST_LIST_NEXT(f, frame_list));
03902          AST_LIST_NEXT(f, frame_list) = NULL;
03903       }
03904 
03905       switch (f->frametype) {
03906       case AST_FRAME_CONTROL:
03907          if (f->subclass.integer == AST_CONTROL_ANSWER) {
03908             if (!ast_test_flag(ast_channel_flags(chan), AST_FLAG_OUTGOING)) {
03909                ast_debug(1, "Ignoring answer on an inbound call!\n");
03910                ast_frfree(f);
03911                f = &ast_null_frame;
03912             } else if (prestate == AST_STATE_UP && ast_channel_is_bridged(chan)) {
03913                ast_debug(1, "Dropping duplicate answer!\n");
03914                ast_frfree(f);
03915                f = &ast_null_frame;
03916             } else {
03917                ast_setstate(chan, AST_STATE_UP);
03918             }
03919          } else if (f->subclass.integer == AST_CONTROL_READ_ACTION) {
03920             read_action_payload = f->data.ptr;
03921             switch (read_action_payload->action) {
03922             case AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO:
03923                ast_party_connected_line_init(&connected);
03924                ast_party_connected_line_copy(&connected, ast_channel_connected(chan));
03925                if (ast_connected_line_parse_data(read_action_payload->payload,
03926                   read_action_payload->payload_size, &connected)) {
03927                   ast_party_connected_line_free(&connected);
03928                   break;
03929                }
03930                ast_channel_unlock(chan);
03931                if (ast_channel_connected_line_sub(NULL, chan, &connected, 0) &&
03932                   ast_channel_connected_line_macro(NULL, chan, &connected, 1, 0)) {
03933                   ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE,
03934                      read_action_payload->payload,
03935                      read_action_payload->payload_size);
03936                }
03937                ast_party_connected_line_free(&connected);
03938                ast_channel_lock(chan);
03939                break;
03940             }
03941             ast_frfree(f);
03942             f = &ast_null_frame;
03943          }
03944          break;
03945       case AST_FRAME_DTMF_END:
03946          send_dtmf_end_event(chan, DTMF_RECEIVED, f->subclass.integer, f->len);
03947          ast_log(LOG_DTMF, "DTMF end '%c' received on %s, duration %ld ms\n", f->subclass.integer, ast_channel_name(chan), f->len);
03948          /* Queue it up if DTMF is deferred, or if DTMF emulation is forced. */
03949          if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_DEFER_DTMF) || ast_test_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF)) {
03950             queue_dtmf_readq(chan, f);
03951             ast_frfree(f);
03952             f = &ast_null_frame;
03953          } else if (!ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_DTMF | AST_FLAG_END_DTMF_ONLY)) {
03954             if (!ast_tvzero(*ast_channel_dtmf_tv(chan)) &&
03955                 ast_tvdiff_ms(ast_tvnow(), *ast_channel_dtmf_tv(chan)) < AST_MIN_DTMF_GAP) {
03956                /* If it hasn't been long enough, defer this digit */
03957                queue_dtmf_readq(chan, f);
03958                ast_frfree(f);
03959                f = &ast_null_frame;
03960             } else {
03961                /* There was no begin, turn this into a begin and send the end later */
03962                struct timeval tv = ast_tvnow();
03963                f->frametype = AST_FRAME_DTMF_BEGIN;
03964                ast_set_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF);
03965                ast_channel_dtmf_digit_to_emulate_set(chan, f->subclass.integer);
03966                ast_channel_dtmf_tv_set(chan, &tv);
03967                if (f->len) {
03968                   if (f->len > option_dtmfminduration)
03969                      ast_channel_emulate_dtmf_duration_set(chan, f->len);
03970                   else
03971                      ast_channel_emulate_dtmf_duration_set(chan, option_dtmfminduration);
03972                } else
03973                   ast_channel_emulate_dtmf_duration_set(chan, AST_DEFAULT_EMULATE_DTMF_DURATION);
03974                ast_log(LOG_DTMF, "DTMF begin emulation of '%c' with duration %u queued on %s\n", f->subclass.integer, ast_channel_emulate_dtmf_duration(chan), ast_channel_name(chan));
03975             }
03976             if (ast_channel_audiohooks(chan)) {
03977                struct ast_frame *old_frame = f;
03978                /*!
03979                 * \todo XXX It is possible to write a digit to the audiohook twice
03980                 * if the digit was originally read while the channel was in autoservice. */
03981                f = ast_audiohook_write_list(chan, ast_channel_audiohooks(chan), AST_AUDIOHOOK_DIRECTION_READ, f);
03982                if (old_frame != f)
03983                   ast_frfree(old_frame);
03984             }
03985          } else {
03986             struct timeval now = ast_tvnow();
03987             if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_DTMF)) {
03988                ast_log(LOG_DTMF, "DTMF end accepted with begin '%c' on %s\n", f->subclass.integer, ast_channel_name(chan));
03989                ast_clear_flag(ast_channel_flags(chan), AST_FLAG_IN_DTMF);
03990                if (!f->len)
03991                   f->len = ast_tvdiff_ms(now, *ast_channel_dtmf_tv(chan));
03992 
03993                /* detect tones that were received on
03994                 * the wire with durations shorter than
03995                 * option_dtmfminduration and set f->len
03996                 * to the actual duration of the DTMF
03997                 * frames on the wire.  This will cause
03998                 * dtmf emulation to be triggered later
03999                 * on.
04000                 */
04001                if (ast_tvdiff_ms(now, *ast_channel_dtmf_tv(chan)) < option_dtmfminduration) {
04002                   f->len = ast_tvdiff_ms(now, *ast_channel_dtmf_tv(chan));
04003                   ast_log(LOG_DTMF, "DTMF end '%c' detected to have actual duration %ld on the wire, emulation will be triggered on %s\n", f->subclass.integer, f->len, ast_channel_name(chan));
04004                }
04005             } else if (!f->len) {
04006                ast_log(LOG_DTMF, "DTMF end accepted without begin '%c' on %s\n", f->subclass.integer, ast_channel_name(chan));
04007                f->len = option_dtmfminduration;
04008             }
04009             if (f->len < option_dtmfminduration && !ast_test_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY)) {
04010                ast_log(LOG_DTMF, "DTMF end '%c' has duration %ld but want minimum %u, emulating on %s\n", f->subclass.integer, f->len, option_dtmfminduration, ast_channel_name(chan));
04011                ast_set_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF);
04012                ast_channel_dtmf_digit_to_emulate_set(chan, f->subclass.integer);
04013                ast_channel_emulate_dtmf_duration_set(chan, option_dtmfminduration - f->len);
04014                ast_frfree(f);
04015                f = &ast_null_frame;
04016             } else {
04017                ast_log(LOG_DTMF, "DTMF end passthrough '%c' on %s\n", f->subclass.integer, ast_channel_name(chan));
04018                if (f->len < option_dtmfminduration) {
04019                   f->len = option_dtmfminduration;
04020                }
04021                ast_channel_dtmf_tv_set(chan, &now);
04022             }
04023             if (ast_channel_audiohooks(chan)) {
04024                struct ast_frame *old_frame = f;
04025                f = ast_audiohook_write_list(chan, ast_channel_audiohooks(chan), AST_AUDIOHOOK_DIRECTION_READ, f);
04026                if (old_frame != f)
04027                   ast_frfree(old_frame);
04028             }
04029          }
04030          break;
04031       case AST_FRAME_DTMF_BEGIN:
04032          send_dtmf_begin_event(chan, DTMF_RECEIVED, f->subclass.integer);
04033          ast_log(LOG_DTMF, "DTMF begin '%c' received on %s\n", f->subclass.integer, ast_channel_name(chan));
04034          if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_DEFER_DTMF | AST_FLAG_END_DTMF_ONLY | AST_FLAG_EMULATE_DTMF) ||
04035              (!ast_tvzero(*ast_channel_dtmf_tv(chan)) &&
04036                ast_tvdiff_ms(ast_tvnow(), *ast_channel_dtmf_tv(chan)) < AST_MIN_DTMF_GAP) ) {
04037             ast_log(LOG_DTMF, "DTMF begin ignored '%c' on %s\n", f->subclass.integer, ast_channel_name(chan));
04038             ast_frfree(f);
04039             f = &ast_null_frame;
04040          } else {
04041             struct timeval now = ast_tvnow();
04042             ast_set_flag(ast_channel_flags(chan), AST_FLAG_IN_DTMF);
04043             ast_channel_dtmf_tv_set(chan, &now);
04044             ast_log(LOG_DTMF, "DTMF begin passthrough '%c' on %s\n", f->subclass.integer, ast_channel_name(chan));
04045          }
04046          break;
04047       case AST_FRAME_NULL:
04048          /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration
04049           * is reached , because we want to make sure we pass at least one
04050           * voice frame through before starting the next digit, to ensure a gap
04051           * between DTMF digits. */
04052          if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF)) {
04053             struct timeval now = ast_tvnow();
04054             if (!ast_channel_emulate_dtmf_duration(chan)) {
04055                ast_clear_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF);
04056                ast_channel_dtmf_digit_to_emulate_set(chan, 0);
04057             } else if (ast_tvdiff_ms(now, *ast_channel_dtmf_tv(chan)) >= ast_channel_emulate_dtmf_duration(chan)) {
04058                ast_channel_emulate_dtmf_duration_set(chan, 0);
04059                ast_frfree(f);
04060                f = ast_channel_dtmff(chan);
04061                f->frametype = AST_FRAME_DTMF_END;
04062                f->subclass.integer = ast_channel_dtmf_digit_to_emulate(chan);
04063                f->len = ast_tvdiff_ms(now, *ast_channel_dtmf_tv(chan));
04064                ast_channel_dtmf_tv_set(chan, &now);
04065                ast_clear_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF);
04066                ast_channel_dtmf_digit_to_emulate_set(chan, 0);
04067                ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass.integer, ast_channel_name(chan));
04068                if (ast_channel_audiohooks(chan)) {
04069                   struct ast_frame *old_frame = f;
04070                   f = ast_audiohook_write_list(chan, ast_channel_audiohooks(chan), AST_AUDIOHOOK_DIRECTION_READ, f);
04071                   if (old_frame != f) {
04072                      ast_frfree(old_frame);
04073                   }
04074                }
04075             }
04076          }
04077          break;
04078       case AST_FRAME_VOICE:
04079          /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration
04080           * is reached , because we want to make sure we pass at least one
04081           * voice frame through before starting the next digit, to ensure a gap
04082           * between DTMF digits. */
04083          if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF) && !ast_channel_emulate_dtmf_duration(chan)) {
04084             ast_clear_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF);
04085             ast_channel_dtmf_digit_to_emulate_set(chan, 0);
04086          }
04087 
04088          if (dropaudio || ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_DTMF)) {
04089             if (dropaudio)
04090                ast_read_generator_actions(chan, f);
04091             ast_frfree(f);
04092             f = &ast_null_frame;
04093          }
04094 
04095          if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF) && !ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_DTMF)) {
04096             struct timeval now = ast_tvnow();
04097             if (ast_tvdiff_ms(now, *ast_channel_dtmf_tv(chan)) >= ast_channel_emulate_dtmf_duration(chan)) {
04098                ast_channel_emulate_dtmf_duration_set(chan, 0);
04099                ast_frfree(f);
04100                f = ast_channel_dtmff(chan);
04101                f->frametype = AST_FRAME_DTMF_END;
04102                f->subclass.integer = ast_channel_dtmf_digit_to_emulate(chan);
04103                f->len = ast_tvdiff_ms(now, *ast_channel_dtmf_tv(chan));
04104                ast_channel_dtmf_tv_set(chan, &now);
04105                if (ast_channel_audiohooks(chan)) {
04106                   struct ast_frame *old_frame = f;
04107                   f = ast_audiohook_write_list(chan, ast_channel_audiohooks(chan), AST_AUDIOHOOK_DIRECTION_READ, f);
04108                   if (old_frame != f)
04109                      ast_frfree(old_frame);
04110                }
04111                ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass.integer, ast_channel_name(chan));
04112             } else {
04113                /* Drop voice frames while we're still in the middle of the digit */
04114                ast_frfree(f);
04115                f = &ast_null_frame;
04116             }
04117             break;
04118          }
04119          if (f->frametype != AST_FRAME_VOICE) {
04120             break;
04121          }
04122          if (ast_format_cmp(f->subclass.format, ast_channel_rawreadformat(chan)) != AST_FORMAT_CMP_EQUAL
04123             && ast_format_cmp(f->subclass.format, ast_channel_readformat(chan)) != AST_FORMAT_CMP_EQUAL) {
04124             struct ast_format *core_format;
04125 
04126             /*
04127              * Note: This frame may not be one of the current native
04128              * formats.  We may have gotten it out of the read queue from
04129              * a previous multi-frame translation, from a framehook
04130              * injected frame, or the device we're talking to isn't
04131              * respecting negotiated formats.  Regardless we will accept
04132              * all frames.
04133              *
04134              * Update the read translation path to handle the new format
04135              * that just came in.  If the core wants slinear we need to
04136              * setup a new translation path because the core is usually
04137              * doing something with the audio itself and may not handle
04138              * any other format.  e.g., Softmix bridge, holding bridge
04139              * announcer channel, recording, AMD...  Otherwise, we'll
04140              * setup to pass the frame as is to the core.  In this case
04141              * the core doesn't care.  The channel is likely in
04142              * autoservice, safesleep, or the channel is in a bridge.
04143              * Let the bridge technology deal with format compatibility
04144              * between the channels in the bridge.
04145              *
04146              * Beware of the transcode_via_slin and genericplc options as
04147              * they force any transcoding to go through slin on a bridge.
04148              * Unfortunately transcode_via_slin is enabled by default and
04149              * genericplc is enabled in the codecs.conf.sample file.
04150              *
04151              * XXX Only updating translation to slinear frames has some
04152              * corner cases if slinear is one of the native formats and
04153              * there are different sample rates involved.  We might wind
04154              * up with conflicting translation paths between channels
04155              * where the read translation path on this channel reduces
04156              * the sample rate followed by a write translation path on
04157              * the peer channel that increases the sample rate.
04158              */
04159             core_format = ast_channel_readformat(chan);
04160             if (!ast_format_cache_is_slinear(core_format)) {
04161                core_format = f->subclass.format;
04162             }
04163             if (ast_set_read_format_path(chan, f->subclass.format, core_format)) {
04164                /* Drop frame.  We couldn't make it compatible with the core. */
04165                ast_frfree(f);
04166                f = &ast_null_frame;
04167                break;
04168             }
04169          }
04170          /* Send frame to audiohooks if present */
04171          if (ast_channel_audiohooks(chan)) {
04172             struct ast_frame *old_frame = f;
04173 
04174             f = ast_audiohook_write_list(chan, ast_channel_audiohooks(chan), AST_AUDIOHOOK_DIRECTION_READ, f);
04175             if (old_frame != f) {
04176                ast_frfree(old_frame);
04177             }
04178          }
04179          if (ast_channel_monitor(chan) && ast_channel_monitor(chan)->read_stream) {
04180             /* XXX what does this do ? */
04181 #ifndef MONITOR_CONSTANT_DELAY
04182             int jump = ast_channel_outsmpl(chan) - ast_channel_insmpl(chan) - 4 * f->samples;
04183             if (jump >= 0) {
04184                jump = calc_monitor_jump((ast_channel_outsmpl(chan) - ast_channel_insmpl(chan)),
04185                   ast_format_get_sample_rate(f->subclass.format),
04186                   ast_format_get_sample_rate(ast_channel_monitor(chan)->read_stream->fmt->format));
04187                if (ast_seekstream(ast_channel_monitor(chan)->read_stream, jump, SEEK_FORCECUR) == -1) {
04188                   ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
04189                }
04190                ast_channel_insmpl_set(chan, ast_channel_insmpl(chan) + (ast_channel_outsmpl(chan) - ast_channel_insmpl(chan)) + f->samples);
04191             } else {
04192                ast_channel_insmpl_set(chan, ast_channel_insmpl(chan) + f->samples);
04193             }
04194 #else
04195             int jump = calc_monitor_jump((ast_channel_outsmpl(chan) - ast_channel_insmpl(chan)),
04196                ast_format_get_sample_rate(f->subclass.codec),
04197                ast_format_get_sample_rate(ast_channel_monitor(chan)->read_stream->fmt->format));
04198             if (jump - MONITOR_DELAY >= 0) {
04199                if (ast_seekstream(ast_channel_monitor(chan)->read_stream, jump - f->samples, SEEK_FORCECUR) == -1) {
04200                   ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
04201                }
04202                ast_channel_insmpl(chan) += ast_channel_outsmpl(chan) - ast_channel_insmpl(chan);
04203             } else {
04204                ast_channel_insmpl(chan) += f->samples;
04205             }
04206 #endif
04207             if (ast_channel_monitor(chan)->state == AST_MONITOR_RUNNING) {
04208                if (ast_writestream(ast_channel_monitor(chan)->read_stream, f) < 0)
04209                   ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
04210             }
04211          }
04212 
04213          if (ast_channel_readtrans(chan)
04214             && ast_format_cmp(f->subclass.format, ast_channel_rawreadformat(chan)) == AST_FORMAT_CMP_EQUAL) {
04215             f = ast_translate(ast_channel_readtrans(chan), f, 1);
04216             if (!f) {
04217                f = &ast_null_frame;
04218             }
04219          }
04220 
04221          /*
04222           * It is possible for the translation process on the channel to have
04223           * produced multiple frames from the single input frame we passed it; if
04224           * this happens, queue the additional frames *before* the frames we may
04225           * have queued earlier. if the readq was empty, put them at the head of
04226           * the queue, and if it was not, put them just after the frame that was
04227           * at the end of the queue.
04228           */
04229          if (AST_LIST_NEXT(f, frame_list)) {
04230             if (!readq_tail) {
04231                ast_queue_frame_head(chan, AST_LIST_NEXT(f, frame_list));
04232             } else {
04233                __ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list), 0, readq_tail);
04234             }
04235             ast_frfree(AST_LIST_NEXT(f, frame_list));
04236             AST_LIST_NEXT(f, frame_list) = NULL;
04237          }
04238 
04239          /*
04240           * Run generator sitting on the line if timing device not available
04241           * and synchronous generation of outgoing frames is necessary
04242           */
04243          ast_read_generator_actions(chan, f);
04244          break;
04245       default:
04246          /* Just pass it on! */
04247          break;
04248       }
04249    } else {
04250       /* Make sure we always return NULL in the future */
04251       if (!ast_channel_softhangup_internal_flag(chan)) {
04252          ast_channel_softhangup_internal_flag_add(chan, AST_SOFTHANGUP_DEV);
04253       }
04254       if (cause)
04255          ast_channel_hangupcause_set(chan, cause);
04256       if (ast_channel_generator(chan))
04257          ast_deactivate_generator(chan);
04258       /* We no longer End the CDR here */
04259    }
04260 
04261    /* High bit prints debugging */
04262    if (ast_channel_fin(chan) & DEBUGCHAN_FLAG)
04263       ast_frame_dump(ast_channel_name(chan), f, "<<");
04264    ast_channel_fin_set(chan, FRAMECOUNT_INC(ast_channel_fin(chan)));
04265 
04266 done:
04267    if (ast_channel_music_state(chan) && ast_channel_generator(chan) && ast_channel_generator(chan)->digit && f && f->frametype == AST_FRAME_DTMF_END)
04268       ast_channel_generator(chan)->digit(chan, f->subclass.integer);
04269 
04270    if (ast_channel_audiohooks(chan) && ast_audiohook_write_list_empty(ast_channel_audiohooks(chan))) {
04271       /* The list gets recreated if audiohooks are added again later */
04272       ast_audiohook_detach_list(ast_channel_audiohooks(chan));
04273       ast_channel_audiohooks_set(chan, NULL);
04274    }
04275    ast_channel_unlock(chan);
04276    return f;
04277 }

struct ast_channel* __ast_request_and_dial ( const char *  type,
struct ast_format_cap cap,
const struct ast_assigned_ids assignedids,
const struct ast_channel requestor,
const char *  addr,
int  timeout,
int *  reason,
const char *  cid_num,
const char *  cid_name,
struct outgoing_helper oh 
) [read]

Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it.

Parameters:
type type of channel to request
cap format capabilities for requested channel
assignedids Unique Id to assign to channel
requestor channel requesting data
addr destination of the call
timeout maximum amount of time to wait for an answer
reason why unsuccessful (if unsuccessful)
cid_num Caller-ID Number
cid_name Caller-ID Name (ascii)
oh Outgoing helper
Returns:
Returns an ast_channel on success or no answer, NULL on failure. Check the value of chan->_state to know if the call was answered or not.

Definition at line 5703 of file channel.c.

References outgoing_helper::account, ast_call(), ast_call_forward(), AST_CAUSE_NO_ANSWER, ast_channel_call_forward(), ast_channel_connected(), ast_channel_context_set(), ast_channel_datastore_inherit(), ast_channel_exten_set(), ast_channel_flags(), ast_channel_hangupcause_hash_set(), ast_channel_hangupcause_set(), ast_channel_inherit_variables(), ast_channel_lock, ast_channel_lock_both, ast_channel_priority_set(), ast_channel_req_accountcodes(), AST_CHANNEL_REQUESTOR_BRIDGE_PEER, ast_channel_set_connected_line(), ast_channel_stage_snapshot(), ast_channel_stage_snapshot_done(), ast_channel_unlock, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CC, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_PVT_CAUSE_CODE, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, AST_FLAG_ORIGINATED, AST_FRAME_CONTROL, ast_frfree, ast_hangup(), ast_log, ast_party_connected_line_set_init(), AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, ast_read(), ast_remaining_ms(), ast_request(), ast_set_callerid(), ast_set_flag, ast_set_variables(), AST_STATE_UP, ast_strlen_zero, ast_tvnow(), ast_waitfor(), outgoing_helper::cid_name, outgoing_helper::cid_num, outgoing_helper::connect_on_early_media, outgoing_helper::context, ast_frame::data, ast_frame::datalen, outgoing_helper::exten, ast_frame::frametype, handle_cause(), ast_party_connected_line::id, ast_frame_subclass::integer, LOG_NOTICE, ast_party_id::name, NULL, ast_party_id::number, outgoing_helper::parent_channel, ast_party_name::presentation, ast_party_number::presentation, outgoing_helper::priority, ast_frame::ptr, ast_party_name::str, ast_party_number::str, ast_frame::subclass, ast_party_name::valid, ast_party_number::valid, and outgoing_helper::vars.

Referenced by announce_to_dial(), and ast_request_and_dial().

05704 {
05705    int dummy_outstate;
05706    int cause = 0;
05707    struct ast_channel *chan;
05708    int res = 0;
05709    int last_subclass = 0;
05710    struct ast_party_connected_line connected;
05711 
05712    if (outstate)
05713       *outstate = 0;
05714    else
05715       outstate = &dummy_outstate;   /* make outstate always a valid pointer */
05716 
05717    chan = ast_request(type, cap, assignedids, requestor, addr, &cause);
05718    if (!chan) {
05719       ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, addr);
05720       handle_cause(cause, outstate);
05721       return NULL;
05722    }
05723 
05724    if (oh) {
05725       if (oh->vars) {
05726          ast_channel_lock(chan);
05727          ast_set_variables(chan, oh->vars);
05728          ast_channel_unlock(chan);
05729       }
05730       if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) {
05731          /*
05732           * Use the oh values instead of the function parameters for the
05733           * outgoing CallerID.
05734           */
05735          cid_num = oh->cid_num;
05736          cid_name = oh->cid_name;
05737       }
05738       if (oh->parent_channel) {
05739          /* Safely inherit variables and datastores from the parent channel. */
05740          ast_channel_lock_both(oh->parent_channel, chan);
05741          ast_channel_inherit_variables(oh->parent_channel, chan);
05742          ast_channel_datastore_inherit(oh->parent_channel, chan);
05743          ast_channel_unlock(oh->parent_channel);
05744          ast_channel_unlock(chan);
05745       }
05746       if (!ast_strlen_zero(oh->account)) {
05747          ast_channel_lock(chan);
05748          ast_channel_stage_snapshot(chan);
05749          ast_channel_accountcode_set(chan, oh->account);
05750          ast_channel_peeraccount_set(chan, oh->account);
05751          ast_channel_stage_snapshot_done(chan);
05752          ast_channel_unlock(chan);
05753       }
05754    }
05755 
05756    /*
05757     * I seems strange to set the CallerID on an outgoing call leg
05758     * to whom we are calling, but this function's callers are doing
05759     * various Originate methods.  This call leg goes to the local
05760     * user.  Once the local user answers, the dialplan needs to be
05761     * able to access the CallerID from the CALLERID function as if
05762     * the local user had placed this call.
05763     */
05764    ast_set_callerid(chan, cid_num, cid_name, cid_num);
05765 
05766    ast_set_flag(ast_channel_flags(chan), AST_FLAG_ORIGINATED);
05767    ast_party_connected_line_set_init(&connected, ast_channel_connected(chan));
05768    if (cid_num) {
05769       connected.id.number.valid = 1;
05770       connected.id.number.str = (char *) cid_num;
05771       connected.id.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
05772    }
05773    if (cid_name) {
05774       connected.id.name.valid = 1;
05775       connected.id.name.str = (char *) cid_name;
05776       connected.id.name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
05777    }
05778    ast_channel_set_connected_line(chan, &connected, NULL);
05779    if (requestor) {
05780       ast_channel_lock_both(chan, (struct ast_channel *) requestor);
05781       ast_channel_req_accountcodes(chan, requestor, AST_CHANNEL_REQUESTOR_BRIDGE_PEER);
05782       ast_channel_unlock(chan);
05783       ast_channel_unlock((struct ast_channel *) requestor);
05784    }
05785 
05786    if (ast_call(chan, addr, 0)) {   /* ast_call failed... */
05787       ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, addr);
05788    } else {
05789       struct timeval start = ast_tvnow();
05790       res = 1; /* mark success in case chan->_state is already AST_STATE_UP */
05791       while (timeout && ast_channel_state(chan) != AST_STATE_UP) {
05792          struct ast_frame *f;
05793          int ms = ast_remaining_ms(start, timeout);
05794 
05795          res = ast_waitfor(chan, ms);
05796          if (res == 0) { /* timeout, treat it like ringing */
05797             *outstate = AST_CONTROL_RINGING;
05798             break;
05799          }
05800          if (res < 0) /* error or done */
05801             break;
05802          if (!ast_strlen_zero(ast_channel_call_forward(chan))) {
05803             if (!(chan = ast_call_forward(NULL, chan, NULL, cap, oh, outstate))) {
05804                return NULL;
05805             }
05806             continue;
05807          }
05808 
05809          f = ast_read(chan);
05810          if (!f) {
05811             *outstate = AST_CONTROL_HANGUP;
05812             res = 0;
05813             break;
05814          }
05815          if (f->frametype == AST_FRAME_CONTROL) {
05816             switch (f->subclass.integer) {
05817             case AST_CONTROL_RINGING:  /* record but keep going */
05818                *outstate = f->subclass.integer;
05819                break;
05820 
05821             case AST_CONTROL_BUSY:
05822                *outstate = f->subclass.integer;
05823                timeout = 0;
05824                break;
05825 
05826             case AST_CONTROL_INCOMPLETE:
05827                *outstate = AST_CONTROL_CONGESTION;
05828                timeout = 0;
05829                break;
05830 
05831             case AST_CONTROL_CONGESTION:
05832                *outstate = f->subclass.integer;
05833                timeout = 0;
05834                break;
05835 
05836             case AST_CONTROL_ANSWER:
05837                *outstate = f->subclass.integer;
05838                timeout = 0;      /* trick to force exit from the while() */
05839                break;
05840 
05841             case AST_CONTROL_PVT_CAUSE_CODE:
05842                ast_channel_hangupcause_hash_set(chan, f->data.ptr, f->datalen);
05843                break;
05844 
05845             case AST_CONTROL_PROGRESS:
05846                if (oh && oh->connect_on_early_media) {
05847                   *outstate = f->subclass.integer;
05848                   timeout = 0;      /* trick to force exit from the while() */
05849                   break;
05850                }
05851                /* Fallthrough */
05852             /* Ignore these */
05853             case AST_CONTROL_PROCEEDING:
05854             case AST_CONTROL_HOLD:
05855             case AST_CONTROL_UNHOLD:
05856             case AST_CONTROL_VIDUPDATE:
05857             case AST_CONTROL_SRCUPDATE:
05858             case AST_CONTROL_SRCCHANGE:
05859             case AST_CONTROL_CONNECTED_LINE:
05860             case AST_CONTROL_REDIRECTING:
05861             case AST_CONTROL_CC:
05862             case -1:       /* Ignore -- just stopping indications */
05863                break;
05864 
05865             default:
05866                ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass.integer);
05867             }
05868             last_subclass = f->subclass.integer;
05869          }
05870          ast_frfree(f);
05871       }
05872    }
05873 
05874    /* Final fixups */
05875    if (oh) {
05876       if (!ast_strlen_zero(oh->context))
05877          ast_channel_context_set(chan, oh->context);
05878       if (!ast_strlen_zero(oh->exten))
05879          ast_channel_exten_set(chan, oh->exten);
05880       if (oh->priority)
05881          ast_channel_priority_set(chan, oh->priority);
05882    }
05883    if (ast_channel_state(chan) == AST_STATE_UP)
05884       *outstate = AST_CONTROL_ANSWER;
05885 
05886    if (res <= 0) {
05887       ast_channel_lock(chan);
05888       if (AST_CONTROL_RINGING == last_subclass) {
05889          ast_channel_hangupcause_set(chan, AST_CAUSE_NO_ANSWER);
05890       }
05891       ast_channel_unlock(chan);
05892       ast_hangup(chan);
05893       chan = NULL;
05894    }
05895    return chan;
05896 }

static void __fini_backends ( void   )  [static]

Definition at line 127 of file channel.c.

00142 {

static void __fini_channelvars ( void   )  [static]

Definition at line 7598 of file channel.c.

07601 {

static void __init_backends ( void   )  [static]

Definition at line 127 of file channel.c.

00142 {

static void __init_channelvars ( void   )  [static]

Definition at line 7598 of file channel.c.

07601 {

static void __init_state2str_threadbuf ( void   )  [static]

Definition at line 107 of file channel.c.

00121 {

static void adjust_frame_for_plc ( struct ast_channel chan,
struct ast_frame frame,
struct ast_datastore datastore 
) [static]

Definition at line 4895 of file channel.c.

References ast_calloc, ast_channel_datastore_remove(), ast_datastore_free(), ast_free, AST_FRIENDLY_OFFSET, ast_frame::data, ast_datastore::data, ast_frame::datalen, plc_ds::num_samples, ast_frame::offset, plc_fillin(), plc_rx(), plc_ds::plc_state, ast_frame::ptr, ast_frame::samples, and plc_ds::samples_buf.

Referenced by apply_plc().

04896 {
04897    int num_new_samples = frame->samples;
04898    struct plc_ds *plc = datastore->data;
04899 
04900    /* As a general note, let me explain the somewhat odd calculations used when taking
04901     * the frame offset into account here. According to documentation in frame.h, the frame's
04902     * offset field indicates the number of bytes that the audio is offset. The plc->samples_buf
04903     * is not an array of bytes, but rather an array of 16-bit integers since it holds SLIN
04904     * samples. So I had two choices to make here with the offset.
04905     *
04906     * 1. Make the offset AST_FRIENDLY_OFFSET bytes. The main downside for this is that
04907     *    I can't just add AST_FRIENDLY_OFFSET to the plc->samples_buf and have the pointer
04908     *    arithmetic come out right. I would have to do some odd casting or division for this to
04909     *    work as I wanted.
04910     * 2. Make the offset AST_FRIENDLY_OFFSET * 2 bytes. This allows the pointer arithmetic
04911     *    to work out better with the plc->samples_buf. The downside here is that the buffer's
04912     *    allocation contains an extra 64 bytes of unused space.
04913     *
04914     * I decided to go with option 2. This is why in the calloc statement and the statement that
04915     * sets the frame's offset, AST_FRIENDLY_OFFSET is multiplied by 2.
04916     */
04917 
04918    /* If this audio frame has no samples to fill in, ignore it */
04919    if (!num_new_samples) {
04920       return;
04921    }
04922 
04923    /* First, we need to be sure that our buffer is large enough to accomodate
04924     * the samples we need to fill in. This will likely only occur on the first
04925     * frame we write.
04926     */
04927    if (plc->num_samples < num_new_samples) {
04928       ast_free(plc->samples_buf);
04929       plc->samples_buf = ast_calloc(1, (num_new_samples * sizeof(*plc->samples_buf)) + (AST_FRIENDLY_OFFSET * 2));
04930       if (!plc->samples_buf) {
04931          ast_channel_datastore_remove(chan, datastore);
04932          ast_datastore_free(datastore);
04933          return;
04934       }
04935       plc->num_samples = num_new_samples;
04936    }
04937 
04938    if (frame->datalen == 0) {
04939       plc_fillin(&plc->plc_state, plc->samples_buf + AST_FRIENDLY_OFFSET, frame->samples);
04940       frame->data.ptr = plc->samples_buf + AST_FRIENDLY_OFFSET;
04941       frame->datalen = num_new_samples * 2;
04942       frame->offset = AST_FRIENDLY_OFFSET * 2;
04943    } else {
04944       plc_rx(&plc->plc_state, frame->data.ptr, frame->samples);
04945    }
04946 }

static void apply_plc ( struct ast_channel chan,
struct ast_frame frame 
) [static]

Definition at line 4948 of file channel.c.

References adjust_frame_for_plc(), ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_datastore_alloc, ast_datastore_free(), ast_datastore::data, and NULL.

Referenced by ast_write().

04949 {
04950    struct ast_datastore *datastore;
04951    struct plc_ds *plc;
04952 
04953    datastore = ast_channel_datastore_find(chan, &plc_ds_info, NULL);
04954    if (datastore) {
04955       plc = datastore->data;
04956       adjust_frame_for_plc(chan, frame, datastore);
04957       return;
04958    }
04959 
04960    datastore = ast_datastore_alloc(&plc_ds_info, NULL);
04961    if (!datastore) {
04962       return;
04963    }
04964    plc = ast_calloc(1, sizeof(*plc));
04965    if (!plc) {
04966       ast_datastore_free(datastore);
04967       return;
04968    }
04969    datastore->data = plc;
04970    ast_channel_datastore_add(chan, datastore);
04971    adjust_frame_for_plc(chan, frame, datastore);
04972 }

int ast_activate_generator ( struct ast_channel chan,
struct ast_generator gen,
void *  params 
)

Activate a given generator

Definition at line 2950 of file channel.c.

References ast_generator::alloc, ast_channel_generator(), ast_channel_generator_set(), ast_channel_generatordata(), ast_channel_generatordata_set(), ast_channel_lock, ast_channel_unlock, ast_prod(), ast_settimeout(), generator_force(), ast_channel::generatordata, NULL, and ast_generator::release.

Referenced by app_exec(), ast_channel_start_silence_generator(), ast_linear_stream(), ast_playtones_start(), ast_tonepair_start(), channel_spy(), eivr_comm(), local_ast_moh_start(), old_milliwatt_exec(), spandsp_fax_gateway_start(), and transmit_audio().

02951 {
02952    int res = 0;
02953    void *generatordata = NULL;
02954 
02955    ast_channel_lock(chan);
02956    if (ast_channel_generatordata(chan)) {
02957       struct ast_generator *generator_old = ast_channel_generator(chan);
02958 
02959       if (generator_old && generator_old->release) {
02960          generator_old->release(chan, ast_channel_generatordata(chan));
02961       }
02962    }
02963    if (gen->alloc && !(generatordata = gen->alloc(chan, params))) {
02964       res = -1;
02965    }
02966    ast_channel_generatordata_set(chan, generatordata);
02967    if (!res) {
02968       ast_settimeout(chan, 50, generator_force, chan);
02969       ast_channel_generator_set(chan, gen);
02970    }
02971    ast_channel_unlock(chan);
02972 
02973    ast_prod(chan);
02974 
02975    return res;
02976 }

int ast_active_channels ( void   ) 

returns number of active/allocated channels

Returns:
number of channels available for lookup

Definition at line 513 of file channel.c.

References ao2_container_count(), and channels.

Referenced by action_corestatus(), ast_var_channels(), ast_var_channels_table(), dahdi_restart(), handle_chanlist(), handle_show_settings(), and really_quit().

00514 {
00515    return channels ? ao2_container_count(channels) : 0;
00516 }

int ast_answer ( struct ast_channel chan  ) 

Answer a channel.

Parameters:
chan channel to answer
This function answers a channel and handles all necessary call setup functions.

Note:
The channel passed does not need to be locked, but is locked by the function when needed.

This function will wait up to 500 milliseconds for media to arrive on the channel before returning to the caller, so that the caller can properly assume the channel is 'ready' for media flow.

Return values:
0 on success
non-zero on failure

Definition at line 2846 of file channel.c.

References __ast_answer().

Referenced by agent_login_exec(), agi_exec_full(), alarmreceiver_exec(), announce_request(), answer_trunk_chan(), app_exec(), ast_auto_answer(), ast_bridge_add_channel(), ast_do_pickup(), ast_pickup_call(), auth_exec(), background_detect_exec(), bridge_channel_handle_control(), bridge_parking_push(), bridgewait_exec(), common_exec(), conf_exec(), conf_start_record(), confbridge_exec(), count_exec(), dahdiras_exec(), dial_exec_full(), dictate_exec(), directory_exec(), disa_exec(), eivr_comm(), handle_answer(), ices_exec(), local_call(), media_request_helper(), minivm_accmess_exec(), minivm_greet_exec(), minivm_record_exec(), old_milliwatt_exec(), park_app_exec(), parked_call_app_exec(), pbx_builtin_background(), playback_exec(), privacy_exec(), read_exec(), readexten_exec(), receivefax_exec(), record_exec(), sayunixtime_exec(), send_waveform_to_channel(), sendfax_exec(), setup_privacy_args(), skel_exec(), sla_station_exec(), speech_background(), testclient_exec(), testserver_exec(), transmit(), vm_exec(), vm_execmain(), vm_playmsgexec(), waitfor_exec(), and zapateller_exec().

02847 {
02848    return __ast_answer(chan, 0);
02849 }

int ast_auto_answer ( struct ast_channel chan  )  [inline]

Answer a channel, if it's not already answered.

Parameters:
chan channel to answer
See ast_answer()

Return values:
0 on success
non-zero on failure

Definition at line 2851 of file channel.c.

References ast_answer(), and AST_STATE_UP.

Referenced by record_file().

02852 {
02853    if (ast_channel_state(chan) == AST_STATE_UP) {
02854       /* Already answered */
02855       return 0;
02856    }
02857    return ast_answer(chan);
02858 }

int ast_call ( struct ast_channel chan,
const char *  addr,
int  timeout 
)

Make a call.

Note:
Absolutely _NO_ channel locks should be held before calling this function.
Parameters:
chan which channel to make the call on
addr destination of the call
timeout time to wait on for connect (Doesn't seem to be used.)
Place a call, take no longer than timeout ms.
Return values:
0 on success
-1 on failure

Definition at line 6145 of file channel.c.

References ast_channel_flags(), ast_channel_lock, ast_channel_tech(), ast_channel_unlock, ast_check_hangup(), AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, ast_set_flag, ast_test_flag, ast_channel_tech::call, and call().

Referenced by __ast_request_and_dial(), ast_call_forward(), attended_transfer_bridge(), begin_dial_channel(), blind_transfer_bridge(), dial_exec_full(), do_forward(), feature_attended_transfer(), findmeexec(), park_local_transfer(), retransfer_enter(), ring_entry(), and wait_for_answer().

06146 {
06147    /* Place an outgoing call, but don't wait any longer than timeout ms before returning.
06148       If the remote end does not answer within the timeout, then do NOT hang up, but
06149       return anyway.  */
06150    int res = -1;
06151    /* Stop if we're a zombie or need a soft hangup */
06152    ast_channel_lock(chan);
06153    if (!ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
06154       if (ast_channel_tech(chan)->call)
06155          res = ast_channel_tech(chan)->call(chan, addr, timeout);
06156       ast_set_flag(ast_channel_flags(chan), AST_FLAG_OUTGOING);
06157    }
06158    ast_channel_unlock(chan);
06159    return res;
06160 }

struct ast_channel* ast_call_forward ( struct ast_channel caller,
struct ast_channel orig,
int *  timeout,
struct ast_format_cap cap,
struct outgoing_helper oh,
int *  outstate 
) [read]

Forwards a call to a new channel specified by the original channel's call_forward str. If possible, the new forwarded channel is created and returned while the original one is terminated.

Parameters:
caller in channel that requested orig
orig channel being replaced by the call forward channel
timeout maximum amount of time to wait for setup of new forward channel
cap format capabilities for requested channel
oh outgoing helper used with original channel
outstate reason why unsuccessful (if uncuccessful)
Returns:
Returns the forwarded call's ast_channel on success or NULL on failure

Definition at line 5628 of file channel.c.

References outgoing_helper::account, ast_call(), ast_channel_call_forward(), ast_channel_connected(), ast_channel_context(), ast_channel_flags(), ast_channel_lock, ast_channel_lock_both, ast_channel_redirecting(), ast_channel_req_accountcodes(), AST_CHANNEL_REQUESTOR_REPLACEMENT, ast_channel_stage_snapshot(), ast_channel_stage_snapshot_done(), ast_channel_unlock, ast_copy_string(), AST_FLAG_ORIGINATED, ast_hangup(), ast_log, ast_party_connected_line_copy(), ast_party_redirecting_copy(), ast_request(), ast_set_flag, ast_set_variables(), ast_strlen_zero, call_forward_inherit(), handle_cause(), LOG_NOTICE, NULL, outgoing_helper::parent_channel, pbx_builtin_getvar_helper(), S_OR, type, and outgoing_helper::vars.

Referenced by __ast_request_and_dial().

05629 {
05630    char tmpchan[256];
05631    struct ast_channel *new_chan = NULL;
05632    char *data, *type;
05633    int cause = 0;
05634    int res;
05635 
05636    /* gather data and request the new forward channel */
05637    ast_copy_string(tmpchan, ast_channel_call_forward(orig), sizeof(tmpchan));
05638    if ((data = strchr(tmpchan, '/'))) {
05639       *data++ = '\0';
05640       type = tmpchan;
05641    } else {
05642       const char *forward_context;
05643       ast_channel_lock(orig);
05644       forward_context = pbx_builtin_getvar_helper(orig, "FORWARD_CONTEXT");
05645       snprintf(tmpchan, sizeof(tmpchan), "%s@%s", ast_channel_call_forward(orig), S_OR(forward_context, ast_channel_context(orig)));
05646       ast_channel_unlock(orig);
05647       data = tmpchan;
05648       type = "Local";
05649    }
05650    if (!(new_chan = ast_request(type, cap, NULL, orig, data, &cause))) {
05651       ast_log(LOG_NOTICE, "Unable to create channel for call forward to '%s/%s' (cause = %d)\n", type, data, cause);
05652       handle_cause(cause, outstate);
05653       ast_hangup(orig);
05654       return NULL;
05655    }
05656 
05657    /* Copy/inherit important information into new channel */
05658    if (oh) {
05659       if (oh->vars) {
05660          ast_channel_lock(new_chan);
05661          ast_set_variables(new_chan, oh->vars);
05662          ast_channel_unlock(new_chan);
05663       }
05664       if (oh->parent_channel) {
05665          call_forward_inherit(new_chan, oh->parent_channel, orig);
05666       }
05667       if (!ast_strlen_zero(oh->account)) {
05668          ast_channel_lock(new_chan);
05669          ast_channel_stage_snapshot(new_chan);
05670          ast_channel_accountcode_set(new_chan, oh->account);
05671          ast_channel_peeraccount_set(new_chan, oh->account);
05672          ast_channel_stage_snapshot_done(new_chan);
05673          ast_channel_unlock(new_chan);
05674       }
05675    } else if (caller) { /* no outgoing helper so use caller if available */
05676       call_forward_inherit(new_chan, caller, orig);
05677    }
05678    ast_set_flag(ast_channel_flags(new_chan), AST_FLAG_ORIGINATED);
05679 
05680    ast_channel_lock_both(orig, new_chan);
05681    ast_party_connected_line_copy(ast_channel_connected(new_chan), ast_channel_connected(orig));
05682    ast_party_redirecting_copy(ast_channel_redirecting(new_chan), ast_channel_redirecting(orig));
05683    ast_channel_req_accountcodes(new_chan, orig, AST_CHANNEL_REQUESTOR_REPLACEMENT);
05684    ast_channel_unlock(new_chan);
05685    ast_channel_unlock(orig);
05686 
05687    /* call new channel */
05688    res = ast_call(new_chan, data, 0);
05689    if (timeout) {
05690       *timeout = res;
05691    }
05692    if (res) {
05693       ast_log(LOG_NOTICE, "Unable to call forward to channel %s/%s\n", type, (char *)data);
05694       ast_hangup(orig);
05695       ast_hangup(new_chan);
05696       return NULL;
05697    }
05698    ast_hangup(orig);
05699 
05700    return new_chan;
05701 }

const char* ast_cause2str ( int  cause  ) 

Gives the string form of a given hangup cause.

Gives the string form of a given cause code.

Definition at line 638 of file channel.c.

References ARRAY_LEN, causes, and causes_map::desc.

Referenced by __transmit_response(), ast_channel_data_add_structure(), bridge_dissolve(), channel_destroyed_event(), channel_state_change(), dial_exec_full(), findmeexec(), hangupcause_read(), sip_hangup(), and transmit_request_with_auth().

00639 {
00640    int x;
00641 
00642    for (x = 0; x < ARRAY_LEN(causes); x++) {
00643       if (causes[x].cause == cause)
00644          return causes[x].desc;
00645    }
00646 
00647    return "Unknown";
00648 }

void ast_change_name ( struct ast_channel chan,
const char *  newname 
)

Change channel name.

Precondition:
Absolutely all channels _MUST_ be unlocked before calling this function.
Parameters:
chan the channel to change the name of
newname the name to change to
Returns:
nothing
Note:
this function must _NEVER_ be used when any channels are locked regardless if it is the channel who's name is being changed or not because it invalidates our channel container locking order... lock container first, then the individual channels, never the other way around.

Definition at line 6413 of file channel.c.

References __ast_change_name_nolink(), ao2_link, ao2_lock, ao2_unlink, ao2_unlock, ast_channel_lock, ast_channel_unlock, and channels.

Referenced by update_name().

06414 {
06415    /* We must re-link, as the hash value will change here. */
06416    ao2_lock(channels);
06417    ast_channel_lock(chan);
06418    ao2_unlink(channels, chan);
06419    __ast_change_name_nolink(chan, newname);
06420    ao2_link(channels, chan);
06421    ast_channel_unlock(chan);
06422    ao2_unlock(channels);
06423 }

const char* ast_channel_amaflags2string ( enum ama_flags  flags  ) 

Convert the enum representation of an AMA flag to a string representation.

Since:
12
Parameters:
flags integer flag
Return values:
A string representation of the flag

Definition at line 4382 of file channel.c.

References AST_AMA_BILLING, AST_AMA_DOCUMENTATION, and AST_AMA_OMIT.

Referenced by _sip_show_peer(), _skinny_show_line(), ast_cdr_format_var(), ast_channel_data_add_structure(), build_csv_record(), build_radius_record(), cdr_read_callback(), handle_cli_ooh323_show_config(), handle_cli_ooh323_show_peer(), handle_cli_ooh323_show_user(), manager_log(), peers_data_provider_get(), sip_show_user(), tds_log(), and users_data_provider_get().

04383 {
04384    switch (flag) {
04385    case AST_AMA_OMIT:
04386       return "OMIT";
04387    case AST_AMA_BILLING:
04388       return "BILLING";
04389    case AST_AMA_DOCUMENTATION:
04390       return "DOCUMENTATION";
04391    default:
04392       return "Unknown";
04393    }
04394 }

struct ast_channel* ast_channel_bridge_peer ( struct ast_channel chan  )  [read]

Get the channel's bridge peer only if the bridge is two-party.

Since:
12.0.0
Parameters:
chan Channel desiring the bridge peer channel.
Note:
The returned peer channel is the current peer in the bridge when called.

Absolutely _NO_ channel locks should be held when calling this function.

Return values:
NULL Channel not in a bridge or the bridge is not two-party.
non-NULL Reffed peer channel at time of calling.

Definition at line 10367 of file channel.c.

References ao2_ref, ast_bridge_peer(), ast_channel_get_bridge(), ast_channel_lock, ast_channel_unlock, and NULL.

Referenced by _skinny_show_lines(), analog_ss_thread(), ast_channel_data_add_structure(), ast_rtp_instance_set_stats_vars(), ast_set_hangupsource(), ast_unreal_queryoption(), ast_var_channels_table(), attach_barge(), cb_events(), channel_do_masquerade(), create_jb(), export_aoc_vars(), fax_detect_framehook(), fax_gateway_framehook(), func_channel_read(), get_refer_info(), handle_incoming_request(), handle_request_bye(), manager_park(), mgcp_hangup(), my_get_sigpvt_bridged_channel(), and spandsp_fax_gateway_start().

10368 {
10369    struct ast_channel *peer;
10370    struct ast_bridge *bridge;
10371 
10372    /* Get the bridge the channel is in. */
10373    ast_channel_lock(chan);
10374    bridge = ast_channel_get_bridge(chan);
10375    ast_channel_unlock(chan);
10376    if (!bridge) {
10377       return NULL;
10378    }
10379 
10380    peer = ast_bridge_peer(bridge, chan);
10381    ao2_ref(bridge, -1);
10382    return peer;
10383 }

static int ast_channel_by_exten_cb ( void *  obj,
void *  arg,
void *  data,
int  flags 
) [static]

Definition at line 1294 of file channel.c.

References ast_channel_context(), ast_channel_exten(), ast_channel_lock, ast_channel_macrocontext(), ast_channel_macroexten(), ast_channel_unlock, ast_log, ast_strlen_zero, CMP_MATCH, CMP_STOP, context, exten, and LOG_ERROR.

Referenced by ast_channel_get_by_exten(), and ast_channel_iterator_by_exten_new().

01295 {
01296    struct ast_channel *chan = obj;
01297    char *context = arg;
01298    char *exten = data;
01299    int ret = CMP_MATCH;
01300 
01301    if (ast_strlen_zero(exten) || ast_strlen_zero(context)) {
01302       ast_log(LOG_ERROR, "BUG! Must have a context and extension to match!\n");
01303       return CMP_STOP;
01304    }
01305 
01306    ast_channel_lock(chan);
01307    if (strcasecmp(ast_channel_context(chan), context) && strcasecmp(ast_channel_macrocontext(chan), context)) {
01308       ret = 0; /* Context match failed, continue */
01309    } else if (strcasecmp(ast_channel_exten(chan), exten) && strcasecmp(ast_channel_macroexten(chan), exten)) {
01310       ret = 0; /* Extension match failed, continue */
01311    }
01312    ast_channel_unlock(chan);
01313 
01314    return ret;
01315 }

static int ast_channel_by_name_cb ( void *  obj,
void *  arg,
void *  data,
int  flags 
) [static]

Definition at line 1272 of file channel.c.

References ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_log, ast_strlen_zero, CMP_MATCH, CMP_STOP, LOG_ERROR, and name.

Referenced by ast_channel_get_by_name_prefix(), and ast_channel_iterator_by_name_new().

01273 {
01274    struct ast_channel *chan = obj;
01275    const char *name = arg;
01276    size_t name_len = *(size_t *) data;
01277    int ret = CMP_MATCH;
01278 
01279    if (ast_strlen_zero(name)) {
01280       ast_log(LOG_ERROR, "BUG! Must supply a channel name or partial name to match!\n");
01281       return CMP_STOP;
01282    }
01283 
01284    ast_channel_lock(chan);
01285    if ((!name_len && strcasecmp(ast_channel_name(chan), name))
01286       || (name_len && strncasecmp(ast_channel_name(chan), name, name_len))) {
01287       ret = 0; /* name match failed, keep looking */
01288    }
01289    ast_channel_unlock(chan);
01290 
01291    return ret;
01292 }

static int ast_channel_by_uniqueid_cb ( void *  obj,
void *  arg,
void *  data,
int  flags 
) [static]

Definition at line 1317 of file channel.c.

References ast_channel_lock, ast_channel_uniqueid(), ast_channel_unlock, ast_log, ast_strlen_zero, CMP_MATCH, CMP_STOP, LOG_ERROR, and ast_channel::uniqueid.

Referenced by ast_channel_get_by_name_prefix().

01318 {
01319    struct ast_channel *chan = obj;
01320    char *uniqueid = arg;
01321    size_t id_len = *(size_t *) data;
01322    int ret = CMP_MATCH;
01323 
01324    if (ast_strlen_zero(uniqueid)) {
01325       ast_log(LOG_ERROR, "BUG! Must supply a uniqueid or partial uniqueid to match!\n");
01326       return CMP_STOP;
01327    }
01328 
01329    ast_channel_lock(chan);
01330    if ((!id_len && strcasecmp(ast_channel_uniqueid(chan), uniqueid))
01331       || (id_len && strncasecmp(ast_channel_uniqueid(chan), uniqueid, id_len))) {
01332       ret = 0; /* uniqueid match failed, keep looking */
01333    }
01334    ast_channel_unlock(chan);
01335 
01336    return ret;
01337 }

struct ast_channel* ast_channel_callback ( ao2_callback_data_fn cb_fn,
void *  arg,
void *  data,
int  ao2_flags 
) [read]

Call a function with every active channel.

This function executes a callback one time for each active channel on the system. The channel is provided as an argument to the function.

Note:
Absolutely _NO_ channel locks should be held before calling this function.
Since:
1.8

Definition at line 1266 of file channel.c.

References ao2_callback_data, and channels.

Referenced by ast_channel_get_by_exten(), ast_channel_get_by_name_prefix(), ast_channel_iterator_by_exten_new(), ast_channel_iterator_by_name_new(), ast_pickup_find_by_group(), find_by_channel(), find_by_part(), handle_core_set_debug_channel(), and pickup_by_mark().

01268 {
01269    return ao2_callback_data(channels, ao2_flags, cb_fn, arg, data);
01270 }

int ast_channel_cc_params_init ( struct ast_channel chan,
const struct ast_cc_config_params base_params 
)

Set up datastore with CCSS parameters for a channel.

Since:
1.8
Note:
If base_params is NULL, the channel will get the default values for all CCSS parameters.
This function makes use of datastore operations on the channel, so it is important to lock the channel before calling this function.

Parameters:
chan The channel to create the datastore on
base_params CCSS parameters we wish to copy into the channel
Return values:
0 Success
-1 Failure

Definition at line 10254 of file channel.c.

References ast_cc_config_params_destroy(), ast_cc_config_params_init, ast_cc_copy_config_params(), ast_channel_datastore_add(), ast_datastore_alloc, ast_datastore::data, and NULL.

Referenced by ast_channel_get_cc_config_params(), ast_unreal_call_setup(), ast_unreal_new_channels(), dahdi_new(), and sip_new().

10256 {
10257    struct ast_cc_config_params *cc_params;
10258    struct ast_datastore *cc_datastore;
10259 
10260    if (!(cc_params = ast_cc_config_params_init())) {
10261       return -1;
10262    }
10263 
10264    if (!(cc_datastore = ast_datastore_alloc(&cc_channel_datastore_info, NULL))) {
10265       ast_cc_config_params_destroy(cc_params);
10266       return -1;
10267    }
10268 
10269    if (base_params) {
10270       ast_cc_copy_config_params(cc_params, base_params);
10271    }
10272    cc_datastore->data = cc_params;
10273    ast_channel_datastore_add(chan, cc_datastore);
10274    return 0;
10275 }

void ast_channel_clear_softhangup ( struct ast_channel chan,
int  flag 
)

Clear a set of softhangup flags from a channel.

Never clear a softhangup flag from a channel directly. Instead, use this function. This ensures that all aspects of the softhangup process are aborted.

Parameters:
chan the channel to clear the flag on
flag the flag or flags to clear
Returns:
Nothing.

Definition at line 2505 of file channel.c.

References ast_channel_lock, ast_channel_readq(), ast_channel_softhangup_internal_flag(), ast_channel_softhangup_internal_flag_clear(), ast_channel_unlock, AST_CONTROL_END_OF_Q, AST_FRAME_CONTROL, ast_frfree, AST_LIST_LAST, AST_LIST_REMOVE, ast_frame::frametype, ast_frame_subclass::integer, and ast_frame::subclass.

Referenced by __ast_pbx_run(), ast_bridge_setup_after_goto(), chan_cleanup(), collect_digits(), gosub_run(), and stasis_app_exec().

02506 {
02507    ast_channel_lock(chan);
02508 
02509    ast_channel_softhangup_internal_flag_clear(chan, flag);
02510 
02511    if (!ast_channel_softhangup_internal_flag(chan)) {
02512       struct ast_frame *fr;
02513 
02514       /* If we have completely cleared the softhangup flag,
02515        * then we need to fully abort the hangup process.  This requires
02516        * pulling the END_OF_Q frame out of the channel frame queue if it
02517        * still happens to be there. */
02518 
02519       fr = AST_LIST_LAST(ast_channel_readq(chan));
02520       if (fr && fr->frametype == AST_FRAME_CONTROL &&
02521             fr->subclass.integer == AST_CONTROL_END_OF_Q) {
02522          AST_LIST_REMOVE(ast_channel_readq(chan), fr, frame_list);
02523          ast_frfree(fr);
02524       }
02525    }
02526 
02527    ast_channel_unlock(chan);
02528 }

static int ast_channel_cmp_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 1416 of file channel.c.

References ast_log, CMP_STOP, and LOG_ERROR.

01417 {
01418    ast_log(LOG_ERROR, "BUG! Should never be called!\n");
01419    return CMP_STOP;
01420 }

int ast_channel_cmpwhentohangup ( struct ast_channel chan,
time_t  offset 
)

Compare a offset with the settings of when to hang a channel up.

Parameters:
chan channel on which to check for hang up
offset offset in seconds from current time
Returns:
1, 0, or -1
This function compares a offset from current time with the absolute time out on a channel (when to hang up). If the absolute time out on a channel is earlier than current time plus the offset, it returns 1, if the two time values are equal, it return 0, otherwise, it return -1.
See also:
ast_channel_cmpwhentohangup_tv()
Version:
1.6.1 deprecated function (only had seconds precision)

Definition at line 558 of file channel.c.

References ast_channel_cmpwhentohangup_tv().

00559 {
00560    struct timeval when = { offset, };
00561    return ast_channel_cmpwhentohangup_tv(chan, when);
00562 }

int ast_channel_cmpwhentohangup_tv ( struct ast_channel chan,
struct timeval  offset 
)

Compare a offset with when to hangup channel.

Compare a offset with the settings of when to hang a channel up.

Definition at line 543 of file channel.c.

References ast_channel_whentohangup(), ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), and ast_tvzero().

Referenced by ast_channel_cmpwhentohangup().

00544 {
00545    struct timeval whentohangup;
00546 
00547    if (ast_tvzero(*ast_channel_whentohangup(chan)))
00548       return ast_tvzero(offset) ? 0 : -1;
00549 
00550    if (ast_tvzero(offset))
00551       return 1;
00552 
00553    whentohangup = ast_tvadd(offset, ast_tvnow());
00554 
00555    return ast_tvdiff_ms(whentohangup, *ast_channel_whentohangup(chan));
00556 }

int ast_channel_connected_line_macro ( struct ast_channel autoservice_chan,
struct ast_channel macro_chan,
const void *  connected_info,
int  is_caller,
int  frame 
)

Run a connected line interception macro and update a channel's connected line information.

Since:
1.8
Deprecated:
You should use the ast_channel_connected_line_sub() function instead.
Whenever we want to update a channel's connected line information, we may need to run a macro so that an administrator can manipulate the information before sending it out. This function both runs the macro and sends the update to the channel.

Parameters:
autoservice_chan Channel to place into autoservice while the macro is running. It is perfectly safe for this to be NULL
macro_chan The channel to run the macro on. Also the channel from which we determine which macro we need to run.
connected_info Either an ast_party_connected_line or ast_frame pointer of type AST_CONTROL_CONNECTED_LINE
is_caller If true, then run CONNECTED_LINE_CALLER_SEND_MACRO with arguments from CONNECTED_LINE_CALLER_SEND_MACRO_ARGS, otherwise run CONNECTED_LINE_CALLEE_SEND_MACRO with arguments from CONNECTED_LINE_CALLEE_SEND_MACRO_ARGS
frame If true, then connected_info is an ast_frame pointer, otherwise it is an ast_party_connected_line pointer.
Return values:
0 Success
-1 Either the macro does not exist, or there was an error while attempting to run the macro
Todo:
Have multiple return codes based on the MACRO_RESULT
Todo:
Make constants so that caller and frame can be more expressive than just '1' and '0'

Definition at line 10045 of file channel.c.

References ast_app_run_macro(), ast_channel_connected(), ast_channel_lock, ast_channel_unlock, ast_channel_update_connected_line(), ast_connected_line_parse_data(), ast_log, ast_party_connected_line_copy(), ast_party_connected_line_free(), ast_party_connected_line_init(), ast_strdupa, ast_strlen_zero, chanlist::connected, ast_frame::data, ast_frame::datalen, LOG_WARNING, NULL, pbx_builtin_getvar_helper(), ast_frame::ptr, retval, and S_OR.

Referenced by __ast_read(), app_exec(), ast_do_pickup(), bridge_channel_handle_control(), handle_frame(), and wait_for_answer().

10046 {
10047    static int deprecation_warning = 0;
10048    const char *macro;
10049    const char *macro_args;
10050    int retval;
10051 
10052    ast_channel_lock(macro_chan);
10053    macro = pbx_builtin_getvar_helper(macro_chan, is_caller
10054       ? "CONNECTED_LINE_CALLER_SEND_MACRO" : "CONNECTED_LINE_CALLEE_SEND_MACRO");
10055    macro = ast_strdupa(S_OR(macro, ""));
10056    macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller
10057       ? "CONNECTED_LINE_CALLER_SEND_MACRO_ARGS" : "CONNECTED_LINE_CALLEE_SEND_MACRO_ARGS");
10058    macro_args = ast_strdupa(S_OR(macro_args, ""));
10059 
10060    if (ast_strlen_zero(macro)) {
10061       ast_channel_unlock(macro_chan);
10062       return -1;
10063    }
10064 
10065    if (!deprecation_warning) {
10066       deprecation_warning = 1;
10067       ast_log(LOG_WARNING, "Usage of CONNECTED_LINE_CALLE[ER]_SEND_MACRO is deprecated.  Please use CONNECTED_LINE_SEND_SUB instead.\n");
10068    }
10069    if (is_frame) {
10070       const struct ast_frame *frame = connected_info;
10071 
10072       ast_connected_line_parse_data(frame->data.ptr, frame->datalen, ast_channel_connected(macro_chan));
10073    } else {
10074       const struct ast_party_connected_line *connected = connected_info;
10075 
10076       ast_party_connected_line_copy(ast_channel_connected(macro_chan), connected);
10077    }
10078    ast_channel_unlock(macro_chan);
10079 
10080    retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args);
10081    if (!retval) {
10082       struct ast_party_connected_line saved_connected;
10083 
10084       ast_party_connected_line_init(&saved_connected);
10085       ast_channel_lock(macro_chan);
10086       ast_party_connected_line_copy(&saved_connected, ast_channel_connected(macro_chan));
10087       ast_channel_unlock(macro_chan);
10088       ast_channel_update_connected_line(macro_chan, &saved_connected, NULL);
10089       ast_party_connected_line_free(&saved_connected);
10090    }
10091 
10092    return retval;
10093 }

int ast_channel_connected_line_sub ( struct ast_channel autoservice_chan,
struct ast_channel sub_chan,
const void *  connected_info,
int  frame 
)

Run a connected line interception subroutine and update a channel's connected line information.

Since:
11 Whenever we want to update a channel's connected line information, we may need to run a subroutine so that an administrator can manipulate the information before sending it out. This function both runs the subroutine specified by CONNECTED_LINE_SEND_SUB and sends the update to the channel.
Parameters:
autoservice_chan Channel to place into autoservice while the sub is running. It is perfectly safe for this to be NULL
sub_chan The channel to run the subroutine on. Also the channel from which we determine which subroutine we need to run.
connected_info Either an ast_party_connected_line or ast_frame pointer of type AST_CONTROL_CONNECTED_LINE
frame If true, then connected_info is an ast_frame pointer, otherwise it is an ast_party_connected_line pointer.
Return values:
0 Success
-1 Either the subroutine does not exist, or there was an error while attempting to run the subroutine

Definition at line 10145 of file channel.c.

References ast_app_run_sub(), ast_channel_connected(), ast_channel_lock, ast_channel_unlock, ast_channel_update_connected_line(), ast_connected_line_parse_data(), ast_party_connected_line_copy(), ast_party_connected_line_free(), ast_party_connected_line_init(), ast_strdupa, ast_strlen_zero, chanlist::connected, ast_frame::data, ast_frame::datalen, NULL, pbx_builtin_getvar_helper(), ast_frame::ptr, retval, S_OR, and sub.

Referenced by __ast_read(), app_exec(), ast_do_pickup(), bridge_channel_handle_control(), handle_frame(), and wait_for_answer().

10146 {
10147    const char *sub;
10148    const char *sub_args;
10149    int retval;
10150 
10151    ast_channel_lock(sub_chan);
10152    sub = pbx_builtin_getvar_helper(sub_chan, "CONNECTED_LINE_SEND_SUB");
10153    sub = ast_strdupa(S_OR(sub, ""));
10154    sub_args = pbx_builtin_getvar_helper(sub_chan, "CONNECTED_LINE_SEND_SUB_ARGS");
10155    sub_args = ast_strdupa(S_OR(sub_args, ""));
10156 
10157    if (ast_strlen_zero(sub)) {
10158       ast_channel_unlock(sub_chan);
10159       return -1;
10160    }
10161 
10162    if (is_frame) {
10163       const struct ast_frame *frame = connected_info;
10164 
10165       ast_connected_line_parse_data(frame->data.ptr, frame->datalen, ast_channel_connected(sub_chan));
10166    } else {
10167       const struct ast_party_connected_line *connected = connected_info;
10168 
10169       ast_party_connected_line_copy(ast_channel_connected(sub_chan), connected);
10170    }
10171    ast_channel_unlock(sub_chan);
10172 
10173    retval = ast_app_run_sub(autoservice_chan, sub_chan, sub, sub_args, 0);
10174    if (!retval) {
10175       struct ast_party_connected_line saved_connected;
10176 
10177       ast_party_connected_line_init(&saved_connected);
10178       ast_channel_lock(sub_chan);
10179       ast_party_connected_line_copy(&saved_connected, ast_channel_connected(sub_chan));
10180       ast_channel_unlock(sub_chan);
10181       ast_channel_update_connected_line(sub_chan, &saved_connected, NULL);
10182       ast_party_connected_line_free(&saved_connected);
10183    }
10184 
10185    return retval;
10186 }

int ast_channel_datastore_add ( struct ast_channel chan,
struct ast_datastore datastore 
)

Add a datastore to a channel.

Note:
The channel should be locked before calling this function.
Return values:
0 success
non-zero failure

Definition at line 2386 of file channel.c.

References ast_channel_datastores(), and AST_LIST_INSERT_HEAD.

Referenced by __after_bridge_set_goto(), _macro_exec(), acf_curlopt_write(), acf_iaxvar_write(), acf_odbc_read(), add_features_datastore(), add_masquerade_store(), add_to_agi(), after_bridge_cb_setup(), apply_plc(), ast_cel_fabricate_channel_from_event(), ast_channel_cc_params_init(), ast_channel_suppress(), ast_do_pickup(), ast_iax2_new(), ast_jb_create_framehook(), ast_setup_cc_recall_datastore(), audiohook_volume_get(), authenticate_reply(), bridge_features_ds_set_full(), calendar_query_exec(), cc_interfaces_datastore_init(), chan_cleanup(), channel_feature_hooks_set_full(), command_prestart_queue_command(), create_msg_q_chan(), create_parked_subscription_full(), dial_exec_full(), dial_masquerade_datastore_add(), do_notify(), dundi_query_read(), enable_jack_hook(), enum_query_read(), find_or_create_details(), find_transaction(), frame_trace_helper(), func_channel_write_real(), func_confbridge_helper(), get_feature_ds(), get_lock(), get_replace_channel_store(), gosub_exec(), init_hook(), lua_get_state(), msg_datastore_find_or_create(), MYSQL_exec(), pitchshift_helper(), raise_exception(), set_internal_datastore(), set_talk_detect(), setup_bridge_roles_datastore(), setup_mixmonitor_ds(), setup_park_common_datastore(), shared_write(), smdi_msg_retrieve_read(), socket_process_helper(), speech_create(), speex_write(), srv_datastore_setup(), stasis_app_channel_set_stasis_end_published(), t38_attach_framehook(), try_calling(), and volume_write().

02387 {
02388    int res = 0;
02389 
02390    AST_LIST_INSERT_HEAD(ast_channel_datastores(chan), datastore, entry);
02391 
02392    return res;
02393 }

struct ast_datastore* ast_channel_datastore_alloc ( const struct ast_datastore_info info,
const char *  uid 
) [read]

Create a channel data store object.

Note:
None of the datastore API calls lock the ast_channel they are using. So, the channel should be locked before calling the functions that take a channel argument.
Deprecated:
You should use the ast_datastore_alloc() generic function instead.
Version:
1.6.1 deprecated

Definition at line 2359 of file channel.c.

References ast_datastore_alloc.

02360 {
02361    return ast_datastore_alloc(info, uid);
02362 }

struct ast_datastore* ast_channel_datastore_find ( struct ast_channel chan,
const struct ast_datastore_info info,
const char *  uid 
) [read]

Find a datastore on a channel.

Note:
The channel should be locked before calling this function.

The datastore returned from this function must not be used if the reference to the channel is released.

Return values:
pointer to the datastore if found
NULL if not found

Definition at line 2400 of file channel.c.

References ast_channel_datastores(), AST_LIST_TRAVERSE, ast_datastore::info, NULL, and ast_datastore::uid.

Referenced by _macro_exec(), acf_curl_helper(), acf_curlopt_helper(), acf_curlopt_write(), acf_exception_read(), acf_fetch(), acf_iaxvar_read(), acf_iaxvar_write(), acf_odbc_read(), add_agi_cmd(), add_features_datastore(), add_masquerade_store(), add_to_agi(), after_bridge_cb_find(), after_bridge_cb_setup(), after_bridge_goto_remove(), apply_plc(), ast_bridge_features_ds_get(), ast_bridge_read_after_goto(), ast_can_pickup(), ast_cc_agent_set_interfaces_chanvar(), ast_cc_call_init(), ast_cc_completed(), ast_cc_extension_monitor_add_dialstring(), ast_cc_get_current_core_id(), ast_cc_is_recall(), ast_cc_offer(), ast_channel_feature_hooks_get(), ast_channel_get_cc_config_params(), ast_channel_suppress(), ast_channel_unsuppress(), ast_handle_cc_control_frame(), ast_ignore_cc(), ast_jb_create_framehook(), ast_odbc_retrieve_transaction_obj(), ast_set_cc_interfaces_chanvar(), audiohook_volume_callback(), audiohook_volume_get(), balance_stack(), bridge_features_ds_set_full(), calendar_event_read(), calendar_query_exec(), calendar_query_result_exec(), cc_build_payload(), chan_cleanup(), channel_feature_hooks_set_full(), clear_dialed_interfaces(), command_prestart_get_container(), command_prestart_queue_command(), conf_find_bridge_profile(), conf_find_user_profile(), conf_set_menu_to_user(), dial_exec_full(), dial_masquerade_datastore_find(), dialplan_handle_msg_cb(), disable_jack_hook(), dundi_result_read(), enable_jack_hook(), enum_result_read(), exec_odbcfinish(), fetch_bridge_roles_datastore(), find_details(), find_speech(), find_transaction(), fixup_callback(), frame_trace_helper(), func_channel_read(), func_channel_write_real(), func_confbridge_helper(), func_mixmonitor_read(), get_agi_cmd(), get_feature_chan_ds(), get_feature_ds(), get_lock(), get_park_common_datastore_copy(), get_replace_channel_store(), gosub_exec(), gosub_run(), handle_gosub(), has_masquerade_store(), hook_off(), hook_re_enable(), iax2_call(), jack_hook_callback(), local_read(), local_write(), lock_fixup(), lua_get_state(), mark_transaction_active(), msg_data_func_read(), msg_datastore_find_or_create(), msg_func_read(), msg_send_exec(), MYSQL_exec(), pitchshift_cb(), pitchshift_helper(), pop_exec(), raise_exception(), release_transaction(), remove_masquerade_store(), remove_stasis_end_published(), remove_talk_detect(), return_exec(), set_internal_datastore(), set_security_requirements(), set_talk_detect(), shared_read(), shared_write(), smdi_msg_read(), speech_datastore_destroy(), speex_callback(), speex_read(), speex_write(), srv_query_read(), srv_result_read(), stackpeek_read(), stasis_app_channel_is_internal(), stasis_app_channel_is_stasis_end_published(), stop_mixmonitor_full(), t38_attach_framehook(), talk_detect_audiohook_cb(), try_calling(), unlock_read(), volume_callback(), volume_write(), wipe_park_common_datastore(), and wipe_subscription_datastore().

02401 {
02402    struct ast_datastore *datastore = NULL;
02403 
02404    if (info == NULL)
02405       return NULL;
02406 
02407    AST_LIST_TRAVERSE(ast_channel_datastores(chan), datastore, entry) {
02408       if (datastore->info != info) {
02409          continue;
02410       }
02411 
02412       if (uid == NULL) {
02413          /* matched by type only */
02414          break;
02415       }
02416 
02417       if ((datastore->uid != NULL) && !strcasecmp(uid, datastore->uid)) {
02418          /* Matched by type AND uid */
02419          break;
02420       }
02421    }
02422 
02423    return datastore;
02424 }

int ast_channel_datastore_free ( struct ast_datastore datastore  ) 

Free a channel data store object.

Deprecated:
You should use the ast_datastore_free() generic function instead.
Version:
1.6.1 deprecated

Definition at line 2364 of file channel.c.

References ast_datastore_free().

02365 {
02366    return ast_datastore_free(datastore);
02367 }

int ast_channel_datastore_inherit ( struct ast_channel from,
struct ast_channel to 
)

Inherit datastores from a parent to a child.

Definition at line 2369 of file channel.c.

References ast_channel_datastores(), ast_datastore_alloc, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_datastore::data, DATASTORE_INHERIT_FOREVER, ast_datastore_info::duplicate, ast_datastore::info, ast_datastore::inheritance, NULL, and ast_datastore::uid.

Referenced by __ast_request_and_dial(), ast_unreal_call_setup(), begin_dial_prerun(), call_forward_inherit(), common_recall_channel_setup(), copy_caller_data(), dial_exec_full(), do_forward(), findmeexec(), park_local_transfer(), ring_entry(), and wait_for_answer().

02370 {
02371    struct ast_datastore *datastore = NULL, *datastore2;
02372 
02373    AST_LIST_TRAVERSE(ast_channel_datastores(from), datastore, entry) {
02374       if (datastore->inheritance > 0) {
02375          datastore2 = ast_datastore_alloc(datastore->info, datastore->uid);
02376          if (datastore2) {
02377             datastore2->data = datastore->info->duplicate ? datastore->info->duplicate(datastore->data) : NULL;
02378             datastore2->inheritance = datastore->inheritance == DATASTORE_INHERIT_FOREVER ? DATASTORE_INHERIT_FOREVER : datastore->inheritance - 1;
02379             AST_LIST_INSERT_TAIL(ast_channel_datastores(to), datastore2, entry);
02380          }
02381       }
02382    }
02383    return 0;
02384 }

int ast_channel_datastore_remove ( struct ast_channel chan,
struct ast_datastore datastore 
)

int ast_channel_defer_dtmf ( struct ast_channel chan  ) 

Set defer DTMF flag on channel.

Defers DTMF so that you only read things like hangups and audio.

Definition at line 1248 of file channel.c.

References ast_channel_flags(), AST_FLAG_DEFER_DTMF, ast_set_flag, and ast_test_flag.

Referenced by __adsi_transmit_messages(), and find_cache().

01249 {
01250    int pre = 0;
01251 
01252    if (chan) {
01253       pre = ast_test_flag(ast_channel_flags(chan), AST_FLAG_DEFER_DTMF);
01254       ast_set_flag(ast_channel_flags(chan), AST_FLAG_DEFER_DTMF);
01255    }
01256    return pre;
01257 }

static void ast_channel_destructor ( void *  obj  )  [static]

Free a channel structure.

Definition at line 2168 of file channel.c.

References ast_app_group_discard(), ast_assert, ast_atomic_fetchadd_int(), ast_cdr_free(), ast_channel_caller(), ast_channel_callid(), ast_channel_callid_cleanup(), ast_channel_cdr(), ast_channel_cdr_set(), ast_channel_connected(), ast_channel_connected_indicated(), ast_channel_datastores(), ast_channel_dialed(), ast_channel_epfd(), ast_channel_flags(), ast_channel_internal_alertpipe_close(), ast_channel_internal_cleanup(), ast_channel_internal_is_finalized(), ast_channel_lock, ast_channel_monitor(), ast_channel_music_state(), ast_channel_name(), AST_CHANNEL_NAME, ast_channel_named_callgroups_set(), ast_channel_named_pickupgroups_set(), ast_channel_nativeformats_set(), ast_channel_pbx(), ast_channel_publish_snapshot(), ast_channel_readq(), ast_channel_readtrans(), ast_channel_redirecting(), ast_channel_sched(), ast_channel_set_oldwriteformat(), ast_channel_set_rawreadformat(), ast_channel_set_rawwriteformat(), ast_channel_set_readformat(), ast_channel_set_writeformat(), ast_channel_tech_pvt(), ast_channel_timer(), ast_channel_timer_set(), ast_channel_unlock, ast_channel_varshead(), ast_channel_writetrans(), ast_channel_zone(), ast_channel_zone_set(), ast_copy_string(), ast_datastore_free(), AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed_literal(), AST_DEVSTATE_NOT_CACHABLE, AST_FLAG_DEAD, AST_FLAG_DISABLE_DEVSTATE_CACHE, AST_FLAG_SNAPSHOT_STAGE, ast_free, ast_frfree, ast_jb_destroy(), AST_LIST_REMOVE_HEAD, ast_log_callid(), AST_MAX_FDS, ast_moh_cleanup(), ast_party_caller_free(), ast_party_connected_line_free(), ast_party_dialed_free(), ast_party_redirecting_free(), ast_pbx_hangup_handler_destroy(), ast_sched_context_destroy(), ast_set_flag, ast_test_flag, ast_timer_close(), ast_tone_zone_unref(), ast_translator_free_path(), ast_var_delete(), LOG_WARNING, NULL, publish_cache_clear(), and ast_channel_monitor::stop.

Referenced by __ast_channel_alloc_ap().

02169 {
02170    struct ast_channel *chan = obj;
02171 #ifdef HAVE_EPOLL
02172    int i;
02173 #endif
02174    struct ast_var_t *vardata;
02175    struct ast_frame *f;
02176    struct varshead *headp;
02177    struct ast_datastore *datastore;
02178    char device_name[AST_CHANNEL_NAME];
02179    ast_callid callid;
02180 
02181    /* Stop monitoring */
02182    if (ast_channel_monitor(chan)) {
02183       ast_channel_monitor(chan)->stop(chan, 0);
02184    }
02185 
02186    /* If there is native format music-on-hold state, free it */
02187    if (ast_channel_music_state(chan)) {
02188       ast_moh_cleanup(chan);
02189    }
02190 
02191    ast_pbx_hangup_handler_destroy(chan);
02192 
02193    /* Things that may possibly raise Stasis messages shouldn't occur after this point */
02194    ast_set_flag(ast_channel_flags(chan), AST_FLAG_DEAD);
02195 
02196    if (ast_channel_internal_is_finalized(chan)) {
02197       /* A channel snapshot should not be in the process of being staged now. */
02198       ast_assert(!ast_test_flag(ast_channel_flags(chan), AST_FLAG_SNAPSHOT_STAGE));
02199 
02200       ast_channel_lock(chan);
02201       ast_channel_publish_snapshot(chan);
02202       ast_channel_unlock(chan);
02203       publish_cache_clear(chan);
02204    }
02205 
02206    ast_channel_lock(chan);
02207 
02208    /* Get rid of each of the data stores on the channel */
02209    while ((datastore = AST_LIST_REMOVE_HEAD(ast_channel_datastores(chan), entry)))
02210       /* Free the data store */
02211       ast_datastore_free(datastore);
02212 
02213    /* While the channel is locked, take the reference to its callid while we tear down the call. */
02214    callid = ast_channel_callid(chan);
02215    ast_channel_callid_cleanup(chan);
02216 
02217    ast_channel_unlock(chan);
02218 
02219    /* Lock and unlock the channel just to be sure nobody has it locked still
02220       due to a reference that was stored in a datastore. (i.e. app_chanspy) */
02221    ast_channel_lock(chan);
02222    ast_channel_unlock(chan);
02223 
02224    if (ast_channel_tech_pvt(chan)) {
02225       ast_log_callid(LOG_WARNING, callid, "Channel '%s' may not have been hung up properly\n", ast_channel_name(chan));
02226       ast_free(ast_channel_tech_pvt(chan));
02227    }
02228 
02229    if (ast_channel_sched(chan)) {
02230       ast_sched_context_destroy(ast_channel_sched(chan));
02231    }
02232 
02233    if (ast_channel_internal_is_finalized(chan)) {
02234       char *dashptr;
02235 
02236       ast_copy_string(device_name, ast_channel_name(chan), sizeof(device_name));
02237       if ((dashptr = strrchr(device_name, '-'))) {
02238          *dashptr = '\0';
02239       }
02240    } else {
02241       device_name[0] = '\0';
02242    }
02243 
02244    /* Free translators */
02245    if (ast_channel_readtrans(chan))
02246       ast_translator_free_path(ast_channel_readtrans(chan));
02247    if (ast_channel_writetrans(chan))
02248       ast_translator_free_path(ast_channel_writetrans(chan));
02249    if (ast_channel_pbx(chan))
02250       ast_log_callid(LOG_WARNING, callid, "PBX may not have been terminated properly on '%s'\n", ast_channel_name(chan));
02251 
02252    /* Free formats */
02253    ast_channel_set_oldwriteformat(chan, NULL);
02254    ast_channel_set_rawreadformat(chan, NULL);
02255    ast_channel_set_rawwriteformat(chan, NULL);
02256    ast_channel_set_readformat(chan, NULL);
02257    ast_channel_set_writeformat(chan, NULL);
02258 
02259    ast_party_dialed_free(ast_channel_dialed(chan));
02260    ast_party_caller_free(ast_channel_caller(chan));
02261    ast_party_connected_line_free(ast_channel_connected(chan));
02262    ast_party_connected_line_free(ast_channel_connected_indicated(chan));
02263    ast_party_redirecting_free(ast_channel_redirecting(chan));
02264 
02265    /* Close pipes if appropriate */
02266    ast_channel_internal_alertpipe_close(chan);
02267    if (ast_channel_timer(chan)) {
02268       ast_timer_close(ast_channel_timer(chan));
02269       ast_channel_timer_set(chan, NULL);
02270    }
02271 #ifdef HAVE_EPOLL
02272    for (i = 0; i < AST_MAX_FDS; i++) {
02273       if (ast_channel_internal_epfd_data(chan, i)) {
02274          ast_free(ast_channel_internal_epfd_data(chan, i));
02275       }
02276    }
02277    close(ast_channel_epfd(chan));
02278 #endif
02279    while ((f = AST_LIST_REMOVE_HEAD(ast_channel_readq(chan), frame_list)))
02280       ast_frfree(f);
02281 
02282    /* loop over the variables list, freeing all data and deleting list items */
02283    /* no need to lock the list, as the channel is already locked */
02284    headp = ast_channel_varshead(chan);
02285    while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
02286       ast_var_delete(vardata);
02287 
02288    ast_app_group_discard(chan);
02289 
02290    /* Destroy the jitterbuffer */
02291    ast_jb_destroy(chan);
02292 
02293    if (ast_channel_cdr(chan)) {
02294       ast_cdr_free(ast_channel_cdr(chan));
02295       ast_channel_cdr_set(chan, NULL);
02296    }
02297 
02298    if (ast_channel_zone(chan)) {
02299       ast_channel_zone_set(chan, ast_tone_zone_unref(ast_channel_zone(chan)));
02300    }
02301 
02302    ast_channel_internal_cleanup(chan);
02303 
02304    if (device_name[0]) {
02305       /*
02306        * We have a device name to notify of a new state.
02307        *
02308        * Queue an unknown state, because, while we know that this particular
02309        * instance is dead, we don't know the state of all other possible
02310        * instances.
02311        */
02312       ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, (ast_test_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_DEVSTATE_CACHE) ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), device_name);
02313    }
02314 
02315    ast_channel_nativeformats_set(chan, NULL);
02316 
02317    ast_channel_named_callgroups_set(chan, NULL);
02318    ast_channel_named_pickupgroups_set(chan, NULL);
02319 
02320    ast_atomic_fetchadd_int(&chancount, -1);
02321 }

int ast_channel_early_bridge ( struct ast_channel c0,
struct ast_channel c1 
)

Bridge two channels together (early).

Parameters:
c0 first channel to bridge
c1 second channel to bridge
Bridge two channels (c0 and c1) together early. This implies either side may not be answered yet.
Returns:
Returns 0 on success and -1 if it could not be done

Definition at line 7047 of file channel.c.

References ast_channel_tech(), and ast_channel_tech::early_bridge.

Referenced by dial_exec_full(), and wait_for_answer().

07048 {
07049    /* Make sure we can early bridge, if not error out */
07050    if (!ast_channel_tech(c0)->early_bridge || (c1 && (!ast_channel_tech(c1)->early_bridge || ast_channel_tech(c0)->early_bridge != ast_channel_tech(c1)->early_bridge)))
07051       return -1;
07052 
07053    return ast_channel_tech(c0)->early_bridge(c0, c1);
07054 }

void ast_channel_end_dtmf ( struct ast_channel chan,
char  digit,
struct timeval  start,
const char *  why 
)

Simulate a DTMF end on a broken bridge channel.

Parameters:
chan Channel sending DTMF that has not ended.
digit DTMF digit to stop.
start DTMF digit start time.
why Reason bridge broken.
Returns:
Nothing

Definition at line 10651 of file channel.c.

References ast_channel_flags(), ast_channel_lock, ast_channel_name(), ast_channel_softhangup_internal_flag(), ast_channel_unlock, AST_FLAG_ZOMBIE, ast_log, ast_senddigit_end(), AST_SOFTHANGUP_ASYNCGOTO, ast_test_flag, ast_tvdiff_ms(), ast_tvnow(), LOG_DTMF, and option_dtmfminduration.

Referenced by bridge_channel_internal_join(), and channel_do_masquerade().

10652 {
10653    int dead;
10654    long duration;
10655 
10656    ast_channel_lock(chan);
10657    dead = ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE)
10658       || (ast_channel_softhangup_internal_flag(chan)
10659          & ~AST_SOFTHANGUP_ASYNCGOTO);
10660    ast_channel_unlock(chan);
10661    if (dead) {
10662       /* Channel is a zombie or a real hangup. */
10663       return;
10664    }
10665 
10666    duration = ast_tvdiff_ms(ast_tvnow(), start);
10667    if (duration < option_dtmfminduration) {
10668       duration = option_dtmfminduration;
10669    }
10670    ast_senddigit_end(chan, digit, duration);
10671    ast_log(LOG_DTMF, "DTMF end '%c' simulated on %s due to %s, duration %ld ms\n",
10672       digit, ast_channel_name(chan), why, duration);
10673 }

int ast_channel_feature_hooks_append ( struct ast_channel chan,
struct ast_bridge_features features 
)

Appends to the channel-attached features a channel has access to upon being bridged.

Note:
The channel must be locked when calling this function.
Parameters:
chan Which channel to set features for
features The feature set to append to the channel's features
Return values:
0 on success
-1 on failure

Definition at line 10733 of file channel.c.

References channel_feature_hooks_set_full().

Referenced by AST_TEST_DEFINE().

10734 {
10735    return channel_feature_hooks_set_full(chan, features, 0);
10736 }

struct ast_bridge_features* ast_channel_feature_hooks_get ( struct ast_channel chan  )  [read]

Gets the channel-attached features a channel has access to upon being bridged.

Note:
The channel must be locked when calling this function.
Parameters:
chan Which channel to get features for
Return values:
non-NULL The features currently set for this channel
NULL if the features have not been set

Definition at line 10685 of file channel.c.

References ast_channel_datastore_find(), ast_datastore::data, and NULL.

Referenced by bridge_channel_internal_join().

10686 {
10687    struct ast_datastore *datastore;
10688 
10689    datastore = ast_channel_datastore_find(chan, &bridge_features_info, NULL);
10690    if (!datastore) {
10691       return NULL;
10692    }
10693    return datastore->data;
10694 }

int ast_channel_feature_hooks_replace ( struct ast_channel chan,
struct ast_bridge_features features 
)

Sets the channel-attached features a channel has access to upon being bridged.

Note:
The channel must be locked when calling this function.
Parameters:
chan Which channel to set features for
features The feature set with which to replace the channel's features
Return values:
0 on success
-1 on failure

Definition at line 10738 of file channel.c.

References channel_feature_hooks_set_full().

10739 {
10740    return channel_feature_hooks_set_full(chan, features, 1);
10741 }

struct ast_bridge* ast_channel_get_bridge ( const struct ast_channel chan  )  [read]

Get the bridge associated with a channel.

Since:
12.0.0
Parameters:
chan The channel whose bridge we want
The bridge returned has its reference count incremented. Use ao2_cleanup() or ao2_ref() in order to decrement the reference count when you are finished with the bridge.

Note:
This function expects the channel to be locked prior to being called and will not grab the channel lock.
Return values:
NULL No bridge present on the channel
non-NULL The bridge the channel is in

Definition at line 10337 of file channel.c.

References ao2_ref, and ast_channel_internal_bridge().

Referenced by acquire_bridge(), ast_bridge_add_channel(), ast_channel_bridge_peer(), ast_channel_snapshot_create(), generate_status(), get_transfer_parties(), handle_invite_replaces(), handle_showchan(), invite_replaces(), manager_bridge_kick(), native_rtp_framehook(), and serialize_showchan().

10338 {
10339    struct ast_bridge *bridge;
10340 
10341    bridge = ast_channel_internal_bridge(chan);
10342    if (bridge) {
10343       ao2_ref(bridge, +1);
10344    }
10345    return bridge;
10346 }

struct ast_bridge_channel* ast_channel_get_bridge_channel ( struct ast_channel chan  )  [read]

Get a reference to the channel's bridge pointer.

Since:
12.0.0
Parameters:
chan The channel whose bridge channel is desired
Note:
This increases the reference count of the bridge_channel. Use ao2_ref() or ao2_cleanup() to decrement the refcount when you are finished with it.

It is expected that the channel is locked prior to placing this call.

Return values:
NULL The channel has no bridge_channel
non-NULL A reference to the bridge_channel

Definition at line 10385 of file channel.c.

References ao2_ref, and ast_channel_internal_bridge_channel().

Referenced by __analog_ss_thread(), agent_bridge_channel_get_lock(), analog_ss_thread(), ast_bridge_add_channel(), ast_bridge_notify_masquerade(), ast_bridge_transfer_attended(), ast_bridge_transfer_blind(), bridge_after_cb(), bridge_channel_internal_queue_attended_transfer(), bridge_channel_internal_queue_blind_transfer(), bridge_move(), handle_soft_key_event_message(), handle_stimulus_message(), hold(), manager_park_bridged(), mgcp_ss(), parker_parked_call_message_response(), play_sound(), recall_pull(), ringing(), transfer_pull(), try_parking(), and unhold().

10386 {
10387    struct ast_bridge_channel *bridge_channel;
10388 
10389    bridge_channel = ast_channel_internal_bridge_channel(chan);
10390    if (bridge_channel) {
10391       ao2_ref(bridge_channel, +1);
10392    }
10393    return bridge_channel;
10394 }

struct ast_channel* ast_channel_get_by_exten ( const char *  exten,
const char *  context 
) [read]

Find a channel by extension and context.

Parameters:
exten the extension to search for
context the context to search for
Return a channel that is currently at the specified extension and context.

Return values:
a channel that is at the specified extension and context
NULL if no channel was found
Since:
1.8

Definition at line 1447 of file channel.c.

References ast_channel_by_exten_cb(), and ast_channel_callback().

01448 {
01449    char *l_exten = (char *) exten;
01450    char *l_context = (char *) context;
01451 
01452    return ast_channel_callback(ast_channel_by_exten_cb, l_context, l_exten, 0);
01453 }

struct ast_channel* ast_channel_get_by_name ( const char *  name  )  [read]

Find a channel by name.

Channel search functions

Parameters:
name the name or uniqueid of the channel to search for
Find a channel that has the same name as the provided argument.

Return values:
a channel with the name specified by the argument
NULL if no channel was found
Since:
1.8

Definition at line 1442 of file channel.c.

References ast_channel_get_by_name_prefix().

Referenced by action_add_agi_cmd(), action_aocmessage(), action_atxfer(), action_blind_transfer(), action_getvar(), action_hangup(), action_redirect(), action_sendtext(), action_setvar(), action_status(), action_timeout(), ari_channels_handle_originate_with_id(), ari_channels_handle_snoop_channel(), ast_ari_channels_get_channel_var(), ast_ari_channels_hangup(), ast_async_goto_by_name(), asyncgoto_exec(), bridge_channel_attended_transfer(), bridge_parking_push(), call_forwarded_handler(), change_monitor_action(), channel_find(), common_exec(), controlplayback_manager(), do_pause_or_unpause(), find_control(), func_mchan_read(), func_mchan_write(), handle_cli_agi_add_cmd(), handle_core_set_debug_channel(), handle_getvariablefull(), handle_hangup(), handle_redirect(), handle_set_chanvar(), handle_show_chanvar(), handle_show_hangup_channel(), handle_showchan(), handle_softhangup(), import_helper(), manager_bridge_kick(), manager_mixmonitor(), manager_mute_mixmonitor(), manager_mutestream(), manager_optimize_away(), manager_park(), manager_play_dtmf(), manager_stop_mixmonitor(), parker_parked_call_message_response(), parking_park_bridge_channel(), pbx_builtin_importvar(), refer_progress_bridge(), senddtmf_exec(), shared_read(), shared_write(), start_monitor_action(), stasis_app_bridge_moh_channel(), stasis_app_bridge_moh_stop(), stasis_app_bridge_playback_channel_find(), and stop_monitor_action().

01443 {
01444    return ast_channel_get_by_name_prefix(name, 0);
01445 }

struct ast_channel* ast_channel_get_by_name_prefix ( const char *  name,
size_t  name_len 
) [read]

Find a channel by a name prefix.

Parameters:
name The channel name or uniqueid prefix to search for
name_len Only search for up to this many characters from the name
Find a channel that has the same name prefix as specified by the arguments.

Return values:
a channel with the name prefix specified by the arguments
NULL if no channel was found
Since:
1.8

Definition at line 1422 of file channel.c.

References ast_channel_by_name_cb(), ast_channel_by_uniqueid_cb(), ast_channel_callback(), ast_strlen_zero, NULL, and OBJ_KEY.

Referenced by action_aocmessage(), action_bridge(), ast_channel_get_by_name(), ast_parse_device_state(), bridge_exec(), cc_generic_agent_stop_ringing(), common_exec(), handle_bridge_kick_channel(), handle_cli_mixmonitor(), shared_read(), and shared_write().

01423 {
01424    struct ast_channel *chan;
01425    char *l_name = (char *) name;
01426 
01427    chan = ast_channel_callback(ast_channel_by_name_cb, l_name, &name_len,
01428       (name_len == 0) /* optimize if it is a complete name match */ ? OBJ_KEY : 0);
01429    if (chan) {
01430       return chan;
01431    }
01432 
01433    if (ast_strlen_zero(l_name)) {
01434       /* We didn't have a name to search for so quit. */
01435       return NULL;
01436    }
01437 
01438    /* Now try a search for uniqueid. */
01439    return ast_channel_callback(ast_channel_by_uniqueid_cb, l_name, &name_len, 0);
01440 }

int ast_channel_get_cc_agent_type ( struct ast_channel chan,
char *  agent_type,
size_t  size 
)

Find the appropriate CC agent type to use given a channel.

Since:
1.8
During call completion, we will need to create a call completion agent structure. To figure out the type of agent to construct, we need to ask the channel driver for the appropriate type.

Prior to adding this function, the call completion core attempted to figure this out for itself by stripping the technology off the channel's name. However, in the case of chan_dahdi, there are multiple agent types registered, and so simply searching for an agent type called "DAHDI" is not possible. In a case where multiple agent types are defined, the channel driver must have a queryoption callback defined in its channel_tech, and the queryoption callback must handle AST_OPTION_CC_AGENT_TYPE

If a channel driver does not have a queryoption callback or if the queryoption callback does not handle AST_OPTION_CC_AGENT_TYPE, then the old behavior of using the technology portion of the channel name is used instead. This is perfectly suitable for channel drivers whose channel technologies are a one-to-one match with the agent types defined within.

Note that this function is only called when the agent policy on a given channel is set to "native." Generic agents' type can be determined automatically by the core.

Parameters:
chan The channel for which we wish to retrieve the agent type
[out] agent_type The type of agent the channel driver wants us to use
size The size of the buffer to write to

Definition at line 10316 of file channel.c.

References ast_channel_name(), ast_channel_queryoption(), ast_copy_string(), and AST_OPTION_CC_AGENT_TYPE.

Referenced by find_agent_callbacks().

10317 {
10318    int len = size;
10319    char *slash;
10320 
10321    if (!ast_channel_queryoption(chan, AST_OPTION_CC_AGENT_TYPE, agent_type, &len, 0)) {
10322       return 0;
10323    }
10324 
10325    ast_copy_string(agent_type, ast_channel_name(chan), size);
10326    if ((slash = strchr(agent_type, '/'))) {
10327       *slash = '\0';
10328    }
10329    return 0;
10330 }

struct ast_cc_config_params* ast_channel_get_cc_config_params ( struct ast_channel chan  )  [read]

Get the CCSS parameters from a channel.

Since:
1.8
This function makes use of datastore operations on the channel, so it is important to lock the channel before calling this function.

Parameters:
chan Channel to retrieve parameters from
Return values:
NULL Failure
non-NULL The parameters desired

Definition at line 10277 of file channel.c.

References ast_assert, ast_channel_cc_params_init(), ast_channel_datastore_find(), ast_datastore::data, and NULL.

Referenced by acf_cc_read(), acf_cc_write(), analog_call(), ast_cc_call_failed(), ast_cc_call_init(), ast_queue_cc_frame(), ast_unreal_call_setup(), ast_unreal_new_channels(), cc_agent_init(), cc_core_init_instance(), and find_agent_callbacks().

10278 {
10279    struct ast_datastore *cc_datastore;
10280 
10281    if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) {
10282       /* If we can't find the datastore, it almost definitely means that the channel type being
10283        * used has not had its driver modified to parse CC config parameters. The best action
10284        * to take here is to create the parameters on the spot with the defaults set.
10285        */
10286       if (ast_channel_cc_params_init(chan, NULL)) {
10287          return NULL;
10288       }
10289       if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) {
10290          /* Should be impossible */
10291          return NULL;
10292       }
10293    }
10294 
10295    ast_assert(cc_datastore->data != NULL);
10296    return cc_datastore->data;
10297 }

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.

Since:
1.8
A common practice in Asterisk is to determine the device being talked to by dissecting the channel name. For certain channel types, this is not accurate. For instance, an ISDN channel is named based on what B channel is used, not the device being communicated with.

This function interfaces with a channel tech's queryoption callback to retrieve the name of the device being communicated with. If the channel does not implement this specific option, then the traditional method of using the channel name is used instead.

Parameters:
chan The channel to retrieve the information from
[out] device_name The buffer to place the device's name into
name_buffer_length The allocated space for the device_name
Returns:
0 always

Definition at line 10299 of file channel.c.

References ast_channel_name(), ast_channel_queryoption(), ast_copy_string(), and AST_OPTION_DEVICE_NAME.

Referenced by ast_cc_call_failed(), ast_cc_is_recall(), ast_queue_cc_frame(), cc_core_init_instance(), cccancel_exec(), ccreq_exec(), chan_pjsip_indicate(), dial_exec_full(), sip_call(), and sip_handle_cc().

10300 {
10301    int len = name_buffer_length;
10302    char *dash;
10303    if (!ast_channel_queryoption(chan, AST_OPTION_DEVICE_NAME, device_name, &len, 0)) {
10304       return 0;
10305    }
10306 
10307    /* Dang. Do it the old-fashioned way */
10308    ast_copy_string(device_name, ast_channel_name(chan), name_buffer_length);
10309    if ((dash = strrchr(device_name, '-'))) {
10310       *dash = '\0';
10311    }
10312 
10313    return 0;
10314 }

int ast_channel_get_duration ( struct ast_channel chan  ) 

Obtain how long the channel since the channel was created.

Since:
12
Parameters:
chan The channel object
Return values:
0 if the time value cannot be computed (or you called this really fast)
The number of seconds the channel has been up

Definition at line 2860 of file channel.c.

References ast_assert, ast_channel_creationtime(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), and NULL.

Referenced by end_bridge_callback(), serialize_showchan(), and show_chanstats_cb().

02861 {
02862    ast_assert(NULL != chan);
02863 
02864    if (ast_tvzero(ast_channel_creationtime(chan))) {
02865       return 0;
02866    }
02867    return (ast_tvdiff_ms(ast_tvnow(), ast_channel_creationtime(chan)) / 1000);
02868 }

struct varshead* ast_channel_get_manager_vars ( struct ast_channel chan  )  [read]

Gets the variables for a given channel, as specified by ast_channel_set_manager_vars().

Since:
12 The returned variable list is an AO2 object, so ao2_cleanup() to free it.
Parameters:
chan Channel to get variables for.
Returns:
List of channel variables.

NULL on error

Definition at line 7681 of file channel.c.

References ao2_alloc, ao2_cleanup, ao2_ref, ast_free, ast_func_read2(), AST_LIST_EMPTY, AST_LIST_TRAVERSE, ast_log, AST_RWLIST_INSERT_TAIL, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_str_buffer(), ast_str_create(), ast_var_assign(), ast_var_t::entries, manager_channel_variable::isfunc, lock, LOG_ERROR, manager_channel_variable::name, NULL, pbx_builtin_getvar_helper(), RAII_VAR, SCOPED_LOCK, tmp(), var, and varshead_dtor().

Referenced by append_channel_vars(), and ast_channel_snapshot_create().

07682 {
07683    RAII_VAR(struct varshead *, ret, NULL, ao2_cleanup);
07684    RAII_VAR(struct ast_str *, tmp, NULL, ast_free);
07685    struct manager_channel_variable *mcv;
07686    SCOPED_LOCK(lock, &channelvars, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK);
07687 
07688    if (AST_LIST_EMPTY(&channelvars)) {
07689       return NULL;
07690    }
07691 
07692    ret = ao2_alloc(sizeof(*ret), varshead_dtor);
07693    tmp = ast_str_create(16);
07694 
07695    if (!ret || !tmp) {
07696       return NULL;
07697    }
07698 
07699    AST_LIST_TRAVERSE(&channelvars, mcv, entry) {
07700       const char *val = NULL;
07701       struct ast_var_t *var;
07702 
07703       if (mcv->isfunc) {
07704          if (ast_func_read2(chan, mcv->name, &tmp, 0) == 0) {
07705             val = ast_str_buffer(tmp);
07706          } else {
07707             ast_log(LOG_ERROR,
07708                "Error invoking function %s\n", mcv->name);
07709          }
07710       } else {
07711          val = pbx_builtin_getvar_helper(chan, mcv->name);
07712       }
07713 
07714       var = ast_var_assign(mcv->name, val ? val : "");
07715       if (!var) {
07716          return NULL;
07717       }
07718 
07719       AST_RWLIST_INSERT_TAIL(ret, var, entries);
07720    }
07721 
07722    ao2_ref(ret, +1);
07723    return ret;
07724 }

int ast_channel_get_up_time ( struct ast_channel chan  ) 

Obtain how long it has been since the channel was answered.

Since:
12
Parameters:
chan The channel object
Return values:
0 if the channel isn't answered (or you called this really fast)
The number of seconds the channel has been up

Definition at line 2870 of file channel.c.

References ast_assert, ast_channel_answertime(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), and NULL.

Referenced by action_confbridgelist_item(), and end_bridge_callback().

02871 {
02872    ast_assert(NULL != chan);
02873 
02874    if (ast_tvzero(ast_channel_answertime(chan))) {
02875       return 0;
02876    }
02877    return (ast_tvdiff_ms(ast_tvnow(), ast_channel_answertime(chan)) / 1000);
02878 }

struct varshead* ast_channel_get_vars ( struct ast_channel chan  )  [read]

Gets the variables for a given channel, as set using pbx_builtin_setvar_helper().

Since:
12 The returned variable list is an AO2 object, so ao2_cleanup() to free it.
Parameters:
chan Channel to get variables for
Returns:
List of channel variables.

NULL on error

Definition at line 7656 of file channel.c.

References ao2_alloc, ao2_cleanup, ao2_ref, ast_channel_varshead(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_var_assign(), ast_var_name(), ast_var_value(), ast_var_t::entries, NULL, RAII_VAR, var, and varshead_dtor().

07657 {
07658    RAII_VAR(struct varshead *, ret, NULL, ao2_cleanup);
07659    struct ast_var_t *cv;
07660 
07661    ret = ao2_alloc(sizeof(*ret), varshead_dtor);
07662 
07663    if (!ret) {
07664       return NULL;
07665    }
07666 
07667    AST_LIST_TRAVERSE(ast_channel_varshead(chan), cv, entries) {
07668       struct ast_var_t *var = ast_var_assign(ast_var_name(cv), ast_var_value(cv));
07669 
07670       if (!var) {
07671          return NULL;
07672       }
07673 
07674       AST_LIST_INSERT_TAIL(ret, var, entries);
07675    }
07676 
07677    ao2_ref(ret, +1);
07678    return ret;
07679 }

void ast_channel_hangupcause_hash_set ( struct ast_channel chan,
const struct ast_control_pvt_cause_code cause_code,
int  datalen 
)

Sets the HANGUPCAUSE hash and optionally the SIP_CAUSE hash on the given channel.

Parameters:
chan channel on which to set the cause information
cause_code ast_control_pvt_cause_code structure containing cause information
datalen total length of the structure since it may vary

Definition at line 4355 of file channel.c.

References ast_channel_dialed_causes_add(), ast_channel_name(), ast_func_write(), ast_log, ast_control_pvt_cause_code::chan_name, ast_control_pvt_cause_code::code, ast_control_pvt_cause_code::emulate_sip_cause, and LOG_WARNING.

Referenced by __analog_handle_event(), __ast_request_and_dial(), ast_indicate_data(), chan_pjsip_incoming_response(), handle_incoming(), jingle_action_session_terminate(), and socket_process_helper().

04356 {
04357    char causevar[256];
04358 
04359    if (ast_channel_dialed_causes_add(chan, cause_code, datalen)) {
04360       ast_log(LOG_WARNING, "Unable to store hangup cause for %s on %s\n", cause_code->chan_name, ast_channel_name(chan));
04361    }
04362 
04363    if (cause_code->emulate_sip_cause) {
04364       snprintf(causevar, sizeof(causevar), "HASH(SIP_CAUSE,%s)", cause_code->chan_name);
04365       ast_func_write(chan, causevar, cause_code->code);
04366    }
04367 }

int ast_channel_has_audio_frame_or_monitor ( struct ast_channel chan  ) 

Check if the channel has active audiohooks, active framehooks, or a monitor.

Since:
12.0.0
Parameters:
chan The channel to check.
Return values:
non-zero if channel has active audiohooks, framehooks, or monitor.

Definition at line 2591 of file channel.c.

References ast_audiohook_write_list_empty(), ast_channel_audiohooks(), ast_channel_framehooks(), ast_channel_monitor(), and ast_framehook_list_contains_no_active().

Referenced by native_bridge_is_capable(), optimize_lock_chan_stack(), and optimize_lock_peer_stack().

int ast_channel_has_hook_requiring_audio ( struct ast_channel chan  ) 

Check if the channel has any active hooks that require audio.

Since:
12.3.0
Parameters:
chan The channel to check.
Return values:
non-zero if channel has active audiohooks, audio framehooks, or monitor.

Definition at line 2598 of file channel.c.

References ast_audiohook_write_list_empty(), ast_channel_audiohooks(), ast_channel_framehooks(), ast_channel_monitor(), AST_FRAME_VOICE, and ast_framehook_list_contains_no_active_of_type().

Referenced by native_rtp_bridge_capable().

int ast_channel_has_manager_vars ( void   ) 

Return whether or not any manager variables have been set.

Since:
12.4.0
Return values:
0 if no manager variables are expected
1 if manager variables are expected

Definition at line 7610 of file channel.c.

References AST_LIST_EMPTY, AST_RWLIST_RDLOCK, and AST_RWLIST_UNLOCK.

Referenced by ast_channel_publish_varset().

07611 {
07612    int vars_present;
07613 
07614    AST_RWLIST_RDLOCK(&channelvars);
07615    vars_present = !AST_LIST_EMPTY(&channelvars);
07616    AST_RWLIST_UNLOCK(&channelvars);
07617 
07618    return vars_present;
07619 }

static int ast_channel_hash_cb ( const void *  obj,
const int  flags 
) [static]

Definition at line 7423 of file channel.c.

References ast_channel_name(), ast_str_case_hash(), ast_strlen_zero, name, and OBJ_KEY.

07424 {
07425    const char *name = (flags & OBJ_KEY) ? obj : ast_channel_name((struct ast_channel *) obj);
07426 
07427    /* If the name isn't set, return 0 so that the ao2_find() search will
07428     * start in the first bucket. */
07429    if (ast_strlen_zero(name)) {
07430       return 0;
07431    }
07432 
07433    return ast_str_case_hash(name);
07434 }

void ast_channel_inherit_variables ( const struct ast_channel parent,
struct ast_channel child 
)

Inherits channel variable from parent to child channel.

Parameters:
parent Parent channel
child Child channel
Scans all channel variables in the parent channel, looking for those that should be copied into the child channel. Variables whose names begin with a single '_' are copied into the child channel with the prefix removed. Variables whose names begin with '__' are copied into the child channel with their names unchanged.

Definition at line 6425 of file channel.c.

References ast_channel_name(), ast_channel_publish_varset(), ast_channel_varshead(), ast_debug, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_var_assign(), ast_var_full_name(), ast_var_value(), and ast_var_t::entries.

Referenced by __ast_request_and_dial(), begin_dial_prerun(), call_forward_inherit(), common_recall_channel_setup(), copy_caller_data(), dial_exec_full(), do_forward(), findmeexec(), park_local_transfer(), ring_entry(), and wait_for_answer().

06426 {
06427    struct ast_var_t *current;
06428    struct ast_var_t *newvar;
06429    const char *varname;
06430    int vartype;
06431 
06432    AST_LIST_TRAVERSE(ast_channel_varshead((struct ast_channel *) parent), current, entries) {
06433       varname = ast_var_full_name(current);
06434       if (!varname) {
06435          continue;
06436       }
06437 
06438       vartype = 0;
06439       if (varname[0] == '_') {
06440          vartype = 1;
06441          if (varname[1] == '_') {
06442             vartype = 2;
06443          }
06444       }
06445 
06446       switch (vartype) {
06447       case 1:
06448          newvar = ast_var_assign(&varname[1], ast_var_value(current));
06449          break;
06450       case 2:
06451          newvar = ast_var_assign(varname, ast_var_value(current));
06452          break;
06453       default:
06454          continue;
06455       }
06456       if (newvar) {
06457          ast_debug(1, "Inheriting variable %s from %s to %s.\n",
06458             ast_var_full_name(newvar), ast_channel_name(parent),
06459             ast_channel_name(child));
06460          AST_LIST_INSERT_TAIL(ast_channel_varshead(child), newvar, entries);
06461          ast_channel_publish_varset(child, ast_var_full_name(newvar),
06462             ast_var_value(newvar));
06463       }
06464    }
06465 }

int ast_channel_is_bridged ( const struct ast_channel chan  ) 

Determine if a channel is in a bridge.

Since:
12.0.0
Parameters:
chan The channel to test
Note:
This function expects the channel to be locked prior to being called and will not grab the channel lock.
Return values:
0 The channel is not bridged
non-zero The channel is bridged

Definition at line 10348 of file channel.c.

References ast_channel_internal_bridge(), and NULL.

Referenced by __ast_read(), action_redirect(), ast_async_goto(), ast_audiohook_attach(), ast_audiohook_remove(), ast_framehook_attach(), ast_framehook_detach(), ast_framehook_list_fixup(), ast_var_channel_bridge(), audio_audiohook_write_list(), chan_pjsip_set_rtp_peer(), common_exec(), console_transfer(), dtmf_audiohook_write_list(), mixmonitor_thread(), sip_set_rtp_peer(), stasis_app_exec(), wait_for_bridged(), and wait_for_unbridged().

10349 {
10350    return ast_channel_internal_bridge(chan) != NULL;
10351 }

int ast_channel_is_leaving_bridge ( struct ast_channel chan  ) 

Determine if a channel is leaving a bridge, but not hung up.

Since:
12.4.0
Parameters:
chan The channel to test
Note:
If a channel is hung up, it is implicitly leaving any bridge it may be in. This function is used to test if a channel is leaving a bridge but may survive the experience, if it has a place to go to (dialplan or otherwise)
Return values:
0 The channel is not leaving the bridge or is hung up
non-zero The channel is leaving the bridge

Definition at line 10353 of file channel.c.

References ast_channel_softhangup_internal_flag(), ast_channel_unbridged(), and AST_SOFTHANGUP_ASYNCGOTO.

Referenced by bridge_channel_internal_pull().

10354 {
10355    int hangup_flags = ast_channel_softhangup_internal_flag(chan);
10356    int hangup_test = hangup_flags & AST_SOFTHANGUP_ASYNCGOTO;
10357    int unbridge = ast_channel_unbridged(chan);
10358 
10359    /* This function should only return true if either the unbridged flag or
10360     * the ASYNCGOTO soft hangup flag is set and when no other soft hangup
10361     * flags are set. Any other soft hangup flags being set should make it
10362     * return false.
10363     */
10364    return ((hangup_test || unbridge) && (hangup_test == hangup_flags));
10365 }

struct ast_channel_iterator* ast_channel_iterator_all_new ( void   )  [read]

Create a new channel iterator.

After creating an iterator using this function, the ast_channel_iterator_next() function can be used to iterate through all channels that exist.

Note:
You must call ast_channel_iterator_destroy() when done.
Return values:
NULL on failure
a new channel iterator
Since:
1.8

Definition at line 1396 of file channel.c.

References ast_channel_iterator::active_iterator, ao2_iterator_init(), ast_calloc, channels, NULL, and ast_channel_iterator::simple_iterator.

Referenced by action_hangup(), action_status(), ast_var_channel_bridge(), ast_var_channel_types_table(), ast_var_channels_table(), common_exec(), data_channels_provider_handler(), func_channels_read(), handle_show_hangup_all(), and handle_softhangup().

01397 {
01398    struct ast_channel_iterator *i;
01399 
01400    if (!(i = ast_calloc(1, sizeof(*i)))) {
01401       return NULL;
01402    }
01403 
01404    i->simple_iterator = ao2_iterator_init(channels, 0);
01405    i->active_iterator = &i->simple_iterator;
01406 
01407    return i;
01408 }

struct ast_channel_iterator* ast_channel_iterator_by_exten_new ( const char *  exten,
const char *  context 
) [read]

Create a new channel iterator based on extension.

Parameters:
exten The extension that channels must be in
context The context that channels must be in
After creating an iterator using this function, the ast_channel_iterator_next() function can be used to iterate through all channels that are currently in the specified context and extension.

Note:
You must call ast_channel_iterator_destroy() when done.
Return values:
NULL on failure
a new channel iterator based on the specified parameters
Since:
1.8

Definition at line 1356 of file channel.c.

References ast_channel_iterator::active_iterator, ast_calloc, ast_channel_by_exten_cb(), ast_channel_callback(), ast_free, NULL, and OBJ_MULTIPLE.

Referenced by common_exec(), and pickup_by_exten().

01357 {
01358    struct ast_channel_iterator *i;
01359    char *l_exten = (char *) exten;
01360    char *l_context = (char *) context;
01361 
01362    if (!(i = ast_calloc(1, sizeof(*i)))) {
01363       return NULL;
01364    }
01365 
01366    i->active_iterator = (void *) ast_channel_callback(ast_channel_by_exten_cb,
01367       l_context, l_exten, OBJ_MULTIPLE);
01368    if (!i->active_iterator) {
01369       ast_free(i);
01370       return NULL;
01371    }
01372 
01373    return i;
01374 }

struct ast_channel_iterator* ast_channel_iterator_by_name_new ( const char *  name,
size_t  name_len 
) [read]

Create a new channel iterator based on name.

Parameters:
name channel name or channel uniqueid to match
name_len number of characters in the channel name to match on. This would be used to match based on name prefix. If matching on the full channel name is desired, then this parameter should be 0.
After creating an iterator using this function, the ast_channel_iterator_next() function can be used to iterate through all channels that exist that have the specified name or name prefix.

Note:
You must call ast_channel_iterator_destroy() when done.
Return values:
NULL on failure
a new channel iterator based on the specified parameters
Since:
1.8

Definition at line 1376 of file channel.c.

References ast_channel_iterator::active_iterator, ast_calloc, ast_channel_by_name_cb(), ast_channel_callback(), ast_free, NULL, OBJ_KEY, and OBJ_MULTIPLE.

Referenced by common_exec(), get_device_state_causing_channels(), and softhangup_exec().

01377 {
01378    struct ast_channel_iterator *i;
01379    char *l_name = (char *) name;
01380 
01381    if (!(i = ast_calloc(1, sizeof(*i)))) {
01382       return NULL;
01383    }
01384 
01385    i->active_iterator = (void *) ast_channel_callback(ast_channel_by_name_cb,
01386       l_name, &name_len,
01387       OBJ_MULTIPLE | (name_len == 0 /* match the whole word, so optimize */ ? OBJ_KEY : 0));
01388    if (!i->active_iterator) {
01389       ast_free(i);
01390       return NULL;
01391    }
01392 
01393    return i;
01394 }

struct ast_channel_iterator* ast_channel_iterator_destroy ( struct ast_channel_iterator i  )  [read]

Destroy a channel iterator.

Parameters:
i the itereator to destroy
This function is used to destroy a channel iterator that was retrieved by using one of the channel_iterator_xxx_new() functions.

Returns:
NULL, for convenience to clear out the pointer to the iterator that was just destroyed.
Since:
1.8

Definition at line 1348 of file channel.c.

References ast_channel_iterator::active_iterator, ao2_iterator_destroy(), ast_free, and NULL.

Referenced by action_hangup(), action_status(), ast_var_channel_bridge(), ast_var_channel_types_table(), ast_var_channels_table(), common_exec(), data_channels_provider_handler(), func_channels_read(), get_device_state_causing_channels(), handle_show_hangup_all(), handle_softhangup(), pickup_by_exten(), and softhangup_exec().

01349 {
01350    ao2_iterator_destroy(i->active_iterator);
01351    ast_free(i);
01352 
01353    return NULL;
01354 }

struct ast_channel* ast_channel_iterator_next ( struct ast_channel_iterator i  )  [read]

Get the next channel for a channel iterator.

Parameters:
i the channel iterator that was created using one of the channel_iterator_xxx_new() functions.
This function should be used to iterate through all channels that match a specified set of parameters that were provided when the iterator was created.

Return values:
the next channel that matches the parameters used when the iterator was created.
NULL,if no more channels match the iterator parameters.
Since:
1.8

Definition at line 1410 of file channel.c.

References ast_channel_iterator::active_iterator, and ao2_iterator_next.

Referenced by action_hangup(), action_status(), ast_var_channel_bridge(), ast_var_channel_types_table(), ast_var_channels_table(), data_channels_provider_handler(), func_channels_read(), get_device_state_causing_channels(), handle_show_hangup_all(), handle_softhangup(), next_channel(), pickup_by_exten(), and softhangup_exec().

01411 {
01412    return ao2_iterator_next(i->active_iterator);
01413 }

int ast_channel_make_compatible ( struct ast_channel chan,
struct ast_channel peer 
)

Make the frame formats of two channels compatible.

Parameters:
chan First channel to make compatible. Should be the calling party.
peer Other channel to make compatible. Should be the called party.
Note:
Absolutely _NO_ channel locks should be held before calling this function.
Set two channels to compatible frame formats in both directions. The path from peer to chan is made compatible first to allow for in-band audio in case the other direction cannot be made compatible.

Return values:
0 on success.
-1 on error.

Definition at line 6376 of file channel.c.

References ast_channel_make_compatible_helper().

Referenced by app_exec(), dial_exec_full(), do_forward(), fax_detect_framehook(), fax_gateway_framehook(), native_bridge_join(), simple_bridge_join(), try_calling(), and wait_for_answer().

06377 {
06378    /*
06379     * Set up translation from the peer to the chan first in case we
06380     * need to hear any in-band tones and the other direction fails.
06381     */
06382    if (ast_channel_make_compatible_helper(peer, chan)) {
06383       return -1;
06384    }
06385 
06386    /* Set up translation from the chan to the peer */
06387    if (ast_channel_make_compatible_helper(chan, peer)) {
06388       return -1;
06389    }
06390 
06391    return 0;
06392 }

static int ast_channel_make_compatible_helper ( struct ast_channel from,
struct ast_channel to 
) [static]

Set up translation from one channel to another.

Definition at line 6301 of file channel.c.

References ao2_cleanup, ao2_replace, ast_channel_lock_both, ast_channel_name(), ast_channel_nativeformats(), ast_channel_unlock, ast_format_cache_get_slin_by_rate(), ast_format_cache_is_slinear(), ast_format_cap_has_type(), ast_format_cmp(), AST_FORMAT_CMP_NOT_EQUAL, ast_format_get_name(), ast_format_get_sample_rate(), ast_log, AST_MEDIA_TYPE_AUDIO, ast_opt_generic_plc, ast_opt_transcode_via_slin, ast_set_read_format(), ast_set_write_format(), ast_translate_path_steps(), ast_translator_best_choice(), LOG_WARNING, NULL, and RAII_VAR.

Referenced by ast_channel_make_compatible().

06302 {
06303    struct ast_format_cap *src_cap;
06304    struct ast_format_cap *dst_cap;
06305    RAII_VAR(struct ast_format *, best_src_fmt, NULL, ao2_cleanup);
06306    RAII_VAR(struct ast_format *, best_dst_fmt, NULL, ao2_cleanup);
06307    int no_path;
06308 
06309    /*
06310     * We cannot short circuit this code because it is possible to ask
06311     * to make compatible two channels that are "compatible" because
06312     * they already have translation paths setup but together make for
06313     * a sub-optimal path.  e.g., The From channel has g722 -> ulaw
06314     * and the To channel has ulaw -> g722.  They are "compatible" but
06315     * together the translations are unnecessary and the audio loses
06316     * fidelity in the process.
06317     */
06318 
06319    ast_channel_lock_both(from, to);
06320 
06321    src_cap = ast_channel_nativeformats(from); /* shallow copy, do not destroy */
06322    dst_cap = ast_channel_nativeformats(to);   /* shallow copy, do not destroy */
06323 
06324    /* If there's no audio in this call, don't bother with trying to find a translation path */
06325    if (!ast_format_cap_has_type(src_cap, AST_MEDIA_TYPE_AUDIO)
06326       || !ast_format_cap_has_type(dst_cap, AST_MEDIA_TYPE_AUDIO)) {
06327       ast_channel_unlock(to);
06328       ast_channel_unlock(from);
06329       return 0;
06330    }
06331 
06332    no_path = ast_translator_best_choice(dst_cap, src_cap, &best_dst_fmt, &best_src_fmt);
06333 
06334    ast_channel_unlock(to);
06335    ast_channel_unlock(from);
06336 
06337    if (no_path) {
06338       ast_log(LOG_WARNING, "No path to translate from %s to %s\n",
06339          ast_channel_name(from), ast_channel_name(to));
06340       return -1;
06341    }
06342 
06343    /* if the best path is not 'pass through', then
06344     * transcoding is needed; if desired, force transcode path
06345     * to use SLINEAR between channels, but only if there is
06346     * no direct conversion available. If generic PLC is
06347     * desired, then transcoding via SLINEAR is a requirement
06348     */
06349    if (ast_format_cmp(best_dst_fmt, best_src_fmt) == AST_FORMAT_CMP_NOT_EQUAL
06350       && (ast_opt_generic_plc || ast_opt_transcode_via_slin)) {
06351       int use_slin = (ast_format_cache_is_slinear(best_src_fmt)
06352          || ast_format_cache_is_slinear(best_dst_fmt)) ? 1 : 0;
06353 
06354       if (use_slin || ast_translate_path_steps(best_dst_fmt, best_src_fmt) != 1) {
06355          int best_sample_rate = (ast_format_get_sample_rate(best_src_fmt) > ast_format_get_sample_rate(best_dst_fmt)) ?
06356             ast_format_get_sample_rate(best_src_fmt) : ast_format_get_sample_rate(best_dst_fmt);
06357 
06358          /* pick the best signed linear format based upon what preserves the sample rate the best. */
06359          ao2_replace(best_src_fmt, ast_format_cache_get_slin_by_rate(best_sample_rate));
06360       }
06361    }
06362 
06363    if (ast_set_read_format(from, best_src_fmt)) {
06364       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %s\n",
06365          ast_channel_name(from), ast_format_get_name(best_src_fmt));
06366       return -1;
06367    }
06368    if (ast_set_write_format(to, best_src_fmt)) {
06369       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %s\n",
06370          ast_channel_name(to), ast_format_get_name(best_src_fmt));
06371       return -1;
06372    }
06373    return 0;
06374 }

int ast_channel_move ( struct ast_channel dest,
struct ast_channel source 
)

Move a channel from its current location to a new location.

Since:
12 The intention of this function is to have the destination channel take on the identity of the source channel.
Note:
This function is NOT intended to be used on bridged channels. If you wish to move an unbridged channel into the place of a bridged channel, then use ast_bridge_join() or ast_bridge_impart(). If you wish to move a bridged channel into the place of another bridged channel, then use ast_bridge_move().

When this function returns succesfully, the source channel is in a state where its continued use is unreliable.

absolutely _NO_ channel locks should be held before calling this function.

Parameters:
dest The place to move the source channel
source The channel to move
Return values:
0 Success
non-zero Failure

Definition at line 10457 of file channel.c.

References ast_channel_flags(), ast_channel_lock_both, ast_channel_masq_set(), ast_channel_masqr_set(), ast_channel_name(), ast_channel_unlock, AST_FLAG_ZOMBIE, ast_log, ast_test_flag, channel_do_masquerade(), channel_move_lock, lock, LOG_WARNING, and SCOPED_MUTEX.

Referenced by after_bridge_move_channel(), ast_channel_yank(), ast_do_pickup(), handle_invite_replaces(), local_call(), and refer_incoming_invite_request().

10458 {
10459    SCOPED_MUTEX(lock, &channel_move_lock);
10460 
10461    if (dest == source) {
10462       ast_log(LOG_WARNING, "Can't move channel '%s' into itself!\n",
10463          ast_channel_name(dest));
10464       return -1;
10465    }
10466 
10467    ast_channel_lock_both(dest, source);
10468 
10469    if (ast_test_flag(ast_channel_flags(dest), AST_FLAG_ZOMBIE)
10470       || ast_test_flag(ast_channel_flags(source), AST_FLAG_ZOMBIE)) {
10471       /* Zombies! Run! */
10472       ast_log(LOG_WARNING,
10473          "Can't move channel. One or both is dead (%s <-- %s)\n",
10474          ast_channel_name(dest), ast_channel_name(source));
10475       ast_channel_unlock(source);
10476       ast_channel_unlock(dest);
10477       return -1;
10478    }
10479 
10480    ast_channel_masq_set(dest, source);
10481    ast_channel_masqr_set(source, dest);
10482 
10483    ast_channel_unlock(dest);
10484    ast_channel_unlock(source);
10485 
10486    channel_do_masquerade(dest, source);
10487    return 0;
10488 }

void ast_channel_name_to_dial_string ( char *  channel_name  ) 

Removes the trailing identifiers from a channel name string.

Since:
12.0.0
Parameters:
channel_name string that you wish to turn into a dial string. This string will be edited in place.

Definition at line 6493 of file channel.c.

Referenced by parked_user_set_parker_dial_string(), and setup_park_common_datastore().

06494 {
06495    char *dash;
06496 
06497    /* Truncate after the dash */
06498    dash = strrchr(channel_name, '-');
06499    if (dash) {
06500       *dash = '\0';
06501    }
06502 }

int ast_channel_queryoption ( struct ast_channel channel,
int  option,
void *  data,
int *  datalen,
int  block 
)

Checks the value of an option.

Query the value of an option Works similarly to setoption except only reads the options.

Definition at line 7077 of file channel.c.

References ast_channel_lock, ast_channel_tech(), ast_channel_unlock, ast_log, errno, LOG_ERROR, and ast_channel_tech::queryoption.

Referenced by ast_channel_get_cc_agent_type(), ast_channel_get_device_name(), ast_channel_get_t38_state(), ast_unreal_queryoption(), rcvfax_exec(), and sndfax_exec().

07078 {
07079    int res;
07080 
07081    ast_channel_lock(chan);
07082    if (!ast_channel_tech(chan)->queryoption) {
07083       errno = ENOSYS;
07084       ast_channel_unlock(chan);
07085       return -1;
07086    }
07087 
07088    if (block)
07089       ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
07090 
07091    res = ast_channel_tech(chan)->queryoption(chan, option, data, datalen);
07092    ast_channel_unlock(chan);
07093 
07094    return res;
07095 }

void ast_channel_queue_connected_line_update ( struct ast_channel chan,
const struct ast_party_connected_line connected,
const struct ast_set_party_connected_line update 
)

Queue a connected line update frame on a channel.

Since:
1.8
Parameters:
chan Asterisk channel to indicate connected line information
connected Connected line information
update What connected line information to update. NULL if all.
Returns:
Nothing

Definition at line 8843 of file channel.c.

References ast_connected_line_build_data(), AST_CONTROL_CONNECTED_LINE, and ast_queue_control_data().

Referenced by ast_do_pickup(), handle_request_invite(), handle_request_update(), handle_response_invite(), misdn_queue_connected_line_update(), onAlerting(), onCallEstablished(), onProgress(), queue_connected_line_update(), sip_call(), and update_initial_connected_line().

08844 {
08845    unsigned char data[1024];  /* This should be large enough */
08846    size_t datalen;
08847 
08848    datalen = ast_connected_line_build_data(data, sizeof(data), connected, update);
08849    if (datalen == (size_t) -1) {
08850       return;
08851    }
08852 
08853    ast_queue_control_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen);
08854 }

void ast_channel_queue_redirecting_update ( struct ast_channel chan,
const struct ast_party_redirecting redirecting,
const struct ast_set_party_redirecting update 
)

Queue a redirecting update frame on a channel.

Since:
1.8
Parameters:
chan Asterisk channel to indicate redirecting id information
redirecting Redirecting id information
update What redirecting information to update. NULL if all.
Returns:
Nothing

Definition at line 10032 of file channel.c.

References AST_CONTROL_REDIRECTING, ast_queue_control_data(), and ast_redirecting_build_data().

Referenced by cb_events(), handle_response_invite(), and misdn_facility_ie_handler().

10033 {
10034    unsigned char data[1024];  /* This should be large enough */
10035    size_t datalen;
10036 
10037    datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update);
10038    if (datalen == (size_t) -1) {
10039       return;
10040    }
10041 
10042    ast_queue_control_data(chan, AST_CONTROL_REDIRECTING, data, datalen);
10043 }

const char* ast_channel_reason2str ( int  reason  ) 

return an english explanation of the code returned thru __ast_request_and_dial's 'outstate' argument

Parameters:
reason The integer argument, usually taken from AST_CONTROL_ macros
Returns:
char pointer explaining the code

Definition at line 5554 of file channel.c.

References AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_RING, and AST_CONTROL_RINGING.

Referenced by attempt_thread().

05555 {
05556    switch (reason) /* the following appear to be the only ones actually returned by request_and_dial */
05557    {
05558    case 0:
05559       return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)";
05560    case AST_CONTROL_HANGUP:
05561       return "Hangup";
05562    case AST_CONTROL_RING:
05563       return "Local Ring";
05564    case AST_CONTROL_RINGING:
05565       return "Remote end Ringing";
05566    case AST_CONTROL_ANSWER:
05567       return "Remote end has Answered";
05568    case AST_CONTROL_BUSY:
05569       return "Remote end is Busy";
05570    case AST_CONTROL_CONGESTION:
05571       return "Congestion (circuits busy)";
05572    default:
05573       return "Unknown Reason!!";
05574    }
05575 }

int ast_channel_redirecting_macro ( struct ast_channel autoservice_chan,
struct ast_channel macro_chan,
const void *  redirecting_info,
int  is_caller,
int  is_frame 
)

Run a redirecting interception macro and update a channel's redirecting information.

Since:
1.8
Deprecated:
You should use the ast_channel_redirecting_sub() function instead.
Whenever we want to update a channel's redirecting information, we may need to run a macro so that an administrator can manipulate the information before sending it out. This function both runs the macro and sends the update to the channel.

Parameters:
autoservice_chan Channel to place into autoservice while the macro is running. It is perfectly safe for this to be NULL
macro_chan The channel to run the macro on. Also the channel from which we determine which macro we need to run.
redirecting_info Either an ast_party_redirecting or ast_frame pointer of type AST_CONTROL_REDIRECTING
is_caller If true, then run REDIRECTING_CALLER_SEND_MACRO with arguments from REDIRECTING_CALLER_SEND_MACRO_ARGS, otherwise run REDIRECTING_CALLEE_SEND_MACRO with arguments from REDIRECTING_CALLEE_SEND_MACRO_ARGS
is_frame If true, then redirecting_info is an ast_frame pointer, otherwise it is an ast_party_redirecting pointer.
Return values:
0 Success
-1 Either the macro does not exist, or there was an error while attempting to run the macro
Todo:
Have multiple return codes based on the MACRO_RESULT
Todo:
Make constants so that caller and frame can be more expressive than just '1' and '0'

Definition at line 10095 of file channel.c.

References ast_app_run_macro(), ast_channel_lock, ast_channel_redirecting(), ast_channel_unlock, ast_channel_update_redirecting(), ast_log, ast_party_redirecting_copy(), ast_party_redirecting_free(), ast_party_redirecting_init(), ast_redirecting_parse_data(), ast_strdupa, ast_strlen_zero, ast_frame::data, ast_frame::datalen, LOG_WARNING, NULL, pbx_builtin_getvar_helper(), ast_frame::ptr, retval, and S_OR.

Referenced by bridge_channel_handle_control(), call_forward_inherit(), do_forward(), handle_frame(), and wait_for_answer().

10096 {
10097    static int deprecation_warning = 0;
10098    const char *macro;
10099    const char *macro_a