Fri Feb 10 06:35:39 2012

Asterisk developer's documentation


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/cel.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 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_subaddress_ies
struct  ast_silence_generator
struct  backends
 the list of registered channel types More...
struct  chanlist
 List of channel drivers. More...
struct  plc_ds
struct  tonepair_def
struct  tonepair_state
struct  xfer_masquerade_ds

Defines

#define AST_DEFAULT_EMULATE_DTMF_DURATION   100
#define AST_MIN_DTMF_DURATION   80
#define AST_MIN_DTMF_GAP   45
#define FORMAT   "%-10.10s %-40.40s %-12.12s %-12.12s %-12.12s\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
}
 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, 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
}
 Element identifiers for redirecting indication frame data. More...

Functions

int __ast_answer (struct ast_channel *chan, unsigned int delay, int cdr_answer)
 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 char *linkedid, const int amaflag, 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 char *linkedid, const int amaflag, const char *file, int line, const char *function, const char *name_fmt, va_list ap)
 Create a new channel structure.
static int __ast_channel_masquerade (struct ast_channel *original, struct ast_channel *clonechan, struct ast_datastore *xfer_ds)
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_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 __init_backends (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.
void ast_begin_shutdown (int hangup)
struct ast_formatast_best_codec (struct ast_format_cap *cap, struct ast_format *result)
 Pick the best audio codec.
struct ast_channelast_bridged_channel (struct ast_channel *chan)
 Find bridged channel.
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.
void ast_cancel_shutdown (void)
 Cancel a shutdown in progress.
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.
struct ast_channelast_channel_alloc (int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const char *linkedid, const int amaflag, const char *name_fmt,...)
enum ast_bridge_result ast_channel_bridge (struct ast_channel *c0, struct ast_channel *c1, struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc)
 Bridge two channels together.
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.
static void ast_channel_change_linkedid (struct ast_channel *chan, const char *linkedid)
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_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).
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.
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.
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)
 Makes two channel formats 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_masquerade (struct ast_channel *original, struct ast_channel *clone)
 Weird function made for call transfers.
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_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.
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_linkgroup (struct ast_channel *chan, struct ast_channel *peer)
 Propagate the oldest linkedid between associated channels.
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)
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.
int ast_channel_supports_html (struct ast_channel *chan)
 Checks for HTML support on a channel.
int ast_channel_transfer_masquerade (struct ast_channel *target_chan, const struct ast_party_connected_line *target_id, int target_held, struct ast_channel *transferee_chan, const struct ast_party_connected_line *transferee_id, int transferee_held)
 Setup a masquerade to transfer a call.
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.
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.
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)
int ast_do_masquerade (struct ast_channel *original)
 Masquerade a channel.
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.
static enum ast_bridge_result ast_generic_bridge (struct ast_channel *c0, struct ast_channel *c1, struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc)
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)
int 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_internal_timing_enabled (struct ast_channel *chan)
 Check if the channel can run in internal timing mode.
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.
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.
int ast_party_id_presentation (const struct ast_party_id *id)
 Determine the overall presentation value for the given party.
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_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)
char * ast_print_group (char *buf, int buflen, ast_group_t group)
 Print call group and pickup group ---.
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_raw_answer (struct ast_channel *chan, int cdr_answer)
 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_channelast_request (const char *type, struct ast_format_cap *request_cap, 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_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 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)
 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.
static void ast_set_owners_and_peers (struct ast_channel *chan1, struct ast_channel *chan2)
int ast_set_read_format (struct ast_channel *chan, struct ast_format *format)
 Sets read format on channel chan.
int ast_set_read_format_by_id (struct ast_channel *chan, enum ast_format_id id)
 Sets read format on channel chan by id.
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.
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_by_id (struct ast_channel *chan, enum ast_format_id id)
 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_shutting_down (void)
 Returns non-zero if Asterisk is being shut down.
int ast_softhangup (struct ast_channel *chan, int cause)
 Softly hangup a channel, lock.
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.
void ast_uninstall_music_functions (void)
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 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 void bridge_play_sounds (struct ast_channel *c0, struct ast_channel *c1)
static void bridge_playfile (struct ast_channel *chan, struct ast_channel *peer, const char *sound, int remain)
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)
const char * channelreloadreason2txt (enum channelreloadreason reason)
 Convert enum channelreloadreason to text string for manager event.
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 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 destroy_hooks (struct ast_channel *chan)
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 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 void manager_bridge_event (int onoff, int type, struct ast_channel *c0, struct ast_channel *c1)
 Send manager event for bridge link and unlink events.
static void masquerade_colp_transfer (struct ast_channel *transferee, struct xfer_masquerade_ds *colp)
static const char * oldest_linkedid (const char *a, const char *b)
static void party_connected_line_copy_transfer (struct ast_party_connected_line *dest, const struct ast_party_connected_line *src)
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 queue_dtmf_readq (struct ast_channel *chan, struct ast_frame *f)
static void report_new_callerid (struct ast_channel *chan)
static void send_dtmf_event (struct ast_channel *chan, const char *direction, const char digit, const char *begin, const char *end)
static int set_format (struct ast_channel *chan, struct ast_format_cap *cap_set, struct ast_format *rawformat, struct ast_format *format, struct ast_trans_pvt **trans, 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 * 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 update_bridge_vars (struct ast_channel *c0, struct ast_channel *c1)
static void xfer_ds_destroy (void *data)

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
struct {
   int   cause
   const char *   desc
   const char *   name
causes []
 map AST_CAUSE's to readable string representations
static struct ast_datastore_info cc_channel_datastore_info
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 int shutting_down
 Prevent new channel allocation if shutting down.
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_generator tonepair
static int uniqueint
static struct ast_datastore_info xfer_ds_info


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 104 of file channel.c.

Referenced by __ast_read(), and ast_senddigit().

#define AST_MIN_DTMF_DURATION   80

Minimum allowed digit length - 80ms

Definition at line 107 of file channel.c.

Referenced by __ast_read().

#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 111 of file channel.c.

Referenced by __ast_read(), and should_skip_dtmf().

#define FORMAT   "%-10.10s %-40.40s %-12.12s %-12.12s %-12.12s\n"

#define NUM_CHANNEL_BUCKETS   1567

Definition at line 141 of file channel.c.

Referenced by ast_channels_init().

#define STATE2STR_BUFSIZE   32

Definition at line 100 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 

Definition at line 8526 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 
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 

Definition at line 8847 of file channel.c.


Function Documentation

int __ast_answer ( struct ast_channel chan,
unsigned int  delay,
int  cdr_answer 
)

Answer a channel, with a selectable delay before returning.

Parameters:
chan channel to answer
delay maximum amount of time to wait for incoming media
cdr_answer flag to control whether any associated CDR should be marked as 'answered'
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 2767 of file channel.c.

References ast_channel::_state, ast_channel_lock, ast_channel_name(), ast_channel_unlock, AST_CONTROL_HANGUP, ast_debug, 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_STATE_RING, AST_STATE_RINGING, 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().

02768 {
02769    int res = 0;
02770    enum ast_channel_state old_state;
02771 
02772    old_state = chan->_state;
02773    if ((res = ast_raw_answer(chan, cdr_answer))) {
02774       return res;
02775    }
02776 
02777    switch (old_state) {
02778    case AST_STATE_RINGING:
02779    case AST_STATE_RING:
02780       /* wait for media to start flowing, but don't wait any longer
02781        * than 'delay' or 500 milliseconds, whichever is longer
02782        */
02783       do {
02784          AST_LIST_HEAD_NOLOCK(, ast_frame) frames;
02785          struct ast_frame *cur, *new;
02786          int ms = MAX(delay, 500);
02787          unsigned int done = 0;
02788 
02789          AST_LIST_HEAD_INIT_NOLOCK(&frames);
02790 
02791          for (;;) {
02792             ms = ast_waitfor(chan, ms);
02793             if (ms < 0) {
02794                ast_log(LOG_WARNING, "Error condition occurred when polling channel %s for a voice frame: %s\n", ast_channel_name(chan), strerror(errno));
02795                res = -1;
02796                break;
02797             }
02798             if (ms == 0) {
02799                ast_debug(2, "Didn't receive a media frame from %s within %d ms of answering. Continuing anyway\n", ast_channel_name(chan), MAX(delay, 500));
02800                break;
02801             }
02802             cur = ast_read(chan);
02803             if (!cur || ((cur->frametype == AST_FRAME_CONTROL) &&
02804                     (cur->subclass.integer == AST_CONTROL_HANGUP))) {
02805                if (cur) {
02806                   ast_frfree(cur);
02807                }
02808                res = -1;
02809                ast_debug(2, "Hangup of channel %s detected in answer routine\n", ast_channel_name(chan));
02810                break;
02811             }
02812 
02813             if ((new = ast_frisolate(cur)) != cur) {
02814                ast_frfree(cur);
02815             }
02816 
02817             AST_LIST_INSERT_HEAD(&frames, new, frame_list);
02818 
02819             /* if a specific delay period was requested, continue
02820              * until that delay has passed. don't stop just because
02821              * incoming media has arrived.
02822              */
02823             if (delay) {
02824                continue;
02825             }
02826 
02827             switch (new->frametype) {
02828                /* all of these frametypes qualify as 'media' */
02829             case AST_FRAME_VOICE:
02830             case AST_FRAME_VIDEO:
02831             case AST_FRAME_TEXT:
02832             case AST_FRAME_DTMF_BEGIN:
02833             case AST_FRAME_DTMF_END:
02834             case AST_FRAME_IMAGE:
02835             case AST_FRAME_HTML:
02836             case AST_FRAME_MODEM:
02837                done = 1;
02838                break;
02839             case AST_FRAME_CONTROL:
02840             case AST_FRAME_IAX:
02841             case AST_FRAME_NULL:
02842             case AST_FRAME_CNG:
02843                break;
02844             }
02845 
02846             if (done) {
02847                break;
02848             }
02849          }
02850 
02851          if (res == 0) {
02852             ast_channel_lock(chan);
02853             while ((cur = AST_LIST_REMOVE_HEAD(&frames, frame_list))) {
02854                ast_queue_frame_head(chan, cur);
02855                ast_frfree(cur);
02856             }
02857             ast_channel_unlock(chan);
02858          }
02859       } while (0);
02860       break;
02861    default:
02862       break;
02863    }
02864 
02865    return res;
02866 }

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 6080 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(), and ast_do_masquerade().

06081 {
06082    ast_manager_event(chan, EVENT_FLAG_CALL, "Rename", "Channel: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", ast_channel_name(chan), newname, ast_channel_uniqueid(chan));
06083    ast_channel_name_set(chan, newname);
06084 }

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 char *  linkedid,
const int  amaflag,
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.

Definition at line 1153 of file channel.c.

References __ast_channel_alloc_ap().

01159 {
01160    va_list ap;
01161    struct ast_channel *result;
01162 
01163    va_start(ap, name_fmt);
01164    result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context,
01165                linkedid, amaflag, file, line, function, name_fmt, ap);
01166    va_end(ap);
01167 
01168    return result;
01169 }

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 char *  linkedid,
const int  amaflag,
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 913 of file channel.c.

References __ao2_alloc_debug(), ast_channel::_state, ast_channel::alertpipe, ast_channel::amaflags, ao2_alloc, ao2_link, ao2_ref, ARRAY_LEN, AST_ALERT_FD, ast_atomic_fetchadd_int(), ast_cdr_alloc(), ast_cdr_init(), ast_cdr_start(), AST_CEL_CHANNEL_START, ast_cel_report_event(), ast_channel_accountcode(), ast_channel_destructor(), ast_channel_name(), ast_channel_name_set(), ast_channel_set_fd(), ast_channel_uniqueid(), ast_channel_unref, ast_config_AST_SYSTEM_NAME, ast_copy_string(), ast_default_accountcode, ast_default_amaflags, ast_format_cap_alloc(), ast_get_channel_tech(), AST_LIST_HEAD_INIT_NOLOCK, ast_log(), ast_manager_event, ast_party_caller_init(), ast_party_connected_line_init(), ast_party_dialed_init(), ast_party_redirecting_init(), ast_sched_context_create(), ast_state2str(), ast_strdup, ast_strdupa, ast_string_field_init, ast_strlen_zero(), ast_timer_fd(), ast_timer_get_name(), ast_timer_open(), AST_TIMING_FD, ast_channel::autochans, ast_channel::caller, ast_channel::cdr, channels, ast_channel::connected, ast_channel::context, ast_channel::datastores, defaultlanguage, ast_channel::dialed, errno, EVENT_FLAG_CALL, ast_channel::exten, ast_channel::fds, ast_channel::fin, chanlist::flags, ast_channel::fout, ast_party_caller::id, LOG_WARNING, ast_party_id::name, ast_channel::nativeformats, null_tech, ast_party_id::number, ast_channel::priority, ast_channel::redirecting, S_OR, ast_channel::sched, ast_party_number::str, ast_party_name::str, ast_channel::streamid, ast_channel::tech, chanlist::tech, ast_channel::timer, ast_channel::timingfd, ast_party_number::valid, ast_party_name::valid, and ast_channel::varshead.

Referenced by __ast_channel_alloc(), and ast_channel_alloc().

00917 {
00918    struct ast_channel *tmp;
00919    int x;
00920    int flags;
00921    struct varshead *headp;
00922    char *tech = "", *tech2 = NULL;
00923 
00924    /* If shutting down, don't allocate any new channels */
00925    if (shutting_down) {
00926       ast_log(LOG_WARNING, "Channel allocation failed: Refusing due to active shutdown\n");
00927       return NULL;
00928    }
00929 
00930 #if defined(REF_DEBUG)
00931    tmp = __ao2_alloc_debug(sizeof(*tmp), ast_channel_destructor, "", file, line,
00932       function, 1);
00933 #elif defined(__AST_DEBUG_MALLOC)
00934    tmp = __ao2_alloc_debug(sizeof(*tmp), ast_channel_destructor, "", file, line,
00935       function, 0);
00936 #else
00937    tmp = ao2_alloc(sizeof(*tmp), ast_channel_destructor);
00938 #endif
00939    if (!tmp) {
00940       /* Channel structure allocation failure. */
00941       return NULL;
00942    }
00943    if (!(tmp->nativeformats = ast_format_cap_alloc())) {
00944       ao2_ref(tmp, -1);
00945       /* format capabilities structure allocation failure */
00946       return NULL;
00947    }
00948 
00949    /*
00950     * Init file descriptors to unopened state so
00951     * the destructor can know not to close them.
00952     */
00953    tmp->timingfd = -1;
00954    for (x = 0; x < ARRAY_LEN(tmp->alertpipe); ++x) {
00955       tmp->alertpipe[x] = -1;
00956    }
00957    for (x = 0; x < ARRAY_LEN(tmp->fds); ++x) {
00958       tmp->fds[x] = -1;
00959    }
00960 #ifdef HAVE_EPOLL
00961    tmp->epfd = epoll_create(25);
00962 #endif
00963 
00964    if (!(tmp->sched = ast_sched_context_create())) {
00965       ast_log(LOG_WARNING, "Channel allocation failed: Unable to create schedule context\n");
00966       return ast_channel_unref(tmp);
00967    }
00968    
00969    ast_party_dialed_init(&tmp->dialed);
00970    ast_party_caller_init(&tmp->caller);
00971    ast_party_connected_line_init(&tmp->connected);
00972    ast_party_redirecting_init(&tmp->redirecting);
00973 
00974    if (cid_name) {
00975       tmp->caller.id.name.valid = 1;
00976       tmp->caller.id.name.str = ast_strdup(cid_name);
00977       if (!tmp->caller.id.name.str) {
00978          return ast_channel_unref(tmp);
00979       }
00980    }
00981    if (cid_num) {
00982       tmp->caller.id.number.valid = 1;
00983       tmp->caller.id.number.str = ast_strdup(cid_num);
00984       if (!tmp->caller.id.number.str) {
00985          return ast_channel_unref(tmp);
00986       }
00987    }
00988 
00989    if ((tmp->timer = ast_timer_open())) {
00990       if (strcmp(ast_timer_get_name(tmp->timer), "timerfd")) {
00991          needqueue = 0;
00992       }
00993       tmp->timingfd = ast_timer_fd(tmp->timer);
00994    }
00995 
00996    if (needqueue) {
00997       if (pipe(tmp->alertpipe)) {
00998          ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe! Try increasing max file descriptors with ulimit -n\n");
00999          return ast_channel_unref(tmp);
01000       } else {
01001          flags = fcntl(tmp->alertpipe[0], F_GETFL);
01002          if (fcntl(tmp->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) {
01003             ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
01004             return ast_channel_unref(tmp);
01005          }
01006          flags = fcntl(tmp->alertpipe[1], F_GETFL);
01007          if (fcntl(tmp->alertpipe[1], F_SETFL, flags | O_NONBLOCK) < 0) {
01008             ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
01009             return ast_channel_unref(tmp);
01010          }
01011       }
01012    }
01013 
01014    /*
01015     * This is the last place the channel constructor can fail.
01016     *
01017     * The destructor takes advantage of this fact to ensure that the
01018     * AST_CEL_CHANNEL_END is not posted if we have not posted the
01019     * AST_CEL_CHANNEL_START yet.
01020     */
01021    if ((ast_string_field_init(tmp, 128))) {
01022       return ast_channel_unref(tmp);
01023    }
01024 
01025    /* Always watch the alertpipe */
01026    ast_channel_set_fd(tmp, AST_ALERT_FD, tmp->alertpipe[0]);
01027    /* And timing pipe */
01028    ast_channel_set_fd(tmp, AST_TIMING_FD, tmp->timingfd);
01029 
01030    /* Initial state */
01031    tmp->_state = state;
01032 
01033    tmp->streamid = -1;
01034    
01035    tmp->fin = global_fin;
01036    tmp->fout = global_fout;
01037 
01038    if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) {
01039       ast_channel_uniqueid_build(tmp, "%li.%d", (long) time(NULL), 
01040          ast_atomic_fetchadd_int(&uniqueint, 1));
01041    } else {
01042       ast_channel_uniqueid_build(tmp, "%s-%li.%d", ast_config_AST_SYSTEM_NAME, 
01043          (long) time(NULL), ast_atomic_fetchadd_int(&uniqueint, 1));
01044    }
01045 
01046    if (!ast_strlen_zero(linkedid)) {
01047       ast_channel_linkedid_set(tmp, linkedid);
01048    } else {
01049       ast_channel_linkedid_set(tmp, ast_channel_uniqueid(tmp));
01050    }
01051 
01052    if (!ast_strlen_zero(name_fmt)) {
01053       char *slash, *slash2;
01054       /* Almost every channel is calling this function, and setting the name via the ast_string_field_build() call.
01055        * And they all use slightly different formats for their name string.
01056        * This means, to set the name here, we have to accept variable args, and call the string_field_build from here.
01057        * This means, that the stringfields must have a routine that takes the va_lists directly, and 
01058        * uses them to build the string, instead of forming the va_lists internally from the vararg ... list.
01059        * This new function was written so this can be accomplished.
01060        */
01061       ast_channel_name_build_va(tmp, name_fmt, ap);
01062       tech = ast_strdupa(ast_channel_name(tmp));
01063       if ((slash = strchr(tech, '/'))) {
01064          if ((slash2 = strchr(slash + 1, '/'))) {
01065             tech2 = slash + 1;
01066             *slash2 = '\0';
01067          }
01068          *slash = '\0';
01069       }
01070    } else {
01071       /*
01072        * Start the string with '-' so it becomes an empty string
01073        * in the destructor.
01074        */
01075       ast_channel_name_set(tmp, "-**Unknown**");
01076    }
01077 
01078    /* Reminder for the future: under what conditions do we NOT want to track cdrs on channels? */
01079 
01080    /* These 4 variables need to be set up for the cdr_init() to work right */
01081    if (amaflag)
01082       tmp->amaflags = amaflag;
01083    else
01084       tmp->amaflags = ast_default_amaflags;
01085    
01086    if (!ast_strlen_zero(acctcode))
01087       ast_channel_accountcode_set(tmp, acctcode);
01088    else
01089       ast_channel_accountcode_set(tmp, ast_default_accountcode);
01090       
01091    if (!ast_strlen_zero(context))
01092       ast_copy_string(tmp->context, context, sizeof(tmp->context));
01093    else
01094       strcpy(tmp->context, "default");
01095 
01096    if (!ast_strlen_zero(exten))
01097       ast_copy_string(tmp->exten, exten, sizeof(tmp->exten));
01098    else
01099       strcpy(tmp->exten, "s");
01100 
01101    tmp->priority = 1;
01102 
01103    tmp->cdr = ast_cdr_alloc();
01104    ast_cdr_init(tmp->cdr, tmp);
01105    ast_cdr_start(tmp->cdr);
01106 
01107    ast_cel_report_event(tmp, AST_CEL_CHANNEL_START, NULL, NULL, NULL);
01108 
01109    headp = &tmp->varshead;
01110    AST_LIST_HEAD_INIT_NOLOCK(headp);
01111    
01112    AST_LIST_HEAD_INIT_NOLOCK(&tmp->datastores);
01113 
01114    AST_LIST_HEAD_INIT_NOLOCK(&tmp->autochans);
01115    
01116    ast_channel_language_set(tmp, defaultlanguage);
01117 
01118    tmp->tech = &null_tech;
01119 
01120    ao2_link(channels, tmp);
01121 
01122    /*
01123     * And now, since the channel structure is built, and has its name, let's
01124     * call the manager event generator with this Newchannel event. This is the
01125     * proper and correct place to make this call, but you sure do have to pass
01126     * a lot of data into this func to do it here!
01127     */
01128    if (ast_get_channel_tech(tech) || (tech2 && ast_get_channel_tech(tech2))) {
01129       ast_manager_event(tmp, EVENT_FLAG_CALL, "Newchannel",
01130          "Channel: %s\r\n"
01131          "ChannelState: %d\r\n"
01132          "ChannelStateDesc: %s\r\n"
01133          "CallerIDNum: %s\r\n"
01134          "CallerIDName: %s\r\n"
01135          "AccountCode: %s\r\n"
01136          "Exten: %s\r\n"
01137          "Context: %s\r\n"
01138          "Uniqueid: %s\r\n",
01139          ast_channel_name(tmp), 
01140          state, 
01141          ast_state2str(state),
01142          S_OR(cid_num, ""),
01143          S_OR(cid_name, ""),
01144          ast_channel_accountcode(tmp),
01145          S_OR(exten, ""),
01146          S_OR(context, ""),
01147          ast_channel_uniqueid(tmp));
01148    }
01149 
01150    return tmp;
01151 }

static int __ast_channel_masquerade ( struct ast_channel original,
struct ast_channel clonechan,
struct ast_datastore xfer_ds 
) [static]

Definition at line 5844 of file channel.c.

References ast_channel::_bridge, ast_bridged_channel(), ast_channel_datastore_add(), ast_channel_lock_both, ast_channel_name(), ast_channel_trylock, ast_channel_unlock, ast_debug, AST_FLAG_ZOMBIE, ast_log(), ast_null_frame, ast_queue_frame(), ast_test_flag, ast_channel_tech::get_base_channel, LOG_WARNING, ast_channel::masq, ast_channel::masqr, and ast_channel::tech.

Referenced by ast_channel_masquerade(), and ast_channel_transfer_masquerade().

05845 {
05846    int res = -1;
05847    struct ast_channel *final_orig, *final_clone, *base;
05848 
05849    for (;;) {
05850       final_orig = original;
05851       final_clone = clonechan;
05852 
05853       ast_channel_lock_both(original, clonechan);
05854 
05855       if (ast_test_flag(original, AST_FLAG_ZOMBIE)
05856          || ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) {
05857          /* Zombies! Run! */
05858          ast_log(LOG_WARNING,
05859             "Can't setup masquerade. One or both channels is dead. (%s <-- %s)\n",
05860             ast_channel_name(original), ast_channel_name(clonechan));
05861          ast_channel_unlock(clonechan);
05862          ast_channel_unlock(original);
05863          return -1;
05864       }
05865 
05866       /*
05867        * Each of these channels may be sitting behind a channel proxy
05868        * (i.e. chan_agent) and if so, we don't really want to
05869        * masquerade it, but its proxy
05870        */
05871       if (original->_bridge
05872          && (original->_bridge != ast_bridged_channel(original))
05873          && (original->_bridge->_bridge != original)) {
05874          final_orig = original->_bridge;
05875       }
05876       if (clonechan->_bridge
05877          && (clonechan->_bridge != ast_bridged_channel(clonechan))
05878          && (clonechan->_bridge->_bridge != clonechan)) {
05879          final_clone = clonechan->_bridge;
05880       }
05881       if (final_clone->tech->get_base_channel
05882          && (base = final_clone->tech->get_base_channel(final_clone))) {
05883          final_clone = base;
05884       }
05885 
05886       if ((final_orig != original) || (final_clone != clonechan)) {
05887          /*
05888           * Lots and lots of deadlock avoidance.  The main one we're
05889           * competing with is ast_write(), which locks channels
05890           * recursively, when working with a proxy channel.
05891           */
05892          if (ast_channel_trylock(final_orig)) {
05893             ast_channel_unlock(clonechan);
05894             ast_channel_unlock(original);
05895 
05896             /* Try again */
05897             continue;
05898          }
05899          if (ast_channel_trylock(final_clone)) {
05900             ast_channel_unlock(final_orig);
05901             ast_channel_unlock(clonechan);
05902             ast_channel_unlock(original);
05903 
05904             /* Try again */
05905             continue;
05906          }
05907          ast_channel_unlock(clonechan);
05908          ast_channel_unlock(original);
05909          original = final_orig;
05910          clonechan = final_clone;
05911 
05912          if (ast_test_flag(original, AST_FLAG_ZOMBIE)
05913             || ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) {
05914             /* Zombies! Run! */
05915             ast_log(LOG_WARNING,
05916                "Can't setup masquerade. One or both channels is dead. (%s <-- %s)\n",
05917                ast_channel_name(original), ast_channel_name(clonechan));
05918             ast_channel_unlock(clonechan);
05919             ast_channel_unlock(original);
05920             return -1;
05921          }
05922       }
05923       break;
05924    }
05925 
05926    if (original == clonechan) {
05927       ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", ast_channel_name(original));
05928       ast_channel_unlock(clonechan);
05929       ast_channel_unlock(original);
05930       return -1;
05931    }
05932 
05933    ast_debug(1, "Planning to masquerade channel %s into the structure of %s\n",
05934       ast_channel_name(clonechan), ast_channel_name(original));
05935 
05936    if (!original->masqr && !original->masq && !clonechan->masq && !clonechan->masqr) {
05937       original->masq = clonechan;
05938       clonechan->masqr = original;
05939       if (xfer_ds) {
05940          ast_channel_datastore_add(original, xfer_ds);
05941       }
05942       ast_queue_frame(original, &ast_null_frame);
05943       ast_queue_frame(clonechan, &ast_null_frame);
05944       ast_debug(1, "Done planning to masquerade channel %s into the structure of %s\n", ast_channel_name(clonechan), ast_channel_name(original));
05945       res = 0;
05946    } else if (original->masq) {
05947       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
05948          ast_channel_name(original->masq), ast_channel_name(original));
05949    } else if (original->masqr) {
05950       /* not yet as a previously planned masq hasn't yet happened */
05951       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
05952          ast_channel_name(original), ast_channel_name(original->masqr));
05953    } else if (clonechan->masq) {
05954       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
05955          ast_channel_name(clonechan->masq), ast_channel_name(clonechan));
05956    } else { /* (clonechan->masqr) */
05957       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
05958       ast_channel_name(clonechan), ast_channel_name(clonechan->masqr));
05959    }
05960 
05961    ast_channel_unlock(clonechan);
05962    ast_channel_unlock(original);
05963 
05964    return res;
05965 }

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

Definition at line 1206 of file channel.c.

References ast_channel::alertpipe, ast_channel_lock, ast_channel_name(), 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(), ast_channel::blocker, errno, f, frames, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, ast_channel::readq, ast_frame::subclass, ast_channel::timer, and ast_channel::timingfd.

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

01207 {
01208    struct ast_frame *f;
01209    struct ast_frame *cur;
01210    unsigned int new_frames = 0;
01211    unsigned int new_voice_frames = 0;
01212    unsigned int queued_frames = 0;
01213    unsigned int queued_voice_frames = 0;
01214    AST_LIST_HEAD_NOLOCK(, ast_frame) frames;
01215 
01216    ast_channel_lock(chan);
01217 
01218    /*
01219     * Check the last frame on the queue if we are queuing the new
01220     * frames after it.
01221     */
01222    cur = AST_LIST_LAST(&chan->readq);
01223    if (cur && cur->frametype == AST_FRAME_CONTROL && !head && (!after || after == cur)) {
01224       switch (cur->subclass.integer) {
01225       case AST_CONTROL_END_OF_Q:
01226          if (fin->frametype == AST_FRAME_CONTROL
01227             && fin->subclass.integer == AST_CONTROL_HANGUP) {
01228             /*
01229              * Destroy the end-of-Q marker frame so we can queue the hangup
01230              * frame in its place.
01231              */
01232             AST_LIST_REMOVE(&chan->readq, cur, frame_list);
01233             ast_frfree(cur);
01234 
01235             /*
01236              * This has degenerated to a normal queue append anyway.  Since
01237              * we just destroyed the last frame in the queue we must make
01238              * sure that "after" is NULL or bad things will happen.
01239              */
01240             after = NULL;
01241             break;
01242          }
01243          /* Fall through */
01244       case AST_CONTROL_HANGUP:
01245          /* Don't queue anything. */
01246          ast_channel_unlock(chan);
01247          return 0;
01248       default:
01249          break;
01250       }
01251    }
01252 
01253    /* Build copies of all the new frames and count them */
01254    AST_LIST_HEAD_INIT_NOLOCK(&frames);
01255    for (cur = fin; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
01256       if (!(f = ast_frdup(cur))) {
01257          if (AST_LIST_FIRST(&frames)) {
01258             ast_frfree(AST_LIST_FIRST(&frames));
01259          }
01260          ast_channel_unlock(chan);
01261          return -1;
01262       }
01263 
01264       AST_LIST_INSERT_TAIL(&frames, f, frame_list);
01265       new_frames++;
01266       if (f->frametype == AST_FRAME_VOICE) {
01267          new_voice_frames++;
01268       }
01269    }
01270 
01271    /* Count how many frames exist on the queue */
01272    AST_LIST_TRAVERSE(&chan->readq, cur, frame_list) {
01273       queued_frames++;
01274       if (cur->frametype == AST_FRAME_VOICE) {
01275          queued_voice_frames++;
01276       }
01277    }
01278 
01279    if ((queued_frames + new_frames > 128 || queued_voice_frames + new_voice_frames > 96)) {
01280       int count = 0;
01281       ast_log(LOG_WARNING, "Exceptionally long %squeue length queuing to %s\n", queued_frames + new_frames > 128 ? "" : "voice ", ast_channel_name(chan));
01282       AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->readq, cur, frame_list) {
01283          /* Save the most recent frame */
01284          if (!AST_LIST_NEXT(cur, frame_list)) {
01285             break;
01286          } else if (cur->frametype == AST_FRAME_VOICE || cur->frametype == AST_FRAME_VIDEO || cur->frametype == AST_FRAME_NULL) {
01287             if (++count > 64) {
01288                break;
01289             }
01290             AST_LIST_REMOVE_CURRENT(frame_list);
01291             ast_frfree(cur);
01292          }
01293       }
01294       AST_LIST_TRAVERSE_SAFE_END;
01295    }
01296 
01297    if (after) {
01298       AST_LIST_INSERT_LIST_AFTER(&chan->readq, &frames, after, frame_list);
01299    } else {
01300       if (head) {
01301          AST_LIST_APPEND_LIST(&frames, &chan->readq, frame_list);
01302          AST_LIST_HEAD_INIT_NOLOCK(&chan->readq);
01303       }
01304       AST_LIST_APPEND_LIST(&chan->readq, &frames, frame_list);
01305    }
01306 
01307    if (chan->alertpipe[1] > -1) {
01308       int blah[new_frames];
01309 
01310       memset(blah, 1, sizeof(blah));
01311       if (write(chan->alertpipe[1], &blah, sizeof(blah)) != (sizeof(blah))) {
01312          ast_log(LOG_WARNING, "Unable to write to alert pipe on %s (qlen = %d): %s!\n",
01313             ast_channel_name(chan), queued_frames, strerror(errno));
01314       }
01315    } else if (chan->timingfd > -1) {
01316       ast_timer_enable_continuous(chan->timer);
01317    } else if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
01318       pthread_kill(chan->blocker, SIGURG);
01319    }
01320 
01321    ast_channel_unlock(chan);
01322 
01323    return 0;
01324 }

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 3568 of file channel.c.

References __ast_queue_frame(), ast_channel::_softhangup, ast_channel::_state, ast_control_read_action_payload::action, ast_channel::alertpipe, ast_audiohook_detach_list(), AST_AUDIOHOOK_DIRECTION_READ, ast_audiohook_write_list(), ast_audiohook_write_list_empty(), ast_bridged_channel(), AST_CEL_ANSWER, ast_cel_report_event(), ast_channel_connected_line_macro(), ast_channel_lock, ast_channel_name(), 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_do_masquerade(), 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_ZOMBIE, ast_format_cap_iscompatible(), ast_format_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_getformatname(), ast_getformatname_multiple(), 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_DURATION, 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_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(), ast_channel::audiohooks, ast_channel::blocker, calc_monitor_jump(), cause, ast_channel::connected, ast_frame::data, DEBUGCHAN_FLAG, ast_generator::digit, ast_channel::dtmf_tv, ast_channel::dtmff, ast_channel::emulate_dtmf_digit, ast_channel::emulate_dtmf_duration, errno, ast_channel_tech::exception, ast_channel::fdno, ast_channel::fds, ast_channel::fin, chanlist::flags, ast_filestream::fmt, ast_format_def::format, ast_frame_subclass::format, FRAMECOUNT_INC, ast_channel::framehooks, ast_frame::frametype, ast_generator::generate, ast_channel::generator, ast_channel::generatordata, ast_channel::hangupcause, ast_channel::insmpl, ast_frame_subclass::integer, ast_frame::len, LOG_DTMF, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_channel::masq, ast_channel::monitor, ast_channel::music_state, ast_channel::nativeformats, ast_channel::outsmpl, ast_control_read_action_payload::payload, ast_control_read_action_payload::payload_size, ast_frame::ptr, queue_dtmf_readq(), ast_channel_tech::read, ast_channel_monitor::read_stream, ast_channel::readq, ast_channel::readtrans, ast_frame::samples, SEEK_FORCECUR, send_dtmf_event(), should_skip_dtmf(), ast_channel_monitor::state, ast_frame::subclass, ast_channel::tech, ast_channel::timer, ast_channel::timingdata, ast_channel::timingfd, ast_channel::timingfunc, and ast_frame::uint32.

Referenced by ast_read(), and ast_read_noaudio().

03569 {
03570    struct ast_frame *f = NULL;   /* the return value */
03571    int blah;
03572    int prestate;
03573    int cause = 0;
03574 
03575    /* this function is very long so make sure there is only one return
03576     * point at the end (there are only two exceptions to this).
03577     */
03578 
03579    if (chan->masq) {
03580       if (ast_do_masquerade(chan))
03581          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
03582       else
03583          f =  &ast_null_frame;
03584       return f;
03585    }
03586 
03587    /* if here, no masq has happened, lock the channel and proceed */
03588    ast_channel_lock(chan);
03589 
03590    /* Stop if we're a zombie or need a soft hangup */
03591    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
03592       if (chan->generator)
03593          ast_deactivate_generator(chan);
03594 
03595       /*
03596        * It is possible for chan->_softhangup to be set and there
03597        * still be control frames that need to be read.  Instead of
03598        * just going to 'done' in the case of ast_check_hangup(), we
03599        * need to queue the end-of-Q frame so that it can mark the end
03600        * of the read queue.  If there are frames to be read,
03601        * ast_queue_control() will be called repeatedly, but will only
03602        * queue the first end-of-Q frame.
03603        */
03604       if (chan->_softhangup) {
03605          ast_queue_control(chan, AST_CONTROL_END_OF_Q);
03606       } else {
03607          goto done;
03608       }
03609    } else {
03610 #ifdef AST_DEVMODE
03611       /*
03612        * The ast_waitfor() code records which of the channel's file
03613        * descriptors reported that data is available.  In theory,
03614        * ast_read() should only be called after ast_waitfor() reports
03615        * that a channel has data available for reading.  However,
03616        * there still may be some edge cases throughout the code where
03617        * ast_read() is called improperly.  This can potentially cause
03618        * problems, so if this is a developer build, make a lot of
03619        * noise if this happens so that it can be addressed.
03620        *
03621        * One of the potential problems is blocking on a dead channel.
03622        */
03623       if (chan->fdno == -1) {
03624          ast_log(LOG_ERROR,
03625             "ast_read() on chan '%s' called with no recorded file descriptor.\n",
03626             ast_channel_name(chan));
03627       }
03628 #endif
03629    }
03630 
03631    prestate = chan->_state;
03632 
03633    /* Read and ignore anything on the alertpipe, but read only
03634       one sizeof(blah) per frame that we send from it */
03635    if (chan->alertpipe[0] > -1) {
03636       int flags = fcntl(chan->alertpipe[0], F_GETFL);
03637       /* For some odd reason, the alertpipe occasionally loses nonblocking status,
03638        * which immediately causes a deadlock scenario.  Detect and prevent this. */
03639       if ((flags & O_NONBLOCK) == 0) {
03640          ast_log(LOG_ERROR, "Alertpipe on channel %s lost O_NONBLOCK?!!\n", ast_channel_name(chan));
03641          if (fcntl(chan->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) {
03642             ast_log(LOG_WARNING, "Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
03643             f = &ast_null_frame;
03644             goto done;
03645          }
03646       }
03647       if (read(chan->alertpipe[0], &blah, sizeof(blah)) < 0) {
03648          if (errno != EINTR && errno != EAGAIN)
03649             ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno));
03650       }
03651    }
03652 
03653    if (chan->timingfd > -1 && chan->fdno == AST_TIMING_FD) {
03654       enum ast_timer_event res;
03655 
03656       ast_clear_flag(chan, AST_FLAG_EXCEPTION);
03657 
03658       res = ast_timer_get_event(chan->timer);
03659 
03660       switch (res) {
03661       case AST_TIMING_EVENT_EXPIRED:
03662          ast_timer_ack(chan->timer, 1);
03663 
03664          if (chan->timingfunc) {
03665             /* save a copy of func/data before unlocking the channel */
03666             int (*func)(const void *) = chan->timingfunc;
03667             void *data = chan->timingdata;
03668             chan->fdno = -1;
03669             ast_channel_unlock(chan);
03670             func(data);
03671          } else {
03672             ast_timer_set_rate(chan->timer, 0);
03673             chan->fdno = -1;
03674             ast_channel_unlock(chan);
03675          }
03676 
03677          /* cannot 'goto done' because the channel is already unlocked */
03678          return &ast_null_frame;
03679 
03680       case AST_TIMING_EVENT_CONTINUOUS:
03681          if (AST_LIST_EMPTY(&chan->readq) || 
03682             !AST_LIST_NEXT(AST_LIST_FIRST(&chan->readq), frame_list)) {
03683             ast_timer_disable_continuous(chan->timer);
03684          }
03685          break;
03686       }
03687 
03688    } else if (chan->fds[AST_GENERATOR_FD] > -1 && chan->fdno == AST_GENERATOR_FD) {
03689       /* if the AST_GENERATOR_FD is set, call the generator with args
03690        * set to -1 so it can do whatever it needs to.
03691        */
03692       void *tmp = chan->generatordata;
03693       chan->generatordata = NULL;     /* reset to let ast_write get through */
03694       chan->generator->generate(chan, tmp, -1, -1);
03695       chan->generatordata = tmp;
03696       f = &ast_null_frame;
03697       chan->fdno = -1;
03698       goto done;
03699    } else if (chan->fds[AST_JITTERBUFFER_FD] > -1 && chan->fdno == AST_JITTERBUFFER_FD) {
03700       ast_clear_flag(chan, AST_FLAG_EXCEPTION);
03701    }
03702 
03703    /* Check for pending read queue */
03704    if (!AST_LIST_EMPTY(&chan->readq)) {
03705       int skip_dtmf = should_skip_dtmf(chan);
03706 
03707       AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->readq, f, frame_list) {
03708          /* We have to be picky about which frame we pull off of the readq because
03709           * there are cases where we want to leave DTMF frames on the queue until
03710           * some later time. */
03711 
03712          if ( (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && skip_dtmf) {
03713             continue;
03714          }
03715 
03716          AST_LIST_REMOVE_CURRENT(frame_list);
03717          break;
03718       }
03719       AST_LIST_TRAVERSE_SAFE_END;
03720       
03721       if (!f) {
03722          /* There were no acceptable frames on the readq. */
03723          f = &ast_null_frame;
03724          if (chan->alertpipe[0] > -1) {
03725             int poke = 0;
03726             /* Restore the state of the alertpipe since we aren't ready for any
03727              * of the frames in the readq. */
03728             if (write(chan->alertpipe[1], &poke, sizeof(poke)) != sizeof(poke)) {
03729                ast_log(LOG_ERROR, "Failed to write to alertpipe: %s\n", strerror(errno));
03730             }
03731          }
03732       }
03733 
03734       /* Interpret hangup and end-of-Q frames to return NULL */
03735       /* XXX why not the same for frames from the channel ? */
03736       if (f->frametype == AST_FRAME_CONTROL) {
03737          switch (f->subclass.integer) {
03738          case AST_CONTROL_HANGUP:
03739             chan->_softhangup |= AST_SOFTHANGUP_DEV;
03740             cause = f->data.uint32;
03741             /* Fall through */
03742          case AST_CONTROL_END_OF_Q:
03743             ast_frfree(f);
03744             f = NULL;
03745             break;
03746          default:
03747             break;
03748          }
03749       }
03750    } else {
03751       chan->blocker = pthread_self();
03752       if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
03753          if (chan->tech->exception)
03754             f = chan->tech->exception(chan);
03755          else {
03756             ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", ast_channel_name(chan));
03757             f = &ast_null_frame;
03758          }
03759          /* Clear the exception flag */
03760          ast_clear_flag(chan, AST_FLAG_EXCEPTION);
03761       } else if (chan->tech && chan->tech->read)
03762          f = chan->tech->read(chan);
03763       else
03764          ast_log(LOG_WARNING, "No read routine on channel %s\n", ast_channel_name(chan));
03765    }
03766 
03767    /* Perform the framehook read event here. After the frame enters the framehook list
03768     * there is no telling what will happen, <insert mad scientist laugh here>!!! */
03769    f = ast_framehook_list_read_event(chan->framehooks, f);
03770 
03771    /*
03772     * Reset the recorded file descriptor that triggered this read so that we can
03773     * easily detect when ast_read() is called without properly using ast_waitfor().
03774     */
03775    chan->fdno = -1;
03776 
03777    if (f) {
03778       struct ast_frame *readq_tail = AST_LIST_LAST(&chan->readq);
03779       struct ast_control_read_action_payload *read_action_payload;
03780       struct ast_party_connected_line connected;
03781 
03782       /* if the channel driver returned more than one frame, stuff the excess
03783          into the readq for the next ast_read call
03784       */
03785       if (AST_LIST_NEXT(f, frame_list)) {
03786          ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list));
03787          ast_frfree(AST_LIST_NEXT(f, frame_list));
03788          AST_LIST_NEXT(f, frame_list) = NULL;
03789       }
03790 
03791       switch (f->frametype) {
03792       case AST_FRAME_CONTROL:
03793          if (f->subclass.integer == AST_CONTROL_ANSWER) {
03794             if (!ast_test_flag(chan, AST_FLAG_OUTGOING)) {
03795                ast_debug(1, "Ignoring answer on an inbound call!\n");
03796                ast_frfree(f);
03797                f = &ast_null_frame;
03798             } else if (prestate == AST_STATE_UP && ast_bridged_channel(chan)) {
03799                ast_debug(1, "Dropping duplicate answer!\n");
03800                ast_frfree(f);
03801                f = &ast_null_frame;
03802             } else {
03803                /* Answer the CDR */
03804                ast_setstate(chan, AST_STATE_UP);
03805                /* removed a call to ast_cdr_answer(chan->cdr) from here. */
03806                ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL);
03807             }
03808          } else if (f->subclass.integer == AST_CONTROL_READ_ACTION) {
03809             read_action_payload = f->data.ptr;
03810             switch (read_action_payload->action) {
03811             case AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO:
03812                ast_party_connected_line_init(&connected);
03813                ast_party_connected_line_copy(&connected, &chan->connected);
03814                if (ast_connected_line_parse_data(read_action_payload->payload,
03815                   read_action_payload->payload_size, &connected)) {
03816                   ast_party_connected_line_free(&connected);
03817                   break;
03818                }
03819                if (ast_channel_connected_line_macro(NULL, chan, &connected, 1, 0)) {
03820                   ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE,
03821                      read_action_payload->payload,
03822                      read_action_payload->payload_size);
03823                }
03824                ast_party_connected_line_free(&connected);
03825                break;
03826             }
03827             ast_frfree(f);
03828             f = &ast_null_frame;
03829          }
03830          break;
03831       case AST_FRAME_DTMF_END:
03832          send_dtmf_event(chan, "Received", f->subclass.integer, "No", "Yes");
03833          ast_log(LOG_DTMF, "DTMF end '%c' received on %s, duration %ld ms\n", f->subclass.integer, ast_channel_name(chan), f->len);
03834          /* Queue it up if DTMF is deferred, or if DTMF emulation is forced. */
03835          if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF) || ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
03836             queue_dtmf_readq(chan, f);
03837             ast_frfree(f);
03838             f = &ast_null_frame;
03839          } else if (!ast_test_flag(chan, AST_FLAG_IN_DTMF | AST_FLAG_END_DTMF_ONLY)) {
03840             if (!ast_tvzero(chan->dtmf_tv) && 
03841                 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) {
03842                /* If it hasn't been long enough, defer this digit */
03843                queue_dtmf_readq(chan, f);
03844                ast_frfree(f);
03845                f = &ast_null_frame;
03846             } else {
03847                /* There was no begin, turn this into a begin and send the end later */
03848                f->frametype = AST_FRAME_DTMF_BEGIN;
03849                ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
03850                chan->emulate_dtmf_digit = f->subclass.integer;
03851                chan->dtmf_tv = ast_tvnow();
03852                if (f->len) {
03853                   if (f->len > AST_MIN_DTMF_DURATION)
03854                      chan->emulate_dtmf_duration = f->len;
03855                   else 
03856                      chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION;
03857                } else
03858                   chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION;
03859                ast_log(LOG_DTMF, "DTMF begin emulation of '%c' with duration %u queued on %s\n", f->subclass.integer, chan->emulate_dtmf_duration, ast_channel_name(chan));
03860             }
03861             if (chan->audiohooks) {
03862                struct ast_frame *old_frame = f;
03863                /*!
03864                 * \todo XXX It is possible to write a digit to the audiohook twice
03865                 * if the digit was originally read while the channel was in autoservice. */
03866                f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
03867                if (old_frame != f)
03868                   ast_frfree(old_frame);
03869             }
03870          } else {
03871             struct timeval now = ast_tvnow();
03872             if (ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
03873                ast_log(LOG_DTMF, "DTMF end accepted with begin '%c' on %s\n", f->subclass.integer, ast_channel_name(chan));
03874                ast_clear_flag(chan, AST_FLAG_IN_DTMF);
03875                if (!f->len)
03876                   f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
03877 
03878                /* detect tones that were received on
03879                 * the wire with durations shorter than
03880                 * AST_MIN_DTMF_DURATION and set f->len
03881                 * to the actual duration of the DTMF
03882                 * frames on the wire.  This will cause
03883                 * dtmf emulation to be triggered later
03884                 * on.
03885                 */
03886                if (ast_tvdiff_ms(now, chan->dtmf_tv) < AST_MIN_DTMF_DURATION) {
03887                   f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
03888                   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));
03889                }
03890             } else if (!f->len) {
03891                ast_log(LOG_DTMF, "DTMF end accepted without begin '%c' on %s\n", f->subclass.integer, ast_channel_name(chan));
03892                f->len = AST_MIN_DTMF_DURATION;
03893             }
03894             if (f->len < AST_MIN_DTMF_DURATION && !ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)) {
03895                ast_log(LOG_DTMF, "DTMF end '%c' has duration %ld but want minimum %d, emulating on %s\n", f->subclass.integer, f->len, AST_MIN_DTMF_DURATION, ast_channel_name(chan));
03896                ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
03897                chan->emulate_dtmf_digit = f->subclass.integer;
03898                chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION - f->len;
03899                ast_frfree(f);
03900                f = &ast_null_frame;
03901             } else {
03902                ast_log(LOG_DTMF, "DTMF end passthrough '%c' on %s\n", f->subclass.integer, ast_channel_name(chan));
03903                if (f->len < AST_MIN_DTMF_DURATION) {
03904                   f->len = AST_MIN_DTMF_DURATION;
03905                }
03906                chan->dtmf_tv = now;
03907             }
03908             if (chan->audiohooks) {
03909                struct ast_frame *old_frame = f;
03910                f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
03911                if (old_frame != f)
03912                   ast_frfree(old_frame);
03913             }
03914          }
03915          break;
03916       case AST_FRAME_DTMF_BEGIN:
03917          send_dtmf_event(chan, "Received", f->subclass.integer, "Yes", "No");
03918          ast_log(LOG_DTMF, "DTMF begin '%c' received on %s\n", f->subclass.integer, ast_channel_name(chan));
03919          if ( ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_END_DTMF_ONLY | AST_FLAG_EMULATE_DTMF) || 
03920              (!ast_tvzero(chan->dtmf_tv) && 
03921                ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) ) {
03922             ast_log(LOG_DTMF, "DTMF begin ignored '%c' on %s\n", f->subclass.integer, ast_channel_name(chan));
03923             ast_frfree(f);
03924             f = &ast_null_frame;
03925          } else {
03926             ast_set_flag(chan, AST_FLAG_IN_DTMF);
03927             chan->dtmf_tv = ast_tvnow();
03928             ast_log(LOG_DTMF, "DTMF begin passthrough '%c' on %s\n", f->subclass.integer, ast_channel_name(chan));
03929          }
03930          break;
03931       case AST_FRAME_NULL:
03932          /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration
03933           * is reached , because we want to make sure we pass at least one
03934           * voice frame through before starting the next digit, to ensure a gap
03935           * between DTMF digits. */
03936          if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
03937             struct timeval now = ast_tvnow();
03938             if (!chan->emulate_dtmf_duration) {
03939                ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
03940                chan->emulate_dtmf_digit = 0;
03941             } else if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
03942                chan->emulate_dtmf_duration = 0;
03943                ast_frfree(f);
03944                f = &chan->dtmff;
03945                f->frametype = AST_FRAME_DTMF_END;
03946                f->subclass.integer = chan->emulate_dtmf_digit;
03947                f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
03948                chan->dtmf_tv = now;
03949                ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
03950                chan->emulate_dtmf_digit = 0;
03951                ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass.integer, ast_channel_name(chan));
03952                if (chan->audiohooks) {
03953                   struct ast_frame *old_frame = f;
03954                   f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
03955                   if (old_frame != f) {
03956                      ast_frfree(old_frame);
03957                   }
03958                }
03959             }
03960          }
03961          break;
03962       case AST_FRAME_VOICE:
03963          /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration
03964           * is reached , because we want to make sure we pass at least one
03965           * voice frame through before starting the next digit, to ensure a gap
03966           * between DTMF digits. */
03967          if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !chan->emulate_dtmf_duration) {
03968             ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
03969             chan->emulate_dtmf_digit = 0;
03970          }
03971 
03972          if (dropaudio || ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
03973             if (dropaudio)
03974                ast_read_generator_actions(chan, f);
03975             ast_frfree(f);
03976             f = &ast_null_frame;
03977          }
03978 
03979          if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
03980             struct timeval now = ast_tvnow();
03981             if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
03982                chan->emulate_dtmf_duration = 0;
03983                ast_frfree(f);
03984                f = &chan->dtmff;
03985                f->frametype = AST_FRAME_DTMF_END;
03986                f->subclass.integer = chan->emulate_dtmf_digit;
03987                f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
03988                chan->dtmf_tv = now;
03989                if (chan->audiohooks) {
03990                   struct ast_frame *old_frame = f;
03991                   f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
03992                   if (old_frame != f)
03993                      ast_frfree(old_frame);
03994                }
03995                ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass.integer, ast_channel_name(chan));
03996             } else {
03997                /* Drop voice frames while we're still in the middle of the digit */
03998                ast_frfree(f);
03999                f = &ast_null_frame;
04000             }
04001          } else if ((f->frametype == AST_FRAME_VOICE) && !ast_format_cap_iscompatible(chan->nativeformats, &f->subclass.format)) {
04002             /* This frame is not one of the current native formats -- drop it on the floor */
04003             char to[200];
04004             ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n",
04005                ast_channel_name(chan), ast_getformatname(&f->subclass.format), ast_getformatname_multiple(to, sizeof(to), chan->nativeformats));
04006             ast_frfree(f);
04007             f = &ast_null_frame;
04008          } else if ((f->frametype == AST_FRAME_VOICE)) {
04009             /* Send frame to audiohooks if present */
04010             if (chan->audiohooks) {
04011                struct ast_frame *old_frame = f;
04012                f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
04013                if (old_frame != f)
04014                   ast_frfree(old_frame);
04015             }
04016             if (chan->monitor && chan->monitor->read_stream ) {
04017                /* XXX what does this do ? */
04018 #ifndef MONITOR_CONSTANT_DELAY
04019                int jump = chan->outsmpl - chan->insmpl - 4 * f->samples;
04020                if (jump >= 0) {
04021                   jump = calc_monitor_jump((chan->outsmpl - chan->insmpl), ast_format_rate(&f->subclass.format), ast_format_rate(&chan->monitor->read_stream->fmt->format));
04022                   if (ast_seekstream(chan->monitor->read_stream, jump, SEEK_FORCECUR) == -1)
04023                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
04024                   chan->insmpl += (chan->outsmpl - chan->insmpl) + f->samples;
04025                } else
04026                   chan->insmpl+= f->samples;
04027 #else
04028                int jump = calc_monitor_jump((chan->outsmpl - chan->insmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format));
04029                if (jump - MONITOR_DELAY >= 0) {
04030                   if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
04031                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
04032                   chan->insmpl += chan->outsmpl - chan->insmpl;
04033                } else
04034                   chan->insmpl += f->samples;
04035 #endif
04036                if (chan->monitor->state == AST_MONITOR_RUNNING) {
04037                   if (ast_writestream(chan->monitor->read_stream, f) < 0)
04038                      ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
04039                }
04040             }
04041 
04042             if (chan->readtrans && (f = ast_translate(chan->readtrans, f, 1)) == NULL) {
04043                f = &ast_null_frame;
04044             }
04045 
04046             /* it is possible for the translation process on chan->readtrans to have
04047                produced multiple frames from the single input frame we passed it; if
04048                this happens, queue the additional frames *before* the frames we may
04049                have queued earlier. if the readq was empty, put them at the head of
04050                the queue, and if it was not, put them just after the frame that was
04051                at the end of the queue.
04052             */
04053             if (AST_LIST_NEXT(f, frame_list)) {
04054                if (!readq_tail) {
04055                   ast_queue_frame_head(chan, AST_LIST_NEXT(f, frame_list));
04056                } else {
04057                   __ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list), 0, readq_tail);
04058                }
04059                ast_frfree(AST_LIST_NEXT(f, frame_list));
04060                AST_LIST_NEXT(f, frame_list) = NULL;
04061             }
04062 
04063             /* Run generator sitting on the line if timing device not available
04064             * and synchronous generation of outgoing frames is necessary       */
04065             ast_read_generator_actions(chan, f);
04066          }
04067          break;
04068       default:
04069          /* Just pass it on! */
04070          break;
04071       }
04072    } else {
04073       /* Make sure we always return NULL in the future */
04074       if (!chan->_softhangup) {
04075          chan->_softhangup |= AST_SOFTHANGUP_DEV;
04076       }
04077       if (cause)
04078          chan->hangupcause = cause;
04079       if (chan->generator)
04080          ast_deactivate_generator(chan);
04081       /* We no longer End the CDR here */
04082    }
04083 
04084    /* High bit prints debugging */
04085    if (chan->fin & DEBUGCHAN_FLAG)
04086       ast_frame_dump(ast_channel_name(chan), f, "<<");
04087    chan->fin = FRAMECOUNT_INC(chan->fin);
04088 
04089 done:
04090    if (chan->music_state && chan->generator && chan->generator->digit && f && f->frametype == AST_FRAME_DTMF_END)
04091       chan->generator->digit(chan, f->subclass.integer);
04092 
04093    if (chan->audiohooks && ast_audiohook_write_list_empty(chan->audiohooks)) {
04094       /* The list gets recreated if audiohooks are added again later */
04095       ast_audiohook_detach_list(chan->audiohooks);
04096       chan->audiohooks = NULL;
04097    }
04098    ast_channel_unlock(chan);
04099    return f;
04100 }

struct ast_channel* __ast_request_and_dial ( const char *  type,
struct ast_format_cap cap,
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
format capabilities for requested 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 5301 of file channel.c.

References ast_channel::_state, outgoing_helper::account, ast_call(), ast_call_forward(), AST_CAUSE_NO_ANSWER, ast_cdr_alloc(), ast_cdr_answer(), ast_cdr_busy(), ast_cdr_disposition(), ast_cdr_end(), ast_cdr_failed(), AST_CDR_FLAG_ORIGINATED, ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_setapp(), ast_cdr_start(), ast_cdr_update(), ast_channel_call_forward(), ast_channel_datastore_inherit(), ast_channel_inherit_variables(), ast_channel_lock, ast_channel_lock_both, ast_channel_set_connected_line(), 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_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_copy_string(), 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_request(), ast_set_flag, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_waitfor(), cause, ast_channel::cdr, outgoing_helper::cid_name, outgoing_helper::cid_num, ast_channel::connected, ast_channel::context, outgoing_helper::context, ast_channel::exten, outgoing_helper::exten, ast_frame::frametype, handle_cause(), ast_channel::hangupcause, ast_party_connected_line::id, ast_frame_subclass::integer, LOG_NOTICE, ast_party_id::name, ast_party_id::number, outgoing_helper::parent_channel, ast_party_name::presentation, ast_party_number::presentation, ast_channel::priority, outgoing_helper::priority, 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 ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_request_and_dial(), and parkandannounce_exec().

05302 {
05303    int dummy_outstate;
05304    int cause = 0;
05305    struct ast_channel *chan;
05306    int res = 0;
05307    int last_subclass = 0;
05308    struct ast_party_connected_line connected;
05309    
05310    if (outstate)
05311       *outstate = 0;
05312    else
05313       outstate = &dummy_outstate;   /* make outstate always a valid pointer */
05314 
05315    chan = ast_request(type, cap, requestor, addr, &cause);
05316    if (!chan) {
05317       ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, addr);
05318       handle_cause(cause, outstate);
05319       return NULL;
05320    }
05321 
05322    if (oh) {
05323       if (oh->vars) {
05324          ast_set_variables(chan, oh->vars);
05325       }
05326       if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) {
05327          /*
05328           * Use the oh values instead of the function parameters for the
05329           * outgoing CallerID.
05330           */
05331          cid_num = oh->cid_num;
05332          cid_name = oh->cid_name;
05333       }
05334       if (oh->parent_channel) {
05335          /* Safely inherit variables and datastores from the parent channel. */
05336          ast_channel_lock_both(oh->parent_channel, chan);
05337          ast_channel_inherit_variables(oh->parent_channel, chan);
05338          ast_channel_datastore_inherit(oh->parent_channel, chan);
05339          ast_channel_unlock(oh->parent_channel);
05340          ast_channel_unlock(chan);
05341       }
05342       if (oh->account) {
05343          ast_channel_lock(chan);
05344          ast_cdr_setaccount(chan, oh->account);
05345          ast_channel_unlock(chan);
05346       }
05347    }
05348 
05349    ast_set_flag(chan->cdr, AST_CDR_FLAG_ORIGINATED);
05350    ast_party_connected_line_set_init(&connected, &chan->connected);
05351    if (cid_num) {
05352       connected.id.number.valid = 1;
05353       connected.id.number.str = (char *) cid_num;
05354       connected.id.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
05355    }
05356    if (cid_name) {
05357       connected.id.name.valid = 1;
05358       connected.id.name.str = (char *) cid_name;
05359       connected.id.name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
05360    }
05361    ast_channel_set_connected_line(chan, &connected, NULL);
05362 
05363    if (ast_call(chan, addr, 0)) {   /* ast_call failed... */
05364       ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, addr);
05365    } else {
05366       res = 1; /* mark success in case chan->_state is already AST_STATE_UP */
05367       while (timeout && chan->_state != AST_STATE_UP) {
05368          struct ast_frame *f;
05369          res = ast_waitfor(chan, timeout);
05370          if (res == 0) { /* timeout, treat it like ringing */
05371             *outstate = AST_CONTROL_RINGING;
05372             break;
05373          }
05374          if (res < 0) /* error or done */
05375             break;
05376          if (timeout > -1)
05377             timeout = res;
05378          if (!ast_strlen_zero(ast_channel_call_forward(chan))) {
05379             if (!(chan = ast_call_forward(NULL, chan, NULL, cap, oh, outstate))) {
05380                return NULL;
05381             }
05382             continue;
05383          }
05384 
05385          f = ast_read(chan);
05386          if (!f) {
05387             *outstate = AST_CONTROL_HANGUP;
05388             res = 0;
05389             break;
05390          }
05391          if (f->frametype == AST_FRAME_CONTROL) {
05392             switch (f->subclass.integer) {
05393             case AST_CONTROL_RINGING:  /* record but keep going */
05394                *outstate = f->subclass.integer;
05395                break;
05396 
05397             case AST_CONTROL_BUSY:
05398                ast_cdr_busy(chan->cdr);
05399                *outstate = f->subclass.integer;
05400                timeout = 0;
05401                break;
05402 
05403             case AST_CONTROL_INCOMPLETE:
05404                ast_cdr_failed(chan->cdr);
05405                *outstate = AST_CONTROL_CONGESTION;
05406                timeout = 0;
05407                break;
05408 
05409             case AST_CONTROL_CONGESTION:
05410                ast_cdr_failed(chan->cdr);
05411                *outstate = f->subclass.integer;
05412                timeout = 0;
05413                break;
05414 
05415             case AST_CONTROL_ANSWER:
05416                ast_cdr_answer(chan->cdr);
05417                *outstate = f->subclass.integer;
05418                timeout = 0;      /* trick to force exit from the while() */
05419                break;
05420 
05421             /* Ignore these */
05422             case AST_CONTROL_PROGRESS:
05423             case AST_CONTROL_PROCEEDING:
05424             case AST_CONTROL_HOLD:
05425             case AST_CONTROL_UNHOLD:
05426             case AST_CONTROL_VIDUPDATE:
05427             case AST_CONTROL_SRCUPDATE:
05428             case AST_CONTROL_SRCCHANGE:
05429             case AST_CONTROL_CONNECTED_LINE:
05430             case AST_CONTROL_REDIRECTING:
05431             case AST_CONTROL_CC:
05432             case -1:       /* Ignore -- just stopping indications */
05433                break;
05434 
05435             default:
05436                ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass.integer);
05437             }
05438             last_subclass = f->subclass.integer;
05439          }
05440          ast_frfree(f);
05441       }
05442    }
05443 
05444    /* Final fixups */
05445    if (oh) {
05446       if (!ast_strlen_zero(oh->context))
05447          ast_copy_string(chan->context, oh->context, sizeof(chan->context));
05448       if (!ast_strlen_zero(oh->exten))
05449          ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten));
05450       if (oh->priority) 
05451          chan->priority = oh->priority;
05452    }
05453    if (chan->_state == AST_STATE_UP)
05454       *outstate = AST_CONTROL_ANSWER;
05455 
05456    if (res <= 0) {
05457       ast_channel_lock(chan);
05458       if (AST_CONTROL_RINGING == last_subclass) {
05459          chan->hangupcause = AST_CAUSE_NO_ANSWER;
05460       }
05461       if (!chan->cdr && (chan->cdr = ast_cdr_alloc())) {
05462          ast_cdr_init(chan->cdr, chan);
05463       }
05464       if (chan->cdr) {
05465          char tmp[256];
05466 
05467          snprintf(tmp, sizeof(tmp), "%s/%s", type, addr);
05468          ast_cdr_setapp(chan->cdr, "Dial", tmp);
05469          ast_cdr_update(chan);
05470          ast_cdr_start(chan->cdr);
05471          ast_cdr_end(chan->cdr);
05472          /* If the cause wasn't handled properly */
05473          if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) {
05474             ast_cdr_failed(chan->cdr);
05475          }
05476       }
05477       ast_channel_unlock(chan);
05478       ast_hangup(chan);
05479       chan = NULL;
05480    }
05481    return chan;
05482 }

static void __fini_backends ( void   )  [static]

Definition at line 136 of file channel.c.

00151 {

static void __init_backends ( void   )  [static]

Definition at line 136 of file channel.c.

00151 {

static void __init_state2str_threadbuf ( void   )  [static]

Definition at line 99 of file channel.c.

00114 {

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

Definition at line 4565 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().

04566 {
04567    int num_new_samples = frame->samples;
04568    struct plc_ds *plc = datastore->data;
04569 
04570    /* As a general note, let me explain the somewhat odd calculations used when taking
04571     * the frame offset into account here. According to documentation in frame.h, the frame's
04572     * offset field indicates the number of bytes that the audio is offset. The plc->samples_buf
04573     * is not an array of bytes, but rather an array of 16-bit integers since it holds SLIN
04574     * samples. So I had two choices to make here with the offset.
04575     * 
04576     * 1. Make the offset AST_FRIENDLY_OFFSET bytes. The main downside for this is that
04577     *    I can't just add AST_FRIENDLY_OFFSET to the plc->samples_buf and have the pointer
04578     *    arithmetic come out right. I would have to do some odd casting or division for this to
04579     *    work as I wanted.
04580     * 2. Make the offset AST_FRIENDLY_OFFSET * 2 bytes. This allows the pointer arithmetic
04581     *    to work out better with the plc->samples_buf. The downside here is that the buffer's
04582     *    allocation contains an extra 64 bytes of unused space.
04583     * 
04584     * I decided to go with option 2. This is why in the calloc statement and the statement that
04585     * sets the frame's offset, AST_FRIENDLY_OFFSET is multiplied by 2.
04586     */
04587 
04588    /* If this audio frame has no samples to fill in, ignore it */
04589    if (!num_new_samples) {
04590       return;
04591    }
04592 
04593    /* First, we need to be sure that our buffer is large enough to accomodate
04594     * the samples we need to fill in. This will likely only occur on the first
04595     * frame we write.
04596     */
04597    if (plc->num_samples < num_new_samples) {
04598       ast_free(plc->samples_buf);
04599       plc->samples_buf = ast_calloc(1, (num_new_samples * sizeof(*plc->samples_buf)) + (AST_FRIENDLY_OFFSET * 2));
04600       if (!plc->samples_buf) {
04601          ast_channel_datastore_remove(chan, datastore);
04602          ast_datastore_free(datastore);
04603          return;
04604       }
04605       plc->num_samples = num_new_samples;
04606    }
04607 
04608    if (frame->datalen == 0) {
04609       plc_fillin(&plc->plc_state, plc->samples_buf + AST_FRIENDLY_OFFSET, frame->samples);
04610       frame->data.ptr = plc->samples_buf + AST_FRIENDLY_OFFSET;
04611       frame->datalen = num_new_samples * 2;
04612       frame->offset = AST_FRIENDLY_OFFSET * 2;
04613    } else {
04614       plc_rx(&plc->plc_state, frame->data.ptr, frame->samples);
04615    }
04616 }

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

Definition at line 4618 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(), and ast_datastore::data.

Referenced by ast_write().

04619 {
04620    struct ast_datastore *datastore;
04621    struct plc_ds *plc;
04622 
04623    datastore = ast_channel_datastore_find(chan, &plc_ds_info, NULL);
04624    if (datastore) {
04625       plc = datastore->data;
04626       adjust_frame_for_plc(chan, frame, datastore);
04627       return;
04628    }
04629 
04630    datastore = ast_datastore_alloc(&plc_ds_info, NULL);
04631    if (!datastore) {
04632       return;
04633    }
04634    plc = ast_calloc(1, sizeof(*plc));
04635    if (!plc) {
04636       ast_datastore_free(datastore);
04637       return;
04638    }
04639    datastore->data = plc;
04640    ast_channel_datastore_add(chan, datastore);
04641    adjust_frame_for_plc(chan, frame, datastore);
04642 }

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

Activate a given generator

Definition at line 2927 of file channel.c.

References ast_generator::alloc, ast_channel_lock, ast_channel_unlock, ast_prod(), ast_settimeout(), ast_channel::generator, generator_force(), ast_channel::generatordata, 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().

02928 {
02929    int res = 0;
02930 
02931    ast_channel_lock(chan);
02932    if (chan->generatordata) {
02933       if (chan->generator && chan->generator->release)
02934          chan->generator->release(chan, chan->generatordata);
02935       chan->generatordata = NULL;
02936    }
02937    if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) {
02938       res = -1;
02939    }
02940    if (!res) {
02941       ast_settimeout(chan, 50, generator_force, chan);
02942       chan->generator = gen;
02943    }
02944    ast_channel_unlock(chan);
02945 
02946    ast_prod(chan);
02947 
02948    return res;
02949 }

int ast_active_channels ( void   ) 

returns number of active/allocated channels

Returns:
number of active/allocated channels

Definition at line 625 of file channel.c.

References ao2_container_count(), and channels.

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

00626 {
00627    return channels ? ao2_container_count(channels) : 0;
00628 }

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 2868 of file channel.c.

References __ast_answer().

Referenced by action_bridge(), agi_exec_full(), alarmreceiver_exec(), answer_trunk_chan(), app_exec(), ast_control_streamfile(), ast_do_pickup(), ast_pickup_call(), auth_exec(), background_detect_exec(), bridge_exec(), bridge_request(), builtin_parkcall(), common_exec(), conf_exec(), confbridge_exec(), count_exec(), dahdiras_exec(), dial_exec_full(), dictate_exec(), directory_exec(), disa_exec(), eivr_comm(), handle_answer(), ices_exec(), login_exec(), minivm_accmess_exec(), minivm_greet_exec(), minivm_record_exec(), old_milliwatt_exec(), park_call_exec(), parked_call_exec(), pbx_builtin_background(), playback_exec(), privacy_exec(), read_exec(), readexten_exec(), receivefax_exec(), record_exec(), record_thread(), rpt_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(), waitfor_exec(), and zapateller_exec().

02869 {
02870    return __ast_answer(chan, 0, 1);
02871 }

void ast_begin_shutdown ( int  hangup  ) 

Initiate system shutdown -- prevents new channels from being allocated.

Parameters:
hangup If "hangup" is non-zero, all existing channels will receive soft hangups

Definition at line 615 of file channel.c.

References ao2_callback, ast_channel_softhangup_cb(), channels, OBJ_MULTIPLE, and OBJ_NODATA.

Referenced by can_safely_quit().

00616 {
00617    shutting_down = 1;
00618 
00619    if (hangup) {
00620       ao2_callback(channels, OBJ_NODATA | OBJ_MULTIPLE, ast_channel_softhangup_cb, NULL);
00621    }
00622 }

struct ast_format* ast_best_codec ( struct ast_format_cap cap,
struct ast_format result 
) [read]

Pick the best audio codec.

Pick the best codec.

Okay, ulaw is used by all telephony equipment, so start with it

Unless of course, you're a silly European, so then prefer ALAW

G.722 is better then all below, but not as common as the above... so give ulaw and alaw priority

Okay, well, signed linear is easy to translate into other stuff

G.726 is standard ADPCM, in RFC3551 packing order

G.726 is standard ADPCM, in AAL2 packing order

ADPCM has great sound quality and is still pretty easy to translate

Okay, we're down to vocoders now, so pick GSM because it's small and easier to translate and sounds pretty good

iLBC is not too bad

Speex is free, but computationally more expensive than GSM

SILK is pretty awesome.

CELT supports crazy high sample rates

Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough to use it

G.729a is faster than 723 and slightly less expensive

Down to G.723.1 which is proprietary but at least designed for voice

Definition at line 834 of file channel.c.

References ARRAY_LEN, AST_FORMAT_ADPCM, AST_FORMAT_ALAW, ast_format_cap_best_byid(), AST_FORMAT_CELT, ast_format_clear(), AST_FORMAT_G719, AST_FORMAT_G722, AST_FORMAT_G723_1, AST_FORMAT_G726, AST_FORMAT_G726_AAL2, AST_FORMAT_G729A, AST_FORMAT_GSM, AST_FORMAT_ILBC, AST_FORMAT_LPC10, AST_FORMAT_SILK, AST_FORMAT_SIREN14, AST_FORMAT_SIREN7, AST_FORMAT_SLINEAR, AST_FORMAT_SLINEAR12, AST_FORMAT_SLINEAR16, AST_FORMAT_SLINEAR192, AST_FORMAT_SLINEAR24, AST_FORMAT_SLINEAR32, AST_FORMAT_SLINEAR44, AST_FORMAT_SLINEAR48, AST_FORMAT_SLINEAR96, AST_FORMAT_SPEEX, AST_FORMAT_SPEEX16, AST_FORMAT_SPEEX32, AST_FORMAT_TESTLAW, AST_FORMAT_ULAW, ast_getformatname_multiple(), ast_log(), LOG_WARNING, and prefs.

Referenced by __oh323_new(), ast_codec_choose(), ast_iax2_new(), ast_speech_new(), bridge_make_compatible(), echo_exec(), feature_request_and_dial(), free_translation(), gtalk_new(), handle_open_receive_channel_ack_message(), iax2_best_codec(), iax2_request(), jingle_new(), local_new(), mgcp_new(), misdn_new(), multicast_rtp_request(), phone_new(), set_format(), skinny_new(), skinny_set_rtp_peer(), start_rtp(), transmit_connect(), and unistim_new().

00835 {
00836    /* This just our opinion, expressed in code.  We are asked to choose
00837       the best codec to use, given no information */
00838    static const enum ast_format_id prefs[] =
00839    {
00840       /*! Okay, ulaw is used by all telephony equipment, so start with it */
00841       AST_FORMAT_ULAW,
00842       /*! Unless of course, you're a silly European, so then prefer ALAW */
00843       AST_FORMAT_ALAW,
00844       AST_FORMAT_G719,
00845       AST_FORMAT_SIREN14,
00846       AST_FORMAT_SIREN7,
00847       AST_FORMAT_TESTLAW,
00848       /*! G.722 is better then all below, but not as common as the above... so give ulaw and alaw priority */
00849       AST_FORMAT_G722,
00850       /*! Okay, well, signed linear is easy to translate into other stuff */
00851       AST_FORMAT_SLINEAR192,
00852       AST_FORMAT_SLINEAR96,
00853       AST_FORMAT_SLINEAR48,
00854       AST_FORMAT_SLINEAR44,
00855       AST_FORMAT_SLINEAR32,
00856       AST_FORMAT_SLINEAR24,
00857       AST_FORMAT_SLINEAR16,
00858       AST_FORMAT_SLINEAR12,
00859       AST_FORMAT_SLINEAR,
00860       /*! G.726 is standard ADPCM, in RFC3551 packing order */
00861       AST_FORMAT_G726,
00862       /*! G.726 is standard ADPCM, in AAL2 packing order */
00863       AST_FORMAT_G726_AAL2,
00864       /*! ADPCM has great sound quality and is still pretty easy to translate */
00865       AST_FORMAT_ADPCM,
00866       /*! Okay, we're down to vocoders now, so pick GSM because it's small and easier to
00867           translate and sounds pretty good */
00868       AST_FORMAT_GSM,
00869       /*! iLBC is not too bad */
00870       AST_FORMAT_ILBC,
00871       /*! Speex is free, but computationally more expensive than GSM */
00872       AST_FORMAT_SPEEX32,
00873       AST_FORMAT_SPEEX16,
00874       AST_FORMAT_SPEEX,
00875       /*! SILK is pretty awesome. */
00876       AST_FORMAT_SILK,
00877       /*! CELT supports crazy high sample rates */
00878       AST_FORMAT_CELT,
00879       /*! Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough
00880           to use it */
00881       AST_FORMAT_LPC10,
00882       /*! G.729a is faster than 723 and slightly less expensive */
00883       AST_FORMAT_G729A,
00884       /*! Down to G.723.1 which is proprietary but at least designed for voice */
00885       AST_FORMAT_G723_1,
00886    };
00887    char buf[512];
00888    int x;
00889 
00890    /* Find the first preferred codec in the format given */
00891    for (x = 0; x < ARRAY_LEN(prefs); x++) {
00892       if (ast_format_cap_best_byid(cap, prefs[x], result)) {
00893          return result;
00894       }
00895    }
00896 
00897    ast_format_clear(result);
00898    ast_log(LOG_WARNING, "Don't know any of %s formats\n", ast_getformatname_multiple(buf, sizeof(buf), cap));
00899 
00900    return NULL;
00901 }

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

Find bridged channel.

Note:
This function does _not_ return a reference to the bridged channel. The reason for this is mostly historical. It _should_ return a reference, but it will take a lot of work to make the code base account for that. So, for now, the old rules still apply for how to handle this function. If this function is being used from the channel thread that owns the channel, then a reference is already held, and channel locking is not required to guarantee that the channel will stay around. If this function is used outside of the associated channel thread, the channel parameter 'chan' MUST be locked before calling this function. Also, 'chan' must remain locked for the entire time that the result of this function is being used.
Parameters:
chan Current channel
Returns:
A pointer to the bridged channel

Definition at line 6932 of file channel.c.

References ast_channel::_bridge, ast_channel_tech::bridged_channel, and ast_channel::tech.

Referenced by __analog_handle_event(), __analog_ss_thread(), __ast_channel_masquerade(), __ast_read(), __dahdi_exception(), _skinny_show_lines(), action_agents(), action_coreshowchannels(), agents_data_provider_get(), agents_show(), agents_show_online(), analog_attempt_transfer(), analog_exception(), analog_hangup(), analog_ss_thread(), ast_bridge_call(), ast_cel_report_event(), ast_channel_data_add_structure(), ast_channel_set_linkgroup(), ast_do_masquerade(), ast_rtp_instance_set_stats_vars(), ast_set_hangupsource(), ast_var_channel_bridge(), ast_var_channels_table(), attempt_transfer(), cb_events(), channel_spy(), check_bridge(), common_exec(), console_transfer(), create_jb(), dahdi_handle_event(), dahdi_hangup(), export_aoc_vars(), fax_detect_framehook(), fax_gateway_framehook(), func_channel_read(), get_refer_info(), handle_chanlist(), handle_hd_hf(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_refer(), handle_showchan(), handle_soft_key_event_message(), handle_stimulus_message(), key_call(), key_dial_page(), local_attended_transfer(), local_queryoption(), mgcp_hangup(), mgcp_ss(), misdn_attempt_transfer(), mixmonitor_thread(), my_get_sigpvt_bridged_channel(), park_call_full(), schedule_delivery(), serialize_showchan(), sip_hangup(), sip_set_rtp_peer(), skinny_transfer(), socket_process(), spandsp_fax_gateway_start(), start_spying(), startmon(), TransferCallStep1(), and unistim_hangup().

06933 {
06934    struct ast_channel *bridged;
06935    bridged = chan->_bridge;
06936    if (bridged && bridged->tech->bridged_channel)
06937       bridged = bridged->tech->bridged_channel(chan, bridged);
06938    return bridged;
06939 }

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 5610 of file channel.c.

References AST_CDR_FLAG_DIALED, ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, ast_set_flag, ast_test_flag, ast_channel_tech::call, ast_channel::cdr, and ast_channel::tech.

Referenced by __ast_request_and_dial(), alloc_playback_chan(), ast_call_forward(), attempt_reconnect(), begin_dial_channel(), connect_link(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), ring_entry(), rpt(), rpt_exec(), and wait_for_answer().

05611 {
05612    /* Place an outgoing call, but don't wait any longer than timeout ms before returning.
05613       If the remote end does not answer within the timeout, then do NOT hang up, but
05614       return anyway.  */
05615    int res = -1;
05616    /* Stop if we're a zombie or need a soft hangup */
05617    ast_channel_lock(chan);
05618    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
05619       if (chan->cdr) {
05620          ast_set_flag(chan->cdr, AST_CDR_FLAG_DIALED);
05621       }
05622       if (chan->tech->call)
05623          res = chan->tech->call(chan, addr, timeout);
05624       ast_set_flag(chan, AST_FLAG_OUTGOING);
05625    }
05626    ast_channel_unlock(chan);
05627    return res;
05628 }

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
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 5231 of file channel.c.

References outgoing_helper::account, ast_call(), AST_CDR_FLAG_ORIGINATED, ast_cdr_setaccount(), ast_channel_accountcode(), ast_channel_call_forward(), ast_channel_lock, ast_channel_lock_both, ast_channel_unlock, ast_copy_flags, ast_copy_string(), ast_hangup(), ast_log(), ast_party_connected_line_copy(), ast_party_redirecting_copy(), ast_request(), ast_set_variables(), call_forward_inherit(), cause, ast_channel::cdr, ast_channel::connected, ast_channel::context, handle_cause(), LOG_NOTICE, outgoing_helper::parent_channel, pbx_builtin_getvar_helper(), ast_channel::redirecting, S_OR, type, and outgoing_helper::vars.

Referenced by __ast_request_and_dial(), and feature_request_and_dial().

05232 {
05233    char tmpchan[256];
05234    struct ast_channel *new_chan = NULL;
05235    char *data, *type;
05236    int cause = 0;
05237    int res;
05238 
05239    /* gather data and request the new forward channel */
05240    ast_copy_string(tmpchan, ast_channel_call_forward(orig), sizeof(tmpchan));
05241    if ((data = strchr(tmpchan, '/'))) {
05242       *data++ = '\0';
05243       type = tmpchan;
05244    } else {
05245       const char *forward_context;
05246       ast_channel_lock(orig);
05247       forward_context = pbx_builtin_getvar_helper(orig, "FORWARD_CONTEXT");
05248       snprintf(tmpchan, sizeof(tmpchan), "%s@%s", ast_channel_call_forward(orig), S_OR(forward_context, orig->context));
05249       ast_channel_unlock(orig);
05250       data = tmpchan;
05251       type = "Local";
05252    }
05253    if (!(new_chan = ast_request(type, cap, orig, data, &cause))) {
05254       ast_log(LOG_NOTICE, "Unable to create channel for call forward to '%s/%s' (cause = %d)\n", type, data, cause);
05255       handle_cause(cause, outstate);
05256       ast_hangup(orig);
05257       return NULL;
05258    }
05259 
05260    /* Copy/inherit important information into new channel */
05261    if (oh) {
05262       if (oh->vars) {
05263          ast_set_variables(new_chan, oh->vars);
05264       }
05265       if (oh->parent_channel) {
05266          call_forward_inherit(new_chan, oh->parent_channel, orig);
05267       }
05268       if (oh->account) {
05269          ast_channel_lock(new_chan);
05270          ast_cdr_setaccount(new_chan, oh->account);
05271          ast_channel_unlock(new_chan);
05272       }
05273    } else if (caller) { /* no outgoing helper so use caller if avaliable */
05274       call_forward_inherit(new_chan, caller, orig);
05275    }
05276 
05277    ast_channel_lock_both(orig, new_chan);
05278    ast_copy_flags(new_chan->cdr, orig->cdr, AST_CDR_FLAG_ORIGINATED);
05279    ast_channel_accountcode_set(new_chan, ast_channel_accountcode(orig));
05280    ast_party_connected_line_copy(&new_chan->connected, &orig->connected);
05281    ast_party_redirecting_copy(&new_chan->redirecting, &orig->redirecting);
05282    ast_channel_unlock(new_chan);
05283    ast_channel_unlock(orig);
05284 
05285    /* call new channel */
05286    res = ast_call(new_chan, data, 0);
05287    if (timeout) {
05288       *timeout = res;
05289    }
05290    if (res) {
05291       ast_log(LOG_NOTICE, "Unable to call forward to channel %s/%s\n", type, (char *)data);
05292       ast_hangup(orig);
05293       ast_hangup(new_chan);
05294       return NULL;
05295    }
05296    ast_hangup(orig);
05297 
05298    return new_chan;
05299 }

void ast_cancel_shutdown ( void   ) 

Cancel a shutdown in progress.

Cancels an existing shutdown and returns to normal operation

Definition at line 631 of file channel.c.

Referenced by handle_abort_shutdown().

00632 {
00633    shutting_down = 0;
00634 }

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 752 of file channel.c.

References ARRAY_LEN, and causes.

Referenced by __transmit_response(), ast_channel_data_add_structure(), ast_do_masquerade(), ast_hangup(), dial_exec_full(), findmeexec(), sip_hangup(), and transmit_request_with_auth().

00753 {
00754    int x;
00755 
00756    for (x = 0; x < ARRAY_LEN(causes); x++) {
00757       if (causes[x].cause == cause)
00758          return causes[x].desc;
00759    }
00760 
00761    return "Unknown";
00762 }

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 6086 of file channel.c.

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

Referenced by update_name().

06087 {
06088    /* We must re-link, as the hash value will change here. */
06089    ao2_unlink(channels, chan);
06090    ast_channel_lock(chan);
06091    __ast_change_name_nolink(chan, newname);
06092    ast_channel_unlock(chan);
06093    ao2_link(channels, chan);
06094 }

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 char *  linkedid,
const int  amaflag,
const char *  name_fmt,
  ... 
) [read]

Definition at line 9534 of file channel.c.

References __ast_channel_alloc_ap().

09539 {
09540    va_list ap;
09541    struct ast_channel *result;
09542 
09543 
09544    va_start(ap, name_fmt);
09545    result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context,
09546                linkedid, amaflag, __FILE__, __LINE__, __FUNCTION__, name_fmt, ap);
09547    va_end(ap);
09548 
09549    return result;
09550 }

enum ast_bridge_result ast_channel_bridge ( struct ast_channel c0,
struct ast_channel c1,
struct ast_bridge_config config,
struct ast_frame **  fo,
struct ast_channel **  rc 
)

Bridge two channels together.

Parameters:
c0 first channel to bridge
c1 second channel to bridge
config config for the channels
fo destination frame(?)
rc destination channel(?)
Bridge two channels (c0 and c1) together. If an important frame occurs, we return that frame in *rf (remember, it could be NULL) and which channel (0 or 1) in rc

Definition at line 7286 of file channel.c.

References ast_channel::_bridge, ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_RETRY, ast_channel_clear_softhangup(), ast_channel_make_compatible(), ast_channel_name(), ast_check_hangup(), ast_check_hangup_locked(), ast_clear_flag, AST_CONTROL_SRCUPDATE, ast_debug, AST_FEATURE_PLAY_WARNING, AST_FEATURE_WARNING_ACTIVE, AST_FLAG_END_DTMF_ONLY, AST_FLAG_NBRIDGE, AST_FLAG_ZOMBIE, ast_format_cap_copy(), ast_format_cap_destroy(), ast_format_cap_dup(), ast_format_cap_identical(), ast_format_cmp(), AST_FORMAT_CMP_NOT_EQUAL, ast_framehook_list_is_empty(), ast_generic_bridge(), ast_indicate(), ast_log(), ast_samp2tv(), ast_set_flag, ast_set_owners_and_peers(), AST_SOFTHANGUP_UNBRIDGE, ast_test_flag, ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), ast_verb, ast_channel::audiohooks, ast_channel_tech::bridge, bridge_play_sounds(), bridge_playfile(), ast_bridge_config::end_sound, ast_bridge_config::feature_start_time, ast_bridge_config::feature_timer, ast_bridge_config::features_callee, ast_bridge_config::features_caller, ast_bridge_config::flags, ast_channel::framehooks, ast_channel::generator, LOG_WARNING, manager_bridge_event(), ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::nativeformats, ast_bridge_config::nexteventts, ast_bridge_config::play_warning, ast_channel::readformat, ast_channel_tech::send_digit_begin, ast_bridge_config::start_sound, ast_bridge_config::start_time, ast_channel::tech, ast_bridge_config::timelimit, update_bridge_vars(), ast_bridge_config::warning_freq, ast_bridge_config::warning_sound, and ast_channel::writeformat.

Referenced by ast_bridge_call().

07288 {
07289    enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
07290    struct ast_format_cap *o0nativeformats;
07291    struct ast_format_cap *o1nativeformats;
07292    long time_left_ms=0;
07293    char caller_warning = 0;
07294    char callee_warning = 0;
07295 
07296    *fo = NULL;
07297 
07298    if (c0->_bridge) {
07299       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
07300          ast_channel_name(c0), ast_channel_name(c0->_bridge));
07301       return -1;
07302    }
07303    if (c1->_bridge) {
07304       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
07305          ast_channel_name(c1), ast_channel_name(c1->_bridge));
07306       return -1;
07307    }
07308    
07309    /* Stop if we're a zombie or need a soft hangup */
07310    if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
07311        ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1))
07312       return -1;
07313 
07314    o0nativeformats = ast_format_cap_dup(c0->nativeformats);
07315    o1nativeformats = ast_format_cap_dup(c1->nativeformats);
07316    if (!o0nativeformats || !o1nativeformats) {
07317       ast_format_cap_destroy(o0nativeformats);
07318       ast_format_cap_destroy(o1nativeformats);
07319       ast_log(LOG_WARNING, "failed to copy native formats\n");
07320       return -1;
07321    }
07322 
07323    caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING);
07324    callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING);
07325 
07326    if (ast_tvzero(config->start_time)) {
07327       config->start_time = ast_tvnow();
07328       if (config->start_sound) {
07329          if (caller_warning) {
07330             bridge_playfile(c0, c1, config->start_sound, config->timelimit / 1000);
07331          }
07332          if (callee_warning) {
07333             bridge_playfile(c1, c0, config->start_sound, config->timelimit / 1000);
07334          }
07335       }
07336    }
07337 
07338    /* Keep track of bridge */
07339    c0->_bridge = c1;
07340    c1->_bridge = c0;
07341 
07342    ast_set_owners_and_peers(c0, c1);
07343 
07344    if (config->feature_timer && !ast_tvzero(config->nexteventts)) {
07345       config->nexteventts = ast_tvadd(config->feature_start_time, ast_samp2tv(config->feature_timer, 1000));
07346    } else if (config->timelimit) {
07347       time_left_ms = config->timelimit - ast_tvdiff_ms(ast_tvnow(), config->start_time);
07348       config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
07349       if ((caller_warning || callee_warning) && config->play_warning) {
07350          long next_warn = config->play_warning;
07351          if (time_left_ms < config->play_warning && config->warning_freq > 0) {
07352             /* At least one warning was played, which means we are returning after feature */
07353             long warns_passed = (config->play_warning - time_left_ms) / config->warning_freq;
07354             /* It is 'warns_passed * warning_freq' NOT '(warns_passed + 1) * warning_freq',
07355                because nexteventts will be updated once again in the 'if (!to)' block */
07356             next_warn = config->play_warning - warns_passed * config->warning_freq;
07357          }
07358          config->nexteventts = ast_tvsub(config->nexteventts, ast_samp2tv(next_warn, 1000));
07359       }
07360    } else {
07361       config->nexteventts.tv_sec = 0;
07362       config->nexteventts.tv_usec = 0;
07363    }
07364 
07365    if (!c0->tech->send_digit_begin)
07366       ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY);
07367    if (!c1->tech->send_digit_begin)
07368       ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY);
07369    manager_bridge_event(1, 1, c0, c1);
07370 
07371    /* Before we enter in and bridge these two together tell them both the source of audio has changed */
07372    ast_indicate(c0, AST_CONTROL_SRCUPDATE);
07373    ast_indicate(c1, AST_CONTROL_SRCUPDATE);
07374 
07375    for (/* ever */;;) {
07376       struct timeval now = { 0, };
07377       int to;
07378 
07379       to = -1;
07380 
07381       if (!ast_tvzero(config->nexteventts)) {
07382          now = ast_tvnow();
07383          to = ast_tvdiff_ms(config->nexteventts, now);
07384          if (to <= 0) {
07385             if (!config->timelimit) {
07386                res = AST_BRIDGE_COMPLETE;
07387                break;
07388             }
07389             to = 0;
07390          }
07391       }
07392 
07393       if (config->timelimit) {
07394          time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time);
07395          if (time_left_ms < to)
07396             to = time_left_ms;
07397 
07398          if (time_left_ms <= 0) {
07399             if (caller_warning && config->end_sound)
07400                bridge_playfile(c0, c1, config->end_sound, 0);
07401             if (callee_warning && config->end_sound)
07402                bridge_playfile(c1, c0, config->end_sound, 0);
07403             *fo = NULL;
07404             res = 0;
07405             break;
07406          }
07407 
07408          if (!to) {
07409             if (time_left_ms >= 5000 && config->warning_sound && config->play_warning && ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) {
07410                int t = (time_left_ms + 500) / 1000; /* round to nearest second */
07411                if (caller_warning)
07412                   bridge_playfile(c0, c1, config->warning_sound, t);
07413                if (callee_warning)
07414                   bridge_playfile(c1, c0, config->warning_sound, t);
07415             }
07416 
07417             if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000))) {
07418                config->nexteventts = ast_tvadd(config->nexteventts, ast_samp2tv(config->warning_freq, 1000));
07419             } else {
07420                config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
07421             }
07422          }
07423          ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE);
07424       }
07425 
07426       if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */
07427          if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
07428             ast_channel_clear_softhangup(c0, AST_SOFTHANGUP_UNBRIDGE);
07429          }
07430          if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
07431             ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE);
07432          }
07433          c0->_bridge = c1;
07434          c1->_bridge = c0;
07435          ast_debug(1, "Unbridge signal received. Ending native bridge.\n");
07436          continue;
07437       }
07438 
07439       /* Stop if we're a zombie or need a soft hangup */
07440       if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
07441           ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) {
07442          *fo = NULL;
07443          res = 0;
07444          ast_debug(1, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n",
07445             ast_channel_name(c0), ast_channel_name(c1),
07446             ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No",
07447             ast_check_hangup(c0) ? "Yes" : "No",
07448             ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No",
07449             ast_check_hangup(c1) ? "Yes" : "No");
07450          break;
07451       }
07452 
07453       update_bridge_vars(c0, c1);
07454 
07455       bridge_play_sounds(c0, c1);
07456 
07457       if (c0->tech->bridge &&
07458          /* if < 1 ms remains use generic bridging for accurate timing */
07459          (!config->timelimit || to > 1000 || to == 0) &&
07460           (c0->tech->bridge == c1->tech->bridge) &&
07461           !c0->monitor && !c1->monitor &&
07462           !c0->audiohooks && !c1->audiohooks &&
07463           ast_framehook_list_is_empty(c0->framehooks) && ast_framehook_list_is_empty(c1->framehooks) &&
07464           !c0->masq && !c0->masqr && !c1->masq && !c1->masqr) {
07465          int timeoutms = to - 1000 > 0 ? to - 1000 : to;
07466          /* Looks like they share a bridge method and nothing else is in the way */
07467          ast_set_flag(c0, AST_FLAG_NBRIDGE);
07468          ast_set_flag(c1, AST_FLAG_NBRIDGE);
07469          if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, timeoutms)) == AST_BRIDGE_COMPLETE) {
07470             manager_bridge_event(0, 1, c0, c1);
07471             ast_debug(1, "Returning from native bridge, channels: %s, %s\n", ast_channel_name(c0), ast_channel_name(c1));
07472 
07473             ast_clear_flag(c0, AST_FLAG_NBRIDGE);
07474             ast_clear_flag(c1, AST_FLAG_NBRIDGE);
07475 
07476             if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */
07477                continue;
07478             }
07479 
07480             c0->_bridge = NULL;
07481             c1->_bridge = NULL;
07482             ast_format_cap_destroy(o0nativeformats);
07483             ast_format_cap_destroy(o1nativeformats);
07484             return res;
07485          } else {
07486             ast_clear_flag(c0, AST_FLAG_NBRIDGE);
07487             ast_clear_flag(c1, AST_FLAG_NBRIDGE);
07488          }
07489          switch (res) {
07490          case AST_BRIDGE_RETRY:
07491             if (config->play_warning) {
07492                ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
07493             }
07494             continue;
07495          default:
07496             ast_verb(3, "Native bridging %s and %s ended\n", ast_channel_name(c0), ast_channel_name(c1));
07497             /* fallthrough */
07498          case AST_BRIDGE_FAILED_NOWARN:
07499             break;
07500          }
07501       }
07502 
07503       if (((ast_format_cmp(&c1->readformat, &c0->writeformat) == AST_FORMAT_CMP_NOT_EQUAL) ||
07504          (ast_format_cmp(&c0->readformat, &c1->writeformat) == AST_FORMAT_CMP_NOT_EQUAL) ||
07505           !ast_format_cap_identical(c0->nativeformats, o0nativeformats) ||
07506          !ast_format_cap_identical(c1->nativeformats, o1nativeformats)) &&
07507           !(c0->generator || c1->generator)) {
07508          if (ast_channel_make_compatible(c0, c1)) {
07509             ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", ast_channel_name(c0), ast_channel_name(c1));
07510             manager_bridge_event(0, 1, c0, c1);
07511             ast_format_cap_destroy(o0nativeformats);
07512             ast_format_cap_destroy(o1nativeformats);
07513             return AST_BRIDGE_FAILED;
07514          }
07515 
07516          ast_format_cap_copy(o0nativeformats, c0->nativeformats);
07517          ast_format_cap_copy(o1nativeformats, c1->nativeformats);
07518       }
07519 
07520       update_bridge_vars(c0, c1);
07521 
07522       res = ast_generic_bridge(c0, c1, config, fo, rc);
07523       if (res != AST_BRIDGE_RETRY) {
07524          break;
07525       } else if (config->feature_timer) {
07526          /* feature timer expired but has not been updated, sending to ast_bridge_call to do so */
07527          break;
07528       }
07529    }
07530 
07531    ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY);
07532    ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY);
07533 
07534    /* Now that we have broken the bridge the source will change yet again */
07535    ast_indicate(c0, AST_CONTROL_SRCUPDATE);
07536    ast_indicate(c1, AST_CONTROL_SRCUPDATE);
07537 
07538    c0->_bridge = NULL;
07539    c1->_bridge = NULL;
07540 
07541    manager_bridge_event(0, 1, c0, c1);
07542    ast_debug(1, "Bridge stops bridging channels %s and %s\n", ast_channel_name(c0), ast_channel_name(c1));
07543 
07544    ast_format_cap_destroy(o0nativeformats);
07545    ast_format_cap_destroy(o1nativeformats);
07546    return res;
07547 }

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

Definition at line 1442 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_log(), ast_strlen_zero(), CMP_MATCH, CMP_STOP, ast_channel::context, context, ast_channel::exten, exten, LOG_ERROR, ast_channel::macrocontext, and ast_channel::macroexten.

Referenced by ast_channel_get_by_exten(), and ast_channel_iterator_by_exten_new().

01443 {
01444    struct ast_channel *chan = obj;
01445    char *context = arg;
01446    char *exten = data;
01447    int ret = CMP_MATCH;
01448 
01449    if (ast_strlen_zero(exten) || ast_strlen_zero(context)) {
01450       ast_log(LOG_ERROR, "BUG! Must have a context and extension to match!\n");
01451       return CMP_STOP;
01452    }
01453 
01454    ast_channel_lock(chan);
01455    if (strcasecmp(chan->context, context) && strcasecmp(chan->macrocontext, context)) {
01456       ret = 0; /* Context match failed, continue */
01457    } else if (strcasecmp(chan->exten, exten) && strcasecmp(chan->macroexten, exten)) {
01458       ret = 0; /* Extension match failed, continue */
01459    }
01460    ast_channel_unlock(chan);
01461 
01462    return ret;
01463 }

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

Definition at line 1420 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().

01421 {
01422    struct ast_channel *chan = obj;
01423    const char *name = arg;
01424    size_t name_len = *(size_t *) data;
01425    int ret = CMP_MATCH;
01426 
01427    if (ast_strlen_zero(name)) {
01428       ast_log(LOG_ERROR, "BUG! Must supply a channel name or partial name to match!\n");
01429       return CMP_STOP;
01430    }
01431 
01432    ast_channel_lock(chan);
01433    if ((!name_len && strcasecmp(ast_channel_name(chan), name))
01434       || (name_len && strncasecmp(ast_channel_name(chan), name, name_len))) {
01435       ret = 0; /* name match failed, keep looking */
01436    }
01437    ast_channel_unlock(chan);
01438 
01439    return ret;
01440 }

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

Definition at line 1465 of file channel.c.

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

Referenced by ast_channel_get_by_name_prefix().

01466 {
01467    struct ast_channel *chan = obj;
01468    char *uniqueid = arg;
01469    size_t id_len = *(size_t *) data;
01470    int ret = CMP_MATCH;
01471 
01472    if (ast_strlen_zero(uniqueid)) {
01473       ast_log(LOG_ERROR, "BUG! Must supply a uniqueid or partial uniqueid to match!\n");
01474       return CMP_STOP;
01475    }
01476 
01477    ast_channel_lock(chan);
01478    if ((!id_len && strcasecmp(ast_channel_uniqueid(chan), uniqueid))
01479       || (id_len && strncasecmp(ast_channel_uniqueid(chan), uniqueid, id_len))) {
01480       ret = 0; /* uniqueid match failed, keep looking */
01481    }
01482    ast_channel_unlock(chan);
01483 
01484    return ret;
01485 }

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 1414 of file channel.c.

References ao2_callback_data, and channels.

Referenced by ast_cel_check_retire_linkedid(), 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_call(), handle_core_set_debug_channel(), my_ast_get_channel_by_name_locked(), pickup_by_group(), pickup_by_mark(), pickup_by_part(), and state_notify_build_xml().

01416 {
01417    return ao2_callback_data(channels, ao2_flags, cb_fn, arg, data);
01418 }

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 9440 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, and ast_datastore::data.

Referenced by ast_channel_get_cc_config_params(), dahdi_new(), local_call(), local_request(), and sip_new().

09442 {
09443    struct ast_cc_config_params *cc_params;
09444    struct ast_datastore *cc_datastore;
09445 
09446    if (!(cc_params = ast_cc_config_params_init())) {
09447       return -1;
09448    }
09449 
09450    if (!(cc_datastore = ast_datastore_alloc(&cc_channel_datastore_info, NULL))) {
09451       ast_cc_config_params_destroy(cc_params);
09452       return -1;
09453    }
09454 
09455    if (base_params) {
09456       ast_cc_copy_config_params(cc_params, base_params);
09457    }
09458    cc_datastore->data = cc_params;
09459    ast_channel_datastore_add(chan, cc_datastore);
09460    return 0;
09461 }

static void ast_channel_change_linkedid ( struct ast_channel chan,
const char *  linkedid 
) [static]

Set the channel's linkedid to the given string, and also check to see if the channel's old linkedid is now being retired

Definition at line 6225 of file channel.c.

References ast_cel_check_retire_linkedid(), ast_channel_linkedid(), and ast_strlen_zero().

Referenced by ast_channel_set_linkgroup().

06226 {
06227    /* if the linkedid for this channel is being changed from something, check... */
06228    if (!ast_strlen_zero(ast_channel_linkedid(chan)) && 0 != strcmp(ast_channel_linkedid(chan), linkedid)) {
06229       ast_cel_check_retire_linkedid(chan);
06230    }
06231 
06232    ast_channel_linkedid_set(chan, linkedid);
06233 }

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 2479 of file channel.c.

References ast_channel::_softhangup, ast_channel_lock, 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, ast_channel::readq, and ast_frame::subclass.

Referenced by __ast_pbx_run(), ast_channel_bridge(), ast_generic_bridge(), check_goto_on_transfer(), and collect_digits().

02480 {
02481    ast_channel_lock(chan);
02482 
02483    chan->_softhangup &= ~flag;
02484 
02485    if (!chan->_softhangup) {
02486       struct ast_frame *fr;
02487 
02488       /* If we have completely cleared the softhangup flag,
02489        * then we need to fully abort the hangup process.  This requires
02490        * pulling the END_OF_Q frame out of the channel frame queue if it
02491        * still happens to be there. */
02492 
02493       fr = AST_LIST_LAST(&chan->readq);
02494       if (fr && fr->frametype == AST_FRAME_CONTROL &&
02495             fr->subclass.integer == AST_CONTROL_END_OF_Q) {
02496          AST_LIST_REMOVE(&chan->readq, fr, frame_list);
02497          ast_frfree(fr);
02498       }
02499    }
02500 
02501    ast_channel_unlock(chan);
02502 }

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

Definition at line 1564 of file channel.c.

References ast_log(), CMP_STOP, and LOG_ERROR.

01565 {
01566    ast_log(LOG_ERROR, "BUG! Should never be called!\n");
01567    return CMP_STOP;
01568 }

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 672 of file channel.c.

References ast_channel_cmpwhentohangup_tv().

00673 {
00674    struct timeval when = { offset, };
00675    return ast_channel_cmpwhentohangup_tv(chan, when);
00676 }

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 657 of file channel.c.

References ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), and ast_channel::whentohangup.

Referenced by ast_channel_cmpwhentohangup().

00658 {
00659    struct timeval whentohangup;
00660 
00661    if (ast_tvzero(chan->whentohangup))
00662       return ast_tvzero(offset) ? 0 : -1;
00663 
00664    if (ast_tvzero(offset))
00665       return 1;
00666 
00667    whentohangup = ast_tvadd(offset, ast_tvnow());
00668 
00669    return ast_tvdiff_ms(whentohangup, chan->whentohangup);
00670 }

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

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

Since:
1.8 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
caller If true, then run CONNECTED_LINE_CALLER_SEND_MACRO, otherwise run CONNECTED_LINE_CALLEE_SEND_MACRO
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 9338 of file channel.c.

References ast_app_run_macro(), ast_channel_lock, ast_channel_unlock, ast_channel_update_connected_line(), ast_connected_line_parse_data(), ast_party_connected_line_copy(), ast_strdupa, ast_strlen_zero(), chanlist::connected, ast_channel::connected, ast_frame::data, ast_frame::datalen, pbx_builtin_getvar_helper(), ast_frame::ptr, and S_OR.

Referenced by __ast_read(), app_exec(), ast_bridge_call(), ast_do_pickup(), ast_generic_bridge(), atxfer_fail_cleanup(), builtin_atxfer(), feature_request_and_dial(), handle_frame(), local_bridge_loop(), parked_call_exec(), remote_bridge_loop(), and wait_for_answer().

09339 {
09340    const char *macro;
09341    const char *macro_args;
09342    int retval;
09343 
09344    ast_channel_lock(macro_chan);
09345    macro = pbx_builtin_getvar_helper(macro_chan, is_caller
09346       ? "CONNECTED_LINE_CALLER_SEND_MACRO" : "CONNECTED_LINE_CALLEE_SEND_MACRO");
09347    macro = ast_strdupa(S_OR(macro, ""));
09348    macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller
09349       ? "CONNECTED_LINE_CALLER_SEND_MACRO_ARGS" : "CONNECTED_LINE_CALLEE_SEND_MACRO_ARGS");
09350    macro_args = ast_strdupa(S_OR(macro_args, ""));
09351 
09352    if (ast_strlen_zero(macro)) {
09353       ast_channel_unlock(macro_chan);
09354       return -1;
09355    }
09356 
09357    if (is_frame) {
09358       const struct ast_frame *frame = connected_info;
09359 
09360       ast_connected_line_parse_data(frame->data.ptr, frame->datalen, &macro_chan->connected);
09361    } else {
09362       const struct ast_party_connected_line *connected = connected_info;
09363 
09364       ast_party_connected_line_copy(&macro_chan->connected, connected);
09365    }
09366    ast_channel_unlock(macro_chan);
09367 
09368    if (!(retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args))) {
09369       ast_channel_lock(macro_chan);
09370       ast_channel_update_connected_line(macro_chan, &macro_chan->connected, NULL);
09371       ast_channel_unlock(macro_chan);
09372    }
09373 
09374    return retval;
09375 }

int ast_channel_datastore_add ( struct ast_channel chan,
struct ast_datastore datastore 
)

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 2335 of file channel.c.

References ast_datastore_alloc.

02336 {
02337    return ast_datastore_alloc(info, uid);
02338 }

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 2376 of file channel.c.

References AST_LIST_TRAVERSE, ast_channel::datastores, ast_datastore::info, 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_datastores(), add_to_agi(), apply_plc(), 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_get_cc_config_params(), ast_do_masquerade(), ast_handle_cc_control_frame(), ast_ignore_cc(), ast_odbc_retrieve_transaction_obj(), ast_set_cc_interfaces_chanvar(), attended_transfer_occurred(), audiohook_volume_callback(), audiohook_volume_get(), builtin_atxfer(), calendar_event_read(), calendar_query_exec(), calendar_query_result_exec(), cc_build_payload(), chan_cleanup(), clear_dialed_interfaces(), dial_exec_full(), disable_jack_hook(), dundi_result_read(), enable_jack_hook(), enum_result_read(), exec_odbcfinish(), find_details(), find_speech(), find_transaction(), frame_trace_helper(), func_channel_read(), func_channel_write_real(), func_inheritance_write(), func_mute_write(), get_agi_cmd(), get_lock(), gosub_exec(), handle_gosub(), iax2_call(), jack_hook_callback(), jb_helper(), local_read(), local_write(), lock_fixup(), lua_get_state(), manage_parked_call(), manager_mutestream(), mark_transaction_active(), msg_data_func_read(), msg_datastore_find_or_create(), msg_func_read(), msg_q_cb(), msg_send_exec(), mute_callback(), parked_call_exec(), pitchshift_cb(), pitchshift_helper(), pop_exec(), queue_transfer_fixup(), raise_exception(), release_transaction(), return_exec(), set_security_requirements(), shared_read(), shared_write(), smdi_msg_read(), speech_background(), speech_destroy(), speex_callback(), speex_read(), speex_write(), srv_query_read(), srv_result_read(), stop_mixmonitor_exec(), try_calling(), unlock_read(), volume_callback(), and volume_write().

02377 {
02378    struct ast_datastore *datastore = NULL;
02379    
02380    if (info == NULL)
02381       return NULL;
02382 
02383    AST_LIST_TRAVERSE(&chan->datastores, datastore, entry) {
02384       if (datastore->info != info) {
02385          continue;
02386       }
02387 
02388       if (uid == NULL) {
02389          /* matched by type only */
02390          break;
02391       }
02392 
02393       if ((datastore->uid != NULL) && !strcasecmp(uid, datastore->uid)) {
02394          /* Matched by type AND uid */
02395          break;
02396       }
02397    }
02398 
02399    return datastore;
02400 }

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 2340 of file channel.c.

References ast_datastore_free().

02341 {
02342    return ast_datastore_free(datastore);
02343 }

int ast_channel_datastore_inherit ( struct ast_channel from,
struct ast_channel to 
)

Inherit datastores from a parent to a child.

Definition at line 2345 of file channel.c.

References ast_datastore_alloc, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_datastore::data, DATASTORE_INHERIT_FOREVER, ast_channel::datastores, ast_datastore_info::duplicate, ast_datastore::info, ast_datastore::inheritance, and ast_datastore::uid.

Referenced by __ast_request_and_dial(), begin_dial_channel(), call_forward_inherit(), dial_exec_full(), dial_transfer(), do_forward(), findmeexec(), local_call(), ring_entry(), and wait_for_answer().

02346 {
02347    struct ast_datastore *datastore = NULL, *datastore2;
02348 
02349    AST_LIST_TRAVERSE(&from->datastores, datastore, entry) {
02350       if (datastore->inheritance > 0) {
02351          datastore2 = ast_datastore_alloc(datastore->info, datastore->uid);
02352          if (datastore2) {
02353             datastore2->data = datastore->info->duplicate ? datastore->info->duplicate(datastore->data) : NULL;
02354             datastore2->inheritance = datastore->inheritance == DATASTORE_INHERIT_FOREVER ? DATASTORE_INHERIT_FOREVER : datastore->inheritance - 1;
02355             AST_LIST_INSERT_TAIL(&to->datastores, datastore2, entry);
02356          }
02357       }
02358    }
02359    return 0;
02360 }

int ast_channel_datastore_remove ( struct ast_channel chan,
struct ast_datastore datastore 
)

Remove a datastore from a channel.

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

Definition at line 2371 of file channel.c.

References AST_LIST_REMOVE, and ast_channel::datastores.

Referenced by acf_fetch(), acf_odbc_read(), adjust_frame_for_plc(), ast_do_masquerade(), ast_do_pickup(), chan_cleanup(), clear_dialed_interfaces(), dial_exec_full(), disable_jack_hook(), exec_odbcfinish(), frame_trace_helper(), jb_helper(), lua_get_state(), queue_transfer_fixup(), speech_background(), speech_destroy(), speex_write(), srv_query_read(), stop_mixmonitor_exec(), and try_calling().

02372 {
02373    return AST_LIST_REMOVE(&chan->datastores, datastore, entry) ? 0 : -1;
02374 }

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 1396 of file channel.c.

References AST_FLAG_DEFER_DTMF, ast_set_flag, and ast_test_flag.

Referenced by __adsi_transmit_messages(), and find_cache().

01397 {
01398    int pre = 0;
01399 
01400    if (chan) {
01401       pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF);
01402       ast_set_flag(chan, AST_FLAG_DEFER_DTMF);
01403    }
01404    return pre;
01405 }

static void ast_channel_destructor ( void *  obj  )  [static]

Free a channel structure.

Definition at line 2181 of file channel.c.

References ast_channel::alertpipe, ast_app_group_discard(), ast_cdr_discard(), AST_CEL_CHANNEL_END, ast_cel_check_retire_linkedid(), ast_cel_report_event(), ast_channel_lock, ast_channel_name(), AST_CHANNEL_NAME, ast_channel_unlock, ast_copy_string(), ast_datastore_free(), AST_DEVICE_UNKNOWN, ast_devstate_changed_literal(), ast_format_cap_destroy(), ast_free, ast_frfree, ast_jb_destroy(), AST_LIST_REMOVE_HEAD, ast_log(), AST_MAX_FDS, ast_moh_cleanup(), ast_party_caller_free(), ast_party_connected_line_free(), ast_party_dialed_free(), ast_party_redirecting_free(), ast_sched_context_destroy(), ast_string_field_free_memory, ast_timer_close(), ast_tone_zone_unref(), ast_translator_free_path(), ast_var_delete(), ast_channel::caller, ast_channel::cdr, ast_channel::connected, ast_channel::datastores, ast_channel::dialed, free, LOG_WARNING, ast_channel::monitor, ast_channel::music_state, ast_channel::nativeformats, ast_channel::pbx, ast_channel::readq, ast_channel::readtrans, ast_channel::redirecting, ast_channel::sched, ast_channel_monitor::stop, ast_channel::tech_pvt, ast_channel::timer, ast_channel::varshead, ast_channel::writetrans, and ast_channel::zone.

Referenced by __ast_channel_alloc_ap().

02182 {
02183    struct ast_channel *chan = obj;
02184    int fd;
02185 #ifdef HAVE_EPOLL
02186    int i;
02187 #endif
02188    struct ast_var_t *vardata;
02189    struct ast_frame *f;
02190    struct varshead *headp;
02191    struct ast_datastore *datastore;
02192    char device_name[AST_CHANNEL_NAME];
02193 
02194    if (ast_channel_name(chan)) {
02195       /* The string fields were initialized. */
02196       ast_cel_report_event(chan, AST_CEL_CHANNEL_END, NULL, NULL, NULL);
02197       ast_cel_check_retire_linkedid(chan);
02198    }
02199 
02200    /* Get rid of each of the data stores on the channel */
02201    ast_channel_lock(chan);
02202    while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry)))
02203       /* Free the data store */
02204       ast_datastore_free(datastore);
02205    ast_channel_unlock(chan);
02206 
02207    /* Lock and unlock the channel just to be sure nobody has it locked still
02208       due to a reference that was stored in a datastore. (i.e. app_chanspy) */
02209    ast_channel_lock(chan);
02210    ast_channel_unlock(chan);
02211 
02212    if (chan->tech_pvt) {
02213       ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", ast_channel_name(chan));
02214       ast_free(chan->tech_pvt);
02215    }
02216 
02217    if (chan->sched) {
02218       ast_sched_context_destroy(chan->sched);
02219    }
02220 
02221    if (ast_channel_name(chan)) {
02222       char *dashptr;
02223 
02224       /* The string fields were initialized. */
02225       ast_copy_string(device_name, ast_channel_name(chan), sizeof(device_name));
02226       if ((dashptr = strrchr(device_name, '-'))) {
02227          *dashptr = '\0';
02228       }
02229    } else {
02230       device_name[0] = '\0';
02231    }
02232 
02233    /* Stop monitoring */
02234    if (chan->monitor)
02235       chan->monitor->stop( chan, 0 );
02236 
02237    /* If there is native format music-on-hold state, free it */
02238    if (chan->music_state)
02239       ast_moh_cleanup(chan);
02240 
02241    /* Free translators */
02242    if (chan->readtrans)
02243       ast_translator_free_path(chan->readtrans);
02244    if (chan->writetrans)
02245       ast_translator_free_path(chan->writetrans);
02246    if (chan->pbx)
02247       ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", ast_channel_name(chan));
02248 
02249    ast_party_dialed_free(&chan->dialed);
02250    ast_party_caller_free(&chan->caller);
02251    ast_party_connected_line_free(&chan->connected);
02252    ast_party_redirecting_free(&chan->redirecting);
02253 
02254    /* Close pipes if appropriate */
02255    if ((fd = chan->alertpipe[0]) > -1)
02256       close(fd);
02257    if ((fd = chan->alertpipe[1]) > -1)
02258       close(fd);
02259    if (chan->timer) {
02260       ast_timer_close(chan->timer);
02261    }
02262 #ifdef HAVE_EPOLL
02263    for (i = 0; i < AST_MAX_FDS; i++) {
02264       if (chan->epfd_data[i])
02265          free(chan->epfd_data[i]);
02266    }
02267    close(chan->epfd);
02268 #endif
02269    while ((f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list)))
02270       ast_frfree(f);
02271    
02272    /* loop over the variables list, freeing all data and deleting list items */
02273    /* no need to lock the list, as the channel is already locked */
02274    headp = &chan->varshead;
02275    while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
02276       ast_var_delete(vardata);
02277 
02278    ast_app_group_discard(chan);
02279 
02280    /* Destroy the jitterbuffer */
02281    ast_jb_destroy(chan);
02282 
02283    if (chan->cdr) {
02284       ast_cdr_discard(chan->cdr);
02285       chan->cdr = NULL;
02286    }
02287 
02288    if (chan->zone) {
02289       chan->zone = ast_tone_zone_unref(chan->zone);
02290    }
02291 
02292    ast_string_field_free_memory(chan);
02293 
02294    if (device_name[0]) {
02295       /*
02296        * We have a device name to notify of a new state.
02297        *
02298        * Queue an unknown state, because, while we know that this particular
02299        * instance is dead, we don't know the state of all other possible
02300        * instances.
02301        */
02302       ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, device_name);
02303    }
02304 
02305    chan->nativeformats = ast_format_cap_destroy(chan->nativeformats);
02306 }

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 7186 of file channel.c.

References ast_channel_tech::early_bridge, and ast_channel::tech.

Referenced by dial_exec_full(), and wait_for_answer().

07187 {
07188    /* Make sure we can early bridge, if not error out */
07189    if (!c0->tech->early_bridge || (c1 && (!c1->tech->early_bridge || c0->tech->early_bridge != c1->tech->early_bridge)))
07190       return -1;
07191 
07192    return c0->tech->early_bridge(c0, c1);
07193 }

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 1595 of file channel.c.

References ast_channel_by_exten_cb(), and ast_channel_callback().

01596 {
01597    char *l_exten = (char *) exten;
01598    char *l_context = (char *) context;
01599 
01600    return ast_channel_callback(ast_channel_by_exten_cb, l_context, l_exten, 0);
01601 }

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

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 1570 of file channel.c.

References ast_channel_by_name_cb(), ast_channel_by_uniqueid_cb(), ast_channel_callback(), ast_strlen_zero(), 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_cli_mixmonitor(), shared_read(), and shared_write().

01571 {
01572    struct ast_channel *chan;
01573    char *l_name = (char *) name;
01574 
01575    chan = ast_channel_callback(ast_channel_by_name_cb, l_name, &name_len,
01576       (name_len == 0) /* optimize if it is a complete name match */ ? OBJ_KEY : 0);
01577    if (chan) {
01578       return chan;
01579    }
01580 
01581    if (ast_strlen_zero(l_name)) {
01582       /* We didn't have a name to search for so quit. */
01583       return NULL;
01584    }
01585 
01586    /* Now try a search for uniqueid. */
01587    return ast_channel_callback(ast_channel_by_uniqueid_cb, l_name, &name_len, 0);
01588 }

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 9502 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().

09503 {
09504    int len = size;
09505    char *slash;
09506 
09507    if (!ast_channel_queryoption(chan, AST_OPTION_CC_AGENT_TYPE, agent_type, &len, 0)) {
09508       return 0;
09509    }
09510 
09511    ast_copy_string(agent_type, ast_channel_name(chan), size);
09512    if ((slash = strchr(agent_type, '/'))) {
09513       *slash = '\0';
09514    }
09515    return 0;
09516 }

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 9463 of file channel.c.

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

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

09464 {
09465    struct ast_datastore *cc_datastore;
09466 
09467    if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) {
09468       /* If we can't find the datastore, it almost definitely means that the channel type being
09469        * used has not had its driver modified to parse CC config parameters. The best action
09470        * to take here is to create the parameters on the spot with the defaults set.
09471        */
09472       if (ast_channel_cc_params_init(chan, NULL)) {
09473          return NULL;
09474       }
09475       if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) {
09476          /* Should be impossible */
09477          return NULL;
09478       }
09479    }
09480 
09481    ast_assert(cc_datastore->data != NULL);
09482    return cc_datastore->data;
09483 }

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 9485 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(), dial_exec_full(), sip_call(), and sip_handle_cc().

09486 {
09487    int len = name_buffer_length;
09488    char *dash;
09489    if (!ast_channel_queryoption(chan, AST_OPTION_DEVICE_NAME, device_name, &len, 0)) {
09490       return 0;
09491    }
09492 
09493    /* Dang. Do it the old-fashioned way */
09494    ast_copy_string(device_name, ast_channel_name(chan), name_buffer_length);
09495    if ((dash = strrchr(device_name, '-'))) {
09496       *dash = '\0';
09497    }
09498 
09499    return 0;
09500 }

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

Definition at line 7818 of file channel.c.

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

07819 {
07820    const char *name = (flags & OBJ_KEY) ? obj : ast_channel_name((struct ast_channel *) obj);
07821 
07822    /* If the name isn't set, return 0 so that the ao2_find() search will
07823     * start in the first bucket. */
07824    if (ast_strlen_zero(name)) {
07825       return 0;
07826    }
07827 
07828    return ast_str_case_hash(name);
07829 }

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 6096 of file channel.c.

References ast_debug, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_var_assign(), ast_var_full_name(), ast_var_name(), ast_var_value(), ast_var_t::entries, and ast_channel::varshead.

Referenced by __ast_request_and_dial(), begin_dial_channel(), call_forward_inherit(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), ring_entry(), and wait_for_answer().

06097 {
06098    struct ast_var_t *current, *newvar;
06099    const char *varname;
06100 
06101    AST_LIST_TRAVERSE(&parent->varshead, current, entries) {
06102       int vartype = 0;
06103 
06104       varname = ast_var_full_name(current);
06105       if (!varname)
06106          continue;
06107 
06108       if (varname[0] == '_') {
06109          vartype = 1;
06110          if (varname[1] == '_')
06111             vartype = 2;
06112       }
06113 
06114       switch (vartype) {
06115       case 1:
06116          newvar = ast_var_assign(&varname[1], ast_var_value(current));
06117          if (newvar) {
06118             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
06119             ast_debug(1, "Copying soft-transferable variable %s.\n", ast_var_name(newvar));
06120          }
06121          break;
06122       case 2:
06123          newvar = ast_var_assign(varname, ast_var_value(current));
06124          if (newvar) {
06125             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
06126             ast_debug(1, "Copying hard-transferable variable %s.\n", ast_var_name(newvar));
06127          }
06128          break;
06129       default:
06130          ast_debug(1, "Not copying variable %s.\n", ast_var_name(current));
06131          break;
06132       }
06133    }
06134 }

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 1544 of file channel.c.

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

Referenced by action_coreshowchannels(), action_status(), ast_complete_channels(), ast_var_channel_bridge(), ast_var_channel_types_table(), ast_var_channels_table(), common_exec(), data_channels_provider_handler(), func_channels_read(), handle_chanlist(), and handle_softhangup().

01545 {
01546    struct ast_channel_iterator *i;
01547 
01548    if (!(i = ast_calloc(1, sizeof(*i)))) {
01549       return NULL;
01550    }
01551 
01552    i->simple_iterator = ao2_iterator_init(channels, 0);
01553    i->active_iterator = &i->simple_iterator;
01554 
01555    return i;
01556 }

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 1504 of file channel.c.

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

Referenced by common_exec(), and pickup_by_exten().

01505 {
01506    struct ast_channel_iterator *i;
01507    char *l_exten = (char *) exten;
01508    char *l_context = (char *) context;
01509 
01510    if (!(i = ast_calloc(1, sizeof(*i)))) {
01511       return NULL;
01512    }
01513 
01514    i->active_iterator = (void *) ast_channel_callback(ast_channel_by_exten_cb,
01515       l_context, l_exten, OBJ_MULTIPLE);
01516    if (!i->active_iterator) {
01517       ast_free(i);
01518       return NULL;
01519    }
01520 
01521    return i;
01522 }

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 1524 of file channel.c.

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

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

01525 {
01526    struct ast_channel_iterator *i;
01527    char *l_name = (char *) name;
01528 
01529    if (!(i = ast_calloc(1, sizeof(*i)))) {
01530       return NULL;
01531    }
01532 
01533    i->active_iterator = (void *) ast_channel_callback(ast_channel_by_name_cb,
01534       l_name, &name_len,
01535       OBJ_MULTIPLE | (name_len == 0 /* match the whole word, so optimize */ ? OBJ_KEY : 0));
01536    if (!i->active_iterator) {
01537       ast_free(i);
01538       return NULL;
01539    }
01540 
01541    return i;
01542 }

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 1496 of file channel.c.

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

Referenced by action_coreshowchannels(), action_status(), ast_complete_channels(), ast_var_channel_bridge(), ast_var_channel_types_table(), ast_var_channels_table(), common_exec(), data_channels_provider_handler(), func_channels_read(), handle_chanlist(), handle_softhangup(), pickup_by_exten(), and softhangup_exec().

01497 {
01498    ao2_iterator_destroy(i->active_iterator);
01499    ast_free(i);
01500 
01501    return NULL;
01502 }

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 1558 of file channel.c.

References ast_channel_iterator::active_iterator, and ao2_iterator_next.

Referenced by action_coreshowchannels(), action_status(), ast_complete_channels(), ast_var_channel_bridge(), ast_var_channel_types_table(), ast_var_channels_table(), data_channels_provider_handler(), func_channels_read(), handle_chanlist(), handle_softhangup(), next_channel(), pickup_by_exten(), and softhangup_exec().

01559 {
01560    return ao2_iterator_next(i->active_iterator);
01561 }

int ast_channel_make_compatible ( struct ast_channel c0,
struct ast_channel c1 
)

Makes two channel formats compatible.

Parameters:
c0 first channel to make compatible
c1 other channel to make compatible
Set two channels to compatible formats -- call before ast_channel_bridge in general.
Returns:
Returns 0 on success and -1 if it could not be done

Definition at line 5827 of file channel.c.

References ast_channel_make_compatible_helper().

Referenced by action_bridge(), app_exec(), ast_channel_bridge(), bridge_exec(), check_compat(), dial_exec_full(), do_forward(), fax_detect_framehook(), fax_gateway_framehook(), multiplexed_bridge_join(), parked_call_exec(), simple_bridge_join(), try_calling(), and wait_for_answer().

05828 {
05829    /* Some callers do not check return code, and we must try to set all call legs correctly */
05830    int rc = 0;
05831 
05832    /* Set up translation from the chan to the peer */
05833    rc = ast_channel_make_compatible_helper(chan, peer);
05834 
05835    if (rc < 0)
05836       return rc;
05837 
05838    /* Set up translation from the peer to the chan */
05839    rc = ast_channel_make_compatible_helper(peer, chan);
05840 
05841    return rc;
05842 }

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 5769 of file channel.c.

References ast_channel_name(), ast_channel_setoption(), ast_format_cap_has_type(), ast_format_cmp(), AST_FORMAT_CMP_NOT_EQUAL, ast_format_is_slinear(), ast_format_rate(), ast_format_set(), ast_format_slin_by_rate(), AST_FORMAT_TYPE_AUDIO, ast_getformatname(), ast_log(), ast_opt_generic_plc, ast_opt_transcode_via_slin, AST_OPTION_MAKE_COMPATIBLE, ast_set_read_format(), ast_set_write_format(), ast_translate_path_steps(), ast_translator_best_choice(), ast_channel_tech::bridge, LOG_WARNING, ast_channel::nativeformats, ast_channel::readformat, ast_channel::tech, and ast_channel::writeformat.

Referenced by ast_channel_make_compatible().

05770 {
05771    struct ast_format_cap *src_cap = from->nativeformats; /* shallow copy, do not destroy */
05772    struct ast_format_cap *dst_cap = to->nativeformats;   /* shallow copy, do not destroy */
05773    struct ast_format best_src_fmt;
05774    struct ast_format best_dst_fmt;
05775    int use_slin;
05776 
05777    /* See if the channel driver can natively make these two channels compatible */
05778    if (from->tech->bridge && from->tech->bridge == to->tech->bridge &&
05779        !ast_channel_setoption(from, AST_OPTION_MAKE_COMPATIBLE, to, sizeof(struct ast_channel *), 0)) {
05780       return 0;
05781    }
05782 
05783    if ((ast_format_cmp(&from->readformat, &to->writeformat) != AST_FORMAT_CMP_NOT_EQUAL) &&
05784       (ast_format_cmp(&to->readformat, &from->writeformat) != AST_FORMAT_CMP_NOT_EQUAL)) {
05785       /* Already compatible!  Moving on ... */
05786       return 0;
05787    }
05788 
05789    /* If there's no audio in this call, don't bother with trying to find a translation path */
05790    if (!ast_format_cap_has_type(src_cap, AST_FORMAT_TYPE_AUDIO) || !ast_format_cap_has_type(dst_cap, AST_FORMAT_TYPE_AUDIO))
05791       return 0;
05792 
05793    if (ast_translator_best_choice(dst_cap, src_cap, &best_src_fmt, &best_dst_fmt) < 0) {
05794       ast_log(LOG_WARNING, "No path to translate from %s to %s\n", ast_channel_name(from), ast_channel_name(to));
05795       return -1;
05796    }
05797 
05798    /* if the best path is not 'pass through', then
05799     * transcoding is needed; if desired, force transcode path
05800     * to use SLINEAR between channels, but only if there is
05801     * no direct conversion available. If generic PLC is
05802     * desired, then transcoding via SLINEAR is a requirement
05803     */
05804    use_slin = ast_format_is_slinear(&best_src_fmt) || ast_format_is_slinear(&best_dst_fmt) ? 1 : 0;
05805    if ((ast_format_cmp(&best_src_fmt, &best_dst_fmt) == AST_FORMAT_CMP_NOT_EQUAL) &&
05806       (ast_opt_generic_plc || ast_opt_transcode_via_slin) &&
05807        (ast_translate_path_steps(&best_dst_fmt, &best_src_fmt) != 1 || use_slin)) {
05808 
05809       int best_sample_rate = ast_format_rate(&best_src_fmt) > ast_format_rate(&best_dst_fmt) ?
05810          ast_format_rate(&best_src_fmt) : ast_format_rate(&best_dst_fmt);
05811 
05812       /* pick the best signed linear format based upon what preserves the sample rate the best. */
05813       ast_format_set(&best_dst_fmt, ast_format_slin_by_rate(best_sample_rate), 0);
05814    }
05815 
05816    if (ast_set_read_format(from, &best_dst_fmt) < 0) {
05817       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %s\n", ast_channel_name(from), ast_getformatname(&best_dst_fmt));
05818       return -1;
05819    }
05820    if (ast_set_write_format(to, &best_dst_fmt) < 0) {
05821       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %s\n", ast_channel_name(to), ast_getformatname(&best_dst_fmt));
05822       return -1;
05823    }
05824    return 0;
05825 }

int ast_channel_masquerade ( struct ast_channel original,
struct ast_channel clone 
)

Weird function made for call transfers.

Parameters:
original channel to make a copy of
clone copy of the original channel
This is a very strange and freaky function used primarily for transfer. Suppose that "original" and "clone" are two channels in random situations. This function takes the guts out of "clone" and puts them into the "original" channel, then alerts the channel driver of the change, asking it to fixup any private information (like the p->owner pointer) that is affected by the change. The physical layer of the original channel is hung up.

Note:
Neither channel passed here should be locked before calling this function. This function performs deadlock avoidance involving these two channels.

Definition at line 5967 of file channel.c.

References __ast_channel_masquerade().

Referenced by ast_async_goto(), ast_do_pickup(), attempt_transfer(), builtin_atxfer(), check_availability(), check_bridge(), check_goto_on_transfer(), do_bridge_masquerade(), handle_invite_replaces(), iax_park(), masq_park_call(), sip_park(), and skinny_transfer().

05968 {
05969    return __ast_channel_masquerade(original, clone, NULL);
05970 }

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 7570 of file channel.c.

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

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

07571 {
07572    int res;
07573 
07574    ast_channel_lock(chan);
07575    if (!chan->tech->queryoption) {
07576       errno = ENOSYS;
07577       ast_channel_unlock(chan);
07578       return -1;
07579    }
07580 
07581    if (block)
07582       ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
07583 
07584    res = chan->tech->queryoption(chan, option, data, datalen);
07585    ast_channel_unlock(chan);
07586 
07587    return res;
07588 }

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 8818 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(), local_attended_transfer(), masquerade_colp_transfer(), misdn_queue_connected_line_update(), and sip_call().

08819 {
08820    unsigned char data[1024];  /* This should be large enough */
08821    size_t datalen;
08822 
08823    datalen = ast_connected_line_build_data(data, sizeof(data), connected, update);
08824    if (datalen == (size_t) -1) {
08825       return;
08826    }
08827 
08828    ast_queue_control_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen);
08829 }

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 9325 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().

09326 {
09327    unsigned char data[1024];  /* This should be large enough */
09328    size_t datalen;
09329 
09330    datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update);
09331    if (datalen == (size_t) -1) {
09332       return;
09333    }
09334 
09335    ast_queue_control_data(chan, AST_CONTROL_REDIRECTING, data, datalen);
09336 }

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 5158 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().

05159 {
05160    switch (reason) /* the following appear to be the only ones actually returned by request_and_dial */
05161    {
05162    case 0:
05163       return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)";
05164    case AST_CONTROL_HANGUP:
05165       return "Hangup";
05166    case AST_CONTROL_RING:
05167       return "Local Ring";
05168    case AST_CONTROL_RINGING:
05169       return "Remote end Ringing";
05170    case AST_CONTROL_ANSWER:
05171       return "Remote end has Answered";
05172    case AST_CONTROL_BUSY:
05173       return "Remote end is Busy";
05174    case AST_CONTROL_CONGESTION:
05175       return "Congestion (circuits busy)";
05176    default:
05177       return "Unknown Reason!!";
05178    }
05179 }

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
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, otherwise run REDIRECTING_CALLEE_SEND_MACRO
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 9377 of file channel.c.

References ast_app_run_macro(), ast_channel_lock, ast_channel_unlock, ast_channel_update_redirecting(), ast_party_redirecting_copy(), ast_redirecting_parse_data(), ast_strdupa, ast_strlen_zero(), ast_frame::data, ast_frame::datalen, pbx_builtin_getvar_helper(), ast_frame::ptr, ast_channel::redirecting, and S_OR.

Referenced by ast_bridge_call(), ast_generic_bridge(), call_forward_inherit(), do_forward(), feature_request_and_dial(), handle_frame(), local_bridge_loop(), remote_bridge_loop(), and wait_for_answer().

09378 {
09379    const char *macro;
09380    const char *macro_args;
09381    int retval;
09382 
09383    ast_channel_lock(macro_chan);
09384    macro = pbx_builtin_getvar_helper(macro_chan, is_caller
09385       ? "REDIRECTING_CALLER_SEND_MACRO" : "REDIRECTING_CALLEE_SEND_MACRO");
09386    macro = ast_strdupa(S_OR(macro, ""));
09387    macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller
09388       ? "REDIRECTING_CALLER_SEND_MACRO_ARGS" : "REDIRECTING_CALLEE_SEND_MACRO_ARGS");
09389    macro_args = ast_strdupa(S_OR(macro_args, ""));
09390 
09391    if (ast_strlen_zero(macro)) {
09392       ast_channel_unlock(macro_chan);
09393       return -1;
09394    }
09395 
09396    if (is_frame) {
09397       const struct ast_frame *frame = redirecting_info;
09398 
09399       ast_redirecting_parse_data(frame->data.ptr, frame->datalen, &macro_chan->redirecting);
09400    } else {
09401       const struct ast_party_redirecting *redirecting = redirecting_info;
09402 
09403       ast_party_redirecting_copy(&macro_chan->redirecting, redirecting);
09404    }
09405    ast_channel_unlock(macro_chan);
09406 
09407    retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args);
09408    if (!retval) {
09409       ast_channel_lock(macro_chan);
09410       ast_channel_update_redirecting(macro_chan, &macro_chan->redirecting, NULL);
09411       ast_channel_unlock(macro_chan);
09412    }
09413 
09414    return retval;
09415 }

int ast_channel_register ( const struct ast_channel_tech tech  ) 

Register a new telephony channel in Asterisk.

Register a channel technology (a new channel driver) Called by a channel module to register the kind of channels it supports.

Definition at line 679 of file channel.c.

References ast_calloc, ast_debug, ast_log(), AST_RWLIST_INSERT_HEAD, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, ast_channel_tech::description, LOG_WARNING, chanlist::tech, and ast_channel_tech::type.

Referenced by load_module(), and unload_module().

00680 {
00681    struct chanlist *chan;
00682 
00683    AST_RWLIST_WRLOCK(&backends);
00684 
00685    AST_RWLIST_TRAVERSE(&backends, chan, list) {
00686       if (!strcasecmp(tech->type, chan->tech->type)) {
00687          ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type);
00688          AST_RWLIST_UNLOCK(&backends);
00689          return -1;
00690       }
00691    }
00692 
00693    if (!(chan = ast_calloc(1, sizeof(*chan)))) {
00694       AST_RWLIST_UNLOCK(&backends);
00695       return -1;
00696    }
00697    chan->tech = tech;
00698    AST_RWLIST_INSERT_HEAD(&backends, chan, list);
00699 
00700    ast_debug(1, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description);
00701 
00702    ast_verb(2, "Registered channel type '%s' (%s)\n", chan->tech->type, chan->tech->description);
00703 
00704    AST_RWLIST_UNLOCK(&backends);
00705 
00706    return 0;
00707 }

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

Unlink and release reference to a channel.

This function will unlink the channel from the global channels container if it is still there and also release the current reference to the channel.

Returns:
NULL, convenient for clearing invalid pointers
Note:
Absolutely _NO_ channel locks should be held before calling this function.
Since:
1.8

Definition at line 1702 of file channel.c.

References ao2_unlink, ast_channel_unref, and channels.

Referenced by agent_cleanup(), ast_do_masquerade(), ast_iax2_new(), ast_request(), bridge_request(), do_notify(), gtalk_newcall(), local_new(), and local_request().

01703 {
01704    /* Safe, even if already unlinked. */
01705    ao2_unlink(channels, chan);
01706    return ast_channel_unref(chan);
01707 }

int ast_channel_sendhtml ( struct ast_channel channel,
int  subclass,
const char *  data,
int  datalen 
)

Sends HTML on given channel Send HTML or URL on link.

Returns:
0 on success or -1 on failure

Definition at line 5756 of file channel.c.

References ast_channel_tech::send_html, and ast_channel::tech.

Referenced by agent_sendhtml(), ast_channel_sendurl(), and wait_for_answer().

05757 {
05758    if (chan->tech->send_html)
05759       return chan->tech->send_html(chan, subclass, data, datalen);
05760    return -1;
05761 }

int ast_channel_sendurl ( struct ast_channel channel,
const char *  url 
)

Sends a URL on a given link Send URL on link.

Returns:
0 on success or -1 on failure

Definition at line 5763 of file channel.c.

References ast_channel_sendhtml(), and AST_HTML_URL.

Referenced by dial_exec_full(), sendurl_exec(), and try_calling().

05764 {
05765    return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1);
05766 }

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.

Since:
1.8
Parameters:
chan Asterisk channel to set caller id information
caller Caller id information
update What caller information to update. NULL if all.
Returns:
Nothing
Note:
The channel does not need to be locked before calling this function.

Definition at line 6851 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_party_caller_set(), and ast_channel::caller.

06852 {
06853    if (&chan->caller == caller) {
06854       /* Don't set to self */
06855       return;
06856    }
06857 
06858    ast_channel_lock(chan);
06859    ast_party_caller_set(&chan->caller, caller, update);
06860    ast_channel_unlock(chan);
06861 }

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.

Since:
1.8
Parameters:
chan Asterisk channel to set caller id information
caller Caller id information
update What caller information to update. NULL if all.
Returns:
Nothing
Note:
The channel does not need to be locked before calling this function.

Definition at line 6863 of file channel.c.

References ast_cdr_setcid(), ast_channel_lock, ast_channel_unlock, ast_party_caller_set(), ast_channel::caller, ast_channel::cdr, ast_party_caller::id, ast_party_id::name, ast_party_id::number, report_new_callerid(), S_COR, ast_party_name::str, ast_party_number::str, ast_party_name::valid, and ast_party_number::valid.

Referenced by callerid_write(), dial_exec_full(), do_forward(), misdn_update_caller_id(), and ring_entry().

06864 {
06865    const char *pre_set_number;
06866    const char *pre_set_name;
06867 
06868    if (&chan->caller == caller) {
06869       /* Don't set to self */
06870       return;
06871    }
06872 
06873    ast_channel_lock(chan);
06874    pre_set_number =
06875       S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL);
06876    pre_set_name = S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL);
06877    ast_party_caller_set(&chan->caller, caller, update);
06878    if (S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL)
06879          != pre_set_number
06880       || S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL)
06881          != pre_set_name) {
06882       /* The caller id name or number changed. */
06883       report_new_callerid(chan);
06884    }
06885    if (chan->cdr) {
06886       ast_cdr_setcid(chan->cdr, chan);
06887    }
06888    ast_channel_unlock(chan);
06889 }

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.

Since:
1.8
Parameters:
chan Asterisk channel to set connected line information
connected Connected line information
update What connected line information to update. NULL if all.
Returns:
Nothing
Note:
The channel does not need to be locked before calling this function.

Definition at line 8178 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_party_connected_line_set(), and ast_channel::connected.

Referenced by __ast_request_and_dial(), ast_indicate_data(), connectedline_write(), dial_exec_full(), and feature_request_and_dial().

08179 {
08180    if (&chan->connected == connected) {
08181       /* Don't set to self */
08182       return;
08183    }
08184 
08185    ast_channel_lock(chan);
08186    ast_party_connected_line_set(&chan->connected, connected, update);
08187    ast_channel_unlock(chan);
08188 }

void ast_channel_set_fd ( struct ast_channel chan,
int  which,
int  fd 
)

Set the file descriptor on the channel

Definition at line 2403 of file channel.c.

References ast_calloc, ast_epoll_data::chan, ast_channel::fds, free, and ast_epoll_data::which.

Referenced by __ast_channel_alloc_ap(), __oh323_new(), __oh323_rtp_create(), __oh323_update_info(), alsa_new(), ast_deactivate_generator(), ast_do_masquerade(), dahdi_new(), gtalk_new(), initialize_udptl(), jb_helper(), jingle_new(), mgcp_new(), misdn_new(), my_swap_subchannels(), nbs_new(), oss_new(), phone_new(), process_sdp(), setformat(), sip_new(), skinny_new(), start_rtp(), and swap_subs().

02404 {
02405 #ifdef HAVE_EPOLL
02406    struct epoll_event ev;
02407    struct ast_epoll_data *aed = NULL;
02408 
02409    if (chan->fds[which] > -1) {
02410       epoll_ctl(chan->epfd, EPOLL_CTL_DEL, chan->fds[which], &ev);
02411       aed = chan->epfd_data[which];
02412    }
02413 
02414    /* If this new fd is valid, add it to the epoll */
02415    if (fd > -1) {
02416       if (!aed && (!(aed = ast_calloc(1, sizeof(*aed)))))
02417          return;
02418       
02419       chan->epfd_data[which] = aed;
02420       aed->chan = chan;
02421       aed->which = which;
02422       
02423       ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP;
02424       ev.data.ptr = aed;
02425       epoll_ctl(chan->epfd, EPOLL_CTL_ADD, fd, &ev);
02426    } else if (aed) {
02427       /* We don't have to keep around this epoll data structure now */
02428       free(aed);
02429       chan->epfd_data[which] = NULL;
02430    }
02431 #endif
02432    chan->fds[which] = fd;
02433    return;
02434 }

void ast_channel_set_linkgroup ( struct ast_channel chan,
struct ast_channel peer 
)

Propagate the oldest linkedid between associated channels.

propagate the linked id between chan and peer

Definition at line 6240 of file channel.c.

References ast_channel::_bridge, ast_bridged_channel(), ast_channel_change_linkedid(), ast_channel_linkedid(), ast_channel_uniqueid(), ast_strdupa, and oldest_linkedid().

Referenced by ast_bridge_call(), and ast_do_masquerade().

06241 {
06242    const char* linkedid=NULL;
06243    struct ast_channel *bridged;
06244 
06245    linkedid = oldest_linkedid(ast_channel_linkedid(chan), ast_channel_linkedid(peer));
06246    linkedid = oldest_linkedid(linkedid, ast_channel_uniqueid(chan));
06247    linkedid = oldest_linkedid(linkedid, ast_channel_uniqueid(peer));
06248    if (chan->_bridge) {
06249       bridged = ast_bridged_channel(chan);
06250       if (bridged != peer) {
06251          linkedid = oldest_linkedid(linkedid, ast_channel_linkedid(bridged));
06252          linkedid = oldest_linkedid(linkedid, ast_channel_uniqueid(bridged));
06253       }
06254    }
06255    if (peer->_bridge) {
06256       bridged = ast_bridged_channel(peer);
06257       if (bridged != chan) {
06258          linkedid = oldest_linkedid(linkedid, ast_channel_linkedid(bridged));
06259          linkedid = oldest_linkedid(linkedid, ast_channel_uniqueid(bridged));
06260       }
06261    }
06262 
06263    /* just in case setting a stringfield to itself causes problems */
06264    linkedid = ast_strdupa(linkedid);
06265 
06266    ast_channel_change_linkedid(chan, linkedid);
06267    ast_channel_change_linkedid(peer, linkedid);
06268    if (chan->_bridge) {
06269       bridged = ast_bridged_channel(chan);
06270       if (bridged != peer) {
06271          ast_channel_change_linkedid(bridged, linkedid);
06272       }
06273    }
06274    if (peer->_bridge) {
06275       bridged = ast_bridged_channel(peer);
06276       if (bridged != chan) {
06277          ast_channel_change_linkedid(bridged, linkedid);
06278       }
06279    }
06280 }

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.

Since:
1.8
Parameters:
chan Asterisk channel to set redirecting id information
redirecting Redirecting id information
update What redirecting information to update. NULL if all.
Returns:
Nothing
Note:
The channel does not need to be locked before calling this function.

Definition at line 8831 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_party_redirecting_set(), and ast_channel::redirecting.

Referenced by ast_indicate_data(), do_forward(), handle_request_invite(), handle_response(), misdn_copy_redirecting_to_ast(), redirecting_write(), and wait_for_answer().

08832 {
08833    if (&chan->redirecting == redirecting) {
08834       /* Don't set to self */
08835       return;
08836    }
08837 
08838    ast_channel_lock(chan);
08839    ast_party_redirecting_set(&chan->redirecting, redirecting, update);
08840    ast_channel_unlock(chan);
08841 }

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

Sets an option on a channel.

Parameters:
channel channel to set options on
option option to change
data data specific to option
datalen length of the data
block blocking or not
Set an option on a channel (see frame.h), optionally blocking awaiting the reply
Returns:
0 on success and -1 on failure

Definition at line 7550 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_log(), errno, LOG_ERROR, ast_channel_tech::setoption, and ast_channel::tech.

Referenced by analog_hangup(), ast_bridge_call(), ast_channel_make_compatible_helper(), common_exec(), conf_run(), dahdi_hangup(), dial_exec_full(), func_channel_write(), func_channel_write_real(), handle_tddmode(), play_record_review(), rcvfax_exec(), reset_volumes(), rpt(), rpt_exec(), set_format(), set_listen_volume(), set_security_requirements(), set_talk_volume(), sndfax_exec(), try_calling(), and vm_forwardoptions().

07551 {
07552    int res;
07553 
07554    ast_channel_lock(chan);
07555    if (!chan->tech->setoption) {
07556       errno = ENOSYS;
07557       ast_channel_unlock(chan);
07558       return -1;
07559    }
07560 
07561    if (block)
07562       ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
07563 
07564    res = chan->tech->setoption(chan, option, data, datalen);
07565    ast_channel_unlock(chan);
07566 
07567    return res;
07568 }

void ast_channel_setwhentohangup ( struct ast_channel chan,
time_t  offset 
)

Set when to hang a channel up.

Parameters:
chan channel on which to check for hang up
offset offset in seconds relative to the current time of when to hang up
This function sets the absolute time out on a channel (when to hang up).

Note:
This function does not require that the channel is locked before calling it.
Returns:
Nothing
See also:
ast_channel_setwhentohangup_tv()
Version:
1.6.1 deprecated function (only had seconds precision)

Definition at line 650 of file channel.c.

References ast_channel_setwhentohangup_tv().

00651 {
00652    struct timeval when = { offset, };
00653    ast_channel_setwhentohangup_tv(chan, when);
00654 }

void ast_channel_setwhentohangup_tv ( struct ast_channel chan,
struct timeval  offset 
)

Set when to hangup channel.

Set when to hang a channel up.

Definition at line 643 of file channel.c.

References ast_null_frame, ast_queue_frame(), ast_tvadd(), ast_tvnow(), ast_tvzero(), and ast_channel::whentohangup.

Referenced by action_timeout(), ast_channel_setwhentohangup(), handle_autohangup(), and timeout_write().

00644 {
00645    chan->whentohangup = ast_tvzero(offset) ? offset : ast_tvadd(offset, ast_tvnow());
00646    ast_queue_frame(chan, &ast_null_frame);
00647    return;
00648 }

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

Definition at line 606 of file channel.c.

References ast_softhangup(), and AST_SOFTHANGUP_SHUTDOWN.

Referenced by ast_begin_shutdown().

00607 {
00608    struct ast_channel *chan = obj;
00609 
00610    ast_softhangup(chan, AST_SOFTHANGUP_SHUTDOWN);
00611 
00612    return 0;
00613 }

struct ast_silence_generator* ast_channel_start_silence_generator ( struct ast_channel chan  )  [read]

Starts a silence generator on the given channel.

Parameters:
chan The channel to generate silence on
Returns:
An ast_silence_generator pointer, or NULL if an error occurs
This function will cause SLINEAR silence to be generated on the supplied channel until it is disabled; if the channel cannot be put into SLINEAR mode then the function will fail.

Note:
The pointer returned by this function must be preserved and passed to ast_channel_stop_silence_generator when you wish to stop the silence generation.

Definition at line 8052 of file channel.c.

References ast_activate_generator(), ast_calloc, ast_channel_name(), ast_debug, ast_format_copy(), AST_FORMAT_SLINEAR, ast_free, ast_log(), ast_set_write_format_by_id(), LOG_ERROR, ast_silence_generator::old_write_format, and ast_channel::writeformat.

Referenced by __ast_play_and_record(), ast_bridge_call(), ast_dtmf_stream(), ast_readstring_full(), ast_safe_sleep_conditional(), channel_spy(), record_exec(), TransferCallStep1(), waitfor_exec(), and waitforring_exec().

08053 {
08054    struct ast_silence_generator *state;
08055 
08056    if (!(state = ast_calloc(1, sizeof(*state)))) {
08057       return NULL;
08058    }
08059 
08060    ast_format_copy(&state->old_write_format, &chan->writeformat);
08061 
08062    if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR) < 0) {
08063       ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
08064       ast_free(state);
08065       return NULL;
08066    }
08067 
08068    ast_activate_generator(chan, &silence_generator, state);
08069 
08070    ast_debug(1, "Started silence generator on '%s'\n", ast_channel_name(chan));
08071 
08072    return state;
08073 }

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.

Parameters:
chan The channel to operate on
state The ast_silence_generator pointer return by a previous call to ast_channel_start_silence_generator.
Returns:
nothing
This function will stop the operating silence generator and return the channel to its previous write format.

Definition at line 8075 of file channel.c.

References ast_channel_name(), ast_deactivate_generator(), ast_debug, ast_free, ast_log(), ast_set_write_format(), LOG_ERROR, and ast_silence_generator::old_write_format.

Referenced by __ast_play_and_record(), ast_bridge_call(), ast_dtmf_stream(), ast_readstring_full(), ast_safe_sleep_conditional(), channel_spy(), HandleCallOutgoing(), key_dial_page(), record_exec(), unistim_hangup(), waitfor_exec(), and waitforring_exec().

08076 {
08077    if (!state)
08078       return;
08079 
08080    ast_deactivate_generator(chan);
08081 
08082    ast_debug(1, "Stopped silence generator on '%s'\n", ast_channel_name(chan));
08083 
08084    if (ast_set_write_format(chan, &state->old_write_format) < 0)
08085       ast_log(LOG_ERROR, "Could not return write format to its original state\n");
08086 
08087    ast_free(state);
08088 }

int ast_channel_supports_html ( struct ast_channel channel  ) 

Checks for HTML support on a channel.

Returns:
0 if channel does not support HTML or non-zero if it does

Definition at line 5751 of file channel.c.

References ast_channel_tech::send_html, and ast_channel::tech.

Referenced by dial_exec_full(), sendurl_exec(), and try_calling().

05752 {
05753    return (chan->tech->send_html) ? 1 : 0;
05754 }

int ast_channel_transfer_masquerade ( struct ast_channel target_chan,
const struct ast_party_connected_line target_id,
int  target_held,
struct ast_channel transferee_chan,
const struct ast_party_connected_line transferee_id,
int  transferee_held 
)

Setup a masquerade to transfer a call.

Since:
1.8
Parameters:
target_chan Target of the call transfer. (Masquerade original channel)
target_id New connected line information for the target channel.
target_held TRUE if the target call is on hold.
transferee_chan Transferee of the call transfer. (Masquerade clone channel)
transferee_id New connected line information for the transferee channel.
transferee_held TRUE if the transferee call is on hold.
Party A - Transferee Party B - Transferer Party C - Target of transfer

Party B transfers A to C.

Party A is connected to bridged channel B1. Party B is connected to channels C1 and C2. Party C is connected to bridged channel B2.

Party B -- C1 == B1 -- Party A __/ / Party B -- C2 == B2 -- Party C

Bridged channel B1 is masqueraded into channel C2. Where B1 is the masquerade clone channel and C2 is the masquerade original channel.

See also:
ast_channel_masquerade()
Note:
Has the same locking requirements as ast_channel_masquerade().
Return values:
0 on success.
-1 on error.

Definition at line 6041 of file channel.c.

References __ast_channel_masquerade(), ast_calloc, ast_datastore_alloc, ast_datastore_free(), ast_datastore::data, party_connected_line_copy_transfer(), xfer_masquerade_ds::target_held, xfer_masquerade_ds::target_id, xfer_masquerade_ds::transferee_held, and xfer_masquerade_ds::transferee_id.

Referenced by analog_attempt_transfer(), and misdn_attempt_transfer().

06048 {
06049    struct ast_datastore *xfer_ds;
06050    struct xfer_masquerade_ds *xfer_colp;
06051    int res;
06052 
06053    xfer_ds = ast_datastore_alloc(&xfer_ds_info, NULL);
06054    if (!xfer_ds) {
06055       return -1;
06056    }
06057 
06058    xfer_colp = ast_calloc(1, sizeof(*xfer_colp));
06059    if (!xfer_colp) {
06060       ast_datastore_free(xfer_ds);
06061       return -1;
06062    }
06063    party_connected_line_copy_transfer(&xfer_colp->target_id, target_id);
06064    xfer_colp->target_held = target_held;
06065    party_connected_line_copy_transfer(&xfer_colp->transferee_id, transferee_id);
06066    xfer_colp->transferee_held = transferee_held;
06067    xfer_ds->data = xfer_colp;
06068 
06069    res = __ast_channel_masquerade(target_chan, transferee_chan, xfer_ds);
06070    if (res) {
06071       ast_datastore_free(xfer_ds);
06072    }
06073    return res;
06074 }

void ast_channel_undefer_dtmf ( struct ast_channel chan  ) 

Unset defer DTMF flag on channel.

Undo defer. ast_read will return any DTMF characters that were queued

Definition at line 1408 of file channel.c.

References ast_clear_flag, and AST_FLAG_DEFER_DTMF.

Referenced by __adsi_transmit_messages(), find_cache(), and rpt_call().

01409 {
01410    if (chan)
01411       ast_clear_flag(chan, AST_FLAG_DEFER_DTMF);
01412 }

void ast_channel_unlink ( struct ast_channel chan  ) 

Remove a channel from the global channels container.

Parameters:
chan channel to remove
In a case where it is desired that a channel not be available in any lookups in the global channels conatiner, use this function.

Definition at line 9552 of file channel.c.

References ao2_unlink, and channels.

Referenced by create_msg_q_chan().

09553 {
09554    ao2_unlink(channels, chan);
09555 }

void ast_channel_unregister ( const struct ast_channel_tech tech  ) 

Unregister channel driver.

Unregister a channel technology.

Definition at line 710 of file channel.c.

References ast_debug, ast_free, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_END, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, chanlist::tech, and ast_channel_tech::type.

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

00711 {
00712    struct chanlist *chan;
00713 
00714    ast_debug(1, "Unregistering channel type '%s'\n", tech->type);
00715 
00716    AST_RWLIST_WRLOCK(&backends);
00717 
00718    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) {
00719       if (chan->tech == tech) {
00720          AST_LIST_REMOVE_CURRENT(list);
00721          ast_free(chan);
00722          ast_verb(2, "Unregistered channel type '%s'\n", tech->type);
00723          break;   
00724       }
00725    }
00726    AST_LIST_TRAVERSE_SAFE_END;
00727 
00728    AST_RWLIST_UNLOCK(&backends);
00729 }

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.

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 8805 of file channel.c.

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

Referenced by app_exec(), ast_channel_connected_line_macro(), ast_do_pickup(), atxfer_fail_cleanup(), builtin_atxfer(), connectedline_write(), parked_call_exec(), and wait_for_answer().

08806 {
08807    unsigned char data[1024];  /* This should be large enough */
08808    size_t datalen;
08809 
08810    datalen = ast_connected_line_build_data(data, sizeof(data), connected, update);
08811    if (datalen == (size_t) -1) {
08812       return;
08813    }
08814 
08815    ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen);
08816 }

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.

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 9312 of file channel.c.

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

Referenced by ast_channel_redirecting_macro(), call_forward_inherit(), do_forward(), redirecting_write(), and wait_for_answer().

09313 {
09314    unsigned char data[1024];  /* This should be large enough */
09315    size_t datalen;
09316 
09317    datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update);
09318    if (datalen == (size_t) -1) {
09319       return;
09320    }
09321 
09322    ast_indicate_data(chan, AST_CONTROL_REDIRECTING, data, datalen);
09323 }

void ast_channels_init ( void   ) 

struct ast_variable* ast_channeltype_list ( void   )  [read]

return an ast_variable list of channeltypes

Definition at line 202 of file channel.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_variable_new(), ast_channel_tech::description, chanlist::tech, ast_channel_tech::type, and var.

Referenced by ast_var_channel_types(), and ast_var_channel_types_table().

00203 {
00204    struct chanlist *cl;
00205    struct ast_variable *var = NULL, *prev = NULL;
00206 
00207    AST_RWLIST_RDLOCK(&backends);
00208    AST_RWLIST_TRAVERSE(&backends, cl, list) {
00209       if (prev)  {
00210          if ((prev->next = ast_variable_new(cl->tech->type, cl->tech->description, "")))
00211             prev = prev->next;
00212       } else {
00213          var = ast_variable_new(cl->tech->type, cl->tech->description, "");
00214          prev = var;
00215       }
00216    }
00217    AST_RWLIST_UNLOCK(&backends);
00218 
00219    return var;
00220 }

int ast_check_hangup ( struct ast_channel chan  ) 

Checks to see if a channel is needing hang up.

Check to see if a channel is needing hang up.

Definition at line 584 of file channel.c.

References ast_channel::_softhangup, ast_debug, AST_SOFTHANGUP_TIMEOUT, ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), and ast_channel::whentohangup.

Referenced by __ast_pbx_run(), __ast_read(), _macro_exec(), agent_indicate(), agi_exec(), agi_handle_command(), announce_thread(), ast_bridge_call(), ast_call(), ast_channel_bridge(), ast_check_hangup_locked(), ast_indicate_data(), ast_raw_answer(), ast_readstring_full(), ast_recvtext(), ast_rtp_instance_bridge(), ast_sendtext(), ast_transfer(), ast_udptl_bridge(), ast_waitfordigit_full(), ast_write(), autoservice_run(), bridge_call_thread(), bridge_exec(), builtin_atxfer(), call_forward_inherit(), channel_spy(), check_bridge(), common_exec(), conf_play(), conf_run(), dahdi_sendtext(), dahdi_setoption(), dial_exec_full(), dundi_lookup_internal(), eagi_exec(), eivr_comm(), feature_request_and_dial(), findmeexec(), func_channel_read(), handle_sendimage(), iax2_bridge(), launch_asyncagi(), local_bridge_loop(), local_fixup(), lua_check_hangup(), ospfinished_exec(), pbx_builtin_incomplete(), pbx_builtin_waitexten(), pbx_exec(), read_exec(), readexten_exec(), remote_bridge_loop(), rpt(), rpt_exec(), run_agi(), run_ras(), try_calling(), and wait_for_answer().

00585 {
00586    if (chan->_softhangup)     /* yes if soft hangup flag set */
00587       return 1;
00588    if (ast_tvzero(chan->whentohangup)) /* no if no hangup scheduled */
00589       return 0;
00590    if (ast_tvdiff_ms(chan->whentohangup, ast_tvnow()) > 0)     /* no if hangup time has not come yet. */
00591       return 0;
00592    ast_debug(4, "Hangup time has come: %" PRIi64 "\n", ast_tvdiff_ms(chan->whentohangup, ast_tvnow()));
00593    chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT; /* record event */
00594    return 1;
00595 }

int ast_check_hangup_locked ( struct ast_channel chan  ) 

Definition at line 597 of file channel.c.

References ast_channel_lock, ast_channel_unlock, and ast_check_hangup().

Referenced by action_redirect(), ast_channel_bridge(), and bridge_channel_feature().

00598 {
00599    int res;
00600    ast_channel_lock(chan);
00601    res = ast_check_hangup(chan);
00602    ast_channel_unlock(chan);
00603    return res;
00604 }

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.

Since:
1.8
Parameters:
data Buffer to fill with the frame data
datalen Size of the buffer to fill
connected Connected line information
update What connected line information to build. NULL if all.
Return values:
-1 if error
Amount of data buffer used

Definition at line 8545 of file channel.c.

References AST_CONNECTED_LINE_ID_PRESENTATION, AST_CONNECTED_LINE_NAME, AST_CONNECTED_LINE_NAME_CHAR_SET, AST_CONNECTED_LINE_NAME_PRESENTATION, AST_CONNECTED_LINE_NAME_VALID, AST_CONNECTED_LINE_NUMBER, AST_CONNECTED_LINE_NUMBER_PLAN, AST_CONNECTED_LINE_NUMBER_PRESENTATION, AST_CONNECTED_LINE_NUMBER_VALID, AST_CONNECTED_LINE_SOURCE, AST_CONNECTED_LINE_SUBADDRESS, AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN, AST_CONNECTED_LINE_SUBADDRESS_TYPE, AST_CONNECTED_LINE_SUBADDRESS_VALID, AST_CONNECTED_LINE_TAG, AST_CONNECTED_LINE_VERSION, ast_log(), ast_set_party_connected_line::id, ast_party_connected_line::id, LOG_WARNING, ast_party_id_ies::name, party_id_build_data(), ast_party_connected_line::source, ast_party_name_ies::str, and value.

Referenced by ast_channel_queue_connected_line_update(), ast_channel_update_connected_line(), local_attended_transfer(), local_indicate(), and masquerade_colp_transfer().

08546 {
08547    int32_t value;
08548    size_t pos = 0;
08549    int res;
08550 
08551    static const struct ast_party_id_ies ies = {
08552       .name.str = AST_CONNECTED_LINE_NAME,
08553       .name.char_set = AST_CONNECTED_LINE_NAME_CHAR_SET,
08554       .name.presentation = AST_CONNECTED_LINE_NAME_PRESENTATION,
08555       .name.valid = AST_CONNECTED_LINE_NAME_VALID,
08556 
08557       .number.str = AST_CONNECTED_LINE_NUMBER,
08558       .number.plan = AST_CONNECTED_LINE_NUMBER_PLAN,
08559       .number.presentation = AST_CONNECTED_LINE_NUMBER_PRESENTATION,
08560       .number.valid = AST_CONNECTED_LINE_NUMBER_VALID,
08561 
08562       .subaddress.str = AST_CONNECTED_LINE_SUBADDRESS,
08563       .subaddress.type = AST_CONNECTED_LINE_SUBADDRESS_TYPE,
08564       .subaddress.odd_even_indicator = AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN,
08565       .subaddress.valid = AST_CONNECTED_LINE_SUBADDRESS_VALID,
08566 
08567       .tag = AST_CONNECTED_LINE_TAG,
08568       .combined_presentation = AST_CONNECTED_LINE_ID_PRESENTATION,
08569    };
08570 
08571    /*
08572     * The size of integer values must be fixed in case the frame is
08573     * shipped to another machine.
08574     */
08575 
08576    /* Connected line frame version */
08577    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08578       ast_log(LOG_WARNING, "No space left for connected line frame version\n");
08579       return -1;
08580    }
08581    data[pos++] = AST_CONNECTED_LINE_VERSION;
08582    data[pos++] = 1;
08583    data[pos++] = 2;/* Version 1 did not have a version ie */
08584 
08585    res = party_id_build_data(data + pos, datalen - pos, &connected->id,
08586       "connected line", &ies, update ? &update->id : NULL);
08587    if (res < 0) {
08588       return -1;
08589    }
08590    pos += res;
08591 
08592    /* Connected line source */
08593    if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
08594       ast_log(LOG_WARNING, "No space left for connected line source\n");
08595       return -1;
08596    }
08597    data[pos++] = AST_CONNECTED_LINE_SOURCE;
08598    data[pos++] = sizeof(value);
08599    value = htonl(connected->source);
08600    memcpy(data + pos, &value, sizeof(value));
08601    pos += sizeof(value);
08602 
08603    return pos;
08604 }

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.

Since:
1.8
Parameters:
dest Destination connected line information
src Source caller information
Returns:
Nothing
Note:
Assumes locks are already acquired

Definition at line 8163 of file channel.c.

References ast_party_caller::ani, ast_party_connected_line::ani, ast_party_caller::ani2, ast_party_connected_line::ani2, ast_party_id_copy(), ast_party_caller::id, and ast_party_connected_line::id.

Referenced by app_exec(), ast_do_pickup(), begin_dial_channel(), builtin_atxfer(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), local_call(), parked_call_exec(), ring_entry(), and wait_for_answer().

08164 {
08165    ast_party_id_copy(&dest->id, &src->id);
08166    ast_party_id_copy(&dest->ani, &src->ani);
08167    dest->ani2 = src->ani2;
08168 }

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.

Since:
1.8
Parameters:
dest Destination caller information
src Source connected line information
Returns:
Nothing
Note:
Assumes locks are already acquired

Definition at line 8170 of file channel.c.

References ast_party_connected_line::ani, ast_party_caller::ani, ast_party_connected_line::ani2, ast_party_caller::ani2, ast_party_id_copy(), ast_party_connected_line::id, and ast_party_caller::id.

Referenced by local_call(), and local_indicate().

08171 {
08172    ast_party_id_copy(&dest->id, &src->id);
08173    ast_party_id_copy(&dest->ani, &src->ani);
08174 
08175    dest->ani2 = src->ani2;
08176 }

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.

Since:
1.8
Parameters:
data Buffer with the frame data to parse
datalen Size of the buffer
connected Extracted connected line information
Return values:
0 on success.
-1 on error.
Note:
The filled in connected line structure needs to be initialized by ast_party_connected_line_set_init() before calling. If defaults are not required use ast_party_connected_line_init().

The filled in connected line structure needs to be destroyed by ast_party_connected_line_free() when it is no longer needed.

Definition at line 8606 of file channel.c.

References AST_CONNECTED_LINE_ID_PRESENTATION, AST_CONNECTED_LINE_NAME, AST_CONNECTED_LINE_NAME_CHAR_SET, AST_CONNECTED_LINE_NAME_PRESENTATION, AST_CONNECTED_LINE_NAME_VALID, AST_CONNECTED_LINE_NUMBER, AST_CONNECTED_LINE_NUMBER_PLAN, AST_CONNECTED_LINE_NUMBER_PRESENTATION, AST_CONNECTED_LINE_NUMBER_VALID, AST_CONNECTED_LINE_SOURCE, AST_CONNECTED_LINE_SUBADDRESS, AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN, AST_CONNECTED_LINE_SUBADDRESS_TYPE, AST_CONNECTED_LINE_SUBADDRESS_VALID, AST_CONNECTED_LINE_TAG, AST_CONNECTED_LINE_VERSION, ast_debug, ast_free, ast_log(), ast_malloc, AST_PARTY_CHAR_SET_ISO8859_1, ast_party_name::char_set, ast_party_id_ies::combined_presentation, ast_party_connected_line::id, LOG_WARNING, ast_party_id::name, ast_party_id::number, ast_party_subaddress::odd_even_indicator, ast_party_number::plan, ast_party_number::presentation, ast_party_name::presentation, ast_party_connected_line::source, ast_party_subaddress::str, ast_party_number::str, ast_party_name::str, ast_party_id::subaddress, ast_party_id::tag, ast_party_subaddress::type, ast_party_subaddress::valid, ast_party_number::valid, ast_party_name::valid, and value.

Referenced by __ast_read(), ast_channel_connected_line_macro(), ast_indicate_data(), feature_request_and_dial(), socket_process(), wait_for_answer(), and wait_for_winner().

08607 {
08608    size_t pos;
08609    unsigned char ie_len;
08610    unsigned char ie_id;
08611    int32_t value;
08612    int frame_version = 1;
08613    int combined_presentation = 0;
08614    int got_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */
08615 
08616    for (pos = 0; pos < datalen; pos += ie_len) {
08617       if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) {
08618          ast_log(LOG_WARNING, "Invalid connected line update\n");
08619          return -1;
08620       }
08621       ie_id = data[pos++];
08622       ie_len = data[pos++];
08623       if (datalen < pos + ie_len) {
08624          ast_log(LOG_WARNING, "Invalid connected line update\n");
08625          return -1;
08626       }
08627 
08628       switch (ie_id) {
08629 /* Connected line party frame version */
08630       case AST_CONNECTED_LINE_VERSION:
08631          if (ie_len != 1) {
08632             ast_log(LOG_WARNING, "Invalid connected line frame version (%u)\n",
08633                (unsigned) ie_len);
08634             break;
08635          }
08636          frame_version = data[pos];
08637          break;
08638 /* Connected line party id name */
08639       case AST_CONNECTED_LINE_NAME:
08640          ast_free(connected->id.name.str);
08641          connected->id.name.str = ast_malloc(ie_len + 1);
08642          if (connected->id.name.str) {
08643             memcpy(connected->id.name.str, data + pos, ie_len);
08644             connected->id.name.str[ie_len] = 0;
08645          }
08646          break;
08647       case AST_CONNECTED_LINE_NAME_CHAR_SET:
08648          if (ie_len != 1) {
08649             ast_log(LOG_WARNING, "Invalid connected line name char set (%u)\n",
08650                (unsigned) ie_len);
08651             break;
08652          }
08653          connected->id.name.char_set = data[pos];
08654          break;
08655       case AST_CONNECTED_LINE_NAME_PRESENTATION:
08656          if (ie_len != 1) {
08657             ast_log(LOG_WARNING, "Invalid connected line name presentation (%u)\n",
08658                (unsigned) ie_len);
08659             break;
08660          }
08661          connected->id.name.presentation = data[pos];
08662          break;
08663       case AST_CONNECTED_LINE_NAME_VALID:
08664          if (ie_len != 1) {
08665             ast_log(LOG_WARNING, "Invalid connected line name valid (%u)\n",
08666                (unsigned) ie_len);
08667             break;
08668          }
08669          connected->id.name.valid = data[pos];
08670          break;
08671 /* Connected line party id number */
08672       case AST_CONNECTED_LINE_NUMBER:
08673          ast_free(connected->id.number.str);
08674          connected->id.number.str = ast_malloc(ie_len + 1);
08675          if (connected->id.number.str) {
08676             memcpy(connected->id.number.str, data + pos, ie_len);
08677             connected->id.number.str[ie_len] = 0;
08678          }
08679          break;
08680       case AST_CONNECTED_LINE_NUMBER_PLAN:
08681          if (ie_len != 1) {
08682             ast_log(LOG_WARNING, "Invalid connected line numbering plan (%u)\n",
08683                (unsigned) ie_len);
08684             break;
08685          }
08686          connected->id.number.plan = data[pos];
08687          break;
08688       case AST_CONNECTED_LINE_NUMBER_PRESENTATION:
08689          if (ie_len != 1) {
08690             ast_log(LOG_WARNING, "Invalid connected line number presentation (%u)\n",
08691                (unsigned) ie_len);
08692             break;
08693          }
08694          connected->id.number.presentation = data[pos];
08695          break;
08696       case AST_CONNECTED_LINE_NUMBER_VALID:
08697          if (ie_len != 1) {
08698             ast_log(LOG_WARNING, "Invalid connected line number valid (%u)\n",
08699                (unsigned) ie_len);
08700             break;
08701          }
08702          connected->id.number.valid = data[pos];
08703          break;
08704 /* Connected line party id combined presentation */
08705       case AST_CONNECTED_LINE_ID_PRESENTATION:
08706          if (ie_len != 1) {
08707             ast_log(LOG_WARNING, "Invalid connected line combined presentation (%u)\n",
08708                (unsigned) ie_len);
08709             break;
08710          }
08711          combined_presentation = data[pos];
08712          got_combined_presentation = 1;
08713          break;
08714 /* Connected line party id subaddress */
08715       case AST_CONNECTED_LINE_SUBADDRESS:
08716          ast_free(connected->id.subaddress.str);
08717          connected->id.subaddress.str = ast_malloc(ie_len + 1);
08718          if (connected->id.subaddress.str) {
08719             memcpy(connected->id.subaddress.str, data + pos, ie_len);
08720             connected->id.subaddress.str[ie_len] = 0;
08721          }
08722          break;
08723       case AST_CONNECTED_LINE_SUBADDRESS_TYPE:
08724          if (ie_len != 1) {
08725             ast_log(LOG_WARNING, "Invalid connected line type of subaddress (%u)\n",
08726                (unsigned) ie_len);
08727             break;
08728          }
08729          connected->id.subaddress.type = data[pos];
08730          break;
08731       case AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN:
08732          if (ie_len != 1) {
08733             ast_log(LOG_WARNING,
08734                "Invalid connected line subaddress odd-even indicator (%u)\n",
08735                (unsigned) ie_len);
08736             break;
08737          }
08738          connected->id.subaddress.odd_even_indicator = data[pos];
08739          break;
08740       case AST_CONNECTED_LINE_SUBADDRESS_VALID:
08741          if (ie_len != 1) {
08742             ast_log(LOG_WARNING, "Invalid connected line subaddress valid (%u)\n",
08743                (unsigned) ie_len);
08744             break;
08745          }
08746          connected->id.subaddress.valid = data[pos];
08747          break;
08748 /* Connected line party tag */
08749       case AST_CONNECTED_LINE_TAG:
08750          ast_free(connected->id.tag);
08751          connected->id.tag = ast_malloc(ie_len + 1);
08752          if (connected->id.tag) {
08753             memcpy(connected->id.tag, data + pos, ie_len);
08754             connected->id.tag[ie_len] = 0;
08755          }
08756          break;
08757 /* Connected line party source */
08758       case AST_CONNECTED_LINE_SOURCE:
08759          if (ie_len != sizeof(value)) {
08760             ast_log(LOG_WARNING, "Invalid connected line source (%u)\n",
08761                (unsigned) ie_len);
08762             break;
08763          }
08764          memcpy(&value, data + pos, sizeof(value));
08765          connected->source = ntohl(value);
08766          break;
08767 /* Connected line party unknown element */
08768       default:
08769          ast_debug(1, "Unknown connected line element: %u (%u)\n",
08770             (unsigned) ie_id, (unsigned) ie_len);
08771          break;
08772       }
08773    }
08774 
08775    switch (frame_version) {
08776    case 1:
08777       /*
08778        * The other end is an earlier version that we need to adjust
08779        * for compatibility.
08780        */
08781       connected->id.name.valid = 1;
08782       connected->id.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
08783       connected->id.number.valid = 1;
08784       if (got_combined_presentation) {
08785          connected->id.name.presentation = combined_presentation;
08786          connected->id.number.presentation = combined_presentation;
08787       }
08788       break;
08789    case 2:
08790       /* The other end is at the same level as we are. */
08791       break;
08792    default:
08793       /*
08794        * The other end is newer than we are.
08795        * We need to assume that they are compatible with us.
08796        */
08797       ast_debug(1, "Connected line frame has newer version: %u\n",
08798          (unsigned) frame_version);
08799       break;
08800    }
08801 
08802    return 0;
08803 }

void ast_deactivate_generator ( struct ast_channel chan  ) 

int ast_do_masquerade ( struct ast_channel original  ) 

Masquerade a channel.

Start masquerading a channel.

Note:
Assumes _NO_ channels and _NO_ channel pvt's are locked. If a channel is locked while calling this function, it invalidates our channel container locking order. All channels must be unlocked before it is permissible to lock the channels' ao2 container.

Definition at line 6399 of file channel.c.

References __ast_change_name_nolink(), ast_channel::_bridge, ast_channel::_softhangup, ast_channel::_state, ast_channel::adsicpe, ast_channel::alertpipe, ao2_link, ao2_lock, ao2_unlink, ao2_unlock, ast_app_group_update(), ast_autochan_new_channel(), ast_bridged_channel(), ast_cause2str(), AST_CEL_BRIDGE_UPDATE, ast_cel_report_event(), ast_channel_accountcode(), ast_channel_datastore_find(), ast_channel_datastore_remove(), ast_channel_language(), ast_channel_lock, ast_channel_musicclass(), ast_channel_name(), AST_CHANNEL_NAME, ast_channel_release(), ast_channel_set_fd(), ast_channel_set_linkgroup(), ast_channel_trylock, ast_channel_uniqueid(), ast_channel_unlock, AST_CONTROL_SRCCHANGE, AST_CONTROL_UNHOLD, ast_copy_string(), ast_datastore_free(), ast_debug, AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, ast_format_cap_copy(), ast_format_copy(), AST_GENERATOR_FD, ast_getformatname(), ast_indicate(), ast_kill_tech, AST_LIST_APPEND_LIST, AST_LIST_FIRST, AST_LIST_HEAD_NOLOCK, AST_LIST_HEAD_SET_NOLOCK, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), ast_manager_event, ast_manager_event_multichan, AST_MAX_FDS, ast_null_frame, ast_queue_frame(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_SOFTHANGUP_DEV, ast_state2str(), ast_test_flag, AST_TIMING_FD, ast_channel::blocker, ast_channel::caller, ast_channel::cdr, ast_datastore_info::chan_fixup, CHANNEL_DEADLOCK_AVOIDANCE, channels, clone_variables(), ast_channel::connected, ast_datastore::data, ast_channel::datastores, ast_channel::dialed, errno, EVENT_FLAG_CALL, ast_channel::fdno, ast_channel::fds, ast_channel_tech::fixup, free_translation(), ast_channel_tech::hangup, ast_channel::hangupcause, ast_datastore::info, LOG_WARNING, ast_channel::masq, ast_channel::masqr, masquerade_colp_transfer(), ast_channel::monitor, ast_channel::nativeformats, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::readq, ast_channel::redirecting, report_new_callerid(), S_OR, ast_channel::tech, ast_channel::tech_pvt, ast_channel::timingfd, xfer_masquerade_ds::transferee_held, ast_channel_tech::type, ast_channel::visible_indication, and ast_channel::writeformat.

Referenced by __ast_read(), ast_async_goto(), ast_do_pickup(), ast_hangup(), ast_waitfor_nandfds(), ast_write(), builtin_atxfer(), check_goto_on_transfer(), do_bridge_masquerade(), handle_invite_replaces(), iax_park(), local_attended_transfer(), masq_park_call(), and sip_park().

06400 {
06401    int x, i;
06402    int res=0;
06403    int origstate;
06404    int visible_indication;
06405    struct ast_frame *current;
06406    const struct ast_channel_tech *t;
06407    void *t_pvt;
06408    union {
06409       struct ast_party_dialed dialed;
06410       struct ast_party_caller caller;
06411       struct ast_party_connected_line connected;
06412       struct ast_party_redirecting redirecting;
06413    } exchange;
06414    struct ast_channel *clonechan, *chans[2];
06415    struct ast_channel *bridged;
06416    struct ast_cdr *cdr;
06417    struct ast_datastore *xfer_ds;
06418    struct xfer_masquerade_ds *xfer_colp;
06419    struct ast_format rformat;
06420    struct ast_format wformat;
06421    struct ast_format tmp_format;
06422    char newn[AST_CHANNEL_NAME];
06423    char orig[AST_CHANNEL_NAME];
06424    char masqn[AST_CHANNEL_NAME];
06425    char zombn[AST_CHANNEL_NAME];
06426 
06427    ast_format_copy(&rformat, &original->readformat);
06428    ast_format_copy(&wformat, &original->writeformat);
06429 
06430    /* XXX This operation is a bit odd.  We're essentially putting the guts of
06431     * the clone channel into the original channel.  Start by killing off the
06432     * original channel's backend.  While the features are nice, which is the
06433     * reason we're keeping it, it's still awesomely weird. XXX */
06434 
06435    /* The reasoning for the channels ao2_container lock here is complex.
06436     * 
06437     * In order to check for a race condition, the original channel must
06438     * be locked.  If it is determined that the masquerade should proceed
06439     * the original channel can absolutely not be unlocked until the end
06440     * of the function.  Since after determining the masquerade should
06441     * continue requires the channels to be unlinked from the ao2_container,
06442     * the container lock must be held first to achieve proper locking order.
06443     */
06444    ao2_lock(channels);
06445 
06446    /* lock the original channel to determine if the masquerade is required or not */
06447    ast_channel_lock(original);
06448 
06449    /*
06450     * This checks to see if the masquerade has already happened or
06451     * not.  There is a race condition that exists for this
06452     * function.  Since all pvt and channel locks must be let go
06453     * before calling do_masquerade, it is possible that it could be
06454     * called multiple times for the same channel.  This check
06455     * verifies whether or not the masquerade has already been
06456     * completed by another thread.
06457     */
06458    while ((clonechan = original->masq) && ast_channel_trylock(clonechan)) {
06459       /*
06460        * A masq is needed but we could not get the clonechan lock
06461        * immediately.  Since this function already holds the global
06462        * container lock, unlocking original for deadlock avoidance
06463        * will not result in any sort of masquerade race condition.  If
06464        * masq is called by a different thread while this happens, it
06465        * will be stuck waiting until we unlock the container.
06466        */
06467       CHANNEL_DEADLOCK_AVOIDANCE(original);
06468    }
06469 
06470    /*
06471     * A final masq check must be done after deadlock avoidance for
06472     * clonechan above or we could get a double masq.  This is
06473     * posible with ast_hangup at least.
06474     */
06475    if (!clonechan) {
06476       /* masq already completed by another thread, or never needed to be done to begin with */
06477       ast_channel_unlock(original);
06478       ao2_unlock(channels);
06479       return 0;
06480    }
06481 
06482    /* Get any transfer masquerade connected line exchange data. */
06483    xfer_ds = ast_channel_datastore_find(original, &xfer_ds_info, NULL);
06484    if (xfer_ds) {
06485       ast_channel_datastore_remove(original, xfer_ds);
06486       xfer_colp = xfer_ds->data;
06487    } else {
06488       xfer_colp = NULL;
06489    }
06490 
06491    /*
06492     * Release any hold on the transferee channel before proceeding
06493     * with the masquerade.
06494     */
06495    if (xfer_colp && xfer_colp->transferee_held) {
06496       ast_indicate(clonechan, AST_CONTROL_UNHOLD);
06497    }
06498 
06499    /* clear the masquerade channels */
06500    original->masq = NULL;
06501    clonechan->masqr = NULL;
06502 
06503    /* unlink from channels container as name (which is the hash value) will change */
06504    ao2_unlink(channels, original);
06505    ao2_unlink(channels, clonechan);
06506 
06507    ast_debug(4, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",
06508       ast_channel_name(clonechan), clonechan->_state, ast_channel_name(original), original->_state);
06509 
06510    /*
06511     * Stop any visible indiction on the original channel so we can
06512     * transfer it to the clonechan taking the original's place.
06513     */
06514    visible_indication = original->visible_indication;
06515    ast_indicate(original, -1);
06516 
06517    chans[0] = clonechan;
06518    chans[1] = original;
06519    ast_manager_event_multichan(EVENT_FLAG_CALL, "Masquerade", 2, chans,
06520       "Clone: %s\r\n"
06521       "CloneState: %s\r\n"
06522       "Original: %s\r\n"
06523       "OriginalState: %s\r\n",
06524       ast_channel_name(clonechan), ast_state2str(clonechan->_state), ast_channel_name(original), ast_state2str(original->_state));
06525 
06526    /* Having remembered the original read/write formats, we turn off any translation on either
06527       one */
06528    free_translation(clonechan);
06529    free_translation(original);
06530 
06531    /* Save the original name */
06532    ast_copy_string(orig, ast_channel_name(original), sizeof(orig));
06533    /* Save the new name */
06534    ast_copy_string(newn, ast_channel_name(clonechan), sizeof(newn));
06535    /* Create the masq name */
06536    snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn);
06537 
06538    /* Mangle the name of the clone channel */
06539    __ast_change_name_nolink(clonechan, masqn);
06540 
06541    /* Copy the name from the clone channel */
06542    __ast_change_name_nolink(original, newn);
06543 
06544    /* share linked id's */
06545    ast_channel_set_linkgroup(original, clonechan);
06546 
06547    /* Swap the technologies */
06548    t = original->tech;
06549    original->tech = clonechan->tech;
06550    clonechan->tech = t;
06551 
06552    /* Swap the cdrs */
06553    cdr = original->cdr;
06554    original->cdr = clonechan->cdr;
06555    clonechan->cdr = cdr;
06556 
06557    t_pvt = original->tech_pvt;
06558    original->tech_pvt = clonechan->tech_pvt;
06559    clonechan->tech_pvt = t_pvt;
06560 
06561    /* Swap the alertpipes */
06562    for (i = 0; i < 2; i++) {
06563       x = original->alertpipe[i];
06564       original->alertpipe[i] = clonechan->alertpipe[i];
06565       clonechan->alertpipe[i] = x;
06566    }
06567 
06568    /* 
06569     * Swap the readq's.  The end result should be this:
06570     *
06571     *  1) All frames should be on the new (original) channel.
06572     *  2) Any frames that were already on the new channel before this
06573     *     masquerade need to be at the end of the readq, after all of the
06574     *     frames on the old (clone) channel.
06575     *  3) The alertpipe needs to get poked for every frame that was already
06576     *     on the new channel, since we are now using the alert pipe from the
06577     *     old (clone) channel.
06578     */
06579    {
06580       AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq;
06581       AST_LIST_HEAD_SET_NOLOCK(&tmp_readq, NULL);
06582 
06583       AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list);
06584       AST_LIST_APPEND_LIST(&original->readq, &clonechan->readq, frame_list);
06585 
06586       while ((current = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) {
06587          AST_LIST_INSERT_TAIL(&original->readq, current, frame_list);
06588          if (original->alertpipe[1] > -1) {
06589             int poke = 0;
06590 
06591             if (write(original->alertpipe[1], &poke, sizeof(poke)) < 0) {
06592                ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
06593             }
06594          }
06595       }
06596    }
06597 
06598    /* Swap the raw formats */
06599    ast_format_copy(&tmp_format, &original->rawreadformat);
06600    ast_format_copy(&original->rawreadformat, &clonechan->rawreadformat);
06601    ast_format_copy(&clonechan->rawreadformat, &tmp_format);
06602 
06603    ast_format_copy(&tmp_format, &original->rawwriteformat);
06604    ast_format_copy(&original->rawwriteformat, &clonechan->rawwriteformat);
06605    ast_format_copy(&clonechan->rawwriteformat, &tmp_format);
06606 
06607    clonechan->_softhangup = AST_SOFTHANGUP_DEV;
06608 
06609    /* And of course, so does our current state.  Note we need not
06610       call ast_setstate since the event manager doesn't really consider
06611       these separate.  We do this early so that the clone has the proper
06612       state of the original channel. */
06613    origstate = original->_state;
06614    original->_state = clonechan->_state;
06615    clonechan->_state = origstate;
06616 
06617    if (clonechan->tech->fixup && clonechan->tech->fixup(original, clonechan)) {
06618       ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", ast_channel_name(clonechan));
06619    }
06620 
06621    /* Start by disconnecting the original's physical side */
06622    if (clonechan->tech->hangup && clonechan->tech->hangup(clonechan)) {
06623       ast_log(LOG_WARNING, "Hangup failed!  Strange things may happen!\n");
06624       res = -1;
06625       goto done;
06626    }
06627 
06628    /*
06629     * We just hung up the physical side of the channel.  Set the
06630     * new zombie to use the kill channel driver for safety.
06631     */
06632    clonechan->tech = &ast_kill_tech;
06633 
06634    /* Mangle the name of the clone channel */
06635    snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig); /* quick, hide the brains! */
06636    __ast_change_name_nolink(clonechan, zombn);
06637 
06638    /* Update the type. */
06639    t_pvt = original->monitor;
06640    original->monitor = clonechan->monitor;
06641    clonechan->monitor = t_pvt;
06642 
06643    /* Keep the same language.  */
06644    ast_channel_language_set(original, ast_channel_language(clonechan));
06645    /* Copy the FD's other than the generator fd */
06646    for (x = 0; x < AST_MAX_FDS; x++) {
06647       if (x != AST_GENERATOR_FD)
06648          ast_channel_set_fd(original, x, clonechan->fds[x]);
06649    }
06650 
06651    ast_app_group_update(clonechan, original);
06652 
06653    /* Move data stores over */
06654    if (AST_LIST_FIRST(&clonechan->datastores)) {
06655       struct ast_datastore *ds;
06656       /* We use a safe traversal here because some fixup routines actually
06657        * remove the datastore from the list and free them.
06658        */
06659       AST_LIST_TRAVERSE_SAFE_BEGIN(&clonechan->datastores, ds, entry) {
06660          if (ds->info->chan_fixup)
06661             ds->info->chan_fixup(ds->data, clonechan, original);
06662       }
06663       AST_LIST_TRAVERSE_SAFE_END;
06664       AST_LIST_APPEND_LIST(&original->datastores, &clonechan->datastores, entry);
06665    }
06666 
06667    ast_autochan_new_channel(clonechan, original);
06668 
06669    clone_variables(original, clonechan);
06670    /* Presense of ADSI capable CPE follows clone */
06671    original->adsicpe = clonechan->adsicpe;
06672    /* Bridge remains the same */
06673    /* CDR fields remain the same */
06674    /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */
06675    /* Application and data remain the same */
06676    /* Clone exception  becomes real one, as with fdno */
06677    ast_set_flag(original, ast_test_flag(clonechan, AST_FLAG_EXCEPTION | AST_FLAG_OUTGOING));
06678    original->fdno = clonechan->fdno;
06679    /* Schedule context remains the same */
06680    /* Stream stuff stays the same */
06681    /* Keep the original state.  The fixup code will need to work with it most likely */
06682 
06683    /*
06684     * Just swap the whole structures, nevermind the allocations,
06685     * they'll work themselves out.
06686     */
06687    exchange.dialed = original->dialed;
06688    original->dialed = clonechan->dialed;
06689    clonechan->dialed = exchange.dialed;
06690 
06691    exchange.caller = original->caller;
06692    original->caller = clonechan->caller;
06693    clonechan->caller = exchange.caller;
06694 
06695    exchange.connected = original->connected;
06696    original->connected = clonechan->connected;
06697    clonechan->connected = exchange.connected;
06698 
06699    exchange.redirecting = original->redirecting;
06700    original->redirecting = clonechan->redirecting;
06701    clonechan->redirecting = exchange.redirecting;
06702 
06703    report_new_callerid(original);
06704 
06705    /* Restore original timing file descriptor */
06706    ast_channel_set_fd(original, AST_TIMING_FD, original->timingfd);
06707 
06708    /* Our native formats are different now */
06709    ast_format_cap_copy(original->nativeformats, clonechan->nativeformats);
06710 
06711    /* Context, extension, priority, app data, jump table,  remain the same */
06712    /* pvt switches.  pbx stays the same, as does next */
06713 
06714    /* Set the write format */
06715    ast_set_write_format(original, &wformat);
06716 
06717    /* Set the read format */
06718    ast_set_read_format(original, &rformat);
06719 
06720    /* Copy the music class */
06721    ast_channel_musicclass_set(original, ast_channel_musicclass(clonechan));
06722 
06723    /* copy over accuntcode and set peeraccount across the bridge */
06724    ast_channel_accountcode_set(original, S_OR(ast_channel_accountcode(clonechan), ""));
06725    if (original->_bridge) {
06726       /* XXX - should we try to lock original->_bridge here? */
06727       ast_channel_peeraccount_set(original->_bridge, S_OR(ast_channel_accountcode(clonechan), ""));
06728       ast_cel_report_event(original, AST_CEL_BRIDGE_UPDATE, NULL, NULL, NULL);
06729    }
06730 
06731    ast_debug(1, "Putting channel %s in %s/%s formats\n", ast_channel_name(original),
06732       ast_getformatname(&wformat), ast_getformatname(&rformat));
06733 
06734    /* Okay.  Last thing is to let the channel driver know about all this mess, so he
06735       can fix up everything as best as possible */
06736    if (original->tech->fixup) {
06737       if (original->tech->fixup(clonechan, original)) {
06738          ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n",
06739             original->tech->type, ast_channel_name(original));
06740          res = -1;
06741          goto done;
06742       }
06743    } else
06744       ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)!  Bad things may happen.\n",
06745          original->tech->type, ast_channel_name(original));
06746 
06747    /* 
06748     * If an indication is currently playing, maintain it on the channel 
06749     * that is taking the place of original 
06750     *
06751     * This is needed because the masquerade is swapping out in the internals
06752     * of this channel, and the new channel private data needs to be made
06753     * aware of the current visible indication (RINGING, CONGESTION, etc.)
06754     */
06755    if (visible_indication) {
06756       ast_indicate(original, visible_indication);
06757    }
06758 
06759    /* Now, at this point, the "clone" channel is totally F'd up.  We mark it as
06760       a zombie so nothing tries to touch it.  If it's already been marked as a
06761       zombie, then free it now (since it already is considered invalid). */
06762    if (ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) {
06763       ast_debug(1, "Destroying channel clone '%s'\n", ast_channel_name(clonechan));
06764       ast_channel_unlock(clonechan);
06765       ast_manager_event(clonechan, EVENT_FLAG_CALL, "Hangup",
06766          "Channel: %s\r\n"
06767          "Uniqueid: %s\r\n"
06768          "Cause: %d\r\n"
06769          "Cause-txt: %s\r\n",
06770          ast_channel_name(clonechan),
06771          ast_channel_uniqueid(clonechan),
06772          clonechan->hangupcause,
06773          ast_cause2str(clonechan->hangupcause)
06774          );
06775       clonechan = ast_channel_release(clonechan);
06776    } else {
06777       ast_debug(1, "Released clone lock on '%s'\n", ast_channel_name(clonechan));
06778       ast_set_flag(clonechan, AST_FLAG_ZOMBIE);
06779       ast_queue_frame(clonechan, &ast_null_frame);
06780    }
06781 
06782    /* Signal any blocker */
06783    if (ast_test_flag(original, AST_FLAG_BLOCKING))
06784       pthread_kill(original->blocker, SIGURG);
06785    ast_debug(1, "Done Masquerading %s (%d)\n", ast_channel_name(original), original->_state);
06786 
06787    if ((bridged = ast_bridged_channel(original))) {
06788       ast_channel_lock(bridged);
06789       ast_indicate(bridged, AST_CONTROL_SRCCHANGE);
06790       ast_channel_unlock(bridged);
06791    }
06792    ast_indicate(original, AST_CONTROL_SRCCHANGE);
06793 
06794    if (xfer_colp) {
06795       /*
06796        * After the masquerade, the original channel pointer actually
06797        * points to the new transferee channel and the bridged channel
06798        * is still the intended transfer target party.
06799        */
06800       masquerade_colp_transfer(original, xfer_colp);
06801    }
06802 
06803 done:
06804    if (xfer_ds) {
06805       ast_datastore_free(xfer_ds);
06806    }
06807    /* it is possible for the clone channel to disappear during this */
06808    if (clonechan) {
06809       ast_channel_unlock(original);
06810       ast_channel_unlock(clonechan);
06811       ao2_link(channels, clonechan);
06812       ao2_link(channels, original);
06813    } else {
06814       ast_channel_unlock(original);
06815       ao2_link(channels, original);
06816    }
06817 
06818    ao2_unlock(channels);
06819 
06820    return res;
06821 }

struct ast_channel* ast_dummy_channel_alloc ( void   )  [read]

Create a fake channel structure.

Return values:
NULL failure
non-NULL successfully allocated channel
Note:
This function should ONLY be used to create a fake channel that can then be populated with data for use in variable substitution when a real channel does not exist.

The created dummy channel should be destroyed by ast_channel_unref(). Using ast_channel_release() needlessly grabs the channel container lock and can cause a deadlock as a result. Also grabbing the channel container lock reduces system performance.

Definition at line 1176 of file channel.c.

References __ao2_alloc_debug(), ao2_alloc, ast_channel_unref, ast_dummy_channel_destructor(), AST_LIST_HEAD_INIT_NOLOCK, ast_string_field_init, and ast_channel::varshead.

Referenced by acf_odbc_read(), acf_odbc_write(), action_getvar(), ast_add_extension2_lockopt(), ast_cel_fabricate_channel_from_event(), ast_pbx_outgoing_cdr_failed(), ast_str_substitute_variables_full(), cli_odbc_read(), cli_odbc_write(), custom_log(), make_email_file(), manager_log(), pbx_substitute_variables_helper_full(), rotate_file(), sendmail(), sendpage(), syslog_log(), and write_cdr().

01178 {
01179    struct ast_channel *tmp;
01180    struct varshead *headp;
01181 
01182 #if defined(REF_DEBUG)
01183    tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel",
01184       file, line, function, 1);
01185 #elif defined(__AST_DEBUG_MALLOC)
01186    tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel",
01187       file, line, function, 0);
01188 #else
01189    tmp = ao2_alloc(sizeof(*tmp), ast_dummy_channel_destructor);
01190 #endif
01191    if (!tmp) {
01192       /* Dummy channel structure allocation failure. */
01193       return NULL;
01194    }
01195 
01196    if ((ast_string_field_init(tmp, 128))) {
01197       return ast_channel_unref(tmp);
01198    }
01199 
01200    headp = &tmp->varshead;
01201    AST_LIST_HEAD_INIT_NOLOCK(headp);
01202 
01203    return tmp;
01204 }

static void ast_dummy_channel_destructor ( void *  obj  )  [static]

Free a dummy channel structure.

Definition at line 2309 of file channel.c.

References ast_cdr_discard(), AST_LIST_REMOVE_HEAD, ast_party_caller_free(), ast_party_connected_line_free(), ast_party_dialed_free(), ast_party_redirecting_free(), ast_string_field_free_memory, ast_var_delete(), ast_channel::caller, ast_channel::cdr, ast_channel::connected, ast_channel::dialed, ast_channel::redirecting, and ast_channel::varshead.

Referenced by ast_dummy_channel_alloc().

02310 {
02311    struct ast_channel *chan = obj;
02312    struct ast_var_t *vardata;
02313    struct varshead *headp;
02314 
02315    headp = &chan->varshead;
02316 
02317    ast_party_dialed_free(&chan->dialed);
02318    ast_party_caller_free(&chan->caller);
02319    ast_party_connected_line_free(&chan->connected);
02320    ast_party_redirecting_free(&chan->redirecting);
02321 
02322    /* loop over the variables list, freeing all data and deleting list items */
02323    /* no need to lock the list, as the channel is already locked */
02324    while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
02325       ast_var_delete(vardata);
02326 
02327    if (chan->cdr) {
02328       ast_cdr_discard(chan->cdr);
02329       chan->cdr = NULL;
02330    }
02331 
02332    ast_string_field_free_memory(chan);
02333 }

static enum ast_bridge_result ast_generic_bridge ( struct ast_channel c0,
struct ast_channel c1,
struct ast_bridge_config config,
struct ast_frame **  fo,
struct ast_channel **  rc 
) [static]

Definition at line 6975 of file channel.c.

References ast_channel::_bridge, ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_IGNORE_SIGS, AST_BRIDGE_RETRY, ast_channel_clear_softhangup(), ast_channel_connected_line_macro(), ast_channel_name(), ast_channel_redirecting_macro(), ast_clear_flag, AST_CONTROL_AOC, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_MCID, AST_CONTROL_REDIRECTING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_debug, AST_FEATURE_WARNING_ACTIVE, ast_format_cap_destroy(), ast_format_cap_dup(), ast_format_cap_identical(), AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_HTML, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_indicate_data(), ast_jb_do_usecheck(), ast_jb_empty_and_reset(), ast_jb_get_and_deliver(), ast_jb_get_when_to_wakeup(), ast_jb_put(), ast_poll_channel_add(), ast_poll_channel_del(), ast_read(), ast_samp2tv(), ast_set_flag, AST_SOFTHANGUP_UNBRIDGE, ast_test_flag, ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), ast_waitfor_n(), ast_write(), ast_frame::data, ast_frame::datalen, ast_bridge_config::feature_timer, ast_bridge_config::flags, ast_frame::frametype, ast_frame_subclass::integer, ast_channel::nativeformats, ast_bridge_config::nexteventts, ast_frame::ptr, ast_frame::subclass, ast_channel::tech_pvt, and ast_bridge_config::timelimit.

Referenced by ast_channel_bridge().

06978 {
06979    /* Copy voice back and forth between the two channels. */
06980    struct ast_channel *cs[3];
06981    struct ast_frame *f;
06982    enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
06983    struct ast_format_cap *o0nativeformats;
06984    struct ast_format_cap *o1nativeformats;
06985    int watch_c0_dtmf;
06986    int watch_c1_dtmf;
06987    void *pvt0, *pvt1;
06988    /* Indicates whether a frame was queued into a jitterbuffer */
06989    int frame_put_in_jb = 0;
06990    int jb_in_use;
06991    int to;
06992 
06993    o0nativeformats = ast_format_cap_dup(c0->nativeformats);
06994    o1nativeformats = ast_format_cap_dup(c1->nativeformats);
06995 
06996    if (!o0nativeformats || !o1nativeformats) {
06997       ast_format_cap_destroy(o0nativeformats); /* NULL safe */
06998       ast_format_cap_destroy(o1nativeformats); /* NULL safe */
06999       return AST_BRIDGE_FAILED;
07000    }
07001 
07002    cs[0] = c0;
07003    cs[1] = c1;
07004    pvt0 = c0->tech_pvt;
07005    pvt1 = c1->tech_pvt;
07006    watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0;
07007    watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1;
07008 
07009    /* Check the need of a jitterbuffer for each channel */
07010    jb_in_use = ast_jb_do_usecheck(c0, c1);
07011    if (jb_in_use)
07012       ast_jb_empty_and_reset(c0, c1);
07013 
07014    ast_poll_channel_add(c0, c1);
07015 
07016    if (config->feature_timer > 0 && ast_tvzero(config->nexteventts)) {
07017       /* nexteventts is not set when the bridge is not scheduled to
07018        * break, so calculate when the bridge should possibly break
07019        * if a partial feature match timed out */
07020       config->nexteventts = ast_tvadd(ast_tvnow(), ast_samp2tv(config->feature_timer, 1000));
07021    }
07022 
07023    for (;;) {
07024       struct ast_channel *who, *other;
07025 
07026       if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) ||
07027           (!ast_format_cap_identical(o0nativeformats, c0->nativeformats)) ||
07028           (!ast_format_cap_identical(o1nativeformats, c1->nativeformats))) {
07029          /* Check for Masquerade, codec changes, etc */
07030          res = AST_BRIDGE_RETRY;
07031          break;
07032       }
07033       if (config->nexteventts.tv_sec) {
07034          to = ast_tvdiff_ms(config->nexteventts, ast_tvnow());
07035          if (to <= 0) {
07036             if (config->timelimit && !config->feature_timer && !ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) {
07037                res = AST_BRIDGE_RETRY;
07038                /* generic bridge ending to play warning */
07039                ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
07040             } else if (config->feature_timer) {
07041                /* feature timer expired - make sure we do not play warning */
07042                ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE);
07043                res = AST_BRIDGE_RETRY;
07044             } else {
07045                res = AST_BRIDGE_COMPLETE;
07046             }
07047             break;
07048          }
07049       } else {
07050          /* If a feature has been started and the bridge is configured to 
07051           * to not break, leave the channel bridge when the feature timer
07052           * time has elapsed so the DTMF will be sent to the other side. 
07053           */
07054          if (!ast_tvzero(config->nexteventts)) {
07055             int diff = ast_tvdiff_ms(config->nexteventts, ast_tvnow());
07056             if (diff <= 0) {
07057                res = AST_BRIDGE_RETRY;
07058                break;
07059             }
07060          }
07061          to = -1;
07062       }
07063       /* Calculate the appropriate max sleep interval - in general, this is the time,
07064          left to the closest jb delivery moment */
07065       if (jb_in_use)
07066          to = ast_jb_get_when_to_wakeup(c0, c1, to);
07067       who = ast_waitfor_n(cs, 2, &to);
07068       if (!who) {
07069          /* No frame received within the specified timeout - check if we have to deliver now */
07070          if (jb_in_use)
07071             ast_jb_get_and_deliver(c0, c1);
07072          if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */
07073             if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
07074                ast_channel_clear_softhangup(c0, AST_SOFTHANGUP_UNBRIDGE);
07075             }
07076             if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
07077                ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE);
07078             }
07079             c0->_bridge = c1;
07080             c1->_bridge = c0;
07081          }
07082          continue;
07083       }
07084       f = ast_read(who);
07085       if (!f) {
07086          *fo = NULL;
07087          *rc = who;
07088          ast_debug(1, "Didn't get a frame from channel: %s\n", ast_channel_name(who));
07089          break;
07090       }
07091 
07092       other = (who == c0) ? c1 : c0; /* the 'other' channel */
07093       /* Try add the frame info the who's bridged channel jitterbuff */
07094       if (jb_in_use)
07095          frame_put_in_jb = !ast_jb_put(other, f);
07096 
07097       if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) {
07098          int bridge_exit = 0;
07099 
07100          switch (f->subclass.integer) {
07101          case AST_CONTROL_AOC:
07102          case AST_CONTROL_MCID:
07103             ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
07104             break;
07105          case AST_CONTROL_REDIRECTING:
07106             if (ast_channel_redirecting_macro(who, other, f, other == c0, 1)) {
07107                ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
07108             }
07109             break;
07110          case AST_CONTROL_CONNECTED_LINE:
07111             if (ast_channel_connected_line_macro(who, other, f, other == c0, 1)) {
07112                ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
07113             }
07114             break;
07115          case AST_CONTROL_HOLD:
07116          case AST_CONTROL_UNHOLD:
07117          case AST_CONTROL_VIDUPDATE:
07118          case AST_CONTROL_SRCUPDATE:
07119          case AST_CONTROL_SRCCHANGE:
07120          case AST_CONTROL_T38_PARAMETERS:
07121             ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
07122             if (jb_in_use) {
07123                ast_jb_empty_and_reset(c0, c1);
07124             }
07125             break;
07126          default:
07127             *fo = f;
07128             *rc = who;
07129             bridge_exit = 1;
07130             ast_debug(1, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass.integer, ast_channel_name(who));
07131             break;
07132          }
07133          if (bridge_exit)
07134             break;
07135       }
07136       if ((f->frametype == AST_FRAME_VOICE) ||
07137           (f->frametype == AST_FRAME_DTMF_BEGIN) ||
07138           (f->frametype == AST_FRAME_DTMF) ||
07139           (f->frametype == AST_FRAME_VIDEO) ||
07140           (f->frametype == AST_FRAME_IMAGE) ||
07141           (f->frametype == AST_FRAME_HTML) ||
07142           (f->frametype == AST_FRAME_MODEM) ||
07143           (f->frametype == AST_FRAME_TEXT)) {
07144          /* monitored dtmf causes exit from bridge */
07145          int monitored_source = (who == c0) ? watch_c0_dtmf : watch_c1_dtmf;
07146 
07147          if (monitored_source &&
07148             (f->frametype == AST_FRAME_DTMF_END ||
07149             f->frametype == AST_FRAME_DTMF_BEGIN)) {
07150             *fo = f;
07151             *rc = who;
07152             ast_debug(1, "Got DTMF %s on channel (%s)\n",
07153                f->frametype == AST_FRAME_DTMF_END ? "end" : "begin",
07154                ast_channel_name(who));
07155 
07156             break;
07157          }
07158          /* Write immediately frames, not passed through jb */
07159          if (!frame_put_in_jb)
07160             ast_write(other, f);
07161             
07162          /* Check if we have to deliver now */
07163          if (jb_in_use)
07164             ast_jb_get_and_deliver(c0, c1);
07165       }
07166       /* XXX do we want to pass on also frames not matched above ? */
07167       ast_frfree(f);
07168 
07169 #ifndef HAVE_EPOLL
07170       /* Swap who gets priority */
07171       cs[2] = cs[0];
07172       cs[0] = cs[1];
07173       cs[1] = cs[2];
07174 #endif
07175    }
07176 
07177    ast_poll_channel_del(c0, c1);
07178 
07179    ast_format_cap_destroy(o0nativeformats);
07180    ast_format_cap_destroy(o1nativeformats);
07181 
07182    return res;
07183 }

struct ast_channel_tech* ast_get_channel_tech ( const char *  name  )  [read]

Get handle to channel driver based on name.

Get a channel technology structure by name.

Definition at line 732 of file channel.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, chanlist::tech, and ast_channel_tech::type.

Referenced by __ast_channel_alloc_ap(), _ast_device_state(), ast_cc_callback(), and ast_var_channel_types_table().

00733 {
00734    struct chanlist *chanls;
00735    const struct ast_channel_tech *ret = NULL;
00736 
00737    AST_RWLIST_RDLOCK(&backends);
00738 
00739    AST_RWLIST_TRAVERSE(&backends, chanls, list) {
00740       if (!strcasecmp(name, chanls->tech->type)) {
00741          ret = chanls->tech;
00742          break;
00743       }
00744    }
00745 
00746    AST_RWLIST_UNLOCK(&backends);
00747    
00748    return ret;
00749 }

ast_group_t ast_get_group ( const char *  s  ) 

Definition at line 7742 of file channel.c.

References ast_log(), ast_strdupa, ast_strlen_zero(), LOG_ERROR, LOG_WARNING, and strsep().

Referenced by _parse(), build_device(), build_gateway(), build_peer(), config_parse_variables(), func_channel_write_real(), process_dahdi(), and read_agent_config().

07743 {
07744    char *piece;
07745    char *c;
07746    int start=0, finish=0, x;
07747    ast_group_t group = 0;
07748 
07749    if (ast_strlen_zero(s))
07750       return 0;
07751 
07752    c = ast_strdupa(s);
07753    
07754    while ((piece = strsep(&c, ","))) {
07755       if (sscanf(piece, "%30d-%30d", &start, &finish) == 2) {
07756          /* Range */
07757       } else if (sscanf(piece, "%30d", &start)) {
07758          /* Just one */
07759          finish = start;
07760       } else {
07761          ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece);
07762          continue;
07763       }
07764       for (x = start; x <= finish; x++) {
07765          if ((x > 63) || (x < 0)) {
07766             ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x);
07767          } else
07768             group |= ((ast_group_t) 1 << x);
07769       }
07770    }
07771    return group;
07772 }

int ast_hangup ( struct ast_channel chan  ) 

Hangup a channel.

Hang up a channel.

Definition at line 2584 of file channel.c.

References ao2_unlink, ast_assert, ast_autoservice_stop(), ast_cause2str(), ast_cc_offer(), ast_cdr_detach(), ast_cdr_end(), AST_CDR_FLAG_BRIDGED, AST_CDR_FLAG_DIALED, AST_CDR_FLAG_POST_DISABLED, AST_CDR_NULL, AST_CEL_HANGUP, ast_cel_report_event(), ast_channel_hangupsource(), ast_channel_lock, ast_channel_name(), ast_channel_uniqueid(), ast_channel_unlock, ast_channel_unref, ast_closestream(), ast_debug, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_log(), ast_manager_event, ast_sched_context_destroy(), ast_set_flag, ast_test_flag, ast_channel::blocker, ast_channel::blockproc, ast_channel::caller, ast_channel::cdr, channels, ast_channel::connected, destroy_hooks(), ast_cdr::disposition, EVENT_FLAG_CALL, free_translation(), ast_channel::generator, ast_channel::generatordata, ast_channel_tech::hangup, ast_channel::hangupcause, ast_party_connected_line::id, ast_party_caller::id, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_party_id::name, ast_party_id::number, pbx_builtin_getvar_helper(), ast_generator::release, S_COR, S_OR, ast_channel::sched, ast_party_name::str, ast_party_number::str, ast_channel::stream, ast_channel::tech, ast_party_name::valid, ast_party_number::valid, and ast_channel::vstream.

Referenced by __analog_handle_event(), __analog_ss_thread(), __ast_pbx_run(), __ast_request_and_dial(), __oh323_new(), action_bridge(), alloc_playback_chan(), alsa_new(), analog_handle_init_event(), analog_ss_thread(), answer_exec_run(), app_exec(), ast_async_goto(), ast_call_forward(), ast_dial_destroy(), ast_dial_hangup(), ast_iax2_new(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pbx_run_app(), async_wait(), begin_dial_channel(), bridge_call_thread(), bridge_channel_thread(), bridge_exec(), build_conf(), builtin_atxfer(), chanavail_exec(), check_availability(), check_compat(), check_goto_on_transfer(), clear_caller(), conf_free(), conf_run(), connect_link(), console_new(), create_msg_q_chan(), dahdi_handle_event(), dahdi_new(), destroy_conference_bridge(), dial_exec_full(), dial_transfer(), do_forward(), do_hang(), feature_attended_transfer(), feature_request_and_dial(), findmeexec(), generic_recall(), gtalk_new(), handle_call_forward(), handle_callforward_button(), handle_frame(), handle_frame_ownerless(), handle_hd_hf(), handle_init_event(), handle_invite_replaces(), handle_request_invite(), handle_timeout_trip(), HandleCallOutgoing(), hangup_chan(), hangupcalls(), hanguptree(), iax2_request(), iax_park(), iax_park_thread(), jingle_new(), local_hangup(), manage_parked_call(), masq_park_call(), mgcp_new(), mgcp_ss(), monitor_dial(), mwi_thread(), my_distinctive_ring(), my_handle_notify_message(), nbs_new(), oss_new(), parkandannounce_exec(), parked_call_exec(), phone_new(), record_thread(), rpt(), rpt_call(), rpt_exec(), rpt_tele_thread(), setsubstate(), sip_park(), sip_park_thread(), sip_pickup_thread(), skinny_new(), skinny_ss(), try_calling(), unistim_new(), usbradio_new(), wait_for_answer(), and wait_for_winner().

02585 {
02586    char extra_str[64]; /* used for cel logging below */
02587    int was_zombie;
02588 
02589    ast_autoservice_stop(chan);
02590 
02591    ast_channel_lock(chan);
02592 
02593    /*
02594     * Do the masquerade if someone is setup to masquerade into us.
02595     *
02596     * NOTE: We must hold the channel lock after testing for a
02597     * pending masquerade and setting the channel as a zombie to
02598     * prevent __ast_channel_masquerade() from setting up a
02599     * masquerade with a dead channel.
02600     */
02601    while (chan->masq) {
02602       ast_channel_unlock(chan);
02603       if (ast_do_masquerade(chan)) {
02604          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
02605 
02606          /* Abort the loop or we might never leave. */
02607          ast_channel_lock(chan);
02608          break;
02609       }
02610       ast_channel_lock(chan);
02611    }
02612 
02613    if (chan->masqr) {
02614       /*
02615        * This channel is one which will be masqueraded into something.
02616        * Mark it as a zombie already so ast_do_masquerade() will know
02617        * to free it later.
02618        */
02619       ast_set_flag(chan, AST_FLAG_ZOMBIE);
02620       destroy_hooks(chan);
02621       ast_channel_unlock(chan);
02622       return 0;
02623    }
02624 
02625    if (!(was_zombie = ast_test_flag(chan, AST_FLAG_ZOMBIE))) {
02626       ast_set_flag(chan, AST_FLAG_ZOMBIE);
02627    }
02628 
02629    ast_channel_unlock(chan);
02630    ao2_unlink(channels, chan);
02631    ast_channel_lock(chan);
02632 
02633    destroy_hooks(chan);
02634 
02635    free_translation(chan);
02636    /* Close audio stream */
02637    if (chan->stream) {
02638       ast_closestream(chan->stream);
02639       chan->stream = NULL;
02640    }
02641    /* Close video stream */
02642    if (chan->vstream) {
02643       ast_closestream(chan->vstream);
02644       chan->vstream = NULL;
02645    }
02646    if (chan->sched) {
02647       ast_sched_context_destroy(chan->sched);
02648       chan->sched = NULL;
02649    }
02650 
02651    if (chan->generatordata) { /* Clear any tone stuff remaining */
02652       if (chan->generator && chan->generator->release) {
02653          chan->generator->release(chan, chan->generatordata);
02654       }
02655    }
02656    chan->generatordata = NULL;
02657    chan->generator = NULL;
02658 
02659    snprintf(extra_str, sizeof(extra_str), "%d,%s,%s", chan->hangupcause, ast_channel_hangupsource(chan), S_OR(pbx_builtin_getvar_helper(chan, "DIALSTATUS"), ""));
02660    ast_cel_report_event(chan, AST_CEL_HANGUP, NULL, extra_str, NULL);
02661 
02662    if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
02663       ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
02664          "is blocked by thread %ld in procedure %s!  Expect a failure\n",
02665          (long) pthread_self(), ast_channel_name(chan), (long)chan->blocker, chan->blockproc);
02666       ast_assert(ast_test_flag(chan, AST_FLAG_BLOCKING) == 0);
02667    }
02668    if (!was_zombie) {
02669       ast_debug(1, "Hanging up channel '%s'\n", ast_channel_name(chan));
02670 
02671       if (chan->tech->hangup) {
02672          chan->tech->hangup(chan);
02673       }
02674    } else {
02675       ast_debug(1, "Hanging up zombie '%s'\n", ast_channel_name(chan));
02676    }
02677 
02678    ast_channel_unlock(chan);
02679 
02680    ast_cc_offer(chan);
02681    ast_manager_event(chan, EVENT_FLAG_CALL, "Hangup",
02682       "Channel: %s\r\n"
02683       "Uniqueid: %s\r\n"
02684       "CallerIDNum: %s\r\n"
02685       "CallerIDName: %s\r\n"
02686       "ConnectedLineNum: %s\r\n"
02687       "ConnectedLineName: %s\r\n"
02688       "Cause: %d\r\n"
02689       "Cause-txt: %s\r\n",
02690       ast_channel_name(chan),
02691       ast_channel_uniqueid(chan),
02692       S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "<unknown>"),
02693       S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, "<unknown>"),
02694       S_COR(chan->connected.id.number.valid, chan->connected.id.number.str, "<unknown>"),
02695       S_COR(chan->connected.id.name.valid, chan->connected.id.name.str, "<unknown>"),
02696       chan->hangupcause,
02697       ast_cause2str(chan->hangupcause)
02698       );
02699 
02700    if (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_BRIDGED) &&
02701       !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED) &&
02702       (chan->cdr->disposition != AST_CDR_NULL || ast_test_flag(chan->cdr, AST_CDR_FLAG_DIALED))) {
02703       ast_channel_lock(chan);
02704       ast_cdr_end(chan->cdr);
02705       ast_cdr_detach(chan->cdr);
02706       chan->cdr = NULL;
02707       ast_channel_unlock(chan);
02708    }
02709 
02710    ast_channel_unref(chan);
02711 
02712    return 0;
02713 }

int ast_indicate ( struct ast_channel chan,
int  condition 
)

Indicates condition of channel.

Note:
Indicate a condition such as AST_CONTROL_BUSY, AST_CONTROL_RINGING, or AST_CONTROL_CONGESTION on a channel
Parameters:
chan channel to change the indication
condition which condition to indicate on the channel
Returns:
Returns 0 on success, -1 on failure

Definition at line 4117 of file channel.c.

References ast_indicate_data().

Referenced by __ast_play_and_record(), agent_request(), alsa_call(), answer_trunk_chan(), app_exec(), ast_bridge_call(), ast_bridge_set_single_src_video_mode(), ast_bridge_update_talker_src_video_mode(), ast_channel_bridge(), ast_do_masquerade(), ast_dtmf_stream(), ast_raw_answer(), attempt_transfer(), builtin_atxfer(), builtin_blindtransfer(), cli_console_answer(), conf_run(), console_call(), dial_exec_full(), disa_exec(), do_forward(), feature_request_and_dial(), finishup(), function_remote(), handle_callforward_button(), handle_frame(), handle_recordfile(), handle_request_refer(), local_attended_transfer(), manage_parked_call(), mgcp_ss(), monitor_dial(), oss_call(), park_call_full(), parked_call_exec(), pbx_builtin_busy(), pbx_builtin_congestion(), pbx_builtin_incomplete(), pbx_builtin_proceeding(), pbx_builtin_progress(), pbx_builtin_ringing(), pbx_builtin_waitexten(), queue_exec(), record_exec(), rna(), rpt(), rpt_exec(), say_periodic_announcement(), say_position(), send_waveform_to_channel(), skinny_ss(), sla_handle_hold_event(), sla_station_exec(), sla_trunk_exec(), try_calling(), and wait_for_answer().

04118 {
04119    return ast_indicate_data(chan, condition, NULL, 0);
04120 }

int ast_indicate_data ( struct ast_channel chan,
int  condition,
const void *  data,
size_t  datalen 
)

Indicates condition of channel, with payload.

Note:
Indicate a condition such as AST_CONTROL_HOLD with payload being music on hold class
Parameters:
chan channel to change the indication
condition which condition to indicate on the channel
data pointer to payload data
datalen size of payload data
Returns:
Returns 0 on success, -1 on failure

Note:
If we compare the enumeration type, which does not have any negative constants, the compiler may optimize this code away. Therefore, we must perform an integer comparison here.

Definition at line 4172 of file channel.c.

References ast_channel::_state, _XXX_AST_CONTROL_T38, ast_channel_lock, ast_channel_name(), ast_channel_set_connected_line(), ast_channel_set_redirecting(), ast_channel_unlock, ast_check_hangup(), ast_connected_line_parse_data(), AST_CONTROL_ANSWER, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CC, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_END_OF_Q, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_MCID, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_READ_ACTION, AST_CONTROL_REDIRECTING, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_TRANSFER, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_CONTROL_VIDUPDATE, AST_CONTROL_WINK, ast_debug, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, ast_framehook_list_is_empty(), ast_framehook_list_write_event(), ast_frdup(), ast_frfree, ast_get_indication_tone(), ast_log(), ast_party_connected_line_free(), ast_party_connected_line_set_init(), ast_party_redirecting_free(), ast_party_redirecting_set_init(), ast_playtones_start(), ast_playtones_stop(), ast_redirecting_parse_data(), AST_STATE_UP, ast_test_flag, ast_tone_zone_sound_unref(), ast_channel::connected, ast_tone_zone_sound::data, ast_frame::data, ast_frame::datalen, ast_channel::framehooks, ast_frame::frametype, ast_channel_tech::indicate, ast_frame_subclass::integer, is_visible_indication(), LOG_WARNING, ast_frame::ptr, ast_channel::redirecting, ast_frame::subclass, ast_channel::tech, ast_channel::visible_indication, and ast_channel::zone.

Referenced by __ast_read(), action_aocmessage(), agent_hangup(), ast_bridge_call(), ast_channel_update_connected_line(), ast_channel_update_redirecting(), ast_generic_bridge(), ast_handle_cc_control_frame(), ast_indicate(), disable_t38(), fax_gateway_indicate_t38(), feature_request_and_dial(), generic_fax_exec(), handle_frame(), local_bridge_loop(), login_exec(), manage_parked_call(), park_call_full(), pbx_builtin_waitexten(), receivefax_t38_init(), remote_bridge_loop(), sendfax_t38_init(), set_fax_t38_caps(), transmit_audio(), transmit_t38(), and wait_for_answer().

04174 {
04175    /* By using an enum, we'll get compiler warnings for values not handled 
04176     * in switch statements. */
04177    enum ast_control_frame_type condition = _condition;
04178    struct ast_tone_zone_sound *ts = NULL;
04179    int res;
04180    /* this frame is used by framehooks. if it is set, we must free it at the end of this function */
04181    struct ast_frame *awesome_frame = NULL;
04182 
04183    ast_channel_lock(chan);
04184 
04185    /* Don't bother if the channel is about to go away, anyway. */
04186    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
04187       res = -1;
04188       goto indicate_cleanup;
04189    }
04190 
04191    if (!ast_framehook_list_is_empty(chan->framehooks)) {
04192       /* Do framehooks now, do it, go, go now */
04193       struct ast_frame frame = {
04194          .frametype = AST_FRAME_CONTROL,
04195          .subclass.integer = condition,
04196          .data.ptr = (void *) data, /* this cast from const is only okay because we do the ast_frdup below */
04197          .datalen = datalen
04198       };
04199 
04200       /* we have now committed to freeing this frame */
04201       awesome_frame = ast_frdup(&frame);
04202 
04203       /* who knows what we will get back! the anticipation is killing me. */
04204       if (!(awesome_frame = ast_framehook_list_write_event(chan->framehooks, awesome_frame))
04205          || awesome_frame->frametype != AST_FRAME_CONTROL) {
04206 
04207          res = 0;
04208          goto indicate_cleanup;
04209       }
04210 
04211       condition = awesome_frame->subclass.integer;
04212       data = awesome_frame->data.ptr;
04213       datalen = awesome_frame->datalen;
04214    }
04215 
04216    switch (condition) {
04217    case AST_CONTROL_CONNECTED_LINE:
04218       {
04219          struct ast_party_connected_line connected;
04220 
04221          ast_party_connected_line_set_init(&connected, &chan->connected);
04222          res = ast_connected_line_parse_data(data, datalen, &connected);
04223          if (!res) {
04224             ast_channel_set_connected_line(chan, &connected, NULL);
04225          }
04226          ast_party_connected_line_free(&connected);
04227       }
04228       break;
04229 
04230    case AST_CONTROL_REDIRECTING:
04231       {
04232          struct ast_party_redirecting redirecting;
04233 
04234          ast_party_redirecting_set_init(&redirecting, &chan->redirecting);
04235          res = ast_redirecting_parse_data(data, datalen, &redirecting);
04236          if (!res) {
04237             ast_channel_set_redirecting(chan, &redirecting, NULL);
04238          }
04239          ast_party_redirecting_free(&redirecting);
04240       }
04241       break;
04242    
04243    default:
04244       break;
04245    }
04246 
04247    if (is_visible_indication(condition)) {
04248       /* A new visible indication is requested. */
04249       chan->visible_indication = condition;
04250    } else if (condition == AST_CONTROL_UNHOLD || _condition < 0) {
04251       /* Visible indication is cleared/stopped. */
04252       chan->visible_indication = 0;
04253    }
04254 
04255    if (chan->tech->indicate) {
04256       /* See if the channel driver can handle this condition. */
04257       res = chan->tech->indicate(chan, condition, data, datalen);
04258    } else {
04259       res = -1;
04260    }
04261 
04262    if (!res) {
04263       /* The channel driver successfully handled this indication */
04264       res = 0;
04265       goto indicate_cleanup;
04266    }
04267 
04268    /* The channel driver does not support this indication, let's fake
04269     * it by doing our own tone generation if applicable. */
04270 
04271    /*!\note If we compare the enumeration type, which does not have any
04272     * negative constants, the compiler may optimize this code away.
04273     * Therefore, we must perform an integer comparison here. */
04274    if (_condition < 0) {
04275       /* Stop any tones that are playing */
04276       ast_playtones_stop(chan);
04277       res = 0;
04278       goto indicate_cleanup;
04279    }
04280 
04281    /* Handle conditions that we have tones for. */
04282    switch (condition) {
04283    case _XXX_AST_CONTROL_T38:
04284       /* deprecated T.38 control frame */
04285       res = -1;
04286       goto indicate_cleanup;
04287    case AST_CONTROL_T38_PARAMETERS:
04288       /* there is no way to provide 'default' behavior for these
04289        * control frames, so we need to return failure, but there
04290        * is also no value in the log message below being emitted
04291        * since failure to handle these frames is not an 'error'
04292        * so just return right now. in addition, we want to return
04293        * whatever value the channel driver returned, in case it
04294        * has some meaning.*/
04295       goto indicate_cleanup;
04296    case AST_CONTROL_RINGING:
04297       ts = ast_get_indication_tone(chan->zone, "ring");
04298       /* It is common practice for channel drivers to return -1 if trying
04299        * to indicate ringing on a channel which is up. The idea is to let the
04300        * core generate the ringing inband. However, we don't want the
04301        * warning message about not being able to handle the specific indication
04302        * to print nor do we want ast_indicate_data to return an "error" for this
04303        * condition
04304        */
04305       if (chan->_state == AST_STATE_UP) {
04306          res = 0;
04307       }
04308       break;
04309    case AST_CONTROL_BUSY:
04310       ts = ast_get_indication_tone(chan->zone, "busy");
04311       break;
04312    case AST_CONTROL_INCOMPLETE:
04313    case AST_CONTROL_CONGESTION:
04314       ts = ast_get_indication_tone(chan->zone, "congestion");
04315       break;
04316    case AST_CONTROL_PROGRESS:
04317    case AST_CONTROL_PROCEEDING:
04318    case AST_CONTROL_VIDUPDATE:
04319    case AST_CONTROL_SRCUPDATE:
04320    case AST_CONTROL_SRCCHANGE:
04321    case AST_CONTROL_RADIO_KEY:
04322    case AST_CONTROL_RADIO_UNKEY:
04323    case AST_CONTROL_OPTION:
04324    case AST_CONTROL_WINK:
04325    case AST_CONTROL_FLASH:
04326    case AST_CONTROL_OFFHOOK:
04327    case AST_CONTROL_TAKEOFFHOOK:
04328    case AST_CONTROL_ANSWER:
04329    case AST_CONTROL_HANGUP:
04330    case AST_CONTROL_RING:
04331    case AST_CONTROL_HOLD:
04332    case AST_CONTROL_UNHOLD:
04333    case AST_CONTROL_TRANSFER:
04334    case AST_CONTROL_CONNECTED_LINE:
04335    case AST_CONTROL_REDIRECTING:
04336    case AST_CONTROL_CC:
04337    case AST_CONTROL_READ_ACTION:
04338    case AST_CONTROL_AOC:
04339    case AST_CONTROL_END_OF_Q:
04340    case AST_CONTROL_MCID:
04341    case AST_CONTROL_UPDATE_RTP_PEER:
04342       /* Nothing left to do for these. */
04343       res = 0;
04344       break;
04345    }
04346 
04347    if (ts) {
04348       /* We have a tone to play, yay. */
04349       ast_debug(1, "Driver for channel '%s' does not support indication %d, emulating it\n", ast_channel_name(chan), condition);
04350       res = ast_playtones_start(chan, 0, ts->data, 1);
04351       ts = ast_tone_zone_sound_unref(ts);
04352    }
04353 
04354    if (res) {
04355       /* not handled */
04356       ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, ast_channel_name(chan));
04357    }
04358 
04359 indicate_cleanup:
04360    ast_channel_unlock(chan);
04361    if (awesome_frame) {
04362       ast_frfree(awesome_frame);
04363    }
04364 
04365    return res;
04366 }

void ast_install_music_functions ( int(*)(struct ast_channel *, const char *, const char *)  start_ptr,
void(*)(struct ast_channel *)  stop_ptr,
void(*)(struct ast_channel *)  cleanup_ptr 
)

Definition at line 7778 of file channel.c.

References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.

Referenced by load_module().

07781 {
07782    ast_moh_start_ptr = start_ptr;
07783    ast_moh_stop_ptr = stop_ptr;
07784    ast_moh_cleanup_ptr = cleanup_ptr;
07785 }

int ast_internal_timing_enabled ( struct ast_channel chan  ) 

Check if the channel can run in internal timing mode.

Parameters:
chan The channel to check
Returns:
boolean
This function will return 1 if internal timing is enabled and the timing device is available.

Definition at line 4102 of file channel.c.

References ast_opt_internal_timing, and ast_channel::timingfd.

Referenced by add_sdp(), and ast_read_generator_actions().

04103 {
04104    return (ast_opt_internal_timing && chan->timingfd > -1);
04105 }

int ast_is_deferrable_frame ( const struct ast_frame frame  ) 

Should we keep this frame for later?

There are functions such as ast_safe_sleep which will service a channel to ensure that it does not have a large backlog of queued frames. When this happens, we want to hold on to specific frame types and just drop others. This function will tell if the frame we just read should be held onto.

Parameters:
frame The frame we just read
Return values:
1 frame should be kept
0 frame should be dropped

Definition at line 1603 of file channel.c.

References 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, and ast_frame::frametype.

Referenced by ast_safe_sleep_conditional(), autoservice_run(), and feature_request_and_dial().

01604 {
01605    /* Do not add a default entry in this switch statement.  Each new
01606     * frame type should be addressed directly as to whether it should
01607     * be queued up or not.
01608     */
01609    switch (frame->frametype) {
01610    case AST_FRAME_CONTROL:
01611    case AST_FRAME_TEXT:
01612    case AST_FRAME_IMAGE:
01613    case AST_FRAME_HTML:
01614       return 1;
01615 
01616    case AST_FRAME_DTMF_END:
01617    case AST_FRAME_DTMF_BEGIN:
01618    case AST_FRAME_VOICE:
01619    case AST_FRAME_VIDEO:
01620    case AST_FRAME_NULL:
01621    case AST_FRAME_IAX:
01622    case AST_FRAME_CNG:
01623    case AST_FRAME_MODEM:
01624       return 0;
01625    }
01626    return 0;
01627 }

void ast_moh_cleanup ( struct ast_channel chan  ) 

Definition at line 7812 of file channel.c.

References ast_moh_cleanup_ptr.

Referenced by ast_channel_destructor().

07813 {
07814    if (ast_moh_cleanup_ptr)
07815       ast_moh_cleanup_ptr(chan);
07816 }

int ast_moh_start ( struct ast_channel chan,
const char *  mclass,
const char *  interpclass 
)

Turn on music on hold on a given channel.

Parameters:
chan The channel structure that will get music on hold
mclass The class to use if the musicclass is not currently set on the channel structure.
interpclass The class to use if the musicclass is not currently set on the channel structure or in the mclass argument.
Return values:
Zero on success
non-zero on failure

Definition at line 7795 of file channel.c.

References ast_moh_start_ptr, and ast_verb.

Referenced by alsa_indicate(), app_exec(), conf_handle_dtmf(), conf_run(), conf_start_moh(), confbridge_exec(), console_indicate(), dahdi_indicate(), dial_exec_full(), feature_exec_app(), gtalk_indicate(), handle_setmusic(), iax2_indicate(), jingle_indicate(), key_call(), leave_conference_bridge(), local_indicate(), mgcp_indicate(), misdn_indication(), moh_handle_digit(), monitor_dial(), oh323_indicate(), oss_indicate(), phone_indicate(), play_moh_exec(), post_join_marked(), post_join_unmarked(), queue_exec(), retrydial_exec(), rna(), say_periodic_announcement(), say_position(), sip_indicate(), skinny_indicate(), start_moh_exec(), TransferCallStep1(), unistim_indicate(), usbradio_indicate(), and wait_moh_exec().

07796 {
07797    if (ast_moh_start_ptr)
07798       return ast_moh_start_ptr(chan, mclass, interpclass);
07799 
07800    ast_verb(3, "Music class %s requested but no musiconhold loaded.\n", mclass ? mclass : (interpclass ? interpclass : "default"));
07801 
07802    return 0;
07803 }

void ast_moh_stop ( struct ast_channel chan  ) 

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.

Since:
1.8
Parameters:
dest Destination caller
src Source caller
Returns:
Nothing

Definition at line 2054 of file channel.c.

References ast_party_caller::ani, ast_party_caller::ani2, ast_party_id_copy(), and ast_party_caller::id.

Referenced by wait_for_answer().

02055 {
02056    if (dest == src) {
02057       /* Don't copy to self */
02058       return;
02059    }
02060 
02061    ast_party_id_copy(&dest->id, &src->id);
02062    ast_party_id_copy(&dest->ani, &src->ani);
02063    dest->ani2 = src->ani2;
02064 }

void ast_party_caller_free ( struct ast_party_caller doomed  ) 

Destroy the caller party contents.

Since:
1.8
Parameters:
doomed The caller party to destroy.
Returns:
Nothing

Definition at line 2080 of file channel.c.

References ast_party_caller::ani, ast_party_id_free(), and ast_party_caller::id.

Referenced by ast_channel_destructor(), ast_dummy_channel_destructor(), callerid_write(), dial_trunk(), and sla_ring_station().

02081 {
02082    ast_party_id_free(&doomed->id);
02083    ast_party_id_free(&doomed->ani);
02084 }

void ast_party_caller_init ( struct ast_party_caller init  ) 

Initialize the given caller structure.

Since:
1.8
Parameters:
init Caller structure to initialize.
Returns:
Nothing

Definition at line 2047 of file channel.c.

References ast_party_caller::ani, ast_party_caller::ani2, ast_party_id_init(), and ast_party_caller::id.

Referenced by __ast_channel_alloc_ap(), dial_trunk(), and sla_ring_station().

02048 {
02049    ast_party_id_init(&init->id);
02050    ast_party_id_init(&init->ani);
02051    init->ani2 = 0;
02052 }

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.

Since:
1.8
This is similar to ast_party_caller_copy, except that NULL values for strings in the src parameter indicate not to update the corresponding dest values.

Parameters:
dest The caller one wishes to update
src The new caller values to update the dest
update What caller information to update. NULL if all.
Returns:
Nada

Definition at line 2073 of file channel.c.

References ast_set_party_caller::ani, ast_party_caller::ani, ast_party_caller::ani2, ast_party_id_set(), ast_set_party_caller::id, and ast_party_caller::id.

Referenced by ast_channel_set_caller(), ast_channel_set_caller_event(), and callerid_write().

02074 {
02075    ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL);
02076    ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL);
02077    dest->ani2 = src->ani2;
02078 }

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.

Since:
1.8
The initialization is needed to allow a set operation to know if a value needs to be updated. Simple integers need the guide's original value in case the set operation is not trying to set a new value. String values are simply set to NULL pointers if they are not going to be updated.

Parameters:
init Caller structure to initialize.
guide Source caller to use as a guide in initializing.
Returns:
Nothing

Definition at line 2066 of file channel.c.

References ast_party_caller::ani, ast_party_caller::ani2, ast_party_id_set_init(), and ast_party_caller::id.

Referenced by callerid_write(), dial_exec_full(), do_forward(), misdn_update_caller_id(), and ring_entry().

02067 {
02068    ast_party_id_set_init(&init->id, &guide->id);
02069    ast_party_id_set_init(&init->ani, &guide->ani);
02070    init->ani2 = guide->ani2;
02071 }

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.

Since:
1.8
Parameters:
connected Collected caller information for the connected line
caller Caller information.
Returns:
Nothing
Warning:
This is a shallow copy.

DO NOT call ast_party_connected_line_free() on the filled in connected line structure!

Definition at line 2123 of file channel.c.

References ast_party_caller::ani, ast_party_connected_line::ani, ast_party_caller::ani2, ast_party_connected_line::ani2, AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN, ast_party_caller::id, ast_party_connected_line::id, and ast_party_connected_line::source.

02124 {
02125    connected->id = caller->id;
02126    connected->ani = caller->ani;
02127    connected->ani2 = caller->ani2;
02128    connected->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN;
02129 }

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.

Since:
1.8
Parameters:
dest Destination connected line
src Source connected line
Returns:
Nothing

Definition at line 2094 of file channel.c.

References ast_party_connected_line::ani, ast_party_connected_line::ani2, ast_party_id_copy(), ast_party_connected_line::id, and ast_party_connected_line::source.

Referenced by __ast_read(), ast_call_forward(), ast_channel_connected_line_macro(), ast_do_pickup(), builtin_atxfer(), dial_exec_full(), do_forward(), local_attended_transfer(), misdn_attempt_transfer(), party_connected_line_copy_transfer(), try_calling(), and wait_for_answer().

02095 {
02096    if (dest == src) {
02097       /* Don't copy to self */
02098       return;
02099    }
02100 
02101    ast_party_id_copy(&dest->id, &src->id);
02102    ast_party_id_copy(&dest->ani, &src->ani);
02103    dest->ani2 = src->ani2;
02104    dest->source = src->source;
02105 }

void ast_party_connected_line_free ( struct ast_party_connected_line doomed  ) 

void ast_party_connected_line_init ( struct ast_party_connected_line init  ) 

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.

Since:
1.8 This is similar to ast_party_connected_line_copy, except that NULL values for strings in the src parameter indicate not to update the corresponding dest values.
Parameters:
dest The connected line one wishes to update
src The new connected line values to update the dest
update What connected line information to update. NULL if all.
Returns:
Nothing

Definition at line 2115 of file channel.c.

References ast_set_party_connected_line::ani, ast_party_connected_line::ani, ast_party_connected_line::ani2, ast_party_id_set(), ast_set_party_connected_line::id, ast_party_connected_line::id, and ast_party_connected_line::source.

Referenced by ast_channel_set_connected_line(), wait_for_answer(), and wait_for_winner().

02116 {
02117    ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL);
02118    ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL);
02119    dest->ani2 = src->ani2;
02120    dest->source = src->source;
02121 }

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.

Since:
1.8
The initialization is needed to allow a set operation to know if a value needs to be updated. Simple integers need the guide's original value in case the set operation is not trying to set a new value. String values are simply set to NULL pointers if they are not going to be updated.

Parameters:
init Connected line structure to initialize.
guide Source connected line to use as a guide in initializing.
Returns:
Nothing

Definition at line 2107 of file channel.c.

References ast_party_connected_line::ani, ast_party_connected_line::ani2, ast_party_id_set_init(), ast_party_connected_line::id, and ast_party_connected_line::source.

Referenced by __ast_request_and_dial(), ast_indicate_data(), connectedline_write(), dial_exec_full(), feature_request_and_dial(), wait_for_answer(), and wait_for_winner().

02108 {
02109    ast_party_id_set_init(&init->id, &guide->id);
02110    ast_party_id_set_init(&init->ani, &guide->ani);
02111    init->ani2 = guide->ani2;
02112    init->source = guide->source;
02113 }

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.

Since:
1.8
Parameters:
dest Destination dialed party
src Source dialed party
Returns:
Nothing

Definition at line 2005 of file channel.c.

References ast_free, ast_party_subaddress_copy(), ast_strdup, ast_party_dialed::number, ast_party_dialed::plan, ast_party_dialed::str, ast_party_dialed::subaddress, and ast_party_dialed::transit_network_select.

Referenced by local_call().

02006 {
02007    if (dest == src) {
02008       /* Don't copy to self */
02009       return;
02010    }
02011 
02012    ast_free(dest->number.str);
02013    dest->number.str = ast_strdup(src->number.str);
02014    dest->number.plan = src->number.plan;
02015    ast_party_subaddress_copy(&dest->subaddress, &src->subaddress);
02016    dest->transit_network_select = src->transit_network_select;
02017 }

void ast_party_dialed_free ( struct ast_party_dialed doomed  ) 

Destroy the dialed party contents.

Since:
1.8
Parameters:
doomed The dialed party to destroy.
Returns:
Nothing

Definition at line 2040 of file channel.c.

References ast_free, ast_party_subaddress_free(), ast_party_dialed::number, ast_party_dialed::str, and ast_party_dialed::subaddress.

Referenced by ast_channel_destructor(), ast_dummy_channel_destructor(), and callerid_write().

02041 {
02042    ast_free(doomed->number.str);
02043    doomed->number.str = NULL;
02044    ast_party_subaddress_free(&doomed->subaddress);
02045 }

void ast_party_dialed_init ( struct ast_party_dialed init  ) 

Initialize the given dialed structure.

Since:
1.8
Parameters:
init Dialed structure to initialize.
Returns:
Nothing

Definition at line 1997 of file channel.c.

References ast_party_subaddress_init(), ast_party_dialed::number, ast_party_dialed::plan, ast_party_dialed::str, ast_party_dialed::subaddress, and ast_party_dialed::transit_network_select.

Referenced by __ast_channel_alloc_ap().

01998 {
01999    init->number.str = NULL;
02000    init->number.plan = 0;/* Unknown */
02001    ast_party_subaddress_init(&init->subaddress);
02002    init->transit_network_select = 0;
02003 }

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.

Since:
1.8
This is similar to ast_party_dialed_copy, except that NULL values for strings in the src parameter indicate not to update the corresponding dest values.

Parameters:
dest The dialed one wishes to update
src The new dialed values to update the dest
Returns:
Nada

Definition at line 2027 of file channel.c.

References ast_free, ast_party_subaddress_set(), ast_strdup, ast_party_dialed::number, ast_party_dialed::plan, ast_party_dialed::str, ast_party_dialed::subaddress, and ast_party_dialed::transit_network_select.

Referenced by callerid_write().

02028 {
02029    if (src->number.str && src->number.str != dest->number.str) {
02030       ast_free(dest->number.str);
02031       dest->number.str = ast_strdup(src->number.str);
02032    }
02033    dest->number.plan = src->number.plan;
02034 
02035    ast_party_subaddress_set(&dest->subaddress, &src->subaddress);
02036 
02037    dest->transit_network_select = src->transit_network_select;
02038 }

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.

Since:
1.8
The initialization is needed to allow a set operation to know if a value needs to be updated. Simple integers need the guide's original value in case the set operation is not trying to set a new value. String values are simply set to NULL pointers if they are not going to be updated.

Parameters:
init Caller structure to initialize.
guide Source dialed to use as a guide in initializing.
Returns:
Nothing

Definition at line 2019 of file channel.c.

References ast_party_subaddress_set_init(), ast_party_dialed::number, ast_party_dialed::plan, ast_party_dialed::str, ast_party_dialed::subaddress, and ast_party_dialed::transit_network_select.

Referenced by callerid_write().

02020 {
02021    init->number.str = NULL;
02022    init->number.plan = guide->number.plan;
02023    ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress);
02024    init->transit_network_select = guide->transit_network_select;
02025 }

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.

Since:
1.8
Parameters:
dest Destination party id
src Source party id
Returns:
Nothing

Definition at line 1876 of file channel.c.

References ast_free, ast_party_name_copy(), ast_party_number_copy(), ast_party_subaddress_copy(), ast_strdup, ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, and ast_party_id::tag.

Referenced by ast_connected_line_copy_from_caller(), ast_connected_line_copy_to_caller(), ast_party_caller_copy(), ast_party_connected_line_copy(), ast_party_redirecting_copy(), and parkandannounce_exec().

01877 {
01878    if (dest == src) {
01879       /* Don't copy to self */
01880       return;
01881    }
01882 
01883    ast_party_name_copy(&dest->name, &src->name);
01884    ast_party_number_copy(&dest->number, &src->number);
01885    ast_party_subaddress_copy(&dest->subaddress, &src->subaddress);
01886 
01887    ast_free(dest->tag);
01888    dest->tag = ast_strdup(src->tag);
01889 }

void ast_party_id_free ( struct ast_party_id doomed  ) 

Destroy the party id contents.

Since:
1.8
Parameters:
doomed The party id to destroy.
Returns:
Nothing

Definition at line 1922 of file channel.c.

References ast_free, ast_party_name_free(), ast_party_number_free(), ast_party_subaddress_free(), ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, and ast_party_id::tag.

Referenced by ast_party_caller_free(), ast_party_connected_line_free(), ast_party_redirecting_free(), and parkandannounce_exec().

01923 {
01924    ast_party_name_free(&doomed->name);
01925    ast_party_number_free(&doomed->number);
01926    ast_party_subaddress_free(&doomed->subaddress);
01927 
01928    ast_free(doomed->tag);
01929    doomed->tag = NULL;
01930 }

void ast_party_id_init ( struct ast_party_id init  ) 

Initialize the given party id structure.

Since:
1.8
Parameters:
init Party id structure to initialize.
Returns:
Nothing

Definition at line 1868 of file channel.c.

References ast_party_name_init(), ast_party_number_init(), ast_party_subaddress_init(), ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, and ast_party_id::tag.

Referenced by ast_party_caller_init(), ast_party_connected_line_init(), ast_party_redirecting_init(), dial_exec_full(), and parkandannounce_exec().

01869 {
01870    ast_party_name_init(&init->name);
01871    ast_party_number_init(&init->number);
01872    ast_party_subaddress_init(&init->subaddress);
01873    init->tag = NULL;
01874 }

int ast_party_id_presentation ( const struct ast_party_id id  ) 

Determine the overall presentation value for the given party.

Since:
1.8
Parameters:
id Party to determine the overall presentation value.
Returns:
Overall presentation value for the given party.

Definition at line 1932 of file channel.c.

References AST_PRES_ALLOWED, AST_PRES_NUMBER_TYPE, AST_PRES_RESTRICTED, AST_PRES_RESTRICTION, AST_PRES_UNAVAILABLE, AST_PRES_USER_NUMBER_UNSCREENED, ast_party_id::name, ast_party_id::number, ast_party_number::valid, and ast_party_name::valid.

Referenced by add_rpid(), ast_str_retrieve_variable(), ast_var_channels_table(), callerpres_read(), iax2_call(), initreqprep(), oh323_call(), party_id_build_data(), party_id_read(), redirecting_read(), report_new_callerid(), setup_env(), sip_call(), and socket_process().

01933 {
01934    int number_priority;
01935    int number_value;
01936    int number_screening;
01937    int name_priority;
01938    int name_value;
01939 
01940    /* Determine name presentation priority. */
01941    if (!id->name.valid) {
01942       name_value = AST_PRES_UNAVAILABLE;
01943       name_priority = 3;
01944    } else {
01945       name_value = id->name.presentation & AST_PRES_RESTRICTION;
01946       switch (name_value) {
01947       case AST_PRES_RESTRICTED:
01948          name_priority = 0;
01949          break;
01950       case AST_PRES_ALLOWED:
01951          name_priority = 1;
01952          break;
01953       case AST_PRES_UNAVAILABLE:
01954          name_priority = 2;
01955          break;
01956       default:
01957          name_value = AST_PRES_UNAVAILABLE;
01958          name_priority = 3;
01959          break;
01960       }
01961    }
01962 
01963    /* Determine number presentation priority. */
01964    if (!id->number.valid) {
01965       number_screening = AST_PRES_USER_NUMBER_UNSCREENED;
01966       number_value = AST_PRES_UNAVAILABLE;
01967       number_priority = 3;
01968    } else {
01969       number_screening = id->number.presentation & AST_PRES_NUMBER_TYPE;
01970       number_value = id->number.presentation & AST_PRES_RESTRICTION;
01971       switch (number_value) {
01972       case AST_PRES_RESTRICTED:
01973          number_priority = 0;
01974          break;
01975       case AST_PRES_ALLOWED:
01976          number_priority = 1;
01977          break;
01978       case AST_PRES_UNAVAILABLE:
01979          number_priority = 2;
01980          break;
01981       default:
01982          number_screening = AST_PRES_USER_NUMBER_UNSCREENED;
01983          number_value = AST_PRES_UNAVAILABLE;
01984          number_priority = 3;
01985          break;
01986       }
01987    }
01988 
01989    /* Select the wining presentation value. */
01990    if (name_priority < number_priority) {
01991       number_value = name_value;
01992    }
01993 
01994    return number_value | number_screening;
01995 }

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.

Since:
1.8
Parameters:
dest The id one wishes to update
src The new id values to update the dest
update What id information to update. NULL if all.
Returns:
Nothing

Definition at line 1899 of file channel.c.

References ast_free, ast_party_name_set(), ast_party_number_set(), ast_party_subaddress_set(), ast_strdup, ast_party_id::name, ast_set_party_id::name, ast_party_id::number, ast_set_party_id::number, ast_party_id::subaddress, ast_set_party_id::subaddress, and ast_party_id::tag.

Referenced by ast_party_caller_set(), ast_party_connected_line_set(), and ast_party_redirecting_set().

01900 {
01901    if (dest == src) {
01902       /* Don't set to self */
01903       return;
01904    }
01905 
01906    if (!update || update->name) {
01907       ast_party_name_set(&dest->name, &src->name);
01908    }
01909    if (!update || update->number) {
01910       ast_party_number_set(&dest->number, &src->number);
01911    }
01912    if (!update || update->subaddress) {
01913       ast_party_subaddress_set(&dest->subaddress, &src->subaddress);
01914    }
01915 
01916    if (src->tag && src->tag != dest->tag) {
01917       ast_free(dest->tag);
01918       dest->tag = ast_strdup(src->tag);
01919    }
01920 }

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.

Since:
1.8
The initialization is needed to allow a set operation to know if a value needs to be updated. Simple integers need the guide's original value in case the set operation is not trying to set a new value. String values are simply set to NULL pointers if they are not going to be updated.

Parameters:
init Party id structure to initialize.
guide Source party id to use as a guide in initializing.
Returns:
Nothing

Definition at line 1891 of file channel.c.

References ast_party_name_set_init(), ast_party_number_set_init(), ast_party_subaddress_set_init(), ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, and ast_party_id::tag.

Referenced by ast_party_caller_set_init(), ast_party_connected_line_set_init(), ast_party_redirecting_set_init(), and dial_exec_full().

01892 {
01893    ast_party_name_set_init(&init->name, &guide->name);
01894    ast_party_number_set_init(&init->number, &guide->number);
01895    ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress);
01896    init->tag = NULL;
01897 }

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.

Since:
1.8
Parameters:
dest Destination party name
src Source party name
Returns:
Nothing

Definition at line 1717 of file channel.c.

References ast_free, ast_strdup, ast_party_name::char_set, ast_party_name::presentation, ast_party_name::str, and ast_party_name::valid.

Referenced by ast_party_id_copy().

01718 {
01719    if (dest == src) {
01720       /* Don't copy to self */
01721       return;
01722    }
01723 
01724    ast_free(dest->str);
01725    dest->str = ast_strdup(src->str);
01726    dest->char_set = src->char_set;
01727    dest->presentation = src->presentation;
01728    dest->valid = src->valid;
01729 }

void ast_party_name_free ( struct ast_party_name doomed  ) 

Destroy the party name contents.

Since:
1.8
Parameters:
doomed The party name to destroy.
Returns:
Nothing

Definition at line 1756 of file channel.c.

References ast_free, and ast_party_name::str.

Referenced by __analog_ss_thread(), analog_ss_thread(), ast_party_id_free(), and skinny_newcall().

01757 {
01758    ast_free(doomed->str);
01759    doomed->str = NULL;
01760 }

void ast_party_name_init ( struct ast_party_name init  ) 

Initialize the given name structure.

Since:
1.8
Parameters:
init Name structure to initialize.
Returns:
Nothing

Definition at line 1709 of file channel.c.

References AST_PARTY_CHAR_SET_ISO8859_1, AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, ast_party_name::char_set, ast_party_name::presentation, ast_party_name::str, and ast_party_name::valid.

Referenced by __analog_ss_thread(), analog_ss_thread(), ast_party_id_init(), and skinny_newcall().

01710 {
01711    init->str = NULL;
01712    init->char_set = AST_PARTY_CHAR_SET_ISO8859_1;
01713    init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
01714    init->valid = 0;
01715 }

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.

Since:
1.8
Parameters:
dest The name one wishes to update
src The new name values to update the dest
Returns:
Nothing

Definition at line 1739 of file channel.c.

References ast_free, ast_strdup, ast_party_name::char_set, ast_party_name::presentation, ast_party_name::str, and ast_party_name::valid.

Referenced by ast_party_id_set().

01740 {
01741    if (dest == src) {
01742       /* Don't set to self */
01743       return;
01744    }
01745 
01746    if (src->str && src->str != dest->str) {
01747       ast_free(dest->str);
01748       dest->str = ast_strdup(src->str);
01749    }
01750 
01751    dest->char_set = src->char_set;
01752    dest->presentation = src->presentation;
01753    dest->valid = src->valid;
01754 }

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.

Since:
1.8
The initialization is needed to allow a set operation to know if a value needs to be updated. Simple integers need the guide's original value in case the set operation is not trying to set a new value. String values are simply set to NULL pointers if they are not going to be updated.

Parameters:
init Party name structure to initialize.
guide Source party name to use as a guide in initializing.
Returns:
Nothing

Definition at line 1731 of file channel.c.

References ast_party_name::char_set, ast_party_name::presentation, ast_party_name::str, and ast_party_name::valid.

Referenced by ast_party_id_set_init().

01732 {
01733    init->str = NULL;
01734    init->char_set = guide->char_set;
01735    init->presentation = guide->presentation;
01736    init->valid = guide->valid;
01737 }

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.

Since:
1.8
Parameters:
dest Destination party number
src Source party number
Returns:
Nothing

Definition at line 1770 of file channel.c.

References ast_free, ast_strdup, ast_party_number::plan, ast_party_number::presentation, ast_party_number::str, and ast_party_number::valid.

Referenced by ast_party_id_copy().

01771 {
01772    if (dest == src) {
01773       /* Don't copy to self */
01774       return;
01775    }
01776 
01777    ast_free(dest->str);
01778    dest->str = ast_strdup(src->str);
01779    dest->plan = src->plan;
01780    dest->presentation = src->presentation;
01781    dest->valid = src->valid;
01782 }

void ast_party_number_free ( struct ast_party_number doomed  ) 

Destroy the party number contents.

Since:
1.8
Parameters:
doomed The party number to destroy.
Returns:
Nothing

Definition at line 1809 of file channel.c.

References ast_free, and ast_party_number::str.

Referenced by __analog_ss_thread(), analog_ss_thread(), ast_party_id_free(), do_forward(), skinny_newcall(), and wait_for_answer().

01810 {
01811    ast_free(doomed->str);
01812    doomed->str = NULL;
01813 }

void ast_party_number_init ( struct ast_party_number init  ) 

Initialize the given number structure.

Since:
1.8
Parameters:
init Number structure to initialize.
Returns:
Nothing

Definition at line 1762 of file channel.c.

References AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, ast_party_number::plan, ast_party_number::presentation, ast_party_number::str, and ast_party_number::valid.

Referenced by __analog_ss_thread(), analog_ss_thread(), ast_party_id_init(), do_forward(), skinny_newcall(), and wait_for_answer().

01763 {
01764    init->str = NULL;
01765    init->plan = 0;/* Unknown */
01766    init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
01767    init->valid = 0;
01768 }

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.

Since:
1.8
Parameters:
dest The number one wishes to update
src The new number values to update the dest
Returns:
Nothing

Definition at line 1792 of file channel.c.

References ast_free, ast_strdup, ast_party_number::plan, ast_party_number::presentation, ast_party_number::str, and ast_party_number::valid.

Referenced by ast_party_id_set().

01793 {
01794    if (dest == src) {
01795       /* Don't set to self */
01796       return;
01797    }
01798 
01799    if (src->str && src->str != dest->str) {
01800       ast_free(dest->str);
01801       dest->str = ast_strdup(src->str);
01802    }
01803 
01804    dest->plan = src->plan;
01805    dest->presentation = src->presentation;
01806    dest->valid = src->valid;
01807 }

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.

Since:
1.8
The initialization is needed to allow a set operation to know if a value needs to be updated. Simple integers need the guide's original value in case the set operation is not trying to set a new value. String values are simply set to NULL pointers if they are not going to be updated.

Parameters:
init Party number structure to initialize.
guide Source party number to use as a guide in initializing.
Returns:
Nothing

Definition at line 1784 of file channel.c.

References ast_party_number::plan, ast_party_number::presentation, ast_party_number::str, and ast_party_number::valid.

Referenced by ast_party_id_set_init().

01785 {
01786    init->str = NULL;
01787    init->plan = guide->plan;
01788    init->presentation = guide->presentation;
01789    init->valid = guide->valid;
01790 }

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.

Since:
1.8
Parameters:
dest Destination redirecting
src Source redirecting
Returns:
Nothing

Definition at line 2145 of file channel.c.

References ast_party_id_copy(), ast_party_redirecting::count, ast_party_redirecting::from, ast_party_redirecting::reason, and ast_party_redirecting::to.

Referenced by ast_call_forward(), ast_channel_redirecting_macro(), begin_dial_channel(), call_forward_inherit(), dial_exec_full(), do_forward(), local_call(), ring_entry(), and wait_for_answer().

02146 {
02147    if (dest == src) {
02148       /* Don't copy to self */
02149       return;
02150    }
02151 
02152    ast_party_id_copy(&dest->from, &src->from);
02153    ast_party_id_copy(&dest->to, &src->to);
02154    dest->count = src->count;
02155    dest->reason = src->reason;
02156 }

void ast_party_redirecting_free ( struct ast_party_redirecting doomed  ) 

Destroy the redirecting information contents.

Since:
1.8
Parameters:
doomed The redirecting information to destroy.
Returns:
Nothing

Definition at line 2174 of file channel.c.

References ast_party_id_free(), ast_party_redirecting::from, and ast_party_redirecting::to.

Referenced by ast_channel_destructor(), ast_dummy_channel_destructor(), ast_indicate_data(), call_forward_inherit(), do_forward(), handle_request_invite(), handle_response(), handle_response_invite(), redirecting_write(), and wait_for_answer().

02175 {
02176    ast_party_id_free(&doomed->from);
02177    ast_party_id_free(&doomed->to);
02178 }

void ast_party_redirecting_init ( struct ast_party_redirecting init  ) 

Initialize the given redirecting structure.

Since:
1.8
Parameters:
init Redirecting structure to initialize.
Returns:
Nothing

Definition at line 2137 of file channel.c.

References ast_party_id_init(), AST_REDIRECTING_REASON_UNKNOWN, ast_party_redirecting::count, ast_party_redirecting::from, ast_party_redirecting::reason, and ast_party_redirecting::to.

Referenced by __ast_channel_alloc_ap(), call_forward_inherit(), do_forward(), handle_request_invite(), handle_response(), handle_response_invite(), and wait_for_answer().

02138 {
02139    ast_party_id_init(&init->from);
02140    ast_party_id_init(&init->to);
02141    init->count = 0;
02142    init->reason = AST_REDIRECTING_REASON_UNKNOWN;
02143 }

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.

Since:
1.8
This is similar to ast_party_redirecting_copy, except that NULL values for strings in the src parameter indicate not to update the corresponding dest values.

Parameters:
dest The redirecting one wishes to update
src The new redirecting values to update the dest
update What redirecting information to update. NULL if all.
Returns:
Nothing

Definition at line 2166 of file channel.c.

References ast_party_id_set(), ast_party_redirecting::count, ast_set_party_redirecting::from, ast_party_redirecting::from, ast_party_redirecting::reason, ast_set_party_redirecting::to, and ast_party_redirecting::to.

Referenced by ast_channel_set_redirecting().

02167 {
02168    ast_party_id_set(&dest->from, &src->from, update ? &update->from : NULL);
02169    ast_party_id_set(&dest->to, &src->to, update ? &update->to : NULL);
02170    dest->reason = src->reason;
02171    dest->count = src->count;
02172 }

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.

Since:
1.8
The initialization is needed to allow a set operation to know if a value needs to be updated. Simple integers need the guide's original value in case the set operation is not trying to set a new value. String values are simply set to NULL pointers if they are not going to be updated.

Parameters:
init Redirecting id structure to initialize.
guide Source redirecting id to use as a guide in initializing.
Returns:
Nothing

Definition at line 2158 of file channel.c.

References ast_party_id_set_init(), ast_party_redirecting::count, ast_party_redirecting::from, ast_party_redirecting::reason, and ast_party_redirecting::to.

Referenced by ast_indicate_data(), misdn_copy_redirecting_to_ast(), and redirecting_write().

02159 {
02160    ast_party_id_set_init(&init->from, &guide->from);
02161    ast_party_id_set_init(&init->to, &guide->to);
02162    init->count = guide->count;
02163    init->reason = guide->reason;
02164 }

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.

Since:
1.8
Parameters:
dest Destination party subaddress
src Source party subaddress
Returns:
Nothing

Definition at line 1823 of file channel.c.

References ast_free, ast_strdup, ast_party_subaddress::odd_even_indicator, ast_party_subaddress::str, ast_party_subaddress::type, and ast_party_subaddress::valid.

Referenced by ast_party_dialed_copy(), and ast_party_id_copy().

01824 {
01825    if (dest == src) {
01826       /* Don't copy to self */
01827       return;
01828    }
01829 
01830    ast_free(dest->str);
01831    dest->str = ast_strdup(src->str);
01832    dest->type = src->type;
01833    dest->odd_even_indicator = src->odd_even_indicator;
01834    dest->valid = src->valid;
01835 }

void ast_party_subaddress_free ( struct ast_party_subaddress doomed  ) 

Destroy the party subaddress contents.

Since:
1.8
Parameters:
doomed The party subaddress to destroy.
Returns:
Nothing

Definition at line 1862 of file channel.c.

References ast_free, and ast_party_subaddress::str.

Referenced by ast_party_dialed_free(), and ast_party_id_free().

01863 {
01864    ast_free(doomed->str);
01865    doomed->str = NULL;
01866 }

void ast_party_subaddress_init ( struct ast_party_subaddress init  ) 

Initialize the given subaddress structure.

Since:
1.8
Parameters:
init Subaddress structure to initialize.
Returns:
Nothing

Definition at line 1815 of file channel.c.

References ast_party_subaddress::odd_even_indicator, ast_party_subaddress::str, ast_party_subaddress::type, and ast_party_subaddress::valid.

Referenced by ast_party_dialed_init(), and ast_party_id_init().

01816 {
01817    init->str = NULL;
01818    init->type = 0;
01819    init->odd_even_indicator = 0;
01820    init->valid = 0;
01821 }

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.

Since:
1.8
Parameters:
dest The subaddress one wishes to update
src The new subaddress values to update the dest
Returns:
Nothing

Definition at line 1845 of file channel.c.

References ast_free, ast_strdup, ast_party_subaddress::odd_even_indicator, ast_party_subaddress::str, ast_party_subaddress::type, and ast_party_subaddress::valid.

Referenced by ast_party_dialed_set(), and ast_party_id_set().

01846 {
01847    if (dest == src) {
01848       /* Don't set to self */
01849       return;
01850    }
01851 
01852    if (src->str && src->str != dest->str) {
01853       ast_free(dest->str);
01854       dest->str = ast_strdup(src->str);
01855    }
01856 
01857    dest->type = src->type;
01858    dest->odd_even_indicator = src->odd_even_indicator;
01859    dest->valid = src->valid;
01860 }

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.

Since:
1.8
The initialization is needed to allow a set operation to know if a value needs to be updated. Simple integers need the guide's original value in case the set operation is not trying to set a new value. String values are simply set to NULL pointers if they are not going to be updated.

Parameters:
init Party subaddress structure to initialize.
guide Source party subaddress to use as a guide in initializing.
Returns:
Nothing

Definition at line 1837 of file channel.c.

References ast_party_subaddress::odd_even_indicator, ast_party_subaddress::str, ast_party_subaddress::type, and ast_party_subaddress::valid.

Referenced by ast_party_dialed_set_init(), and ast_party_id_set_init().

01838 {
01839    init->str = NULL;
01840    init->type = guide->type;
01841    init->odd_even_indicator = guide->odd_even_indicator;
01842    init->valid = guide->valid;
01843 }

int ast_plc_reload ( void   ) 

Reload genericplc configuration value from codecs.conf.

Implementation is in main/channel.c

Definition at line 7831 of file channel.c.

References ast_config_destroy(), ast_config_load, AST_OPT_FLAG_GENERIC_PLC, ast_options, ast_set2_flag, ast_true(), ast_variable_browse(), CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, ast_variable::name, ast_variable::next, ast_variable::value, and var.

Referenced by ast_channels_init().

07832 {
07833    struct ast_variable *var;
07834    struct ast_flags config_flags = { 0 };
07835    struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
07836    if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID)
07837       return 0;
07838    for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
07839       if (!strcasecmp(var->name, "genericplc")) {
07840          ast_set2_flag(&ast_options, ast_true(var->value), AST_OPT_FLAG_GENERIC_PLC);
07841       }
07842    }
07843    ast_config_destroy(cfg);
07844    return 0;
07845 }

void ast_poll_channel_add ( struct ast_channel chan0,
struct ast_channel chan1 
)

Add a channel to an optimized waitfor

Definition at line 2437 of file channel.c.

References AST_MAX_FDS, and ast_channel::fds.

Referenced by ast_generic_bridge(), begin_dial_channel(), feature_request_and_dial(), local_bridge_loop(), remote_bridge_loop(), and wait_for_answer().

02438 {
02439 #ifdef HAVE_EPOLL
02440    struct epoll_event ev;
02441    int i = 0;
02442 
02443    if (chan0->epfd == -1)
02444       return;
02445 
02446    /* Iterate through the file descriptors on chan1, adding them to chan0 */
02447    for (i = 0; i < AST_MAX_FDS; i++) {
02448       if (chan1->fds[i] == -1)
02449          continue;
02450       ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP;
02451       ev.data.ptr = chan1->epfd_data[i];
02452       epoll_ctl(chan0->epfd, EPOLL_CTL_ADD, chan1->fds[i], &ev);
02453    }
02454 
02455 #endif
02456    return;
02457 }

void ast_poll_channel_del ( struct ast_channel chan0,
struct ast_channel chan1 
)

Delete a channel from an optimized waitfor

Definition at line 2460 of file channel.c.

References AST_MAX_FDS, and ast_channel::fds.

Referenced by ast_generic_bridge(), feature_request_and_dial(), local_bridge_loop(), monitor_dial(), remote_bridge_loop(), and wait_for_answer().

02461 {
02462 #ifdef HAVE_EPOLL
02463    struct epoll_event ev;
02464    int i = 0;
02465 
02466    if (chan0->epfd == -1)
02467       return;
02468 
02469    for (i = 0; i < AST_MAX_FDS; i++) {
02470       if (chan1->fds[i] == -1)
02471          continue;
02472       epoll_ctl(chan0->epfd, EPOLL_CTL_DEL, chan1->fds[i], &ev);
02473    }
02474 
02475 #endif
02476    return;
02477 }

char* ast_print_group ( char *  buf,
int  buflen,
ast_group_t  group 
)

Print call group and pickup group ---.

print call- and pickup groups into buffer

Definition at line 7979 of file channel.c.

References first.

Referenced by _sip_show_peer(), _skinny_show_line(), func_channel_read(), function_sippeer(), misdn_cfg_get_config_string(), print_group(), read_config(), and serialize_showchan().

07980 {
07981    unsigned int i;
07982    int first = 1;
07983    char num[3];
07984 
07985    buf[0] = '\0';
07986    
07987    if (!group) /* Return empty string if no group */
07988       return buf;
07989 
07990    for (i = 0; i <= 63; i++) {   /* Max group is 63 */
07991       if (group & ((ast_group_t) 1 << i)) {
07992             if (!first) {
07993             strncat(buf, ", ", buflen - strlen(buf) - 1);
07994          } else {
07995             first = 0;
07996          }
07997          snprintf(num, sizeof(num), "%u", i);
07998          strncat(buf, num, buflen - strlen(buf) - 1);
07999       }
08000    }
08001    return buf;
08002 }

int ast_prod ( struct ast_channel chan  ) 

Send empty audio to prime a channel driver.

Definition at line 4512 of file channel.c.

References ast_channel::_state, ast_channel_name(), ast_debug, ast_format_copy(), AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), AST_STATE_UP, ast_write(), ast_frame::data, ast_frame_subclass::format, LOG_WARNING, ast_frame::ptr, ast_channel::rawwriteformat, ast_frame::src, and ast_frame::subclass.

Referenced by ast_activate_generator().

04513 {
04514    struct ast_frame a = { AST_FRAME_VOICE };
04515    char nothing[128];
04516 
04517    /* Send an empty audio frame to get things moving */
04518    if (chan->_state != AST_STATE_UP) {
04519       ast_debug(1, "Prodding channel '%s'\n", ast_channel_name(chan));
04520       ast_format_copy(&a.subclass.format, &chan->rawwriteformat);
04521       a.data.ptr = nothing + AST_FRIENDLY_OFFSET;
04522       a.src = "ast_prod"; /* this better match check in ast_write */
04523       if (ast_write(chan, &a))
04524          ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", ast_channel_name(chan));
04525    }
04526    return 0;
04527 }

int ast_queue_control ( struct ast_channel chan,
enum ast_control_frame_type  control 
)

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.

Parameters:
chan channel to queue frame onto
control type of control frame
data pointer to payload data to be included in frame
datalen number of bytes of payload data
Return values:
0 success
non-zero failure
The supplied payload data is copied into the frame, so the caller's copy is not modified nor freed, and the resulting frame will retain a copy of the data even if the caller frees their local copy.

Note:
This method should be treated as a 'network transport'; in other words, your frames may be transferred across an IAX2 channel to another system, which may be a different endianness than yours. Because of this, you should ensure that either your frames will never be expected to work across systems, or that you always put your payload data into 'network byte order' before calling this function.

The channel does not need to be locked before calling this function.

Definition at line 1388 of file channel.c.

References AST_FRAME_CONTROL, and ast_queue_frame().

Referenced by __analog_handle_event(), analog_hangup(), ast_channel_queue_connected_line_update(), ast_channel_queue_redirecting_update(), change_t38_state(), dahdi_handle_event(), dahdi_hangup(), fax_gateway_indicate_t38(), handle_request_notify(), handle_response_refer(), iax2_queue_control_data(), iax2_transfer(), interpret_t38_parameters(), local_attended_transfer(), masquerade_colp_transfer(), process_sdp(), setsubstate(), and sip_sipredirect().

01390 {
01391    struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control, .data.ptr = (void *) data, .datalen = datalen };
01392    return ast_queue_frame(chan, &f);
01393 }

int ast_queue_frame ( struct ast_channel chan,
struct ast_frame f 
)

Queue one or more frames to a channel's frame queue.

Parameters:
chan the channel to queue the frame(s) on
f the frame(s) to queue. Note that the frame(s) will be duplicated by this function. It is the responsibility of the caller to handle freeing the memory associated with the frame(s) being passed if necessary.
Return values:
0 success
non-zero failure

Definition at line 1326 of file channel.c.

References __ast_queue_frame().

Referenced by __ast_channel_masquerade(), __ast_read(), __oh323_rtp_create(), __oh323_update_info(), action_atxfer(), agent_request(), alsa_call(), ast_channel_setwhentohangup_tv(), ast_do_masquerade(), ast_dsp_process(), ast_queue_cc_frame(), ast_queue_control(), ast_queue_control_data(), ast_queue_hangup(), ast_queue_hangup_with_cause(), ast_softhangup_nolock(), bridge_write(), cb_events(), cli_console_dial(), cli_console_sendtext(), conf_stop_record(), console_dial(), console_do_answer(), console_flash(), console_sendtext(), dahdi_queue_frame(), dahdi_read(), dictate_exec(), do_immediate_setup(), gtalk_handle_dtmf(), handle_keypad_button_message(), handle_request_info(), handle_request_invite(), handle_response_invite(), iax2_queue_frame(), jingle_handle_dtmf(), local_queue_frame(), mgcp_queue_frame(), oh323_simulate_dtmf_end(), oss_call(), process_sdp(), queue_dtmf_readq(), receive_digit(), receive_message(), rpt_call(), stream_monitor(), t38_tx_packet_handler(), unistim_do_senddigit(), unistim_senddigit_end(), usbradio_read(), and wakeup_sub().

01327 {
01328    return __ast_queue_frame(chan, fin, 0, NULL);
01329 }

int ast_queue_frame_head ( struct ast_channel chan,
struct ast_frame f 
)

Queue one or more frames to the head of a channel's frame queue.

Parameters:
chan the channel to queue the frame(s) on
f the frame(s) to queue. Note that the frame(s) will be duplicated by this function. It is the responsibility of the caller to handle freeing the memory associated with the frame(s) being passed if necessary.
Return values:
0 success
non-zero failure

Definition at line 1331 of file channel.c.

References __ast_queue_frame().

Referenced by __ast_answer(), __ast_read(), ast_autoservice_stop(), ast_safe_sleep_conditional(), and feature_request_and_dial().

01332 {
01333    return __ast_queue_frame(chan, fin, 1, NULL);
01334 }

int ast_queue_hangup ( struct ast_channel chan  ) 

Queue a hangup frame for channel.

Queue a hangup frame.

Definition at line 1337 of file channel.c.

References ast_channel::_softhangup, ast_channel_name(), ast_channel_trylock, ast_channel_uniqueid(), ast_channel_unlock, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, ast_queue_frame(), AST_SOFTHANGUP_DEV, EVENT_FLAG_CALL, and manager_event.

Referenced by cleanup_connection(), cli_console_hangup(), close_call(), gtalk_hangup_farend(), gtalk_is_answered(), handle_request_bye(), handle_request_cancel(), iax2_destroy(), iax2_queue_hangup(), jingle_hangup_farend(), local_fixup(), local_hangup(), mgcp_queue_hangup(), and setsubstate().

01338 {
01339    struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP };
01340    /* Yeah, let's not change a lock-critical value without locking */
01341    if (!ast_channel_trylock(chan)) {
01342       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01343       manager_event(EVENT_FLAG_CALL, "HangupRequest",
01344          "Channel: %s\r\n"
01345          "Uniqueid: %s\r\n",
01346          ast_channel_name(chan),
01347          ast_channel_uniqueid(chan));
01348       ast_channel_unlock(chan);
01349    }
01350    return ast_queue_frame(chan, &f);
01351 }

int ast_queue_hangup_with_cause ( struct ast_channel chan,
int  cause 
)

Queue a hangup frame for channel.

Queue a hangup frame with hangupcause set.

Definition at line 1354 of file channel.c.

References ast_channel::_softhangup, ast_channel_name(), ast_channel_trylock, ast_channel_uniqueid(), ast_channel_unlock, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, ast_queue_frame(), AST_SOFTHANGUP_DEV, ast_frame::data, EVENT_FLAG_CALL, ast_channel::hangupcause, manager_event, and ast_frame::uint32.

Referenced by __analog_handle_event(), __oh323_update_info(), __sip_autodestruct(), close_call(), close_client(), console_hangup(), dahdi_handle_event(), handle_request_bye(), handle_response(), handle_response_invite(), HandleCallOutgoing(), hangup_chan(), hangup_connection(), misdn_answer(), retrans_pkt(), and TransferCallStep1().

01355 {
01356    struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP };
01357 
01358    if (cause >= 0)
01359       f.data.uint32 = cause;
01360 
01361    /* Yeah, let's not change a lock-critical value without locking */
01362    if (!ast_channel_trylock(chan)) {
01363       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01364       if (cause < 0)
01365          f.data.uint32 = chan->hangupcause;
01366 
01367       manager_event(EVENT_FLAG_CALL, "HangupRequest",
01368          "Channel: %s\r\n"
01369          "Uniqueid: %s\r\n"
01370          "Cause: %d\r\n",
01371          ast_channel_name(chan),
01372          ast_channel_uniqueid(chan),
01373          cause);
01374       ast_channel_unlock(chan);
01375    }
01376 
01377    return ast_queue_frame(chan, &f);
01378 }

int ast_raw_answer ( struct ast_channel chan,
int  cdr_answer 
)

Answer a channel.

Parameters:
chan channel to answer
cdr_answer flag to control whether any associated CDR should be marked as 'answered'
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.

Unlike ast_answer(), this function will not wait for media flow to begin. The caller should be careful before sending media to the channel before incoming media arrives, as the outgoing media may be lost.

Return values:
0 on success
non-zero on failure

Definition at line 2715 of file channel.c.

References ast_channel::_state, ast_channel_tech::answer, ast_cdr_answer(), AST_CEL_ANSWER, ast_cel_report_event(), ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, ast_indicate(), ast_setstate(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_test_flag, ast_channel::cdr, and ast_channel::tech.

Referenced by __ast_answer(), and ast_bridge_call().

02716 {
02717    int res = 0;
02718 
02719    ast_channel_lock(chan);
02720 
02721    /* You can't answer an outbound call */
02722    if (ast_test_flag(chan, AST_FLAG_OUTGOING)) {
02723       ast_channel_unlock(chan);
02724       return 0;
02725    }
02726 
02727    /* Stop if we're a zombie or need a soft hangup */
02728    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
02729       ast_channel_unlock(chan);
02730       return -1;
02731    }
02732 
02733    ast_channel_unlock(chan);
02734 
02735    switch (chan->_state) {
02736    case AST_STATE_RINGING:
02737    case AST_STATE_RING:
02738       ast_channel_lock(chan);
02739       if (chan->tech->answer) {
02740          res = chan->tech->answer(chan);
02741       }
02742       ast_setstate(chan, AST_STATE_UP);
02743       if (cdr_answer) {
02744          ast_cdr_answer(chan->cdr);
02745       }
02746       ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL);
02747       ast_channel_unlock(chan);
02748       break;
02749    case AST_STATE_UP:
02750       ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL);
02751       /* Calling ast_cdr_answer when it it has previously been called
02752        * is essentially a no-op, so it is safe.
02753        */
02754       if (cdr_answer) {
02755          ast_cdr_answer(chan->cdr);
02756       }
02757       break;
02758    default:
02759       break;
02760    }
02761 
02762    ast_indicate(chan, -1);
02763 
02764    return res;
02765 }

struct ast_frame* ast_read ( struct ast_channel chan  )  [read]

Reads a frame.

Parameters:
chan channel to read a frame from
Returns:
Returns a frame, or NULL on error. If it returns NULL, you best just stop reading frames and assume the channel has been disconnected.

Definition at line 4107 of file channel.c.

References __ast_read().

Referenced by __adsi_transmit_messages(), __analog_ss_thread(), __ast_answer(), __ast_play_and_record(), __ast_request_and_dial(), adsi_careful_send(), agent_ack_sleep(), agent_read(), analog_ss_thread(), ast_bridge_handle_trip(), ast_generic_bridge(), ast_recvtext(), ast_safe_sleep_conditional(), ast_tonepair(), ast_transfer(), ast_udptl_bridge(), ast_waitfordigit_full(), async_agi_read_frame(), async_wait(), autoservice_run(), background_detect_exec(), channel_spy(), conf_flush(), conf_run(), dahdi_bridge(), dial_exec_full(), dictate_exec(), disa_exec(), disable_t38(), do_waiting(), echo_exec(), eivr_comm(), feature_request_and_dial(), find_cache(), generic_fax_exec(), handle_recordfile(), handle_speechrecognize(), iax2_bridge(), ices_exec(), isAnsweringMachine(), jack_exec(), local_bridge_loop(), manage_parked_call(), measurenoise(), misdn_bridge(), monitor_dial(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), receivefax_t38_init(), record_exec(), recordthread(), remote_bridge_loop(), rpt(), rpt_exec(), run_agi(), send_tone_burst(), send_waveform_to_channel(), sendfax_t38_init(), sendurl_exec(), speech_background(), transmit_audio(), transmit_t38(), wait_for_answer(), wait_for_hangup(), wait_for_winner(), waitforring_exec(), and waitstream_core().

04108 {
04109    return __ast_read(chan, 0);
04110 }

static void ast_read_generator_actions ( struct ast_channel chan,
struct ast_frame f 
) [static]

Definition at line 3462 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_deactivate_generator(), ast_debug, ast_format_cmp(), AST_FORMAT_CMP_NOT_EQUAL, ast_format_rate(), AST_FRAME_CNG, ast_internal_timing_enabled(), ast_settimeout(), ast_frame::datalen, ast_frame_subclass::format, ast_frame::frametype, ast_generator::generate, ast_channel::generator, generator_force(), ast_channel::generatordata, ast_frame::samples, ast_frame::subclass, ast_channel::timingfd, ast_channel::timingfunc, and ast_channel::writeformat.

Referenced by __ast_read().

03463 {
03464    if (chan->generator && chan->generator->generate && chan->generatordata &&  !ast_internal_timing_enabled(chan)) {
03465       void *tmp = chan->generatordata;
03466       int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = chan->generator->generate;
03467       int res;
03468       int samples;
03469 
03470       if (chan->timingfunc) {
03471          ast_debug(1, "Generator got voice, switching to phase locked mode\n");
03472          ast_settimeout(chan, 0, NULL, NULL);
03473       }
03474 
03475       chan->generatordata = NULL;     /* reset, to let writes go through */
03476 
03477       if (ast_format_cmp(&f->subclass.format, &chan->writeformat) == AST_FORMAT_CMP_NOT_EQUAL) {
03478          float factor;
03479          factor = ((float) ast_format_rate(&chan->writeformat)) / ((float) ast_format_rate(&f->subclass.format));
03480          samples = (int) ( ((float) f->samples) * factor );
03481       } else {
03482          samples = f->samples;
03483       }
03484 
03485       /* This unlock is here based on two assumptions that hold true at this point in the
03486        * code. 1) this function is only called from within __ast_read() and 2) all generators
03487        * call ast_write() in their generate callback.
03488        *
03489        * The reason this is added is so that when ast_write is called, the lock that occurs 
03490        * there will not recursively lock the channel. Doing this will cause intended deadlock 
03491        * avoidance not to work in deeper functions
03492        */
03493       ast_channel_unlock(chan);
03494       res = generate(chan, tmp, f->datalen, samples);
03495       ast_channel_lock(chan);
03496       chan->generatordata = tmp;
03497       if (res) {
03498          ast_debug(1, "Auto-deactivating generator\n");
03499          ast_deactivate_generator(chan);
03500       }
03501 
03502    } else if (f->frametype == AST_FRAME_CNG) {
03503       if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) {
03504          ast_debug(1, "Generator got CNG, switching to timed mode\n");
03505          ast_settimeout(chan, 50, generator_force, chan);
03506       }
03507    }
03508 }

struct ast_frame* ast_read_noaudio ( struct ast_channel chan  )  [read]

Reads a frame, returning AST_FRAME_NULL frame if audio.

Parameters:
chan channel to read a frame from
Returns:
Returns a frame, or NULL on error. If it returns NULL, you best just stop reading frames and assume the channel has been disconnected.
Note:
Audio is replaced with AST_FRAME_NULL to avoid transcode when the resulting audio is not necessary.

Definition at line 4112 of file channel.c.

References __ast_read().

Referenced by ast_bridge_handle_trip(), and conf_run().

04113 {
04114    return __ast_read(chan, 1);
04115 }

int ast_readstring ( struct ast_channel c,
char *  s,
int  len,
int  timeout,
int  rtimeout,
char *  enders 
)

Reads multiple digits.

Parameters:
c channel to read from
s string to read in to. Must be at least the size of your length
len how many digits to read (maximum)
timeout how long to timeout between digits
rtimeout timeout to wait on the first digit
enders digits to end the string
Read in a digit string "s", max length "len", maximum timeout between digits "timeout" (-1 for none), terminated by anything in "enders". Give them rtimeout for the first digit.
Returns:
Returns 0 on normal return, or 1 on a timeout. In the case of a timeout, any digits that were read before the timeout will still be available in s. RETURNS 2 in full version when ctrlfd is available, NOT 1

Definition at line 5686 of file channel.c.

References ast_readstring_full().

Referenced by __adsi_transmit_messages(), ast_adsi_begin_download(), ast_adsi_get_cpeinfo(), ast_adsi_load_session(), ast_app_getdata(), dialout(), do_directory(), forward_message(), privacy_exec(), vm_authenticate(), vm_newuser(), and vm_options().

05687 {
05688    return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1);
05689 }

int ast_readstring_full ( struct ast_channel c,
char *  s,
int  len,
int  timeout,
int  ftimeout,
char *  enders,
int  audiofd,
int  ctrlfd 
)

Definition at line 5691 of file channel.c.

References ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_check_hangup(), AST_DIGIT_ANY, AST_FLAG_ZOMBIE, AST_GETDATA_COMPLETE, AST_GETDATA_EMPTY_END_TERMINATED, AST_GETDATA_FAILED, AST_GETDATA_INTERRUPTED, AST_GETDATA_TIMEOUT, ast_opt_transmit_silence, ast_stopstream(), ast_test_flag, ast_waitfordigit_full(), ast_waitstream_full(), and ast_channel::stream.

Referenced by ast_app_getdata_full(), and ast_readstring().

05692 {
05693    int pos = 0;   /* index in the buffer where we accumulate digits */
05694    int to = ftimeout;
05695 
05696    struct ast_silence_generator *silgen = NULL;
05697 
05698    /* Stop if we're a zombie or need a soft hangup */
05699    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
05700       return -1;
05701    if (!len)
05702       return -1;
05703    for (;;) {
05704       int d;
05705       if (c->stream) {
05706          d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
05707          ast_stopstream(c);
05708          if (!silgen && ast_opt_transmit_silence)
05709             silgen = ast_channel_start_silence_generator(c);
05710          usleep(1000);
05711          if (!d)
05712             d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
05713       } else {
05714          if (!silgen && ast_opt_transmit_silence)
05715             silgen = ast_channel_start_silence_generator(c);
05716          d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
05717       }
05718       if (d < 0) {
05719          ast_channel_stop_silence_generator(c, silgen);
05720          return AST_GETDATA_FAILED;
05721       }
05722       if (d == 0) {
05723          s[pos] = '\0';
05724          ast_channel_stop_silence_generator(c, silgen);
05725          return AST_GETDATA_TIMEOUT;
05726       }
05727       if (d == 1) {
05728          s[pos] = '\0';
05729          ast_channel_stop_silence_generator(c, silgen);
05730          return AST_GETDATA_INTERRUPTED;
05731       }
05732       if (strchr(enders, d) && (pos == 0)) {
05733          s[pos] = '\0';
05734          ast_channel_stop_silence_generator(c, silgen);
05735          return AST_GETDATA_EMPTY_END_TERMINATED;
05736       }
05737       if (!strchr(enders, d)) {
05738          s[pos++] = d;
05739       }
05740       if (strchr(enders, d) || (pos >= len)) {
05741          s[pos] = '\0';
05742          ast_channel_stop_silence_generator(c, silgen);
05743          return AST_GETDATA_COMPLETE;
05744       }
05745       to = timeout;
05746    }
05747    /* Never reached */
05748    return 0;
05749 }

int ast_recvchar ( struct ast_channel chan,
int  timeout 
)

Receives a text character from a channel.

Parameters:
chan channel to act upon
timeout timeout in milliseconds (0 for infinite wait)
Read a char of text from a channel
Returns:
0 on success, -1 on failure

Definition at line 4368 of file channel.c.

References ast_free, and ast_recvtext().

Referenced by handle_recvchar().

04369 {
04370    int c;
04371    char *buf = ast_recvtext(chan, timeout);
04372    if (buf == NULL)
04373       return -1;  /* error or timeout */
04374    c = *(unsigned char *)buf;
04375    ast_free(buf);
04376    return c;
04377 }

char* ast_recvtext ( struct ast_channel chan,
int  timeout 
)

Receives a text string from a channel Read a string of text from a channel.

Parameters:
chan channel to act upon
timeout timeout in milliseconds (0 for infinite wait)
Returns:
the received text, or NULL to signify failure.

Definition at line 4379 of file channel.c.

References ast_check_hangup(), AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_TEXT, ast_frfree, ast_read(), ast_strndup, ast_waitfor(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, ast_frame_subclass::integer, ast_frame::ptr, and ast_frame::subclass.

Referenced by ast_recvchar(), and handle_recvtext().

04380 {
04381    int res, done = 0;
04382    char *buf = NULL;
04383    
04384    while (!done) {
04385       struct ast_frame *f;
04386       if (ast_check_hangup(chan))
04387          break;
04388       res = ast_waitfor(chan, timeout);
04389       if (res <= 0) /* timeout or error */
04390          break;
04391       timeout = res; /* update timeout */
04392       f = ast_read(chan);
04393       if (f == NULL)
04394          break; /* no frame */
04395       if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_HANGUP)
04396          done = 1;   /* force a break */
04397       else if (f->frametype == AST_FRAME_TEXT) {      /* what we want */
04398          buf = ast_strndup((char *) f->data.ptr, f->datalen);  /* dup and break */
04399          done = 1;
04400       }
04401       ast_frfree(f);
04402    }
04403    return buf;
04404 }

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.

Since:
1.8
Parameters:
data Buffer to fill with the frame data
datalen Size of the buffer to fill
redirecting Redirecting id information
update What redirecting information to build. NULL if all.
Return values:
-1 if error
Amount of data buffer used

Definition at line 8881 of file channel.c.

References ast_log(), AST_REDIRECTING_COUNT, AST_REDIRECTING_FROM_ID_PRESENTATION, AST_REDIRECTING_FROM_NAME, AST_REDIRECTING_FROM_NAME_CHAR_SET, AST_REDIRECTING_FROM_NAME_PRESENTATION, AST_REDIRECTING_FROM_NAME_VALID, AST_REDIRECTING_FROM_NUMBER, AST_REDIRECTING_FROM_NUMBER_PLAN, AST_REDIRECTING_FROM_NUMBER_PRESENTATION, AST_REDIRECTING_FROM_NUMBER_VALID, AST_REDIRECTING_FROM_SUBADDRESS, AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_FROM_SUBADDRESS_TYPE, AST_REDIRECTING_FROM_SUBADDRESS_VALID, AST_REDIRECTING_FROM_TAG, AST_REDIRECTING_TO_ID_PRESENTATION, AST_REDIRECTING_TO_NAME, AST_REDIRECTING_TO_NAME_CHAR_SET, AST_REDIRECTING_TO_NAME_PRESENTATION, AST_REDIRECTING_TO_NAME_VALID, AST_REDIRECTING_TO_NUMBER, AST_REDIRECTING_TO_NUMBER_PLAN, AST_REDIRECTING_TO_NUMBER_PRESENTATION, AST_REDIRECTING_TO_NUMBER_VALID, AST_REDIRECTING_TO_SUBADDRESS, AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_TO_SUBADDRESS_TYPE, AST_REDIRECTING_TO_SUBADDRESS_VALID, AST_REDIRECTING_TO_TAG, AST_REDIRECTING_VERSION, ast_party_redirecting::count, ast_set_party_redirecting::from, ast_party_redirecting::from, LOG_WARNING, ast_party_id_ies::name, party_id_build_data(), ast_party_redirecting::reason, ast_party_name_ies::str, ast_set_party_redirecting::to, ast_party_redirecting::to, and value.

Referenced by ast_channel_queue_redirecting_update(), ast_channel_update_redirecting(), and local_indicate().

08882 {
08883    int32_t value;
08884    size_t pos = 0;
08885    int res;
08886 
08887    static const struct ast_party_id_ies from_ies = {
08888       .name.str = AST_REDIRECTING_FROM_NAME,
08889       .name.char_set = AST_REDIRECTING_FROM_NAME_CHAR_SET,
08890       .name.presentation = AST_REDIRECTING_FROM_NAME_PRESENTATION,
08891       .name.valid = AST_REDIRECTING_FROM_NAME_VALID,
08892 
08893       .number.str = AST_REDIRECTING_FROM_NUMBER,
08894       .number.plan = AST_REDIRECTING_FROM_NUMBER_PLAN,
08895       .number.presentation = AST_REDIRECTING_FROM_NUMBER_PRESENTATION,
08896       .number.valid = AST_REDIRECTING_FROM_NUMBER_VALID,
08897 
08898       .subaddress.str = AST_REDIRECTING_FROM_SUBADDRESS,
08899       .subaddress.type = AST_REDIRECTING_FROM_SUBADDRESS_TYPE,
08900       .subaddress.odd_even_indicator = AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN,
08901       .subaddress.valid = AST_REDIRECTING_FROM_SUBADDRESS_VALID,
08902 
08903       .tag = AST_REDIRECTING_FROM_TAG,
08904       .combined_presentation = AST_REDIRECTING_FROM_ID_PRESENTATION,
08905    };
08906    static const struct ast_party_id_ies to_ies = {
08907       .name.str = AST_REDIRECTING_TO_NAME,
08908       .name.char_set = AST_REDIRECTING_TO_NAME_CHAR_SET,
08909       .name.presentation = AST_REDIRECTING_TO_NAME_PRESENTATION,
08910       .name.valid = AST_REDIRECTING_TO_NAME_VALID,
08911 
08912       .number.str = AST_REDIRECTING_TO_NUMBER,
08913       .number.plan = AST_REDIRECTING_TO_NUMBER_PLAN,
08914       .number.presentation = AST_REDIRECTING_TO_NUMBER_PRESENTATION,
08915       .number.valid = AST_REDIRECTING_TO_NUMBER_VALID,
08916 
08917       .subaddress.str = AST_REDIRECTING_TO_SUBADDRESS,
08918       .subaddress.type = AST_REDIRECTING_TO_SUBADDRESS_TYPE,
08919       .subaddress.odd_even_indicator = AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN,
08920       .subaddress.valid = AST_REDIRECTING_TO_SUBADDRESS_VALID,
08921 
08922       .tag = AST_REDIRECTING_TO_TAG,
08923       .combined_presentation = AST_REDIRECTING_TO_ID_PRESENTATION,
08924    };
08925 
08926    /* Redirecting frame version */
08927    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08928       ast_log(LOG_WARNING, "No space left for redirecting frame version\n");
08929       return -1;
08930    }
08931    data[pos++] = AST_REDIRECTING_VERSION;
08932    data[pos++] = 1;
08933    data[pos++] = 2;/* Version 1 did not have a version ie */
08934 
08935    res = party_id_build_data(data + pos, datalen - pos, &redirecting->from,
08936       "redirecting-from", &from_ies, update ? &update->from : NULL);
08937    if (res < 0) {
08938       return -1;
08939    }
08940    pos += res;
08941 
08942    res = party_id_build_data(data + pos, datalen - pos, &redirecting->to,
08943       "redirecting-to", &to_ies, update ? &update->to : NULL);
08944    if (res < 0) {
08945       return -1;
08946    }
08947    pos += res;
08948 
08949    /* Redirecting reason */
08950    if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
08951       ast_log(LOG_WARNING, "No space left for redirecting reason\n");
08952       return -1;
08953    }
08954    data[pos++] = AST_REDIRECTING_REASON;
08955    data[pos++] = sizeof(value);
08956    value = htonl(redirecting->reason);
08957    memcpy(data + pos, &value, sizeof(value));
08958    pos += sizeof(value);
08959 
08960    /* Redirecting count */
08961    if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
08962       ast_log(LOG_WARNING, "No space left for redirecting count\n");
08963       return -1;
08964    }
08965    data[pos++] = AST_REDIRECTING_COUNT;
08966    data[pos++] = sizeof(value);
08967    value = htonl(redirecting->count);
08968    memcpy(data + pos, &value, sizeof(value));
08969    pos += sizeof(value);
08970 
08971    return pos;
08972 }

int ast_redirecting_parse_data ( const unsigned char *  data,
size_t  datalen,
struct ast_party_redirecting redirecting 
)

Parse redirecting indication frame data.

Since:
1.8
Parameters:
data Buffer with the frame data to parse
datalen Size of the buffer
redirecting Extracted redirecting id information
Return values:
0 on success.
-1 on error.
Note:
The filled in id structure needs to be initialized by ast_party_redirecting_set_init() before calling.

The filled in id structure needs to be destroyed by ast_party_redirecting_free() when it is no longer needed.

Definition at line 8974 of file channel.c.

References ast_debug, ast_free, ast_log(), ast_malloc, AST_PARTY_CHAR_SET_ISO8859_1, AST_REDIRECTING_COUNT, AST_REDIRECTING_FROM_ID_PRESENTATION, AST_REDIRECTING_FROM_NAME, AST_REDIRECTING_FROM_NAME_CHAR_SET, AST_REDIRECTING_FROM_NAME_PRESENTATION, AST_REDIRECTING_FROM_NAME_VALID, AST_REDIRECTING_FROM_NUMBER, AST_REDIRECTING_FROM_NUMBER_PLAN, AST_REDIRECTING_FROM_NUMBER_PRESENTATION, AST_REDIRECTING_FROM_NUMBER_VALID, AST_REDIRECTING_FROM_SUBADDRESS, AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_FROM_SUBADDRESS_TYPE, AST_REDIRECTING_FROM_SUBADDRESS_VALID, AST_REDIRECTING_FROM_TAG, AST_REDIRECTING_TO_ID_PRESENTATION, AST_REDIRECTING_TO_NAME, AST_REDIRECTING_TO_NAME_CHAR_SET, AST_REDIRECTING_TO_NAME_PRESENTATION, AST_REDIRECTING_TO_NAME_VALID, AST_REDIRECTING_TO_NUMBER, AST_REDIRECTING_TO_NUMBER_PLAN, AST_REDIRECTING_TO_NUMBER_PRESENTATION, AST_REDIRECTING_TO_NUMBER_VALID, AST_REDIRECTING_TO_SUBADDRESS, AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_TO_SUBADDRESS_TYPE, AST_REDIRECTING_TO_SUBADDRESS_VALID, AST_REDIRECTING_TO_TAG, AST_REDIRECTING_VERSION, ast_party_name::char_set, ast_party_redirecting::count, ast_party_redirecting::from, LOG_WARNING, ast_party_id::name, ast_party_id::number, ast_party_subaddress::odd_even_indicator, ast_party_number::plan, ast_party_number::presentation, ast_party_name::presentation, ast_party_redirecting::reason, ast_party_subaddress::str, ast_party_number::str, ast_party_name::str, ast_party_id::subaddress, ast_party_id::tag, ast_party_redirecting::to, ast_party_subaddress::type, ast_party_subaddress::valid, ast_party_number::valid, ast_party_name::valid, and value.

Referenced by ast_channel_redirecting_macro(), and ast_indicate_data().

08975 {
08976    size_t pos;
08977    unsigned char ie_len;
08978    unsigned char ie_id;
08979    int32_t value;
08980    int frame_version = 1;
08981    int from_combined_presentation = 0;
08982    int got_from_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */
08983    int to_combined_presentation = 0;
08984    int got_to_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */
08985 
08986    for (pos = 0; pos < datalen; pos += ie_len) {
08987       if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) {
08988          ast_log(LOG_WARNING, "Invalid redirecting update\n");
08989          return -1;
08990       }
08991       ie_id = data[pos++];
08992       ie_len = data[pos++];
08993       if (datalen < pos + ie_len) {
08994          ast_log(LOG_WARNING, "Invalid redirecting update\n");
08995          return -1;
08996       }
08997 
08998       switch (ie_id) {
08999 /* Redirecting frame version */
09000       case AST_REDIRECTING_VERSION:
09001          if (ie_len != 1) {
09002             ast_log(LOG_WARNING, "Invalid redirecting frame version (%u)\n",
09003                (unsigned) ie_len);
09004             break;
09005          }
09006          frame_version = data[pos];
09007          break;
09008 /* Redirecting-from party id name */
09009       case AST_REDIRECTING_FROM_NAME:
09010          ast_free(redirecting->from.name.str);
09011          redirecting->from.name.str = ast_malloc(ie_len + 1);
09012          if (redirecting->from.name.str) {
09013             memcpy(redirecting->from.name.str, data + pos, ie_len);
09014             redirecting->from.name.str[ie_len] = 0;
09015          }
09016          break;
09017       case AST_REDIRECTING_FROM_NAME_CHAR_SET:
09018          if (ie_len != 1) {
09019             ast_log(LOG_WARNING, "Invalid redirecting-from name char set (%u)\n",
09020                (unsigned) ie_len);
09021             break;
09022          }
09023          redirecting->from.name.char_set = data[pos];
09024          break;
09025       case AST_REDIRECTING_FROM_NAME_PRESENTATION:
09026          if (ie_len != 1) {
09027             ast_log(LOG_WARNING, "Invalid redirecting-from name presentation (%u)\n",
09028                (unsigned) ie_len);
09029             break;
09030          }
09031          redirecting->from.name.presentation = data[pos];
09032          break;
09033       case AST_REDIRECTING_FROM_NAME_VALID:
09034          if (ie_len != 1) {
09035             ast_log(LOG_WARNING, "Invalid redirecting-from name valid (%u)\n",
09036                (unsigned) ie_len);
09037             break;
09038          }
09039          redirecting->from.name.valid = data[pos];
09040          break;
09041 /* Redirecting-from party id number */
09042       case AST_REDIRECTING_FROM_NUMBER:
09043          ast_free(redirecting->from.number.str);
09044          redirecting->from.number.str = ast_malloc(ie_len + 1);
09045          if (redirecting->from.number.str) {
09046             memcpy(redirecting->from.number.str, data + pos, ie_len);
09047             redirecting->from.number.str[ie_len] = 0;
09048          }
09049          break;
09050       case AST_REDIRECTING_FROM_NUMBER_PLAN:
09051          if (ie_len != 1) {
09052             ast_log(LOG_WARNING, "Invalid redirecting-from numbering plan (%u)\n",
09053                (unsigned) ie_len);
09054             break;
09055          }
09056          redirecting->from.number.plan = data[pos];
09057          break;
09058       case AST_REDIRECTING_FROM_NUMBER_PRESENTATION:
09059          if (ie_len != 1) {
09060             ast_log(LOG_WARNING, "Invalid redirecting-from number presentation (%u)\n",
09061                (unsigned) ie_len);
09062             break;
09063          }
09064          redirecting->from.number.presentation = data[pos];
09065          break;
09066       case AST_REDIRECTING_FROM_NUMBER_VALID:
09067          if (ie_len != 1) {
09068             ast_log(LOG_WARNING, "Invalid redirecting-from number valid (%u)\n",
09069                (unsigned) ie_len);
09070             break;
09071          }
09072          redirecting->from.number.valid = data[pos];
09073          break;
09074 /* Redirecting-from party id combined presentation */
09075       case AST_REDIRECTING_FROM_ID_PRESENTATION:
09076          if (ie_len != 1) {
09077             ast_log(LOG_WARNING, "Invalid redirecting-from combined presentation (%u)\n",
09078                (unsigned) ie_len);
09079             break;
09080          }
09081          from_combined_presentation = data[pos];
09082          got_from_combined_presentation = 1;
09083          break;
09084 /* Redirecting-from party id subaddress */
09085       case AST_REDIRECTING_FROM_SUBADDRESS:
09086          ast_free(redirecting->from.subaddress.str);
09087          redirecting->from.subaddress.str = ast_malloc(ie_len + 1);
09088          if (redirecting->from.subaddress.str) {
09089             memcpy(redirecting->from.subaddress.str, data + pos, ie_len);
09090             redirecting->from.subaddress.str[ie_len] = 0;
09091          }
09092          break;
09093       case AST_REDIRECTING_FROM_SUBADDRESS_TYPE:
09094          if (ie_len != 1) {
09095             ast_log(LOG_WARNING, "Invalid redirecting-from type of subaddress (%u)\n",
09096                (unsigned) ie_len);
09097             break;
09098          }
09099          redirecting->from.subaddress.type = data[pos];
09100          break;
09101       case AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN:
09102          if (ie_len != 1) {
09103             ast_log(LOG_WARNING,
09104                "Invalid redirecting-from subaddress odd-even indicator (%u)\n",
09105                (unsigned) ie_len);
09106             break;
09107          }
09108          redirecting->from.subaddress.odd_even_indicator = data[pos];
09109          break;
09110       case AST_REDIRECTING_FROM_SUBADDRESS_VALID:
09111          if (ie_len != 1) {
09112             ast_log(LOG_WARNING, "Invalid redirecting-from subaddress valid (%u)\n",
09113                (unsigned) ie_len);
09114             break;
09115          }
09116          redirecting->from.subaddress.valid = data[pos];
09117          break;
09118 /* Redirecting-from party id tag */
09119       case AST_REDIRECTING_FROM_TAG:
09120          ast_free(redirecting->from.tag);
09121          redirecting->from.tag = ast_malloc(ie_len + 1);
09122          if (redirecting->from.tag) {
09123             memcpy(redirecting->from.tag, data + pos, ie_len);
09124             redirecting->from.tag[ie_len] = 0;
09125          }
09126          break;
09127 /* Redirecting-to party id name */
09128       case AST_REDIRECTING_TO_NAME:
09129          ast_free(redirecting->to.name.str);
09130          redirecting->to.name.str = ast_malloc(ie_len + 1);
09131          if (redirecting->to.name.str) {
09132             memcpy(redirecting->to.name.str, data + pos, ie_len);
09133             redirecting->to.name.str[ie_len] = 0;
09134          }
09135          break;
09136       case AST_REDIRECTING_TO_NAME_CHAR_SET:
09137          if (ie_len != 1) {
09138             ast_log(LOG_WARNING, "Invalid redirecting-to name char set (%u)\n",
09139                (unsigned) ie_len);
09140             break;
09141          }
09142          redirecting->to.name.char_set = data[pos];
09143          break;
09144       case AST_REDIRECTING_TO_NAME_PRESENTATION:
09145          if (ie_len != 1) {
09146             ast_log(LOG_WARNING, "Invalid redirecting-to name presentation (%u)\n",
09147                (unsigned) ie_len);
09148             break;
09149          }
09150          redirecting->to.name.presentation = data[pos];
09151          break;
09152       case AST_REDIRECTING_TO_NAME_VALID:
09153          if (ie_len != 1) {
09154             ast_log(LOG_WARNING, "Invalid redirecting-to name valid (%u)\n",
09155                (unsigned) ie_len);
09156             break;
09157          }
09158          redirecting->to.name.valid = data[pos];
09159          break;
09160 /* Redirecting-to party id number */
09161       case AST_REDIRECTING_TO_NUMBER:
09162          ast_free(redirecting->to.number.str);
09163          redirecting->to.number.str = ast_malloc(ie_len + 1);
09164          if (redirecting->to.number.str) {
09165             memcpy(redirecting->to.number.str, data + pos, ie_len);
09166             redirecting->to.number.str[ie_len] = 0;
09167          }
09168          break;
09169       case AST_REDIRECTING_TO_NUMBER_PLAN:
09170          if (ie_len != 1) {
09171             ast_log(LOG_WARNING, "Invalid redirecting-to numbering plan (%u)\n",
09172                (unsigned) ie_len);
09173             break;
09174          }
09175          redirecting->to.number.plan = data[pos];
09176          break;
09177       case AST_REDIRECTING_TO_NUMBER_PRESENTATION:
09178          if (ie_len != 1) {
09179             ast_log(LOG_WARNING, "Invalid redirecting-to number presentation (%u)\n",
09180                (unsigned) ie_len);
09181             break;
09182          }
09183          redirecting->to.number.presentation = data[pos];
09184          break;
09185       case AST_REDIRECTING_TO_NUMBER_VALID:
09186          if (ie_len != 1) {
09187             ast_log(LOG_WARNING, "Invalid redirecting-to number valid (%u)\n",
09188                (unsigned) ie_len);
09189             break;
09190          }
09191          redirecting->to.number.valid = data[pos];
09192          break;
09193 /* Redirecting-to party id combined presentation */
09194       case AST_REDIRECTING_TO_ID_PRESENTATION:
09195          if (ie_len != 1) {
09196             ast_log(LOG_WARNING, "Invalid redirecting-to combined presentation (%u)\n",
09197                (unsigned) ie_len);
09198             break;
09199          }
09200          to_combined_presentation = data[pos];
09201          got_to_combined_presentation = 1;
09202          break;
09203 /* Redirecting-to party id subaddress */
09204       case AST_REDIRECTING_TO_SUBADDRESS:
09205          ast_free(redirecting->to.subaddress.str);
09206          redirecting->to.subaddress.str = ast_malloc(ie_len + 1);
09207          if (redirecting->to.subaddress.str) {
09208             memcpy(redirecting->to.subaddress.str, data + pos, ie_len);
09209             redirecting->to.subaddress.str[ie_len] = 0;
09210          }
09211          break;
09212       case AST_REDIRECTING_TO_SUBADDRESS_TYPE:
09213          if (ie_len != 1) {
09214             ast_log(LOG_WARNING, "Invalid redirecting-to type of subaddress (%u)\n",
09215                (unsigned) ie_len);
09216             break;
09217          }
09218          redirecting->to.subaddress.type = data[pos];
09219          break;
09220       case AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN:
09221          if (ie_len != 1) {
09222             ast_log(LOG_WARNING,
09223                "Invalid redirecting-to subaddress odd-even indicator (%u)\n",
09224                (unsigned) ie_len);
09225             break;
09226          }
09227          redirecting->to.subaddress.odd_even_indicator = data[pos];
09228          break;
09229       case AST_REDIRECTING_TO_SUBADDRESS_VALID:
09230          if (ie_len != 1) {
09231             ast_log(LOG_WARNING, "Invalid redirecting-to subaddress valid (%u)\n",
09232                (unsigned) ie_len);
09233             break;
09234          }
09235          redirecting->to.subaddress.valid = data[pos];
09236          break;
09237 /* Redirecting-to party id tag */
09238       case AST_REDIRECTING_TO_TAG:
09239          ast_free(redirecting->to.tag);
09240          redirecting->to.tag = ast_malloc(ie_len + 1);
09241          if (redirecting->to.tag) {
09242             memcpy(redirecting->to.tag, data + pos, ie_len);
09243             redirecting->to.tag[ie_len] = 0;
09244          }
09245          break;
09246 /* Redirecting reason */
09247       case AST_REDIRECTING_REASON:
09248          if (ie_len != sizeof(value)) {
09249             ast_log(LOG_WARNING, "Invalid redirecting reason (%u)\n",
09250                (unsigned) ie_len);
09251             break;
09252          }
09253          memcpy(&value, data + pos, sizeof(value));
09254          redirecting->reason = ntohl(value);
09255          break;
09256 /* Redirecting count */
09257       case AST_REDIRECTING_COUNT:
09258          if (ie_len != sizeof(value)) {
09259             ast_log(LOG_WARNING, "Invalid redirecting count (%u)\n",
09260                (unsigned) ie_len);
09261             break;
09262          }
09263          memcpy(&value, data + pos, sizeof(value));
09264          redirecting->count = ntohl(value);
09265          break;
09266 /* Redirecting unknown element */
09267       default:
09268          ast_debug(1, "Unknown redirecting element: %u (%u)\n",
09269             (unsigned) ie_id, (unsigned) ie_len);
09270          break;
09271       }
09272    }
09273 
09274    switch (frame_version) {
09275    case 1:
09276       /*
09277        * The other end is an earlier version that we need to adjust
09278        * for compatibility.
09279        */
09280       redirecting->from.name.valid = 1;
09281       redirecting->from.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
09282       redirecting->from.number.valid = 1;
09283       if (got_from_combined_presentation) {
09284          redirecting->from.name.presentation = from_combined_presentation;
09285          redirecting->from.number.presentation = from_combined_presentation;
09286       }
09287 
09288       redirecting->to.name.valid = 1;
09289       redirecting->to.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
09290       redirecting->to.number.valid = 1;
09291       if (got_to_combined_presentation) {
09292          redirecting->to.name.presentation = to_combined_presentation;
09293          redirecting->to.number.presentation = to_combined_presentation;
09294       }
09295       break;
09296    case 2:
09297       /* The other end is at the same level as we are. */
09298       break;
09299    default:
09300       /*
09301        * The other end is newer than we are.
09302        * We need to assume that they are compatible with us.
09303        */
09304       ast_debug(1, "Redirecting frame has newer version: %u\n",
09305          (unsigned) frame_version);
09306       break;
09307    }
09308 
09309    return 0;
09310 }

struct ast_channel* ast_request ( const char *  type,
struct ast_format_cap request_cap,
const struct ast_channel requestor,
const char *  addr,
int *  cause 
) [read]

Requests a channel.

Parameters:
type type of channel to request
request_cap Format capabilities for requested channel
requestor channel asking for data
addr destination of the call
cause Cause of failure
Request a channel of a given type, with addr as optional information used by the low level module

Return values:
NULL failure
non-NULL channel on success

Definition at line 5529 of file channel.c.

References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_NOSUCHDRIVER, AST_CAUSE_NOTDEFINED, ast_channel_release(), ast_format_cap_add(), ast_format_cap_destroy(), ast_format_cap_dup(), ast_format_cap_get_type(), ast_format_cap_remove_bytype(), ast_format_clear(), AST_FORMAT_TYPE_AUDIO, ast_getformatname_multiple(), ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_translator_best_choice(), ast_channel_tech::capabilities, LOG_WARNING, ast_channel_tech::requester, set_security_requirements(), chanlist::tech, and ast_channel_tech::type.

Referenced by __ast_request_and_dial(), alloc_playback_chan(), ast_call_forward(), attempt_reconnect(), begin_dial_channel(), build_conf(), chanavail_exec(), conf_run(), conf_start_record(), connect_link(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), ring_entry(), rpt(), rpt_call(), rpt_exec(), rpt_tele_thread(), and wait_for_answer().

05530 {
05531    struct chanlist *chan;
05532    struct ast_channel *c;
05533    int res;
05534    int foo;
05535 
05536    if (!cause)
05537       cause = &foo;
05538    *cause = AST_CAUSE_NOTDEFINED;
05539 
05540    if (AST_RWLIST_RDLOCK(&backends)) {
05541       ast_log(LOG_WARNING, "Unable to lock technology backend list\n");
05542       return NULL;
05543    }
05544 
05545    AST_RWLIST_TRAVERSE(&backends, chan, list) {
05546       struct ast_format_cap *tmp_cap;
05547       struct ast_format tmp_fmt;
05548       struct ast_format best_audio_fmt;
05549       struct ast_format_cap *joint_cap;
05550 
05551       if (strcasecmp(type, chan->tech->type))
05552          continue;
05553 
05554       ast_format_clear(&best_audio_fmt);
05555       /* find the best audio format to use */
05556       if ((tmp_cap = ast_format_cap_get_type(request_cap, AST_FORMAT_TYPE_AUDIO))) {
05557          /* We have audio - is it possible to connect the various calls to each other? 
05558             (Avoid this check for calls without audio, like text+video calls)
05559          */
05560          res = ast_translator_best_choice(tmp_cap, chan->tech->capabilities, &tmp_fmt, &best_audio_fmt);
05561          ast_format_cap_destroy(tmp_cap);
05562          if (res < 0) {
05563             char tmp1[256], tmp2[256];
05564             ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %s) to %s\n", type,
05565                ast_getformatname_multiple(tmp1, sizeof(tmp1), chan->tech->capabilities),
05566                ast_getformatname_multiple(tmp2, sizeof(tmp2), request_cap));
05567             *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05568             AST_RWLIST_UNLOCK(&backends);
05569             return NULL;
05570          }
05571       }
05572       AST_RWLIST_UNLOCK(&backends);
05573       if (!chan->tech->requester)
05574          return NULL;
05575 
05576       /* XXX Only the audio format calculated as being the best for translation
05577        * purposes is used for the request. This needs to be re-evaluated.  It may be
05578        * a better choice to send all the audio formats capable of being translated
05579        * during the request and allow the channel drivers to pick the best one. */
05580       if (!(joint_cap = ast_format_cap_dup(request_cap))) {
05581          return NULL;
05582       }
05583       ast_format_cap_remove_bytype(joint_cap, AST_FORMAT_TYPE_AUDIO);
05584       ast_format_cap_add(joint_cap, &best_audio_fmt);
05585 
05586       if (!(c = chan->tech->requester(type, joint_cap, requestor, addr, cause))) {
05587          ast_format_cap_destroy(joint_cap);
05588          return NULL;
05589       }
05590       joint_cap = ast_format_cap_destroy(joint_cap);
05591 
05592       if (set_security_requirements(requestor, c)) {
05593          ast_log(LOG_WARNING, "Setting security requirements failed\n");
05594          c = ast_channel_release(c);
05595          *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05596          return NULL;
05597       }
05598 
05599       /* no need to generate a Newchannel event here; it is done in the channel_alloc call */
05600       return c;
05601    }
05602 
05603    ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
05604    *cause = AST_CAUSE_NOSUCHDRIVER;
05605    AST_RWLIST_UNLOCK(&backends);
05606 
05607    return NULL;
05608 }

struct ast_channel* ast_request_and_dial ( const char *  type,
struct ast_format_cap cap,
const struct ast_channel requestor,
const char *  addr,
int  timeout,
int *  reason,
const char *  cid_num,
const char *  cid_name 
) [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
format capabilities for requested channel
requestor channel asking for 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)
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 5484 of file channel.c.

References __ast_request_and_dial().

Referenced by ast_pbx_outgoing_exten(), and generic_recall().

05485 {
05486    return __ast_request_and_dial(type, cap, requestor, addr, timeout, outstate, cidnum, cidname, NULL);
05487 }

int ast_safe_sleep ( struct ast_channel chan,
int  ms 
)

int ast_safe_sleep_conditional ( struct ast_channel chan,
int  ms,
int(*)(void *)  cond,
void *  data 
)

Wait, look for hangups and condition arg.

Wait for a specified amount of time, looking for hangups and a condition argument.

Definition at line 1630 of file channel.c.

References ast_channel_lock, ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_channel_unlock, ast_frfree, ast_frisolate(), ast_is_deferrable_frame(), AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_HEAD_NOLOCK, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_HEAD, ast_opt_transmit_silence, ast_queue_frame_head(), ast_read(), ast_waitfor(), cond, and ast_channel::generatordata.

Referenced by ast_safe_sleep(), and login_exec().

01631 {
01632    struct ast_frame *f;
01633    struct ast_silence_generator *silgen = NULL;
01634    int res = 0;
01635    AST_LIST_HEAD_NOLOCK(, ast_frame) deferred_frames;
01636 
01637    AST_LIST_HEAD_INIT_NOLOCK(&deferred_frames);
01638 
01639    /* If no other generator is present, start silencegen while waiting */
01640    if (ast_opt_transmit_silence && !chan->generatordata) {
01641       silgen = ast_channel_start_silence_generator(chan);
01642    }
01643 
01644    while (ms > 0) {
01645       struct ast_frame *dup_f = NULL;
01646       if (cond && ((*cond)(data) == 0)) {
01647          break;
01648       }
01649       ms = ast_waitfor(chan, ms);
01650       if (ms < 0) {
01651          res = -1;
01652          break;
01653       }
01654       if (ms > 0) {
01655          f = ast_read(chan);
01656          if (!f) {
01657             res = -1;
01658             break;
01659          }
01660 
01661          if (!ast_is_deferrable_frame(f)) {
01662             ast_frfree(f);
01663             continue;
01664          }
01665          
01666          if ((dup_f = ast_frisolate(f))) {
01667             if (dup_f != f) {
01668                ast_frfree(f);
01669             }
01670             AST_LIST_INSERT_HEAD(&deferred_frames, dup_f, frame_list);
01671          }
01672       }
01673    }
01674 
01675    /* stop silgen if present */
01676    if (silgen) {
01677       ast_channel_stop_silence_generator(chan, silgen);
01678    }
01679 
01680    /* We need to free all the deferred frames, but we only need to
01681     * queue the deferred frames if there was no error and no
01682     * hangup was received
01683     */
01684    ast_channel_lock(chan);
01685    while ((f = AST_LIST_REMOVE_HEAD(&deferred_frames, frame_list))) {
01686       if (!res) {
01687          ast_queue_frame_head(chan, f);
01688       }
01689       ast_frfree(f);
01690    }
01691    ast_channel_unlock(chan);
01692 
01693    return res;
01694 }

int ast_say_character_str ( struct ast_channel chan,
const char *  str,
const char *  ints,
const char *  lang 
)

function to pronounce character and phonetic strings

Definition at line 8141 of file channel.c.

References ast_say_character_str_full.

Referenced by common_exec(), pbx_builtin_saycharacters(), play_mailbox_owner(), rpt_tele_thread(), saycharstr(), saynode(), and vmsayname_exec().

08143 {
08144    return ast_say_character_str_full(chan, str, ints, lang, -1, -1);
08145 }

int ast_say_digit_str ( struct ast_channel chan,
const char *  num,
const char *  ints,
const char *  lang 
)

says digits of a string

Parameters:
chan channel to act upon
num string to speak
ints which dtmf to interrupt on
lang language to speak in
Vocally says the digits of a given string
Return values:
0 on succes
DTMF if interrupted
-1 on failure

Definition at line 8135 of file channel.c.

References ast_say_digit_str_full.

Referenced by __analog_ss_thread(), forward_message(), invent_message(), mgcp_ss(), pbx_builtin_saydigits(), and play_message_callerid().

08137 {
08138    return ast_say_digit_str_full(chan, str, ints, lang, -1, -1);
08139 }

int ast_say_digits ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  lang 
)

says digits

Parameters:
chan channel to act upon
num number to speak
ints which dtmf to interrupt on
lang language to speak
Vocally says digits of a given number
Return values:
0 on success
DTMF if interrupted
-1 on failure

Definition at line 8129 of file channel.c.

References ast_say_digits_full().

Referenced by common_exec(), conf_exec(), conf_run(), park_call_full(), parkandannounce_exec(), and rpt_tele_thread().

08131 {
08132    return ast_say_digits_full(chan, num, ints, lang, -1, -1);
08133 }

int ast_say_digits_full ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  lang,
int  audiofd,
int  ctrlfd 
)

int ast_say_enumeration ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  lang,
const char *  options 
)

says an enumeration

Parameters:
chan channel to say them enumeration on
num number to say on the channel
ints which dtmf to interrupt on
lang language to speak the enumeration
options set to 'f' for female, 'm' for male, 'c' for commune, 'n' for neuter, 'p' for plural
Vocally says an enumeration on a given channel (first, sencond, third, forth, thirtyfirst, hundredth, ....) Especially useful for dates and messages. Says 'last' if num equals to INT_MAX
Return values:
0 on success
DTMF digit on interrupt
-1 on failure

Definition at line 8123 of file channel.c.

References ast_say_enumeration_full.

Referenced by ast_say_date_da(), ast_say_date_de(), ast_say_date_with_format_da(), ast_say_date_with_format_de(), ast_say_date_with_format_en(), ast_say_date_with_format_pl(), and ast_say_date_with_format_vi().

08125 {
08126    return ast_say_enumeration_full(chan, num, ints, language, options, -1, -1);
08127 }

int ast_say_number ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  lang,
const char *  options 
)

says a number

Parameters:
chan channel to say them number on
num number to say on the channel
ints which dtmf to interrupt on
lang language to speak the number
options set to 'f' for female, 'm' for male, 'c' for commune, 'n' for neuter, 'p' for plural
Vocally says a number on a given channel
Return values:
0 on success
DTMF digit on interrupt
-1 on failure

Definition at line 8117 of file channel.c.

References ast_say_number_full.

Referenced by announce_user_count(), ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_fr(), ast_say_date_gr(), ast_say_date_he(), ast_say_date_hu(), ast_say_date_ka(), ast_say_date_nl(), ast_say_date_pt(), ast_say_date_th(), ast_say_date_with_format_da(), ast_say_date_with_format_de(), ast_say_date_with_format_en(), ast_say_date_with_format_es(), ast_say_date_with_format_fr(), ast_say_date_with_format_it(), ast_say_date_with_format_nl(), ast_say_date_with_format_pl(), ast_say_date_with_format_pt(), ast_say_date_with_format_th(), ast_say_date_with_format_vi(), ast_say_datetime_en(), ast_say_datetime_fr(), ast_say_datetime_from_now_en(), ast_say_datetime_from_now_fr(), ast_say_datetime_from_now_he(), ast_say_datetime_from_now_ka(), ast_say_datetime_from_now_pt(), ast_say_datetime_he(), ast_say_datetime_pt(), ast_say_datetime_th(), ast_say_datetime_zh(), ast_say_time_de(), ast_say_time_en(), ast_say_time_fr(), ast_say_time_gr(), ast_say_time_hu(), ast_say_time_ka(), ast_say_time_nl(), ast_say_time_pt(), ast_say_time_pt_BR(), ast_say_time_th(), ast_say_time_zh(), bridge_playfile(), conf_run(), count_exec(), dictate_exec(), get_folder(), gr_say_number_female(), pbx_builtin_saynumber(), play_message(), play_message_duration(), play_sound_helper(), rpt_tele_thread(), say_and_wait(), say_position(), saynum(), try_calling(), vm_intro_gr(), vm_intro_he(), vm_intro_multilang(), vm_intro_pt(), and vm_intro_pt_BR().

08119 {
08120    return ast_say_number_full(chan, num, ints, language, options, -1, -1);
08121 }

int ast_say_phonetic_str ( struct ast_channel chan,
const char *  str,
const char *  ints,
const char *  lang 
)

Definition at line 8147 of file channel.c.

References ast_say_phonetic_str_full.

Referenced by pbx_builtin_sayphonetic().

08149 {
08150    return ast_say_phonetic_str_full(chan, str, ints, lang, -1, -1);
08151 }

int ast_senddigit ( struct ast_channel chan,
char  digit,
unsigned int  duration 
)

Send a DTMF digit to a channel.

Parameters:
chan channel to act upon
digit the DTMF digit to send, encoded in ASCII
duration the duration of the digit ending in ms
Returns:
0 on success, -1 on failure

Definition at line 4502 of file channel.c.

References AST_DEFAULT_EMULATE_DTMF_DURATION, ast_safe_sleep(), ast_senddigit_begin(), ast_senddigit_end(), ast_channel_tech::send_digit_begin, and ast_channel::tech.

Referenced by ast_dtmf_stream(), dial_exec_full(), do_dtmf_phone(), manager_play_dtmf(), and rpt_call().

04503 {
04504    if (chan->tech->send_digit_begin) {
04505       ast_senddigit_begin(chan, digit);
04506       ast_safe_sleep(chan, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION));
04507    }
04508 
04509    return ast_senddigit_end(chan, digit, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION));
04510 }

int ast_senddigit_begin ( struct ast_channel chan,
char  digit 
)

Send a DTMF digit to a channel.

Parameters:
chan channel to act upon
digit the DTMF digit to send, encoded in ASCII
Returns:
0 on success, -1 on failure

Definition at line 4444 of file channel.c.

References ast_channel_name(), ast_debug, ast_playtones_start(), ast_channel_tech::send_digit_begin, and ast_channel::tech.

Referenced by agent_digit_begin(), ast_senddigit(), and ast_write().

04445 {
04446    /* Device does not support DTMF tones, lets fake
04447     * it by doing our own generation. */
04448    static const char * const dtmf_tones[] = {
04449       "941+1336", /* 0 */
04450       "697+1209", /* 1 */
04451       "697+1336", /* 2 */
04452       "697+1477", /* 3 */
04453       "770+1209", /* 4 */
04454       "770+1336", /* 5 */
04455       "770+1477", /* 6 */
04456       "852+1209", /* 7 */
04457       "852+1336", /* 8 */
04458       "852+1477", /* 9 */
04459       "697+1633", /* A */
04460       "770+1633", /* B */
04461       "852+1633", /* C */
04462       "941+1633", /* D */
04463       "941+1209", /* * */
04464       "941+1477"  /* # */
04465    };
04466 
04467    if (!chan->tech->send_digit_begin)
04468       return 0;
04469 
04470    if (!chan->tech->send_digit_begin(chan, digit))
04471       return 0;
04472 
04473    if (digit >= '0' && digit <='9')
04474       ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0);
04475    else if (digit >= 'A' && digit <= 'D')
04476       ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0);
04477    else if (digit == '*')
04478       ast_playtones_start(chan, 0, dtmf_tones[14], 0);
04479    else if (digit == '#')
04480       ast_playtones_start(chan, 0, dtmf_tones[15], 0);
04481    else {
04482       /* not handled */
04483       ast_debug(1, "Unable to generate DTMF tone '%c' for '%s'\n", digit, ast_channel_name(chan));
04484    }
04485 
04486    return 0;
04487 }

int ast_senddigit_end ( struct ast_channel chan,
char  digit,
unsigned int  duration 
)

Send a DTMF digit to a channel.

Parameters:
chan channel to act upon
digit the DTMF digit to send, encoded in ASCII
duration the duration of the digit ending in ms
Returns:
Returns 0 on success, -1 on failure

Definition at line 4489 of file channel.c.

References ast_playtones_stop(), ast_channel::generator, ast_channel_tech::send_digit_end, and ast_channel::tech.

Referenced by agent_digit_end(), ast_senddigit(), and ast_write().

04490 {
04491    int res = -1;
04492 
04493    if (chan->tech->send_digit_end)
04494       res = chan->tech->send_digit_end(chan, digit, duration);
04495 
04496    if (res && chan->generator)
04497       ast_playtones_stop(chan);
04498 
04499    return 0;
04500 }

int ast_sendtext ( struct ast_channel chan,
const char *  text 
)

Sends text to a channel.

Parameters:
chan channel to act upon
text string of text to send on the channel
Write text to a display on a channel

Note:
The channel does not need to be locked before calling this function.
Return values:
0 on success
-1 on failure

Definition at line 4406 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_format_cap_has_type(), ast_format_set(), AST_FORMAT_T140, AST_FORMAT_TYPE_TEXT, AST_FRAME_TEXT, AST_MALLOCD_DATA, ast_strdup, ast_strlen_zero(), ast_test_flag, CHECK_BLOCKING, ast_frame::data, ast_frame::datalen, ast_frame_subclass::format, ast_frame::frametype, ast_frame::mallocd, ast_channel::nativeformats, ast_frame::offset, ast_frame::ptr, ast_channel_tech::send_text, ast_frame::seqno, ast_frame::src, ast_frame::subclass, ast_channel::tech, and ast_channel_tech::write_text.

Referenced by action_sendtext(), agent_sendtext(), handle_sendtext(), send_newkey(), and sendtext_exec().

04407 {
04408    int res = 0;
04409 
04410    ast_channel_lock(chan);
04411    /* Stop if we're a zombie or need a soft hangup */
04412    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
04413       ast_channel_unlock(chan);
04414       return -1;
04415    }
04416 
04417    if (ast_strlen_zero(text)) {
04418       ast_channel_unlock(chan);
04419       return 0;
04420    }
04421 
04422    CHECK_BLOCKING(chan);
04423    if (chan->tech->write_text && (ast_format_cap_has_type(chan->nativeformats, AST_FORMAT_TYPE_TEXT))) {
04424       struct ast_frame f;
04425 
04426       f.frametype = AST_FRAME_TEXT;
04427       f.src = "DIALPLAN";
04428       f.mallocd = AST_MALLOCD_DATA;
04429       f.datalen = strlen(text);
04430       f.data.ptr = ast_strdup(text);
04431       f.offset = 0;
04432       f.seqno = 0;
04433 
04434       ast_format_set(&f.subclass.format, AST_FORMAT_T140, 0);
04435       res = chan->tech->write_text(chan, &f);
04436    } else if (chan->tech->send_text) {
04437       res = chan->tech->send_text(chan, text);
04438    }
04439    ast_clear_flag(chan, AST_FLAG_BLOCKING);
04440    ast_channel_unlock(chan);
04441    return res;
04442 }

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.

Note:
Use ast_channel_set_caller() and ast_channel_set_caller_event() instead.

The channel does not need to be locked before calling this function.

Definition at line 6823 of file channel.c.

References ast_party_caller::ani, ast_cdr_setcid(), ast_channel_lock, ast_channel_unlock, ast_free, ast_strdup, ast_channel::caller, ast_channel::cdr, ast_party_caller::id, ast_party_id::name, ast_party_id::number, report_new_callerid(), ast_party_name::str, ast_party_number::str, ast_party_name::valid, and ast_party_number::valid.

Referenced by __analog_ss_thread(), analog_ss_thread(), cb_events(), disa_exec(), get_pai(), get_rpid(), handle_setcallerid(), mgcp_ss(), privacy_exec(), ring_entry(), rpt_exec(), skinny_newcall(), and socket_process().

06824 {
06825    ast_channel_lock(chan);
06826 
06827    if (cid_num) {
06828       chan->caller.id.number.valid = 1;
06829       ast_free(chan->caller.id.number.str);
06830       chan->caller.id.number.str = ast_strdup(cid_num);
06831    }
06832    if (cid_name) {
06833       chan->caller.id.name.valid = 1;
06834       ast_free(chan->caller.id.name.str);
06835       chan->caller.id.name.str = ast_strdup(cid_name);
06836    }
06837    if (cid_ani) {
06838       chan->caller.ani.number.valid = 1;
06839       ast_free(chan->caller.ani.number.str);
06840       chan->caller.ani.number.str = ast_strdup(cid_ani);
06841    }
06842    if (chan->cdr) {
06843       ast_cdr_setcid(chan->cdr, chan);
06844    }
06845 
06846    report_new_callerid(chan);
06847 
06848    ast_channel_unlock(chan);
06849 }

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.

Parameters:
chan channel to set the field on
source a string describing the source of the hangup for this channel
force 
Since:
1.8
Hangupsource is generally the channel name that caused the bridge to be hung up, but it can also be other things such as "dialplan/agi" This can then be logged in the CDR or CEL

Definition at line 2555 of file channel.c.

References ast_bridged_channel(), ast_channel_hangupsource(), ast_channel_lock, ast_channel_unlock, ast_strlen_zero(), and ast_channel::bridge.

Referenced by __dahdi_exception(), func_channel_write_real(), handle_hangup(), handle_request_bye(), handle_request_cancel(), handle_response_invite(), pbx_builtin_hangup(), and set_hangup_source_and_cause().

02556 {
02557    struct ast_channel *bridge;
02558 
02559    ast_channel_lock(chan);
02560    if (force || ast_strlen_zero(ast_channel_hangupsource(chan))) {
02561       ast_channel_hangupsource_set(chan, source);
02562    }
02563    bridge = ast_bridged_channel(chan);
02564    ast_channel_unlock(chan);
02565 
02566    if (bridge && (force || ast_strlen_zero(ast_channel_hangupsource(bridge)))) {
02567       ast_channel_lock(bridge);
02568       ast_channel_hangupsource_set(chan, source);
02569       ast_channel_unlock(bridge);
02570    }
02571 }

static void ast_set_owners_and_peers ( struct ast_channel chan1,
struct ast_channel chan2 
) [static]

Definition at line 6283 of file channel.c.

References ast_channel_accountcode(), ast_channel_name(), ast_channel_peeraccount(), ast_debug, and ast_strlen_zero().

Referenced by ast_channel_bridge().

06285 {
06286    if (!ast_strlen_zero(ast_channel_accountcode(chan1)) && ast_strlen_zero(ast_channel_peeraccount(chan2))) {
06287       ast_debug(1, "setting peeraccount to %s for %s from data on channel %s\n",
06288             ast_channel_accountcode(chan1), ast_channel_name(chan2), ast_channel_name(chan1));
06289       ast_channel_peeraccount_set(chan2, ast_channel_accountcode(chan1));
06290    }
06291    if (!ast_strlen_zero(ast_channel_accountcode(chan2)) && ast_strlen_zero(ast_channel_peeraccount(chan1))) {
06292       ast_debug(1, "setting peeraccount to %s for %s from data on channel %s\n",
06293             ast_channel_accountcode(chan2), ast_channel_name(chan1), ast_channel_name(chan2));
06294       ast_channel_peeraccount_set(chan1, ast_channel_accountcode(chan2));
06295    }
06296    if (!ast_strlen_zero(ast_channel_peeraccount(chan1)) && ast_strlen_zero(ast_channel_accountcode(chan2))) {
06297       ast_debug(1, "setting accountcode to %s for %s from data on channel %s\n",
06298             ast_channel_peeraccount(chan1), ast_channel_name(chan2), ast_channel_name(chan1));
06299       ast_channel_accountcode_set(chan2, ast_channel_peeraccount(chan1));
06300    }
06301    if (!ast_strlen_zero(ast_channel_peeraccount(chan2)) && ast_strlen_zero(ast_channel_accountcode(chan1))) {
06302       ast_debug(1, "setting accountcode to %s for %s from data on channel %s\n",
06303             ast_channel_peeraccount(chan2), ast_channel_name(chan1), ast_channel_name(chan2));
06304       ast_channel_accountcode_set(chan1, ast_channel_peeraccount(chan2));
06305    }
06306    if (0 != strcmp(ast_channel_accountcode(chan1), ast_channel_peeraccount(chan2))) {
06307       ast_debug(1, "changing peeraccount from %s to %s on %s to match channel %s\n",
06308             ast_channel_peeraccount(chan2), ast_channel_peeraccount(chan1), ast_channel_name(chan2), ast_channel_name(chan1));
06309       ast_channel_peeraccount_set(chan2, ast_channel_accountcode(chan1));
06310    }
06311    if (0 != strcmp(ast_channel_accountcode(chan2), ast_channel_peeraccount(chan1))) {
06312       ast_debug(1, "changing peeraccount from %s to %s on %s to match channel %s\n",
06313             ast_channel_peeraccount(chan1), ast_channel_peeraccount(chan2), ast_channel_name(chan1), ast_channel_name(chan2));
06314       ast_channel_peeraccount_set(chan1, ast_channel_accountcode(chan2));
06315    }
06316 }

int ast_set_read_format ( struct ast_channel chan,
struct ast_format format 
)

int ast_set_read_format_by_id ( struct ast_channel chan,
enum ast_format_id  id 
)

Sets read format on channel chan by id.

Parameters:
chan channel to change
format id to set for reading, only used for formats without attributes
Returns:
Returns 0 on success, -1 on failure

Definition at line 5076 of file channel.c.

References ast_format_cap_add(), ast_format_cap_alloc_nolock(), ast_format_cap_destroy(), ast_format_set(), ast_channel::rawreadformat, ast_channel::readformat, ast_channel::readtrans, and set_format().

Referenced by __ast_play_and_record(), alarmreceiver_exec(), ast_adsi_transmit_message_full(), attempt_reconnect(), background_detect_exec(), build_conf(), conf_run(), connect_link(), dictate_exec(), do_waiting(), eagi_exec(), fax_detect_framehook(), fax_gateway_framehook(), generic_fax_exec(), handle_recordfile(), handle_speechrecognize(), ices_exec(), isAnsweringMachine(), jack_exec(), measurenoise(), old_milliwatt_exec(), record_exec(), rpt(), rpt_exec(), and transmit_audio().

05077 {
05078    struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
05079    struct ast_format tmp_format;
05080    int res;
05081    if (!cap) {
05082       return -1;
05083    }
05084    ast_format_cap_add(cap, ast_format_set(&tmp_format, id, 0));
05085 
05086    res = set_format(chan,
05087       cap,
05088       &chan->rawreadformat,
05089       &chan->readformat,
05090       &chan->readtrans,
05091       0);
05092 
05093    ast_format_cap_destroy(cap);
05094    return res;
05095 }

int ast_set_read_format_from_cap ( struct ast_channel chan,
struct ast_format_cap formats 
)

Sets read format on channel chan from capabilities Set read format for channel to whichever component of "format" is best.

Parameters:
chan channel to change
formats new formats to pick from for reading
Returns:
Returns 0 on success, -1 on failure

Definition at line 5097 of file channel.c.

References ast_channel::rawreadformat, ast_channel::readformat, ast_channel::readtrans, and set_format().

Referenced by agent_call(), and login_exec().

05098 {
05099    return set_format(chan,
05100       cap,
05101       &chan->rawreadformat,
05102       &chan->readformat,
05103       &chan->readtrans,
05104       0);
05105 }

void ast_set_variables ( struct ast_channel chan,
struct ast_variable vars 
)

adds a list of channel variables to a channel

Parameters:
chan the channel
vars a linked list of variables
Variable names can be for a regular channel variable or a dialplan function that has the ability to be written to.

Definition at line 8004 of file channel.c.

References ast_variable::name, ast_variable::next, pbx_builtin_setvar_helper(), and ast_variable::value.

Referenced by __ast_request_and_dial(), ast_call_forward(), ast_pbx_outgoing_app(), and ast_pbx_outgoing_exten().

08005 {
08006    struct ast_variable *cur;
08007 
08008    for (cur = vars; cur; cur = cur->next)
08009       pbx_builtin_setvar_helper(chan, cur->name, cur->value);  
08010 }

int ast_set_write_format ( struct ast_channel chan,
struct ast_format format 
)

Sets write format on channel chan.

Parameters:
chan channel to change
formats,format to set for writing
Returns:
Returns 0 on success, -1 on failure

Definition at line 5107 of file channel.c.

References ast_format_cap_add(), ast_format_cap_alloc_nolock(), ast_format_cap_destroy(), ast_channel::rawwriteformat, set_format(), ast_channel::writeformat, and ast_channel::writetrans.

Referenced by __oh323_update_info(), ast_adsi_transmit_message_full(), ast_channel_make_compatible_helper(), ast_channel_stop_silence_generator(), ast_do_masquerade(), ast_stopstream(), bridge_channel_join(), bridge_make_compatible(), chanspy_exec(), dahdiscan_exec(), echo_exec(), extenspy_exec(), generic_fax_exec(), gtalk_rtp_read(), jingle_rtp_read(), linear_release(), mgcp_rtp_read(), moh_alloc(), moh_files_release(), moh_files_write_format_change(), moh_release(), mp3_exec(), NBScat_exec(), oh323_rtp_read(), playtones_release(), process_sdp(), send_waveform_to_channel(), set_softmix_bridge_data(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_process(), tonepair_release(), transmit_audio(), and unistim_rtp_read().

05108 {
05109    struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
05110    int res;
05111    if (!cap) {
05112       return -1;
05113    }
05114    ast_format_cap_add(cap, format);
05115 
05116    res = set_format(chan,
05117       cap,
05118       &chan->rawwriteformat,
05119       &chan->writeformat,
05120       &chan->writetrans,
05121       1);
05122 
05123    ast_format_cap_destroy(cap);
05124    return res;
05125 }

int ast_set_write_format_by_id ( struct ast_channel chan,
enum ast_format_id  id 
)

Sets write format on channel chan.

Parameters:
chan channel to change
format id to set for writing, only used for formats without attributes
Returns:
Returns 0 on success, -1 on failure

Definition at line 5127 of file channel.c.

References ast_format_cap_add(), ast_format_cap_alloc_nolock(), ast_format_cap_destroy(), ast_format_set(), ast_channel::rawwriteformat, set_format(), ast_channel::writeformat, and ast_channel::writetrans.

Referenced by alarmreceiver_exec(), ast_adsi_transmit_message_full(), ast_channel_start_silence_generator(), ast_write(), attempt_reconnect(), build_conf(), chanspy_exec(), conf_run(), connect_link(), dahdiscan_exec(), extenspy_exec(), fax_gateway_framehook(), generic_fax_exec(), jack_exec(), linear_alloc(), mp3_exec(), NBScat_exec(), old_milliwatt_exec(), playtones_alloc(), rpt(), rpt_exec(), send_waveform_to_channel(), tonepair_alloc(), and transmit_audio().

05128 {
05129    struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
05130    struct ast_format tmp_format;
05131    int res;
05132    if (!cap) {
05133       return -1;
05134    }
05135    ast_format_cap_add(cap, ast_format_set(&tmp_format, id, 0));
05136 
05137    res = set_format(chan,
05138       cap,
05139       &chan->rawwriteformat,
05140       &chan->writeformat,
05141       &chan->writetrans,
05142       1);
05143 
05144    ast_format_cap_destroy(cap);
05145    return res;
05146 }

int ast_set_write_format_from_cap ( struct ast_channel chan,
struct ast_format_cap formats 
)

Sets write format on channel chan Set write format for channel to whichever component of "format" is best.

Parameters:
chan channel to change
formats new formats to pick from for writing
Returns:
Returns 0 on success, -1 on failure

Definition at line 5148 of file channel.c.

References ast_channel::rawwriteformat, set_format(), ast_channel::writeformat, and ast_channel::writetrans.

Referenced by agent_call(), ast_openstream_full(), and login_exec().

05149 {
05150    return set_format(chan,
05151       cap,
05152       &chan->rawwriteformat,
05153       &chan->writeformat,
05154       &chan->writetrans,
05155       1);
05156 }

int ast_setstate ( struct ast_channel chan,
enum ast_channel_state  state 
)

Change the state of a channel.

Definition at line 6891 of file channel.c.

References ast_channel::_state, ast_channel_name(), AST_CHANNEL_NAME, ast_channel_uniqueid(), ast_copy_string(), AST_DEVICE_UNKNOWN, ast_devstate_changed_literal(), ast_manager_event, ast_state2str(), ast_channel::caller, ast_channel::connected, EVENT_FLAG_CALL, ast_party_connected_line::id, ast_party_caller::id, ast_party_id::name, name, ast_party_id::number, S_COR, ast_party_name::str, ast_party_number::str, ast_party_name::valid, and ast_party_number::valid.

Referenced by __analog_handle_event(), __analog_ss_thread(), __ast_read(), __dahdi_exception(), __oh323_update_info(), agent_call(), alsa_answer(), analog_answer(), analog_call(), analog_exception(), analog_ss_thread(), ast_raw_answer(), cb_events(), check_availability(), console_answer(), dahdi_answer(), dahdi_call(), dahdi_handle_event(), dahdi_indicate(), dahdi_read(), do_bridge_masquerade(), gtalk_call(), gtalk_newcall(), handle_invite_replaces(), handle_request_invite(), handle_response_invite(), iax2_call(), jingle_call(), jingle_newcall(), local_queue_frame(), mgcp_answer(), mgcp_call(), mgcp_ss(), misdn_call(), misdn_indication(), my_set_waitingfordt(), nbs_call(), nbs_hangup(), oh323_answer(), oss_answer(), pbx_builtin_busy(), pbx_builtin_congestion(), phone_answer(), phone_call(), phone_exception(), phone_hangup(), phone_write(), release_chan(), release_chan_early(), setsubstate(), sip_answer(), skinny_answer(), skinny_newcall(), unistim_answer(), unistim_call(), unistim_new(), unistim_ss(), update_state(), usbradio_answer(), and usbradio_call().

06892 {
06893    int oldstate = chan->_state;
06894    char name[AST_CHANNEL_NAME], *dashptr;
06895 
06896    if (oldstate == state)
06897       return 0;
06898 
06899    ast_copy_string(name, ast_channel_name(chan), sizeof(name));
06900    if ((dashptr = strrchr(name, '-'))) {
06901       *dashptr = '\0';
06902    }
06903 
06904    chan->_state = state;
06905 
06906    /* We have to pass AST_DEVICE_UNKNOWN here because it is entirely possible that the channel driver
06907     * for this channel is using the callback method for device state. If we pass in an actual state here
06908     * we override what they are saying the state is and things go amuck. */
06909    ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, name);
06910 
06911    /* setstate used to conditionally report Newchannel; this is no more */
06912    ast_manager_event(chan, EVENT_FLAG_CALL, "Newstate",
06913       "Channel: %s\r\n"
06914       "ChannelState: %d\r\n"
06915       "ChannelStateDesc: %s\r\n"
06916       "CallerIDNum: %s\r\n"
06917       "CallerIDName: %s\r\n"
06918       "ConnectedLineNum: %s\r\n"
06919       "ConnectedLineName: %s\r\n"
06920       "Uniqueid: %s\r\n",
06921       ast_channel_name(chan), chan->_state, ast_state2str(chan->_state),
06922       S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
06923       S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""),
06924       S_COR(chan->connected.id.number.valid, chan->connected.id.number.str, ""),
06925       S_COR(chan->connected.id.name.valid, chan->connected.id.name.str, ""),
06926       ast_channel_uniqueid(chan));
06927 
06928    return 0;
06929 }

int ast_settimeout ( struct ast_channel c,
unsigned int  rate,
int(*)(const void *data)  func,
void *  data 
)

Enable or disable timer ticks for a channel.

Parameters:
c channel
rate number of timer ticks per second
func callback function
data 
If timers are supported, force a scheduled expiration on the timer fd, at which point we call the callback function / data

Note:
Call this function with a rate of 0 to turn off the timer ticks
Version:
1.6.1 changed samples parameter to rate, accomodates new timing methods

Definition at line 3332 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_debug, ast_timer_get_max_rate(), ast_timer_set_rate(), ast_channel::timer, ast_channel::timingdata, ast_channel::timingfd, and ast_channel::timingfunc.

Referenced by ast_activate_generator(), ast_deactivate_generator(), ast_read_generator_actions(), ast_readaudio_callback(), and filestream_close().

03333 {
03334    int res;
03335    unsigned int real_rate = rate, max_rate;
03336 
03337    ast_channel_lock(c);
03338 
03339    if (c->timingfd == -1) {
03340       ast_channel_unlock(c);
03341       return -1;
03342    }
03343 
03344    if (!func) {
03345       rate = 0;
03346       data = NULL;
03347    }
03348 
03349    if (rate && rate > (max_rate = ast_timer_get_max_rate(c->timer))) {
03350       real_rate = max_rate;
03351    }
03352 
03353    ast_debug(1, "Scheduling timer at (%u requested / %u actual) timer ticks per second\n", rate, real_rate);
03354 
03355    res = ast_timer_set_rate(c->timer, real_rate);
03356 
03357    c->timingfunc = func;
03358    c->timingdata = data;
03359 
03360    ast_channel_unlock(c);
03361 
03362    return res;
03363 }

int ast_shutting_down ( void   ) 

Returns non-zero if Asterisk is being shut down.

Returns:
non-zero if Asterisk is being shut down

Definition at line 637 of file channel.c.

Referenced by confbridge_exec(), and handle_request_options().

00638 {
00639    return shutting_down;
00640 }

int ast_softhangup ( struct ast_channel chan,
int  cause 
)

int ast_softhangup_nolock ( struct ast_channel chan,
int  cause 
)

Softly hangup a channel, don't lock.

Softly hangup up a channel (no channel lock).

Definition at line 2505 of file channel.c.

References ast_channel::_softhangup, ast_channel_name(), ast_debug, AST_FLAG_BLOCKING, ast_null_frame, ast_queue_frame(), ast_test_flag, and ast_channel::blocker.

Referenced by __analog_handle_event(), action_hangup(), ast_async_goto(), ast_softhangup(), attempt_transfer(), check_pendings(), check_rtp_timeout(), dahdi_softhangup_all(), oh323_indicate(), proc_session_timer(), and sip_indicate().

02506 {
02507    ast_debug(1, "Soft-Hanging up channel '%s'\n", ast_channel_name(chan));
02508    /* Inform channel driver that we need to be hung up, if it cares */
02509    chan->_softhangup |= cause;
02510    ast_queue_frame(chan, &ast_null_frame);
02511    /* Interrupt any poll call or such */
02512    if (ast_test_flag(chan, AST_FLAG_BLOCKING))
02513       pthread_kill(chan->blocker, SIGURG);
02514    return 0;
02515 }

const char* ast_state2str ( enum ast_channel_state  state  ) 

Gives the string form of a given channel state.

Note:
This function is not reentrant.

Definition at line 779 of file channel.c.

References AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DIALING_OFFHOOK, AST_STATE_DOWN, AST_STATE_OFFHOOK, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_threadstorage_get(), STATE2STR_BUFSIZE, and state2str_threadbuf.

Referenced by __ast_channel_alloc_ap(), action_coreshowchannels(), action_status(), agent_hangup(), ast_channel_data_add_structure(), ast_do_masquerade(), ast_setstate(), attempt_transfer(), func_channel_read(), handle_chanlist(), handle_showchan(), local_attended_transfer(), mgcp_new(), serialize_showchan(), sip_hangup(), and update_connectedline().

00780 {
00781    char *buf;
00782 
00783    switch (state) {
00784    case AST_STATE_DOWN:
00785       return "Down";
00786    case AST_STATE_RESERVED:
00787       return "Rsrvd";
00788    case AST_STATE_OFFHOOK:
00789       return "OffHook";
00790    case AST_STATE_DIALING:
00791       return "Dialing";
00792    case AST_STATE_RING:
00793       return "Ring";
00794    case AST_STATE_RINGING:
00795       return "Ringing";
00796    case AST_STATE_UP:
00797       return "Up";
00798    case AST_STATE_BUSY:
00799       return "Busy";
00800    case AST_STATE_DIALING_OFFHOOK:
00801       return "Dialing Offhook";
00802    case AST_STATE_PRERING:
00803       return "Pre-ring";
00804    default:
00805       if (!(buf = ast_threadstorage_get(&state2str_threadbuf, STATE2STR_BUFSIZE)))
00806          return "Unknown";
00807       snprintf(buf, STATE2STR_BUFSIZE, "Unknown (%d)", state);
00808       return buf;
00809    }
00810 }

int ast_str2cause ( const char *  name  ) 

Convert a symbolic hangup cause to number.

Convert the string form of a cause code to a number.

Definition at line 765 of file channel.c.

References ARRAY_LEN, cause, and causes.

Referenced by pbx_builtin_hangup().

00766 {
00767    int x;
00768 
00769    for (x = 0; x < ARRAY_LEN(causes); x++)
00770       if (!strncasecmp(causes[x].name, name, strlen(causes[x].name)))
00771          return causes[x].cause;
00772 
00773    return -1;
00774 }

int ast_tonepair ( struct ast_channel chan,
int  freq1,
int  freq2,
int  duration,
int  vol 
)

Play a tone pair for a given amount of time

Definition at line 7724 of file channel.c.

References ast_frfree, ast_read(), ast_tonepair_start(), ast_waitfor(), and ast_channel::generatordata.

Referenced by zapateller_exec().

07725 {
07726    int res;
07727 
07728    if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
07729       return res;
07730 
07731    /* Give us some wiggle room */
07732    while (chan->generatordata && ast_waitfor(chan, 100) >= 0) {
07733       struct ast_frame *f = ast_read(chan);
07734       if (f)
07735          ast_frfree(f);
07736       else
07737          return -1;
07738    }
07739    return 0;
07740 }

int ast_tonepair_start ( struct ast_channel chan,
int  freq1,
int  freq2,
int  duration,
int  vol 
)

Start a tone going

Definition at line 7706 of file channel.c.

References ast_activate_generator(), tonepair_def::duration, tonepair_def::freq1, tonepair_def::freq2, and tonepair_def::vol.

Referenced by ast_tonepair(), pbx_builtin_waitexten(), play_dialtone(), play_tone_pair(), rpt_tele_thread(), and sendnoise().

07707 {
07708    struct tonepair_def d = { 0, };
07709 
07710    d.freq1 = freq1;
07711    d.freq2 = freq2;
07712    d.duration = duration;
07713    d.vol = (vol < 1) ? 8192 : vol; /* force invalid to 8192 */
07714    if (ast_activate_generator(chan, &tonepair, &d))
07715       return -1;
07716    return 0;
07717 }

void ast_tonepair_stop ( struct ast_channel chan  ) 

Stop a tone from playing

Definition at line 7719 of file channel.c.

References ast_deactivate_generator().

Referenced by sendnoise().

07720 {
07721    ast_deactivate_generator(chan);
07722 }

int ast_transfer ( struct ast_channel chan,
char *  dest 
)

Transfer a call to dest, if the channel supports transfer.

Transfer a channel (if supported).

Called by:

  • app_transfer
  • the manager interface

Definition at line 5637 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_CONTROL_TRANSFER, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, ast_frfree, ast_read(), ast_test_flag, AST_TRANSFER_SUCCESS, ast_waitfor(), ast_frame::data, ast_frame::frametype, ast_frame_subclass::integer, ast_frame::ptr, ast_frame::subclass, ast_channel::tech, and ast_channel_tech::transfer.

Referenced by transfer_exec().

05638 {
05639    int res = -1;
05640 
05641    /* Stop if we're a zombie or need a soft hangup */
05642    ast_channel_lock(chan);
05643    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
05644       if (chan->tech->transfer) {
05645          res = chan->tech->transfer(chan, dest);
05646          if (!res)
05647             res = 1;
05648       } else
05649          res = 0;
05650    }
05651    ast_channel_unlock(chan);
05652 
05653    if (res <= 0) {
05654       return res;
05655    }
05656 
05657    for (;;) {
05658       struct ast_frame *fr;
05659 
05660       res = ast_waitfor(chan, -1);
05661 
05662       if (res < 0 || !(fr = ast_read(chan))) {
05663          res = -1;
05664          break;
05665       }
05666 
05667       if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_TRANSFER) {
05668          enum ast_control_transfer *message = fr->data.ptr;
05669 
05670          if (*message == AST_TRANSFER_SUCCESS) {
05671             res = 1;
05672          } else {
05673             res = -1;
05674          }
05675 
05676          ast_frfree(fr);
05677          break;
05678       }
05679 
05680       ast_frfree(fr);
05681    }
05682 
05683    return res;
05684 }

char* ast_transfercapability2str ( int  transfercapability  )  const

Gives the string form of a given transfer capability.

Parameters:
transfercapability transfer capability to get the name of
Returns:
the text form of the binary transfer capability

Definition at line 813 of file channel.c.

References AST_TRANS_CAP_3_1K_AUDIO, AST_TRANS_CAP_DIGITAL, AST_TRANS_CAP_DIGITAL_W_TONES, AST_TRANS_CAP_RESTRICTED_DIGITAL, AST_TRANS_CAP_SPEECH, and AST_TRANS_CAP_VIDEO.

Referenced by ast_channel_data_add_structure(), cb_events(), misdn_call(), and oh323_call().

00814 {
00815    switch (transfercapability) {
00816    case AST_TRANS_CAP_SPEECH:
00817       return "SPEECH";
00818    case AST_TRANS_CAP_DIGITAL:
00819       return "DIGITAL";
00820    case AST_TRANS_CAP_RESTRICTED_DIGITAL:
00821       return "RESTRICTED_DIGITAL";
00822    case AST_TRANS_CAP_3_1K_AUDIO:
00823       return "3K1AUDIO";
00824    case AST_TRANS_CAP_DIGITAL_W_TONES:
00825       return "DIGITAL_W_TONES";
00826    case AST_TRANS_CAP_VIDEO:
00827       return "VIDEO";
00828    default:
00829       return "UNKNOWN";
00830    }
00831 }

void ast_uninstall_music_functions ( void   ) 

Definition at line 7787 of file channel.c.

References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.

Referenced by unload_module().

07788 {
07789    ast_moh_start_ptr = NULL;
07790    ast_moh_stop_ptr = NULL;
07791    ast_moh_cleanup_ptr = NULL;
07792 }

int ast_waitfor ( struct ast_channel chan,
int  ms 
)

Wait for input on a channel.

Parameters:
chan channel to wait on
ms length of time to wait on the channel
Wait for input on a channel for a given # of milliseconds (<0 for indefinite).
Return values:
< 0 on failure
0 if nothing ever arrived
the # of ms remaining otherwise

Definition at line 3316 of file channel.c.

References ast_waitfor_nandfds().

Referenced by __adsi_transmit_messages(), __analog_ss_thread(), __ast_answer(), __ast_play_and_record(), __ast_request_and_dial(), adsi_careful_send(), agent_ack_sleep(), analog_ss_thread(), ast_dtmf_stream(), ast_recvtext(), ast_safe_sleep_conditional(), ast_tonepair(), ast_transfer(), async_wait(), background_detect_exec(), channel_spy(), conf_flush(), dictate_exec(), disa_exec(), disable_t38(), do_waiting(), echo_exec(), handle_recordfile(), handle_speechrecognize(), ices_exec(), isAnsweringMachine(), jack_exec(), launch_asyncagi(), measurenoise(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), receivefax_t38_init(), record_exec(), recordthread(), send_tone_burst(), send_waveform_to_channel(), sendfax_t38_init(), sendurl_exec(), speech_background(), transmit_audio(), transmit_t38(), wait_for_hangup(), waitforring_exec(), and waitstream_core().

03317 {
03318    int oldms = ms;   /* -1 if no timeout */
03319 
03320    ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms);
03321    if ((ms < 0) && (oldms < 0))
03322       ms = 0;
03323    return ms;
03324 }

struct ast_channel* ast_waitfor_n ( struct ast_channel **  chan,
int  n,
int *  ms 
) [read]

Waits for input on a group of channels Wait for input on an array of channels for a given # of milliseconds.

Returns:
Return channel with activity, or NULL if none has activity.
Parameters:
chan an array of pointers to channels
n number of channels that are to be waited upon
ms time "ms" is modified in-place, if applicable

Definition at line 3311 of file channel.c.

References ast_waitfor_nandfds().

Referenced by ast_generic_bridge(), ast_udptl_bridge(), autoservice_run(), dahdi_bridge(), dial_exec_full(), feature_request_and_dial(), generic_thread_loop(), iax2_bridge(), local_bridge_loop(), misdn_bridge(), monitor_dial(), remote_bridge_loop(), rpt(), rpt_exec(), wait_for_answer(), and wait_for_winner().

03312 {
03313    return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
03314 }

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.

Waits for input on an fd.

Definition at line 2952 of file channel.c.

References ast_waitfor_nandfds().

Referenced by dundi_lookup_internal(), dundi_precache_internal(), and softmix_bridge_thread().

02953 {
02954    int winner = -1;
02955    ast_waitfor_nandfds(NULL, 0, fds, n, exception, &winner, ms);
02956    return winner;
02957 }

struct ast_channel* ast_waitfor_nandfds ( struct ast_channel **  c,
int  n,
int *  fds,
int  nfds,
int *  exception,
int *  outfd,
int *  ms 
) [read]

Wait for x amount of time on a file descriptor to have input.

Waits for activity on a group of channels.

Definition at line 2964 of file channel.c.

References ast_channel::_softhangup, ast_add_fd(), ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, ast_log(), AST_MAX_FDS, ast_poll, ast_set_flag, AST_SOFTHANGUP_TIMEOUT, ast_tvcmp(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), CHECK_BLOCKING, errno, ast_channel::fdno, and LOG_WARNING.

Referenced by ast_waitfor(), ast_waitfor_n(), ast_waitfor_n_fd(), ast_waitfordigit_full(), bridge_channel_join_multithreaded(), conf_run(), eivr_comm(), find_cache(), generic_fax_exec(), multiplexed_thread_function(), run_agi(), and waitstream_core().

02967 {
02968    struct timeval start = { 0 , 0 };
02969    struct pollfd *pfds = NULL;
02970    int res;
02971    long rms;
02972    int x, y, max;
02973    int sz;
02974    struct timeval now = { 0, 0 };
02975    struct timeval whentohangup = { 0, 0 }, diff;
02976    struct ast_channel *winner = NULL;
02977    struct fdmap {
02978       int chan;
02979       int fdno;
02980    } *fdmap = NULL;
02981 
02982    if ((sz = n * AST_MAX_FDS + nfds)) {
02983       pfds = alloca(sizeof(*pfds) * sz);
02984       fdmap = alloca(sizeof(*fdmap) * sz);
02985    }
02986 
02987    if (outfd)
02988       *outfd = -99999;
02989    if (exception)
02990       *exception = 0;
02991    
02992    /* Perform any pending masquerades */
02993    for (x = 0; x < n; x++) {
02994       if (c[x]->masq && ast_do_masquerade(c[x])) {
02995          ast_log(LOG_WARNING, "Masquerade failed\n");
02996          *ms = -1;
02997          return NULL;
02998       }
02999 
03000       ast_channel_lock(c[x]);
03001       if (!ast_tvzero(c[x]->whentohangup)) {
03002          if (ast_tvzero(whentohangup))
03003             now = ast_tvnow();
03004          diff = ast_tvsub(c[x]->whentohangup, now);
03005          if (diff.tv_sec < 0 || ast_tvzero(diff)) {
03006             /* Should already be hungup */
03007             c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03008             ast_channel_unlock(c[x]);
03009             return c[x];
03010          }
03011          if (ast_tvzero(whentohangup) || ast_tvcmp(diff, whentohangup) < 0)
03012             whentohangup = diff;
03013       }
03014       ast_channel_unlock(c[x]);
03015    }
03016    /* Wait full interval */
03017    rms = *ms;
03018    /* INT_MAX, not LONG_MAX, because it matters on 64-bit */
03019    if (!ast_tvzero(whentohangup) && whentohangup.tv_sec < INT_MAX / 1000) {
03020       rms = whentohangup.tv_sec * 1000 + whentohangup.tv_usec / 1000;              /* timeout in milliseconds */
03021       if (*ms >= 0 && *ms < rms) {                                                 /* original *ms still smaller */
03022          rms =  *ms;
03023       }
03024    } else if (!ast_tvzero(whentohangup) && rms < 0) {
03025       /* Tiny corner case... call would need to last >24 days */
03026       rms = INT_MAX;
03027    }
03028    /*
03029     * Build the pollfd array, putting the channels' fds first,
03030     * followed by individual fds. Order is important because
03031     * individual fd's must have priority over channel fds.
03032     */
03033    max = 0;
03034    for (x = 0; x < n; x++) {
03035       for (y = 0; y < AST_MAX_FDS; y++) {
03036          fdmap[max].fdno = y;  /* fd y is linked to this pfds */
03037          fdmap[max].chan = x;  /* channel x is linked to this pfds */
03038          max += ast_add_fd(&pfds[max], c[x]->fds[y]);
03039       }
03040       CHECK_BLOCKING(c[x]);
03041    }
03042    /* Add the individual fds */
03043    for (x = 0; x < nfds; x++) {
03044       fdmap[max].chan = -1;
03045       max += ast_add_fd(&pfds[max], fds[x]);
03046    }
03047 
03048    if (*ms > 0)
03049       start = ast_tvnow();
03050    
03051    if (sizeof(int) == 4) { /* XXX fix timeout > 600000 on linux x86-32 */
03052       do {
03053          int kbrms = rms;
03054          if (kbrms > 600000)
03055             kbrms = 600000;
03056          res = ast_poll(pfds, max, kbrms);
03057          if (!res)
03058             rms -= kbrms;
03059       } while (!res && (rms > 0));
03060    } else {
03061       res = ast_poll(pfds, max, rms);
03062    }
03063    for (x = 0; x < n; x++)
03064       ast_clear_flag(c[x], AST_FLAG_BLOCKING);
03065    if (res < 0) { /* Simulate a timeout if we were interrupted */
03066       if (errno != EINTR)
03067          *ms = -1;
03068       return NULL;
03069    }
03070    if (!ast_tvzero(whentohangup)) {   /* if we have a timeout, check who expired */
03071       now = ast_tvnow();
03072       for (x = 0; x < n; x++) {
03073          if (!ast_tvzero(c[x]->whentohangup) && ast_tvcmp(c[x]->whentohangup, now) <= 0) {
03074             c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03075             if (winner == NULL)
03076                winner = c[x];
03077          }
03078       }
03079    }
03080    if (res == 0) { /* no fd ready, reset timeout and done */
03081       *ms = 0; /* XXX use 0 since we may not have an exact timeout. */
03082       return winner;
03083    }
03084    /*
03085     * Then check if any channel or fd has a pending event.
03086     * Remember to check channels first and fds last, as they
03087     * must have priority on setting 'winner'
03088     */
03089    for (x = 0; x < max; x++) {
03090       res = pfds[x].revents;
03091       if (res == 0)
03092          continue;
03093       if (fdmap[x].chan >= 0) {  /* this is a channel */
03094          winner = c[fdmap[x].chan]; /* override previous winners */
03095          if (res & POLLPRI)
03096             ast_set_flag(winner, AST_FLAG_EXCEPTION);
03097          else
03098             ast_clear_flag(winner, AST_FLAG_EXCEPTION);
03099          winner->fdno = fdmap[x].fdno;
03100       } else {       /* this is an fd */
03101          if (outfd)
03102             *outfd = pfds[x].fd;
03103          if (exception)
03104             *exception = (res & POLLPRI) ? -1 : 0;
03105          winner = NULL;
03106       }
03107    }
03108    if (*ms > 0) {
03109       *ms -= ast_tvdiff_ms(ast_tvnow(), start);
03110       if (*ms < 0)
03111          *ms = 0;
03112    }
03113    return winner;
03114 }

int ast_waitfordigit ( struct ast_channel c,
int  ms 
)

int ast_waitfordigit_full ( struct ast_channel c,
int  ms,
int  audiofd,
int  ctrlfd 
)

Wait for a digit Same as ast_waitfordigit() with audio fd for outputting read audio and ctrlfd to monitor for reading.

Parameters:
c channel to wait for a digit on
ms how many milliseconds to wait
audiofd audio file descriptor to write to if audio frames are received
ctrlfd control file descriptor to monitor for reading
Returns:
Returns 1 if ctrlfd becomes available

Definition at line 3365 of file channel.c.

References ast_check_hangup(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UPDATE_RTP_PEER, AST_FLAG_END_DTMF_ONLY, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_frfree, ast_log(), ast_read(), ast_set_flag, ast_test_flag, ast_waitfor_nandfds(), ast_frame::data, ast_frame::datalen, errno, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, ast_frame::ptr, and ast_frame::subclass.

Referenced by ast_readstring_full(), ast_waitfordigit(), handle_getoption(), and handle_waitfordigit().

03366 {
03367    /* Stop if we're a zombie or need a soft hangup */
03368    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
03369       return -1;
03370 
03371    /* Only look for the end of DTMF, don't bother with the beginning and don't emulate things */
03372    ast_set_flag(c, AST_FLAG_END_DTMF_ONLY);
03373 
03374    /* Wait for a digit, no more than ms milliseconds total. */
03375    
03376    while (ms) {
03377       struct ast_channel *rchan;
03378       int outfd=-1;
03379 
03380       errno = 0;
03381       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
03382       
03383       if (!rchan && outfd < 0 && ms) {
03384          if (errno == 0 || errno == EINTR)
03385             continue;
03386          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
03387          ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03388          return -1;
03389       } else if (outfd > -1) {
03390          /* The FD we were watching has something waiting */
03391          ast_log(LOG_WARNING, "The FD we were waiting for has something waiting. Waitfordigit returning numeric 1\n");
03392          ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03393          return 1;
03394       } else if (rchan) {
03395          int res;
03396          struct ast_frame *f = ast_read(c);
03397          if (!f)
03398             return -1;
03399 
03400          switch (f->frametype) {
03401          case AST_FRAME_DTMF_BEGIN:
03402             break;
03403          case AST_FRAME_DTMF_END:
03404             res = f->subclass.integer;
03405             ast_frfree(f);
03406             ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03407             return res;
03408          case AST_FRAME_CONTROL:
03409             switch (f->subclass.integer) {
03410             case AST_CONTROL_HANGUP:
03411                ast_frfree(f);
03412                ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03413                return -1;
03414             case AST_CONTROL_RINGING:
03415             case AST_CONTROL_ANSWER:
03416             case AST_CONTROL_SRCUPDATE:
03417             case AST_CONTROL_SRCCHANGE:
03418             case AST_CONTROL_CONNECTED_LINE:
03419             case AST_CONTROL_REDIRECTING:
03420             case AST_CONTROL_UPDATE_RTP_PEER:
03421             case -1:
03422                /* Unimportant */
03423                break;
03424             default:
03425                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass.integer);
03426                break;
03427             }
03428             break;
03429          case AST_FRAME_VOICE:
03430             /* Write audio if appropriate */
03431             if (audiofd > -1) {
03432                if (write(audiofd, f->data.ptr, f->datalen) < 0) {
03433                   ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
03434                }
03435             }
03436          default:
03437             /* Ignore */
03438             break;
03439          }
03440          ast_frfree(f);
03441       }
03442    }
03443 
03444    ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03445 
03446    return 0; /* Time is up */
03447 }

int ast_write ( struct ast_channel chan,
struct ast_frame frame 
)

Write a frame to a channel This function writes the given frame to the indicated channel.

Parameters:
chan destination channel of the frame
frame frame that will be written
Returns:
It returns 0 on success, -1 on failure.

Todo:
XXX should return 0 maybe ?

Definition at line 4644 of file channel.c.

References ast_channel::_softhangup, apply_plc(), ast_audiohook_detach_list(), AST_AUDIOHOOK_DIRECTION_WRITE, ast_audiohook_write_list(), ast_audiohook_write_list_empty(), ast_channel_lock, ast_channel_name(), ast_channel_trylock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_CONTROL_UNHOLD, ast_deactivate_generator(), ast_debug, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_WRITE_INT, AST_FLAG_ZOMBIE, ast_format_cap_iscompatible(), ast_format_cmp(), AST_FORMAT_CMP_EQUAL, AST_FORMAT_CMP_NOT_EQUAL, ast_format_rate(), AST_FORMAT_SLINEAR, AST_FORMAT_T140, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_frame_dump(), AST_FRAME_HTML, AST_FRAME_IAX, AST_FRAME_MODEM, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_framehook_list_write_event(), ast_frfree, ast_frisolate(), ast_getformatname(), ast_getformatname_multiple(), AST_LIST_NEXT, ast_log(), AST_MONITOR_RUNNING, ast_opt_generic_plc, ast_seekstream(), ast_senddigit_begin(), ast_senddigit_end(), ast_set_write_format_by_id(), AST_SOFTHANGUP_DEV, ast_test_flag, ast_translate(), ast_writestream(), ast_channel::audiohooks, calc_monitor_jump(), CHECK_BLOCKING, ast_frame::data, ast_frame::datalen, DEBUGCHAN_FLAG, ast_filestream::fmt, ast_format_def::format, ast_frame_subclass::format, ast_channel::fout, FRAMECOUNT_INC, ast_channel::framehooks, ast_frame::frametype, ast_channel::generatordata, ast_format::id, ast_channel_tech::indicate, ast_channel::insmpl, ast_frame_subclass::integer, ast_frame::len, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::nativeformats, chanlist::next, ast_channel::outsmpl, ast_frame::ptr, ast_channel::rawwriteformat, ast_channel_monitor::read_stream, ast_frame::samples, SEEK_FORCECUR, send_dtmf_event(), ast_channel_tech::send_html, ast_channel_tech::send_text, ast_frame::src, ast_channel_monitor::state, ast_frame::subclass, ast_channel::tech, ast_channel_tech::write, ast_channel_monitor::write_stream, ast_channel_tech::write_text, ast_channel_tech::write_video, ast_channel::writeformat, and ast_channel::writetrans.

Referenced by adsi_careful_send(), agent_write(), ast_bridge_call(), ast_generic_bridge(), ast_prod(), ast_readaudio_callback(), ast_readvideo_callback(), ast_udptl_bridge(), ast_write_video(), conf_queue_dtmf(), conf_run(), dahdi_bridge(), dictate_exec(), echo_exec(), fax_generator_generate(), feature_request_and_dial(), function_ilink(), gen_generate(), generic_fax_exec(), handle_jack_audio(), handle_link_data(), iax2_bridge(), jb_get_and_deliver(), linear_generator(), local_bridge_loop(), milliwatt_generate(), misdn_bridge(), moh_files_generator(), moh_generate(), mp3_exec(), multiplexed_bridge_write(), NBScat_exec(), playtones_generator(), remote_bridge_loop(), rpt(), rpt_exec(), send_link_dtmf(), send_link_keyquery(), send_tone_burst(), send_usb_txt(), send_waveform_to_channel(), silence_generator_generate(), simple_bridge_write(), sms_generate(), softmix_bridge_poke(), softmix_bridge_write(), softmix_pass_dtmf(), softmix_pass_video_all(), softmix_pass_video_top_priority(), spandsp_fax_gw_t30_gen(), spy_generate(), t38_tx_packet_handler(), tonepair_generator(), and wait_for_answer().

04645 {
04646    int res = -1;
04647    struct ast_frame *f = NULL;
04648    int count = 0;
04649 
04650    /*Deadlock avoidance*/
04651    while(ast_channel_trylock(chan)) {
04652       /*cannot goto done since the channel is not locked*/
04653       if(count++ > 10) {
04654          ast_debug(1, "Deadlock avoided for write to channel '%s'\n", ast_channel_name(chan));
04655          return 0;
04656       }
04657       usleep(1);
04658    }
04659    /* Stop if we're a zombie or need a soft hangup */
04660    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
04661       goto done;
04662 
04663    /* Handle any pending masquerades */
04664    if (chan->masq) {
04665       ast_channel_unlock(chan);
04666       if (ast_do_masquerade(chan)) {
04667          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
04668          return res; /* no need to goto done: chan is already unlocked for masq */
04669       }
04670       ast_channel_lock(chan);
04671    }
04672    if (chan->masqr) {
04673       res = 0; /* XXX explain, why 0 ? */
04674       goto done;
04675    }
04676 
04677    /* Perform the framehook write event here. After the frame enters the framehook list
04678     * there is no telling what will happen, how awesome is that!!! */
04679    if (!(fr = ast_framehook_list_write_event(chan->framehooks, fr))) {
04680       res = 0;
04681       goto done;
04682    }
04683 
04684    if (chan->generatordata && (!fr->src || strcasecmp(fr->src, "ast_prod"))) {
04685       if (ast_test_flag(chan, AST_FLAG_WRITE_INT)) {
04686             ast_deactivate_generator(chan);
04687       } else {
04688          if (fr->frametype == AST_FRAME_DTMF_END) {
04689             /* There is a generator running while we're in the middle of a digit.
04690              * It's probably inband DTMF, so go ahead and pass it so it can
04691              * stop the generator */
04692             ast_clear_flag(chan, AST_FLAG_BLOCKING);
04693             ast_channel_unlock(chan);
04694             res = ast_senddigit_end(chan, fr->subclass.integer, fr->len);
04695             ast_channel_lock(chan);
04696             CHECK_BLOCKING(chan);
04697          } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_UNHOLD) {
04698             /* This is a side case where Echo is basically being called and the person put themselves on hold and took themselves off hold */
04699             res = (chan->tech->indicate == NULL) ? 0 :
04700                chan->tech->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen);
04701          }
04702          res = 0; /* XXX explain, why 0 ? */
04703          goto done;
04704       }
04705    }
04706    /* High bit prints debugging */
04707    if (chan->fout & DEBUGCHAN_FLAG)
04708       ast_frame_dump(ast_channel_name(chan), fr, ">>");
04709    CHECK_BLOCKING(chan);
04710    switch (fr->frametype) {
04711    case AST_FRAME_CONTROL:
04712       res = (chan->tech->indicate == NULL) ? 0 :
04713          chan->tech->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen);
04714       break;
04715    case AST_FRAME_DTMF_BEGIN:
04716       if (chan->audiohooks) {
04717          struct ast_frame *old_frame = fr;
04718          fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
04719          if (old_frame != fr)
04720             f = fr;
04721       }
04722       send_dtmf_event(chan, "Sent", fr->subclass.integer, "Yes", "No");
04723       ast_clear_flag(chan, AST_FLAG_BLOCKING);
04724       ast_channel_unlock(chan);
04725       res = ast_senddigit_begin(chan, fr->subclass.integer);
04726       ast_channel_lock(chan);
04727       CHECK_BLOCKING(chan);
04728       break;
04729    case AST_FRAME_DTMF_END:
04730       if (chan->audiohooks) {
04731          struct ast_frame *new_frame = fr;
04732 
04733          new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
04734          if (new_frame != fr) {
04735             ast_frfree(new_frame);
04736          }
04737       }
04738       send_dtmf_event(chan, "Sent", fr->subclass.integer, "No", "Yes");
04739       ast_clear_flag(chan, AST_FLAG_BLOCKING);
04740       ast_channel_unlock(chan);
04741       res = ast_senddigit_end(chan, fr->subclass.integer, fr->len);
04742       ast_channel_lock(chan);
04743       CHECK_BLOCKING(chan);
04744       break;
04745    case AST_FRAME_TEXT:
04746       if (fr->subclass.integer == AST_FORMAT_T140) {
04747          res = (chan->tech->write_text == NULL) ? 0 :
04748             chan->tech->write_text(chan, fr);
04749       } else {
04750          res = (chan->tech->send_text == NULL) ? 0 :
04751             chan->tech->send_text(chan, (char *) fr->data.ptr);
04752       }
04753       break;
04754    case AST_FRAME_HTML:
04755       res = (chan->tech->send_html == NULL) ? 0 :
04756          chan->tech->send_html(chan, fr->subclass.integer, (char *) fr->data.ptr, fr->datalen);
04757       break;
04758    case AST_FRAME_VIDEO:
04759       /* XXX Handle translation of video codecs one day XXX */
04760       res = (chan->tech->write_video == NULL) ? 0 :
04761          chan->tech->write_video(chan, fr);
04762       break;
04763    case AST_FRAME_MODEM:
04764       res = (chan->tech->write == NULL) ? 0 :
04765          chan->tech->write(chan, fr);
04766       break;
04767    case AST_FRAME_VOICE:
04768       if (chan->tech->write == NULL)
04769          break;   /*! \todo XXX should return 0 maybe ? */
04770 
04771       if (ast_opt_generic_plc && fr->subclass.format.id == AST_FORMAT_SLINEAR) {
04772          apply_plc(chan, fr);
04773       }
04774 
04775       /* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */
04776       if (ast_format_cmp(&fr->subclass.format, &chan->rawwriteformat) != AST_FORMAT_CMP_NOT_EQUAL) {
04777          f = fr;
04778       } else {
04779          /* XXX Something is not right we are not compatible with this frame bad things can happen
04780           * problems range from no/one-way audio to unexplained line hangups as a last resort try adjust the format
04781           * ideally we do not want to do this and this indicates a deeper problem for now we log these events to
04782           * eliminate user impact and help identify the problem areas
04783           * JIRA issues related to this :-
04784           * ASTERISK-14384, ASTERISK-17502, ASTERISK-17541, ASTERISK-18063, ASTERISK-18325, ASTERISK-18422*/
04785          if ((!ast_format_cap_iscompatible(chan->nativeformats, &fr->subclass.format)) &&
04786              (ast_format_cmp(&chan->writeformat, &fr->subclass.format) != AST_FORMAT_CMP_EQUAL)) {
04787             char nf[512];
04788             ast_log(LOG_WARNING, "Codec mismatch on channel %s setting write format to %s from %s native formats %s\n",
04789                ast_channel_name(chan), ast_getformatname(&fr->subclass.format), ast_getformatname(&chan->writeformat),
04790                ast_getformatname_multiple(nf, sizeof(nf), chan->nativeformats));
04791             ast_set_write_format_by_id(chan, fr->subclass.format.id);
04792          }
04793 
04794          f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
04795       }
04796 
04797       if (!f) {
04798          res = 0;
04799          break;
04800       }
04801 
04802       if (chan->audiohooks) {
04803          struct ast_frame *prev = NULL, *new_frame, *cur, *dup;
04804          int freeoldlist = 0;
04805 
04806          if (f != fr) {
04807             freeoldlist = 1;
04808          }
04809 
04810          /* Since ast_audiohook_write may return a new frame, and the cur frame is
04811           * an item in a list of frames, create a new list adding each cur frame back to it
04812           * regardless if the cur frame changes or not. */
04813          for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
04814             new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, cur);
04815 
04816             /* if this frame is different than cur, preserve the end of the list,
04817              * free the old frames, and set cur to be the new frame */
04818             if (new_frame != cur) {
04819 
04820                /* doing an ast_frisolate here seems silly, but we are not guaranteed the new_frame
04821                 * isn't part of local storage, meaning if ast_audiohook_write is called multiple
04822                 * times it may override the previous frame we got from it unless we dup it */
04823                if ((dup = ast_frisolate(new_frame))) {
04824                   AST_LIST_NEXT(dup, frame_list) = AST_LIST_NEXT(cur, frame_list);
04825                   if (freeoldlist) {
04826                      AST_LIST_NEXT(cur, frame_list) = NULL;
04827                      ast_frfree(cur);
04828                   }
04829                   if (new_frame != dup) {
04830                      ast_frfree(new_frame);
04831                   }
04832                   cur = dup;
04833                }
04834             }
04835 
04836             /* now, regardless if cur is new or not, add it to the new list,
04837              * if the new list has not started, cur will become the first item. */
04838             if (prev) {
04839                AST_LIST_NEXT(prev, frame_list) = cur;
04840             } else {
04841                f = cur; /* set f to be the beginning of our new list */
04842             }
04843             prev = cur;
04844          }
04845       }
04846       
04847       /* If Monitor is running on this channel, then we have to write frames out there too */
04848       /* the translator on chan->writetrans may have returned multiple frames
04849          from the single frame we passed in; if so, feed each one of them to the
04850          monitor */
04851       if (chan->monitor && chan->monitor->write_stream) {
04852          struct ast_frame *cur;
04853 
04854          for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
04855          /* XXX must explain this code */
04856 #ifndef MONITOR_CONSTANT_DELAY
04857             int jump = chan->insmpl - chan->outsmpl - 4 * cur->samples;
04858             if (jump >= 0) {
04859                jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(&f->subclass.format), ast_format_rate(&chan->monitor->read_stream->fmt->format));
04860                if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1)
04861                   ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
04862                chan->outsmpl += (chan->insmpl - chan->outsmpl) + cur->samples;
04863             } else {
04864                chan->outsmpl += cur->samples;
04865             }
04866 #else
04867             int jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format));
04868             if (jump - MONITOR_DELAY >= 0) {
04869                if (ast_seekstream(chan->monitor->write_stream, jump - cur->samples, SEEK_FORCECUR) == -1)
04870                   ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
04871                chan->outsmpl += chan->insmpl - chan->outsmpl;
04872             } else {
04873                chan->outsmpl += cur->samples;
04874             }
04875 #endif
04876             if (chan->monitor->state == AST_MONITOR_RUNNING) {
04877                if (ast_writestream(chan->monitor->write_stream, cur) < 0)
04878                   ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
04879             }
04880          }
04881       }
04882 
04883       /* the translator on chan->writetrans may have returned multiple frames
04884          from the single frame we passed in; if so, feed each one of them to the
04885          channel, freeing each one after it has been written */
04886       if ((f != fr) && AST_LIST_NEXT(f, frame_list)) {
04887          struct ast_frame *cur, *next = NULL;
04888          unsigned int skip = 0;
04889 
04890          cur = f;
04891          while (cur) {
04892             next = AST_LIST_NEXT(cur, frame_list);
04893             AST_LIST_NEXT(cur, frame_list) = NULL;
04894             if (!skip) {
04895                if ((res = chan->tech->write(chan, cur)) < 0) {
04896                   chan->_softhangup |= AST_SOFTHANGUP_DEV;
04897                   skip = 1;
04898                } else if (next) {
04899                   /* don't do this for the last frame in the list,
04900                      as the code outside the loop will do it once
04901                   */
04902                   chan->fout = FRAMECOUNT_INC(chan->fout);
04903                }
04904             }
04905             ast_frfree(cur);
04906             cur = next;
04907          }
04908 
04909          /* reset f so the code below doesn't attempt to free it */
04910          f = NULL;
04911       } else {
04912          res = chan->tech->write(chan, f);
04913       }
04914       break;
04915    case AST_FRAME_NULL:
04916    case AST_FRAME_IAX:
04917       /* Ignore these */
04918       res = 0;
04919       break;
04920    default:
04921       /* At this point, fr is the incoming frame and f is NULL.  Channels do
04922        * not expect to get NULL as a frame pointer and will segfault.  Hence,
04923        * we output the original frame passed in. */
04924       res = chan->tech->write(chan, fr);
04925       break;
04926    }
04927 
04928    if (f && f != fr)
04929       ast_frfree(f);
04930    ast_clear_flag(chan, AST_FLAG_BLOCKING);
04931 
04932    /* Consider a write failure to force a soft hangup */
04933    if (res < 0) {
04934       chan->_softhangup |= AST_SOFTHANGUP_DEV;
04935    } else {
04936       chan->fout = FRAMECOUNT_INC(chan->fout);
04937    }
04938 done:
04939    if (chan->audiohooks && ast_audiohook_write_list_empty(chan->audiohooks)) {
04940       /* The list gets recreated if audiohooks are added again later */
04941       ast_audiohook_detach_list(chan->audiohooks);
04942       chan->audiohooks = NULL;
04943    }
04944    ast_channel_unlock(chan);
04945    return res;
04946 }

int ast_write_video ( struct ast_channel chan,
struct ast_frame frame 
)

Write video frame to a channel This function writes the given frame to the indicated channel.

Parameters:
chan destination channel of the frame
frame frame that will be written
Returns:
It returns 1 on success, 0 if not implemented, and -1 on failure.

Definition at line 4529 of file channel.c.

References ast_write(), ast_channel::tech, and ast_channel_tech::write_video.

04530 {
04531    int res;
04532    if (!chan->tech->write_video)
04533       return 0;
04534    res = ast_write(chan, fr);
04535    if (!res)
04536       res = 1;
04537    return res;
04538 }

static void bridge_play_sounds ( struct ast_channel c0,
struct ast_channel c1 
) [static]

Definition at line 7258 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_strdupa, bridge_playfile(), pbx_builtin_getvar_helper(), and pbx_builtin_setvar_helper().

Referenced by ast_channel_bridge().

07259 {
07260    const char *s, *sound;
07261 
07262    /* See if we need to play an audio file to any side of the bridge */
07263 
07264    ast_channel_lock(c0);
07265    if ((s = pbx_builtin_getvar_helper(c0, "BRIDGE_PLAY_SOUND"))) {
07266       sound = ast_strdupa(s);
07267       ast_channel_unlock(c0);
07268       bridge_playfile(c0, c1, sound, 0);
07269       pbx_builtin_setvar_helper(c0, "BRIDGE_PLAY_SOUND", NULL);
07270    } else {
07271       ast_channel_unlock(c0);
07272    }
07273 
07274    ast_channel_lock(c1);
07275    if ((s = pbx_builtin_getvar_helper(c1, "BRIDGE_PLAY_SOUND"))) {
07276       sound = ast_strdupa(s);
07277       ast_channel_unlock(c1);
07278       bridge_playfile(c1, c0, sound, 0);
07279       pbx_builtin_setvar_helper(c1, "BRIDGE_PLAY_SOUND", NULL);
07280    } else {
07281       ast_channel_unlock(c1);
07282    }
07283 }

static void bridge_playfile ( struct ast_channel chan,
struct ast_channel peer,
const char *  sound,
int  remain 
) [static]

Definition at line 6941 of file channel.c.

References ast_autoservice_start(), ast_autoservice_stop(), ast_channel_language(), AST_DIGIT_ANY, ast_say_number(), and ast_stream_and_wait().

Referenced by ast_channel_bridge(), and bridge_play_sounds().

06942 {
06943    int min = 0, sec = 0, check;
06944 
06945    check = ast_autoservice_start(peer);
06946    if (check)
06947       return;
06948 
06949    if (remain > 0) {
06950       if (remain / 60 > 1) {
06951          min = remain / 60;
06952          sec = remain % 60;
06953       } else {
06954          sec = remain;
06955       }
06956    }
06957    
06958    if (!strcmp(sound,"timeleft")) { /* Queue support */
06959       ast_stream_and_wait(chan, "vm-youhave", "");
06960       if (min) {
06961          ast_say_number(chan, min, AST_DIGIT_ANY, ast_channel_language(chan), NULL);
06962          ast_stream_and_wait(chan, "queue-minutes", "");
06963       }
06964       if (sec) {
06965          ast_say_number(chan, sec, AST_DIGIT_ANY, ast_channel_language(chan), NULL);
06966          ast_stream_and_wait(chan, "queue-seconds", "");
06967       }
06968    } else {
06969       ast_stream_and_wait(chan, sound, "");
06970    }
06971 
06972    ast_autoservice_stop(peer);
06973 }

static int calc_monitor_jump ( int  samples,
int  sample_rate,
int  seek_rate 
) [inline, static]

calculates the number of samples to jump forward with in a monitor stream.

Note:
When using ast_seekstream() with the read and write streams of a monitor, the number of samples to seek forward must be of the same sample rate as the stream or else the jump will not be calculated correctly.
Return values:
number of samples to seek forward after rate conversion.

Definition at line 3555 of file channel.c.

Referenced by __ast_read(), and ast_write().

03556 {
03557    int diff = sample_rate - seek_rate;
03558 
03559    if (diff > 0) {
03560       samples = samples / (float) (sample_rate / seek_rate);
03561    } else if (diff < 0) {
03562       samples = samples * (float) (seek_rate / sample_rate);
03563    }
03564 
03565    return samples;
03566 }

static void call_forward_inherit ( struct ast_channel new_chan,
struct ast_channel parent,
struct ast_channel orig 
) [static]

Definition at line 5204 of file channel.c.

References ast_channel_datastore_inherit(), ast_channel_inherit_variables(), ast_channel_lock, ast_channel_lock_both, ast_channel_redirecting_macro(), ast_channel_unlock, ast_channel_update_redirecting(), ast_check_hangup(), AST_FLAG_ZOMBIE, ast_party_redirecting_copy(), ast_party_redirecting_free(), ast_party_redirecting_init(), ast_test_flag, and ast_channel::redirecting.

Referenced by ast_call_forward().

05205 {
05206    if (!ast_test_flag(parent, AST_FLAG_ZOMBIE) && !ast_check_hangup(parent)) {
05207       struct ast_party_redirecting redirecting;
05208 
05209       /*
05210        * The parent is not a ZOMBIE or hungup so update it with the
05211        * original channel's redirecting information.
05212        */
05213       ast_party_redirecting_init(&redirecting);
05214       ast_channel_lock(orig);
05215       ast_party_redirecting_copy(&redirecting, &orig->redirecting);
05216       ast_channel_unlock(orig);
05217       if (ast_channel_redirecting_macro(orig, parent, &redirecting, 1, 0)) {
05218          ast_channel_update_redirecting(parent, &redirecting, NULL);
05219       }
05220       ast_party_redirecting_free(&redirecting);
05221    }
05222 
05223    /* Safely inherit variables and datastores from the parent channel. */
05224    ast_channel_lock_both(parent, new_chan);
05225    ast_channel_inherit_variables(parent, new_chan);
05226    ast_channel_datastore_inherit(parent, new_chan);
05227    ast_channel_unlock(new_chan);
05228    ast_channel_unlock(parent);
05229 }

static void* channel_cc_params_copy ( void *  data  )  [static]

Definition at line 9417 of file channel.c.

References ast_cc_config_params_init, and ast_cc_copy_config_params().

09418 {
09419    const struct ast_cc_config_params *src = data;
09420    struct ast_cc_config_params *dest = ast_cc_config_params_init();
09421    if (!dest) {
09422       return NULL;
09423    }
09424    ast_cc_copy_config_params(dest, src);
09425    return dest;
09426 }

static void channel_cc_params_destroy ( void *  data  )  [static]

Definition at line 9428 of file channel.c.

References ast_cc_config_params_destroy().

09429 {
09430    struct ast_cc_config_params *cc_params = data;
09431    ast_cc_config_params_destroy(cc_params);
09432 }

const char* channelreloadreason2txt ( enum channelreloadreason  reason  ) 

Convert enum channelreloadreason to text string for manager event.

\ brief Convert channel reloadreason (ENUM) to text string for manager event

Definition at line 8092 of file channel.c.

References CHANNEL_CLI_RELOAD, CHANNEL_MODULE_LOAD, and CHANNEL_MODULE_RELOAD.

Referenced by reload_config().

08093 {
08094    switch (reason) {
08095    case CHANNEL_MODULE_LOAD:
08096       return "LOAD (Channel module load)";
08097 
08098    case CHANNEL_MODULE_RELOAD:
08099       return "RELOAD (Channel module reload)";
08100 
08101    case CHANNEL_CLI_RELOAD:
08102       return "CLIRELOAD (Channel module reload by CLI command)";
08103 
08104    default:
08105       return "MANAGERRELOAD (Channel module reload by manager)";
08106    }
08107 };

static void clone_variables ( struct ast_channel original,
struct ast_channel clonechan 
) [static]

Clone channel variables from 'clone' channel into 'original' channel.

All variables except those related to app_groupcount are cloned. Variables are actually _removed_ from 'clone' channel, presumably because it will subsequently be destroyed.

Note:
Assumes locks will be in place on both channels when called.

Definition at line 6145 of file channel.c.

References AST_LIST_APPEND_LIST, AST_LIST_FIRST, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_var_assign(), ast_var_t::entries, ast_var_t::name, ast_var_t::value, and ast_channel::varshead.

Referenced by ast_do_masquerade().

06146 {
06147    struct ast_var_t *current, *newvar;
06148    /* Append variables from clone channel into original channel */
06149    /* XXX Is this always correct?  We have to in order to keep MACROS working XXX */
06150    if (AST_LIST_FIRST(&clonechan->varshead))
06151       AST_LIST_APPEND_LIST(&original->varshead, &clonechan->varshead, entries);
06152 
06153    /* then, dup the varshead list into the clone */
06154    
06155    AST_LIST_TRAVERSE(&original->varshead, current, entries) {
06156       newvar = ast_var_assign(current->name, current->value);
06157       if (newvar)
06158          AST_LIST_INSERT_TAIL(&clonechan->varshead, newvar, entries);
06159    }
06160 }

static char* complete_channeltypes ( struct ast_cli_args a  )  [static]

Definition at line 316 of file channel.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, ast_cli_args::n, ast_cli_args::pos, chanlist::tech, ast_channel_tech::type, and ast_cli_args::word.

Referenced by handle_cli_core_show_channeltype().

00317 {
00318    struct chanlist *cl;
00319    int which = 0;
00320    int wordlen;
00321    char *ret = NULL;
00322 
00323    if (a->pos != 3)
00324       return NULL;
00325 
00326    wordlen = strlen(a->word);
00327 
00328    AST_RWLIST_RDLOCK(&backends);
00329    AST_RWLIST_TRAVERSE(&backends, cl, list) {
00330       if (!strncasecmp(a->word, cl->tech->type, wordlen) && ++which > a->n) {
00331          ret = ast_strdup(cl->tech->type);
00332          break;
00333       }
00334    }
00335    AST_RWLIST_UNLOCK(&backends);
00336    
00337    return ret;
00338 }

static int data_channels_provider_handler ( const struct ast_data_search search,
struct ast_data root 
) [static]

Definition at line 7851 of file channel.c.

References ast_channel_data_add_structure(), ast_channel_iterator_all_new(), ast_channel_iterator_destroy(), ast_channel_iterator_next(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_channel_unref, ast_data_add_node(), ast_data_remove_node(), ast_data_search_match(), ast_log(), and LOG_ERROR.

07853 {
07854    struct ast_channel *c;
07855    struct ast_channel_iterator *iter = NULL;
07856    struct ast_data *data_channel;
07857 
07858    for (iter = ast_channel_iterator_all_new();
07859       iter && (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) {
07860       ast_channel_lock(c);
07861 
07862       data_channel = ast_data_add_node(root, "channel");
07863       if (!data_channel) {
07864          ast_channel_unlock(c);
07865          continue;
07866       }
07867 
07868       if (ast_channel_data_add_structure(data_channel, c, 1) < 0) {
07869          ast_log(LOG_ERROR, "Unable to add channel structure for channel: %s\n", ast_channel_name(c));
07870       }
07871 
07872       ast_channel_unlock(c);
07873 
07874       if (!ast_data_search_match(search, data_channel)) {
07875          ast_data_remove_node(root, data_channel);
07876       }
07877    }
07878    if (iter) {
07879       ast_channel_iterator_destroy(iter);
07880    }
07881 
07882    return 0;
07883 }

static int data_channeltypes_provider_handler ( const struct ast_data_search search,
struct ast_data data_root 
) [static]

Definition at line 7889 of file channel.c.

References ast_channel_tech::answer, ast_data_add_bool(), ast_data_add_codecs(), ast_data_add_node(), ast_data_add_str(), ast_data_remove_node(), ast_data_search_match(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_channel_tech::bridge, ast_channel_tech::bridged_channel, ast_channel_tech::call, ast_channel_tech::capabilities, ast_channel_tech::cc_callback, ast_channel_tech::description, ast_channel_tech::devicestate, ast_channel_tech::early_bridge, ast_channel_tech::exception, ast_channel_tech::fixup, ast_channel_tech::func_channel_read, ast_channel_tech::func_channel_write, ast_channel_tech::get_base_channel, ast_channel_tech::get_pvt_uniqueid, ast_channel_tech::hangup, ast_channel_tech::indicate, ast_channel_tech::queryoption, ast_channel_tech::read, ast_channel_tech::send_digit_begin, ast_channel_tech::send_digit_end, ast_channel_tech::send_html, ast_channel_tech::send_image, ast_channel_tech::send_text, ast_channel_tech::set_base_channel, ast_channel_tech::setoption, chanlist::tech, ast_channel_tech::transfer, ast_channel_tech::type, ast_channel_tech::write, ast_channel_tech::write_text, and ast_channel_tech::write_video.

07891 {
07892    struct chanlist *cl;
07893    struct ast_data *data_type;
07894 
07895    AST_RWLIST_RDLOCK(&backends);
07896    AST_RWLIST_TRAVERSE(&backends, cl, list) {
07897       data_type = ast_data_add_node(data_root, "type");
07898       if (!data_type) {
07899          continue;
07900       }
07901       ast_data_add_str(data_type, "name", cl->tech->type);
07902       ast_data_add_str(data_type, "description", cl->tech->description);
07903       ast_data_add_bool(data_type, "devicestate", cl->tech->devicestate ? 1 : 0);
07904       ast_data_add_bool(data_type, "indications", cl->tech->indicate ? 1 : 0);
07905       ast_data_add_bool(data_type, "transfer", cl->tech->transfer ? 1 : 0);
07906       ast_data_add_bool(data_type, "send_digit_begin", cl->tech->send_digit_begin ? 1 : 0);
07907       ast_data_add_bool(data_type, "send_digit_end", cl->tech->send_digit_end ? 1 : 0);
07908       ast_data_add_bool(data_type, "call", cl->tech->call ? 1 : 0);
07909       ast_data_add_bool(data_type, "hangup", cl->tech->hangup ? 1 : 0);
07910       ast_data_add_bool(data_type, "answer", cl->tech->answer ? 1 : 0);
07911       ast_data_add_bool(data_type, "read", cl->tech->read ? 1 : 0);
07912       ast_data_add_bool(data_type, "write", cl->tech->write ? 1 : 0);
07913       ast_data_add_bool(data_type, "send_text", cl->tech->send_text ? 1 : 0);
07914       ast_data_add_bool(data_type, "send_image", cl->tech->send_image ? 1 : 0);
07915       ast_data_add_bool(data_type, "send_html", cl->tech->send_html ? 1 : 0);
07916       ast_data_add_bool(data_type, "exception", cl->tech->exception ? 1 : 0);
07917       ast_data_add_bool(data_type, "bridge", cl->tech->bridge ? 1 : 0);
07918       ast_data_add_bool(data_type, "early_bridge", cl->tech->early_bridge ? 1 : 0);
07919       ast_data_add_bool(data_type, "fixup", cl->tech->fixup ? 1 : 0);
07920       ast_data_add_bool(data_type, "setoption", cl->tech->setoption ? 1 : 0);
07921       ast_data_add_bool(data_type, "queryoption", cl->tech->queryoption ? 1 : 0);
07922       ast_data_add_bool(data_type, "write_video", cl->tech->write_video ? 1 : 0);
07923       ast_data_add_bool(data_type, "write_text", cl->tech->write_text ? 1 : 0);
07924       ast_data_add_bool(data_type, "bridged_channel", cl->tech->bridged_channel ? 1 : 0);
07925       ast_data_add_bool(data_type, "func_channel_read", cl->tech->func_channel_read ? 1 : 0);
07926       ast_data_add_bool(data_type, "func_channel_write", cl->tech->func_channel_write ? 1 : 0);
07927       ast_data_add_bool(data_type, "get_base_channel", cl->tech->get_base_channel ? 1 : 0);
07928       ast_data_add_bool(data_type, "set_base_channel", cl->tech->set_base_channel ? 1 : 0);
07929       ast_data_add_bool(data_type, "get_pvt_uniqueid", cl->tech->get_pvt_uniqueid ? 1 : 0);
07930       ast_data_add_bool(data_type, "cc_callback", cl->tech->cc_callback ? 1 : 0);
07931 
07932       ast_data_add_codecs(data_type, "capabilities", cl->tech->capabilities);
07933 
07934       if (!ast_data_search_match(search, data_type)) {
07935          ast_data_remove_node(data_root, data_type);
07936       }
07937    }
07938    AST_RWLIST_UNLOCK(&backends);
07939 
07940    return 0;
07941 }

static void destroy_hooks ( struct ast_channel chan  )  [static]

Definition at line 2573 of file channel.c.

References ast_audiohook_detach_list(), ast_framehook_list_destroy(), and ast_channel::audiohooks.

Referenced by ast_hangup().

02574 {
02575    if (chan->audiohooks) {
02576       ast_audiohook_detach_list(chan->audiohooks);
02577       chan->audiohooks = NULL;
02578    }
02579 
02580    ast_framehook_list_destroy(chan);
02581 }

static void free_translation ( struct ast_channel clonechan  )  [static]

Definition at line 2536 of file channel.c.

References ast_best_codec(), ast_format_cap_is_empty(), ast_format_clear(), ast_format_copy(), ast_translator_free_path(), ast_channel::nativeformats, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readtrans, and ast_channel::writetrans.

Referenced by ast_do_masquerade(), and ast_hangup().

02537 {
02538    if (clonechan->writetrans)
02539       ast_translator_free_path(clonechan->writetrans);
02540    if (clonechan->readtrans)
02541       ast_translator_free_path(clonechan->readtrans);
02542    clonechan->writetrans = NULL;
02543    clonechan->readtrans = NULL;
02544    if (ast_format_cap_is_empty(clonechan->nativeformats)) {
02545       ast_format_clear(&clonechan->rawwriteformat);
02546       ast_format_clear(&clonechan->rawreadformat);
02547    } else {
02548       struct ast_format tmpfmt;
02549       ast_best_codec(clonechan->nativeformats, &tmpfmt);
02550       ast_format_copy(&clonechan->rawwriteformat, &tmpfmt);
02551       ast_format_copy(&clonechan->rawreadformat, &tmpfmt);
02552    }
02553 }

static int generator_force ( const void *  data  )  [static]

Definition at line 2897 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_deactivate_generator(), ast_debug, ast_format_rate(), ast_generator::generate, ast_channel::generator, ast_channel::generatordata, and ast_channel::writeformat.

Referenced by ast_activate_generator(), and ast_read_generator_actions().

02898 {
02899    /* Called if generator doesn't have data */
02900    void *tmp;
02901    int res;
02902    int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = NULL;
02903    struct ast_channel *chan = (struct ast_channel *)data;
02904 
02905    ast_channel_lock(chan);
02906    tmp = chan->generatordata;
02907    chan->generatordata = NULL;
02908    if (chan->generator)
02909       generate = chan->generator->generate;
02910    ast_channel_unlock(chan);
02911 
02912    if (!tmp || !generate)
02913       return 0;
02914 
02915    res = generate(chan, tmp, 0, ast_format_rate(&chan->writeformat) / 50);
02916 
02917    chan->generatordata = tmp;
02918 
02919    if (res) {
02920       ast_debug(1, "Auto-deactivating generator\n");
02921       ast_deactivate_generator(chan);
02922    }
02923 
02924    return 0;
02925 }

static void generator_write_format_change ( struct ast_channel chan  )  [static]

Definition at line 2888 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_channel::generator, ast_channel::generatordata, and ast_generator::write_format_change.

Referenced by set_format().

02889 {
02890    ast_channel_lock(chan);
02891    if (chan->generator && chan->generator->write_format_change) {
02892       chan->generator->write_format_change(chan, chan->generatordata);
02893    }
02894    ast_channel_unlock(chan);
02895 }

static void handle_cause ( int  cause,
int *  outstate 
) [static]

Definition at line 5181 of file channel.c.

References AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CONTROL_BUSY, and AST_CONTROL_CONGESTION.

05182 {
05183    if (outstate) {
05184       /* compute error and return */
05185       if (cause == AST_CAUSE_BUSY)
05186          *outstate = AST_CONTROL_BUSY;
05187       else if (cause == AST_CAUSE_CONGESTION)
05188          *outstate = AST_CONTROL_CONGESTION;
05189       else
05190          *outstate = 0;
05191    }
05192 }

static char* handle_cli_core_show_channeltype ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Show details about a channel driver - CLI command.

Definition at line 341 of file channel.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_getformatname_multiple(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_channel_tech::capabilities, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_channeltypes(), ast_channel_tech::devicestate, ast_cli_args::fd, ast_channel_tech::indicate, ast_channel_tech::send_digit_begin, ast_channel_tech::send_digit_end, ast_channel_tech::send_html, ast_channel_tech::send_image, ast_channel_tech::send_text, chanlist::tech, ast_channel_tech::transfer, ast_channel_tech::type, and ast_cli_entry::usage.

00342 {
00343    struct chanlist *cl = NULL;
00344    char buf[512];
00345 
00346    switch (cmd) {
00347    case CLI_INIT:
00348       e->command = "core show channeltype";
00349       e->usage =
00350          "Usage: core show channeltype <name>\n"
00351          "  Show details about the specified channel type, <name>.\n";
00352       return NULL;
00353    case CLI_GENERATE:
00354       return complete_channeltypes(a);
00355    }
00356 
00357    if (a->argc != 4)
00358       return CLI_SHOWUSAGE;
00359    
00360    AST_RWLIST_RDLOCK(&backends);
00361 
00362    AST_RWLIST_TRAVERSE(&backends, cl, list) {
00363       if (!strncasecmp(cl->tech->type, a->argv[3], strlen(cl->tech->type)))
00364          break;
00365    }
00366 
00367 
00368    if (!cl) {
00369       ast_cli(a->fd, "\n%s is not a registered channel driver.\n", a->argv[3]);
00370       AST_RWLIST_UNLOCK(&backends);
00371       return CLI_FAILURE;
00372    }
00373 
00374    ast_cli(a->fd,
00375       "-- Info about channel driver: %s --\n"
00376       "  Device State: %s\n"
00377       "    Indication: %s\n"
00378       "     Transfer : %s\n"
00379       "  Capabilities: %s\n"
00380       "   Digit Begin: %s\n"
00381       "     Digit End: %s\n"
00382       "    Send HTML : %s\n"
00383       " Image Support: %s\n"
00384       "  Text Support: %s\n",
00385       cl->tech->type,
00386       (cl->tech->devicestate) ? "yes" : "no",
00387       (cl->tech->indicate) ? "yes" : "no",
00388       (cl->tech->transfer) ? "yes" : "no",
00389       ast_getformatname_multiple(buf, sizeof(buf), cl->tech->capabilities),
00390       (cl->tech->send_digit_begin) ? "yes" : "no",
00391       (cl->tech->send_digit_end) ? "yes" : "no",
00392       (cl->tech->send_html) ? "yes" : "no",
00393       (cl->tech->send_image) ? "yes" : "no",
00394       (cl->tech->send_text) ? "yes" : "no"
00395       
00396    );
00397 
00398    AST_RWLIST_UNLOCK(&backends);
00399 
00400    return CLI_SUCCESS;
00401 }

static char* handle_cli_core_show_channeltypes ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Show channel types - CLI command.

Definition at line 275 of file channel.c.

References ast_cli_args::argc, ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_channel_tech::description, ast_channel_tech::devicestate, ast_cli_args::fd, FORMAT, ast_channel_tech::indicate, chanlist::tech, ast_channel_tech::transfer, ast_channel_tech::type, and ast_cli_entry::usage.

00276 {
00277 #define FORMAT  "%-10.10s  %-40.40s %-12.12s %-12.12s %-12.12s\n"
00278    struct chanlist *cl;
00279    int count_chan = 0;
00280 
00281    switch (cmd) {
00282    case CLI_INIT:
00283       e->command = "core show channeltypes";
00284       e->usage =
00285          "Usage: core show channeltypes\n"
00286          "       Lists available channel types registered in your\n"
00287          "       Asterisk server.\n";
00288       return NULL;
00289    case CLI_GENERATE:
00290       return NULL;
00291    }
00292 
00293    if (a->argc != 3)
00294       return CLI_SHOWUSAGE;
00295 
00296    ast_cli(a->fd, FORMAT, "Type", "Description",       "Devicestate", "Indications", "Transfer");
00297    ast_cli(a->fd, FORMAT, "----------", "-----------", "-----------", "-----------", "--------");
00298 
00299    AST_RWLIST_RDLOCK(&backends);
00300    AST_RWLIST_TRAVERSE(&backends, cl, list) {
00301       ast_cli(a->fd, FORMAT, cl->tech->type, cl->tech->description,
00302          (cl->tech->devicestate) ? "yes" : "no",
00303          (cl->tech->indicate) ? "yes" : "no",
00304          (cl->tech->transfer) ? "yes" : "no");
00305       count_chan++;
00306    }
00307    AST_RWLIST_UNLOCK(&backends);
00308 
00309    ast_cli(a->fd, "----------\n%d channel drivers registered.\n", count_chan);
00310 
00311    return CLI_SUCCESS;
00312 
00313 #undef FORMAT
00314 }

static int attribute_const is_visible_indication ( enum ast_control_frame_type  condition  )  [static]

Definition at line 4122 of file channel.c.

References _XXX_AST_CONTROL_T38, AST_CONTROL_ANSWER, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CC, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_END_OF_Q, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_MCID, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_READ_ACTION, AST_CONTROL_REDIRECTING, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_TRANSFER, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_CONTROL_VIDUPDATE, and AST_CONTROL_WINK.

Referenced by ast_indicate_data().

04123 {
04124    /* Don't include a default case here so that we get compiler warnings
04125     * when a new type is added. */
04126 
04127    switch (condition) {
04128    case AST_CONTROL_PROGRESS:
04129    case AST_CONTROL_PROCEEDING:
04130    case AST_CONTROL_VIDUPDATE:
04131    case AST_CONTROL_SRCUPDATE:
04132    case AST_CONTROL_SRCCHANGE:
04133    case AST_CONTROL_RADIO_KEY:
04134    case AST_CONTROL_RADIO_UNKEY:
04135    case AST_CONTROL_OPTION:
04136    case AST_CONTROL_WINK:
04137    case AST_CONTROL_FLASH:
04138    case AST_CONTROL_OFFHOOK:
04139    case AST_CONTROL_TAKEOFFHOOK:
04140    case AST_CONTROL_ANSWER:
04141    case AST_CONTROL_HANGUP:
04142    case AST_CONTROL_CONNECTED_LINE:
04143    case AST_CONTROL_REDIRECTING:
04144    case AST_CONTROL_TRANSFER:
04145    case AST_CONTROL_T38_PARAMETERS:
04146    case _XXX_AST_CONTROL_T38:
04147    case AST_CONTROL_CC:
04148    case AST_CONTROL_READ_ACTION:
04149    case AST_CONTROL_AOC:
04150    case AST_CONTROL_END_OF_Q:
04151    case AST_CONTROL_MCID:
04152    case AST_CONTROL_UPDATE_RTP_PEER:
04153       break;
04154 
04155    case AST_CONTROL_INCOMPLETE:
04156    case AST_CONTROL_CONGESTION:
04157    case AST_CONTROL_BUSY:
04158    case AST_CONTROL_RINGING:
04159    case AST_CONTROL_RING:
04160    case AST_CONTROL_HOLD:
04161       /* You can hear these */
04162       return 1;
04163 
04164    case AST_CONTROL_UNHOLD:
04165       /* This is a special case.  You stop hearing this. */
04166       break;
04167    }
04168 
04169    return 0;
04170 }

static struct ast_frame* kill_exception ( struct ast_channel chan  )  [static, read]

Definition at line 414 of file channel.c.

00415 {
00416    /* Hangup channel. */
00417    return NULL;
00418 }

static int kill_fixup ( struct ast_channel oldchan,
struct ast_channel newchan 
) [static]

Definition at line 426 of file channel.c.

00427 {
00428    /* No problem fixing up the channel. */
00429    return 0;
00430 }

static int kill_hangup ( struct ast_channel chan  )  [static]

Definition at line 432 of file channel.c.

References ast_channel::tech_pvt.

00433 {
00434    chan->tech_pvt = NULL;
00435    return 0;
00436 }

static struct ast_frame* kill_read ( struct ast_channel chan  )  [static, read]

Definition at line 408 of file channel.c.

00409 {
00410    /* Hangup channel. */
00411    return NULL;
00412 }

static int kill_write ( struct ast_channel chan,
struct ast_frame frame 
) [static]

Definition at line 420 of file channel.c.

00421 {
00422    /* Hangup channel. */
00423    return -1;
00424 }

static void manager_bridge_event ( int  onoff,
int  type,
struct ast_channel c0,
struct ast_channel c1 
) [static]

Send manager event for bridge link and unlink events.

Parameters:
onoff Link/Unlinked
type 1 for core, 2 for native
c0 first channel in bridge
c1 second channel in bridge

Definition at line 7201 of file channel.c.

References ast_channel_name(), ast_channel_uniqueid(), ast_manager_event_multichan, ast_channel::caller, EVENT_FLAG_CALL, ast_party_caller::id, ast_party_id::number, S_COR, ast_party_number::str, and ast_party_number::valid.

Referenced by ast_channel_bridge().

07202 {
07203    struct ast_channel *chans[2] = { c0, c1 };
07204    ast_manager_event_multichan(EVENT_FLAG_CALL, "Bridge", 2, chans,
07205       "Bridgestate: %s\r\n"
07206       "Bridgetype: %s\r\n"
07207       "Channel1: %s\r\n"
07208       "Channel2: %s\r\n"
07209       "Uniqueid1: %s\r\n"
07210       "Uniqueid2: %s\r\n"
07211       "CallerID1: %s\r\n"
07212       "CallerID2: %s\r\n",
07213       onoff ? "Link" : "Unlink",
07214       type == 1 ? "core" : "native",
07215       ast_channel_name(c0), ast_channel_name(c1),
07216       ast_channel_uniqueid(c0), ast_channel_uniqueid(c1),
07217       S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, ""),
07218       S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, ""));
07219 }

static void masquerade_colp_transfer ( struct ast_channel transferee,
struct xfer_masquerade_ds colp 
) [static]

Definition at line 6351 of file channel.c.

References ast_channel_queue_connected_line_update(), ast_connected_line_build_data(), AST_CONTROL_READ_ACTION, AST_CONTROL_UNHOLD, AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO, ast_queue_control(), ast_queue_control_data(), frame_size, ast_control_read_action_payload::payload_size, xfer_masquerade_ds::target_held, xfer_masquerade_ds::target_id, and xfer_masquerade_ds::transferee_id.

Referenced by ast_do_masquerade().

06352 {
06353    struct ast_control_read_action_payload *frame_payload;
06354    int payload_size;
06355    int frame_size;
06356    unsigned char connected_line_data[1024];
06357 
06358    /* Release any hold on the target. */
06359    if (colp->target_held) {
06360       ast_queue_control(transferee, AST_CONTROL_UNHOLD);
06361    }
06362 
06363    /*
06364     * Since transferee may not actually be bridged to another channel,
06365     * there is no way for us to queue a frame so that its connected
06366     * line status will be updated.  Instead, we use the somewhat
06367     * hackish approach of using a special control frame type that
06368     * instructs ast_read() to perform a specific action.  In this
06369     * case, the frame we queue tells ast_read() to call the
06370     * connected line interception macro configured for transferee.
06371     */
06372    payload_size = ast_connected_line_build_data(connected_line_data,
06373       sizeof(connected_line_data), &colp->target_id, NULL);
06374    if (payload_size != -1) {
06375       frame_size = payload_size + sizeof(*frame_payload);
06376       frame_payload = alloca(frame_size);
06377       frame_payload->action = AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO;
06378       frame_payload->payload_size = payload_size;
06379       memcpy(frame_payload->payload, connected_line_data, payload_size);
06380       ast_queue_control_data(transferee, AST_CONTROL_READ_ACTION, frame_payload,
06381          frame_size);
06382    }
06383    /*
06384     * In addition to queueing the read action frame so that the
06385     * connected line info on transferee will be updated, we also are
06386     * going to queue a plain old connected line update on transferee to
06387     * update the target.
06388     */
06389    ast_channel_queue_connected_line_update(transferee, &colp->transferee_id, NULL);
06390 }

static const char* oldest_linkedid ( const char *  a,
const char *  b 
) [static]

Definition at line 6175 of file channel.c.

References ast_strlen_zero().

Referenced by ast_channel_set_linkgroup().

06176 {
06177    const char *satime, *saseq;
06178    const char *sbtime, *sbseq;
06179    const char *dash;
06180 
06181    unsigned int atime, aseq, btime, bseq;
06182 
06183    if (ast_strlen_zero(a))
06184       return b;
06185 
06186    if (ast_strlen_zero(b))
06187       return a;
06188 
06189    satime = a;
06190    sbtime = b;
06191 
06192    /* jump over the system name */
06193    if ((dash = strrchr(satime, '-'))) {
06194       satime = dash+1;
06195    }
06196    if ((dash = strrchr(sbtime, '-'))) {
06197       sbtime = dash+1;
06198    }
06199 
06200    /* the sequence comes after the '.' */
06201    saseq = strchr(satime, '.');
06202    sbseq = strchr(sbtime, '.');
06203    if (!saseq || !sbseq)
06204       return NULL;
06205    saseq++;
06206    sbseq++;
06207 
06208    /* convert it all to integers */
06209    atime = atoi(satime); /* note that atoi is ignoring the '.' after the time string */
06210    btime = atoi(sbtime); /* note that atoi is ignoring the '.' after the time string */
06211    aseq = atoi(saseq);
06212    bseq = atoi(sbseq);
06213 
06214    /* and finally compare */
06215    if (atime == btime) {
06216       return (aseq < bseq) ? a : b;
06217    }
06218    else {
06219       return (atime < btime) ? a : b;
06220    }
06221 }

static void party_connected_line_copy_transfer ( struct ast_party_connected_line dest,
const struct ast_party_connected_line src 
) [static]

Definition at line 5982 of file channel.c.

References AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, ast_party_connected_line_copy(), and ast_party_connected_line::source.

Referenced by ast_channel_transfer_masquerade().

05983 {
05984    struct ast_party_connected_line connected;
05985 
05986    connected = *((struct ast_party_connected_line *) src);
05987    connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
05988 
05989    /* Make sure empty strings will be erased. */
05990    if (!connected.id.name.str) {
05991       connected.id.name.str = "";
05992    }
05993    if (!connected.id.number.str) {
05994       connected.id.number.str = "";
05995    }
05996    if (!connected.id.subaddress.str) {
05997       connected.id.subaddress.str = "";
05998    }
05999    if (!connected.id.tag) {
06000       connected.id.tag = "";
06001    }
06002 
06003    ast_party_connected_line_copy(dest, &connected);
06004 }

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]

Definition at line 8442 of file channel.c.

References ast_log(), ast_party_id_presentation(), ast_party_id_ies::combined_presentation, LOG_WARNING, ast_party_id_ies::name, ast_party_id::name, ast_set_party_id::name, ast_party_id_ies::number, ast_party_id::number, ast_set_party_id::number, party_name_build_data(), party_number_build_data(), party_subaddress_build_data(), ast_party_id_ies::subaddress, ast_party_id::subaddress, ast_set_party_id::subaddress, ast_party_id_ies::tag, and ast_party_id::tag.

Referenced by ast_connected_line_build_data(), and ast_redirecting_build_data().

08445 {
08446    size_t length;
08447    size_t pos = 0;
08448    int res;
08449 
08450    /*
08451     * The size of integer values must be fixed in case the frame is
08452     * shipped to another machine.
08453     */
08454 
08455    if (!update || update->name) {
08456       res = party_name_build_data(data + pos, datalen - pos, &id->name, label,
08457          &ies->name);
08458       if (res < 0) {
08459          return -1;
08460       }
08461       pos += res;
08462    }
08463 
08464    if (!update || update->number) {
08465       res = party_number_build_data(data + pos, datalen - pos, &id->number, label,
08466          &ies->number);
08467       if (res < 0) {
08468          return -1;
08469       }
08470       pos += res;
08471    }
08472 
08473    if (!update || update->subaddress) {
08474       res = party_subaddress_build_data(data + pos, datalen - pos, &id->subaddress,
08475          label, &ies->subaddress);
08476       if (res < 0) {
08477          return -1;
08478       }
08479       pos += res;
08480    }
08481 
08482    /* *************** Party id user tag **************************** */
08483    if (id->tag) {
08484       length = strlen(id->tag);
08485       if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08486          ast_log(LOG_WARNING, "No space left for %s tag\n", label);
08487          return -1;
08488       }
08489       data[pos++] = ies->tag;
08490       data[pos++] = length;
08491       memcpy(data + pos, id->tag, length);
08492       pos += length;
08493    }
08494 
08495    /* *************** Party id combined presentation *************** */
08496    if (!update || update->number) {
08497       int presentation;
08498 
08499       if (!update || update->name) {
08500          presentation = ast_party_id_presentation(id);
08501       } else {
08502          /*
08503           * We must compromise because not all the information is available
08504           * to determine a combined presentation value.
08505           * We will only send the number presentation instead.
08506           */
08507          presentation = id->number.presentation;
08508       }
08509 
08510       if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08511          ast_log(LOG_WARNING, "No space left for %s combined presentation\n", label);
08512          return -1;
08513       }
08514       data[pos++] = ies->combined_presentation;
08515       data[pos++] = 1;
08516       data[pos++] = presentation;
08517    }
08518 
08519    return pos;
08520 }

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]

Definition at line 8216 of file channel.c.

References ast_log(), ast_party_name::char_set, ast_party_name_ies::char_set, LOG_WARNING, ast_party_name::presentation, ast_party_name_ies::presentation, ast_party_name_ies::str, ast_party_name::str, ast_party_name::valid, and ast_party_name_ies::valid.

Referenced by party_id_build_data().

08217 {
08218    size_t length;
08219    size_t pos = 0;
08220 
08221    /*
08222     * The size of integer values must be fixed in case the frame is
08223     * shipped to another machine.
08224     */
08225    if (name->str) {
08226       length = strlen(name->str);
08227       if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08228          ast_log(LOG_WARNING, "No space left for %s name\n", label);
08229          return -1;
08230       }
08231       data[pos++] = ies->str;
08232       data[pos++] = length;
08233       memcpy(data + pos, name->str, length);
08234       pos += length;
08235    }
08236 
08237    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08238       ast_log(LOG_WARNING, "No space left for %s name char set\n", label);
08239       return -1;
08240    }
08241    data[pos++] = ies->char_set;
08242    data[pos++] = 1;
08243    data[pos++] = name->char_set;
08244 
08245    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08246       ast_log(LOG_WARNING, "No space left for %s name presentation\n", label);
08247       return -1;
08248    }
08249    data[pos++] = ies->presentation;
08250    data[pos++] = 1;
08251    data[pos++] = name->presentation;
08252 
08253    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08254       ast_log(LOG_WARNING, "No space left for %s name valid\n", label);
08255       return -1;
08256    }
08257    data[pos++] = ies->valid;
08258    data[pos++] = 1;
08259    data[pos++] = name->valid;
08260 
08261    return pos;
08262 }

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]

Definition at line 8290 of file channel.c.

References ast_log(), LOG_WARNING, ast_party_number::plan, ast_party_number_ies::plan, ast_party_number::presentation, ast_party_number_ies::presentation, ast_party_number_ies::str, ast_party_number::str, ast_party_number::valid, and ast_party_number_ies::valid.

Referenced by party_id_build_data().

08291 {
08292    size_t length;
08293    size_t pos = 0;
08294 
08295    /*
08296     * The size of integer values must be fixed in case the frame is
08297     * shipped to another machine.
08298     */
08299    if (number->str) {
08300       length = strlen(number->str);
08301       if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08302          ast_log(LOG_WARNING, "No space left for %s number\n", label);
08303          return -1;
08304       }
08305       data[pos++] = ies->str;
08306       data[pos++] = length;
08307       memcpy(data + pos, number->str, length);
08308       pos += length;
08309    }
08310 
08311    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08312       ast_log(LOG_WARNING, "No space left for %s numbering plan\n", label);
08313       return -1;
08314    }
08315    data[pos++] = ies->plan;
08316    data[pos++] = 1;
08317    data[pos++] = number->plan;
08318 
08319    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08320       ast_log(LOG_WARNING, "No space left for %s number presentation\n", label);
08321       return -1;
08322    }
08323    data[pos++] = ies->presentation;
08324    data[pos++] = 1;
08325    data[pos++] = number->presentation;
08326 
08327    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08328       ast_log(LOG_WARNING, "No space left for %s number valid\n", label);
08329       return -1;
08330    }
08331    data[pos++] = ies->valid;
08332    data[pos++] = 1;
08333    data[pos++] = number->valid;
08334 
08335    return pos;
08336 }

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]

Definition at line 8364 of file channel.c.

References ast_log(), LOG_WARNING, ast_party_subaddress::odd_even_indicator, ast_party_subaddress_ies::odd_even_indicator, ast_party_subaddress_ies::str, ast_party_subaddress::str, ast_party_subaddress::type, ast_party_subaddress_ies::type, ast_party_subaddress::valid, and ast_party_subaddress_ies::valid.

Referenced by party_id_build_data().

08365 {
08366    size_t length;
08367    size_t pos = 0;
08368 
08369    /*
08370     * The size of integer values must be fixed in case the frame is
08371     * shipped to another machine.
08372     */
08373    if (subaddress->str) {
08374       length = strlen(subaddress->str);
08375       if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08376          ast_log(LOG_WARNING, "No space left for %s subaddress\n", label);
08377          return -1;
08378       }
08379       data[pos++] = ies->str;
08380       data[pos++] = length;
08381       memcpy(data + pos, subaddress->str, length);
08382       pos += length;
08383    }
08384 
08385    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08386       ast_log(LOG_WARNING, "No space left for %s type of subaddress\n", label);
08387       return -1;
08388    }
08389    data[pos++] = ies->type;
08390    data[pos++] = 1;
08391    data[pos++] = subaddress->type;
08392 
08393    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08394       ast_log(LOG_WARNING,
08395          "No space left for %s subaddress odd-even indicator\n", label);
08396       return -1;
08397    }
08398    data[pos++] = ies->odd_even_indicator;
08399    data[pos++] = 1;
08400    data[pos++] = subaddress->odd_even_indicator;
08401 
08402    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08403       ast_log(LOG_WARNING, "No space left for %s subaddress valid\n", label);
08404       return -1;
08405    }
08406    data[pos++] = ies->valid;
08407    data[pos++] = 1;
08408    data[pos++] = subaddress->valid;
08409 
08410    return pos;
08411 }

static void plc_ds_destroy ( void *  data  )  [static]

Definition at line 4553 of file channel.c.

References ast_free, and plc_ds::samples_buf.

04554 {
04555    struct plc_ds *plc = data;
04556    ast_free(plc->samples_buf);
04557    ast_free(plc);
04558 }

static void queue_dtmf_readq ( struct ast_channel chan,
struct ast_frame f 
) [inline, static]

Definition at line 3510 of file channel.c.

References AST_FRAME_DTMF_END, ast_queue_frame(), ast_channel::dtmff, ast_frame::frametype, ast_frame_subclass::integer, ast_frame::len, and ast_frame::subclass.

Referenced by __ast_read().

03511 {
03512    struct ast_frame *fr = &chan->dtmff;
03513 
03514    fr->frametype = AST_FRAME_DTMF_END;
03515    fr->subclass.integer = f->subclass.integer;
03516    fr->len = f->len;
03517 
03518    /* The only time this function will be called is for a frame that just came
03519     * out of the channel driver.  So, we want to stick it on the tail of the
03520     * readq. */
03521 
03522    ast_queue_frame(chan, fr);
03523 }

static void report_new_callerid ( struct ast_channel chan  )  [static]

Precondition:
chan is locked

Definition at line 6321 of file channel.c.

References ast_channel_name(), ast_channel_uniqueid(), ast_describe_caller_presentation(), ast_manager_event, ast_party_id_presentation(), ast_channel::caller, EVENT_FLAG_CALL, ast_party_caller::id, ast_party_id::name, ast_party_id::number, S_COR, ast_party_name::str, ast_party_number::str, ast_party_name::valid, and ast_party_number::valid.

Referenced by ast_channel_set_caller_event(), ast_do_masquerade(), and ast_set_callerid().

06322 {
06323    int pres;
06324 
06325    pres = ast_party_id_presentation(&chan->caller.id);
06326    ast_manager_event(chan, EVENT_FLAG_CALL, "NewCallerid",
06327       "Channel: %s\r\n"
06328       "CallerIDNum: %s\r\n"
06329       "CallerIDName: %s\r\n"
06330       "Uniqueid: %s\r\n"
06331       "CID-CallingPres: %d (%s)\r\n",
06332       ast_channel_name(chan),
06333       S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
06334       S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""),
06335       ast_channel_uniqueid(chan),
06336       pres,
06337       ast_describe_caller_presentation(pres)
06338       );
06339 }

static void send_dtmf_event ( struct ast_channel chan,
const char *  direction,
const char  digit,
const char *  begin,
const char *  end 
) [static]

Definition at line 3449 of file channel.c.

References ast_channel_name(), ast_channel_uniqueid(), ast_manager_event, and EVENT_FLAG_DTMF.

Referenced by __ast_read(), and ast_write().

03450 {
03451    ast_manager_event(chan, EVENT_FLAG_DTMF,
03452          "DTMF",
03453          "Channel: %s\r\n"
03454          "Uniqueid: %s\r\n"
03455          "Digit: %c\r\n"
03456          "Direction: %s\r\n"
03457          "Begin: %s\r\n"
03458          "End: %s\r\n",
03459          ast_channel_name(chan), ast_channel_uniqueid(chan), digit, direction, begin, end);
03460 }

static int set_format ( struct ast_channel chan,
struct ast_format_cap cap_set,
struct ast_format rawformat,
struct ast_format format,
struct ast_trans_pvt **  trans,
const int  direction 
) [static]

Definition at line 4948 of file channel.c.

References ast_best_codec(), ast_channel_lock, ast_channel_name(), ast_channel_setoption(), ast_channel_unlock, ast_debug, ast_format_cap_set(), ast_format_cmp(), AST_FORMAT_CMP_NOT_EQUAL, ast_format_copy(), ast_getformatname(), ast_getformatname_multiple(), ast_log(), AST_OPTION_FORMAT_READ, AST_OPTION_FORMAT_WRITE, ast_translator_best_choice(), ast_translator_build_path(), ast_translator_free_path(), generator_write_format_change(), ast_channel::generatordata, LOG_WARNING, and ast_channel::nativeformats.

Referenced by ast_set_read_format(), ast_set_read_format_by_id(), ast_set_read_format_from_cap(), ast_set_write_format(), ast_set_write_format_by_id(), and ast_set_write_format_from_cap().

04954 {
04955    struct ast_format_cap *cap_native = chan->nativeformats;
04956    struct ast_format best_set_fmt;
04957    struct ast_format best_native_fmt;
04958    int res;
04959    char from[200], to[200];
04960 
04961    ast_best_codec(cap_set, &best_set_fmt);
04962 
04963    /* See if the underlying channel driver is capable of performing transcoding for us */
04964    if (!ast_channel_setoption(chan, direction ? AST_OPTION_FORMAT_WRITE : AST_OPTION_FORMAT_READ, &best_set_fmt, sizeof(best_set_fmt), 0)) {
04965       ast_debug(1, "Channel driver natively set channel %s to %s format %s\n", ast_channel_name(chan),
04966            direction ? "write" : "read", ast_getformatname(&best_set_fmt));
04967 
04968       ast_channel_lock(chan);
04969       ast_format_copy(format, &best_set_fmt);
04970       ast_format_copy(rawformat, &best_set_fmt);
04971       ast_format_cap_set(chan->nativeformats, &best_set_fmt);
04972       ast_channel_unlock(chan);
04973 
04974       if (*trans) {
04975          ast_translator_free_path(*trans);
04976       }
04977       *trans = NULL;
04978       /* If there is a generator on the channel, it needs to know about this
04979        * change if it is the write format. */
04980       if (direction && chan->generatordata) {
04981          generator_write_format_change(chan);
04982       }
04983       return 0;
04984    }
04985 
04986    /* Find a translation path from the native format to one of the desired formats */
04987    if (!direction) {
04988       /* reading */
04989       res = ast_translator_best_choice(cap_set, cap_native, &best_set_fmt, &best_native_fmt);
04990    } else {
04991       /* writing */
04992       res = ast_translator_best_choice(cap_native, cap_set, &best_native_fmt, &best_set_fmt);
04993    }
04994 
04995    if (res < 0) {
04996       ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n",
04997          ast_getformatname_multiple(from, sizeof(from), cap_native),
04998          ast_getformatname_multiple(to, sizeof(to), cap_set));
04999       return -1;
05000    }
05001 
05002    /* Now we have a good choice for both. */
05003    ast_channel_lock(chan);
05004 
05005    if ((ast_format_cmp(rawformat, &best_native_fmt) != AST_FORMAT_CMP_NOT_EQUAL) &&
05006       (ast_format_cmp(format, &best_set_fmt) != AST_FORMAT_CMP_NOT_EQUAL) &&
05007       ((ast_format_cmp(rawformat, format) != AST_FORMAT_CMP_NOT_EQUAL) || (*trans))) {
05008       /* the channel is already in these formats, so nothing to do */
05009       ast_channel_unlock(chan);
05010       return 0;
05011    }
05012 
05013    ast_format_copy(rawformat, &best_native_fmt);
05014    /* User perspective is fmt */
05015    ast_format_copy(format, &best_set_fmt);
05016 
05017    /* Free any read translation we have right now */
05018    if (*trans) {
05019       ast_translator_free_path(*trans);
05020       *trans = NULL;
05021    }
05022 
05023    /* Build a translation path from the raw format to the desired format */
05024    if (ast_format_cmp(format, rawformat) != AST_FORMAT_CMP_NOT_EQUAL) {
05025       /*
05026        * If we were able to swap the native format to the format that
05027        * has been requested, then there is no need to try to build
05028        * a translation path.
05029        */
05030       res = 0;
05031    } else {
05032       if (!direction) {
05033          /* reading */
05034          *trans = ast_translator_build_path(format, rawformat);
05035       } else {
05036          /* writing */
05037          *trans = ast_translator_build_path(rawformat, format);
05038       }
05039       res = *trans ? 0 : -1;
05040    }
05041    ast_channel_unlock(chan);
05042 
05043    ast_debug(1, "Set channel %s to %s format %s\n",
05044       ast_channel_name(chan),
05045       direction ? "write" : "read",
05046       ast_getformatname(&best_set_fmt));
05047    
05048    /* If there is a generator on the channel, it needs to know about this
05049     * change if it is the write format. */
05050    if (direction && chan->generatordata) {
05051       generator_write_format_change(chan);
05052    }
05053    return res;
05054 }

static int set_security_requirements ( const struct ast_channel requestor,
struct ast_channel out 
) [static]

Definition at line 5489 of file channel.c.

References ast_channel_datastore_find(), ast_channel_lock, ast_channel_setoption(), ast_channel_unlock, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, ast_datastore::data, ast_secure_call_store::media, secure_call_info, and ast_secure_call_store::signaling.

Referenced by ast_request().

05490 {
05491    int ops[2][2] = {
05492       {AST_OPTION_SECURE_SIGNALING, 0},
05493       {AST_OPTION_SECURE_MEDIA, 0},
05494    };
05495    int i;
05496    struct ast_channel *r = (struct ast_channel *) requestor; /* UGLY */
05497    struct ast_datastore *ds;
05498 
05499    if (!requestor || !out) {
05500       return 0;
05501    }
05502 
05503    ast_channel_lock(r);
05504    if ((ds = ast_channel_datastore_find(r, &secure_call_info, NULL))) {
05505       struct ast_secure_call_store *encrypt = ds->data;
05506       ops[0][1] = encrypt->signaling;
05507       ops[1][1] = encrypt->media;
05508    } else {
05509       ast_channel_unlock(r);
05510       return 0;
05511    }
05512    ast_channel_unlock(r);
05513 
05514    for (i = 0; i < 2; i++) {
05515       if (ops[i][1]) {
05516          if (ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0)) {
05517             /* We require a security feature, but the channel won't provide it */
05518             return -1;
05519          }
05520       } else {
05521          /* We don't care if we can't clear the option on a channel that doesn't support it */
05522          ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0);
05523       }
05524    }
05525 
05526    return 0;
05527 }

static int should_skip_dtmf ( struct ast_channel chan  )  [inline, static]

Determine whether or not we should ignore DTMF in the readq.

Definition at line 3528 of file channel.c.

References AST_FLAG_DEFER_DTMF, AST_FLAG_EMULATE_DTMF, AST_MIN_DTMF_GAP, ast_test_flag, ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), and ast_channel::dtmf_tv.

Referenced by __ast_read().

03529 {
03530    if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF)) {
03531       /* We're in the middle of emulating a digit, or DTMF has been
03532        * explicitly deferred.  Skip this digit, then. */
03533       return 1;
03534    }
03535          
03536    if (!ast_tvzero(chan->dtmf_tv) && 
03537          ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) {
03538       /* We're not in the middle of a digit, but it hasn't been long enough
03539        * since the last digit, so we'll have to skip DTMF for now. */
03540       return 1;
03541    }
03542 
03543    return 0;
03544 }

static void* silence_generator_alloc ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 8012 of file channel.c.

08013 {
08014    /* just store the data pointer in the channel structure */
08015    return data;
08016 }

static int silence_generator_generate ( struct ast_channel chan,
void *  data,
int  len,
int  samples 
) [static]

Definition at line 8023 of file channel.c.

References ast_format_set(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_write(), ast_frame_subclass::format, ast_frame::frametype, and ast_frame::subclass.

08024 {
08025    short buf[samples];
08026    struct ast_frame frame = {
08027       .frametype = AST_FRAME_VOICE,
08028       .data.ptr = buf,
08029       .samples = samples,
08030       .datalen = sizeof(buf),
08031    };
08032    ast_format_set(&frame.subclass.format, AST_FORMAT_SLINEAR, 0);
08033 
08034    memset(buf, 0, sizeof(buf));
08035 
08036    if (ast_write(chan, &frame))
08037       return -1;
08038 
08039    return 0;
08040 }

static void silence_generator_release ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 8018 of file channel.c.

08019 {
08020    /* nothing to do */
08021 }

static void* tonepair_alloc ( struct ast_channel chan,
void *  params 
) [static]

Definition at line 7624 of file channel.c.

References ast_calloc, ast_channel_name(), AST_FLAG_WRITE_INT, ast_format_copy(), AST_FORMAT_SLINEAR, ast_log(), ast_set_flag, ast_set_write_format_by_id(), cos, tonepair_def::duration, tonepair_state::duration, tonepair_state::fac1, tonepair_state::fac2, tonepair_def::freq1, tonepair_def::freq2, LOG_WARNING, M_PI, tonepair_state::modulate, tonepair_state::origwfmt, tonepair_release(), tonepair_state::v1_1, tonepair_state::v2_1, tonepair_state::v2_2, tonepair_state::v3_1, tonepair_state::v3_2, tonepair_def::vol, and ast_channel::writeformat.

07625 {
07626    struct tonepair_state *ts;
07627    struct tonepair_def *td = params;
07628 
07629    if (!(ts = ast_calloc(1, sizeof(*ts))))
07630       return NULL;
07631    ast_format_copy(&ts->origwfmt, &chan->writeformat);
07632    if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR)) {
07633       ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", ast_channel_name(chan));
07634       tonepair_release(NULL, ts);
07635       ts = NULL;
07636    } else {
07637       ts->fac1 = 2.0 * cos(2.0 * M_PI * (td->freq1 / 8000.0)) * 32768.0;
07638       ts->v1_1 = 0;
07639       ts->v2_1 = sin(-4.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
07640       ts->v3_1 = sin(-2.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
07641       ts->v2_1 = 0;
07642       ts->fac2 = 2.0 * cos(2.0 * M_PI * (td->freq2 / 8000.0)) * 32768.0;
07643       ts->v2_2 = sin(-4.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
07644       ts->v3_2 = sin(-2.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
07645       ts->duration = td->duration;
07646       ts->modulate = 0;
07647    }
07648    /* Let interrupts interrupt :) */
07649    ast_set_flag(chan, AST_FLAG_WRITE_INT);
07650    return ts;
07651 }

static int tonepair_generator ( struct ast_channel chan,
void *  data,
int  len,
int  samples 
) [static]

Definition at line 7653 of file channel.c.

References ast_format_set(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_write(), ast_frame::data, tonepair_state::data, ast_frame::datalen, tonepair_state::duration, tonepair_state::f, tonepair_state::fac1, tonepair_state::fac2, ast_frame_subclass::format, ast_frame::frametype, LOG_WARNING, tonepair_state::modulate, ast_frame::offset, tonepair_state::pos, ast_frame::ptr, ast_frame::samples, ast_frame::subclass, tonepair_state::v1_1, tonepair_state::v1_2, tonepair_state::v2_1, tonepair_state::v2_2, tonepair_state::v3_1, and tonepair_state::v3_2.

07654 {
07655    struct tonepair_state *ts = data;
07656    int x;
07657 
07658    /* we need to prepare a frame with 16 * timelen samples as we're
07659     * generating SLIN audio
07660     */
07661    len = samples * 2;
07662 
07663    if (len > sizeof(ts->data) / 2 - 1) {
07664       ast_log(LOG_WARNING, "Can't generate that much data!\n");
07665       return -1;
07666    }
07667    memset(&ts->f, 0, sizeof(ts->f));
07668    for (x=0;x<len/2;x++) {
07669       ts->v1_1 = ts->v2_1;
07670       ts->v2_1 = ts->v3_1;
07671       ts->v3_1 = (ts->fac1 * ts->v2_1 >> 15) - ts->v1_1;
07672       
07673       ts->v1_2 = ts->v2_2;
07674       ts->v2_2 = ts->v3_2;
07675       ts->v3_2 = (ts->fac2 * ts->v2_2 >> 15) - ts->v1_2;
07676       if (ts->modulate) {
07677          int p;
07678          p = ts->v3_2 - 32768;
07679          if (p < 0) p = -p;
07680          p = ((p * 9) / 10) + 1;
07681          ts->data[x] = (ts->v3_1 * p) >> 15;
07682       } else
07683          ts->data[x] = ts->v3_1 + ts->v3_2; 
07684    }
07685    ts->f.frametype = AST_FRAME_VOICE;
07686    ast_format_set(&ts->f.subclass.format, AST_FORMAT_SLINEAR, 0);
07687    ts->f.datalen = len;
07688    ts->f.samples = samples;
07689    ts->f.offset = AST_FRIENDLY_OFFSET;
07690    ts->f.data.ptr = ts->data;
07691    ast_write(chan, &ts->f);
07692    ts->pos += x;
07693    if (ts->duration > 0) {
07694       if (ts->pos >= ts->duration * 8)
07695          return -1;
07696    }
07697    return 0;
07698 }

static void tonepair_release ( struct ast_channel chan,
void *  params 
) [static]

Definition at line 7615 of file channel.c.

References ast_free, ast_set_write_format(), and tonepair_state::origwfmt.

Referenced by tonepair_alloc().

07616 {
07617    struct tonepair_state *ts = params;
07618 
07619    if (chan)
07620       ast_set_write_format(chan, &ts->origwfmt);
07621    ast_free(ts);
07622 }

static void update_bridge_vars ( struct ast_channel c0,
struct ast_channel c1 
) [static]

Definition at line 7221 of file channel.c.

References ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_strdupa, ast_strlen_zero(), ast_channel_tech::get_pvt_uniqueid, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and ast_channel::tech.

Referenced by ast_channel_bridge().

07222 {
07223    const char *c0_name;
07224    const char *c1_name;
07225    const char *c0_pvtid = NULL;
07226    const char *c1_pvtid = NULL;
07227 
07228    ast_channel_lock(c1);
07229    c1_name = ast_strdupa(ast_channel_name(c1));
07230    if (c1->tech->get_pvt_uniqueid) {
07231       c1_pvtid = ast_strdupa(c1->tech->get_pvt_uniqueid(c1));
07232    }
07233    ast_channel_unlock(c1);
07234 
07235    ast_channel_lock(c0);
07236    if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER"))) {
07237       pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1_name);
07238    }
07239    if (c1_pvtid) {
07240       pbx_builtin_setvar_helper(c0, "BRIDGEPVTCALLID", c1_pvtid);
07241    }
07242    c0_name = ast_strdupa(ast_channel_name(c0));
07243    if (c0->tech->get_pvt_uniqueid) {
07244       c0_pvtid = ast_strdupa(c0->tech->get_pvt_uniqueid(c0));
07245    }
07246    ast_channel_unlock(c0);
07247 
07248    ast_channel_lock(c1);
07249    if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER"))) {
07250       pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0_name);
07251    }
07252    if (c0_pvtid) {
07253       pbx_builtin_setvar_helper(c1, "BRIDGEPVTCALLID", c0_pvtid);
07254    }
07255    ast_channel_unlock(c1);
07256 }

static void xfer_ds_destroy ( void *  data  )  [static]


Variable Documentation

Kill the channel channel driver technology descriptor.

The purpose of this channel technology is to encourage the channel to hangup as quickly as possible.

Note:
Used by DTMF atxfer and zombie channels.

Definition at line 447 of file channel.c.

Referenced by ast_do_masquerade().

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]

int cause

struct { ... } causes[] [static]

map AST_CAUSE's to readable string representations

causes.h

Referenced by ast_cause2str(), ast_str2cause(), and dump_cause().

Initial value:

 {
   .type = "Call Completion",
   .duplicate = channel_cc_params_copy,
   .destroy = channel_cc_params_destroy,
}

Definition at line 9434 of file channel.c.

struct ast_data_entry channel_providers[] [static]

Initial value:

 {
   AST_DATA_ENTRY("/asterisk/core/channels", &channels_provider),
   AST_DATA_ENTRY("/asterisk/core/channeltypes", &channeltypes_provider),
}

Definition at line 7961 of file channel.c.

struct ao2_container* channels [static]

All active channels on the system.

Definition at line 145 of file channel.c.

Initial value:

Definition at line 7947 of file channel.c.

Initial value:

Definition at line 7956 of file channel.c.

struct ast_cli_entry cli_channel[] [static]

Initial value:

 {
   AST_CLI_DEFINE(handle_cli_core_show_channeltypes, "List available channel types"),
   AST_CLI_DEFINE(handle_cli_core_show_channeltype,  "Give more details on that channel type")
}

Definition at line 403 of file channel.c.

Referenced by ast_channels_init().

const char* desc

Definition at line 154 of file channel.c.

unsigned long global_fin

The current value of the debug flags is stored in the two variables global_fin and global_fout (declared in main/channel.c)

Definition at line 97 of file channel.c.

Referenced by handle_core_set_debug_channel().

unsigned long global_fout

Definition at line 97 of file channel.c.

Referenced by handle_core_set_debug_channel().

const char* name

Definition at line 153 of file channel.c.

struct ast_channel_tech null_tech [static]

Initial value:

 {
   .type = "NULL",
   .description = "Null channel (should not see this)",
}

Definition at line 903 of file channel.c.

Referenced by __ast_channel_alloc_ap(), and do_notify().

Initial value:

 {
   .type = "plc",
   .destroy = plc_ds_destroy,
}

Definition at line 4560 of file channel.c.

int shutting_down [static]

Prevent new channel allocation if shutting down.

Definition at line 93 of file channel.c.

Initial value:

Definition at line 8042 of file channel.c.

struct ast_threadstorage state2str_threadbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_state2str_threadbuf , .custom_init = NULL , } [static]

Definition at line 99 of file channel.c.

Referenced by ast_state2str().

struct ast_generator tonepair [static]

Initial value:

 {
   alloc: tonepair_alloc,
   release: tonepair_release,
   generate: tonepair_generator,
}

Definition at line 7700 of file channel.c.

int uniqueint [static]

Definition at line 95 of file channel.c.

Initial value:

 {
   .type = "xfer_colp",
   .destroy = xfer_ds_destroy,
}

Definition at line 6036 of file channel.c.


Generated on Fri Feb 10 06:35:41 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6