Mon Oct 8 12:39:19 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"

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 DATA_EXPORT_CHANNEL(MEMBER)
#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.
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 ap1, va_list ap2)
 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)
ast_channel__ast_request_and_dial (const char *type, format_t format, const struct ast_channel *requestor, void *data, 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 __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)
format_t ast_best_codec (format_t fmts)
 Pick the best audio codec.
ast_channelast_bridged_channel (struct ast_channel *chan)
 Find bridged channel.
int ast_call (struct ast_channel *chan, char *addr, int timeout)
 Make a call.
ast_channelast_call_forward (struct ast_channel *caller, struct ast_channel *orig, int *timeout, format_t format, 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 cause code.
void ast_change_name (struct ast_channel *chan, const char *newname)
 Change channel name.
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.
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 the settings of when to hang a channel up.
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_data_add_structure (struct ast_data *tree, struct ast_channel *chan, int add_bridged)
 Insert into an astdata tree, the channel structure.
int ast_channel_data_cmp_structure (const struct ast_data_search *tree, struct ast_channel *chan, const char *structure_name)
 Compare to channel structures using the data api.
int ast_channel_datastore_add (struct ast_channel *chan, struct ast_datastore *datastore)
 Add a datastore to a channel.
ast_datastoreast_channel_datastore_alloc (const const struct ast_datastore_info *info, const char *uid)
ast_datastoreast_channel_datastore_find (struct ast_channel *chan, const const struct ast_datastore_info *info, const char *uid)
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)
 Defers DTMF so that you only read things like hangups and audio.
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).
ast_channelast_channel_get_by_exten (const char *exten, const char *context)
 Find a channel by extension and context.
ast_channelast_channel_get_by_name (const char *name)
 Find a channel by name.
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.
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 struct ast_channelast_channel_get_full (const char *name, size_t name_len, const char *exten, const char *context)
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.
ast_channel_iteratorast_channel_iterator_all_new (void)
 Create a new channel iterator.
ast_channel_iteratorast_channel_iterator_by_exten_new (const char *exten, const char *context)
 Create a new channel iterator based on extension.
ast_channel_iteratorast_channel_iterator_by_name_new (const char *name, size_t name_len)
 Create a new channel iterator based on name.
ast_channel_iteratorast_channel_iterator_destroy (struct ast_channel_iterator *i)
 Destroy a channel iterator.
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 channel technology (a new channel driver) Called by a channel module to register the kind of channels it supports.
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 linked id between chan and peer
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 hang a channel up.
static int ast_channel_softhangup_cb (void *obj, void *arg, int flags)
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_unregister (const struct ast_channel_tech *tech)
 Unregister a channel technology.
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)
ast_variableast_channeltype_list (void)
 return an ast_variable list of channeltypes
int ast_check_hangup (struct ast_channel *chan)
 Check 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.
 AST_DATA_STRUCTURE (ast_channel, DATA_EXPORT_CHANNEL)
void ast_deactivate_generator (struct ast_channel *chan)
int ast_do_masquerade (struct ast_channel *original)
 Start masquerading a channel.
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)
ast_channel_techast_get_channel_tech (const char *name)
 Get a channel technology structure by name.
ast_group_t ast_get_group (const char *s)
int ast_hangup (struct ast_channel *chan)
 Hang up 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- and pickup groups into buffer
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 with payload.
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.
int ast_queue_hangup_with_cause (struct ast_channel *chan, int cause)
 Queue a hangup frame with hangupcause set.
int ast_raw_answer (struct ast_channel *chan, int cdr_answer)
 Answer a channel.
ast_frameast_read (struct ast_channel *chan)
 Reads a frame.
static void ast_read_generator_actions (struct ast_channel *chan, struct ast_frame *f)
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.
ast_channelast_request (const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
 Requests a channel.
ast_channelast_request_and_dial (const char *type, format_t format, const struct ast_channel *requestor, void *data, 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 for a specified amount of time, looking for hangups.
int ast_safe_sleep_conditional (struct ast_channel *chan, int ms, int(*cond)(void *), void *data)
 Wait for a specified amount of time, looking for hangups and a condition argument.
int ast_say_character_str (struct ast_channel *chan, const char *str, const char *ints, const char *lang)
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)
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, format_t fmt)
 Sets read format on channel chan 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, format_t fmt)
 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 up a channel.
int ast_softhangup_nolock (struct ast_channel *chan, int cause)
 Softly hangup up a channel (no channel 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 the string form of a cause code to a 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 channel (if supported).
char * ast_transfercapability2str (int transfercapability)
 Gives the string form of a given transfer capability.
int ast_undestroyed_channels (void)
void ast_uninstall_music_functions (void)
int ast_waitfor (struct ast_channel *c, int ms)
 Wait for input on a channel.
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)
 Waits for input on an fd.
ast_channelast_waitfor_nandfds (struct ast_channel **c, int n, int *fds, int nfds, int *exception, int *outfd, int *ms)
 Waits for activity on a group of channels.
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)
static void channel_data_add_flags (struct ast_data *tree, struct ast_channel *chan)
static struct ast_channel_iteratorchannel_iterator_search (const char *name, size_t name_len, const char *exten, const char *context)
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 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, format_t fmt, format_t *rawformat, format_t *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

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 const struct ast_datastore_info cc_channel_datastore_info
static int chancount
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 const 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 109 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 112 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 116 of file channel.c.

Referenced by __ast_read(), and should_skip_dtmf().

#define DATA_EXPORT_CHANNEL ( MEMBER   ) 

Definition at line 162 of file channel.c.

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

#define NUM_CHANNEL_BUCKETS   1567

Definition at line 146 of file channel.c.

Referenced by ast_channels_init().

#define STATE2STR_BUFSIZE   32

Definition at line 105 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 8584 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 8905 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 2949 of file channel.c.

References ast_channel::_state, ast_channel_lock, 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(), chanlist::chan, errno, frames, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, MAX, ast_channel::name, and ast_frame::subclass.

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

02950 {
02951    int res = 0;
02952    enum ast_channel_state old_state;
02953 
02954    old_state = chan->_state;
02955    if ((res = ast_raw_answer(chan, cdr_answer))) {
02956       return res;
02957    }
02958 
02959    switch (old_state) {
02960    case AST_STATE_RINGING:
02961    case AST_STATE_RING:
02962       /* wait for media to start flowing, but don't wait any longer
02963        * than 'delay' or 500 milliseconds, whichever is longer
02964        */
02965       do {
02966          AST_LIST_HEAD_NOLOCK(, ast_frame) frames;
02967          struct ast_frame *cur, *new;
02968          int ms = MAX(delay, 500);
02969          unsigned int done = 0;
02970 
02971          AST_LIST_HEAD_INIT_NOLOCK(&frames);
02972 
02973          for (;;) {
02974             ms = ast_waitfor(chan, ms);
02975             if (ms < 0) {
02976                ast_log(LOG_WARNING, "Error condition occurred when polling channel %s for a voice frame: %s\n", chan->name, strerror(errno));
02977                res = -1;
02978                break;
02979             }
02980             if (ms == 0) {
02981                ast_debug(2, "Didn't receive a media frame from %s within %d ms of answering. Continuing anyway\n", chan->name, MAX(delay, 500));
02982                break;
02983             }
02984             cur = ast_read(chan);
02985             if (!cur || ((cur->frametype == AST_FRAME_CONTROL) &&
02986                     (cur->subclass.integer == AST_CONTROL_HANGUP))) {
02987                if (cur) {
02988                   ast_frfree(cur);
02989                }
02990                res = -1;
02991                ast_debug(2, "Hangup of channel %s detected in answer routine\n", chan->name);
02992                break;
02993             }
02994 
02995             if ((new = ast_frisolate(cur)) != cur) {
02996                ast_frfree(cur);
02997             }
02998 
02999             AST_LIST_INSERT_HEAD(&frames, new, frame_list);
03000 
03001             /* if a specific delay period was requested, continue
03002              * until that delay has passed. don't stop just because
03003              * incoming media has arrived.
03004              */
03005             if (delay) {
03006                continue;
03007             }
03008 
03009             switch (new->frametype) {
03010                /* all of these frametypes qualify as 'media' */
03011             case AST_FRAME_VOICE:
03012             case AST_FRAME_VIDEO:
03013             case AST_FRAME_TEXT:
03014             case AST_FRAME_DTMF_BEGIN:
03015             case AST_FRAME_DTMF_END:
03016             case AST_FRAME_IMAGE:
03017             case AST_FRAME_HTML:
03018             case AST_FRAME_MODEM:
03019                done = 1;
03020                break;
03021             case AST_FRAME_CONTROL:
03022             case AST_FRAME_IAX:
03023             case AST_FRAME_NULL:
03024             case AST_FRAME_CNG:
03025                break;
03026             }
03027 
03028             if (done) {
03029                break;
03030             }
03031          }
03032 
03033          if (res == 0) {
03034             ast_channel_lock(chan);
03035             while ((cur = AST_LIST_REMOVE_HEAD(&frames, frame_list))) {
03036                ast_queue_frame_head(chan, cur);
03037                ast_frfree(cur);
03038             }
03039             ast_channel_unlock(chan);
03040          }
03041       } while (0);
03042       break;
03043    default:
03044       break;
03045    }
03046 
03047    return res;
03048 }

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

References ast_manager_event, ast_string_field_set, chanlist::chan, EVENT_FLAG_CALL, name, ast_channel::name, and ast_channel::uniqueid.

Referenced by ast_change_name(), and ast_do_masquerade().

06108 {
06109    ast_manager_event(chan, EVENT_FLAG_CALL, "Rename", "Channel: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", chan->name, newname, chan->uniqueid);
06110    ast_string_field_set(chan, name, newname);
06111 }

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.

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

References __ast_channel_alloc_ap().

01361 {
01362    va_list ap1, ap2;
01363    struct ast_channel *result;
01364 
01365    va_start(ap1, name_fmt);
01366    va_start(ap2, name_fmt);
01367    result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context,
01368                linkedid, amaflag, file, line, function, name_fmt, ap1, ap2);
01369    va_end(ap1);
01370    va_end(ap2);
01371 
01372    return result;
01373 }

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  ap1,
va_list  ap2 
) [static]

Create a new channel structure.

Definition at line 1119 of file channel.c.

References __ao2_alloc_debug(), accountcode, ao2_alloc, ao2_link, 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_destructor(), ast_channel_set_fd(), ast_channel_unref, ast_config_AST_SYSTEM_NAME, ast_copy_string(), ast_default_accountcode, ast_default_amaflags, 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_state2str(), ast_strdup, ast_strdupa, ast_string_field_build, ast_string_field_build_va, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_timer_fd(), ast_timer_get_name(), ast_timer_open(), AST_TIMING_FD, channels, defaultlanguage, errno, EVENT_FLAG_CALL, chanlist::flags, language, LOG_WARNING, name, null_tech, S_OR, sched_context_create(), and chanlist::tech.

Referenced by __ast_channel_alloc(), and ast_channel_alloc().

01123 {
01124    struct ast_channel *tmp;
01125    int x;
01126    int flags;
01127    struct varshead *headp;
01128    char *tech = "", *tech2 = NULL;
01129 
01130    /* If shutting down, don't allocate any new channels */
01131    if (shutting_down) {
01132       ast_log(LOG_WARNING, "Channel allocation failed: Refusing due to active shutdown\n");
01133       return NULL;
01134    }
01135 
01136 #if defined(REF_DEBUG)
01137    tmp = __ao2_alloc_debug(sizeof(*tmp), ast_channel_destructor, "", file, line,
01138       function, 1);
01139 #elif defined(__AST_DEBUG_MALLOC)
01140    tmp = __ao2_alloc_debug(sizeof(*tmp), ast_channel_destructor, "", file, line,
01141       function, 0);
01142 #else
01143    tmp = ao2_alloc(sizeof(*tmp), ast_channel_destructor);
01144 #endif
01145    if (!tmp) {
01146       /* Channel structure allocation failure. */
01147       return NULL;
01148    }
01149 
01150    /*
01151     * Init file descriptors to unopened state so
01152     * the destructor can know not to close them.
01153     */
01154    tmp->timingfd = -1;
01155    for (x = 0; x < ARRAY_LEN(tmp->alertpipe); ++x) {
01156       tmp->alertpipe[x] = -1;
01157    }
01158    for (x = 0; x < ARRAY_LEN(tmp->fds); ++x) {
01159       tmp->fds[x] = -1;
01160    }
01161 #ifdef HAVE_EPOLL
01162    tmp->epfd = epoll_create(25);
01163 #endif
01164 
01165    if (!(tmp->sched = sched_context_create())) {
01166       ast_log(LOG_WARNING, "Channel allocation failed: Unable to create schedule context\n");
01167       return ast_channel_unref(tmp);
01168    }
01169    
01170    ast_party_dialed_init(&tmp->dialed);
01171    ast_party_caller_init(&tmp->caller);
01172    ast_party_connected_line_init(&tmp->connected);
01173    ast_party_redirecting_init(&tmp->redirecting);
01174 
01175    if (cid_name) {
01176       tmp->caller.id.name.valid = 1;
01177       tmp->caller.id.name.str = ast_strdup(cid_name);
01178       if (!tmp->caller.id.name.str) {
01179          return ast_channel_unref(tmp);
01180       }
01181    }
01182    if (cid_num) {
01183       tmp->caller.id.number.valid = 1;
01184       tmp->caller.id.number.str = ast_strdup(cid_num);
01185       if (!tmp->caller.id.number.str) {
01186          return ast_channel_unref(tmp);
01187       }
01188    }
01189 
01190    if ((tmp->timer = ast_timer_open())) {
01191       if (strcmp(ast_timer_get_name(tmp->timer), "timerfd")) {
01192          needqueue = 0;
01193       }
01194       tmp->timingfd = ast_timer_fd(tmp->timer);
01195    }
01196 
01197    if (needqueue) {
01198       if (pipe(tmp->alertpipe)) {
01199          ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe! Try increasing max file descriptors with ulimit -n\n");
01200          return ast_channel_unref(tmp);
01201       } else {
01202          flags = fcntl(tmp->alertpipe[0], F_GETFL);
01203          if (fcntl(tmp->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) {
01204             ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
01205             return ast_channel_unref(tmp);
01206          }
01207          flags = fcntl(tmp->alertpipe[1], F_GETFL);
01208          if (fcntl(tmp->alertpipe[1], F_SETFL, flags | O_NONBLOCK) < 0) {
01209             ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
01210             return ast_channel_unref(tmp);
01211          }
01212       }
01213    }
01214 
01215    /*
01216     * This is the last place the channel constructor can fail.
01217     *
01218     * The destructor takes advantage of this fact to ensure that the
01219     * AST_CEL_CHANNEL_END is not posted if we have not posted the
01220     * AST_CEL_CHANNEL_START yet.
01221     */
01222    if ((ast_string_field_init(tmp, 128))) {
01223       return ast_channel_unref(tmp);
01224    }
01225 
01226    /* Always watch the alertpipe */
01227    ast_channel_set_fd(tmp, AST_ALERT_FD, tmp->alertpipe[0]);
01228    /* And timing pipe */
01229    ast_channel_set_fd(tmp, AST_TIMING_FD, tmp->timingfd);
01230 
01231    /* Initial state */
01232    tmp->_state = state;
01233 
01234    tmp->streamid = -1;
01235    
01236    tmp->fin = global_fin;
01237    tmp->fout = global_fout;
01238 
01239    if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) {
01240       ast_string_field_build(tmp, uniqueid, "%li.%d", (long) time(NULL), 
01241          ast_atomic_fetchadd_int(&uniqueint, 1));
01242    } else {
01243       ast_string_field_build(tmp, uniqueid, "%s-%li.%d", ast_config_AST_SYSTEM_NAME, 
01244          (long) time(NULL), ast_atomic_fetchadd_int(&uniqueint, 1));
01245    }
01246 
01247    if (!ast_strlen_zero(linkedid)) {
01248       ast_string_field_set(tmp, linkedid, linkedid);
01249    } else {
01250       ast_string_field_set(tmp, linkedid, tmp->uniqueid);
01251    }
01252 
01253    if (!ast_strlen_zero(name_fmt)) {
01254       char *slash, *slash2;
01255       /* Almost every channel is calling this function, and setting the name via the ast_string_field_build() call.
01256        * And they all use slightly different formats for their name string.
01257        * This means, to set the name here, we have to accept variable args, and call the string_field_build from here.
01258        * This means, that the stringfields must have a routine that takes the va_lists directly, and 
01259        * uses them to build the string, instead of forming the va_lists internally from the vararg ... list.
01260        * This new function was written so this can be accomplished.
01261        */
01262       ast_string_field_build_va(tmp, name, name_fmt, ap1, ap2);
01263       tech = ast_strdupa(tmp->name);
01264       if ((slash = strchr(tech, '/'))) {
01265          if ((slash2 = strchr(slash + 1, '/'))) {
01266             tech2 = slash + 1;
01267             *slash2 = '\0';
01268          }
01269          *slash = '\0';
01270       }
01271    } else {
01272       /*
01273        * Start the string with '-' so it becomes an empty string
01274        * in the destructor.
01275        */
01276       ast_string_field_set(tmp, name, "-**Unknown**");
01277    }
01278 
01279    /* Reminder for the future: under what conditions do we NOT want to track cdrs on channels? */
01280 
01281    /* These 4 variables need to be set up for the cdr_init() to work right */
01282    if (amaflag)
01283       tmp->amaflags = amaflag;
01284    else
01285       tmp->amaflags = ast_default_amaflags;
01286    
01287    if (!ast_strlen_zero(acctcode))
01288       ast_string_field_set(tmp, accountcode, acctcode);
01289    else
01290       ast_string_field_set(tmp, accountcode, ast_default_accountcode);
01291       
01292    if (!ast_strlen_zero(context))
01293       ast_copy_string(tmp->context, context, sizeof(tmp->context));
01294    else
01295       strcpy(tmp->context, "default");
01296 
01297    if (!ast_strlen_zero(exten))
01298       ast_copy_string(tmp->exten, exten, sizeof(tmp->exten));
01299    else
01300       strcpy(tmp->exten, "s");
01301 
01302    tmp->priority = 1;
01303 
01304    tmp->cdr = ast_cdr_alloc();
01305    ast_cdr_init(tmp->cdr, tmp);
01306    ast_cdr_start(tmp->cdr);
01307 
01308    ast_atomic_fetchadd_int(&chancount, +1);
01309    ast_cel_report_event(tmp, AST_CEL_CHANNEL_START, NULL, NULL, NULL);
01310 
01311    headp = &tmp->varshead;
01312    AST_LIST_HEAD_INIT_NOLOCK(headp);
01313    
01314    AST_LIST_HEAD_INIT_NOLOCK(&tmp->datastores);
01315 
01316    AST_LIST_HEAD_INIT_NOLOCK(&tmp->autochans);
01317    
01318    ast_string_field_set(tmp, language, defaultlanguage);
01319 
01320    tmp->tech = &null_tech;
01321 
01322    ao2_link(channels, tmp);
01323 
01324    /*
01325     * And now, since the channel structure is built, and has its name, let's
01326     * call the manager event generator with this Newchannel event. This is the
01327     * proper and correct place to make this call, but you sure do have to pass
01328     * a lot of data into this func to do it here!
01329     */
01330    if (ast_get_channel_tech(tech) || (tech2 && ast_get_channel_tech(tech2))) {
01331       ast_manager_event(tmp, EVENT_FLAG_CALL, "Newchannel",
01332          "Channel: %s\r\n"
01333          "ChannelState: %d\r\n"
01334          "ChannelStateDesc: %s\r\n"
01335          "CallerIDNum: %s\r\n"
01336          "CallerIDName: %s\r\n"
01337          "AccountCode: %s\r\n"
01338          "Exten: %s\r\n"
01339          "Context: %s\r\n"
01340          "Uniqueid: %s\r\n",
01341          tmp->name, 
01342          state, 
01343          ast_state2str(state),
01344          S_OR(cid_num, ""),
01345          S_OR(cid_name, ""),
01346          tmp->accountcode,
01347          S_OR(exten, ""),
01348          S_OR(context, ""),
01349          tmp->uniqueid);
01350    }
01351 
01352    return tmp;
01353 }

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

Definition at line 5871 of file channel.c.

References ast_channel::_bridge, ast_bridged_channel(), ast_channel_datastore_add(), ast_channel_lock_both, 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, ast_channel::name, and ast_channel::tech.

Referenced by ast_channel_masquerade(), and ast_channel_transfer_masquerade().

05872 {
05873    int res = -1;
05874    struct ast_channel *final_orig, *final_clone, *base;
05875 
05876    for (;;) {
05877       final_orig = original;
05878       final_clone = clonechan;
05879 
05880       ast_channel_lock_both(original, clonechan);
05881 
05882       if (ast_test_flag(original, AST_FLAG_ZOMBIE)
05883          || ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) {
05884          /* Zombies! Run! */
05885          ast_log(LOG_WARNING,
05886             "Can't setup masquerade. One or both channels is dead. (%s <-- %s)\n",
05887             original->name, clonechan->name);
05888          ast_channel_unlock(clonechan);
05889          ast_channel_unlock(original);
05890          return -1;
05891       }
05892 
05893       /*
05894        * Each of these channels may be sitting behind a channel proxy
05895        * (i.e. chan_agent) and if so, we don't really want to
05896        * masquerade it, but its proxy
05897        */
05898       if (original->_bridge
05899          && (original->_bridge != ast_bridged_channel(original))
05900          && (original->_bridge->_bridge != original)) {
05901          final_orig = original->_bridge;
05902       }
05903       if (clonechan->_bridge
05904          && (clonechan->_bridge != ast_bridged_channel(clonechan))
05905          && (clonechan->_bridge->_bridge != clonechan)) {
05906          final_clone = clonechan->_bridge;
05907       }
05908       if (final_clone->tech->get_base_channel
05909          && (base = final_clone->tech->get_base_channel(final_clone))) {
05910          final_clone = base;
05911       }
05912 
05913       if ((final_orig != original) || (final_clone != clonechan)) {
05914          /*
05915           * Lots and lots of deadlock avoidance.  The main one we're
05916           * competing with is ast_write(), which locks channels
05917           * recursively, when working with a proxy channel.
05918           */
05919          if (ast_channel_trylock(final_orig)) {
05920             ast_channel_unlock(clonechan);
05921             ast_channel_unlock(original);
05922 
05923             /* Try again */
05924             continue;
05925          }
05926          if (ast_channel_trylock(final_clone)) {
05927             ast_channel_unlock(final_orig);
05928             ast_channel_unlock(clonechan);
05929             ast_channel_unlock(original);
05930 
05931             /* Try again */
05932             continue;
05933          }
05934          ast_channel_unlock(clonechan);
05935          ast_channel_unlock(original);
05936          original = final_orig;
05937          clonechan = final_clone;
05938 
05939          if (ast_test_flag(original, AST_FLAG_ZOMBIE)
05940             || ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) {
05941             /* Zombies! Run! */
05942             ast_log(LOG_WARNING,
05943                "Can't setup masquerade. One or both channels is dead. (%s <-- %s)\n",
05944                original->name, clonechan->name);
05945             ast_channel_unlock(clonechan);
05946             ast_channel_unlock(original);
05947             return -1;
05948          }
05949       }
05950       break;
05951    }
05952 
05953    if (original == clonechan) {
05954       ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name);
05955       ast_channel_unlock(clonechan);
05956       ast_channel_unlock(original);
05957       return -1;
05958    }
05959 
05960    ast_debug(1, "Planning to masquerade channel %s into the structure of %s\n",
05961       clonechan->name, original->name);
05962 
05963    if (!original->masqr && !original->masq && !clonechan->masq && !clonechan->masqr) {
05964       original->masq = clonechan;
05965       clonechan->masqr = original;
05966       if (xfer_ds) {
05967          ast_channel_datastore_add(original, xfer_ds);
05968       }
05969       ast_queue_frame(original, &ast_null_frame);
05970       ast_queue_frame(clonechan, &ast_null_frame);
05971       ast_debug(1, "Done planning to masquerade channel %s into the structure of %s\n", clonechan->name, original->name);
05972       res = 0;
05973    } else if (original->masq) {
05974       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
05975          original->masq->name, original->name);
05976    } else if (original->masqr) {
05977       /* not yet as a previously planned masq hasn't yet happened */
05978       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
05979          original->name, original->masqr->name);
05980    } else if (clonechan->masq) {
05981       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
05982          clonechan->masq->name, clonechan->name);
05983    } else { /* (clonechan->masqr) */
05984       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
05985       clonechan->name, clonechan->masqr->name);
05986    }
05987 
05988    ast_channel_unlock(clonechan);
05989    ast_channel_unlock(original);
05990 
05991    return res;
05992 }

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

Definition at line 1410 of file channel.c.

References ast_channel::alertpipe, ast_channel_lock, 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, chanlist::chan, errno, f, frames, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, ast_channel::name, 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().

01411 {
01412    struct ast_frame *f;
01413    struct ast_frame *cur;
01414    unsigned int new_frames = 0;
01415    unsigned int new_voice_frames = 0;
01416    unsigned int queued_frames = 0;
01417    unsigned int queued_voice_frames = 0;
01418    AST_LIST_HEAD_NOLOCK(, ast_frame) frames;
01419 
01420    ast_channel_lock(chan);
01421 
01422    /*
01423     * Check the last frame on the queue if we are queuing the new
01424     * frames after it.
01425     */
01426    cur = AST_LIST_LAST(&chan->readq);
01427    if (cur && cur->frametype == AST_FRAME_CONTROL && !head && (!after || after == cur)) {
01428       switch (cur->subclass.integer) {
01429       case AST_CONTROL_END_OF_Q:
01430          if (fin->frametype == AST_FRAME_CONTROL
01431             && fin->subclass.integer == AST_CONTROL_HANGUP) {
01432             /*
01433              * Destroy the end-of-Q marker frame so we can queue the hangup
01434              * frame in its place.
01435              */
01436             AST_LIST_REMOVE(&chan->readq, cur, frame_list);
01437             ast_frfree(cur);
01438 
01439             /*
01440              * This has degenerated to a normal queue append anyway.  Since
01441              * we just destroyed the last frame in the queue we must make
01442              * sure that "after" is NULL or bad things will happen.
01443              */
01444             after = NULL;
01445             break;
01446          }
01447          /* Fall through */
01448       case AST_CONTROL_HANGUP:
01449          /* Don't queue anything. */
01450          ast_channel_unlock(chan);
01451          return 0;
01452       default:
01453          break;
01454       }
01455    }
01456 
01457    /* Build copies of all the new frames and count them */
01458    AST_LIST_HEAD_INIT_NOLOCK(&frames);
01459    for (cur = fin; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
01460       if (!(f = ast_frdup(cur))) {
01461          if (AST_LIST_FIRST(&frames)) {
01462             ast_frfree(AST_LIST_FIRST(&frames));
01463          }
01464          ast_channel_unlock(chan);
01465          return -1;
01466       }
01467 
01468       AST_LIST_INSERT_TAIL(&frames, f, frame_list);
01469       new_frames++;
01470       if (f->frametype == AST_FRAME_VOICE) {
01471          new_voice_frames++;
01472       }
01473    }
01474 
01475    /* Count how many frames exist on the queue */
01476    AST_LIST_TRAVERSE(&chan->readq, cur, frame_list) {
01477       queued_frames++;
01478       if (cur->frametype == AST_FRAME_VOICE) {
01479          queued_voice_frames++;
01480       }
01481    }
01482 
01483    if ((queued_frames + new_frames > 128 || queued_voice_frames + new_voice_frames > 96)) {
01484       int count = 0;
01485       ast_log(LOG_WARNING, "Exceptionally long %squeue length queuing to %s\n", queued_frames + new_frames > 128 ? "" : "voice ", chan->name);
01486       AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->readq, cur, frame_list) {
01487          /* Save the most recent frame */
01488          if (!AST_LIST_NEXT(cur, frame_list)) {
01489             break;
01490          } else if (cur->frametype == AST_FRAME_VOICE || cur->frametype == AST_FRAME_VIDEO || cur->frametype == AST_FRAME_NULL) {
01491             if (++count > 64) {
01492                break;
01493             }
01494             AST_LIST_REMOVE_CURRENT(frame_list);
01495             ast_frfree(cur);
01496          }
01497       }
01498       AST_LIST_TRAVERSE_SAFE_END;
01499    }
01500 
01501    if (after) {
01502       AST_LIST_INSERT_LIST_AFTER(&chan->readq, &frames, after, frame_list);
01503    } else {
01504       if (head) {
01505          AST_LIST_APPEND_LIST(&frames, &chan->readq, frame_list);
01506          AST_LIST_HEAD_INIT_NOLOCK(&chan->readq);
01507       }
01508       AST_LIST_APPEND_LIST(&chan->readq, &frames, frame_list);
01509    }
01510 
01511    if (chan->alertpipe[1] > -1) {
01512       int blah[new_frames];
01513 
01514       memset(blah, 1, sizeof(blah));
01515       if (write(chan->alertpipe[1], &blah, sizeof(blah)) != (sizeof(blah))) {
01516          ast_log(LOG_WARNING, "Unable to write to alert pipe on %s (qlen = %d): %s!\n",
01517             chan->name, queued_frames, strerror(errno));
01518       }
01519    } else if (chan->timingfd > -1) {
01520       ast_timer_enable_continuous(chan->timer);
01521    } else if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
01522       pthread_kill(chan->blocker, SIGURG);
01523    }
01524 
01525    ast_channel_unlock(chan);
01526 
01527    return 0;
01528 }

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

Definition at line 3750 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_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_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_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, chanlist::chan, ast_channel::connected, chanlist::connected, 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, f, ast_channel::fdno, ast_channel::fds, ast_channel::fin, chanlist::flags, ast_filestream::fmt, ast_format::format, FRAMECOUNT_INC, ast_channel::framehooks, ast_generator::generate, ast_channel::generator, ast_channel::generatordata, ast_channel::hangupcause, ast_channel::insmpl, LOG_DTMF, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_channel::masq, ast_channel::monitor, ast_channel::music_state, ast_channel::name, ast_channel::nativeformats, ast_channel::outsmpl, ast_control_read_action_payload::payload, ast_control_read_action_payload::payload_size, queue_dtmf_readq(), ast_channel_tech::read, ast_channel_monitor::read_stream, ast_channel::readq, ast_channel::readtrans, SEEK_FORCECUR, send_dtmf_event(), should_skip_dtmf(), ast_channel_monitor::state, ast_channel::tech, ast_channel::timer, ast_channel::timingdata, ast_channel::timingfd, and ast_channel::timingfunc.

Referenced by ast_read(), and ast_read_noaudio().

03751 {
03752    struct ast_frame *f = NULL;   /* the return value */
03753    int blah;
03754    int prestate;
03755    int cause = 0;
03756 
03757    /* this function is very long so make sure there is only one return
03758     * point at the end (there are only two exceptions to this).
03759     */
03760 
03761    if (chan->masq) {
03762       ast_do_masquerade(chan);
03763       return &ast_null_frame;
03764    }
03765 
03766    /* if here, no masq has happened, lock the channel and proceed */
03767    ast_channel_lock(chan);
03768 
03769    /* Stop if we're a zombie or need a soft hangup */
03770    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
03771       if (chan->generator)
03772          ast_deactivate_generator(chan);
03773 
03774       /*
03775        * It is possible for chan->_softhangup to be set and there
03776        * still be control frames that need to be read.  Instead of
03777        * just going to 'done' in the case of ast_check_hangup(), we
03778        * need to queue the end-of-Q frame so that it can mark the end
03779        * of the read queue.  If there are frames to be read,
03780        * ast_queue_control() will be called repeatedly, but will only
03781        * queue the first end-of-Q frame.
03782        */
03783       if (chan->_softhangup) {
03784          ast_queue_control(chan, AST_CONTROL_END_OF_Q);
03785       } else {
03786          goto done;
03787       }
03788    } else {
03789 #ifdef AST_DEVMODE
03790       /*
03791        * The ast_waitfor() code records which of the channel's file
03792        * descriptors reported that data is available.  In theory,
03793        * ast_read() should only be called after ast_waitfor() reports
03794        * that a channel has data available for reading.  However,
03795        * there still may be some edge cases throughout the code where
03796        * ast_read() is called improperly.  This can potentially cause
03797        * problems, so if this is a developer build, make a lot of
03798        * noise if this happens so that it can be addressed.
03799        *
03800        * One of the potential problems is blocking on a dead channel.
03801        */
03802       if (chan->fdno == -1) {
03803          ast_log(LOG_ERROR,
03804             "ast_read() on chan '%s' called with no recorded file descriptor.\n",
03805             chan->name);
03806       }
03807 #endif
03808    }
03809 
03810    prestate = chan->_state;
03811    if (chan->timingfd > -1 && chan->fdno == AST_TIMING_FD) {
03812       enum ast_timer_event res;
03813 
03814       ast_clear_flag(chan, AST_FLAG_EXCEPTION);
03815 
03816       res = ast_timer_get_event(chan->timer);
03817 
03818       switch (res) {
03819       case AST_TIMING_EVENT_EXPIRED:
03820          ast_timer_ack(chan->timer, 1);
03821 
03822          if (chan->timingfunc) {
03823             /* save a copy of func/data before unlocking the channel */
03824             int (*func)(const void *) = chan->timingfunc;
03825             void *data = chan->timingdata;
03826             chan->fdno = -1;
03827             ast_channel_unlock(chan);
03828             func(data);
03829          } else {
03830             ast_timer_set_rate(chan->timer, 0);
03831             chan->fdno = -1;
03832             ast_channel_unlock(chan);
03833          }
03834 
03835          /* cannot 'goto done' because the channel is already unlocked */
03836          return &ast_null_frame;
03837 
03838       case AST_TIMING_EVENT_CONTINUOUS:
03839          if (AST_LIST_EMPTY(&chan->readq) || 
03840             !AST_LIST_NEXT(AST_LIST_FIRST(&chan->readq), frame_list)) {
03841             ast_timer_disable_continuous(chan->timer);
03842          }
03843          break;
03844       }
03845 
03846    } else if (chan->fds[AST_GENERATOR_FD] > -1 && chan->fdno == AST_GENERATOR_FD) {
03847       /* if the AST_GENERATOR_FD is set, call the generator with args
03848        * set to -1 so it can do whatever it needs to.
03849        */
03850       void *tmp = chan->generatordata;
03851       chan->generatordata = NULL;     /* reset to let ast_write get through */
03852       chan->generator->generate(chan, tmp, -1, -1);
03853       chan->generatordata = tmp;
03854       f = &ast_null_frame;
03855       chan->fdno = -1;
03856       goto done;
03857    }
03858 
03859    /* Read and ignore anything on the alertpipe, but read only
03860       one sizeof(blah) per frame that we send from it */
03861    if (chan->alertpipe[0] > -1) {
03862       int flags = fcntl(chan->alertpipe[0], F_GETFL);
03863       /* For some odd reason, the alertpipe occasionally loses nonblocking status,
03864        * which immediately causes a deadlock scenario.  Detect and prevent this. */
03865       if ((flags & O_NONBLOCK) == 0) {
03866          ast_log(LOG_ERROR, "Alertpipe on channel %s lost O_NONBLOCK?!!\n", chan->name);
03867          if (fcntl(chan->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) {
03868             ast_log(LOG_WARNING, "Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
03869             f = &ast_null_frame;
03870             goto done;
03871          }
03872       }
03873       if (read(chan->alertpipe[0], &blah, sizeof(blah)) < 0) {
03874          if (errno != EINTR && errno != EAGAIN)
03875             ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno));
03876       }
03877    }
03878 
03879 
03880    /* Check for pending read queue */
03881    if (!AST_LIST_EMPTY(&chan->readq)) {
03882       int skip_dtmf = should_skip_dtmf(chan);
03883 
03884       AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->readq, f, frame_list) {
03885          /* We have to be picky about which frame we pull off of the readq because
03886           * there are cases where we want to leave DTMF frames on the queue until
03887           * some later time. */
03888 
03889          if ( (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && skip_dtmf) {
03890             continue;
03891          }
03892 
03893          AST_LIST_REMOVE_CURRENT(frame_list);
03894          break;
03895       }
03896       AST_LIST_TRAVERSE_SAFE_END;
03897       
03898       if (!f) {
03899          /* There were no acceptable frames on the readq. */
03900          f = &ast_null_frame;
03901          if (chan->alertpipe[0] > -1) {
03902             int poke = 0;
03903             /* Restore the state of the alertpipe since we aren't ready for any
03904              * of the frames in the readq. */
03905             if (write(chan->alertpipe[1], &poke, sizeof(poke)) != sizeof(poke)) {
03906                ast_log(LOG_ERROR, "Failed to write to alertpipe: %s\n", strerror(errno));
03907             }
03908          }
03909       }
03910 
03911       /* Interpret hangup and end-of-Q frames to return NULL */
03912       /* XXX why not the same for frames from the channel ? */
03913       if (f->frametype == AST_FRAME_CONTROL) {
03914          switch (f->subclass.integer) {
03915          case AST_CONTROL_HANGUP:
03916             chan->_softhangup |= AST_SOFTHANGUP_DEV;
03917             cause = f->data.uint32;
03918             /* Fall through */
03919          case AST_CONTROL_END_OF_Q:
03920             ast_frfree(f);
03921             f = NULL;
03922             break;
03923          default:
03924             break;
03925          }
03926       }
03927    } else {
03928       chan->blocker = pthread_self();
03929       if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
03930          if (chan->tech->exception)
03931             f = chan->tech->exception(chan);
03932          else {
03933             ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name);
03934             f = &ast_null_frame;
03935          }
03936          /* Clear the exception flag */
03937          ast_clear_flag(chan, AST_FLAG_EXCEPTION);
03938       } else if (chan->tech && chan->tech->read)
03939          f = chan->tech->read(chan);
03940       else
03941          ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
03942    }
03943 
03944    /*
03945     * Reset the recorded file descriptor that triggered this read so that we can
03946     * easily detect when ast_read() is called without properly using ast_waitfor().
03947     */
03948    chan->fdno = -1;
03949 
03950    /* Perform the framehook read event here. After the frame enters the framehook list
03951     * there is no telling what will happen, <insert mad scientist laugh here>!!! */
03952    f = ast_framehook_list_read_event(chan->framehooks, f);
03953 
03954    if (f) {
03955       struct ast_frame *readq_tail = AST_LIST_LAST(&chan->readq);
03956       struct ast_control_read_action_payload *read_action_payload;
03957       struct ast_party_connected_line connected;
03958 
03959       /* if the channel driver returned more than one frame, stuff the excess
03960          into the readq for the next ast_read call
03961       */
03962       if (AST_LIST_NEXT(f, frame_list)) {
03963          ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list));
03964          ast_frfree(AST_LIST_NEXT(f, frame_list));
03965          AST_LIST_NEXT(f, frame_list) = NULL;
03966       }
03967 
03968       switch (f->frametype) {
03969       case AST_FRAME_CONTROL:
03970          if (f->subclass.integer == AST_CONTROL_ANSWER) {
03971             if (!ast_test_flag(chan, AST_FLAG_OUTGOING)) {
03972                ast_debug(1, "Ignoring answer on an inbound call!\n");
03973                ast_frfree(f);
03974                f = &ast_null_frame;
03975             } else if (prestate == AST_STATE_UP && ast_bridged_channel(chan)) {
03976                ast_debug(1, "Dropping duplicate answer!\n");
03977                ast_frfree(f);
03978                f = &ast_null_frame;
03979             } else {
03980                /* Answer the CDR */
03981                ast_setstate(chan, AST_STATE_UP);
03982                /* removed a call to ast_cdr_answer(chan->cdr) from here. */
03983                ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL);
03984             }
03985          } else if (f->subclass.integer == AST_CONTROL_READ_ACTION) {
03986             read_action_payload = f->data.ptr;
03987             switch (read_action_payload->action) {
03988             case AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO:
03989                ast_party_connected_line_init(&connected);
03990                ast_party_connected_line_copy(&connected, &chan->connected);
03991                if (ast_connected_line_parse_data(read_action_payload->payload,
03992                   read_action_payload->payload_size, &connected)) {
03993                   ast_party_connected_line_free(&connected);
03994                   break;
03995                }
03996                ast_channel_unlock(chan);
03997                if (ast_channel_connected_line_macro(NULL, chan, &connected, 1, 0)) {
03998                   ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE,
03999                      read_action_payload->payload,
04000                      read_action_payload->payload_size);
04001                }
04002                ast_party_connected_line_free(&connected);
04003                ast_channel_lock(chan);
04004                break;
04005             }
04006             ast_frfree(f);
04007             f = &ast_null_frame;
04008          }
04009          break;
04010       case AST_FRAME_DTMF_END:
04011          send_dtmf_event(chan, "Received", f->subclass.integer, "No", "Yes");
04012          ast_log(LOG_DTMF, "DTMF end '%c' received on %s, duration %ld ms\n", f->subclass.integer, chan->name, f->len);
04013          /* Queue it up if DTMF is deferred, or if DTMF emulation is forced. */
04014          if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF) || ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
04015             queue_dtmf_readq(chan, f);
04016             ast_frfree(f);
04017             f = &ast_null_frame;
04018          } else if (!ast_test_flag(chan, AST_FLAG_IN_DTMF | AST_FLAG_END_DTMF_ONLY)) {
04019             if (!ast_tvzero(chan->dtmf_tv) && 
04020                 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) {
04021                /* If it hasn't been long enough, defer this digit */
04022                queue_dtmf_readq(chan, f);
04023                ast_frfree(f);
04024                f = &ast_null_frame;
04025             } else {
04026                /* There was no begin, turn this into a begin and send the end later */
04027                f->frametype = AST_FRAME_DTMF_BEGIN;
04028                ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
04029                chan->emulate_dtmf_digit = f->subclass.integer;
04030                chan->dtmf_tv = ast_tvnow();
04031                if (f->len) {
04032                   if (f->len > AST_MIN_DTMF_DURATION)
04033                      chan->emulate_dtmf_duration = f->len;
04034                   else 
04035                      chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION;
04036                } else
04037                   chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION;
04038                ast_log(LOG_DTMF, "DTMF begin emulation of '%c' with duration %u queued on %s\n", f->subclass.integer, chan->emulate_dtmf_duration, chan->name);
04039             }
04040             if (chan->audiohooks) {
04041                struct ast_frame *old_frame = f;
04042                /*!
04043                 * \todo XXX It is possible to write a digit to the audiohook twice
04044                 * if the digit was originally read while the channel was in autoservice. */
04045                f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
04046                if (old_frame != f)
04047                   ast_frfree(old_frame);
04048             }
04049          } else {
04050             struct timeval now = ast_tvnow();
04051             if (ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
04052                ast_log(LOG_DTMF, "DTMF end accepted with begin '%c' on %s\n", f->subclass.integer, chan->name);
04053                ast_clear_flag(chan, AST_FLAG_IN_DTMF);
04054                if (!f->len)
04055                   f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
04056 
04057                /* detect tones that were received on
04058                 * the wire with durations shorter than
04059                 * AST_MIN_DTMF_DURATION and set f->len
04060                 * to the actual duration of the DTMF
04061                 * frames on the wire.  This will cause
04062                 * dtmf emulation to be triggered later
04063                 * on.
04064                 */
04065                if (ast_tvdiff_ms(now, chan->dtmf_tv) < AST_MIN_DTMF_DURATION) {
04066                   f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
04067                   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, chan->name);
04068                }
04069             } else if (!f->len) {
04070                ast_log(LOG_DTMF, "DTMF end accepted without begin '%c' on %s\n", f->subclass.integer, chan->name);
04071                f->len = AST_MIN_DTMF_DURATION;
04072             }
04073             if (f->len < AST_MIN_DTMF_DURATION && !ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)) {
04074                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, chan->name);
04075                ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
04076                chan->emulate_dtmf_digit = f->subclass.integer;
04077                chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION - f->len;
04078                ast_frfree(f);
04079                f = &ast_null_frame;
04080             } else {
04081                ast_log(LOG_DTMF, "DTMF end passthrough '%c' on %s\n", f->subclass.integer, chan->name);
04082                if (f->len < AST_MIN_DTMF_DURATION) {
04083                   f->len = AST_MIN_DTMF_DURATION;
04084                }
04085                chan->dtmf_tv = now;
04086             }
04087             if (chan->audiohooks) {
04088                struct ast_frame *old_frame = f;
04089                f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
04090                if (old_frame != f)
04091                   ast_frfree(old_frame);
04092             }
04093          }
04094          break;
04095       case AST_FRAME_DTMF_BEGIN:
04096          send_dtmf_event(chan, "Received", f->subclass.integer, "Yes", "No");
04097          ast_log(LOG_DTMF, "DTMF begin '%c' received on %s\n", f->subclass.integer, chan->name);
04098          if ( ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_END_DTMF_ONLY | AST_FLAG_EMULATE_DTMF) || 
04099              (!ast_tvzero(chan->dtmf_tv) && 
04100                ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) ) {
04101             ast_log(LOG_DTMF, "DTMF begin ignored '%c' on %s\n", f->subclass.integer, chan->name);
04102             ast_frfree(f);
04103             f = &ast_null_frame;
04104          } else {
04105             ast_set_flag(chan, AST_FLAG_IN_DTMF);
04106             chan->dtmf_tv = ast_tvnow();
04107             ast_log(LOG_DTMF, "DTMF begin passthrough '%c' on %s\n", f->subclass.integer, chan->name);
04108          }
04109          break;
04110       case AST_FRAME_NULL:
04111          /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration
04112           * is reached , because we want to make sure we pass at least one
04113           * voice frame through before starting the next digit, to ensure a gap
04114           * between DTMF digits. */
04115          if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
04116             struct timeval now = ast_tvnow();
04117             if (!chan->emulate_dtmf_duration) {
04118                ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
04119                chan->emulate_dtmf_digit = 0;
04120             } else if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
04121                chan->emulate_dtmf_duration = 0;
04122                ast_frfree(f);
04123                f = &chan->dtmff;
04124                f->frametype = AST_FRAME_DTMF_END;
04125                f->subclass.integer = chan->emulate_dtmf_digit;
04126                f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
04127                chan->dtmf_tv = now;
04128                ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
04129                chan->emulate_dtmf_digit = 0;
04130                ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass.integer, chan->name);
04131                if (chan->audiohooks) {
04132                   struct ast_frame *old_frame = f;
04133                   f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
04134                   if (old_frame != f) {
04135                      ast_frfree(old_frame);
04136                   }
04137                }
04138             }
04139          }
04140          break;
04141       case AST_FRAME_VOICE:
04142          /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration
04143           * is reached , because we want to make sure we pass at least one
04144           * voice frame through before starting the next digit, to ensure a gap
04145           * between DTMF digits. */
04146          if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !chan->emulate_dtmf_duration) {
04147             ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
04148             chan->emulate_dtmf_digit = 0;
04149          }
04150 
04151          if (dropaudio || ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
04152             if (dropaudio)
04153                ast_read_generator_actions(chan, f);
04154             ast_frfree(f);
04155             f = &ast_null_frame;
04156          }
04157 
04158          if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
04159             struct timeval now = ast_tvnow();
04160             if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
04161                chan->emulate_dtmf_duration = 0;
04162                ast_frfree(f);
04163                f = &chan->dtmff;
04164                f->frametype = AST_FRAME_DTMF_END;
04165                f->subclass.integer = chan->emulate_dtmf_digit;
04166                f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
04167                chan->dtmf_tv = now;
04168                if (chan->audiohooks) {
04169                   struct ast_frame *old_frame = f;
04170                   f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
04171                   if (old_frame != f)
04172                      ast_frfree(old_frame);
04173                }
04174                ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass.integer, chan->name);
04175             } else {
04176                /* Drop voice frames while we're still in the middle of the digit */
04177                ast_frfree(f);
04178                f = &ast_null_frame;
04179             }
04180          } else if ((f->frametype == AST_FRAME_VOICE) && !(f->subclass.codec & chan->nativeformats)) {
04181             /* This frame is not one of the current native formats -- drop it on the floor */
04182             char to[200];
04183             ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n",
04184                chan->name, ast_getformatname(f->subclass.codec), ast_getformatname_multiple(to, sizeof(to), chan->nativeformats));
04185             ast_frfree(f);
04186             f = &ast_null_frame;
04187          } else if ((f->frametype == AST_FRAME_VOICE)) {
04188             /* Send frame to audiohooks if present */
04189             if (chan->audiohooks) {
04190                struct ast_frame *old_frame = f;
04191                f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
04192                if (old_frame != f)
04193                   ast_frfree(old_frame);
04194             }
04195             if (chan->monitor && chan->monitor->read_stream ) {
04196                /* XXX what does this do ? */
04197 #ifndef MONITOR_CONSTANT_DELAY
04198                int jump = chan->outsmpl - chan->insmpl - 4 * f->samples;
04199                if (jump >= 0) {
04200                   jump = calc_monitor_jump((chan->outsmpl - chan->insmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format));
04201                   if (ast_seekstream(chan->monitor->read_stream, jump, SEEK_FORCECUR) == -1)
04202                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
04203                   chan->insmpl += (chan->outsmpl - chan->insmpl) + f->samples;
04204                } else
04205                   chan->insmpl+= f->samples;
04206 #else
04207                int jump = calc_monitor_jump((chan->outsmpl - chan->insmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format));
04208                if (jump - MONITOR_DELAY >= 0) {
04209                   if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
04210                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
04211                   chan->insmpl += chan->outsmpl - chan->insmpl;
04212                } else
04213                   chan->insmpl += f->samples;
04214 #endif
04215                if (chan->monitor->state == AST_MONITOR_RUNNING) {
04216                   if (ast_writestream(chan->monitor->read_stream, f) < 0)
04217                      ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
04218                }
04219             }
04220 
04221             if (chan->readtrans && (f = ast_translate(chan->readtrans, f, 1)) == NULL) {
04222                f = &ast_null_frame;
04223             }
04224 
04225             /* it is possible for the translation process on chan->readtrans to have
04226                produced multiple frames from the single input frame we passed it; if
04227                this happens, queue the additional frames *before* the frames we may
04228                have queued earlier. if the readq was empty, put them at the head of
04229                the queue, and if it was not, put them just after the frame that was
04230                at the end of the queue.
04231             */
04232             if (AST_LIST_NEXT(f, frame_list)) {
04233                if (!readq_tail) {
04234                   ast_queue_frame_head(chan, AST_LIST_NEXT(f, frame_list));
04235                } else {
04236                   __ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list), 0, readq_tail);
04237                }
04238                ast_frfree(AST_LIST_NEXT(f, frame_list));
04239                AST_LIST_NEXT(f, frame_list) = NULL;
04240             }
04241 
04242             /* Run generator sitting on the line if timing device not available
04243             * and synchronous generation of outgoing frames is necessary       */
04244             ast_read_generator_actions(chan, f);
04245          }
04246          break;
04247       default:
04248          /* Just pass it on! */
04249          break;
04250       }
04251    } else {
04252       /* Make sure we always return NULL in the future */
04253       if (!chan->_softhangup) {
04254          chan->_softhangup |= AST_SOFTHANGUP_DEV;
04255       }
04256       if (cause)
04257          chan->hangupcause = cause;
04258       if (chan->generator)
04259          ast_deactivate_generator(chan);
04260       /* We no longer End the CDR here */
04261    }
04262 
04263    /* High bit prints debugging */
04264    if (chan->fin & DEBUGCHAN_FLAG)
04265       ast_frame_dump(chan->name, f, "<<");
04266    chan->fin = FRAMECOUNT_INC(chan->fin);
04267 
04268 done:
04269    if (chan->music_state && chan->generator && chan->generator->digit && f && f->frametype == AST_FRAME_DTMF_END)
04270       chan->generator->digit(chan, f->subclass.integer);
04271 
04272    if (chan->audiohooks && ast_audiohook_write_list_empty(chan->audiohooks)) {
04273       /* The list gets recreated if audiohooks are added again later */
04274       ast_audiohook_detach_list(chan->audiohooks);
04275       chan->audiohooks = NULL;
04276    }
04277    ast_channel_unlock(chan);
04278    return f;
04279 }

struct ast_channel* __ast_request_and_dial ( const char *  type,
format_t  format,
const struct ast_channel requestor,
void *  data,
int  timeout,
int *  reason,
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.

Parameters:
type type of channel to request
format requested channel format
requestor channel requesting data
data data to pass to the channel requester
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 5341 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_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_callerid(), ast_set_flag, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_waitfor(), ast_channel::call_forward, cause, ast_channel::cdr, chanlist::chan, outgoing_helper::cid_name, outgoing_helper::cid_num, ast_channel::connected, chanlist::connected, ast_channel::context, outgoing_helper::context, ast_channel::exten, outgoing_helper::exten, f, handle_cause(), ast_channel::hangupcause, ast_party_connected_line::id, 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_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().

05342 {
05343    int dummy_outstate;
05344    int cause = 0;
05345    struct ast_channel *chan;
05346    int res = 0;
05347    int last_subclass = 0;
05348    struct ast_party_connected_line connected;
05349    
05350    if (outstate)
05351       *outstate = 0;
05352    else
05353       outstate = &dummy_outstate;   /* make outstate always a valid pointer */
05354 
05355    chan = ast_request(type, format, requestor, data, &cause);
05356    if (!chan) {
05357       ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
05358       handle_cause(cause, outstate);
05359       return NULL;
05360    }
05361 
05362    if (oh) {
05363       if (oh->vars) {
05364          ast_set_variables(chan, oh->vars);
05365       }
05366       if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) {
05367          /*
05368           * Use the oh values instead of the function parameters for the
05369           * outgoing CallerID.
05370           */
05371          cid_num = oh->cid_num;
05372          cid_name = oh->cid_name;
05373       }
05374       if (oh->parent_channel) {
05375          /* Safely inherit variables and datastores from the parent channel. */
05376          ast_channel_lock_both(oh->parent_channel, chan);
05377          ast_channel_inherit_variables(oh->parent_channel, chan);
05378          ast_channel_datastore_inherit(oh->parent_channel, chan);
05379          ast_channel_unlock(oh->parent_channel);
05380          ast_channel_unlock(chan);
05381       }
05382       if (oh->account) {
05383          ast_channel_lock(chan);
05384          ast_cdr_setaccount(chan, oh->account);
05385          ast_channel_unlock(chan);
05386       }
05387    }
05388 
05389    /*
05390     * I seems strange to set the CallerID on an outgoing call leg
05391     * to whom we are calling, but this function's callers are doing
05392     * various Originate methods.  This call leg goes to the local
05393     * user.  Once the local user answers, the dialplan needs to be
05394     * able to access the CallerID from the CALLERID function as if
05395     * the local user had placed this call.
05396     */
05397    ast_set_callerid(chan, cid_num, cid_name, cid_num);
05398 
05399    ast_set_flag(chan->cdr, AST_CDR_FLAG_ORIGINATED);
05400    ast_party_connected_line_set_init(&connected, &chan->connected);
05401    if (cid_num) {
05402       connected.id.number.valid = 1;
05403       connected.id.number.str = (char *) cid_num;
05404       connected.id.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
05405    }
05406    if (cid_name) {
05407       connected.id.name.valid = 1;
05408       connected.id.name.str = (char *) cid_name;
05409       connected.id.name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
05410    }
05411    ast_channel_set_connected_line(chan, &connected, NULL);
05412 
05413    if (ast_call(chan, data, 0)) {   /* ast_call failed... */
05414       ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
05415    } else {
05416       res = 1; /* mark success in case chan->_state is already AST_STATE_UP */
05417       while (timeout && chan->_state != AST_STATE_UP) {
05418          struct ast_frame *f;
05419          res = ast_waitfor(chan, timeout);
05420          if (res == 0) { /* timeout, treat it like ringing */
05421             *outstate = AST_CONTROL_RINGING;
05422             break;
05423          }
05424          if (res < 0) /* error or done */
05425             break;
05426          if (timeout > -1)
05427             timeout = res;
05428          if (!ast_strlen_zero(chan->call_forward)) {
05429             if (!(chan = ast_call_forward(NULL, chan, NULL, format, oh, outstate))) {
05430                return NULL;
05431             }
05432             continue;
05433          }
05434 
05435          f = ast_read(chan);
05436          if (!f) {
05437             *outstate = AST_CONTROL_HANGUP;
05438             res = 0;
05439             break;
05440          }
05441          if (f->frametype == AST_FRAME_CONTROL) {
05442             switch (f->subclass.integer) {
05443             case AST_CONTROL_RINGING:  /* record but keep going */
05444                *outstate = f->subclass.integer;
05445                break;
05446 
05447             case AST_CONTROL_BUSY:
05448                ast_cdr_busy(chan->cdr);
05449                *outstate = f->subclass.integer;
05450                timeout = 0;
05451                break;
05452 
05453             case AST_CONTROL_INCOMPLETE:
05454                ast_cdr_failed(chan->cdr);
05455                *outstate = AST_CONTROL_CONGESTION;
05456                timeout = 0;
05457                break;
05458 
05459             case AST_CONTROL_CONGESTION:
05460                ast_cdr_failed(chan->cdr);
05461                *outstate = f->subclass.integer;
05462                timeout = 0;
05463                break;
05464 
05465             case AST_CONTROL_ANSWER:
05466                ast_cdr_answer(chan->cdr);
05467                *outstate = f->subclass.integer;
05468                timeout = 0;      /* trick to force exit from the while() */
05469                break;
05470 
05471             /* Ignore these */
05472             case AST_CONTROL_PROGRESS:
05473             case AST_CONTROL_PROCEEDING:
05474             case AST_CONTROL_HOLD:
05475             case AST_CONTROL_UNHOLD:
05476             case AST_CONTROL_VIDUPDATE:
05477             case AST_CONTROL_SRCUPDATE:
05478             case AST_CONTROL_SRCCHANGE:
05479             case AST_CONTROL_CONNECTED_LINE:
05480             case AST_CONTROL_REDIRECTING:
05481             case AST_CONTROL_CC:
05482             case -1:       /* Ignore -- just stopping indications */
05483                break;
05484 
05485             default:
05486                ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass.integer);
05487             }
05488             last_subclass = f->subclass.integer;
05489          }
05490          ast_frfree(f);
05491       }
05492    }
05493 
05494    /* Final fixups */
05495    if (oh) {
05496       if (!ast_strlen_zero(oh->context))
05497          ast_copy_string(chan->context, oh->context, sizeof(chan->context));
05498       if (!ast_strlen_zero(oh->exten))
05499          ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten));
05500       if (oh->priority) 
05501          chan->priority = oh->priority;
05502    }
05503    if (chan->_state == AST_STATE_UP)
05504       *outstate = AST_CONTROL_ANSWER;
05505 
05506    if (res <= 0) {
05507       ast_channel_lock(chan);
05508       if (AST_CONTROL_RINGING == last_subclass) {
05509          chan->hangupcause = AST_CAUSE_NO_ANSWER;
05510       }
05511       if (!chan->cdr && (chan->cdr = ast_cdr_alloc())) {
05512          ast_cdr_init(chan->cdr, chan);
05513       }
05514       if (chan->cdr) {
05515          char tmp[256];
05516 
05517          snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data);
05518          ast_cdr_setapp(chan->cdr, "Dial", tmp);
05519          ast_cdr_update(chan);
05520          ast_cdr_start(chan->cdr);
05521          ast_cdr_end(chan->cdr);
05522          /* If the cause wasn't handled properly */
05523          if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) {
05524             ast_cdr_failed(chan->cdr);
05525          }
05526       }
05527       ast_channel_unlock(chan);
05528       ast_hangup(chan);
05529       chan = NULL;
05530    }
05531    return chan;
05532 }

static void __init_state2str_threadbuf ( void   )  [static]

Definition at line 104 of file channel.c.

00119 {

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

Definition at line 4722 of file channel.c.

References ast_calloc, ast_channel_datastore_remove(), ast_datastore_free(), ast_free, AST_FRIENDLY_OFFSET, chanlist::chan, 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().

04723 {
04724    int num_new_samples = frame->samples;
04725    struct plc_ds *plc = datastore->data;
04726 
04727    /* As a general note, let me explain the somewhat odd calculations used when taking
04728     * the frame offset into account here. According to documentation in frame.h, the frame's
04729     * offset field indicates the number of bytes that the audio is offset. The plc->samples_buf
04730     * is not an array of bytes, but rather an array of 16-bit integers since it holds SLIN
04731     * samples. So I had two choices to make here with the offset.
04732     * 
04733     * 1. Make the offset AST_FRIENDLY_OFFSET bytes. The main downside for this is that
04734     *    I can't just add AST_FRIENDLY_OFFSET to the plc->samples_buf and have the pointer
04735     *    arithmetic come out right. I would have to do some odd casting or division for this to
04736     *    work as I wanted.
04737     * 2. Make the offset AST_FRIENDLY_OFFSET * 2 bytes. This allows the pointer arithmetic
04738     *    to work out better with the plc->samples_buf. The downside here is that the buffer's
04739     *    allocation contains an extra 64 bytes of unused space.
04740     * 
04741     * I decided to go with option 2. This is why in the calloc statement and the statement that
04742     * sets the frame's offset, AST_FRIENDLY_OFFSET is multiplied by 2.
04743     */
04744 
04745    /* If this audio frame has no samples to fill in, ignore it */
04746    if (!num_new_samples) {
04747       return;
04748    }
04749 
04750    /* First, we need to be sure that our buffer is large enough to accomodate
04751     * the samples we need to fill in. This will likely only occur on the first
04752     * frame we write.
04753     */
04754    if (plc->num_samples < num_new_samples) {
04755       ast_free(plc->samples_buf);
04756       plc->samples_buf = ast_calloc(1, (num_new_samples * sizeof(*plc->samples_buf)) + (AST_FRIENDLY_OFFSET * 2));
04757       if (!plc->samples_buf) {
04758          ast_channel_datastore_remove(chan, datastore);
04759          ast_datastore_free(datastore);
04760          return;
04761       }
04762       plc->num_samples = num_new_samples;
04763    }
04764 
04765    if (frame->datalen == 0) {
04766       plc_fillin(&plc->plc_state, plc->samples_buf + AST_FRIENDLY_OFFSET, frame->samples);
04767       frame->data.ptr = plc->samples_buf + AST_FRIENDLY_OFFSET;
04768       frame->datalen = num_new_samples * 2;
04769       frame->offset = AST_FRIENDLY_OFFSET * 2;
04770    } else {
04771       plc_rx(&plc->plc_state, frame->data.ptr, frame->samples);
04772    }
04773 }

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

Definition at line 4775 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(), chanlist::chan, ast_datastore::data, and plc_ds_info.

Referenced by ast_write().

04776 {
04777    struct ast_datastore *datastore;
04778    struct plc_ds *plc;
04779 
04780    datastore = ast_channel_datastore_find(chan, &plc_ds_info, NULL);
04781    if (datastore) {
04782       plc = datastore->data;
04783       adjust_frame_for_plc(chan, frame, datastore);
04784       return;
04785    }
04786 
04787    datastore = ast_datastore_alloc(&plc_ds_info, NULL);
04788    if (!datastore) {
04789       return;
04790    }
04791    plc = ast_calloc(1, sizeof(*plc));
04792    if (!plc) {
04793       ast_datastore_free(datastore);
04794       return;
04795    }
04796    datastore->data = plc;
04797    ast_channel_datastore_add(chan, datastore);
04798    adjust_frame_for_plc(chan, frame, datastore);
04799 }

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

Activate a given generator

Definition at line 3100 of file channel.c.

References ast_generator::alloc, ast_channel_lock, ast_channel_unlock, ast_prod(), ast_settimeout(), chanlist::chan, gen, ast_channel::generator, generator_force(), ast_channel::generatordata, and ast_generator::release.

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

03101 {
03102    int res = 0;
03103 
03104    ast_channel_lock(chan);
03105    if (chan->generatordata) {
03106       if (chan->generator && chan->generator->release)
03107          chan->generator->release(chan, chan->generatordata);
03108       chan->generatordata = NULL;
03109    }
03110    if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) {
03111       res = -1;
03112    }
03113    if (!res) {
03114       ast_settimeout(chan, 50, generator_force, chan);
03115       chan->generator = gen;
03116    }
03117    ast_channel_unlock(chan);
03118 
03119    ast_prod(chan);
03120 
03121    return res;
03122 }

int ast_active_channels ( void   ) 

returns number of active/allocated channels

Returns:
number of channels available for lookup

Definition at line 837 of file channel.c.

References ao2_container_count(), and channels.

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

00838 {
00839    return channels ? ao2_container_count(channels) : 0;
00840 }

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

References __ast_answer(), and chanlist::chan.

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(), builtin_parkcall(), common_exec(), conf_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(), 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().

03051 {
03052    return __ast_answer(chan, 0, 1);
03053 }

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

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

Referenced by can_safely_quit().

00828 {
00829    shutting_down = 1;
00830 
00831    if (hangup) {
00832       ao2_callback(channels, OBJ_NODATA | OBJ_MULTIPLE, ast_channel_softhangup_cb, NULL);
00833    }
00834 }

format_t ast_best_codec ( format_t  fmts  ) 

Pick the best audio codec.

Pick the best codec Choose the best codec... Uhhh... Yah.

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

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

References ARRAY_LEN, AST_FORMAT_ADPCM, AST_FORMAT_ALAW, AST_FORMAT_AUDIO_MASK, 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_SIREN14, AST_FORMAT_SIREN7, AST_FORMAT_SLINEAR, AST_FORMAT_SLINEAR16, AST_FORMAT_SPEEX, AST_FORMAT_SPEEX16, AST_FORMAT_TESTLAW, AST_FORMAT_ULAW, ast_getformatname_multiple(), ast_log(), LOG_WARNING, and prefs.

Referenced by __oh323_new(), agent_call(), ast_codec_choose(), ast_iax2_new(), ast_speech_new(), bridge_make_compatible(), builtin_atxfer(), echo_exec(), findmeexec(), gtalk_new(), handle_open_receive_channel_ack_message(), iax2_request(), jingle_new(), local_new(), login_exec(), mgcp_new(), multicast_rtp_request(), set_format(), sip_new(), skinny_new(), skinny_set_rtp_peer(), socket_process(), start_rtp(), transmit_connect(), and unistim_new().

01052 {
01053    /* This just our opinion, expressed in code.  We are asked to choose
01054       the best codec to use, given no information */
01055    int x;
01056    static const format_t prefs[] =
01057    {
01058       /*! Okay, ulaw is used by all telephony equipment, so start with it */
01059       AST_FORMAT_ULAW,
01060       /*! Unless of course, you're a silly European, so then prefer ALAW */
01061       AST_FORMAT_ALAW,
01062       AST_FORMAT_G719,
01063       AST_FORMAT_SIREN14,
01064       AST_FORMAT_SIREN7,
01065       AST_FORMAT_TESTLAW,
01066       /*! G.722 is better then all below, but not as common as the above... so give ulaw and alaw priority */
01067       AST_FORMAT_G722,
01068       /*! Okay, well, signed linear is easy to translate into other stuff */
01069       AST_FORMAT_SLINEAR16,
01070       AST_FORMAT_SLINEAR,
01071       /*! G.726 is standard ADPCM, in RFC3551 packing order */
01072       AST_FORMAT_G726,
01073       /*! G.726 is standard ADPCM, in AAL2 packing order */
01074       AST_FORMAT_G726_AAL2,
01075       /*! ADPCM has great sound quality and is still pretty easy to translate */
01076       AST_FORMAT_ADPCM,
01077       /*! Okay, we're down to vocoders now, so pick GSM because it's small and easier to
01078           translate and sounds pretty good */
01079       AST_FORMAT_GSM,
01080       /*! iLBC is not too bad */
01081       AST_FORMAT_ILBC,
01082       /*! Speex is free, but computationally more expensive than GSM */
01083       AST_FORMAT_SPEEX16,
01084       AST_FORMAT_SPEEX,
01085       /*! Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough
01086           to use it */
01087       AST_FORMAT_LPC10,
01088       /*! G.729a is faster than 723 and slightly less expensive */
01089       AST_FORMAT_G729A,
01090       /*! Down to G.723.1 which is proprietary but at least designed for voice */
01091       AST_FORMAT_G723_1,
01092    };
01093    char buf[512];
01094 
01095    /* Strip out video */
01096    fmts &= AST_FORMAT_AUDIO_MASK;
01097    
01098    /* Find the first preferred codec in the format given */
01099    for (x = 0; x < ARRAY_LEN(prefs); x++) {
01100       if (fmts & prefs[x])
01101          return prefs[x];
01102    }
01103 
01104    ast_log(LOG_WARNING, "Don't know any of %s formats\n", ast_getformatname_multiple(buf, sizeof(buf), fmts));
01105 
01106    return 0;
01107 }

struct ast_channel* ast_bridged_channel ( struct ast_channel chan  ) 

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

References ast_channel::_bridge, ast_channel_tech::bridged_channel, chanlist::chan, 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(), 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(), sig_pri_attempt_transfer(), sip_get_rtp_peer(), sip_get_trtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), sip_hangup(), sip_set_rtp_peer(), skinny_transfer(), socket_process(), start_spying(), startmon(), TransferCallStep1(), and unistim_hangup().

06995 {
06996    struct ast_channel *bridged;
06997    bridged = chan->_bridge;
06998    if (bridged && bridged->tech->bridged_channel)
06999       bridged = bridged->tech->bridged_channel(chan, bridged);
07000    return bridged;
07001 }

int ast_call ( struct ast_channel chan,
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 (Should be treated as const char *)
timeout time to wait on for connect
Place a call, take no longer than timeout ms.
Returns:
-1 on failure, 0 on not enough time (does not automatically stop ringing), and the number of seconds the connect took otherwise.

Definition at line 5645 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, chanlist::chan, and ast_channel::tech.

Referenced by __ast_request_and_dial(), ast_call_forward(), begin_dial_channel(), dial_exec_full(), dial_transfer(), do_forward(), do_idle_thread(), feature_request_and_dial(), findmeexec(), play_sound_file(), and ring_entry().

05646 {
05647    /* Place an outgoing call, but don't wait any longer than timeout ms before returning.
05648       If the remote end does not answer within the timeout, then do NOT hang up, but
05649       return anyway.  */
05650    int res = -1;
05651    /* Stop if we're a zombie or need a soft hangup */
05652    ast_channel_lock(chan);
05653    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
05654       if (chan->cdr) {
05655          ast_set_flag(chan->cdr, AST_CDR_FLAG_DIALED);
05656       }
05657       if (chan->tech->call)
05658          res = chan->tech->call(chan, addr, timeout);
05659       ast_set_flag(chan, AST_FLAG_OUTGOING);
05660    }
05661    ast_channel_unlock(chan);
05662    return res;
05663 }

struct ast_channel* ast_call_forward ( struct ast_channel caller,
struct ast_channel orig,
int *  timeout,
format_t  format,
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.

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 requested channel format
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 5271 of file channel.c.

References outgoing_helper::account, ast_channel::accountcode, accountcode, ast_call(), AST_CDR_FLAG_ORIGINATED, ast_cdr_setaccount(), 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(), ast_string_field_set, ast_channel::call_forward, call_forward_inherit(), ast_channel::caller, 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().

05272 {
05273    char tmpchan[256];
05274    struct ast_channel *new_chan = NULL;
05275    char *data, *type;
05276    int cause = 0;
05277    int res;
05278 
05279    /* gather data and request the new forward channel */
05280    ast_copy_string(tmpchan, orig->call_forward, sizeof(tmpchan));
05281    if ((data = strchr(tmpchan, '/'))) {
05282       *data++ = '\0';
05283       type = tmpchan;
05284    } else {
05285       const char *forward_context;
05286       ast_channel_lock(orig);
05287       forward_context = pbx_builtin_getvar_helper(orig, "FORWARD_CONTEXT");
05288       snprintf(tmpchan, sizeof(tmpchan), "%s@%s", orig->call_forward, S_OR(forward_context, orig->context));
05289       ast_channel_unlock(orig);
05290       data = tmpchan;
05291       type = "Local";
05292    }
05293    if (!(new_chan = ast_request(type, format, orig, data, &cause))) {
05294       ast_log(LOG_NOTICE, "Unable to create channel for call forward to '%s/%s' (cause = %d)\n", type, data, cause);
05295       handle_cause(cause, outstate);
05296       ast_hangup(orig);
05297       return NULL;
05298    }
05299 
05300    /* Copy/inherit important information into new channel */
05301    if (oh) {
05302       if (oh->vars) {
05303          ast_set_variables(new_chan, oh->vars);
05304       }
05305       if (oh->parent_channel) {
05306          call_forward_inherit(new_chan, oh->parent_channel, orig);
05307       }
05308       if (oh->account) {
05309          ast_channel_lock(new_chan);
05310          ast_cdr_setaccount(new_chan, oh->account);
05311          ast_channel_unlock(new_chan);
05312       }
05313    } else if (caller) { /* no outgoing helper so use caller if avaliable */
05314       call_forward_inherit(new_chan, caller, orig);
05315    }
05316 
05317    ast_channel_lock_both(orig, new_chan);
05318    ast_copy_flags(new_chan->cdr, orig->cdr, AST_CDR_FLAG_ORIGINATED);
05319    ast_string_field_set(new_chan, accountcode, orig->accountcode);
05320    ast_party_connected_line_copy(&new_chan->connected, &orig->connected);
05321    ast_party_redirecting_copy(&new_chan->redirecting, &orig->redirecting);
05322    ast_channel_unlock(new_chan);
05323    ast_channel_unlock(orig);
05324 
05325    /* call new channel */
05326    res = ast_call(new_chan, data, 0);
05327    if (timeout) {
05328       *timeout = res;
05329    }
05330    if (res) {
05331       ast_log(LOG_NOTICE, "Unable to call forward to channel %s/%s\n", type, (char *)data);
05332       ast_hangup(orig);
05333       ast_hangup(new_chan);
05334       return NULL;
05335    }
05336    ast_hangup(orig);
05337 
05338    return new_chan;
05339 }

void ast_cancel_shutdown ( void   ) 

Cancel a shutdown in progress.

Cancels an existing shutdown and returns to normal operation

Definition at line 848 of file channel.c.

Referenced by handle_abort_shutdown().

00849 {
00850    shutting_down = 0;
00851 }

const char* ast_cause2str ( int  state  ) 

Gives the string form of a given cause code.

Parameters:
state cause to get the description of
Returns:
the text form of the binary cause code given

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

00970 {
00971    int x;
00972 
00973    for (x = 0; x < ARRAY_LEN(causes); x++) {
00974       if (causes[x].cause == cause)
00975          return causes[x].desc;
00976    }
00977 
00978    return "Unknown";
00979 }

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

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

Referenced by update_name().

06114 {
06115    /* We must re-link, as the hash value will change here. */
06116    ao2_lock(channels);
06117    ast_channel_lock(chan);
06118    ao2_unlink(channels, chan);
06119    __ast_change_name_nolink(chan, newname);
06120    ao2_link(channels, chan);
06121    ast_channel_unlock(chan);
06122    ao2_unlock(channels);
06123 }

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,
  ... 
)

Definition at line 9603 of file channel.c.

References __ast_channel_alloc_ap().

09608 {
09609    va_list ap1, ap2;
09610    struct ast_channel *result;
09611 
09612 
09613    va_start(ap1, name_fmt);
09614    va_start(ap2, name_fmt);
09615    result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context,
09616                linkedid, amaflag, __FILE__, __LINE__, __FUNCTION__, name_fmt, ap1, ap2);
09617    va_end(ap1);
09618    va_end(ap2);
09619 
09620    return result;
09621 }

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 7337 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_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_framehook_list_is_empty(), ast_generic_bridge(), ast_indicate(), ast_log(), ast_manager_event_multichan, 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_channel::caller, config, EVENT_FLAG_CALL, ast_channel::framehooks, ast_channel::generator, ast_party_caller::id, LOG_WARNING, manager_bridge_event(), ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::name, ast_channel::nativeformats, ast_party_id::number, ast_channel::readformat, S_COR, ast_channel_tech::send_digit_begin, ast_party_number::str, ast_channel::tech, ast_channel::uniqueid, update_bridge_vars(), ast_party_number::valid, and ast_channel::writeformat.

Referenced by ast_bridge_call().

07339 {
07340    struct ast_channel *chans[2] = { c0, c1 };
07341    enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
07342    format_t o0nativeformats;
07343    format_t o1nativeformats;
07344    long time_left_ms=0;
07345    char caller_warning = 0;
07346    char callee_warning = 0;
07347 
07348    *fo = NULL;
07349 
07350    if (c0->_bridge) {
07351       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
07352          c0->name, c0->_bridge->name);
07353       return -1;
07354    }
07355    if (c1->_bridge) {
07356       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
07357          c1->name, c1->_bridge->name);
07358       return -1;
07359    }
07360    
07361    /* Stop if we're a zombie or need a soft hangup */
07362    if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
07363        ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1))
07364       return -1;
07365 
07366    caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING);
07367    callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING);
07368 
07369    if (ast_tvzero(config->start_time)) {
07370       config->start_time = ast_tvnow();
07371       if (config->start_sound) {
07372          if (caller_warning) {
07373             bridge_playfile(c0, c1, config->start_sound, config->timelimit / 1000);
07374          }
07375          if (callee_warning) {
07376             bridge_playfile(c1, c0, config->start_sound, config->timelimit / 1000);
07377          }
07378       }
07379    }
07380 
07381    /* Keep track of bridge */
07382    c0->_bridge = c1;
07383    c1->_bridge = c0;
07384 
07385    ast_set_owners_and_peers(c0, c1);
07386 
07387    o0nativeformats = c0->nativeformats;
07388    o1nativeformats = c1->nativeformats;
07389 
07390    if (config->feature_timer && !ast_tvzero(config->nexteventts)) {
07391       config->nexteventts = ast_tvadd(config->feature_start_time, ast_samp2tv(config->feature_timer, 1000));
07392    } else if (config->timelimit) {
07393       time_left_ms = config->timelimit - ast_tvdiff_ms(ast_tvnow(), config->start_time);
07394       config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
07395       if ((caller_warning || callee_warning) && config->play_warning) {
07396          long next_warn = config->play_warning;
07397          if (time_left_ms < config->play_warning && config->warning_freq > 0) {
07398             /* At least one warning was played, which means we are returning after feature */
07399             long warns_passed = (config->play_warning - time_left_ms) / config->warning_freq;
07400             /* It is 'warns_passed * warning_freq' NOT '(warns_passed + 1) * warning_freq',
07401                because nexteventts will be updated once again in the 'if (!to)' block */
07402             next_warn = config->play_warning - warns_passed * config->warning_freq;
07403          }
07404          config->nexteventts = ast_tvsub(config->nexteventts, ast_samp2tv(next_warn, 1000));
07405       }
07406    } else {
07407       config->nexteventts.tv_sec = 0;
07408       config->nexteventts.tv_usec = 0;
07409    }
07410 
07411    if (!c0->tech->send_digit_begin)
07412       ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY);
07413    if (!c1->tech->send_digit_begin)
07414       ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY);
07415    manager_bridge_event(1, 1, c0, c1);
07416 
07417    /* Before we enter in and bridge these two together tell them both the source of audio has changed */
07418    ast_indicate(c0, AST_CONTROL_SRCUPDATE);
07419    ast_indicate(c1, AST_CONTROL_SRCUPDATE);
07420 
07421    for (/* ever */;;) {
07422       struct timeval now = { 0, };
07423       int to;
07424 
07425       to = -1;
07426 
07427       if (!ast_tvzero(config->nexteventts)) {
07428          now = ast_tvnow();
07429          to = ast_tvdiff_ms(config->nexteventts, now);
07430          if (to <= 0) {
07431             if (!config->timelimit) {
07432                res = AST_BRIDGE_COMPLETE;
07433                break;
07434             }
07435             to = 0;
07436          }
07437       }
07438 
07439       if (config->timelimit) {
07440          time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time);
07441          if (time_left_ms < to)
07442             to = time_left_ms;
07443 
07444          if (time_left_ms <= 0) {
07445             if (caller_warning && config->end_sound)
07446                bridge_playfile(c0, c1, config->end_sound, 0);
07447             if (callee_warning && config->end_sound)
07448                bridge_playfile(c1, c0, config->end_sound, 0);
07449             *fo = NULL;
07450             res = 0;
07451             break;
07452          }
07453 
07454          if (!to) {
07455             if (time_left_ms >= 5000 && config->warning_sound && config->play_warning && ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) {
07456                int t = (time_left_ms + 500) / 1000; /* round to nearest second */
07457                if (caller_warning)
07458                   bridge_playfile(c0, c1, config->warning_sound, t);
07459                if (callee_warning)
07460                   bridge_playfile(c1, c0, config->warning_sound, t);
07461             }
07462 
07463             if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000))) {
07464                config->nexteventts = ast_tvadd(config->nexteventts, ast_samp2tv(config->warning_freq, 1000));
07465             } else {
07466                config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
07467             }
07468          }
07469          ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE);
07470       }
07471 
07472       if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */
07473          if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
07474             ast_channel_clear_softhangup(c0, AST_SOFTHANGUP_UNBRIDGE);
07475          }
07476          if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
07477             ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE);
07478          }
07479          c0->_bridge = c1;
07480          c1->_bridge = c0;
07481          ast_debug(1, "Unbridge signal received. Ending native bridge.\n");
07482          continue;
07483       }
07484 
07485       /* Stop if we're a zombie or need a soft hangup */
07486       if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
07487           ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) {
07488          *fo = NULL;
07489          res = 0;
07490          ast_debug(1, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n",
07491             c0->name, c1->name,
07492             ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No",
07493             ast_check_hangup(c0) ? "Yes" : "No",
07494             ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No",
07495             ast_check_hangup(c1) ? "Yes" : "No");
07496          break;
07497       }
07498 
07499       update_bridge_vars(c0, c1);
07500 
07501       bridge_play_sounds(c0, c1);
07502 
07503       if (c0->tech->bridge &&
07504          /* if < 1 ms remains use generic bridging for accurate timing */
07505          (!config->timelimit || to > 1000 || to == 0) &&
07506           (c0->tech->bridge == c1->tech->bridge) &&
07507           !c0->monitor && !c1->monitor &&
07508           !c0->audiohooks && !c1->audiohooks &&
07509           ast_framehook_list_is_empty(c0->framehooks) && ast_framehook_list_is_empty(c1->framehooks) &&
07510           !c0->masq && !c0->masqr && !c1->masq && !c1->masqr) {
07511          int timeoutms = to - 1000 > 0 ? to - 1000 : to;
07512          /* Looks like they share a bridge method and nothing else is in the way */
07513          ast_set_flag(c0, AST_FLAG_NBRIDGE);
07514          ast_set_flag(c1, AST_FLAG_NBRIDGE);
07515          if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, timeoutms)) == AST_BRIDGE_COMPLETE) {
07516             ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans,
07517                "Channel1: %s\r\n"
07518                "Channel2: %s\r\n"
07519                "Uniqueid1: %s\r\n"
07520                "Uniqueid2: %s\r\n"
07521                "CallerID1: %s\r\n"
07522                "CallerID2: %s\r\n",
07523                c0->name, c1->name,
07524                c0->uniqueid, c1->uniqueid,
07525                S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"),
07526                S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>"));
07527 
07528             ast_debug(1, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name);
07529 
07530             ast_clear_flag(c0, AST_FLAG_NBRIDGE);
07531             ast_clear_flag(c1, AST_FLAG_NBRIDGE);
07532 
07533             if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */
07534                continue;
07535             }
07536 
07537             c0->_bridge = NULL;
07538             c1->_bridge = NULL;
07539             return res;
07540          } else {
07541             ast_clear_flag(c0, AST_FLAG_NBRIDGE);
07542             ast_clear_flag(c1, AST_FLAG_NBRIDGE);
07543          }
07544          switch (res) {
07545          case AST_BRIDGE_RETRY:
07546             if (config->play_warning) {
07547                ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
07548             }
07549             continue;
07550          default:
07551             ast_verb(3, "Native bridging %s and %s ended\n", c0->name, c1->name);
07552             /* fallthrough */
07553          case AST_BRIDGE_FAILED_NOWARN:
07554             break;
07555          }
07556       }
07557 
07558       if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) ||
07559           (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) &&
07560           !(c0->generator || c1->generator)) {
07561          if (ast_channel_make_compatible(c0, c1)) {
07562             ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
07563             manager_bridge_event(0, 1, c0, c1);
07564             return AST_BRIDGE_FAILED;
07565          }
07566          o0nativeformats = c0->nativeformats;
07567          o1nativeformats = c1->nativeformats;
07568       }
07569 
07570       update_bridge_vars(c0, c1);
07571 
07572       res = ast_generic_bridge(c0, c1, config, fo, rc);
07573       if (res != AST_BRIDGE_RETRY) {
07574          break;
07575       } else if (config->feature_timer) {
07576          /* feature timer expired but has not been updated, sending to ast_bridge_call to do so */
07577          break;
07578       }
07579    }
07580 
07581    ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY);
07582    ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY);
07583 
07584    /* Now that we have broken the bridge the source will change yet again */
07585    ast_indicate(c0, AST_CONTROL_SRCUPDATE);
07586    ast_indicate(c1, AST_CONTROL_SRCUPDATE);
07587 
07588    c0->_bridge = NULL;
07589    c1->_bridge = NULL;
07590 
07591    ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans,
07592       "Channel1: %s\r\n"
07593       "Channel2: %s\r\n"
07594       "Uniqueid1: %s\r\n"
07595       "Uniqueid2: %s\r\n"
07596       "CallerID1: %s\r\n"
07597       "CallerID2: %s\r\n",
07598       c0->name, c1->name,
07599       c0->uniqueid, c1->uniqueid,
07600       S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"),
07601       S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>"));
07602    ast_debug(1, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name);
07603 
07604    return res;
07605 }

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

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

References ao2_callback_data, and channels.

Referenced by 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().

01608 {
01609    return ao2_callback_data(channels, ao2_flags, cb_fn, arg, data);
01610 }

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

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

09511 {
09512    struct ast_cc_config_params *cc_params;
09513    struct ast_datastore *cc_datastore;
09514 
09515    if (!(cc_params = ast_cc_config_params_init())) {
09516       return -1;
09517    }
09518 
09519    if (!(cc_datastore = ast_datastore_alloc(&cc_channel_datastore_info, NULL))) {
09520       ast_cc_config_params_destroy(cc_params);
09521       return -1;
09522    }
09523 
09524    if (base_params) {
09525       ast_cc_copy_config_params(cc_params, base_params);
09526    }
09527    cc_datastore->data = cc_params;
09528    ast_channel_datastore_add(chan, cc_datastore);
09529    return 0;
09530 }

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

References ast_assert, ast_cel_check_retire_linkedid(), ast_cel_linkedid_ref(), ast_string_field_set, chanlist::chan, and ast_channel::linkedid.

Referenced by ast_channel_set_linkgroup().

06254 {
06255    ast_assert(linkedid != NULL);
06256    /* if the linkedid for this channel is being changed from something, check... */
06257    if (!strcmp(chan->linkedid, linkedid)) {
06258       return;
06259    }
06260 
06261    ast_cel_check_retire_linkedid(chan);
06262    ast_string_field_set(chan, linkedid, linkedid);
06263    ast_cel_linkedid_ref(linkedid);
06264 }

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 2674 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, chanlist::chan, ast_frame::frametype, ast_frame_subclass::integer, ast_channel::readq, and ast_frame::subclass.

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

02675 {
02676    ast_channel_lock(chan);
02677 
02678    chan->_softhangup &= ~flag;
02679 
02680    if (!chan->_softhangup) {
02681       struct ast_frame *fr;
02682 
02683       /* If we have completely cleared the softhangup flag,
02684        * then we need to fully abort the hangup process.  This requires
02685        * pulling the END_OF_Q frame out of the channel frame queue if it
02686        * still happens to be there. */
02687 
02688       fr = AST_LIST_LAST(&chan->readq);
02689       if (fr && fr->frametype == AST_FRAME_CONTROL &&
02690             fr->subclass.integer == AST_CONTROL_END_OF_Q) {
02691          AST_LIST_REMOVE(&chan->readq, fr, frame_list);
02692          ast_frfree(fr);
02693       }
02694    }
02695 
02696    ast_channel_unlock(chan);
02697 }

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

Definition at line 1692 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_strlen_zero(), chanlist::chan, CMP_MATCH, ast_channel::context, ast_channel::exten, ast_channel::macrocontext, ast_channel::macroexten, ast_channel::name, and ast_channel::uniqueid.

01693 {
01694    struct ast_channel *chan = obj, *cmp_args = arg;
01695    size_t name_len;
01696    int ret = CMP_MATCH;
01697 
01698    /* This is sort of a hack.  Basically, we're using an arbitrary field
01699     * in ast_channel to pass the name_len for a prefix match.  If this
01700     * gets changed, then the uses of ao2_find() must be changed, too. */
01701    name_len = cmp_args->rings;
01702 
01703    ast_channel_lock(chan);
01704 
01705    if (!ast_strlen_zero(cmp_args->name)) { /* match by name */
01706       if ((!name_len && strcasecmp(chan->name, cmp_args->name)) ||
01707             (name_len && strncasecmp(chan->name, cmp_args->name, name_len))) {
01708          ret = 0; /* name match failed */
01709       }
01710    } else if (!ast_strlen_zero(cmp_args->exten)) {
01711       if (cmp_args->context && strcasecmp(chan->context, cmp_args->context) &&
01712             strcasecmp(chan->macrocontext, cmp_args->context)) {
01713          ret = 0; /* context match failed */
01714       }
01715       if (ret && strcasecmp(chan->exten, cmp_args->exten) &&
01716             strcasecmp(chan->macroexten, cmp_args->exten)) {
01717          ret = 0; /* exten match failed */
01718       }
01719    } else if (!ast_strlen_zero(cmp_args->uniqueid)) {
01720       if ((!name_len && strcasecmp(chan->uniqueid, cmp_args->uniqueid)) ||
01721             (name_len && strncasecmp(chan->uniqueid, cmp_args->uniqueid, name_len))) {
01722          ret = 0; /* uniqueid match failed */
01723       }
01724    } else {
01725       ret = 0;
01726    }
01727 
01728    ast_channel_unlock(chan);
01729 
01730    return ret;
01731 }

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

References ast_channel_cmpwhentohangup_tv(), and chanlist::chan.

00890 {
00891    struct timeval when = { offset, };
00892    return ast_channel_cmpwhentohangup_tv(chan, when);
00893 }

int ast_channel_cmpwhentohangup_tv ( struct ast_channel chan,
struct timeval  offset 
)

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

Parameters:
chan channel on which to check for hangup
offset offset in seconds and microseconds 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.
Since:
1.6.1

Definition at line 874 of file channel.c.

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

Referenced by ast_channel_cmpwhentohangup().

00875 {
00876    struct timeval whentohangup;
00877 
00878    if (ast_tvzero(chan->whentohangup))
00879       return ast_tvzero(offset) ? 0 : -1;
00880 
00881    if (ast_tvzero(offset))
00882       return 1;
00883 
00884    whentohangup = ast_tvadd(offset, ast_tvnow());
00885 
00886    return ast_tvdiff_ms(whentohangup, chan->whentohangup);
00887 }

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

Make constants so that caller and frame can be more expressive than just '1' and '0'

Definition at line 9396 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_party_connected_line_free(), ast_party_connected_line_init(), ast_strdupa, ast_strlen_zero(), 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(), atxfer_fail_cleanup(), builtin_atxfer(), feature_request_and_dial(), handle_frame(), parked_call_exec(), remote_bridge_loop(), and wait_for_answer().

09397 {
09398    const char *macro;
09399    const char *macro_args;
09400    int retval;
09401 
09402    ast_channel_lock(macro_chan);
09403    macro = pbx_builtin_getvar_helper(macro_chan, is_caller
09404       ? "CONNECTED_LINE_CALLER_SEND_MACRO" : "CONNECTED_LINE_CALLEE_SEND_MACRO");
09405    macro = ast_strdupa(S_OR(macro, ""));
09406    macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller
09407       ? "CONNECTED_LINE_CALLER_SEND_MACRO_ARGS" : "CONNECTED_LINE_CALLEE_SEND_MACRO_ARGS");
09408    macro_args = ast_strdupa(S_OR(macro_args, ""));
09409 
09410    if (ast_strlen_zero(macro)) {
09411       ast_channel_unlock(macro_chan);
09412       return -1;
09413    }
09414 
09415    if (is_frame) {
09416       const struct ast_frame *frame = connected_info;
09417 
09418       ast_connected_line_parse_data(frame->data.ptr, frame->datalen, &macro_chan->connected);
09419    } else {
09420       const struct ast_party_connected_line *connected = connected_info;
09421 
09422       ast_party_connected_line_copy(&macro_chan->connected, connected);
09423    }
09424    ast_channel_unlock(macro_chan);
09425 
09426    retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args);
09427    if (!retval) {
09428       struct ast_party_connected_line saved_connected;
09429 
09430       ast_party_connected_line_init(&saved_connected);
09431       ast_channel_lock(macro_chan);
09432       ast_party_connected_line_copy(&saved_connected, &macro_chan->connected);
09433       ast_channel_unlock(macro_chan);
09434       ast_channel_update_connected_line(macro_chan, &saved_connected, NULL);
09435       ast_party_connected_line_free(&saved_connected);
09436    }
09437 
09438    return retval;
09439 }

int ast_channel_data_add_structure ( struct ast_data tree,
struct ast_channel chan,
int  add_bridged 
)

Insert into an astdata tree, the channel structure.

Parameters:
[in] tree The ast data tree.
[in] chan The channel structure to add to tree.
[in] add_bridged Add the bridged channel to the structure.
Return values:
<0 on error.
0 on success.

Definition at line 347 of file channel.c.

References ast_channel::_softhangup, ast_channel::_state, ast_channel::amaflags, ast_bridged_channel(), ast_cause2str(), ast_cdr_data_add_structure(), ast_cdr_flags2str(), ast_channel_data_add_structure(), ast_data_add_bool(), ast_data_add_codecs(), ast_data_add_int(), ast_data_add_node(), ast_data_add_str(), ast_data_add_structure, ast_data_add_uint(), AST_SOFTHANGUP_APPUNLOAD, AST_SOFTHANGUP_ASYNCGOTO, AST_SOFTHANGUP_DEV, AST_SOFTHANGUP_EXPLICIT, AST_SOFTHANGUP_SHUTDOWN, AST_SOFTHANGUP_TIMEOUT, AST_SOFTHANGUP_UNBRIDGE, ast_state2str(), ast_tone_zone_data_add_structure(), ast_transfercapability2str(), ast_channel::cdr, chanlist::chan, channel_data_add_flags(), ast_channel::hangupcause, ast_channel::nativeformats, ast_channel::oldwriteformat, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::transfercapability, ast_channel::whentohangup, ast_channel::writeformat, and ast_channel::zone.

Referenced by agents_data_provider_get(), ast_channel_data_add_structure(), data_channels_provider_handler(), queues_data_provider_get_helper(), and user_add_provider_cb().

00349 {
00350    struct ast_channel *bc;
00351    struct ast_data *data_bridged;
00352    struct ast_data *data_cdr;
00353    struct ast_data *data_flags;
00354    struct ast_data *data_zones;
00355    struct ast_data *enum_node;
00356    struct ast_data *data_softhangup;
00357 #if 0 /* XXX AstData: ast_callerid no longer exists. (Equivalent code not readily apparent.) */
00358    struct ast_data *data_callerid;
00359    char value_str[100];
00360 #endif
00361 
00362    if (!tree) {
00363       return -1;
00364    }
00365 
00366    ast_data_add_structure(ast_channel, tree, chan);
00367 
00368    if (add_bridged) {
00369       bc = ast_bridged_channel(chan);
00370       if (bc) {
00371          data_bridged = ast_data_add_node(tree, "bridged");
00372          if (!data_bridged) {
00373             return -1;
00374          }
00375          ast_channel_data_add_structure(data_bridged, bc, 0);
00376       }
00377    }
00378 
00379    ast_data_add_codecs(tree, "oldwriteformat", chan->oldwriteformat);
00380    ast_data_add_codecs(tree, "nativeformats", chan->nativeformats);
00381    ast_data_add_codecs(tree, "readformat", chan->readformat);
00382    ast_data_add_codecs(tree, "writeformat", chan->writeformat);
00383    ast_data_add_codecs(tree, "rawreadformat", chan->rawreadformat);
00384    ast_data_add_codecs(tree, "rawwriteformat", chan->rawwriteformat);
00385 
00386    /* state */
00387    enum_node = ast_data_add_node(tree, "state");
00388    if (!enum_node) {
00389       return -1;
00390    }
00391    ast_data_add_str(enum_node, "text", ast_state2str(chan->_state));
00392    ast_data_add_int(enum_node, "value", chan->_state);
00393 
00394    /* hangupcause */
00395    enum_node = ast_data_add_node(tree, "hangupcause");
00396    if (!enum_node) {
00397       return -1;
00398    }
00399    ast_data_add_str(enum_node, "text", ast_cause2str(chan->hangupcause));
00400    ast_data_add_int(enum_node, "value", chan->hangupcause);
00401 
00402    /* amaflags */
00403    enum_node = ast_data_add_node(tree, "amaflags");
00404    if (!enum_node) {
00405       return -1;
00406    }
00407    ast_data_add_str(enum_node, "text", ast_cdr_flags2str(chan->amaflags));
00408    ast_data_add_int(enum_node, "value", chan->amaflags);
00409 
00410    /* transfercapability */
00411    enum_node = ast_data_add_node(tree, "transfercapability");
00412    if (!enum_node) {
00413       return -1;
00414    }
00415    ast_data_add_str(enum_node, "text", ast_transfercapability2str(chan->transfercapability));
00416    ast_data_add_int(enum_node, "value", chan->transfercapability);
00417 
00418    /* _softphangup */
00419    data_softhangup = ast_data_add_node(tree, "softhangup");
00420    if (!data_softhangup) {
00421       return -1;
00422    }
00423    ast_data_add_bool(data_softhangup, "dev", chan->_softhangup & AST_SOFTHANGUP_DEV);
00424    ast_data_add_bool(data_softhangup, "asyncgoto", chan->_softhangup & AST_SOFTHANGUP_ASYNCGOTO);
00425    ast_data_add_bool(data_softhangup, "shutdown", chan->_softhangup & AST_SOFTHANGUP_SHUTDOWN);
00426    ast_data_add_bool(data_softhangup, "timeout", chan->_softhangup & AST_SOFTHANGUP_TIMEOUT);
00427    ast_data_add_bool(data_softhangup, "appunload", chan->_softhangup & AST_SOFTHANGUP_APPUNLOAD);
00428    ast_data_add_bool(data_softhangup, "explicit", chan->_softhangup & AST_SOFTHANGUP_EXPLICIT);
00429    ast_data_add_bool(data_softhangup, "unbridge", chan->_softhangup & AST_SOFTHANGUP_UNBRIDGE);
00430 
00431    /* channel flags */
00432    data_flags = ast_data_add_node(tree, "flags");
00433    if (!data_flags) {
00434       return -1;
00435    }
00436    channel_data_add_flags(data_flags, chan);
00437 
00438    ast_data_add_uint(tree, "timetohangup", chan->whentohangup.tv_sec);
00439 
00440 #if 0 /* XXX AstData: ast_callerid no longer exists. (Equivalent code not readily apparent.) */
00441    /* callerid */
00442    data_callerid = ast_data_add_node(tree, "callerid");
00443    if (!data_callerid) {
00444       return -1;
00445    }
00446    ast_data_add_structure(ast_callerid, data_callerid, &(chan->cid));
00447    /* insert the callerid ton */
00448    enum_node = ast_data_add_node(data_callerid, "cid_ton");
00449    if (!enum_node) {
00450       return -1;
00451    }
00452    ast_data_add_int(enum_node, "value", chan->cid.cid_ton);
00453    snprintf(value_str, sizeof(value_str), "TON: %s/Plan: %s",
00454       party_number_ton2str(chan->cid.cid_ton),
00455       party_number_plan2str(chan->cid.cid_ton));
00456    ast_data_add_str(enum_node, "text", value_str);
00457 #endif
00458 
00459    /* tone zone */
00460    if (chan->zone) {
00461       data_zones = ast_data_add_node(tree, "zone");
00462       if (!data_zones) {
00463          return -1;
00464       }
00465       ast_tone_zone_data_add_structure(data_zones, chan->zone);
00466    }
00467 
00468    /* insert cdr */
00469    data_cdr = ast_data_add_node(tree, "cdr");
00470    if (!data_cdr) {
00471       return -1;
00472    }
00473 
00474    ast_cdr_data_add_structure(data_cdr, chan->cdr, 1);
00475 
00476    return 0;
00477 }

int ast_channel_data_cmp_structure ( const struct ast_data_search tree,
struct ast_channel chan,
const char *  structure_name 
)

Compare to channel structures using the data api.

Parameters:
[in] tree The search tree generated by the data api.
[in] chan The channel to compare.
[in] structure_name The name of the node of the channel structure.
Return values:
0 The structure matches.
1 The structure doesn't matches.

Definition at line 479 of file channel.c.

References ast_data_search_cmp_structure, and chanlist::chan.

00481 {
00482    return ast_data_search_cmp_structure(tree, ast_channel, chan, structure_name);
00483 }

int ast_channel_datastore_add ( struct ast_channel chan,
struct ast_datastore datastore 
)

Add a datastore to a channel.

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

Definition at line 2557 of file channel.c.

References AST_LIST_INSERT_HEAD, chanlist::chan, ast_channel::datastores, and ast_datastore::entry.

Referenced by __ast_channel_masquerade(), _macro_exec(), acf_curlopt_write(), acf_iaxvar_write(), add_features_datastore(), add_to_agi(), apply_plc(), ast_cel_fabricate_channel_from_event(), ast_channel_cc_params_init(), ast_do_pickup(), ast_iax2_new(), ast_setup_cc_recall_datastore(), audiohook_volume_get(), authenticate_reply(), calendar_query_exec(), cc_interfaces_datastore_init(), dial_exec_full(), do_notify(), dundi_query_read(), enable_jack_hook(), enum_query_read(), find_or_create_details(), find_transaction(), frame_trace_helper(), func_channel_write_real(), get_lock(), gosub_exec(), lua_get_state(), mute_add_audiohook(), pitchshift_helper(), raise_exception(), set_chan_app_data(), setup_inheritance_datastore(), setup_mixmonitor_ds(), setup_transfer_datastore(), shared_write(), smdi_msg_retrieve_read(), socket_process(), speech_create(), speex_write(), srv_datastore_setup(), and volume_write().

02558 {
02559    int res = 0;
02560 
02561    AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry);
02562 
02563    return res;
02564 }

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

Definition at line 2530 of file channel.c.

References ast_datastore_alloc, and ast_datastore::info.

02531 {
02532    return ast_datastore_alloc(info, uid);
02533 }

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

Definition at line 2571 of file channel.c.

References AST_LIST_TRAVERSE, chanlist::chan, ast_channel::datastores, ast_datastore::entry, ast_datastore::info, and ast_datastore::uid.

02572 {
02573    struct ast_datastore *datastore = NULL;
02574    
02575    if (info == NULL)
02576       return NULL;
02577 
02578    AST_LIST_TRAVERSE(&chan->datastores, datastore, entry) {
02579       if (datastore->info != info) {
02580          continue;
02581       }
02582 
02583       if (uid == NULL) {
02584          /* matched by type only */
02585          break;
02586       }
02587 
02588       if ((datastore->uid != NULL) && !strcasecmp(uid, datastore->uid)) {
02589          /* Matched by type AND uid */
02590          break;
02591       }
02592    }
02593 
02594    return datastore;
02595 }

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

References ast_datastore_free().

02536 {
02537    return ast_datastore_free(datastore);
02538 }

int ast_channel_datastore_inherit ( struct ast_channel from,
struct ast_channel to 
)

Inherit datastores from a parent to a child.

Definition at line 2540 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::entry, 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(), and ring_entry().

02541 {
02542    struct ast_datastore *datastore = NULL, *datastore2;
02543 
02544    AST_LIST_TRAVERSE(&from->datastores, datastore, entry) {
02545       if (datastore->inheritance > 0) {
02546          datastore2 = ast_datastore_alloc(datastore->info, datastore->uid);
02547          if (datastore2) {
02548             datastore2->data = datastore->info->duplicate ? datastore->info->duplicate(datastore->data) : NULL;
02549             datastore2->inheritance = datastore->inheritance == DATASTORE_INHERIT_FOREVER ? DATASTORE_INHERIT_FOREVER : datastore->inheritance - 1;
02550             AST_LIST_INSERT_TAIL(&to->datastores, datastore2, entry);
02551          }
02552       }
02553    }
02554    return 0;
02555 }

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

References AST_LIST_REMOVE, chanlist::chan, ast_channel::datastores, and ast_datastore::entry.

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

02567 {
02568    return AST_LIST_REMOVE(&chan->datastores, datastore, entry) ? 0 : -1;
02569 }

int ast_channel_defer_dtmf ( struct ast_channel chan  ) 

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

Returns:
non-zero if channel was already DTMF-deferred or 0 if channel is just now being DTMF-deferred

Definition at line 1588 of file channel.c.

References AST_FLAG_DEFER_DTMF, ast_set_flag, ast_test_flag, and chanlist::chan.

Referenced by find_cache().

01589 {
01590    int pre = 0;
01591 
01592    if (chan) {
01593       pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF);
01594       ast_set_flag(chan, AST_FLAG_DEFER_DTMF);
01595    }
01596    return pre;
01597 }

static void ast_channel_destructor ( void *  obj  )  [static]

Free a channel structure.

Definition at line 2371 of file channel.c.

References ast_channel::alertpipe, ast_app_group_discard(), ast_atomic_fetchadd_int(), ast_cdr_discard(), AST_CEL_CHANNEL_END, ast_cel_check_retire_linkedid(), ast_cel_report_event(), ast_channel_lock, AST_CHANNEL_NAME, ast_channel_unlock, ast_copy_string(), ast_datastore_free(), AST_DEVICE_UNKNOWN, ast_devstate_changed_literal(), 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_string_field_free_memory, ast_timer_close(), ast_tone_zone_unref(), ast_translator_free_path(), ast_var_delete(), ast_channel::caller, ast_channel::cdr, chanlist::chan, ast_channel::connected, ast_channel::datastores, ast_channel::dialed, ast_datastore::entry, f, free, LOG_WARNING, ast_channel::monitor, ast_channel::music_state, ast_channel::name, ast_channel::pbx, ast_channel::readq, ast_channel::readtrans, ast_channel::redirecting, ast_channel::sched, sched_context_destroy(), 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().

02372 {
02373    struct ast_channel *chan = obj;
02374    int fd;
02375 #ifdef HAVE_EPOLL
02376    int i;
02377 #endif
02378    struct ast_var_t *vardata;
02379    struct ast_frame *f;
02380    struct varshead *headp;
02381    struct ast_datastore *datastore;
02382    char device_name[AST_CHANNEL_NAME];
02383 
02384    if (chan->name) {
02385       /* The string fields were initialized. */
02386       ast_cel_report_event(chan, AST_CEL_CHANNEL_END, NULL, NULL, NULL);
02387       ast_cel_check_retire_linkedid(chan);
02388    }
02389 
02390    /* Get rid of each of the data stores on the channel */
02391    ast_channel_lock(chan);
02392    while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry)))
02393       /* Free the data store */
02394       ast_datastore_free(datastore);
02395    ast_channel_unlock(chan);
02396 
02397    /* Lock and unlock the channel just to be sure nobody has it locked still
02398       due to a reference that was stored in a datastore. (i.e. app_chanspy) */
02399    ast_channel_lock(chan);
02400    ast_channel_unlock(chan);
02401 
02402    if (chan->tech_pvt) {
02403       ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
02404       ast_free(chan->tech_pvt);
02405    }
02406 
02407    if (chan->sched)
02408       sched_context_destroy(chan->sched);
02409 
02410    if (chan->name) {
02411       char *dashptr;
02412 
02413       /* The string fields were initialized. */
02414       ast_copy_string(device_name, chan->name, sizeof(device_name));
02415       if ((dashptr = strrchr(device_name, '-'))) {
02416          *dashptr = '\0';
02417       }
02418    } else {
02419       device_name[0] = '\0';
02420    }
02421 
02422    /* Stop monitoring */
02423    if (chan->monitor)
02424       chan->monitor->stop( chan, 0 );
02425 
02426    /* If there is native format music-on-hold state, free it */
02427    if (chan->music_state)
02428       ast_moh_cleanup(chan);
02429 
02430    /* Free translators */
02431    if (chan->readtrans)
02432       ast_translator_free_path(chan->readtrans);
02433    if (chan->writetrans)
02434       ast_translator_free_path(chan->writetrans);
02435    if (chan->pbx)
02436       ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
02437 
02438    ast_party_dialed_free(&chan->dialed);
02439    ast_party_caller_free(&chan->caller);
02440    ast_party_connected_line_free(&chan->connected);
02441    ast_party_redirecting_free(&chan->redirecting);
02442 
02443    /* Close pipes if appropriate */
02444    if ((fd = chan->alertpipe[0]) > -1)
02445       close(fd);
02446    if ((fd = chan->alertpipe[1]) > -1)
02447       close(fd);
02448    if (chan->timer) {
02449       ast_timer_close(chan->timer);
02450    }
02451 #ifdef HAVE_EPOLL
02452    for (i = 0; i < AST_MAX_FDS; i++) {
02453       if (chan->epfd_data[i])
02454          free(chan->epfd_data[i]);
02455    }
02456    close(chan->epfd);
02457 #endif
02458    while ((f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list)))
02459       ast_frfree(f);
02460    
02461    /* loop over the variables list, freeing all data and deleting list items */
02462    /* no need to lock the list, as the channel is already locked */
02463    headp = &chan->varshead;
02464    while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
02465       ast_var_delete(vardata);
02466 
02467    ast_app_group_discard(chan);
02468 
02469    /* Destroy the jitterbuffer */
02470    ast_jb_destroy(chan);
02471 
02472    if (chan->cdr) {
02473       ast_cdr_discard(chan->cdr);
02474       chan->cdr = NULL;
02475    }
02476 
02477    if (chan->zone) {
02478       chan->zone = ast_tone_zone_unref(chan->zone);
02479    }
02480 
02481    ast_string_field_free_memory(chan);
02482 
02483    if (device_name[0]) {
02484       /*
02485        * We have a device name to notify of a new state.
02486        *
02487        * Queue an unknown state, because, while we know that this particular
02488        * instance is dead, we don't know the state of all other possible
02489        * instances.
02490        */
02491       ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, device_name);
02492    }
02493    ast_atomic_fetchadd_int(&chancount, -1);
02494 }

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

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

Referenced by dial_exec_full().

07238 {
07239    /* Make sure we can early bridge, if not error out */
07240    if (!c0->tech->early_bridge || (c1 && (!c1->tech->early_bridge || c0->tech->early_bridge != c1->tech->early_bridge)))
07241       return -1;
07242 
07243    return c0->tech->early_bridge(c0, c1);
07244 }

struct ast_channel* ast_channel_get_by_exten ( const char *  exten,
const char *  context 
)

Find a channel by extension and context.

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

References ast_channel_get_full().

01786 {
01787    return ast_channel_get_full(NULL, 0, exten, context);
01788 }

struct ast_channel* ast_channel_get_by_name ( const char *  name  ) 

Find a channel by name.

Find a channel that has the same name as the provided argument.

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

Definition at line 1775 of file channel.c.

References ast_channel_get_full().

Referenced by action_add_agi_cmd(), action_aocmessage(), action_atxfer(), action_getvar(), action_hangup(), action_redirect(), action_sendtext(), action_setvar(), action_status(), action_timeout(), ast_async_goto_by_name(), ast_bridge_call(), asyncgoto_exec(), change_monitor_action(), do_pause_or_unpause(), func_mchan_read(), func_mchan_write(), handle_channelstatus(), handle_cli_agi_add_cmd(), handle_core_set_debug_channel(), handle_getvariablefull(), handle_hangup(), handle_redirect(), handle_set_chanvar(), handle_show_chanvar(), handle_showchan(), handle_softhangup(), import_helper(), manager_mute_mixmonitor(), manager_mutestream(), manager_optimize_away(), manager_park(), manager_play_dtmf(), park_call_full(), pbx_builtin_importvar(), senddtmf_exec(), shared_read(), shared_write(), start_monitor_action(), and stop_monitor_action().

01776 {
01777    return ast_channel_get_full(name, 0, NULL, NULL);
01778 }

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

Find a channel by a name prefix.

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

References ast_channel_get_full().

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

01781 {
01782    return ast_channel_get_full(name, name_len, NULL, NULL);
01783 }

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

References ast_channel_queryoption(), ast_copy_string(), AST_OPTION_CC_AGENT_TYPE, and ast_channel::name.

Referenced by find_agent_callbacks().

09572 {
09573    int len = size;
09574    char *slash;
09575 
09576    if (!ast_channel_queryoption(chan, AST_OPTION_CC_AGENT_TYPE, agent_type, &len, 0)) {
09577       return 0;
09578    }
09579 
09580    ast_copy_string(agent_type, chan->name, size);
09581    if ((slash = strchr(agent_type, '/'))) {
09582       *slash = '\0';
09583    }
09584    return 0;
09585 }

struct ast_cc_config_params* ast_channel_get_cc_config_params ( struct ast_channel chan  ) 

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

References ast_assert, ast_channel_cc_params_init(), ast_channel_datastore_find(), cc_channel_datastore_info, 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(), local_request(), sig_pri_cc_available(), and sig_pri_cc_generic_check().

09533 {
09534    struct ast_datastore *cc_datastore;
09535 
09536    if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) {
09537       /* If we can't find the datastore, it almost definitely means that the channel type being
09538        * used has not had its driver modified to parse CC config parameters. The best action
09539        * to take here is to create the parameters on the spot with the defaults set.
09540        */
09541       if (ast_channel_cc_params_init(chan, NULL)) {
09542          return NULL;
09543       }
09544       if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) {
09545          /* Should be impossible */
09546          return NULL;
09547       }
09548    }
09549 
09550    ast_assert(cc_datastore->data != NULL);
09551    return cc_datastore->data;
09552 }

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

References ast_channel_queryoption(), ast_copy_string(), AST_OPTION_DEVICE_NAME, and ast_channel::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(), sig_pri_call(), sig_pri_cc_available(), sig_pri_cc_generic_check(), sip_call(), and sip_handle_cc().

09555 {
09556    int len = name_buffer_length;
09557    char *dash;
09558    if (!ast_channel_queryoption(chan, AST_OPTION_DEVICE_NAME, device_name, &len, 0)) {
09559       return 0;
09560    }
09561 
09562    /* Dang. Do it the old-fashioned way */
09563    ast_copy_string(device_name, chan->name, name_buffer_length);
09564    if ((dash = strrchr(device_name, '-'))) {
09565       *dash = '\0';
09566    }
09567 
09568    return 0;
09569 }

static struct ast_channel* ast_channel_get_full ( const char *  name,
size_t  name_len,
const char *  exten,
const char *  context 
) [static]

Definition at line 1733 of file channel.c.

References ao2_find, ast_copy_string(), ast_strlen_zero(), chanlist::chan, channels, ast_channel::context, ast_channel::exten, ast_channel::name, OBJ_POINTER, and ast_channel::uniqueid.

Referenced by ast_channel_get_by_exten(), ast_channel_get_by_name(), and ast_channel_get_by_name_prefix().

01735 {
01736    struct ast_channel tmp_chan = {
01737       .name = name,
01738       /* This is sort of a hack.  Basically, we're using an arbitrary field
01739        * in ast_channel to pass the name_len for a prefix match.  If this
01740        * gets changed, then the compare callback must be changed, too. */
01741       .rings = name_len,
01742    };
01743    struct ast_channel *chan;
01744 
01745    if (exten) {
01746       ast_copy_string(tmp_chan.exten, exten, sizeof(tmp_chan.exten));
01747    }
01748 
01749    if (context) {
01750       ast_copy_string(tmp_chan.context, context, sizeof(tmp_chan.context));
01751    }
01752 
01753    if ((chan = ao2_find(channels, &tmp_chan,
01754               (!ast_strlen_zero(name) && (name_len == 0)) ? OBJ_POINTER : 0))) {
01755       return chan;
01756    }
01757 
01758    if (!name) {
01759       return NULL;
01760    }
01761 
01762    /* If name was specified, but the result was NULL, 
01763     * try a search on uniqueid, instead. */
01764 
01765    {
01766       struct ast_channel tmp_chan2 = {
01767          .uniqueid = name,
01768          .rings = name_len,
01769       };
01770 
01771       return ao2_find(channels, &tmp_chan2, 0);
01772    }
01773 }

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

Definition at line 7876 of file channel.c.

References ast_str_case_hash(), ast_strlen_zero(), and ast_channel::name.

07877 {
07878    const struct ast_channel *chan = obj;
07879 
07880    /* If the name isn't set, return 0 so that the ao2_find() search will
07881     * start in the first bucket. */
07882    if (ast_strlen_zero(chan->name)) {
07883       return 0;
07884    }
07885 
07886    return ast_str_case_hash(chan->name);
07887 }

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 6125 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(), and ring_entry().

06126 {
06127    struct ast_var_t *current, *newvar;
06128    const char *varname;
06129 
06130    AST_LIST_TRAVERSE(&parent->varshead, current, entries) {
06131       int vartype = 0;
06132 
06133       varname = ast_var_full_name(current);
06134       if (!varname)
06135          continue;
06136 
06137       if (varname[0] == '_') {
06138          vartype = 1;
06139          if (varname[1] == '_')
06140             vartype = 2;
06141       }
06142 
06143       switch (vartype) {
06144       case 1:
06145          newvar = ast_var_assign(&varname[1], ast_var_value(current));
06146          if (newvar) {
06147             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
06148             ast_debug(1, "Copying soft-transferable variable %s.\n", ast_var_name(newvar));
06149          }
06150          break;
06151       case 2:
06152          newvar = ast_var_assign(varname, ast_var_value(current));
06153          if (newvar) {
06154             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
06155             ast_debug(1, "Copying hard-transferable variable %s.\n", ast_var_name(newvar));
06156          }
06157          break;
06158       default:
06159          ast_debug(1, "Not copying variable %s.\n", ast_var_name(current));
06160          break;
06161       }
06162    }
06163 }

struct ast_channel_iterator* ast_channel_iterator_all_new ( void   ) 

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.

Return values:
NULL on failure
a new channel iterator
Since:
1.8

Definition at line 1673 of file channel.c.

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

01674 {
01675    struct ast_channel_iterator *i;
01676 
01677    if (!(i = ast_calloc(1, sizeof(*i)))) {
01678       return NULL;
01679    }
01680 
01681    i->simple_iterator = ao2_iterator_init(channels, 0);
01682    i->active_iterator = &i->simple_iterator;
01683 
01684    return i;
01685 }

struct ast_channel_iterator* ast_channel_iterator_by_exten_new ( const char *  exten,
const char *  context 
)

Create a new channel iterator based on extension.

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.

Return values:
NULL on failure
a new channel iterator based on the specified parameters
Since:
1.8

Definition at line 1663 of file channel.c.

References channel_iterator_search().

Referenced by common_exec(), and pickup_by_exten().

01664 {
01665    return channel_iterator_search(NULL, 0, exten, context);
01666 }

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

Create a new channel iterator based on name.

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.

Return values:
NULL on failure
a new channel iterator based on the specified parameters
Since:
1.8

Definition at line 1668 of file channel.c.

References channel_iterator_search().

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

01669 {
01670    return channel_iterator_search(name, name_len, NULL, NULL);
01671 }

struct ast_channel_iterator* ast_channel_iterator_destroy ( struct ast_channel_iterator i  ) 

Destroy a channel iterator.

This function is used to destroy a channel iterator that was retrieved by using one of the channel_iterator_new() functions.

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

Definition at line 1621 of file channel.c.

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

Referenced by action_coreshowchannels(), 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().

01622 {
01623    ao2_iterator_destroy(i->active_iterator);
01624    ast_free(i);
01625 
01626    return NULL;
01627 }

struct ast_channel* ast_channel_iterator_next ( struct ast_channel_iterator i  ) 

Get the next channel for a channel iterator.

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

01688 {
01689    return ao2_iterator_next(i->active_iterator);
01690 }

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

References ast_channel_make_compatible_helper(), and chanlist::chan.

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

05855 {
05856    /* Some callers do not check return code, and we must try to set all call legs correctly */
05857    int rc = 0;
05858 
05859    /* Set up translation from the chan to the peer */
05860    rc = ast_channel_make_compatible_helper(chan, peer);
05861 
05862    if (rc < 0)
05863       return rc;
05864 
05865    /* Set up translation from the peer to the chan */
05866    rc = ast_channel_make_compatible_helper(peer, chan);
05867 
05868    return rc;
05869 }

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

References ast_channel_setoption(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_SLINEAR, 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::name, ast_channel::nativeformats, ast_channel::readformat, ast_channel::tech, and ast_channel::writeformat.

Referenced by ast_channel_make_compatible().

05805 {
05806    format_t src, dst;
05807    int use_slin;
05808 
05809    /* See if the channel driver can natively make these two channels compatible */
05810    if (from->tech->bridge && from->tech->bridge == to->tech->bridge &&
05811        !ast_channel_setoption(from, AST_OPTION_MAKE_COMPATIBLE, to, sizeof(struct ast_channel *), 0)) {
05812       return 0;
05813    }
05814 
05815    if (from->readformat == to->writeformat && from->writeformat == to->readformat) {
05816       /* Already compatible!  Moving on ... */
05817       return 0;
05818    }
05819 
05820    /* Set up translation from the 'from' channel to the 'to' channel */
05821    src = from->nativeformats;
05822    dst = to->nativeformats;
05823 
05824    /* If there's no audio in this call, don't bother with trying to find a translation path */
05825    if ((src & AST_FORMAT_AUDIO_MASK) == 0 || (dst & AST_FORMAT_AUDIO_MASK) == 0)
05826       return 0;
05827 
05828    if (ast_translator_best_choice(&dst, &src) < 0) {
05829       ast_log(LOG_WARNING, "No path to translate from %s to %s\n", from->name, to->name);
05830       return -1;
05831    }
05832 
05833    /* if the best path is not 'pass through', then
05834     * transcoding is needed; if desired, force transcode path
05835     * to use SLINEAR between channels, but only if there is
05836     * no direct conversion available. If generic PLC is
05837     * desired, then transcoding via SLINEAR is a requirement
05838     */
05839    use_slin = (src == AST_FORMAT_SLINEAR || dst == AST_FORMAT_SLINEAR);
05840    if ((src != dst) && (ast_opt_generic_plc || ast_opt_transcode_via_slin) &&
05841        (ast_translate_path_steps(dst, src) != 1 || use_slin))
05842       dst = AST_FORMAT_SLINEAR;
05843    if (ast_set_read_format(from, dst) < 0) {
05844       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %s\n", from->name, ast_getformatname(dst));
05845       return -1;
05846    }
05847    if (ast_set_write_format(to, dst) < 0) {
05848       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %s\n", to->name, ast_getformatname(dst));
05849       return -1;
05850    }
05851    return 0;
05852 }

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

05995 {
05996    return __ast_channel_masquerade(original, clone, NULL);
05997 }

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

References ast_channel_lock, ast_channel_unlock, ast_log(), chanlist::chan, 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().

07629 {
07630    int res;
07631 
07632    ast_channel_lock(chan);
07633    if (!chan->tech->queryoption) {
07634       errno = ENOSYS;
07635       ast_channel_unlock(chan);
07636       return -1;
07637    }
07638 
07639    if (block)
07640       ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
07641 
07642    res = chan->tech->queryoption(chan, option, data, datalen);
07643    ast_channel_unlock(chan);
07644 
07645    return res;
07646 }

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

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

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(), sig_pri_handle_subcmds(), and sip_call().

08877 {
08878    unsigned char data[1024];  /* This should be large enough */
08879    size_t datalen;
08880 
08881    datalen = ast_connected_line_build_data(data, sizeof(data), connected, update);
08882    if (datalen == (size_t) -1) {
08883       return;
08884    }
08885 
08886    ast_queue_control_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen);
08887 }

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

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

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

09384 {
09385    unsigned char data[1024];  /* This should be large enough */
09386    size_t datalen;
09387 
09388    datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update);
09389    if (datalen == (size_t) -1) {
09390       return;
09391    }
09392 
09393    ast_queue_control_data(chan, AST_CONTROL_REDIRECTING, data, datalen);
09394 }

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

05199 {
05200    switch (reason) /* the following appear to be the only ones actually returned by request_and_dial */
05201    {
05202    case 0:
05203       return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)";
05204    case AST_CONTROL_HANGUP:
05205       return "Hangup";
05206    case AST_CONTROL_RING:
05207       return "Local Ring";
05208    case AST_CONTROL_RINGING:
05209       return "Remote end Ringing";
05210    case AST_CONTROL_ANSWER:
05211       return "Remote end has Answered";
05212    case AST_CONTROL_BUSY:
05213       return "Remote end is Busy";
05214    case AST_CONTROL_CONGESTION:
05215       return "Congestion (circuits busy)";
05216    default:
05217       return "Unknown Reason!!";
05218    }
05219 }

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

Make constants so that caller and frame can be more expressive than just '1' and '0'

Definition at line 9441 of file channel.c.

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

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

09442 {
09443    const char *macro;
09444    const char *macro_args;
09445    int retval;
09446 
09447    ast_channel_lock(macro_chan);
09448    macro = pbx_builtin_getvar_helper(macro_chan, is_caller
09449       ? "REDIRECTING_CALLER_SEND_MACRO" : "REDIRECTING_CALLEE_SEND_MACRO");
09450    macro = ast_strdupa(S_OR(macro, ""));
09451    macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller
09452       ? "REDIRECTING_CALLER_SEND_MACRO_ARGS" : "REDIRECTING_CALLEE_SEND_MACRO_ARGS");
09453    macro_args = ast_strdupa(S_OR(macro_args, ""));
09454 
09455    if (ast_strlen_zero(macro)) {
09456       ast_channel_unlock(macro_chan);
09457       return -1;
09458    }
09459 
09460    if (is_frame) {
09461       const struct ast_frame *frame = redirecting_info;
09462 
09463       ast_redirecting_parse_data(frame->data.ptr, frame->datalen, &macro_chan->redirecting);
09464    } else {
09465       const struct ast_party_redirecting *redirecting = redirecting_info;
09466 
09467       ast_party_redirecting_copy(&macro_chan->redirecting, redirecting);
09468    }
09469    ast_channel_unlock(macro_chan);
09470 
09471    retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args);
09472    if (!retval) {
09473       struct ast_party_redirecting saved_redirecting;
09474 
09475       ast_party_redirecting_init(&saved_redirecting);
09476       ast_channel_lock(macro_chan);
09477       ast_party_redirecting_copy(&saved_redirecting, &macro_chan->redirecting);
09478       ast_channel_unlock(macro_chan);
09479       ast_channel_update_redirecting(macro_chan, &saved_redirecting, NULL);
09480       ast_party_redirecting_free(&saved_redirecting);
09481    }
09482 
09483    return retval;
09484 }

int ast_channel_register ( const struct ast_channel_tech tech  ) 

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

Parameters:
tech Structure defining channel technology or "type"
Returns:
Returns 0 on success, -1 on failure.

Definition at line 896 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, chanlist::chan, chanlist::list, LOG_WARNING, ast_channel::tech, chanlist::tech, and ast_channel_tech::type.

Referenced by load_module(), and unload_module().

00897 {
00898    struct chanlist *chan;
00899 
00900    AST_RWLIST_WRLOCK(&backends);
00901 
00902    AST_RWLIST_TRAVERSE(&backends, chan, list) {
00903       if (!strcasecmp(tech->type, chan->tech->type)) {
00904          ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type);
00905          AST_RWLIST_UNLOCK(&backends);
00906          return -1;
00907       }
00908    }
00909    
00910    if (!(chan = ast_calloc(1, sizeof(*chan)))) {
00911       AST_RWLIST_UNLOCK(&backends);
00912       return -1;
00913    }
00914    chan->tech = tech;
00915    AST_RWLIST_INSERT_HEAD(&backends, chan, list);
00916 
00917    ast_debug(1, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description);
00918 
00919    ast_verb(2, "Registered channel type '%s' (%s)\n", chan->tech->type, chan->tech->description);
00920 
00921    AST_RWLIST_UNLOCK(&backends);
00922 
00923    return 0;
00924 }

struct ast_channel* ast_channel_release ( struct ast_channel chan  ) 

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

References ao2_unlink, ast_channel_unref, chanlist::chan, and channels.

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

01890 {
01891    /* Safe, even if already unlinked. */
01892    ao2_unlink(channels, chan);
01893    return ast_channel_unref(chan);
01894 }

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

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

Referenced by agent_sendhtml(), and ast_channel_sendurl().

05792 {
05793    if (chan->tech->send_html)
05794       return chan->tech->send_html(chan, subclass, data, datalen);
05795    return -1;
05796 }

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

References ast_channel_sendhtml(), AST_HTML_URL, and chanlist::chan.

Referenced by dial_exec_full(), and sendurl_exec().

05799 {
05800    return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1);
05801 }

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

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

06914 {
06915    if (&chan->caller == caller) {
06916       /* Don't set to self */
06917       return;
06918    }
06919 
06920    ast_channel_lock(chan);
06921    ast_party_caller_set(&chan->caller, caller, update);
06922    ast_channel_unlock(chan);
06923 }

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

References ast_cdr_setcid(), ast_channel_lock, ast_channel_unlock, ast_party_caller_set(), ast_channel::caller, ast_channel::cdr, chanlist::chan, 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, update(), ast_party_name::valid, and ast_party_number::valid.

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

06926 {
06927    const char *pre_set_number;
06928    const char *pre_set_name;
06929 
06930    if (&chan->caller == caller) {
06931       /* Don't set to self */
06932       return;
06933    }
06934 
06935    ast_channel_lock(chan);
06936    pre_set_number =
06937       S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL);
06938    pre_set_name = S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL);
06939    ast_party_caller_set(&chan->caller, caller, update);
06940    if (S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL)
06941          != pre_set_number
06942       || S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL)
06943          != pre_set_name) {
06944       /* The caller id name or number changed. */
06945       report_new_callerid(chan);
06946    }
06947    if (chan->cdr) {
06948       ast_cdr_setcid(chan->cdr, chan);
06949    }
06950    ast_channel_unlock(chan);
06951 }

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

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

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

08237 {
08238    if (&chan->connected == connected) {
08239       /* Don't set to self */
08240       return;
08241    }
08242 
08243    ast_channel_lock(chan);
08244    ast_party_connected_line_set(&chan->connected, connected, update);
08245    ast_channel_unlock(chan);
08246 }

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

Set the file descriptor on the channel

Definition at line 2598 of file channel.c.

References ast_calloc, chanlist::chan, ast_channel::data, ast_channel::fds, and free.

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(), jingle_new(), mgcp_new(), misdn_new(), my_swap_subchannels(), nbs_new(), oss_new(), phone_new(), process_sdp(), setformat(), sip_new(), sip_set_rtp_peer(), skinny_new(), start_rtp(), and swap_subs().

02599 {
02600 #ifdef HAVE_EPOLL
02601    struct epoll_event ev;
02602    struct ast_epoll_data *aed = NULL;
02603 
02604    if (chan->fds[which] > -1) {
02605       epoll_ctl(chan->epfd, EPOLL_CTL_DEL, chan->fds[which], &ev);
02606       aed = chan->epfd_data[which];
02607    }
02608 
02609    /* If this new fd is valid, add it to the epoll */
02610    if (fd > -1) {
02611       if (!aed && (!(aed = ast_calloc(1, sizeof(*aed)))))
02612          return;
02613       
02614       chan->epfd_data[which] = aed;
02615       aed->chan = chan;
02616       aed->which = which;
02617       
02618       ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP;
02619       ev.data.ptr = aed;
02620       epoll_ctl(chan->epfd, EPOLL_CTL_ADD, fd, &ev);
02621    } else if (aed) {
02622       /* We don't have to keep around this epoll data structure now */
02623       free(aed);
02624       chan->epfd_data[which] = NULL;
02625    }
02626 #endif
02627    chan->fds[which] = fd;
02628    return;
02629 }

void ast_channel_set_linkgroup ( struct ast_channel chan,
struct ast_channel peer 
)

propagate the linked id between chan and peer

Definition at line 6270 of file channel.c.

References ast_channel::_bridge, ast_bridged_channel(), ast_channel_change_linkedid(), ast_strdupa, chanlist::chan, ast_channel::linkedid, oldest_linkedid(), and ast_channel::uniqueid.

Referenced by ast_bridge_call(), and ast_do_masquerade().

06271 {
06272    const char* linkedid=NULL;
06273    struct ast_channel *bridged;
06274 
06275    linkedid = oldest_linkedid(chan->linkedid, peer->linkedid);
06276    linkedid = oldest_linkedid(linkedid, chan->uniqueid);
06277    linkedid = oldest_linkedid(linkedid, peer->uniqueid);
06278    if (chan->_bridge) {
06279       bridged = ast_bridged_channel(chan);
06280       if (bridged != peer) {
06281          linkedid = oldest_linkedid(linkedid, bridged->linkedid);
06282          linkedid = oldest_linkedid(linkedid, bridged->uniqueid);
06283       }
06284    }
06285    if (peer->_bridge) {
06286       bridged = ast_bridged_channel(peer);
06287       if (bridged != chan) {
06288          linkedid = oldest_linkedid(linkedid, bridged->linkedid);
06289          linkedid = oldest_linkedid(linkedid, bridged->uniqueid);
06290       }
06291    }
06292 
06293    /* just in case setting a stringfield to itself causes problems */
06294    linkedid = ast_strdupa(linkedid);
06295 
06296    ast_channel_change_linkedid(chan, linkedid);
06297    ast_channel_change_linkedid(peer, linkedid);
06298    if (chan->_bridge) {
06299       bridged = ast_bridged_channel(chan);
06300       if (bridged != peer) {
06301          ast_channel_change_linkedid(bridged, linkedid);
06302       }
06303    }
06304    if (peer->_bridge) {
06305       bridged = ast_bridged_channel(peer);
06306       if (bridged != chan) {
06307          ast_channel_change_linkedid(bridged, linkedid);
06308       }
06309    }
06310 }

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

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

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

08890 {
08891    if (&chan->redirecting == redirecting) {
08892       /* Don't set to self */
08893       return;
08894    }
08895 
08896    ast_channel_lock(chan);
08897    ast_party_redirecting_set(&chan->redirecting, redirecting, update);
08898    ast_channel_unlock(chan);
08899 }

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

References ast_channel_lock, ast_channel_unlock, ast_log(), chanlist::chan, 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(), set_format(), set_listen_volume(), set_security_requirements(), set_talk_volume(), sndfax_exec(), and vm_forwardoptions().

07609 {
07610    int res;
07611 
07612    ast_channel_lock(chan);
07613    if (!chan->tech->setoption) {
07614       errno = ENOSYS;
07615       ast_channel_unlock(chan);
07616       return -1;
07617    }
07618 
07619    if (block)
07620       ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
07621 
07622    res = chan->tech->setoption(chan, option, data, datalen);
07623    ast_channel_unlock(chan);
07624 
07625    return res;
07626 }

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

References ast_channel_setwhentohangup_tv(), and chanlist::chan.

00868 {
00869    struct timeval when = { offset, };
00870    ast_channel_setwhentohangup_tv(chan, when);
00871 }

void ast_channel_setwhentohangup_tv ( struct ast_channel chan,
struct timeval  offset 
)

Set when to hang a channel up.

Parameters:
chan channel on which to check for hang up
offset offset in seconds and useconds 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
Since:
1.6.1

Definition at line 860 of file channel.c.

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

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

00861 {
00862    chan->whentohangup = ast_tvzero(offset) ? offset : ast_tvadd(offset, ast_tvnow());
00863    ast_queue_frame(chan, &ast_null_frame);
00864    return;
00865 }

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

Definition at line 818 of file channel.c.

References ast_softhangup(), AST_SOFTHANGUP_SHUTDOWN, and chanlist::chan.

Referenced by ast_begin_shutdown().

00819 {
00820    struct ast_channel *chan = obj;
00821 
00822    ast_softhangup(chan, AST_SOFTHANGUP_SHUTDOWN);
00823 
00824    return 0;
00825 }

struct ast_silence_generator* ast_channel_start_silence_generator ( struct ast_channel chan  ) 

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

References ast_activate_generator(), ast_calloc, ast_debug, AST_FORMAT_SLINEAR, ast_free, ast_log(), ast_set_write_format(), LOG_ERROR, ast_channel::name, ast_silence_generator::old_write_format, silence_generator, state, 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(), TransferCallStep1(), waitfor_exec(), and waitforring_exec().

08111 {
08112    struct ast_silence_generator *state;
08113 
08114    if (!(state = ast_calloc(1, sizeof(*state)))) {
08115       return NULL;
08116    }
08117 
08118    state->old_write_format = chan->writeformat;
08119 
08120    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
08121       ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
08122       ast_free(state);
08123       return NULL;
08124    }
08125 
08126    ast_activate_generator(chan, &silence_generator, state);
08127 
08128    ast_debug(1, "Started silence generator on '%s'\n", chan->name);
08129 
08130    return state;
08131 }

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

References ast_deactivate_generator(), ast_debug, ast_free, ast_log(), ast_set_write_format(), LOG_ERROR, ast_channel::name, and state.

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

08134 {
08135    if (!state)
08136       return;
08137 
08138    ast_deactivate_generator(chan);
08139 
08140    ast_debug(1, "Stopped silence generator on '%s'\n", chan->name);
08141 
08142    if (ast_set_write_format(chan, state->old_write_format) < 0)
08143       ast_log(LOG_ERROR, "Could not return write format to its original state\n");
08144 
08145    ast_free(state);
08146 }

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

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

Referenced by dial_exec_full(), and sendurl_exec().

05787 {
05788    return (chan->tech->send_html) ? 1 : 0;
05789 }

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 6068 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_id, xfer_masquerade_ds::transferee_id, and xfer_ds_info.

Referenced by analog_attempt_transfer(), misdn_attempt_transfer(), and sig_pri_attempt_transfer().

06075 {
06076    struct ast_datastore *xfer_ds;
06077    struct xfer_masquerade_ds *xfer_colp;
06078    int res;
06079 
06080    xfer_ds = ast_datastore_alloc(&xfer_ds_info, NULL);
06081    if (!xfer_ds) {
06082       return -1;
06083    }
06084 
06085    xfer_colp = ast_calloc(1, sizeof(*xfer_colp));
06086    if (!xfer_colp) {
06087       ast_datastore_free(xfer_ds);
06088       return -1;
06089    }
06090    party_connected_line_copy_transfer(&xfer_colp->target_id, target_id);
06091    xfer_colp->target_held = target_held;
06092    party_connected_line_copy_transfer(&xfer_colp->transferee_id, transferee_id);
06093    xfer_colp->transferee_held = transferee_held;
06094    xfer_ds->data = xfer_colp;
06095 
06096    res = __ast_channel_masquerade(target_chan, transferee_chan, xfer_ds);
06097    if (res) {
06098       ast_datastore_free(xfer_ds);
06099    }
06100    return res;
06101 }

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

References ast_clear_flag, AST_FLAG_DEFER_DTMF, and chanlist::chan.

Referenced by find_cache().

01601 {
01602    if (chan)
01603       ast_clear_flag(chan, AST_FLAG_DEFER_DTMF);
01604 }

void ast_channel_unregister ( const struct ast_channel_tech tech  ) 

Unregister a channel technology.

Parameters:
tech Structure defining channel technology or "type" that was previously registered
Returns:
No return value.

Definition at line 927 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::chan, chanlist::list, ast_channel::tech, chanlist::tech, and ast_channel_tech::type.

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

00928 {
00929    struct chanlist *chan;
00930 
00931    ast_debug(1, "Unregistering channel type '%s'\n", tech->type);
00932 
00933    AST_RWLIST_WRLOCK(&backends);
00934 
00935    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) {
00936       if (chan->tech == tech) {
00937          AST_LIST_REMOVE_CURRENT(list);
00938          ast_free(chan);
00939          ast_verb(2, "Unregistered channel type '%s'\n", tech->type);
00940          break;   
00941       }
00942    }
00943    AST_LIST_TRAVERSE_SAFE_END;
00944 
00945    AST_RWLIST_UNLOCK(&backends);
00946 }

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

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

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

08864 {
08865    unsigned char data[1024];  /* This should be large enough */
08866    size_t datalen;
08867 
08868    datalen = ast_connected_line_build_data(data, sizeof(data), connected, update);
08869    if (datalen == (size_t) -1) {
08870       return;
08871    }
08872 
08873    ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen);
08874 }

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

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

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

09371 {
09372    unsigned char data[1024];  /* This should be large enough */
09373    size_t datalen;
09374 
09375    datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update);
09376    if (datalen == (size_t) -1) {
09377       return;
09378    }
09379 
09380    ast_indicate_data(chan, AST_CONTROL_REDIRECTING, data, datalen);
09381 }

void ast_channels_init ( void   ) 

Provided by channel.c

Definition at line 8024 of file channel.c.

References ao2_container_alloc, ARRAY_LEN, ast_channel_cmp_cb(), ast_channel_hash_cb(), ast_cli_register_multiple(), ast_data_register_multiple_core, ast_plc_reload(), channel_providers, channels, cli_channel, and NUM_CHANNEL_BUCKETS.

Referenced by main().

struct ast_variable* ast_channeltype_list ( void   ) 

return an ast_variable list of channeltypes

Definition at line 252 of file channel.c.

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

Referenced by ast_var_channel_types(), and ast_var_channel_types_table().

00253 {
00254    struct chanlist *cl;
00255    struct ast_variable *var = NULL, *prev = NULL;
00256 
00257    AST_RWLIST_RDLOCK(&backends);
00258    AST_RWLIST_TRAVERSE(&backends, cl, list) {
00259       if (prev)  {
00260          if ((prev->next = ast_variable_new(cl->tech->type, cl->tech->description, "")))
00261             prev = prev->next;
00262       } else {
00263          var = ast_variable_new(cl->tech->type, cl->tech->description, "");
00264          prev = var;
00265       }
00266    }
00267    AST_RWLIST_UNLOCK(&backends);
00268 
00269    return var;
00270 }

int ast_check_hangup ( struct ast_channel chan  ) 

Check to see if a channel is needing hang up.

Parameters:
chan channel on which to check for hang up This function determines if the channel is being requested to be hung up.
Returns:
Returns 0 if not, or 1 if hang up is requested (including time-out).

Definition at line 796 of file channel.c.

References ast_channel::_softhangup, ast_debug, AST_SOFTHANGUP_TIMEOUT, ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), chanlist::chan, 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(), launch_asyncagi(), local_fixup(), lua_check_hangup(), ospfinished_exec(), pbx_builtin_incomplete(), pbx_builtin_waitexten(), pbx_exec(), read_exec(), readexten_exec(), remote_bridge_loop(), run_agi(), and run_ras().

00797 {
00798    if (chan->_softhangup)     /* yes if soft hangup flag set */
00799       return 1;
00800    if (ast_tvzero(chan->whentohangup)) /* no if no hangup scheduled */
00801       return 0;
00802    if (ast_tvdiff_ms(chan->whentohangup, ast_tvnow()) > 0)  /* no if hangup time has not come yet. */
00803       return 0;
00804    ast_debug(4, "Hangup time has come: %" PRIi64 "\n", ast_tvdiff_ms(chan->whentohangup, ast_tvnow()));
00805    chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT; /* record event */
00806    return 1;
00807 }

int ast_check_hangup_locked ( struct ast_channel chan  ) 

Definition at line 809 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_check_hangup(), and chanlist::chan.

Referenced by action_redirect(), and ast_channel_bridge().

00810 {
00811    int res;
00812    ast_channel_lock(chan);
00813    res = ast_check_hangup(chan);
00814    ast_channel_unlock(chan);
00815    return res;
00816 }

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 8603 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(), connected, LOG_WARNING, ast_party_id_ies::name, party_id_build_data(), ast_party_name_ies::str, update(), and value.

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

08604 {
08605    int32_t value;
08606    size_t pos = 0;
08607    int res;
08608 
08609    static const struct ast_party_id_ies ies = {
08610       .name.str = AST_CONNECTED_LINE_NAME,
08611       .name.char_set = AST_CONNECTED_LINE_NAME_CHAR_SET,
08612       .name.presentation = AST_CONNECTED_LINE_NAME_PRESENTATION,
08613       .name.valid = AST_CONNECTED_LINE_NAME_VALID,
08614 
08615       .number.str = AST_CONNECTED_LINE_NUMBER,
08616       .number.plan = AST_CONNECTED_LINE_NUMBER_PLAN,
08617       .number.presentation = AST_CONNECTED_LINE_NUMBER_PRESENTATION,
08618       .number.valid = AST_CONNECTED_LINE_NUMBER_VALID,
08619 
08620       .subaddress.str = AST_CONNECTED_LINE_SUBADDRESS,
08621       .subaddress.type = AST_CONNECTED_LINE_SUBADDRESS_TYPE,
08622       .subaddress.odd_even_indicator = AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN,
08623       .subaddress.valid = AST_CONNECTED_LINE_SUBADDRESS_VALID,
08624 
08625       .tag = AST_CONNECTED_LINE_TAG,
08626       .combined_presentation = AST_CONNECTED_LINE_ID_PRESENTATION,
08627    };
08628 
08629    /*
08630     * The size of integer values must be fixed in case the frame is
08631     * shipped to another machine.
08632     */
08633 
08634    /* Connected line frame version */
08635    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08636       ast_log(LOG_WARNING, "No space left for connected line frame version\n");
08637       return -1;
08638    }
08639    data[pos++] = AST_CONNECTED_LINE_VERSION;
08640    data[pos++] = 1;
08641    data[pos++] = 2;/* Version 1 did not have a version ie */
08642 
08643    res = party_id_build_data(data + pos, datalen - pos, &connected->id,
08644       "connected line", &ies, update ? &update->id : NULL);
08645    if (res < 0) {
08646       return -1;
08647    }
08648    pos += res;
08649 
08650    /* Connected line source */
08651    if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
08652       ast_log(LOG_WARNING, "No space left for connected line source\n");
08653       return -1;
08654    }
08655    data[pos++] = AST_CONNECTED_LINE_SOURCE;
08656    data[pos++] = sizeof(value);
08657    value = htonl(connected->source);
08658    memcpy(data + pos, &value, sizeof(value));
08659    pos += sizeof(value);
08660 
08661    return pos;
08662 }

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

08222 {
08223    ast_party_id_copy(&dest->id, &src->id);
08224    ast_party_id_copy(&dest->ani, &src->ani);
08225    dest->ani2 = src->ani2;
08226 }

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

08229 {
08230    ast_party_id_copy(&dest->id, &src->id);
08231    ast_party_id_copy(&dest->ani, &src->ani);
08232 
08233    dest->ani2 = src->ani2;
08234 }

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 8664 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_free, ast_log(), ast_malloc, AST_PARTY_CHAR_SET_ISO8859_1, ast_party_id_ies::combined_presentation, connected, LOG_DEBUG, LOG_WARNING, and value.

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

08665 {
08666    size_t pos;
08667    unsigned char ie_len;
08668    unsigned char ie_id;
08669    int32_t value;
08670    int frame_version = 1;
08671    int combined_presentation = 0;
08672    int got_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */
08673 
08674    for (pos = 0; pos < datalen; pos += ie_len) {
08675       if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) {
08676          ast_log(LOG_WARNING, "Invalid connected line update\n");
08677          return -1;
08678       }
08679       ie_id = data[pos++];
08680       ie_len = data[pos++];
08681       if (datalen < pos + ie_len) {
08682          ast_log(LOG_WARNING, "Invalid connected line update\n");
08683          return -1;
08684       }
08685 
08686       switch (ie_id) {
08687 /* Connected line party frame version */
08688       case AST_CONNECTED_LINE_VERSION:
08689          if (ie_len != 1) {
08690             ast_log(LOG_WARNING, "Invalid connected line frame version (%u)\n",
08691                (unsigned) ie_len);
08692             break;
08693          }
08694          frame_version = data[pos];
08695          break;
08696 /* Connected line party id name */
08697       case AST_CONNECTED_LINE_NAME:
08698          ast_free(connected->id.name.str);
08699          connected->id.name.str = ast_malloc(ie_len + 1);
08700          if (connected->id.name.str) {
08701             memcpy(connected->id.name.str, data + pos, ie_len);
08702             connected->id.name.str[ie_len] = 0;
08703          }
08704          break;
08705       case AST_CONNECTED_LINE_NAME_CHAR_SET:
08706          if (ie_len != 1) {
08707             ast_log(LOG_WARNING, "Invalid connected line name char set (%u)\n",
08708                (unsigned) ie_len);
08709             break;
08710          }
08711          connected->id.name.char_set = data[pos];
08712          break;
08713       case AST_CONNECTED_LINE_NAME_PRESENTATION:
08714          if (ie_len != 1) {
08715             ast_log(LOG_WARNING, "Invalid connected line name presentation (%u)\n",
08716                (unsigned) ie_len);
08717             break;
08718          }
08719          connected->id.name.presentation = data[pos];
08720          break;
08721       case AST_CONNECTED_LINE_NAME_VALID:
08722          if (ie_len != 1) {
08723             ast_log(LOG_WARNING, "Invalid connected line name valid (%u)\n",
08724                (unsigned) ie_len);
08725             break;
08726          }
08727          connected->id.name.valid = data[pos];
08728          break;
08729 /* Connected line party id number */
08730       case AST_CONNECTED_LINE_NUMBER:
08731          ast_free(connected->id.number.str);
08732          connected->id.number.str = ast_malloc(ie_len + 1);
08733          if (connected->id.number.str) {
08734             memcpy(connected->id.number.str, data + pos, ie_len);
08735             connected->id.number.str[ie_len] = 0;
08736          }
08737          break;
08738       case AST_CONNECTED_LINE_NUMBER_PLAN:
08739          if (ie_len != 1) {
08740             ast_log(LOG_WARNING, "Invalid connected line numbering plan (%u)\n",
08741                (unsigned) ie_len);
08742             break;
08743          }
08744          connected->id.number.plan = data[pos];
08745          break;
08746       case AST_CONNECTED_LINE_NUMBER_PRESENTATION:
08747          if (ie_len != 1) {
08748             ast_log(LOG_WARNING, "Invalid connected line number presentation (%u)\n",
08749                (unsigned) ie_len);
08750             break;
08751          }
08752          connected->id.number.presentation = data[pos];
08753          break;
08754       case AST_CONNECTED_LINE_NUMBER_VALID:
08755          if (ie_len != 1) {
08756             ast_log(LOG_WARNING, "Invalid connected line number valid (%u)\n",
08757                (unsigned) ie_len);
08758             break;
08759          }
08760          connected->id.number.valid = data[pos];
08761          break;
08762 /* Connected line party id combined presentation */
08763       case AST_CONNECTED_LINE_ID_PRESENTATION:
08764          if (ie_len != 1) {
08765             ast_log(LOG_WARNING, "Invalid connected line combined presentation (%u)\n",
08766                (unsigned) ie_len);
08767             break;
08768          }
08769          combined_presentation = data[pos];
08770          got_combined_presentation = 1;
08771          break;
08772 /* Connected line party id subaddress */
08773       case AST_CONNECTED_LINE_SUBADDRESS:
08774          ast_free(connected->id.subaddress.str);
08775          connected->id.subaddress.str = ast_malloc(ie_len + 1);
08776          if (connected->id.subaddress.str) {
08777             memcpy(connected->id.subaddress.str, data + pos, ie_len);
08778             connected->id.subaddress.str[ie_len] = 0;
08779          }
08780          break;
08781       case AST_CONNECTED_LINE_SUBADDRESS_TYPE:
08782          if (ie_len != 1) {
08783             ast_log(LOG_WARNING, "Invalid connected line type of subaddress (%u)\n",
08784                (unsigned) ie_len);
08785             break;
08786          }
08787          connected->id.subaddress.type = data[pos];
08788          break;
08789       case AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN:
08790          if (ie_len != 1) {
08791             ast_log(LOG_WARNING,
08792                "Invalid connected line subaddress odd-even indicator (%u)\n",
08793                (unsigned) ie_len);
08794             break;
08795          }
08796          connected->id.subaddress.odd_even_indicator = data[pos];
08797          break;
08798       case AST_CONNECTED_LINE_SUBADDRESS_VALID:
08799          if (ie_len != 1) {
08800             ast_log(LOG_WARNING, "Invalid connected line subaddress valid (%u)\n",
08801                (unsigned) ie_len);
08802             break;
08803          }
08804          connected->id.subaddress.valid = data[pos];
08805          break;
08806 /* Connected line party tag */
08807       case AST_CONNECTED_LINE_TAG:
08808          ast_free(connected->id.tag);
08809          connected->id.tag = ast_malloc(ie_len + 1);
08810          if (connected->id.tag) {
08811             memcpy(connected->id.tag, data + pos, ie_len);
08812             connected->id.tag[ie_len] = 0;
08813          }
08814          break;
08815 /* Connected line party source */
08816       case AST_CONNECTED_LINE_SOURCE:
08817          if (ie_len != sizeof(value)) {
08818             ast_log(LOG_WARNING, "Invalid connected line source (%u)\n",
08819                (unsigned) ie_len);
08820             break;
08821          }
08822          memcpy(&value, data + pos, sizeof(value));
08823          connected->source = ntohl(value);
08824          break;
08825 /* Connected line party unknown element */
08826       default:
08827          ast_log(LOG_DEBUG, "Unknown connected line element: %u (%u)\n",
08828             (unsigned) ie_id, (unsigned) ie_len);
08829          break;
08830       }
08831    }
08832 
08833    switch (frame_version) {
08834    case 1:
08835       /*
08836        * The other end is an earlier version that we need to adjust
08837        * for compatibility.
08838        */
08839       connected->id.name.valid = 1;
08840       connected->id.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
08841       connected->id.number.valid = 1;
08842       if (got_combined_presentation) {
08843          connected->id.name.presentation = combined_presentation;
08844          connected->id.number.presentation = combined_presentation;
08845       }
08846       break;
08847    case 2:
08848       /* The other end is at the same level as we are. */
08849       break;
08850    default:
08851       /*
08852        * The other end is newer than we are.
08853        * We need to assume that they are compatible with us.
08854        */
08855       ast_log(LOG_DEBUG, "Connected line frame has newer version: %u\n",
08856          (unsigned) frame_version);
08857       break;
08858    }
08859 
08860    return 0;
08861 }

AST_DATA_STRUCTURE ( ast_channel  ,
DATA_EXPORT_CHANNEL   
)

void ast_deactivate_generator ( struct ast_channel chan  ) 

Deactivate an active generator

Definition at line 3055 of file channel.c.

References ast_channel_lock, ast_channel_set_fd(), ast_channel_unlock, ast_clear_flag, AST_FLAG_WRITE_INT, AST_GENERATOR_FD, ast_settimeout(), chanlist::chan, ast_channel::generator, ast_channel::generatordata, and ast_generator::release.

Referenced by __ast_read(), app_exec(), ast_channel_stop_silence_generator(), ast_openstream_full(), ast_playtones_stop(), ast_quiet_chan(), ast_read_generator_actions(), ast_tonepair_stop(), ast_write(), cb_events(), channel_spy(), dial_exec_full(), generator_force(), local_ast_moh_stop(), old_milliwatt_exec(), transmit_audio(), and wait_for_answer().

03056 {
03057    ast_channel_lock(chan);
03058    if (chan->generatordata) {
03059       if (chan->generator && chan->generator->release)
03060          chan->generator->release(chan, chan->generatordata);
03061       chan->generatordata = NULL;
03062       chan->generator = NULL;
03063       ast_channel_set_fd(chan, AST_GENERATOR_FD, -1);
03064       ast_clear_flag(chan, AST_FLAG_WRITE_INT);
03065       ast_settimeout(chan, 0, NULL, NULL);
03066    }
03067    ast_channel_unlock(chan);
03068 }

int ast_do_masquerade ( struct ast_channel original  ) 

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.

< TRUE if the clonechan was a zombie before the masquerade.

Definition at line 6429 of file channel.c.

References __ast_change_name_nolink(), ast_channel::_bridge, ast_channel::_softhangup, ast_channel::_state, accountcode, 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_datastore_find(), ast_channel_datastore_remove(), ast_channel_lock, ast_channel_lock_both, AST_CHANNEL_NAME, ast_channel_ref, ast_channel_set_fd(), ast_channel_set_linkgroup(), ast_channel_unlock, ast_channel_unref, 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_GENERATOR_FD, ast_getformatname(), ast_indicate(), ast_kill_tech, AST_LIST_APPEND_LIST, AST_LIST_FIRST, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_HEAD_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_string_field_set, ast_test_flag, AST_TIMING_FD, ast_channel::blocker, ast_channel::caller, ast_channel::cdr, ast_datastore_info::chan_fixup, channels, clone_variables(), ast_channel::connected, chanlist::connected, ast_datastore::data, ast_channel::datastores, ast_channel::dialed, ast_datastore::entry, errno, EVENT_FLAG_CALL, ast_channel::fdno, ast_channel::fds, ast_channel_tech::fixup, free_translation(), ast_datastore::info, ast_channel::language, language, LOG_WARNING, ast_channel::masq, ast_channel::masqr, masquerade_colp_transfer(), ast_channel::monitor, musicclass, ast_channel::name, 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, ast_channel::writeformat, and xfer_ds_info.

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

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

struct ast_channel* ast_dummy_channel_alloc ( void   ) 

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

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

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(), custom_log(), make_email_file(), manager_log(), pbx_substitute_variables_helper_full(), rotate_file(), sendmail(), sendpage(), syslog_log(), and write_cdr().

01382 {
01383    struct ast_channel *tmp;
01384    struct varshead *headp;
01385 
01386 #if defined(REF_DEBUG)
01387    tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel",
01388       file, line, function, 1);
01389 #elif defined(__AST_DEBUG_MALLOC)
01390    tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel",
01391       file, line, function, 0);
01392 #else
01393    tmp = ao2_alloc(sizeof(*tmp), ast_dummy_channel_destructor);
01394 #endif
01395    if (!tmp) {
01396       /* Dummy channel structure allocation failure. */
01397       return NULL;
01398    }
01399 
01400    if ((ast_string_field_init(tmp, 128))) {
01401       return ast_channel_unref(tmp);
01402    }
01403 
01404    headp = &tmp->varshead;
01405    AST_LIST_HEAD_INIT_NOLOCK(headp);
01406 
01407    return tmp;
01408 }

static void ast_dummy_channel_destructor ( void *  obj  )  [static]

Free a dummy channel structure.

Definition at line 2497 of file channel.c.

References ast_cdr_discard(), ast_datastore_free(), 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, chanlist::chan, ast_channel::connected, ast_channel::datastores, ast_channel::dialed, ast_datastore::entry, ast_channel::redirecting, and ast_channel::varshead.

Referenced by ast_dummy_channel_alloc().

02498 {
02499    struct ast_channel *chan = obj;
02500    struct ast_var_t *vardata;
02501    struct varshead *headp;
02502    struct ast_datastore *datastore;
02503 
02504    /* Get rid of each of the data stores on the channel */
02505    while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry))) {
02506       /* Free the data store */
02507       ast_datastore_free(datastore);
02508    }
02509 
02510    headp = &chan->varshead;
02511 
02512    ast_party_dialed_free(&chan->dialed);
02513    ast_party_caller_free(&chan->caller);
02514    ast_party_connected_line_free(&chan->connected);
02515    ast_party_redirecting_free(&chan->redirecting);
02516 
02517    /* loop over the variables list, freeing all data and deleting list items */
02518    /* no need to lock the list, as the channel is already locked */
02519    while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
02520       ast_var_delete(vardata);
02521 
02522    if (chan->cdr) {
02523       ast_cdr_discard(chan->cdr);
02524       chan->cdr = NULL;
02525    }
02526 
02527    ast_string_field_free_memory(chan);
02528 }

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

References AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_RETRY, ast_clear_flag, AST_FEATURE_WARNING_ACTIVE, ast_jb_do_usecheck(), ast_jb_empty_and_reset(), ast_poll_channel_add(), ast_samp2tv(), ast_set_flag, ast_test_flag, ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), config, f, ast_channel::nativeformats, and ast_channel::tech_pvt.

Referenced by ast_channel_bridge().

07040 {
07041    /* Copy voice back and forth between the two channels. */
07042    struct ast_channel *cs[3];
07043    struct ast_frame *f;
07044    enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
07045    format_t o0nativeformats;
07046    format_t o1nativeformats;
07047    int watch_c0_dtmf;
07048    int watch_c1_dtmf;
07049    void *pvt0, *pvt1;
07050    /* Indicates whether a frame was queued into a jitterbuffer */
07051    int frame_put_in_jb = 0;
07052    int jb_in_use;
07053    int to;
07054    
07055    cs[0] = c0;
07056    cs[1] = c1;
07057    pvt0 = c0->tech_pvt;
07058    pvt1 = c1->tech_pvt;
07059    o0nativeformats = c0->nativeformats;
07060    o1nativeformats = c1->nativeformats;
07061    watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0;
07062    watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1;
07063 
07064    /* Check the need of a jitterbuffer for each channel */
07065    jb_in_use = ast_jb_do_usecheck(c0, c1);
07066    if (jb_in_use)
07067       ast_jb_empty_and_reset(c0, c1);
07068 
07069    ast_poll_channel_add(c0, c1);
07070 
07071    if (config->feature_timer > 0 && ast_tvzero(config->nexteventts)) {
07072       /* nexteventts is not set when the bridge is not scheduled to
07073        * break, so calculate when the bridge should possibly break
07074        * if a partial feature match timed out */
07075       config->nexteventts = ast_tvadd(ast_tvnow(), ast_samp2tv(config->feature_timer, 1000));
07076    }
07077 
07078    for (;;) {
07079       struct ast_channel *who, *other;
07080 
07081       if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) ||
07082           (o0nativeformats != c0->nativeformats) ||
07083           (o1nativeformats != c1->nativeformats)) {
07084          /* Check for Masquerade, codec changes, etc */
07085          res = AST_BRIDGE_RETRY;
07086          break;
07087       }
07088       if (config->nexteventts.tv_sec) {
07089          to = ast_tvdiff_ms(config->nexteventts, ast_tvnow());
07090          if (to <= 0) {
07091             if (config->timelimit && !config->feature_timer && !ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) {
07092                res = AST_BRIDGE_RETRY;
07093                /* generic bridge ending to play warning */
07094                ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
07095             } else if (config->feature_timer) {
07096                /* feature timer expired - make sure we do not play warning */
07097                ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE);
07098                res = AST_BRIDGE_RETRY;
07099             } else {
07100                res = AST_BRIDGE_COMPLETE;
07101             }
07102             break;
07103          }
07104       } else {
07105          /* If a feature has been started and the bridge is configured to 
07106           * to not break, leave the channel bridge when the feature timer
07107           * time has elapsed so the DTMF will be sent to the other side. 
07108           */
07109          if (!ast_tvzero(config->nexteventts)) {
07110             int diff = ast_tvdiff_ms(config->nexteventts, ast_tvnow());
07111             if (diff <= 0) {
07112                res = AST_BRIDGE_RETRY;
07113                break;
07114             }
07115          }
07116          to = -1;
07117       }
07118       /* Calculate the appropriate max sleep interval - in general, this is the time,
07119          left to the closest jb delivery moment */
07120       if (jb_in_use)
07121          to = ast_jb_get_when_to_wakeup(c0, c1, to);
07122       who = ast_waitfor_n(cs, 2, &to);
07123       if (!who) {
07124          /* No frame received within the specified timeout - check if we have to deliver now */
07125          if (jb_in_use)
07126             ast_jb_get_and_deliver(c0, c1);
07127          if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */
07128             if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
07129                ast_channel_clear_softhangup(c0, AST_SOFTHANGUP_UNBRIDGE);
07130             }
07131             if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
07132                ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE);
07133             }
07134             c0->_bridge = c1;
07135             c1->_bridge = c0;
07136          }
07137          continue;
07138       }
07139       f = ast_read(who);
07140       if (!f) {
07141          *fo = NULL;
07142          *rc = who;
07143          ast_debug(1, "Didn't get a frame from channel: %s\n",who->name);
07144          break;
07145       }
07146 
07147       other = (who == c0) ? c1 : c0; /* the 'other' channel */
07148       /* Try add the frame info the who's bridged channel jitterbuff */
07149       if (jb_in_use)
07150          frame_put_in_jb = !ast_jb_put(other, f);
07151 
07152       if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) {
07153          int bridge_exit = 0;
07154 
07155          switch (f->subclass.integer) {
07156          case AST_CONTROL_AOC:
07157             ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
07158             break;
07159          case AST_CONTROL_REDIRECTING:
07160             if (ast_channel_redirecting_macro(who, other, f, other == c0, 1)) {
07161                ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
07162             }
07163             break;
07164          case AST_CONTROL_CONNECTED_LINE:
07165             if (ast_channel_connected_line_macro(who, other, f, other == c0, 1)) {
07166                ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
07167             }
07168             break;
07169          case AST_CONTROL_HOLD:
07170          case AST_CONTROL_UNHOLD:
07171          case AST_CONTROL_VIDUPDATE:
07172          case AST_CONTROL_SRCUPDATE:
07173          case AST_CONTROL_SRCCHANGE:
07174          case AST_CONTROL_T38_PARAMETERS:
07175             ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
07176             if (jb_in_use) {
07177                ast_jb_empty_and_reset(c0, c1);
07178             }
07179             break;
07180          default:
07181             *fo = f;
07182             *rc = who;
07183             bridge_exit = 1;
07184             ast_debug(1, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass.integer, who->name);
07185             break;
07186          }
07187          if (bridge_exit)
07188             break;
07189       }
07190       if ((f->frametype == AST_FRAME_VOICE) ||
07191           (f->frametype == AST_FRAME_DTMF_BEGIN) ||
07192           (f->frametype == AST_FRAME_DTMF) ||
07193           (f->frametype == AST_FRAME_VIDEO) ||
07194           (f->frametype == AST_FRAME_IMAGE) ||
07195           (f->frametype == AST_FRAME_HTML) ||
07196           (f->frametype == AST_FRAME_MODEM) ||
07197           (f->frametype == AST_FRAME_TEXT)) {
07198          /* monitored dtmf causes exit from bridge */
07199          int monitored_source = (who == c0) ? watch_c0_dtmf : watch_c1_dtmf;
07200 
07201          if (monitored_source &&
07202             (f->frametype == AST_FRAME_DTMF_END ||
07203             f->frametype == AST_FRAME_DTMF_BEGIN)) {
07204             *fo = f;
07205             *rc = who;
07206             ast_debug(1, "Got DTMF %s on channel (%s)\n", 
07207                f->frametype == AST_FRAME_DTMF_END ? "end" : "begin",
07208                who->name);
07209 
07210             break;
07211          }
07212          /* Write immediately frames, not passed through jb */
07213          if (!frame_put_in_jb)
07214             ast_write(other, f);
07215             
07216          /* Check if we have to deliver now */
07217          if (jb_in_use)
07218             ast_jb_get_and_deliver(c0, c1);
07219       }
07220       /* XXX do we want to pass on also frames not matched above ? */
07221       ast_frfree(f);
07222 
07223 #ifndef HAVE_EPOLL
07224       /* Swap who gets priority */
07225       cs[2] = cs[0];
07226       cs[0] = cs[1];
07227       cs[1] = cs[2];
07228 #endif
07229    }
07230 
07231    ast_poll_channel_del(c0, c1);
07232 
07233    return res;
07234 }

struct ast_channel_tech* ast_get_channel_tech ( const char *  name  ) 

Get a channel technology structure by name.

Parameters:
name name of technology to find
Returns:
a pointer to the structure, or NULL if no matching technology found

Definition at line 949 of file channel.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, chanlist::list, 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().

00950 {
00951    struct chanlist *chanls;
00952    const struct ast_channel_tech *ret = NULL;
00953 
00954    AST_RWLIST_RDLOCK(&backends);
00955 
00956    AST_RWLIST_TRAVERSE(&backends, chanls, list) {
00957       if (!strcasecmp(name, chanls->tech->type)) {
00958          ret = chanls->tech;
00959          break;
00960       }
00961    }
00962 
00963    AST_RWLIST_UNLOCK(&backends);
00964    
00965    return ret;
00966 }

ast_group_t ast_get_group ( const char *  s  ) 

Definition at line 7800 of file channel.c.

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

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

07801 {
07802    char *piece;
07803    char *c;
07804    int start=0, finish=0, x;
07805    ast_group_t group = 0;
07806 
07807    if (ast_strlen_zero(s))
07808       return 0;
07809 
07810    c = ast_strdupa(s);
07811    
07812    while ((piece = strsep(&c, ","))) {
07813       if (sscanf(piece, "%30d-%30d", &start, &finish) == 2) {
07814          /* Range */
07815       } else if (sscanf(piece, "%30d", &start)) {
07816          /* Just one */
07817          finish = start;
07818       } else {
07819          ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece);
07820          continue;
07821       }
07822       for (x = start; x <= finish; x++) {
07823          if ((x > 63) || (x < 0)) {
07824             ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x);
07825          } else
07826             group |= ((ast_group_t) 1 << x);
07827       }
07828    }
07829    return group;
07830 }

int ast_hangup ( struct ast_channel chan  ) 

Hang up a channel.

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

This function performs a hard hangup on a channel. Unlike the soft-hangup, this function performs all stream stopping, etc, on the channel that needs to end. chan is no longer valid after this call.

Parameters:
chan channel to hang up
Returns:
Returns 0 on success, -1 on failure.

Definition at line 2771 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_lock, 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_set_flag, ast_test_flag, ast_channel::blocker, ast_channel::blockproc, ast_channel::caller, ast_channel::cdr, chanlist::chan, 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_channel::hangupsource, ast_party_connected_line::id, ast_party_caller::id, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_party_id::name, ast_channel::name, ast_party_id::number, pbx_builtin_getvar_helper(), ast_generator::release, S_COR, S_OR, ast_channel::sched, sched_context_destroy(), ast_party_name::str, ast_party_number::str, ast_channel::stream, ast_channel::tech, ast_channel::uniqueid, ast_party_name::valid, ast_party_number::valid, and ast_channel::vstream.

Referenced by __analog_handle_event(), __analog_ss_thread(), __ast_request_and_dial(), __oh323_new(), action_bridge(), 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_call_thread_launch(), bridge_channel_thread(), bridge_exec(), build_conf(), builtin_atxfer(), chanavail_exec(), check_availability(), check_compat(), check_goto_on_transfer(), clear_caller(), conf_run(), console_new(), dahdi_handle_event(), dahdi_new(), destroy_conference_bridge(), dial_exec_full(), dial_transfer(), do_forward(), do_hang(), do_idle_thread(), feature_attended_transfer(), feature_request_and_dial(), findmeexec(), generic_recall(), gtalk_new(), handle_call_forward(), handle_callforward_button(), handle_enbloc_call_message(), handle_frame(), handle_frame_ownerless(), handle_hd_hf(), handle_init_event(), handle_invite_replaces(), handle_offhook_message(), handle_request_invite(), handle_soft_key_event_message(), handle_stimulus_message(), handle_timeout_trip(), handle_transfer_button(), 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(), play_sound_file(), pri_dchannel(), pri_ss_thread(), sip_park(), sip_park_thread(), sip_pickup_thread(), skinny_new(), skinny_ss(), unistim_new(), and wait_for_winner().

02772 {
02773    char extra_str[64]; /* used for cel logging below */
02774    int was_zombie;
02775 
02776    ast_autoservice_stop(chan);
02777 
02778    ast_channel_lock(chan);
02779 
02780    /*
02781     * Do the masquerade if someone is setup to masquerade into us.
02782     *
02783     * NOTE: We must hold the channel lock after testing for a
02784     * pending masquerade and setting the channel as a zombie to
02785     * prevent __ast_channel_masquerade() from setting up a
02786     * masquerade with a dead channel.
02787     */
02788    while (chan->masq) {
02789       ast_channel_unlock(chan);
02790       ast_do_masquerade(chan);
02791       ast_channel_lock(chan);
02792    }
02793 
02794    if (chan->masqr) {
02795       /*
02796        * This channel is one which will be masqueraded into something.
02797        * Mark it as a zombie already so ast_do_masquerade() will know
02798        * to free it later.
02799        */
02800       ast_set_flag(chan, AST_FLAG_ZOMBIE);
02801       destroy_hooks(chan);
02802       ast_channel_unlock(chan);
02803       return 0;
02804    }
02805 
02806    /* Mark as a zombie so a masquerade cannot be setup on this channel. */
02807    if (!(was_zombie = ast_test_flag(chan, AST_FLAG_ZOMBIE))) {
02808       ast_set_flag(chan, AST_FLAG_ZOMBIE);
02809    }
02810 
02811    ast_channel_unlock(chan);
02812    ao2_unlink(channels, chan);
02813    ast_channel_lock(chan);
02814 
02815    destroy_hooks(chan);
02816 
02817    free_translation(chan);
02818    /* Close audio stream */
02819    if (chan->stream) {
02820       ast_closestream(chan->stream);
02821       chan->stream = NULL;
02822    }
02823    /* Close video stream */
02824    if (chan->vstream) {
02825       ast_closestream(chan->vstream);
02826       chan->vstream = NULL;
02827    }
02828    if (chan->sched) {
02829       sched_context_destroy(chan->sched);
02830       chan->sched = NULL;
02831    }
02832 
02833    if (chan->generatordata) { /* Clear any tone stuff remaining */
02834       if (chan->generator && chan->generator->release) {
02835          chan->generator->release(chan, chan->generatordata);
02836       }
02837    }
02838    chan->generatordata = NULL;
02839    chan->generator = NULL;
02840 
02841    snprintf(extra_str, sizeof(extra_str), "%d,%s,%s", chan->hangupcause, chan->hangupsource, S_OR(pbx_builtin_getvar_helper(chan, "DIALSTATUS"), ""));
02842    ast_cel_report_event(chan, AST_CEL_HANGUP, NULL, extra_str, NULL);
02843 
02844    if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
02845       ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
02846          "is blocked by thread %ld in procedure %s!  Expect a failure\n",
02847          (long) pthread_self(), chan->name, (long)chan->blocker, chan->blockproc);
02848       ast_assert(ast_test_flag(chan, AST_FLAG_BLOCKING) == 0);
02849    }
02850    if (!was_zombie) {
02851       ast_debug(1, "Hanging up channel '%s'\n", chan->name);
02852 
02853       if (chan->tech->hangup) {
02854          chan->tech->hangup(chan);
02855       }
02856    } else {
02857       ast_debug(1, "Hanging up zombie '%s'\n", chan->name);
02858    }
02859 
02860    ast_channel_unlock(chan);
02861 
02862    ast_cc_offer(chan);
02863    ast_manager_event(chan, EVENT_FLAG_CALL, "Hangup",
02864       "Channel: %s\r\n"
02865       "Uniqueid: %s\r\n"
02866       "CallerIDNum: %s\r\n"
02867       "CallerIDName: %s\r\n"
02868       "ConnectedLineNum: %s\r\n"
02869       "ConnectedLineName: %s\r\n"
02870       "Cause: %d\r\n"
02871       "Cause-txt: %s\r\n",
02872       chan->name,
02873       chan->uniqueid,
02874       S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "<unknown>"),
02875       S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, "<unknown>"),
02876       S_COR(chan->connected.id.number.valid, chan->connected.id.number.str, "<unknown>"),
02877       S_COR(chan->connected.id.name.valid, chan->connected.id.name.str, "<unknown>"),
02878       chan->hangupcause,
02879       ast_cause2str(chan->hangupcause)
02880       );
02881 
02882    if (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_BRIDGED) &&
02883       !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED) &&
02884       (chan->cdr->disposition != AST_CDR_NULL || ast_test_flag(chan->cdr, AST_CDR_FLAG_DIALED))) {
02885       ast_channel_lock(chan);
02886       ast_cdr_end(chan->cdr);
02887       ast_cdr_detach(chan->cdr);
02888       chan->cdr = NULL;
02889       ast_channel_unlock(chan);
02890    }
02891 
02892    ast_channel_unref(chan);
02893 
02894    return 0;
02895 }

int ast_indicate ( struct ast_channel chan,
int  condition 
)

Indicates condition of channel.

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

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

References ast_indicate_data(), and chanlist::chan.

Referenced by __ast_play_and_record(), agent_request(), alsa_call(), answer_trunk_chan(), ast_bridge_call(), 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(), do_forward(), feature_request_and_dial(), finishup(), 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(), rna(), say_periodic_announcement(), say_position(), send_waveform_to_channel(), skinny_ss(), sla_handle_hold_event(), sla_station_exec(), and sla_trunk_exec().

04297 {
04298    return ast_indicate_data(chan, condition, NULL, 0);
04299 }

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

Indicates condition of channel, with payload.

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

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

References ast_channel::_state, _XXX_AST_CONTROL_T38, ast_channel_lock, 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_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(), chanlist::chan, ast_channel::connected, chanlist::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_channel::name, 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_handle_cc_control_frame(), ast_indicate(), disable_t38(), feature_request_and_dial(), generic_fax_exec(), handle_frame(), 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().

04352 {
04353    /* By using an enum, we'll get compiler warnings for values not handled 
04354     * in switch statements. */
04355    enum ast_control_frame_type condition = _condition;
04356    struct ast_tone_zone_sound *ts = NULL;
04357    int res;
04358    /* this frame is used by framehooks. if it is set, we must free it at the end of this function */
04359    struct ast_frame *awesome_frame = NULL;
04360 
04361    ast_channel_lock(chan);
04362 
04363    /* Don't bother if the channel is about to go away, anyway. */
04364    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
04365       res = -1;
04366       goto indicate_cleanup;
04367    }
04368 
04369    if (!ast_framehook_list_is_empty(chan->framehooks)) {
04370       /* Do framehooks now, do it, go, go now */
04371       struct ast_frame frame = {
04372          .frametype = AST_FRAME_CONTROL,
04373          .subclass.integer = condition,
04374          .data.ptr = (void *) data, /* this cast from const is only okay because we do the ast_frdup below */
04375          .datalen = datalen
04376       };
04377 
04378       /* we have now committed to freeing this frame */
04379       awesome_frame = ast_frdup(&frame);
04380 
04381       /* who knows what we will get back! the anticipation is killing me. */
04382       if (!(awesome_frame = ast_framehook_list_write_event(chan->framehooks, awesome_frame))
04383          || awesome_frame->frametype != AST_FRAME_CONTROL) {
04384 
04385          res = 0;
04386          goto indicate_cleanup;
04387       }
04388 
04389       condition = awesome_frame->subclass.integer;
04390       data = awesome_frame->data.ptr;
04391       datalen = awesome_frame->datalen;
04392    }
04393 
04394    switch (condition) {
04395    case AST_CONTROL_CONNECTED_LINE:
04396       {
04397          struct ast_party_connected_line connected;
04398 
04399          ast_party_connected_line_set_init(&connected, &chan->connected);
04400          res = ast_connected_line_parse_data(data, datalen, &connected);
04401          if (!res) {
04402             ast_channel_set_connected_line(chan, &connected, NULL);
04403          }
04404          ast_party_connected_line_free(&connected);
04405       }
04406       break;
04407 
04408    case AST_CONTROL_REDIRECTING:
04409       {
04410          struct ast_party_redirecting redirecting;
04411 
04412          ast_party_redirecting_set_init(&redirecting, &chan->redirecting);
04413          res = ast_redirecting_parse_data(data, datalen, &redirecting);
04414          if (!res) {
04415             ast_channel_set_redirecting(chan, &redirecting, NULL);
04416          }
04417          ast_party_redirecting_free(&redirecting);
04418       }
04419       break;
04420    
04421    default:
04422       break;
04423    }
04424 
04425    if (is_visible_indication(condition)) {
04426       /* A new visible indication is requested. */
04427       chan->visible_indication = condition;
04428    } else if (condition == AST_CONTROL_UNHOLD || _condition < 0) {
04429       /* Visible indication is cleared/stopped. */
04430       chan->visible_indication = 0;
04431    }
04432 
04433    if (chan->tech->indicate) {
04434       /* See if the channel driver can handle this condition. */
04435       res = chan->tech->indicate(chan, condition, data, datalen);
04436    } else {
04437       res = -1;
04438    }
04439 
04440    if (!res) {
04441       /* The channel driver successfully handled this indication */
04442       res = 0;
04443       goto indicate_cleanup;
04444    }
04445 
04446    /* The channel driver does not support this indication, let's fake
04447     * it by doing our own tone generation if applicable. */
04448 
04449    /*!\note If we compare the enumeration type, which does not have any
04450     * negative constants, the compiler may optimize this code away.
04451     * Therefore, we must perform an integer comparison here. */
04452    if (_condition < 0) {
04453       /* Stop any tones that are playing */
04454       ast_playtones_stop(chan);
04455       res = 0;
04456       goto indicate_cleanup;
04457    }
04458 
04459    /* Handle conditions that we have tones for. */
04460    switch (condition) {
04461    case _XXX_AST_CONTROL_T38:
04462       /* deprecated T.38 control frame */
04463       res = -1;
04464       goto indicate_cleanup;
04465    case AST_CONTROL_T38_PARAMETERS:
04466       /* there is no way to provide 'default' behavior for these
04467        * control frames, so we need to return failure, but there
04468        * is also no value in the log message below being emitted
04469        * since failure to handle these frames is not an 'error'
04470        * so just return right now. in addition, we want to return
04471        * whatever value the channel driver returned, in case it
04472        * has some meaning.*/
04473       goto indicate_cleanup;
04474    case AST_CONTROL_RINGING:
04475       ts = ast_get_indication_tone(chan->zone, "ring");
04476       /* It is common practice for channel drivers to return -1 if trying
04477        * to indicate ringing on a channel which is up. The idea is to let the
04478        * core generate the ringing inband. However, we don't want the
04479        * warning message about not being able to handle the specific indication
04480        * to print nor do we want ast_indicate_data to return an "error" for this
04481        * condition
04482        */
04483       if (chan->_state == AST_STATE_UP) {
04484          res = 0;
04485       }
04486       break;
04487    case AST_CONTROL_BUSY:
04488       ts = ast_get_indication_tone(chan->zone, "busy");
04489       break;
04490    case AST_CONTROL_INCOMPLETE:
04491    case AST_CONTROL_CONGESTION:
04492       ts = ast_get_indication_tone(chan->zone, "congestion");
04493       break;
04494    case AST_CONTROL_PROGRESS:
04495    case AST_CONTROL_PROCEEDING:
04496    case AST_CONTROL_VIDUPDATE:
04497    case AST_CONTROL_SRCUPDATE:
04498    case AST_CONTROL_SRCCHANGE:
04499    case AST_CONTROL_RADIO_KEY:
04500    case AST_CONTROL_RADIO_UNKEY:
04501    case AST_CONTROL_OPTION:
04502    case AST_CONTROL_WINK:
04503    case AST_CONTROL_FLASH:
04504    case AST_CONTROL_OFFHOOK:
04505    case AST_CONTROL_TAKEOFFHOOK:
04506    case AST_CONTROL_ANSWER:
04507    case AST_CONTROL_HANGUP:
04508    case AST_CONTROL_RING:
04509    case AST_CONTROL_HOLD:
04510    case AST_CONTROL_UNHOLD:
04511    case AST_CONTROL_TRANSFER:
04512    case AST_CONTROL_CONNECTED_LINE:
04513    case AST_CONTROL_REDIRECTING:
04514    case AST_CONTROL_CC:
04515    case AST_CONTROL_READ_ACTION:
04516    case AST_CONTROL_AOC:
04517    case AST_CONTROL_END_OF_Q:
04518    case AST_CONTROL_UPDATE_RTP_PEER:
04519       /* Nothing left to do for these. */
04520       res = 0;
04521       break;
04522    }
04523 
04524    if (ts) {
04525       /* We have a tone to play, yay. */
04526       ast_debug(1, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
04527       res = ast_playtones_start(chan, 0, ts->data, 1);
04528       ts = ast_tone_zone_sound_unref(ts);
04529    }
04530 
04531    if (res) {
04532       /* not handled */
04533       ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
04534    }
04535 
04536 indicate_cleanup:
04537    ast_channel_unlock(chan);
04538    if (awesome_frame) {
04539       ast_frfree(awesome_frame);
04540    }
04541 
04542    return res;
04543 }

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

References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.

Referenced by load_module().

07839 {
07840    ast_moh_start_ptr = start_ptr;
07841    ast_moh_stop_ptr = stop_ptr;
07842    ast_moh_cleanup_ptr = cleanup_ptr;
07843 }

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

References ast_opt_internal_timing, chanlist::chan, and ast_channel::timingfd.

Referenced by add_sdp(), and ast_read_generator_actions().

04282 {
04283    return (ast_opt_internal_timing && chan->timingfd > -1);
04284 }

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

01791 {
01792    /* Do not add a default entry in this switch statement.  Each new
01793     * frame type should be addressed directly as to whether it should
01794     * be queued up or not.
01795     */
01796    switch (frame->frametype) {
01797    case AST_FRAME_CONTROL:
01798    case AST_FRAME_TEXT:
01799    case AST_FRAME_IMAGE:
01800    case AST_FRAME_HTML:
01801       return 1;
01802 
01803    case AST_FRAME_DTMF_END:
01804    case AST_FRAME_DTMF_BEGIN:
01805    case AST_FRAME_VOICE:
01806    case AST_FRAME_VIDEO:
01807    case AST_FRAME_NULL:
01808    case AST_FRAME_IAX:
01809    case AST_FRAME_CNG:
01810    case AST_FRAME_MODEM:
01811       return 0;
01812    }
01813    return 0;
01814 }

void ast_moh_cleanup ( struct ast_channel chan  ) 

Definition at line 7870 of file channel.c.

References ast_moh_cleanup_ptr.

Referenced by ast_channel_destructor().

07871 {
07872    if (ast_moh_cleanup_ptr)
07873       ast_moh_cleanup_ptr(chan);
07874 }

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

References ast_moh_start_ptr, and ast_verb.

Referenced by alsa_indicate(), app_exec(), conf_start_moh(), 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(), menu_callback(), 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(), sig_pri_indicate(), sip_indicate(), skinny_indicate(), start_moh_exec(), TransferCallStep1(), unistim_indicate(), and wait_moh_exec().

07854 {
07855    if (ast_moh_start_ptr)
07856       return ast_moh_start_ptr(chan, mclass, interpclass);
07857 
07858    ast_verb(3, "Music class %s requested but no musiconhold loaded.\n", mclass ? mclass : (interpclass ? interpclass : "default"));
07859 
07860    return 0;
07861 }

void ast_moh_stop ( struct ast_channel chan  ) 

Turn off music on hold on a given channel.

Turn off music on hold on a given channel

Definition at line 7864 of file channel.c.

References ast_moh_stop_ptr.

Referenced by alsa_indicate(), app_exec(), ast_quiet_chan(), conf_run(), console_indicate(), dahdi_indicate(), dial_exec_full(), do_bridge_masquerade(), feature_exec_app(), gtalk_indicate(), handle_setmusic(), iax2_indicate(), jingle_indicate(), key_call(), key_dial_page(), local_indicate(), menu_callback(), mgcp_indicate(), misdn_indication(), moh_handle_digit(), monitor_dial(), oh323_indicate(), oss_indicate(), phone_indicate(), play_moh_exec(), post_join_marked(), post_join_unmarked(), retrydial_exec(), say_periodic_announcement(), say_position(), sig_pri_indicate(), sip_indicate(), skinny_indicate(), stop_moh_exec(), unistim_hangup(), unistim_indicate(), and wait_moh_exec().

07865 {
07866    if (ast_moh_stop_ptr)
07867       ast_moh_stop_ptr(chan);
07868 }

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

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

02245 {
02246    if (dest == src) {
02247       /* Don't copy to self */
02248       return;
02249    }
02250 
02251    ast_party_id_copy(&dest->id, &src->id);
02252    ast_party_id_copy(&dest->ani, &src->ani);
02253    dest->ani2 = src->ani2;
02254 }

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

02271 {
02272    ast_party_id_free(&doomed->id);
02273    ast_party_id_free(&doomed->ani);
02274 }

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 2237 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(), sig_pri_set_caller_id(), and sla_ring_station().

02238 {
02239    ast_party_id_init(&init->id);
02240    ast_party_id_init(&init->ani);
02241    init->ani2 = 0;
02242 }

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

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

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

02264 {
02265    ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL);
02266    ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL);
02267    dest->ani2 = src->ani2;
02268 }

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 2256 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(), ring_entry(), and sig_pri_handle_subcmds().

02257 {
02258    ast_party_id_set_init(&init->id, &guide->id);
02259    ast_party_id_set_init(&init->ani, &guide->ani);
02260    init->ani2 = guide->ani2;
02261 }

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 2313 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_channel::caller, chanlist::connected, ast_party_caller::id, ast_party_connected_line::id, and ast_party_connected_line::source.

02314 {
02315    connected->id = caller->id;
02316    connected->ani = caller->ani;
02317    connected->ani2 = caller->ani2;
02318    connected->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN;
02319 }

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 2284 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(), and party_connected_line_copy_transfer().

02285 {
02286    if (dest == src) {
02287       /* Don't copy to self */
02288       return;
02289    }
02290 
02291    ast_party_id_copy(&dest->id, &src->id);
02292    ast_party_id_copy(&dest->ani, &src->ani);
02293    dest->ani2 = src->ani2;
02294    dest->source = src->source;
02295 }

void ast_party_connected_line_free ( struct ast_party_connected_line doomed  ) 

Destroy the connected line information contents.

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

Definition at line 2321 of file channel.c.

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

Referenced by __ast_read(), app_exec(), ast_channel_connected_line_macro(), ast_channel_destructor(), ast_do_pickup(), ast_dummy_channel_destructor(), ast_indicate_data(), atxfer_fail_cleanup(), builtin_atxfer(), callattempt_free(), chanlist_free(), connectedline_write(), destroy_calling_tree(), feature_request_and_dial(), local_attended_transfer(), misdn_attempt_transfer(), parked_call_exec(), sig_pri_handle_subcmds(), socket_process(), wait_for_answer(), wait_for_winner(), and xfer_ds_destroy().

02322 {
02323    ast_party_id_free(&doomed->id);
02324    ast_party_id_free(&doomed->ani);
02325 }

void ast_party_connected_line_init ( struct ast_party_connected_line init  ) 

Initialize the given connected line structure.

Since:
1.8
Parameters:
init Connected line structure to initialize.
Returns:
Nothing

Definition at line 2276 of file channel.c.

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

Referenced by __ast_channel_alloc_ap(), __ast_read(), ast_channel_connected_line_macro(), ast_do_pickup(), builtin_atxfer(), do_forward(), handle_request_invite(), handle_request_update(), handle_response_invite(), local_attended_transfer(), misdn_attempt_transfer(), misdn_queue_connected_line_update(), parked_call_exec(), sig_pri_handle_subcmds(), sip_call(), socket_process(), and wait_for_answer().

02277 {
02278    ast_party_id_init(&init->id);
02279    ast_party_id_init(&init->ani);
02280    init->ani2 = 0;
02281    init->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN;
02282 }

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

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

Referenced by ast_channel_set_connected_line(), and wait_for_winner().

02306 {
02307    ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL);
02308    ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL);
02309    dest->ani2 = src->ani2;
02310    dest->source = src->source;
02311 }

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 2297 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(), and wait_for_winner().

02298 {
02299    ast_party_id_set_init(&init->id, &guide->id);
02300    ast_party_id_set_init(&init->ani, &guide->ani);
02301    init->ani2 = guide->ani2;
02302    init->source = guide->source;
02303 }

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

02196 {
02197    if (dest == src) {
02198       /* Don't copy to self */
02199       return;
02200    }
02201 
02202    ast_free(dest->number.str);
02203    dest->number.str = ast_strdup(src->number.str);
02204    dest->number.plan = src->number.plan;
02205    ast_party_subaddress_copy(&dest->subaddress, &src->subaddress);
02206    dest->transit_network_select = src->transit_network_select;
02207 }

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

02231 {
02232    ast_free(doomed->number.str);
02233    doomed->number.str = NULL;
02234    ast_party_subaddress_free(&doomed->subaddress);
02235 }

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

02188 {
02189    init->number.str = NULL;
02190    init->number.plan = 0;/* Unknown */
02191    ast_party_subaddress_init(&init->subaddress);
02192    init->transit_network_select = 0;
02193 }

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

02218 {
02219    if (src->number.str && src->number.str != dest->number.str) {
02220       ast_free(dest->number.str);
02221       dest->number.str = ast_strdup(src->number.str);
02222    }
02223    dest->number.plan = src->number.plan;
02224 
02225    ast_party_subaddress_set(&dest->subaddress, &src->subaddress);
02226 
02227    dest->transit_network_select = src->transit_network_select;
02228 }

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

02210 {
02211    init->number.str = NULL;
02212    init->number.plan = guide->number.plan;
02213    ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress);
02214    init->transit_network_select = guide->transit_network_select;
02215 }

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

02064 {
02065    if (dest == src) {
02066       /* Don't copy to self */
02067       return;
02068    }
02069 
02070    ast_party_name_copy(&dest->name, &src->name);
02071    ast_party_number_copy(&dest->number, &src->number);
02072    ast_party_subaddress_copy(&dest->subaddress, &src->subaddress);
02073 
02074    ast_free(dest->tag);
02075    dest->tag = ast_strdup(src->tag);
02076 }

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 2109 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(), parkandannounce_exec(), and sig_pri_mcid_event().

02110 {
02111    ast_party_name_free(&doomed->name);
02112    ast_party_number_free(&doomed->number);
02113    ast_party_subaddress_free(&doomed->subaddress);
02114 
02115    ast_free(doomed->tag);
02116    doomed->tag = NULL;
02117 }

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 2055 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(), parkandannounce_exec(), and sig_pri_mcid_event().

02056 {
02057    ast_party_name_init(&init->name);
02058    ast_party_number_init(&init->number);
02059    ast_party_subaddress_init(&init->subaddress);
02060    init->tag = NULL;
02061 }

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

References AST_PRES_ALLOWED, AST_PRES_NUMBER_NOT_AVAILABLE, AST_PRES_NUMBER_TYPE, AST_PRES_RESTRICTED, AST_PRES_RESTRICTION, AST_PRES_UNAVAILABLE, AST_PRES_USER_NUMBER_UNSCREENED, and id.

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

02120 {
02121    int number_priority;
02122    int number_value;
02123    int number_screening;
02124    int name_priority;
02125    int name_value;
02126 
02127    /* Determine name presentation priority. */
02128    if (!id->name.valid) {
02129       name_value = AST_PRES_UNAVAILABLE;
02130       name_priority = 3;
02131    } else {
02132       name_value = id->name.presentation & AST_PRES_RESTRICTION;
02133       switch (name_value) {
02134       case AST_PRES_RESTRICTED:
02135          name_priority = 0;
02136          break;
02137       case AST_PRES_ALLOWED:
02138          name_priority = 1;
02139          break;
02140       case AST_PRES_UNAVAILABLE:
02141          name_priority = 2;
02142          break;
02143       default:
02144          name_value = AST_PRES_UNAVAILABLE;
02145          name_priority = 3;
02146          break;
02147       }
02148    }
02149 
02150    /* Determine number presentation priority. */
02151    if (!id->number.valid) {
02152       number_screening = AST_PRES_USER_NUMBER_UNSCREENED;
02153       number_value = AST_PRES_UNAVAILABLE;
02154       number_priority = 3;
02155    } else {
02156       number_screening = id->number.presentation & AST_PRES_NUMBER_TYPE;
02157       number_value = id->number.presentation & AST_PRES_RESTRICTION;
02158       switch (number_value) {
02159       case AST_PRES_RESTRICTED:
02160          number_priority = 0;
02161          break;
02162       case AST_PRES_ALLOWED:
02163          number_priority = 1;
02164          break;
02165       case AST_PRES_UNAVAILABLE:
02166          number_priority = 2;
02167          break;
02168       default:
02169          number_screening = AST_PRES_USER_NUMBER_UNSCREENED;
02170          number_value = AST_PRES_UNAVAILABLE;
02171          number_priority = 3;
02172          break;
02173       }
02174    }
02175 
02176    /* Select the wining presentation value. */
02177    if (name_priority < number_priority) {
02178       number_value = name_value;
02179    }
02180    if (number_value == AST_PRES_UNAVAILABLE) {
02181       return AST_PRES_NUMBER_NOT_AVAILABLE;
02182    }
02183 
02184    return number_value | number_screening;
02185 }

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 2086 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_party_id::number, ast_party_id::subaddress, ast_party_id::tag, and update().

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

02087 {
02088    if (dest == src) {
02089       /* Don't set to self */
02090       return;
02091    }
02092 
02093    if (!update || update->name) {
02094       ast_party_name_set(&dest->name, &src->name);
02095    }
02096    if (!update || update->number) {
02097       ast_party_number_set(&dest->number, &src->number);
02098    }
02099    if (!update || update->subaddress) {
02100       ast_party_subaddress_set(&dest->subaddress, &src->subaddress);
02101    }
02102 
02103    if (src->tag && src->tag != dest->tag) {
02104       ast_free(dest->tag);
02105       dest->tag = ast_strdup(src->tag);
02106    }
02107 }

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

02079 {
02080    ast_party_name_set_init(&init->name, &guide->name);
02081    ast_party_number_set_init(&init->number, &guide->number);
02082    ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress);
02083    init->tag = NULL;
02084 }

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

01905 {
01906    if (dest == src) {
01907       /* Don't copy to self */
01908       return;
01909    }
01910 
01911    ast_free(dest->str);
01912    dest->str = ast_strdup(src->str);
01913    dest->char_set = src->char_set;
01914    dest->presentation = src->presentation;
01915    dest->valid = src->valid;
01916 }

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

01944 {
01945    ast_free(doomed->str);
01946    doomed->str = NULL;
01947 }

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

01897 {
01898    init->str = NULL;
01899    init->char_set = AST_PARTY_CHAR_SET_ISO8859_1;
01900    init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
01901    init->valid = 0;
01902 }

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

01927 {
01928    if (dest == src) {
01929       /* Don't set to self */
01930       return;
01931    }
01932 
01933    if (src->str && src->str != dest->str) {
01934       ast_free(dest->str);
01935       dest->str = ast_strdup(src->str);
01936    }
01937 
01938    dest->char_set = src->char_set;
01939    dest->presentation = src->presentation;
01940    dest->valid = src->valid;
01941 }

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

01919 {
01920    init->str = NULL;
01921    init->char_set = guide->char_set;
01922    init->presentation = guide->presentation;
01923    init->valid = guide->valid;
01924 }

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

01958 {
01959    if (dest == src) {
01960       /* Don't copy to self */
01961       return;
01962    }
01963 
01964    ast_free(dest->str);
01965    dest->str = ast_strdup(src->str);
01966    dest->plan = src->plan;
01967    dest->presentation = src->presentation;
01968    dest->valid = src->valid;
01969 }

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 1996 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(), and skinny_newcall().

01997 {
01998    ast_free(doomed->str);
01999    doomed->str = NULL;
02000 }

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 1949 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(), and skinny_newcall().

01950 {
01951    init->str = NULL;
01952    init->plan = 0;/* Unknown */
01953    init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
01954    init->valid = 0;
01955 }

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

01980 {
01981    if (dest == src) {
01982       /* Don't set to self */
01983       return;
01984    }
01985 
01986    if (src->str && src->str != dest->str) {
01987       ast_free(dest->str);
01988       dest->str = ast_strdup(src->str);
01989    }
01990 
01991    dest->plan = src->plan;
01992    dest->presentation = src->presentation;
01993    dest->valid = src->valid;
01994 }

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

01972 {
01973    init->str = NULL;
01974    init->plan = guide->plan;
01975    init->presentation = guide->presentation;
01976    init->valid = guide->valid;
01977 }

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 2335 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(), and ring_entry().

02336 {
02337    if (dest == src) {
02338       /* Don't copy to self */
02339       return;
02340    }
02341 
02342    ast_party_id_copy(&dest->from, &src->from);
02343    ast_party_id_copy(&dest->to, &src->to);
02344    dest->count = src->count;
02345    dest->reason = src->reason;
02346 }

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

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

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

02365 {
02366    ast_party_id_free(&doomed->from);
02367    ast_party_id_free(&doomed->to);
02368 }

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 2327 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(), ast_channel_redirecting_macro(), call_forward_inherit(), do_forward(), handle_request_invite(), handle_response(), and handle_response_invite().

02328 {
02329    ast_party_id_init(&init->from);
02330    ast_party_id_init(&init->to);
02331    init->count = 0;
02332    init->reason = AST_REDIRECTING_REASON_UNKNOWN;
02333 }

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

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

Referenced by ast_channel_set_redirecting().

02357 {
02358    ast_party_id_set(&dest->from, &src->from, update ? &update->from : NULL);
02359    ast_party_id_set(&dest->to, &src->to, update ? &update->to : NULL);
02360    dest->reason = src->reason;
02361    dest->count = src->count;
02362 }

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 2348 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(), redirecting_write(), and sig_pri_redirecting_convert().

02349 {
02350    ast_party_id_set_init(&init->from, &guide->from);
02351    ast_party_id_set_init(&init->to, &guide->to);
02352    init->count = guide->count;
02353    init->reason = guide->reason;
02354 }

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

02011 {
02012    if (dest == src) {
02013       /* Don't copy to self */
02014       return;
02015    }
02016 
02017    ast_free(dest->str);
02018    dest->str = ast_strdup(src->str);
02019    dest->type = src->type;
02020    dest->odd_even_indicator = src->odd_even_indicator;
02021    dest->valid = src->valid;
02022 }

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

References ast_free, and ast_party_subaddress::str.

Referenced by ast_party_dialed_free(), and ast_party_id_free().

02050 {
02051    ast_free(doomed->str);
02052    doomed->str = NULL;
02053 }

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 2002 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(), ast_party_id_init(), sig_pri_call(), and sig_pri_set_subaddress().

02003 {
02004    init->str = NULL;
02005    init->type = 0;
02006    init->odd_even_indicator = 0;
02007    init->valid = 0;
02008 }

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 2032 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(), ast_party_id_set(), and sig_pri_handle_subcmds().

02033 {
02034    if (dest == src) {
02035       /* Don't set to self */
02036       return;
02037    }
02038 
02039    if (src->str && src->str != dest->str) {
02040       ast_free(dest->str);
02041       dest->str = ast_strdup(src->str);
02042    }
02043 
02044    dest->type = src->type;
02045    dest->odd_even_indicator = src->odd_even_indicator;
02046    dest->valid = src->valid;
02047 }

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

02025 {
02026    init->str = NULL;
02027    init->type = guide->type;
02028    init->odd_even_indicator = guide->odd_even_indicator;
02029    init->valid = guide->valid;
02030 }

int ast_plc_reload ( void   ) 

Reload genericplc configuration value from codecs.conf.

Implementation is in main/channel.c

Definition at line 7889 of file channel.c.

References 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, and var.

Referenced by ast_channels_init().

07890 {
07891    struct ast_variable *var;
07892    struct ast_flags config_flags = { 0 };
07893    struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
07894    if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID)
07895       return 0;
07896    for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
07897       if (!strcasecmp(var->name, "genericplc")) {
07898          ast_set2_flag(&ast_options, ast_true(var->value), AST_OPT_FLAG_GENERIC_PLC);
07899       }
07900    }
07901    ast_config_destroy(cfg);
07902    return 0;
07903 }

void ast_poll_channel_add ( struct ast_channel chan0,
struct ast_channel chan1 
)

Add a channel to an optimized waitfor

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

02633 {
02634 #ifdef HAVE_EPOLL
02635    struct epoll_event ev;
02636    int i = 0;
02637 
02638    if (chan0->epfd == -1)
02639       return;
02640 
02641    /* Iterate through the file descriptors on chan1, adding them to chan0 */
02642    for (i = 0; i < AST_MAX_FDS; i++) {
02643       if (chan1->fds[i] == -1)
02644          continue;
02645       ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP;
02646       ev.data.ptr = chan1->epfd_data[i];
02647       epoll_ctl(chan0->epfd, EPOLL_CTL_ADD, chan1->fds[i], &ev);
02648    }
02649 
02650 #endif
02651    return;
02652 }

void ast_poll_channel_del ( struct ast_channel chan0,
struct ast_channel chan1 
)

Delete a channel from an optimized waitfor

Definition at line 2655 of file channel.c.

References AST_MAX_FDS, and ast_channel::fds.

Referenced by feature_request_and_dial(), and monitor_dial().

02656 {
02657 #ifdef HAVE_EPOLL
02658    struct epoll_event ev;
02659    int i = 0;
02660 
02661    if (chan0->epfd == -1)
02662       return;
02663 
02664    for (i = 0; i < AST_MAX_FDS; i++) {
02665       if (chan1->fds[i] == -1)
02666          continue;
02667       epoll_ctl(chan0->epfd, EPOLL_CTL_DEL, chan1->fds[i], &ev);
02668    }
02669 
02670 #endif
02671    return;
02672 }

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

print call- and pickup groups into buffer

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

08038 {
08039    unsigned int i;
08040    int first = 1;
08041    char num[3];
08042 
08043    buf[0] = '\0';
08044    
08045    if (!group) /* Return empty string if no group */
08046       return buf;
08047 
08048    for (i = 0; i <= 63; i++) {   /* Max group is 63 */
08049       if (group & ((ast_group_t) 1 << i)) {
08050             if (!first) {
08051             strncat(buf, ", ", buflen - strlen(buf) - 1);
08052          } else {
08053             first = 0;
08054          }
08055          snprintf(num, sizeof(num), "%u", i);
08056          strncat(buf, num, buflen - strlen(buf) - 1);
08057       }
08058    }
08059    return buf;
08060 }

int ast_prod ( struct ast_channel chan  ) 

Send empty audio to prime a channel driver.

Definition at line 4669 of file channel.c.

References ast_channel::_state, ast_debug, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), AST_STATE_UP, ast_write(), chanlist::chan, ast_frame_subclass::codec, ast_frame::data, LOG_WARNING, ast_channel::name, ast_frame::ptr, ast_channel::rawwriteformat, ast_frame::src, and ast_frame::subclass.

Referenced by ast_activate_generator().

04670 {
04671    struct ast_frame a = { AST_FRAME_VOICE };
04672    char nothing[128];
04673 
04674    /* Send an empty audio frame to get things moving */
04675    if (chan->_state != AST_STATE_UP) {
04676       ast_debug(1, "Prodding channel '%s'\n", chan->name);
04677       a.subclass.codec = chan->rawwriteformat;
04678       a.data.ptr = nothing + AST_FRIENDLY_OFFSET;
04679       a.src = "ast_prod"; /* this better match check in ast_write */
04680       if (ast_write(chan, &a))
04681          ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name);
04682    }
04683    return 0;
04684 }

int ast_queue_control ( struct ast_channel chan,
enum ast_control_frame_type  control 
)

Queue a control frame with payload.

Parameters:
chan channel to queue frame onto
control type of control frame
Note:
The channel does not need to be locked before calling this function.
Return values:
zero on success
non-zero on failure

Definition at line 1573 of file channel.c.

References AST_FRAME_CONTROL, ast_queue_frame(), chanlist::chan, and f.

Referenced by __analog_handle_event(), __analog_ss_thread(), __ast_read(), __dahdi_exception(), __oh323_update_info(), analog_call(), analog_exception(), analog_hangup(), analog_ss_thread(), ast_do_pickup(), attempt_transfer(), auto_congest(), cb_events(), cli_console_answer(), cli_console_flash(), console_answer(), console_call(), console_sendtext(), dahdi_handle_event(), dahdi_hangup(), gtalk_is_answered(), gtalk_ringing_ack(), handle_hd_hf(), handle_offhook_message(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), handle_response_refer(), handle_soft_key_event_message(), handle_stimulus_message(), HandleCallIncoming(), jingle_is_answered(), jingle_ringing_ack(), masquerade_colp_transfer(), misdn_facility_ie_handler(), multicast_rtp_call(), nbs_call(), phone_call(), process_sdp(), receive_digit(), remote_hold(), send_cause2ast(), setup_rtp_connection(), skinny_call(), skinny_transfer(), skinny_unhold(), unistim_call(), and update_state().

01574 {
01575    struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control };
01576    return ast_queue_frame(chan, &f);
01577 }

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

References AST_FRAME_CONTROL, ast_queue_frame(), chanlist::chan, and f.

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(), handle_request_notify(), handle_response_refer(), iax2_queue_control_data(), iax2_transfer(), interpret_t38_parameters(), local_attended_transfer(), masquerade_colp_transfer(), process_sdp(), sig_pri_aoc_d_from_pri(), sig_pri_aoc_e_from_pri(), sig_pri_aoc_s_from_pri(), sig_pri_send_aoce_termination_request(), sip_sipredirect(), and skinny_hold().

01582 {
01583    struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control, .data.ptr = (void *) data, .datalen = datalen };
01584    return ast_queue_frame(chan, &f);
01585 }

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

References __ast_queue_frame(), and chanlist::chan.

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_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(), 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(), keypad_digit(), local_queue_frame(), mgcp_queue_frame(), oh323_simulate_dtmf_end(), oss_call(), pri_queue_frame(), process_sdp(), queue_dtmf_readq(), receive_digit(), receive_message(), sig_pri_dial_complete(), sig_pri_handle_hold(), sig_pri_handle_subcmds(), stream_monitor(), unistim_do_senddigit(), unistim_senddigit_end(), and wakeup_sub().

01531 {
01532    return __ast_queue_frame(chan, fin, 0, NULL);
01533 }

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

References __ast_queue_frame(), and chanlist::chan.

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

01536 {
01537    return __ast_queue_frame(chan, fin, 1, NULL);
01538 }

int ast_queue_hangup ( struct ast_channel chan  ) 

Queue a hangup frame.

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

Definition at line 1541 of file channel.c.

References ast_channel::_softhangup, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, ast_queue_frame(), AST_SOFTHANGUP_DEV, chanlist::chan, and f.

Referenced by bridge_queue_hangup(), cleanup_connection(), cli_console_hangup(), close_call(), gtalk_hangup_farend(), gtalk_is_answered(), handle_onhook_message(), handle_request_bye(), handle_soft_key_event_message(), iax2_destroy(), iax2_queue_hangup(), jingle_hangup_farend(), local_fixup(), local_hangup(), mgcp_queue_hangup(), and sip_queue_hangup_cause().

01542 {
01543    struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP };
01544    /* Yeah, let's not change a lock-critical value without locking */
01545    if (!ast_channel_trylock(chan)) {
01546       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01547       ast_channel_unlock(chan);
01548    }
01549    return ast_queue_frame(chan, &f);
01550 }

int ast_queue_hangup_with_cause ( struct ast_channel chan,
int  cause 
)

Queue a hangup frame with hangupcause set.

Note:
The channel does not need to be locked before calling this function.
Parameters:
[in] chan channel to queue frame onto
[in] cause the hangup cause
Returns:
0 on success, -1 on error
Since:
1.6.1

Definition at line 1553 of file channel.c.

References ast_channel::_softhangup, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, ast_queue_frame(), AST_SOFTHANGUP_DEV, chanlist::chan, f, and ast_channel::hangupcause.

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

01554 {
01555    struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP };
01556 
01557    if (cause >= 0)
01558       f.data.uint32 = cause;
01559 
01560    /* Yeah, let's not change a lock-critical value without locking */
01561    if (!ast_channel_trylock(chan)) {
01562       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01563       if (cause < 0)
01564          f.data.uint32 = chan->hangupcause;
01565 
01566       ast_channel_unlock(chan);
01567    }
01568 
01569    return ast_queue_frame(chan, &f);
01570 }

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 2897 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, chanlist::chan, and ast_channel::tech.

Referenced by __ast_answer(), and ast_bridge_call().

02898 {
02899    int res = 0;
02900 
02901    ast_channel_lock(chan);
02902 
02903    /* You can't answer an outbound call */
02904    if (ast_test_flag(chan, AST_FLAG_OUTGOING)) {
02905       ast_channel_unlock(chan);
02906       return 0;
02907    }
02908 
02909    /* Stop if we're a zombie or need a soft hangup */
02910    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
02911       ast_channel_unlock(chan);
02912       return -1;
02913    }
02914 
02915    ast_channel_unlock(chan);
02916 
02917    switch (chan->_state) {
02918    case AST_STATE_RINGING:
02919    case AST_STATE_RING:
02920       ast_channel_lock(chan);
02921       if (chan->tech->answer) {
02922          res = chan->tech->answer(chan);
02923       }
02924       ast_setstate(chan, AST_STATE_UP);
02925       if (cdr_answer) {
02926          ast_cdr_answer(chan->cdr);
02927       }
02928       ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL);
02929       ast_channel_unlock(chan);
02930       break;
02931    case AST_STATE_UP:
02932       ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL);
02933       /* Calling ast_cdr_answer when it it has previously been called
02934        * is essentially a no-op, so it is safe.
02935        */
02936       if (cdr_answer) {
02937          ast_cdr_answer(chan->cdr);
02938       }
02939       break;
02940    default:
02941       break;
02942    }
02943 
02944    ast_indicate(chan, -1);
02945 
02946    return res;
02947 }

struct ast_frame* ast_read ( struct ast_channel chan  ) 

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

References __ast_read(), and chanlist::chan.

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_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_idle_thread(), do_waiting(), echo_exec(), eivr_comm(), feature_request_and_dial(), find_cache(), generic_fax_exec(), handle_recordfile(), handle_speechrecognize(), 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(), recordthread(), remote_bridge_loop(), run_agi(), send_tone_burst(), send_waveform_to_channel(), sendfax_t38_init(), sendurl_exec(), speech_background(), transmit_audio(), transmit_t38(), wait_for_hangup(), wait_for_winner(), waitforring_exec(), and waitstream_core().

04287 {
04288    return __ast_read(chan, 0);
04289 }

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

Definition at line 3644 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_deactivate_generator(), ast_debug, ast_format_rate(), AST_FRAME_CNG, ast_internal_timing_enabled(), ast_settimeout(), chanlist::chan, f, ast_generator::generate, ast_channel::generator, generator_force(), ast_channel::generatordata, ast_channel::timingfd, ast_channel::timingfunc, and ast_channel::writeformat.

Referenced by __ast_read().

03645 {
03646    if (chan->generator && chan->generator->generate && chan->generatordata &&  !ast_internal_timing_enabled(chan)) {
03647       void *tmp = chan->generatordata;
03648       int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = chan->generator->generate;
03649       int res;
03650       int samples;
03651 
03652       if (chan->timingfunc) {
03653          ast_debug(1, "Generator got voice, switching to phase locked mode\n");
03654          ast_settimeout(chan, 0, NULL, NULL);
03655       }
03656 
03657       chan->generatordata = NULL;     /* reset, to let writes go through */
03658 
03659       if (f->subclass.codec != chan->writeformat) {
03660          float factor;
03661          factor = ((float) ast_format_rate(chan->writeformat)) / ((float) ast_format_rate(f->subclass.codec));
03662          samples = (int) ( ((float) f->samples) * factor );
03663       } else {
03664          samples = f->samples;
03665       }
03666       
03667       /* This unlock is here based on two assumptions that hold true at this point in the
03668        * code. 1) this function is only called from within __ast_read() and 2) all generators
03669        * call ast_write() in their generate callback.
03670        *
03671        * The reason this is added is so that when ast_write is called, the lock that occurs 
03672        * there will not recursively lock the channel. Doing this will cause intended deadlock 
03673        * avoidance not to work in deeper functions
03674        */
03675       ast_channel_unlock(chan);
03676       res = generate(chan, tmp, f->datalen, samples);
03677       ast_channel_lock(chan);
03678       chan->generatordata = tmp;
03679       if (res) {
03680          ast_debug(1, "Auto-deactivating generator\n");
03681          ast_deactivate_generator(chan);
03682       }
03683 
03684    } else if (f->frametype == AST_FRAME_CNG) {
03685       if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) {
03686          ast_debug(1, "Generator got CNG, switching to timed mode\n");
03687          ast_settimeout(chan, 50, generator_force, chan);
03688       }
03689    }
03690 }

struct ast_frame* ast_read_noaudio ( struct ast_channel chan  ) 

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

References __ast_read(), and chanlist::chan.

Referenced by ast_bridge_handle_trip(), and conf_run().

04292 {
04293    return __ast_read(chan, 1);
04294 }

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

References ast_readstring_full().

Referenced by adsi_begin_download(), adsi_get_cpeinfo(), adsi_load_session(), ast_app_getdata(), dialout(), do_directory(), forward_message(), privacy_exec(), vm_authenticate(), vm_newuser(), and vm_options().

05722 {
05723    return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1);
05724 }

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

05727 {
05728    int pos = 0;   /* index in the buffer where we accumulate digits */
05729    int to = ftimeout;
05730 
05731    struct ast_silence_generator *silgen = NULL;
05732 
05733    /* Stop if we're a zombie or need a soft hangup */
05734    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
05735       return -1;
05736    if (!len)
05737       return -1;
05738    for (;;) {
05739       int d;
05740       if (c->stream) {
05741          d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
05742          ast_stopstream(c);
05743          if (!silgen && ast_opt_transmit_silence)
05744             silgen = ast_channel_start_silence_generator(c);
05745          usleep(1000);
05746          if (!d)
05747             d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
05748       } else {
05749          if (!silgen && ast_opt_transmit_silence)
05750             silgen = ast_channel_start_silence_generator(c);
05751          d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
05752       }
05753       if (d < 0) {
05754          ast_channel_stop_silence_generator(c, silgen);
05755          return AST_GETDATA_FAILED;
05756       }
05757       if (d == 0) {
05758          s[pos] = '\0';
05759          ast_channel_stop_silence_generator(c, silgen);
05760          return AST_GETDATA_TIMEOUT;
05761       }
05762       if (d == 1) {
05763          s[pos] = '\0';
05764          ast_channel_stop_silence_generator(c, silgen);
05765          return AST_GETDATA_INTERRUPTED;
05766       }
05767       if (strchr(enders, d) && (pos == 0)) {
05768          s[pos] = '\0';
05769          ast_channel_stop_silence_generator(c, silgen);
05770          return AST_GETDATA_EMPTY_END_TERMINATED;
05771       }
05772       if (!strchr(enders, d)) {
05773          s[pos++] = d;
05774       }
05775       if (strchr(enders, d) || (pos >= len)) {
05776          s[pos] = '\0';
05777          ast_channel_stop_silence_generator(c, silgen);
05778          return AST_GETDATA_COMPLETE;
05779       }
05780       to = timeout;
05781    }
05782    /* Never reached */
05783    return 0;
05784 }

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

References ast_free, ast_recvtext(), and chanlist::chan.

Referenced by handle_recvchar().

04546 {
04547    int c;
04548    char *buf = ast_recvtext(chan, timeout);
04549    if (buf == NULL)
04550       return -1;  /* error or timeout */
04551    c = *(unsigned char *)buf;
04552    ast_free(buf);
04553    return c;
04554 }

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 4556 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(), chanlist::chan, and f.

Referenced by ast_recvchar(), and handle_recvtext().

04557 {
04558    int res, done = 0;
04559    char *buf = NULL;
04560    
04561    while (!done) {
04562       struct ast_frame *f;
04563       if (ast_check_hangup(chan))
04564          break;
04565       res = ast_waitfor(chan, timeout);
04566       if (res <= 0) /* timeout or error */
04567          break;
04568       timeout = res; /* update timeout */
04569       f = ast_read(chan);
04570       if (f == NULL)
04571          break; /* no frame */
04572       if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_HANGUP)
04573          done = 1;   /* force a break */
04574       else if (f->frametype == AST_FRAME_TEXT) {      /* what we want */
04575          buf = ast_strndup((char *) f->data.ptr, f->datalen);  /* dup and break */
04576          done = 1;
04577       }
04578       ast_frfree(f);
04579    }
04580    return buf;
04581 }

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 8939 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_party_redirecting::from, LOG_WARNING, ast_party_id_ies::name, party_id_build_data(), ast_party_redirecting::reason, ast_party_name_ies::str, ast_party_redirecting::to, update(), and value.

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

08940 {
08941    int32_t value;
08942    size_t pos = 0;
08943    int res;
08944 
08945    static const struct ast_party_id_ies from_ies = {
08946       .name.str = AST_REDIRECTING_FROM_NAME,
08947       .name.char_set = AST_REDIRECTING_FROM_NAME_CHAR_SET,
08948       .name.presentation = AST_REDIRECTING_FROM_NAME_PRESENTATION,
08949       .name.valid = AST_REDIRECTING_FROM_NAME_VALID,
08950 
08951       .number.str = AST_REDIRECTING_FROM_NUMBER,
08952       .number.plan = AST_REDIRECTING_FROM_NUMBER_PLAN,
08953       .number.presentation = AST_REDIRECTING_FROM_NUMBER_PRESENTATION,
08954       .number.valid = AST_REDIRECTING_FROM_NUMBER_VALID,
08955 
08956       .subaddress.str = AST_REDIRECTING_FROM_SUBADDRESS,
08957       .subaddress.type = AST_REDIRECTING_FROM_SUBADDRESS_TYPE,
08958       .subaddress.odd_even_indicator = AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN,
08959       .subaddress.valid = AST_REDIRECTING_FROM_SUBADDRESS_VALID,
08960 
08961       .tag = AST_REDIRECTING_FROM_TAG,
08962       .combined_presentation = AST_REDIRECTING_FROM_ID_PRESENTATION,
08963    };
08964    static const struct ast_party_id_ies to_ies = {
08965       .name.str = AST_REDIRECTING_TO_NAME,
08966       .name.char_set = AST_REDIRECTING_TO_NAME_CHAR_SET,
08967       .name.presentation = AST_REDIRECTING_TO_NAME_PRESENTATION,
08968       .name.valid = AST_REDIRECTING_TO_NAME_VALID,
08969 
08970       .number.str = AST_REDIRECTING_TO_NUMBER,
08971       .number.plan = AST_REDIRECTING_TO_NUMBER_PLAN,
08972       .number.presentation = AST_REDIRECTING_TO_NUMBER_PRESENTATION,
08973       .number.valid = AST_REDIRECTING_TO_NUMBER_VALID,
08974 
08975       .subaddress.str = AST_REDIRECTING_TO_SUBADDRESS,
08976       .subaddress.type = AST_REDIRECTING_TO_SUBADDRESS_TYPE,
08977       .subaddress.odd_even_indicator = AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN,
08978       .subaddress.valid = AST_REDIRECTING_TO_SUBADDRESS_VALID,
08979 
08980       .tag = AST_REDIRECTING_TO_TAG,
08981       .combined_presentation = AST_REDIRECTING_TO_ID_PRESENTATION,
08982    };
08983 
08984    /* Redirecting frame version */
08985    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08986       ast_log(LOG_WARNING, "No space left for redirecting frame version\n");
08987       return -1;
08988    }
08989    data[pos++] = AST_REDIRECTING_VERSION;
08990    data[pos++] = 1;
08991    data[pos++] = 2;/* Version 1 did not have a version ie */
08992 
08993    res = party_id_build_data(data + pos, datalen - pos, &redirecting->from,
08994       "redirecting-from", &from_ies, update ? &update->from : NULL);
08995    if (res < 0) {
08996       return -1;
08997    }
08998    pos += res;
08999 
09000    res = party_id_build_data(data + pos, datalen - pos, &redirecting->to,
09001       "redirecting-to", &to_ies, update ? &update->to : NULL);
09002    if (res < 0) {
09003       return -1;
09004    }
09005    pos += res;
09006 
09007    /* Redirecting reason */
09008    if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
09009       ast_log(LOG_WARNING, "No space left for redirecting reason\n");
09010       return -1;
09011    }
09012    data[pos++] = AST_REDIRECTING_REASON;
09013    data[pos++] = sizeof(value);
09014    value = htonl(redirecting->reason);
09015    memcpy(data + pos, &value, sizeof(value));
09016    pos += sizeof(value);
09017 
09018    /* Redirecting count */
09019    if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
09020       ast_log(LOG_WARNING, "No space left for redirecting count\n");
09021       return -1;
09022    }
09023    data[pos++] = AST_REDIRECTING_COUNT;
09024    data[pos++] = sizeof(value);
09025    value = htonl(redirecting->count);
09026    memcpy(data + pos, &value, sizeof(value));
09027    pos += sizeof(value);
09028 
09029    return pos;
09030 }

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

References 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_DEBUG, 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().

09033 {
09034    size_t pos;
09035    unsigned char ie_len;
09036    unsigned char ie_id;
09037    int32_t value;
09038    int frame_version = 1;
09039    int from_combined_presentation = 0;
09040    int got_from_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */
09041    int to_combined_presentation = 0;
09042    int got_to_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */
09043 
09044    for (pos = 0; pos < datalen; pos += ie_len) {
09045       if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) {
09046          ast_log(LOG_WARNING, "Invalid redirecting update\n");
09047          return -1;
09048       }
09049       ie_id = data[pos++];
09050       ie_len = data[pos++];
09051       if (datalen < pos + ie_len) {
09052          ast_log(LOG_WARNING, "Invalid redirecting update\n");
09053          return -1;
09054       }
09055 
09056       switch (ie_id) {
09057 /* Redirecting frame version */
09058       case AST_REDIRECTING_VERSION:
09059          if (ie_len != 1) {
09060             ast_log(LOG_WARNING, "Invalid redirecting frame version (%u)\n",
09061                (unsigned) ie_len);
09062             break;
09063          }
09064          frame_version = data[pos];
09065          break;
09066 /* Redirecting-from party id name */
09067       case AST_REDIRECTING_FROM_NAME:
09068          ast_free(redirecting->from.name.str);
09069          redirecting->from.name.str = ast_malloc(ie_len + 1);
09070          if (redirecting->from.name.str) {
09071             memcpy(redirecting->from.name.str, data + pos, ie_len);
09072             redirecting->from.name.str[ie_len] = 0;
09073          }
09074          break;
09075       case AST_REDIRECTING_FROM_NAME_CHAR_SET:
09076          if (ie_len != 1) {
09077             ast_log(LOG_WARNING, "Invalid redirecting-from name char set (%u)\n",
09078                (unsigned) ie_len);
09079             break;
09080          }
09081          redirecting->from.name.char_set = data[pos];
09082          break;
09083       case AST_REDIRECTING_FROM_NAME_PRESENTATION:
09084          if (ie_len != 1) {
09085             ast_log(LOG_WARNING, "Invalid redirecting-from name presentation (%u)\n",
09086                (unsigned) ie_len);
09087             break;
09088          }
09089          redirecting->from.name.presentation = data[pos];
09090          break;
09091       case AST_REDIRECTING_FROM_NAME_VALID:
09092          if (ie_len != 1) {
09093             ast_log(LOG_WARNING, "Invalid redirecting-from name valid (%u)\n",
09094                (unsigned) ie_len);
09095             break;
09096          }
09097          redirecting->from.name.valid = data[pos];
09098          break;
09099 /* Redirecting-from party id number */
09100       case AST_REDIRECTING_FROM_NUMBER:
09101          ast_free(redirecting->from.number.str);
09102          redirecting->from.number.str = ast_malloc(ie_len + 1);
09103          if (redirecting->from.number.str) {
09104             memcpy(redirecting->from.number.str, data + pos, ie_len);
09105             redirecting->from.number.str[ie_len] = 0;
09106          }
09107          break;
09108       case AST_REDIRECTING_FROM_NUMBER_PLAN:
09109          if (ie_len != 1) {
09110             ast_log(LOG_WARNING, "Invalid redirecting-from numbering plan (%u)\n",
09111                (unsigned) ie_len);
09112             break;
09113          }
09114          redirecting->from.number.plan = data[pos];
09115          break;
09116       case AST_REDIRECTING_FROM_NUMBER_PRESENTATION:
09117          if (ie_len != 1) {
09118             ast_log(LOG_WARNING, "Invalid redirecting-from number presentation (%u)\n",
09119                (unsigned) ie_len);
09120             break;
09121          }
09122          redirecting->from.number.presentation = data[pos];
09123          break;
09124       case AST_REDIRECTING_FROM_NUMBER_VALID:
09125          if (ie_len != 1) {
09126             ast_log(LOG_WARNING, "Invalid redirecting-from number valid (%u)\n",
09127                (unsigned) ie_len);
09128             break;
09129          }
09130          redirecting->from.number.valid = data[pos];
09131          break;
09132 /* Redirecting-from party id combined presentation */
09133       case AST_REDIRECTING_FROM_ID_PRESENTATION:
09134          if (ie_len != 1) {
09135             ast_log(LOG_WARNING, "Invalid redirecting-from combined presentation (%u)\n",
09136                (unsigned) ie_len);
09137             break;
09138          }
09139          from_combined_presentation = data[pos];
09140          got_from_combined_presentation = 1;
09141          break;
09142 /* Redirecting-from party id subaddress */
09143       case AST_REDIRECTING_FROM_SUBADDRESS:
09144          ast_free(redirecting->from.subaddress.str);
09145          redirecting->from.subaddress.str = ast_malloc(ie_len + 1);
09146          if (redirecting->from.subaddress.str) {
09147             memcpy(redirecting->from.subaddress.str, data + pos, ie_len);
09148             redirecting->from.subaddress.str[ie_len] = 0;
09149          }
09150          break;
09151       case AST_REDIRECTING_FROM_SUBADDRESS_TYPE:
09152          if (ie_len != 1) {
09153             ast_log(LOG_WARNING, "Invalid redirecting-from type of subaddress (%u)\n",
09154                (unsigned) ie_len);
09155             break;
09156          }
09157          redirecting->from.subaddress.type = data[pos];
09158          break;
09159       case AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN:
09160          if (ie_len != 1) {
09161             ast_log(LOG_WARNING,
09162                "Invalid redirecting-from subaddress odd-even indicator (%u)\n",
09163                (unsigned) ie_len);
09164             break;
09165          }
09166          redirecting->from.subaddress.odd_even_indicator = data[pos];
09167          break;
09168       case AST_REDIRECTING_FROM_SUBADDRESS_VALID:
09169          if (ie_len != 1) {
09170             ast_log(LOG_WARNING, "Invalid redirecting-from subaddress valid (%u)\n",
09171                (unsigned) ie_len);
09172             break;
09173          }
09174          redirecting->from.subaddress.valid = data[pos];
09175          break;
09176 /* Redirecting-from party id tag */
09177       case AST_REDIRECTING_FROM_TAG:
09178          ast_free(redirecting->from.tag);
09179          redirecting->from.tag = ast_malloc(ie_len + 1);
09180          if (redirecting->from.tag) {
09181             memcpy(redirecting->from.tag, data + pos, ie_len);
09182             redirecting->from.tag[ie_len] = 0;
09183          }
09184          break;
09185 /* Redirecting-to party id name */
09186       case AST_REDIRECTING_TO_NAME:
09187          ast_free(redirecting->to.name.str);
09188          redirecting->to.name.str = ast_malloc(ie_len + 1);
09189          if (redirecting->to.name.str) {
09190             memcpy(redirecting->to.name.str, data + pos, ie_len);
09191             redirecting->to.name.str[ie_len] = 0;
09192          }
09193          break;
09194       case AST_REDIRECTING_TO_NAME_CHAR_SET:
09195          if (ie_len != 1) {
09196             ast_log(LOG_WARNING, "Invalid redirecting-to name char set (%u)\n",
09197                (unsigned) ie_len);
09198             break;
09199          }
09200          redirecting->to.name.char_set = data[pos];
09201          break;
09202       case AST_REDIRECTING_TO_NAME_PRESENTATION:
09203          if (ie_len != 1) {
09204             ast_log(LOG_WARNING, "Invalid redirecting-to name presentation (%u)\n",
09205                (unsigned) ie_len);
09206             break;
09207          }
09208          redirecting->to.name.presentation = data[pos];
09209          break;
09210       case AST_REDIRECTING_TO_NAME_VALID:
09211          if (ie_len != 1) {
09212             ast_log(LOG_WARNING, "Invalid redirecting-to name valid (%u)\n",
09213                (unsigned) ie_len);
09214             break;
09215          }
09216          redirecting->to.name.valid = data[pos];
09217          break;
09218 /* Redirecting-to party id number */
09219       case AST_REDIRECTING_TO_NUMBER:
09220          ast_free(redirecting->to.number.str);
09221          redirecting->to.number.str = ast_malloc(ie_len + 1);
09222          if (redirecting->to.number.str) {
09223             memcpy(redirecting->to.number.str, data + pos, ie_len);
09224             redirecting->to.number.str[ie_len] = 0;
09225          }
09226          break;
09227       case AST_REDIRECTING_TO_NUMBER_PLAN:
09228          if (ie_len != 1) {
09229             ast_log(LOG_WARNING, "Invalid redirecting-to numbering plan (%u)\n",
09230                (unsigned) ie_len);
09231             break;
09232          }
09233          redirecting->to.number.plan = data[pos];
09234          break;
09235       case AST_REDIRECTING_TO_NUMBER_PRESENTATION:
09236          if (ie_len != 1) {
09237             ast_log(LOG_WARNING, "Invalid redirecting-to number presentation (%u)\n",
09238                (unsigned) ie_len);
09239             break;
09240          }
09241          redirecting->to.number.presentation = data[pos];
09242          break;
09243       case AST_REDIRECTING_TO_NUMBER_VALID:
09244          if (ie_len != 1) {
09245             ast_log(LOG_WARNING, "Invalid redirecting-to number valid (%u)\n",
09246                (unsigned) ie_len);
09247             break;
09248          }
09249          redirecting->to.number.valid = data[pos];
09250          break;
09251 /* Redirecting-to party id combined presentation */
09252       case AST_REDIRECTING_TO_ID_PRESENTATION:
09253          if (ie_len != 1) {
09254             ast_log(LOG_WARNING, "Invalid redirecting-to combined presentation (%u)\n",
09255                (unsigned) ie_len);
09256             break;
09257          }
09258          to_combined_presentation = data[pos];
09259          got_to_combined_presentation = 1;
09260          break;
09261 /* Redirecting-to party id subaddress */
09262       case AST_REDIRECTING_TO_SUBADDRESS:
09263          ast_free(redirecting->to.subaddress.str);
09264          redirecting->to.subaddress.str = ast_malloc(ie_len + 1);
09265          if (redirecting->to.subaddress.str) {
09266             memcpy(redirecting->to.subaddress.str, data + pos, ie_len);
09267             redirecting->to.subaddress.str[ie_len] = 0;
09268          }
09269          break;
09270       case AST_REDIRECTING_TO_SUBADDRESS_TYPE:
09271          if (ie_len != 1) {
09272             ast_log(LOG_WARNING, "Invalid redirecting-to type of subaddress (%u)\n",
09273                (unsigned) ie_len);
09274             break;
09275          }
09276          redirecting->to.subaddress.type = data[pos];
09277          break;
09278       case AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN:
09279          if (ie_len != 1) {
09280             ast_log(LOG_WARNING,
09281                "Invalid redirecting-to subaddress odd-even indicator (%u)\n",
09282                (unsigned) ie_len);
09283             break;
09284          }
09285          redirecting->to.subaddress.odd_even_indicator = data[pos];
09286          break;
09287       case AST_REDIRECTING_TO_SUBADDRESS_VALID:
09288          if (ie_len != 1) {
09289             ast_log(LOG_WARNING, "Invalid redirecting-to subaddress valid (%u)\n",
09290                (unsigned) ie_len);
09291             break;
09292          }
09293          redirecting->to.subaddress.valid = data[pos];
09294          break;
09295 /* Redirecting-to party id tag */
09296       case AST_REDIRECTING_TO_TAG:
09297          ast_free(redirecting->to.tag);
09298          redirecting->to.tag = ast_malloc(ie_len + 1);
09299          if (redirecting->to.tag) {
09300             memcpy(redirecting->to.tag, data + pos, ie_len);
09301             redirecting->to.tag[ie_len] = 0;
09302          }
09303          break;
09304 /* Redirecting reason */
09305       case AST_REDIRECTING_REASON:
09306          if (ie_len != sizeof(value)) {
09307             ast_log(LOG_WARNING, "Invalid redirecting reason (%u)\n",
09308                (unsigned) ie_len);
09309             break;
09310          }
09311          memcpy(&value, data + pos, sizeof(value));
09312          redirecting->reason = ntohl(value);
09313          break;
09314 /* Redirecting count */
09315       case AST_REDIRECTING_COUNT:
09316          if (ie_len != sizeof(value)) {
09317             ast_log(LOG_WARNING, "Invalid redirecting count (%u)\n",
09318                (unsigned) ie_len);
09319             break;
09320          }
09321          memcpy(&value, data + pos, sizeof(value));
09322          redirecting->count = ntohl(value);
09323          break;
09324 /* Redirecting unknown element */
09325       default:
09326          ast_log(LOG_DEBUG, "Unknown redirecting element: %u (%u)\n",
09327             (unsigned) ie_id, (unsigned) ie_len);
09328          break;
09329       }
09330    }
09331 
09332    switch (frame_version) {
09333    case 1:
09334       /*
09335        * The other end is an earlier version that we need to adjust
09336        * for compatibility.
09337        */
09338       redirecting->from.name.valid = 1;
09339       redirecting->from.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
09340       redirecting->from.number.valid = 1;
09341       if (got_from_combined_presentation) {
09342          redirecting->from.name.presentation = from_combined_presentation;
09343          redirecting->from.number.presentation = from_combined_presentation;
09344       }
09345 
09346       redirecting->to.name.valid = 1;
09347       redirecting->to.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
09348       redirecting->to.number.valid = 1;
09349       if (got_to_combined_presentation) {
09350          redirecting->to.name.presentation = to_combined_presentation;
09351          redirecting->to.number.presentation = to_combined_presentation;
09352       }
09353       break;
09354    case 2:
09355       /* The other end is at the same level as we are. */
09356       break;
09357    default:
09358       /*
09359        * The other end is newer than we are.
09360        * We need to assume that they are compatible with us.
09361        */
09362       ast_log(LOG_DEBUG, "Redirecting frame has newer version: %u\n",
09363          (unsigned) frame_version);
09364       break;
09365    }
09366 
09367    return 0;
09368 }

struct ast_channel* ast_request ( const char *  type,
format_t  format,
const struct ast_channel requestor,
void *  data,
int *  status 
)

Requests a channel.

Parameters:
type type of channel to request
format requested channel format (codec)
requestor channel asking for data
data data to pass to the channel requester (Should be treated as const char *)
status status
Request a channel of a given type, with data as optional information used by the low level module

Return values:
NULL failure
non-NULL channel on success

Definition at line 5579 of file channel.c.

References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_NOSUCHDRIVER, AST_CAUSE_NOTDEFINED, ast_channel_release(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_translator_best_choice(), ast_channel_tech::capabilities, capabilities, chanlist::chan, chanlist::list, LOG_WARNING, ast_channel_tech::requester, set_security_requirements(), ast_channel::tech, and ast_channel_tech::type.

Referenced by __ast_request_and_dial(), ast_call_forward(), begin_dial_channel(), build_conf(), chanavail_exec(), conf_run(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), play_sound_file(), and ring_entry().

05580 {
05581    struct chanlist *chan;
05582    struct ast_channel *c;
05583    format_t capabilities;
05584    format_t fmt;
05585    int res;
05586    int foo;
05587    format_t videoformat = format & AST_FORMAT_VIDEO_MASK;
05588    format_t textformat = format & AST_FORMAT_TEXT_MASK;
05589 
05590    if (!cause)
05591       cause = &foo;
05592    *cause = AST_CAUSE_NOTDEFINED;
05593 
05594    if (AST_RWLIST_RDLOCK(&backends)) {
05595       ast_log(LOG_WARNING, "Unable to lock technology backend list\n");
05596       return NULL;
05597    }
05598 
05599    AST_RWLIST_TRAVERSE(&backends, chan, list) {
05600       if (strcasecmp(type, chan->tech->type))
05601          continue;
05602 
05603       capabilities = chan->tech->capabilities;
05604       fmt = format & AST_FORMAT_AUDIO_MASK;
05605       if (fmt) {
05606          /* We have audio - is it possible to connect the various calls to each other? 
05607             (Avoid this check for calls without audio, like text+video calls)
05608          */
05609          res = ast_translator_best_choice(&fmt, &capabilities);
05610          if (res < 0) {
05611             char tmp1[256], tmp2[256];
05612             ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %s) to %s\n", type,
05613                ast_getformatname_multiple(tmp1, sizeof(tmp1), chan->tech->capabilities),
05614                ast_getformatname_multiple(tmp2, sizeof(tmp2), format));
05615             *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05616             AST_RWLIST_UNLOCK(&backends);
05617             return NULL;
05618          }
05619       }
05620       AST_RWLIST_UNLOCK(&backends);
05621       if (!chan->tech->requester)
05622          return NULL;
05623 
05624       if (!(c = chan->tech->requester(type, capabilities | videoformat | textformat, requestor, data, cause)))
05625          return NULL;
05626 
05627       if (set_security_requirements(requestor, c)) {
05628          ast_log(LOG_WARNING, "Setting security requirements failed\n");
05629          c = ast_channel_release(c);
05630          *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05631          return NULL;
05632       }
05633 
05634       /* no need to generate a Newchannel event here; it is done in the channel_alloc call */
05635       return c;
05636    }
05637 
05638    ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
05639    *cause = AST_CAUSE_NOSUCHDRIVER;
05640    AST_RWLIST_UNLOCK(&backends);
05641 
05642    return NULL;
05643 }

struct ast_channel* ast_request_and_dial ( const char *  type,
format_t  format,
const struct ast_channel requestor,
void *  data,
int  timeout,
int *  reason,
const char *  cid_num,
const char *  cid_name 
)

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 requested channel format
requestor channel asking for data
data data to pass to the channel requester
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 5534 of file channel.c.

References __ast_request_and_dial().

Referenced by ast_pbx_outgoing_exten(), and generic_recall().

05535 {
05536    return __ast_request_and_dial(type, format, requestor, data, timeout, outstate, cidnum, cidname, NULL);
05537 }

int ast_safe_sleep ( struct ast_channel chan,
int  ms 
)

Wait for a specified amount of time, looking for hangups.

Parameters:
chan channel to wait for
ms length of time in milliseconds to sleep
Waits for a specified amount of time, servicing the channel as required.
Returns:
returns -1 on hangup, otherwise 0.

Definition at line 1884 of file channel.c.

References ast_safe_sleep_conditional(), and chanlist::chan.

Referenced by __analog_ss_thread(), adsi_transmit_message_full(), alarmreceiver_exec(), analog_ss_thread(), ast_dtmf_stream(), ast_senddigit(), builtin_atxfer(), builtin_parkcall(), conf_run(), dahdi_send_callrerouting_facility_exec(), dictate_exec(), flash_exec(), handle_callforward_button(), login_exec(), mgcp_ss(), milliwatt_exec(), misdn_check_l2l1(), old_milliwatt_exec(), park_call_exec(), pbx_builtin_wait(), play_moh_exec(), playtone(), privacy_exec(), receive_ademco_contact_id(), skinny_ss(), testclient_exec(), testserver_exec(), wait_for_hangup(), wait_moh_exec(), waituntil_exec(), and zapateller_exec().

01885 {
01886    return ast_safe_sleep_conditional(chan, ms, NULL, NULL);
01887 }

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

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

Parameters:
chan channel to wait for
ms length of time in milliseconds to sleep
cond a function pointer for testing continue condition
data argument to be passed to the condition test function
Returns:
returns -1 on hangup, otherwise 0.
Waits for a specified amount of time, servicing the channel as required. If cond returns 0, this function returns.

Definition at line 1817 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(), chanlist::chan, f, and ast_channel::generatordata.

Referenced by ast_safe_sleep(), and login_exec().

01818 {
01819    struct ast_frame *f;
01820    struct ast_silence_generator *silgen = NULL;
01821    int res = 0;
01822    AST_LIST_HEAD_NOLOCK(, ast_frame) deferred_frames;
01823 
01824    AST_LIST_HEAD_INIT_NOLOCK(&deferred_frames);
01825 
01826    /* If no other generator is present, start silencegen while waiting */
01827    if (ast_opt_transmit_silence && !chan->generatordata) {
01828       silgen = ast_channel_start_silence_generator(chan);
01829    }
01830 
01831    while (ms > 0) {
01832       struct ast_frame *dup_f = NULL;
01833       if (cond && ((*cond)(data) == 0)) {
01834          break;
01835       }
01836       ms = ast_waitfor(chan, ms);
01837       if (ms < 0) {
01838          res = -1;
01839          break;
01840       }
01841       if (ms > 0) {
01842          f = ast_read(chan);
01843          if (!f) {
01844             res = -1;
01845             break;
01846          }
01847 
01848          if (!ast_is_deferrable_frame(f)) {
01849             ast_frfree(f);
01850             continue;
01851          }
01852          
01853          if ((dup_f = ast_frisolate(f))) {
01854             if (dup_f != f) {
01855                ast_frfree(f);
01856             }
01857             AST_LIST_INSERT_HEAD(&deferred_frames, dup_f, frame_list);
01858          }
01859       }
01860    }
01861 
01862    /* stop silgen if present */
01863    if (silgen) {
01864       ast_channel_stop_silence_generator(chan, silgen);
01865    }
01866 
01867    /* We need to free all the deferred frames, but we only need to
01868     * queue the deferred frames if there was no error and no
01869     * hangup was received
01870     */
01871    ast_channel_lock(chan);
01872    while ((f = AST_LIST_REMOVE_HEAD(&deferred_frames, frame_list))) {
01873       if (!res) {
01874          ast_queue_frame_head(chan, f);
01875       }
01876       ast_frfree(f);
01877    }
01878    ast_channel_unlock(chan);
01879 
01880    return res;
01881 }

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

Definition at line 8199 of file channel.c.

References ast_say_character_str_full.

Referenced by common_exec(), pbx_builtin_saycharacters(), play_mailbox_owner(), and vmsayname_exec().

08201 {
08202    return ast_say_character_str_full(chan, str, ints, lang, -1, -1);
08203 }

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

08195 {
08196    return ast_say_digit_str_full(chan, str, ints, lang, -1, -1);
08197 }

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

References ast_say_digits_full().

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

08189 {
08190    return ast_say_digits_full(chan, num, ints, lang, -1, -1);
08191 }

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

Definition at line 8211 of file channel.c.

References ast_say_digit_str_full.

Referenced by ast_say_digits(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_he(), ast_say_number_full_hu(), ast_say_number_full_it(), ast_say_number_full_ka(), ast_say_number_full_nl(), ast_say_number_full_no(), ast_say_number_full_pt(), ast_say_number_full_ru(), ast_say_number_full_se(), ast_say_number_full_th(), ast_say_number_full_ur(), ast_say_number_full_vi(), ast_say_number_full_zh(), and say_init_mode().

08213 {
08214    char buf[256];
08215 
08216    snprintf(buf, sizeof(buf), "%d", num);
08217 
08218    return ast_say_digit_str_full(chan, buf, ints, lang, audiofd, ctrlfd);
08219 }

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

08183 {
08184    return ast_say_enumeration_full(chan, num, ints, language, options, -1, -1);
08185 }

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 8175 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(), say_and_wait(), say_position(), vm_intro_gr(), vm_intro_he(), vm_intro_multilang(), vm_intro_pt(), and vm_intro_pt_BR().

08177 {
08178    return ast_say_number_full(chan, num, ints, language, options, -1, -1);
08179 }

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

Definition at line 8205 of file channel.c.

References ast_say_phonetic_str_full.

Referenced by pbx_builtin_sayphonetic().

08207 {
08208    return ast_say_phonetic_str_full(chan, str, ints, lang, -1, -1);
08209 }

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

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

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

04660 {
04661    if (chan->tech->send_digit_begin) {
04662       ast_senddigit_begin(chan, digit);
04663       ast_safe_sleep(chan, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION));
04664    }
04665    
04666    return ast_senddigit_end(chan, digit, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION));
04667 }

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

References ast_debug, ast_playtones_start(), chanlist::chan, ast_channel::name, ast_channel_tech::send_digit_begin, and ast_channel::tech.

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

04602 {
04603    /* Device does not support DTMF tones, lets fake
04604     * it by doing our own generation. */
04605    static const char * const dtmf_tones[] = {
04606       "941+1336", /* 0 */
04607       "697+1209", /* 1 */
04608       "697+1336", /* 2 */
04609       "697+1477", /* 3 */
04610       "770+1209", /* 4 */
04611       "770+1336", /* 5 */
04612       "770+1477", /* 6 */
04613       "852+1209", /* 7 */
04614       "852+1336", /* 8 */
04615       "852+1477", /* 9 */
04616       "697+1633", /* A */
04617       "770+1633", /* B */
04618       "852+1633", /* C */
04619       "941+1633", /* D */
04620       "941+1209", /* * */
04621       "941+1477"  /* # */
04622    };
04623 
04624    if (!chan->tech->send_digit_begin)
04625       return 0;
04626 
04627    if (!chan->tech->send_digit_begin(chan, digit))
04628       return 0;
04629 
04630    if (digit >= '0' && digit <='9')
04631       ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0);
04632    else if (digit >= 'A' && digit <= 'D')
04633       ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0);
04634    else if (digit == '*')
04635       ast_playtones_start(chan, 0, dtmf_tones[14], 0);
04636    else if (digit == '#')
04637       ast_playtones_start(chan, 0, dtmf_tones[15], 0);
04638    else {
04639       /* not handled */
04640       ast_debug(1, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name);
04641    }
04642 
04643    return 0;
04644 }

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

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

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

04647 {
04648    int res = -1;
04649 
04650    if (chan->tech->send_digit_end)
04651       res = chan->tech->send_digit_end(chan, digit, duration);
04652 
04653    if (res && chan->generator)
04654       ast_playtones_stop(chan);
04655    
04656    return 0;
04657 }

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

References ast_channel_lock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_test_flag, chanlist::chan, CHECK_BLOCKING, ast_channel_tech::send_text, and ast_channel::tech.

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

04584 {
04585    int res = 0;
04586 
04587    ast_channel_lock(chan);
04588    /* Stop if we're a zombie or need a soft hangup */
04589    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
04590       ast_channel_unlock(chan);
04591       return -1;
04592    }
04593    CHECK_BLOCKING(chan);
04594    if (chan->tech->send_text)
04595       res = chan->tech->send_text(chan, text);
04596    ast_clear_flag(chan, AST_FLAG_BLOCKING);
04597    ast_channel_unlock(chan);
04598    return res;
04599 }

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 6885 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, chanlist::chan, 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(), __ast_request_and_dial(), analog_ss_thread(), cb_events(), get_pai(), get_rpid(), handle_setcallerid(), mgcp_ss(), ring_entry(), skinny_newcall(), and socket_process().

06886 {
06887    ast_channel_lock(chan);
06888 
06889    if (cid_num) {
06890       chan->caller.id.number.valid = 1;
06891       ast_free(chan->caller.id.number.str);
06892       chan->caller.id.number.str = ast_strdup(cid_num);
06893    }
06894    if (cid_name) {
06895       chan->caller.id.name.valid = 1;
06896       ast_free(chan->caller.id.name.str);
06897       chan->caller.id.name.str = ast_strdup(cid_name);
06898    }
06899    if (cid_ani) {
06900       chan->caller.ani.number.valid = 1;
06901       ast_free(chan->caller.ani.number.str);
06902       chan->caller.ani.number.str = ast_strdup(cid_ani);
06903    }
06904    if (chan->cdr) {
06905       ast_cdr_setcid(chan->cdr, chan);
06906    }
06907 
06908    report_new_callerid(chan);
06909 
06910    ast_channel_unlock(chan);
06911 }

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 
Note:
Absolutely _NO_ channel locks should be held before calling this function.
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 2736 of file channel.c.

References ast_bridged_channel(), ast_channel_lock, ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_string_field_set, ast_strlen_zero(), ast_channel::bridge, chanlist::chan, and ast_channel::hangupsource.

Referenced by __dahdi_exception(), analog_exception(), func_channel_write_real(), handle_hangup(), pbx_builtin_hangup(), set_hangup_source_and_cause(), and sip_queue_hangup_cause().

02737 {
02738    struct ast_channel *bridge;
02739 
02740    ast_channel_lock(chan);
02741    if (force || ast_strlen_zero(chan->hangupsource)) {
02742       ast_string_field_set(chan, hangupsource, source);
02743    }
02744    bridge = ast_bridged_channel(chan);
02745    if (bridge) {
02746       ast_channel_ref(bridge);
02747    }
02748    ast_channel_unlock(chan);
02749 
02750    if (bridge) {
02751       ast_channel_lock(bridge);
02752       if (force || ast_strlen_zero(bridge->hangupsource)) {
02753          ast_string_field_set(bridge, hangupsource, source);
02754       }
02755       ast_channel_unlock(bridge);
02756       ast_channel_unref(bridge);
02757    }
02758 }

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

Definition at line 6313 of file channel.c.

References accountcode, ast_channel::accountcode, ast_log(), ast_string_field_set, ast_strlen_zero(), LOG_DEBUG, ast_channel::name, and ast_channel::peeraccount.

Referenced by ast_channel_bridge().

06315 {
06316    if (!ast_strlen_zero(chan1->accountcode) && ast_strlen_zero(chan2->peeraccount)) {
06317       ast_log(LOG_DEBUG, "setting peeraccount to %s for %s from data on channel %s\n",
06318             chan1->accountcode, chan2->name, chan1->name);
06319       ast_string_field_set(chan2, peeraccount, chan1->accountcode);
06320    }
06321    if (!ast_strlen_zero(chan2->accountcode) && ast_strlen_zero(chan1->peeraccount)) {
06322       ast_log(LOG_DEBUG, "setting peeraccount to %s for %s from data on channel %s\n",
06323             chan2->accountcode, chan1->name, chan2->name);
06324       ast_string_field_set(chan1, peeraccount, chan2->accountcode);
06325    }
06326    if (!ast_strlen_zero(chan1->peeraccount) && ast_strlen_zero(chan2->accountcode)) {
06327       ast_log(LOG_DEBUG, "setting accountcode to %s for %s from data on channel %s\n",
06328             chan1->peeraccount, chan2->name, chan1->name);
06329       ast_string_field_set(chan2, accountcode, chan1->peeraccount);
06330    }
06331    if (!ast_strlen_zero(chan2->peeraccount) && ast_strlen_zero(chan1->accountcode)) {
06332       ast_log(LOG_DEBUG, "setting accountcode to %s for %s from data on channel %s\n",
06333             chan2->peeraccount, chan1->name, chan2->name);
06334       ast_string_field_set(chan1, accountcode, chan2->peeraccount);
06335    }
06336    if (0 != strcmp(chan1->accountcode, chan2->peeraccount)) {
06337       ast_log(LOG_DEBUG, "changing peeraccount from %s to %s on %s to match channel %s\n",
06338             chan2->peeraccount, chan1->peeraccount, chan2->name, chan1->name);
06339       ast_string_field_set(chan2, peeraccount, chan1->accountcode);
06340    }
06341    if (0 != strcmp(chan2->accountcode, chan1->peeraccount)) {
06342       ast_log(LOG_DEBUG, "changing peeraccount from %s to %s on %s to match channel %s\n",
06343             chan1->peeraccount, chan2->peeraccount, chan1->name, chan2->name);
06344       ast_string_field_set(chan1, peeraccount, chan2->accountcode);
06345    }
06346 }

int ast_set_read_format ( struct ast_channel chan,
format_t  format 
)

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

Parameters:
chan channel to change
format format to change to
Returns:
Returns 0 on success, -1 on failure

Definition at line 5186 of file channel.c.

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

Referenced by __ast_play_and_record(), __oh323_update_info(), adsi_transmit_message_full(), agent_call(), alarmreceiver_exec(), ast_channel_make_compatible_helper(), ast_do_masquerade(), background_detect_exec(), bridge_channel_join(), bridge_make_compatible(), build_conf(), conf_run(), dictate_exec(), do_waiting(), eagi_exec(), echo_exec(), generic_fax_exec(), gtalk_rtp_read(), handle_recordfile(), handle_speechrecognize(), ices_exec(), isAnsweringMachine(), jack_exec(), jingle_rtp_read(), login_exec(), measurenoise(), mgcp_rtp_read(), oh323_rtp_read(), old_milliwatt_exec(), process_sdp(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_process(), speech_background(), transmit_audio(), and unistim_rtp_read().

05187 {
05188    return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat,
05189            &chan->readtrans, 0);
05190 }

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

08063 {
08064    struct ast_variable *cur;
08065 
08066    for (cur = vars; cur; cur = cur->next)
08067       pbx_builtin_setvar_helper(chan, cur->name, cur->value);  
08068 }

int ast_set_write_format ( struct ast_channel chan,
format_t  format 
)

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

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

Definition at line 5192 of file channel.c.

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

Referenced by __oh323_update_info(), adsi_transmit_message_full(), agent_call(), alarmreceiver_exec(), ast_channel_make_compatible_helper(), ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_do_masquerade(), ast_openstream_full(), ast_stopstream(), ast_write(), bridge_channel_join(), bridge_make_compatible(), build_conf(), chanspy_exec(), conf_run(), dahdiscan_exec(), echo_exec(), extenspy_exec(), generic_fax_exec(), gtalk_rtp_read(), jack_exec(), jingle_rtp_read(), linear_alloc(), linear_release(), login_exec(), mgcp_rtp_read(), moh_alloc(), moh_files_release(), moh_release(), mp3_exec(), NBScat_exec(), oh323_rtp_read(), old_milliwatt_exec(), playtones_alloc(), playtones_release(), process_sdp(), send_waveform_to_channel(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_process(), tonepair_alloc(), tonepair_release(), transmit_audio(), and unistim_rtp_read().

05193 {
05194    return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat,
05195            &chan->writetrans, 1);
05196 }

int ast_setstate ( struct ast_channel chan,
enum ast_channel_state  state 
)

Change the state of a channel.

Definition at line 6953 of file channel.c.

References ast_channel::_state, AST_CHANNEL_NAME, ast_copy_string(), AST_DEVICE_UNKNOWN, ast_devstate_changed_literal(), ast_manager_event, ast_state2str(), ast_channel::caller, chanlist::chan, ast_channel::connected, EVENT_FLAG_CALL, ast_party_connected_line::id, ast_party_caller::id, ast_party_id::name, ast_channel::name, name, ast_party_id::number, S_COR, ast_party_name::str, ast_party_number::str, ast_channel::uniqueid, 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_offhook_message(), handle_request_invite(), handle_response_invite(), handle_soft_key_event_message(), handle_stimulus_message(), 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(), pri_ss_thread(), release_chan(), release_chan_early(), sig_pri_answer(), sig_pri_call(), sig_pri_indicate(), sip_answer(), skinny_answer(), skinny_call(), skinny_newcall(), unistim_answer(), unistim_call(), unistim_new(), unistim_ss(), and update_state().

06954 {
06955    int oldstate = chan->_state;
06956    char name[AST_CHANNEL_NAME], *dashptr;
06957 
06958    if (oldstate == state)
06959       return 0;
06960 
06961    ast_copy_string(name, chan->name, sizeof(name));
06962    if ((dashptr = strrchr(name, '-'))) {
06963       *dashptr = '\0';
06964    }
06965 
06966    chan->_state = state;
06967 
06968    /* We have to pass AST_DEVICE_UNKNOWN here because it is entirely possible that the channel driver
06969     * for this channel is using the callback method for device state. If we pass in an actual state here
06970     * we override what they are saying the state is and things go amuck. */
06971    ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, name);
06972 
06973    /* setstate used to conditionally report Newchannel; this is no more */
06974    ast_manager_event(chan, EVENT_FLAG_CALL, "Newstate",
06975       "Channel: %s\r\n"
06976       "ChannelState: %d\r\n"
06977       "ChannelStateDesc: %s\r\n"
06978       "CallerIDNum: %s\r\n"
06979       "CallerIDName: %s\r\n"
06980       "ConnectedLineNum: %s\r\n"
06981       "ConnectedLineName: %s\r\n"
06982       "Uniqueid: %s\r\n",
06983       chan->name, chan->_state, ast_state2str(chan->_state),
06984       S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
06985       S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""),
06986       S_COR(chan->connected.id.number.valid, chan->connected.id.number.str, ""),
06987       S_COR(chan->connected.id.name.valid, chan->connected.id.name.str, ""),
06988       chan->uniqueid);
06989 
06990    return 0;
06991 }

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

References ast_channel_lock, ast_channel_unlock, ast_debug, ast_timer_get_max_rate(), ast_timer_set_rate(), AST_TIMING_FD, ast_channel::fdno, 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().

03503 {
03504    int res;
03505    unsigned int real_rate = rate, max_rate;
03506 
03507    ast_channel_lock(c);
03508 
03509    if (c->timingfd == -1) {
03510       ast_channel_unlock(c);
03511       return -1;
03512    }
03513 
03514    if (!func) {
03515       rate = 0;
03516       data = NULL;
03517    }
03518 
03519    if (rate && rate > (max_rate = ast_timer_get_max_rate(c->timer))) {
03520       real_rate = max_rate;
03521    }
03522 
03523    ast_debug(1, "Scheduling timer at (%u requested / %u actual) timer ticks per second\n", rate, real_rate);
03524 
03525    res = ast_timer_set_rate(c->timer, real_rate);
03526 
03527    c->timingfunc = func;
03528    c->timingdata = data;
03529 
03530    if (func == NULL && rate == 0 && c->fdno == AST_TIMING_FD) {
03531       /* Clearing the timing func and setting the rate to 0
03532        * means that we don't want to be reading from the timingfd
03533        * any more. Setting c->fdno to -1 means we won't have any
03534        * errant reads from the timingfd, meaning we won't potentially
03535        * miss any important frames.
03536        */
03537       c->fdno = -1;
03538    }
03539 
03540    ast_channel_unlock(c);
03541 
03542    return res;
03543 }

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

Referenced by handle_request_options().

00855 {
00856    return shutting_down;
00857 }

int ast_softhangup ( struct ast_channel chan,
int  reason 
)

Softly hangup up a channel.

Parameters:
chan channel to be soft-hung-up
reason an AST_SOFTHANGUP_* reason code
Call the protocol layer, but don't destroy the channel structure (use this if you are trying to safely hangup a channel managed by another thread.

Note:
The channel passed to this function does not need to be locked.
Returns:
Returns 0 regardless

Definition at line 2713 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_softhangup_nolock(), and chanlist::chan.

Referenced by __analog_handle_event(), __ast_module_user_hangup_all(), __unload_module(), agent_hangup(), agent_logoff(), agent_read(), ast_bridge_call(), ast_channel_softhangup_cb(), ast_dial_join(), cc_generic_agent_stop_ringing(), conf_free(), dahdi_handle_event(), handle_hangup(), handle_softhangup(), login_exec(), manager_park(), mgcp_pktcgate_remove(), read_agent_config(), sla_handle_hold_event(), softhangup_exec(), start_spying(), startmon(), and unload_module().

02714 {
02715    int res;
02716 
02717    ast_channel_lock(chan);
02718    res = ast_softhangup_nolock(chan, cause);
02719    ast_channel_unlock(chan);
02720 
02721    return res;
02722 }

int ast_softhangup_nolock ( struct ast_channel chan,
int  reason 
)

Softly hangup up a channel (no channel lock).

Parameters:
chan channel to be soft-hung-up
reason an AST_SOFTHANGUP_* reason code

Definition at line 2700 of file channel.c.

References ast_channel::_softhangup, ast_debug, AST_FLAG_BLOCKING, ast_null_frame, ast_queue_frame(), ast_test_flag, ast_channel::blocker, chanlist::chan, and ast_channel::name.

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(), sig_pri_indicate(), sig_pri_send_aoce_termination_request(), sip_indicate(), and skinny_indicate().

02701 {
02702    ast_debug(1, "Soft-Hanging up channel '%s'\n", chan->name);
02703    /* Inform channel driver that we need to be hung up, if it cares */
02704    chan->_softhangup |= cause;
02705    ast_queue_frame(chan, &ast_null_frame);
02706    /* Interrupt any poll call or such */
02707    if (ast_test_flag(chan, AST_FLAG_BLOCKING))
02708       pthread_kill(chan->blocker, SIGURG);
02709    return 0;
02710 }

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 996 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(), 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().

00997 {
00998    char *buf;
00999 
01000    switch (state) {
01001    case AST_STATE_DOWN:
01002       return "Down";
01003    case AST_STATE_RESERVED:
01004       return "Rsrvd";
01005    case AST_STATE_OFFHOOK:
01006       return "OffHook";
01007    case AST_STATE_DIALING:
01008       return "Dialing";
01009    case AST_STATE_RING:
01010       return "Ring";
01011    case AST_STATE_RINGING:
01012       return "Ringing";
01013    case AST_STATE_UP:
01014       return "Up";
01015    case AST_STATE_BUSY:
01016       return "Busy";
01017    case AST_STATE_DIALING_OFFHOOK:
01018       return "Dialing Offhook";
01019    case AST_STATE_PRERING:
01020       return "Pre-ring";
01021    default:
01022       if (!(buf = ast_threadstorage_get(&state2str_threadbuf, STATE2STR_BUFSIZE)))
01023          return "Unknown";
01024       snprintf(buf, STATE2STR_BUFSIZE, "Unknown (%d)", state);
01025       return buf;
01026    }
01027 }

int ast_str2cause ( const char *  name  ) 

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

Parameters:
name string form of the cause
Returns:
the cause code

Definition at line 982 of file channel.c.

References ARRAY_LEN, and causes.

Referenced by pbx_builtin_hangup().

00983 {
00984    int x;
00985 
00986    for (x = 0; x < ARRAY_LEN(causes); x++)
00987       if (!strncasecmp(causes[x].name, name, strlen(causes[x].name)))
00988          return causes[x].cause;
00989 
00990    return -1;
00991 }

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

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

Referenced by zapateller_exec().

07783 {
07784    int res;
07785 
07786    if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
07787       return res;
07788 
07789    /* Give us some wiggle room */
07790    while (chan->generatordata && ast_waitfor(chan, 100) >= 0) {
07791       struct ast_frame *f = ast_read(chan);
07792       if (f)
07793          ast_frfree(f);
07794       else
07795          return -1;
07796    }
07797    return 0;
07798 }

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

Start a tone going

Definition at line 7764 of file channel.c.

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

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

07765 {
07766    struct tonepair_def d = { 0, };
07767 
07768    d.freq1 = freq1;
07769    d.freq2 = freq2;
07770    d.duration = duration;
07771    d.vol = (vol < 1) ? 8192 : vol; /* force invalid to 8192 */
07772    if (ast_activate_generator(chan, &tonepair, &d))
07773       return -1;
07774    return 0;
07775 }

void ast_tonepair_stop ( struct ast_channel chan  ) 

Stop a tone from playing

Definition at line 7777 of file channel.c.

References ast_deactivate_generator().

Referenced by sendnoise().

07778 {
07779    ast_deactivate_generator(chan);
07780 }

int ast_transfer ( struct ast_channel chan,
char *  dest 
)

Transfer a channel (if supported).

Called by:

Definition at line 5672 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(), chanlist::chan, ast_channel::tech, and ast_channel_tech::transfer.

Referenced by transfer_exec().

05673 {
05674    int res = -1;
05675 
05676    /* Stop if we're a zombie or need a soft hangup */
05677    ast_channel_lock(chan);
05678    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
05679       if (chan->tech->transfer) {
05680          res = chan->tech->transfer(chan, dest);
05681          if (!res)
05682             res = 1;
05683       } else
05684          res = 0;
05685    }
05686    ast_channel_unlock(chan);
05687 
05688    if (res <= 0) {
05689       return res;
05690    }
05691 
05692    for (;;) {
05693       struct ast_frame *fr;
05694 
05695       res = ast_waitfor(chan, -1);
05696 
05697       if (res < 0 || !(fr = ast_read(chan))) {
05698          res = -1;
05699          break;
05700       }
05701 
05702       if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_TRANSFER) {
05703          enum ast_control_transfer *message = fr->data.ptr;
05704 
05705          if (*message == AST_TRANSFER_SUCCESS) {
05706             res = 1;
05707          } else {
05708             res = -1;
05709          }
05710 
05711          ast_frfree(fr);
05712          break;
05713       }
05714 
05715       ast_frfree(fr);
05716    }
05717 
05718    return res;
05719 }

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 1030 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(), oh323_call(), sig_pri_call(), and sig_pri_new_ast_channel().

01031 {
01032    switch (transfercapability) {
01033    case AST_TRANS_CAP_SPEECH:
01034       return "SPEECH";
01035    case AST_TRANS_CAP_DIGITAL:
01036       return "DIGITAL";
01037    case AST_TRANS_CAP_RESTRICTED_DIGITAL:
01038       return "RESTRICTED_DIGITAL";
01039    case AST_TRANS_CAP_3_1K_AUDIO:
01040       return "3K1AUDIO";
01041    case AST_TRANS_CAP_DIGITAL_W_TONES:
01042       return "DIGITAL_W_TONES";
01043    case AST_TRANS_CAP_VIDEO:
01044       return "VIDEO";
01045    default:
01046       return "UNKNOWN";
01047    }
01048 }

int ast_undestroyed_channels ( void   ) 

Returns:
the number of channels not yet destroyed

Definition at line 842 of file channel.c.

References ast_atomic_fetchadd_int().

Referenced by can_safely_quit().

00843 {
00844    return ast_atomic_fetchadd_int(&chancount, 0);
00845 }

void ast_uninstall_music_functions ( void   ) 

Definition at line 7845 of file channel.c.

References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.

Referenced by unload_module().

07846 {
07847    ast_moh_start_ptr = NULL;
07848    ast_moh_stop_ptr = NULL;
07849    ast_moh_cleanup_ptr = NULL;
07850 }

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 3486 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_idle_thread(), 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(), 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().

03487 {
03488    int oldms = ms;   /* -1 if no timeout */
03489 
03490    ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms);
03491    if ((ms < 0) && (oldms < 0))
03492       ms = 0;
03493    return ms;
03494 }

struct ast_channel* ast_waitfor_n ( struct ast_channel **  chan,
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.

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

References ast_waitfor_nandfds().

Referenced by ast_udptl_bridge(), autoservice_run(), dahdi_bridge(), dial_exec_full(), feature_request_and_dial(), generic_thread_loop(), misdn_bridge(), monitor_dial(), remote_bridge_loop(), wait_for_answer(), and wait_for_winner().

03482 {
03483    return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
03484 }

int ast_waitfor_n_fd ( int *  fds,
int  n,
int *  ms,
int *  exception 
)

Waits for input on an fd.

Note:
This version works on fd's only. Be careful with it.

Definition at line 3125 of file channel.c.

References ast_waitfor_nandfds().

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

03126 {
03127    int winner = -1;
03128    ast_waitfor_nandfds(NULL, 0, fds, n, exception, &winner, ms);
03129    return winner;
03130 }

struct ast_channel* ast_waitfor_nandfds ( struct ast_channel **  chan,
int  n,
int *  fds,
int  nfds,
int *  exception,
int *  outfd,
int *  ms 
)

Waits for activity on a group of channels.

Parameters:
chan an array of pointers to channels
n number of channels that are to be waited upon
fds an array of fds to wait upon
nfds the number of fds to wait upon
exception exception flag
outfd fd that had activity on it
ms how long the wait was
Big momma function here. Wait for activity on any of the n channels, or any of the nfds file descriptors.
Returns:
Returns the channel with activity, or NULL on error or if an FD came first. If the FD came first, it will be returned in outfd, otherwise, outfd will be -1

Definition at line 3137 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_MAX_FDS, ast_poll, ast_set_flag, AST_SOFTHANGUP_TIMEOUT, ast_tvcmp(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), chanlist::chan, CHECK_BLOCKING, and errno.

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

03140 {
03141    struct timeval start = { 0 , 0 };
03142    struct pollfd *pfds = NULL;
03143    int res;
03144    long rms;
03145    int x, y, max;
03146    int sz;
03147    struct timeval now = { 0, 0 };
03148    struct timeval whentohangup = { 0, 0 }, diff;
03149    struct ast_channel *winner = NULL;
03150    struct fdmap {
03151       int chan;
03152       int fdno;
03153    } *fdmap = NULL;
03154 
03155    if (outfd)
03156       *outfd = -99999;
03157    if (exception)
03158       *exception = 0;
03159    
03160    if ((sz = n * AST_MAX_FDS + nfds)) {
03161       pfds = alloca(sizeof(*pfds) * sz);
03162       fdmap = alloca(sizeof(*fdmap) * sz);
03163    } else {
03164       /* nothing to allocate and no FDs to check */
03165       return NULL;
03166    }
03167 
03168    /* Perform any pending masquerades */
03169    for (x = 0; x < n; x++) {
03170       while (c[x]->masq) {
03171          ast_do_masquerade(c[x]);
03172       }
03173 
03174       ast_channel_lock(c[x]);
03175       if (!ast_tvzero(c[x]->whentohangup)) {
03176          if (ast_tvzero(whentohangup))
03177             now = ast_tvnow();
03178          diff = ast_tvsub(c[x]->whentohangup, now);
03179          if (diff.tv_sec < 0 || ast_tvzero(diff)) {
03180             /* Should already be hungup */
03181             c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03182             ast_channel_unlock(c[x]);
03183             return c[x];
03184          }
03185          if (ast_tvzero(whentohangup) || ast_tvcmp(diff, whentohangup) < 0)
03186             whentohangup = diff;
03187       }
03188       ast_channel_unlock(c[x]);
03189    }
03190    /* Wait full interval */
03191    rms = *ms;
03192    /* INT_MAX, not LONG_MAX, because it matters on 64-bit */
03193    if (!ast_tvzero(whentohangup) && whentohangup.tv_sec < INT_MAX / 1000) {
03194       rms = whentohangup.tv_sec * 1000 + whentohangup.tv_usec / 1000;              /* timeout in milliseconds */
03195       if (*ms >= 0 && *ms < rms) {                                                 /* original *ms still smaller */
03196          rms =  *ms;
03197       }
03198    } else if (!ast_tvzero(whentohangup) && rms < 0) {
03199       /* Tiny corner case... call would need to last >24 days */
03200       rms = INT_MAX;
03201    }
03202    /*
03203     * Build the pollfd array, putting the channels' fds first,
03204     * followed by individual fds. Order is important because
03205     * individual fd's must have priority over channel fds.
03206     */
03207    max = 0;
03208    for (x = 0; x < n; x++) {
03209       for (y = 0; y < AST_MAX_FDS; y++) {
03210          fdmap[max].fdno = y;  /* fd y is linked to this pfds */
03211          fdmap[max].chan = x;  /* channel x is linked to this pfds */
03212          max += ast_add_fd(&pfds[max], c[x]->fds[y]);
03213       }
03214       CHECK_BLOCKING(c[x]);
03215    }
03216    /* Add the individual fds */
03217    for (x = 0; x < nfds; x++) {
03218       fdmap[max].chan = -1;
03219       max += ast_add_fd(&pfds[max], fds[x]);
03220    }
03221 
03222    if (*ms > 0)
03223       start = ast_tvnow();
03224    
03225    if (sizeof(int) == 4) { /* XXX fix timeout > 600000 on linux x86-32 */
03226       do {
03227          int kbrms = rms;
03228          if (kbrms > 600000)
03229             kbrms = 600000;
03230          res = ast_poll(pfds, max, kbrms);
03231          if (!res)
03232             rms -= kbrms;
03233       } while (!res && (rms > 0));
03234    } else {
03235       res = ast_poll(pfds, max, rms);
03236    }
03237    for (x = 0; x < n; x++)
03238       ast_clear_flag(c[x], AST_FLAG_BLOCKING);
03239    if (res < 0) { /* Simulate a timeout if we were interrupted */
03240       if (errno != EINTR)
03241          *ms = -1;
03242       return NULL;
03243    }
03244    if (!ast_tvzero(whentohangup)) {   /* if we have a timeout, check who expired */
03245       now = ast_tvnow();
03246       for (x = 0; x < n; x++) {
03247          if (!ast_tvzero(c[x]->whentohangup) && ast_tvcmp(c[x]->whentohangup, now) <= 0) {
03248             c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03249             if (winner == NULL)
03250                winner = c[x];
03251          }
03252       }
03253    }
03254    if (res == 0) { /* no fd ready, reset timeout and done */
03255       *ms = 0; /* XXX use 0 since we may not have an exact timeout. */
03256       return winner;
03257    }
03258    /*
03259     * Then check if any channel or fd has a pending event.
03260     * Remember to check channels first and fds last, as they
03261     * must have priority on setting 'winner'
03262     */
03263    for (x = 0; x < max; x++) {
03264       res = pfds[x].revents;
03265       if (res == 0)
03266          continue;
03267       if (fdmap[x].chan >= 0) {  /* this is a channel */
03268          winner = c[fdmap[x].chan]; /* override previous winners */
03269          if (res & POLLPRI)
03270             ast_set_flag(winner, AST_FLAG_EXCEPTION);
03271          else
03272             ast_clear_flag(winner, AST_FLAG_EXCEPTION);
03273          winner->fdno = fdmap[x].fdno;
03274       } else {       /* this is an fd */
03275          if (outfd)
03276             *outfd = pfds[x].fd;
03277          if (exception)
03278             *exception = (res & POLLPRI) ? -1 : 0;
03279          winner = NULL;
03280       }
03281    }
03282    if (*ms > 0) {
03283       *ms -= ast_tvdiff_ms(ast_tvnow(), start);
03284       if (*ms < 0)
03285          *ms = 0;
03286    }
03287    return winner;
03288 }

int ast_waitfordigit ( struct ast_channel c,
int  ms 
)

Waits for a digit.

Parameters:
c channel to wait for a digit on
ms how many milliseconds to wait
Returns:
Returns <0 on error, 0 on no entry, and the digit on success.

Definition at line 3497 of file channel.c.

References ast_waitfordigit_full().

Referenced by __analog_ss_thread(), _while_exec(), adsi_get_cpeid(), adsi_get_cpeinfo(), adsi_print(), adsi_read_encoded_dtmf(), adsi_transmit_message_full(), advanced_options(), analog_my_getsigstr(), analog_ss_thread(), ast_app_dtget(), ast_control_streamfile(), ast_record_review(), bridge_channel_feature(), builtin_atxfer(), collect_digits(), common_exec(), cpeid_exec(), dialout(), directory_exec(), forward_message(), get_folder(), ivr_dispatch(), mgcp_ss(), my_getsigstr(), pbx_builtin_waitexten(), play_record_review(), pri_ss_thread(), read_exec(), read_newoption(), readexten_exec(), retrydial_exec(), select_item_menu(), select_item_pause(), select_item_seq(), sendnoise(), testclient_exec(), testserver_exec(), vm_execmain(), vm_forwardoptions(), vm_instructions_en(), vm_options(), vm_tempgreeting(), and wait_a_bit().

03498 {
03499    return ast_waitfordigit_full(c, ms, -1, -1);
03500 }

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

References ast_check_hangup(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, 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(), errno, f, and LOG_WARNING.

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

03546 {
03547    /* Stop if we're a zombie or need a soft hangup */
03548    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
03549       return -1;
03550 
03551    /* Only look for the end of DTMF, don't bother with the beginning and don't emulate things */
03552    ast_set_flag(c, AST_FLAG_END_DTMF_ONLY);
03553 
03554    /* Wait for a digit, no more than ms milliseconds total. */
03555    
03556    while (ms) {
03557       struct ast_channel *rchan;
03558       int outfd=-1;
03559 
03560       errno = 0;
03561       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
03562       
03563       if (!rchan && outfd < 0 && ms) {
03564          if (errno == 0 || errno == EINTR)
03565             continue;
03566          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
03567          ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03568          return -1;
03569       } else if (outfd > -1) {
03570          /* The FD we were watching has something waiting */
03571          ast_log(LOG_WARNING, "The FD we were waiting for has something waiting. Waitfordigit returning numeric 1\n");
03572          ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03573          return 1;
03574       } else if (rchan) {
03575          int res;
03576          struct ast_frame *f = ast_read(c);
03577          if (!f)
03578             return -1;
03579 
03580          switch (f->frametype) {
03581          case AST_FRAME_DTMF_BEGIN:
03582             break;
03583          case AST_FRAME_DTMF_END:
03584             res = f->subclass.integer;
03585             ast_frfree(f);
03586             ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03587             return res;
03588          case AST_FRAME_CONTROL:
03589             switch (f->subclass.integer) {
03590             case AST_CONTROL_HANGUP:
03591                ast_frfree(f);
03592                ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03593                return -1;
03594             case AST_CONTROL_RINGING:
03595             case AST_CONTROL_ANSWER:
03596             case AST_CONTROL_SRCUPDATE:
03597             case AST_CONTROL_SRCCHANGE:
03598             case AST_CONTROL_CONNECTED_LINE:
03599             case AST_CONTROL_REDIRECTING:
03600             case AST_CONTROL_UPDATE_RTP_PEER:
03601             case AST_CONTROL_HOLD:
03602             case AST_CONTROL_UNHOLD:
03603             case -1:
03604                /* Unimportant */
03605                break;
03606             default:
03607                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass.integer);
03608                break;
03609             }
03610             break;
03611          case AST_FRAME_VOICE:
03612             /* Write audio if appropriate */
03613             if (audiofd > -1) {
03614                if (write(audiofd, f->data.ptr, f->datalen) < 0) {
03615                   ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
03616                }
03617             }
03618          default:
03619             /* Ignore */
03620             break;
03621          }
03622          ast_frfree(f);
03623       }
03624    }
03625 
03626    ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03627 
03628    return 0; /* Time is up */
03629 }

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 4801 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_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_AUDIO_MASK, 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(), AST_SOFTHANGUP_DEV, ast_test_flag, ast_translate(), ast_writestream(), ast_channel::audiohooks, calc_monitor_jump(), chanlist::chan, CHECK_BLOCKING, ast_frame_subclass::codec, ast_frame::data, ast_frame::datalen, DEBUGCHAN_FLAG, f, ast_filestream::fmt, ast_format::format, ast_channel::fout, FRAMECOUNT_INC, ast_channel::framehooks, ast_frame::frametype, ast_channel::generatordata, 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::name, 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_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(), gen_generate(), generic_fax_exec(), handle_jack_audio(), jb_get_and_deliver(), linear_generator(), milliwatt_generate(), misdn_bridge(), moh_files_generator(), moh_generate(), mp3_exec(), multiplexed_bridge_write(), NBScat_exec(), remote_bridge_loop(), send_tone_burst(), send_waveform_to_channel(), silence_generator_generate(), simple_bridge_write(), softmix_bridge_poke(), softmix_bridge_write(), spy_generate(), and t38_tx_packet_handler().

04802 {
04803    int res = -1;
04804    struct ast_frame *f = NULL;
04805    int count = 0;
04806 
04807    /*Deadlock avoidance*/
04808    while(ast_channel_trylock(chan)) {
04809       /*cannot goto done since the channel is not locked*/
04810       if(count++ > 10) {
04811          ast_debug(1, "Deadlock avoided for write to channel '%s'\n", chan->name);
04812          return 0;
04813       }
04814       usleep(1);
04815    }
04816    /* Stop if we're a zombie or need a soft hangup */
04817    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
04818       goto done;
04819 
04820    /* Handle any pending masquerades */
04821    while (chan->masq) {
04822       ast_channel_unlock(chan);
04823       ast_do_masquerade(chan);
04824       ast_channel_lock(chan);
04825    }
04826    if (chan->masqr) {
04827       res = 0; /* XXX explain, why 0 ? */
04828       goto done;
04829    }
04830 
04831    /* Perform the framehook write event here. After the frame enters the framehook list
04832     * there is no telling what will happen, how awesome is that!!! */
04833    if (!(fr = ast_framehook_list_write_event(chan->framehooks, fr))) {
04834       res = 0;
04835       goto done;
04836    }
04837 
04838    if (chan->generatordata && (!fr->src || strcasecmp(fr->src, "ast_prod"))) {
04839       if (ast_test_flag(chan, AST_FLAG_WRITE_INT)) {
04840             ast_deactivate_generator(chan);
04841       } else {
04842          if (fr->frametype == AST_FRAME_DTMF_END) {
04843             /* There is a generator running while we're in the middle of a digit.
04844              * It's probably inband DTMF, so go ahead and pass it so it can
04845              * stop the generator */
04846             ast_clear_flag(chan, AST_FLAG_BLOCKING);
04847             ast_channel_unlock(chan);
04848             res = ast_senddigit_end(chan, fr->subclass.integer, fr->len);
04849             ast_channel_lock(chan);
04850             CHECK_BLOCKING(chan);
04851          } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_UNHOLD) {
04852             /* This is a side case where Echo is basically being called and the person put themselves on hold and took themselves off hold */
04853             res = (chan->tech->indicate == NULL) ? 0 :
04854                chan->tech->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen);
04855          }
04856          res = 0; /* XXX explain, why 0 ? */
04857          goto done;
04858       }
04859    }
04860    /* High bit prints debugging */
04861    if (chan->fout & DEBUGCHAN_FLAG)
04862       ast_frame_dump(chan->name, fr, ">>");
04863    CHECK_BLOCKING(chan);
04864    switch (fr->frametype) {
04865    case AST_FRAME_CONTROL:
04866       res = (chan->tech->indicate == NULL) ? 0 :
04867          chan->tech->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen);
04868       break;
04869    case AST_FRAME_DTMF_BEGIN:
04870       if (chan->audiohooks) {
04871          struct ast_frame *old_frame = fr;
04872          fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
04873          if (old_frame != fr)
04874             f = fr;
04875       }
04876       send_dtmf_event(chan, "Sent", fr->subclass.integer, "Yes", "No");
04877       ast_clear_flag(chan, AST_FLAG_BLOCKING);
04878       ast_channel_unlock(chan);
04879       res = ast_senddigit_begin(chan, fr->subclass.integer);
04880       ast_channel_lock(chan);
04881       CHECK_BLOCKING(chan);
04882       break;
04883    case AST_FRAME_DTMF_END:
04884       if (chan->audiohooks) {
04885          struct ast_frame *new_frame = fr;
04886 
04887          new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
04888          if (new_frame != fr) {
04889             ast_frfree(new_frame);
04890          }
04891       }
04892       send_dtmf_event(chan, "Sent", fr->subclass.integer, "No", "Yes");
04893       ast_clear_flag(chan, AST_FLAG_BLOCKING);
04894       ast_channel_unlock(chan);
04895       res = ast_senddigit_end(chan, fr->subclass.integer, fr->len);
04896       ast_channel_lock(chan);
04897       CHECK_BLOCKING(chan);
04898       break;
04899    case AST_FRAME_TEXT:
04900       if (fr->subclass.integer == AST_FORMAT_T140) {
04901          res = (chan->tech->write_text == NULL) ? 0 :
04902             chan->tech->write_text(chan, fr);
04903       } else {
04904          res = (chan->tech->send_text == NULL) ? 0 :
04905             chan->tech->send_text(chan, (char *) fr->data.ptr);
04906       }
04907       break;
04908    case AST_FRAME_HTML:
04909       res = (chan->tech->send_html == NULL) ? 0 :
04910          chan->tech->send_html(chan, fr->subclass.integer, (char *) fr->data.ptr, fr->datalen);
04911       break;
04912    case AST_FRAME_VIDEO:
04913       /* XXX Handle translation of video codecs one day XXX */
04914       res = (chan->tech->write_video == NULL) ? 0 :
04915          chan->tech->write_video(chan, fr);
04916       break;
04917    case AST_FRAME_MODEM:
04918       res = (chan->tech->write == NULL) ? 0 :
04919          chan->tech->write(chan, fr);
04920       break;
04921    case AST_FRAME_VOICE:
04922       if (chan->tech->write == NULL)
04923          break;   /*! \todo XXX should return 0 maybe ? */
04924 
04925       if (ast_opt_generic_plc && fr->subclass.codec == AST_FORMAT_SLINEAR) {
04926          apply_plc(chan, fr);
04927       }
04928 
04929       /* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */
04930       if (fr->subclass.codec == chan->rawwriteformat) {
04931          f = fr;
04932       } else {
04933          if ((!(fr->subclass.codec & chan->nativeformats)) && (chan->writeformat != fr->subclass.codec)) {
04934             char nf[512];
04935 
04936             /*
04937              * XXX Something is not right.  We are not compatible with this
04938              * frame.  Bad things can happen.  Problems range from no audio,
04939              * one-way audio, to unexplained line hangups.  As a last resort
04940              * try to adjust the format.  Ideally, we do not want to do this
04941              * because it indicates a deeper problem.  For now, we log these
04942              * events to reduce user impact and help identify the problem
04943              * areas.
04944              */
04945             ast_log(LOG_WARNING, "Codec mismatch on channel %s setting write format to %s from %s native formats %s\n",
04946                chan->name, ast_getformatname(fr->subclass.codec), ast_getformatname(chan->writeformat),
04947                ast_getformatname_multiple(nf, sizeof(nf), chan->nativeformats & AST_FORMAT_AUDIO_MASK));
04948             ast_set_write_format(chan, fr->subclass.codec);
04949          }
04950 
04951          f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
04952       }
04953 
04954       if (!f) {
04955          res = 0;
04956          break;
04957       }
04958 
04959       if (chan->audiohooks) {
04960          struct ast_frame *prev = NULL, *new_frame, *cur, *dup;
04961          int freeoldlist = 0;
04962 
04963          if (f != fr) {
04964             freeoldlist = 1;
04965          }
04966 
04967          /* Since ast_audiohook_write may return a new frame, and the cur frame is
04968           * an item in a list of frames, create a new list adding each cur frame back to it
04969           * regardless if the cur frame changes or not. */
04970          for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
04971             new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, cur);
04972 
04973             /* if this frame is different than cur, preserve the end of the list,
04974              * free the old frames, and set cur to be the new frame */
04975             if (new_frame != cur) {
04976 
04977                /* doing an ast_frisolate here seems silly, but we are not guaranteed the new_frame
04978                 * isn't part of local storage, meaning if ast_audiohook_write is called multiple
04979                 * times it may override the previous frame we got from it unless we dup it */
04980                if ((dup = ast_frisolate(new_frame))) {
04981                   AST_LIST_NEXT(dup, frame_list) = AST_LIST_NEXT(cur, frame_list);
04982                   if (freeoldlist) {
04983                      AST_LIST_NEXT(cur, frame_list) = NULL;
04984                      ast_frfree(cur);
04985                   }
04986                   if (new_frame != dup) {
04987                      ast_frfree(new_frame);
04988                   }
04989                   cur = dup;
04990                }
04991             }
04992 
04993             /* now, regardless if cur is new or not, add it to the new list,
04994              * if the new list has not started, cur will become the first item. */
04995             if (prev) {
04996                AST_LIST_NEXT(prev, frame_list) = cur;
04997             } else {
04998                f = cur; /* set f to be the beginning of our new list */
04999             }
05000             prev = cur;
05001          }
05002       }
05003       
05004       /* If Monitor is running on this channel, then we have to write frames out there too */
05005       /* the translator on chan->writetrans may have returned multiple frames
05006          from the single frame we passed in; if so, feed each one of them to the
05007          monitor */
05008       if (chan->monitor && chan->monitor->write_stream) {
05009          struct ast_frame *cur;
05010 
05011          for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
05012          /* XXX must explain this code */
05013 #ifndef MONITOR_CONSTANT_DELAY
05014             int jump = chan->insmpl - chan->outsmpl - 4 * cur->samples;
05015             if (jump >= 0) {
05016                jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format));
05017                if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1)
05018                   ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
05019                chan->outsmpl += (chan->insmpl - chan->outsmpl) + cur->samples;
05020             } else {
05021                chan->outsmpl += cur->samples;
05022             }
05023 #else
05024             int jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format));
05025             if (jump - MONITOR_DELAY >= 0) {
05026                if (ast_seekstream(chan->monitor->write_stream, jump - cur->samples, SEEK_FORCECUR) == -1)
05027                   ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
05028                chan->outsmpl += chan->insmpl - chan->outsmpl;
05029             } else {
05030                chan->outsmpl += cur->samples;
05031             }
05032 #endif
05033             if (chan->monitor->state == AST_MONITOR_RUNNING) {
05034                if (ast_writestream(chan->monitor->write_stream, cur) < 0)
05035                   ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
05036             }
05037          }
05038       }
05039 
05040       /* the translator on chan->writetrans may have returned multiple frames
05041          from the single frame we passed in; if so, feed each one of them to the
05042          channel, freeing each one after it has been written */
05043       if ((f != fr) && AST_LIST_NEXT(f, frame_list)) {
05044          struct ast_frame *cur, *next;
05045          unsigned int skip = 0;
05046 
05047          for (cur = f, next = AST_LIST_NEXT(cur, frame_list);
05048               cur;
05049               cur = next, next = cur ? AST_LIST_NEXT(cur, frame_list) : NULL) {
05050             if (!skip) {
05051                if ((res = chan->tech->write(chan, cur)) < 0) {
05052                   chan->_softhangup |= AST_SOFTHANGUP_DEV;
05053                   skip = 1;
05054                } else if (next) {
05055                   /* don't do this for the last frame in the list,
05056                      as the code outside the loop will do it once
05057                   */
05058                   chan->fout = FRAMECOUNT_INC(chan->fout);
05059                }
05060             }
05061             ast_frfree(cur);
05062          }
05063 
05064          /* reset f so the code below doesn't attempt to free it */
05065          f = NULL;
05066       } else {
05067          res = chan->tech->write(chan, f);
05068       }
05069       break;
05070    case AST_FRAME_NULL:
05071    case AST_FRAME_IAX:
05072       /* Ignore these */
05073       res = 0;
05074       break;
05075    default:
05076       /* At this point, fr is the incoming frame and f is NULL.  Channels do
05077        * not expect to get NULL as a frame pointer and will segfault.  Hence,
05078        * we output the original frame passed in. */
05079       res = chan->tech->write(chan, fr);
05080       break;
05081    }
05082 
05083    if (f && f != fr)
05084       ast_frfree(f);
05085    ast_clear_flag(chan, AST_FLAG_BLOCKING);
05086 
05087    /* Consider a write failure to force a soft hangup */
05088    if (res < 0) {
05089       chan->_softhangup |= AST_SOFTHANGUP_DEV;
05090    } else {
05091       chan->fout = FRAMECOUNT_INC(chan->fout);
05092    }
05093 done:
05094    if (chan->audiohooks && ast_audiohook_write_list_empty(chan->audiohooks)) {
05095       /* The list gets recreated if audiohooks are added again later */
05096       ast_audiohook_detach_list(chan->audiohooks);
05097       chan->audiohooks = NULL;
05098    }
05099    ast_channel_unlock(chan);
05100    return res;
05101 }

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

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

04687 {
04688    int res;
04689    if (!chan->tech->write_video)
04690       return 0;
04691    res = ast_write(chan, fr);
04692    if (!res)
04693       res = 1;
04694    return res;
04695 }

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

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

07310 {
07311    const char *s, *sound;
07312 
07313    /* See if we need to play an audio file to any side of the bridge */
07314 
07315    ast_channel_lock(c0);
07316    if ((s = pbx_builtin_getvar_helper(c0, "BRIDGE_PLAY_SOUND"))) {
07317       sound = ast_strdupa(s);
07318       ast_channel_unlock(c0);
07319       bridge_playfile(c0, c1, sound, 0);
07320       pbx_builtin_setvar_helper(c0, "BRIDGE_PLAY_SOUND", NULL);
07321    } else {
07322       ast_channel_unlock(c0);
07323    }
07324 
07325    ast_channel_lock(c1);
07326    if ((s = pbx_builtin_getvar_helper(c1, "BRIDGE_PLAY_SOUND"))) {
07327       sound = ast_strdupa(s);
07328       ast_channel_unlock(c1);
07329       bridge_playfile(c1, c0, sound, 0);
07330       pbx_builtin_setvar_helper(c1, "BRIDGE_PLAY_SOUND", NULL);
07331    } else {
07332       ast_channel_unlock(c1);
07333    }
07334 }

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

Definition at line 7003 of file channel.c.

References ast_autoservice_start(), ast_autoservice_stop(), AST_DIGIT_ANY, ast_say_number(), ast_stream_and_wait(), and chanlist::chan.

Referenced by ast_channel_bridge(), and bridge_play_sounds().

07004 {
07005    int min = 0, sec = 0, check;
07006 
07007    check = ast_autoservice_start(peer);
07008    if (check)
07009       return;
07010 
07011    if (remain > 0) {
07012       if (remain / 60 > 1) {
07013          min = remain / 60;
07014          sec = remain % 60;
07015       } else {
07016          sec = remain;
07017       }
07018    }
07019    
07020    if (!strcmp(sound,"timeleft")) { /* Queue support */
07021       ast_stream_and_wait(chan, "vm-youhave", "");
07022       if (min) {
07023          ast_say_number(chan, min, AST_DIGIT_ANY, chan->language, NULL);
07024          ast_stream_and_wait(chan, "queue-minutes", "");
07025       }
07026       if (sec) {
07027          ast_say_number(chan, sec, AST_DIGIT_ANY, chan->language, NULL);
07028          ast_stream_and_wait(chan, "queue-seconds", "");
07029       }
07030    } else {
07031       ast_stream_and_wait(chan, sound, "");
07032    }
07033 
07034    ast_autoservice_stop(peer);
07035 }

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

Referenced by __ast_read(), and ast_write().

03738 {
03739    int diff = sample_rate - seek_rate;
03740 
03741    if (diff > 0) {
03742       samples = samples / (float) (sample_rate / seek_rate);
03743    } else if (diff < 0) {
03744       samples = samples * (float) (seek_rate / sample_rate);
03745    }
03746 
03747    return samples;
03748 }

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

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

05245 {
05246    if (!ast_test_flag(parent, AST_FLAG_ZOMBIE) && !ast_check_hangup(parent)) {
05247       struct ast_party_redirecting redirecting;
05248 
05249       /*
05250        * The parent is not a ZOMBIE or hungup so update it with the
05251        * original channel's redirecting information.
05252        */
05253       ast_party_redirecting_init(&redirecting);
05254       ast_channel_lock(orig);
05255       ast_party_redirecting_copy(&redirecting, &orig->redirecting);
05256       ast_channel_unlock(orig);
05257       if (ast_channel_redirecting_macro(orig, parent, &redirecting, 1, 0)) {
05258          ast_channel_update_redirecting(parent, &redirecting, NULL);
05259       }
05260       ast_party_redirecting_free(&redirecting);
05261    }
05262 
05263    /* Safely inherit variables and datastores from the parent channel. */
05264    ast_channel_lock_both(parent, new_chan);
05265    ast_channel_inherit_variables(parent, new_chan);
05266    ast_channel_datastore_inherit(parent, new_chan);
05267    ast_channel_unlock(new_chan);
05268    ast_channel_unlock(parent);
05269 }

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

Definition at line 9486 of file channel.c.

References ast_cc_config_params_init, and ast_cc_copy_config_params().

09487 {
09488    const struct ast_cc_config_params *src = data;
09489    struct ast_cc_config_params *dest = ast_cc_config_params_init();
09490    if (!dest) {
09491       return NULL;
09492    }
09493    ast_cc_copy_config_params(dest, src);
09494    return dest;
09495 }

static void channel_cc_params_destroy ( void *  data  )  [static]

Definition at line 9497 of file channel.c.

References ast_cc_config_params_destroy().

09498 {
09499    struct ast_cc_config_params *cc_params = data;
09500    ast_cc_config_params_destroy(cc_params);
09501 }

static void channel_data_add_flags ( struct ast_data tree,
struct ast_channel chan 
) [static]

Definition at line 272 of file channel.c.

References ast_data_add_bool(), AST_FLAG_ANSWERED_ELSEWHERE, AST_FLAG_BLOCKING, AST_FLAG_BRIDGE_HANGUP_DONT, AST_FLAG_BRIDGE_HANGUP_RUN, AST_FLAG_DEFER_DTMF, AST_FLAG_DISABLE_WORKAROUNDS, AST_FLAG_EMULATE_DTMF, AST_FLAG_END_DTMF_ONLY, AST_FLAG_EXCEPTION, AST_FLAG_IN_AUTOLOOP, AST_FLAG_IN_DTMF, AST_FLAG_MASQ_NOSTREAM, AST_FLAG_MOH, AST_FLAG_NBRIDGE, AST_FLAG_OUTGOING, AST_FLAG_SPYING, AST_FLAG_WRITE_INT, AST_FLAG_ZOMBIE, ast_test_flag, and chanlist::chan.

Referenced by ast_channel_data_add_structure().

00274 {
00275    ast_data_add_bool(tree, "DEFER_DTMF", ast_test_flag(chan, AST_FLAG_DEFER_DTMF));
00276    ast_data_add_bool(tree, "WRITE_INT", ast_test_flag(chan, AST_FLAG_WRITE_INT));
00277    ast_data_add_bool(tree, "BLOCKING", ast_test_flag(chan, AST_FLAG_BLOCKING));
00278    ast_data_add_bool(tree, "ZOMBIE", ast_test_flag(chan, AST_FLAG_ZOMBIE));
00279    ast_data_add_bool(tree, "EXCEPTION", ast_test_flag(chan, AST_FLAG_EXCEPTION));
00280    ast_data_add_bool(tree, "MOH", ast_test_flag(chan, AST_FLAG_MOH));
00281    ast_data_add_bool(tree, "SPYING", ast_test_flag(chan, AST_FLAG_SPYING));
00282    ast_data_add_bool(tree, "NBRIDGE", ast_test_flag(chan, AST_FLAG_NBRIDGE));
00283    ast_data_add_bool(tree, "IN_AUTOLOOP", ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP));
00284    ast_data_add_bool(tree, "OUTGOING", ast_test_flag(chan, AST_FLAG_OUTGOING));
00285    ast_data_add_bool(tree, "IN_DTMF", ast_test_flag(chan, AST_FLAG_IN_DTMF));
00286    ast_data_add_bool(tree, "EMULATE_DTMF", ast_test_flag(chan, AST_FLAG_EMULATE_DTMF));
00287    ast_data_add_bool(tree, "END_DTMF_ONLY", ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY));
00288    ast_data_add_bool(tree, "ANSWERED_ELSEWHERE", ast_test_flag(chan, AST_FLAG_ANSWERED_ELSEWHERE));
00289    ast_data_add_bool(tree, "MASQ_NOSTREAM", ast_test_flag(chan, AST_FLAG_MASQ_NOSTREAM));
00290    ast_data_add_bool(tree, "BRIDGE_HANGUP_RUN", ast_test_flag(chan, AST_FLAG_BRIDGE_HANGUP_RUN));
00291    ast_data_add_bool(tree, "BRIDGE_HANGUP_DONT", ast_test_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT));
00292    ast_data_add_bool(tree, "DISABLE_WORKAROUNDS", ast_test_flag(chan, AST_FLAG_DISABLE_WORKAROUNDS));
00293 }

static struct ast_channel_iterator* channel_iterator_search ( const char *  name,
size_t  name_len,
const char *  exten,
const char *  context 
) [static]

Definition at line 1629 of file channel.c.

References ao2_find, ast_calloc, ast_copy_string(), ast_free, ast_strlen_zero(), channels, ast_channel::context, ast_channel::exten, ast_channel::name, OBJ_MULTIPLE, and OBJ_POINTER.

Referenced by ast_channel_iterator_by_exten_new(), and ast_channel_iterator_by_name_new().

01632 {
01633    struct ast_channel_iterator *i;
01634    struct ast_channel tmp_chan = {
01635       .name = name,
01636       /* This is sort of a hack.  Basically, we're using an arbitrary field
01637        * in ast_channel to pass the name_len for a prefix match.  If this
01638        * gets changed, then the compare callback must be changed, too. */
01639       .rings = name_len,
01640    };
01641 
01642    if (!(i = ast_calloc(1, sizeof(*i)))) {
01643       return NULL;
01644    }
01645 
01646    if (exten) {
01647       ast_copy_string(tmp_chan.exten, exten, sizeof(tmp_chan.exten));
01648    }
01649 
01650    if (context) {
01651       ast_copy_string(tmp_chan.context, context, sizeof(tmp_chan.context));
01652    }
01653 
01654    if (!(i->active_iterator = ao2_find(channels, &tmp_chan,
01655                    OBJ_MULTIPLE | ((!ast_strlen_zero(name) && (name_len == 0)) ? OBJ_POINTER : 0)))) {
01656           ast_free(i);
01657           return NULL;
01658    }
01659 
01660    return i;
01661 }

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

References CHANNEL_CLI_RELOAD, CHANNEL_MODULE_LOAD, and CHANNEL_MODULE_RELOAD.

08151 {
08152    switch (reason) {
08153    case CHANNEL_MODULE_LOAD:
08154       return "LOAD (Channel module load)";
08155 
08156    case CHANNEL_MODULE_RELOAD:
08157       return "RELOAD (Channel module reload)";
08158 
08159    case CHANNEL_CLI_RELOAD:
08160       return "CLIRELOAD (Channel module reload by CLI command)";
08161 
08162    default:
08163       return "MANAGERRELOAD (Channel module reload by manager)";
08164    }
08165 };

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

References AST_LIST_APPEND_LIST, 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().

06175 {
06176    struct ast_var_t *current, *newvar;
06177    /* Append variables from clone channel into original channel */
06178    /* XXX Is this always correct?  We have to in order to keep MACROS working XXX */
06179    AST_LIST_APPEND_LIST(&original->varshead, &clonechan->varshead, entries);
06180 
06181    /* then, dup the varshead list into the clone */
06182    
06183    AST_LIST_TRAVERSE(&original->varshead, current, entries) {
06184       newvar = ast_var_assign(current->name, current->value);
06185       if (newvar)
06186          AST_LIST_INSERT_TAIL(&clonechan->varshead, newvar, entries);
06187    }
06188 }

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

Definition at line 527 of file channel.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, chanlist::list, 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().

00528 {
00529    struct chanlist *cl;
00530    int which = 0;
00531    int wordlen;
00532    char *ret = NULL;
00533 
00534    if (a->pos != 3)
00535       return NULL;
00536 
00537    wordlen = strlen(a->word);
00538 
00539    AST_RWLIST_RDLOCK(&backends);
00540    AST_RWLIST_TRAVERSE(&backends, cl, list) {
00541       if (!strncasecmp(a->word, cl->tech->type, wordlen) && ++which > a->n) {
00542          ret = ast_strdup(cl->tech->type);
00543          break;
00544       }
00545    }
00546    AST_RWLIST_UNLOCK(&backends);
00547    
00548    return ret;
00549 }

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

Definition at line 7909 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_unlock, ast_channel_unref, ast_data_add_node(), ast_data_remove_node(), ast_data_search_match(), ast_log(), and LOG_ERROR.

07911 {
07912    struct ast_channel *c;
07913    struct ast_channel_iterator *iter = NULL;
07914    struct ast_data *data_channel;
07915 
07916    for (iter = ast_channel_iterator_all_new();
07917       iter && (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) {
07918       ast_channel_lock(c);
07919 
07920       data_channel = ast_data_add_node(root, "channel");
07921       if (!data_channel) {
07922          ast_channel_unlock(c);
07923          continue;
07924       }
07925 
07926       if (ast_channel_data_add_structure(data_channel, c, 1) < 0) {
07927          ast_log(LOG_ERROR, "Unable to add channel structure for channel: %s\n", c->name);
07928       }
07929 
07930       ast_channel_unlock(c);
07931 
07932       if (!ast_data_search_match(search, data_channel)) {
07933          ast_data_remove_node(root, data_channel);
07934       }
07935    }
07936    if (iter) {
07937       ast_channel_iterator_destroy(iter);
07938    }
07939 
07940    return 0;
07941 }

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

Definition at line 7947 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.

07949 {
07950    struct chanlist *cl;
07951    struct ast_data *data_type;
07952 
07953    AST_RWLIST_RDLOCK(&backends);
07954    AST_RWLIST_TRAVERSE(&backends, cl, list) {
07955       data_type = ast_data_add_node(data_root, "type");
07956       if (!data_type) {
07957          continue;
07958       }
07959       ast_data_add_str(data_type, "name", cl->tech->type);
07960       ast_data_add_str(data_type, "description", cl->tech->description);
07961       ast_data_add_bool(data_type, "devicestate", cl->tech->devicestate ? 1 : 0);
07962       ast_data_add_bool(data_type, "indications", cl->tech->indicate ? 1 : 0);
07963       ast_data_add_bool(data_type, "transfer", cl->tech->transfer ? 1 : 0);
07964       ast_data_add_bool(data_type, "send_digit_begin", cl->tech->send_digit_begin ? 1 : 0);
07965       ast_data_add_bool(data_type, "send_digit_end", cl->tech->send_digit_end ? 1 : 0);
07966       ast_data_add_bool(data_type, "call", cl->tech->call ? 1 : 0);
07967       ast_data_add_bool(data_type, "hangup", cl->tech->hangup ? 1 : 0);
07968       ast_data_add_bool(data_type, "answer", cl->tech->answer ? 1 : 0);
07969       ast_data_add_bool(data_type, "read", cl->tech->read ? 1 : 0);
07970       ast_data_add_bool(data_type, "write", cl->tech->write ? 1 : 0);
07971       ast_data_add_bool(data_type, "send_text", cl->tech->send_text ? 1 : 0);
07972       ast_data_add_bool(data_type, "send_image", cl->tech->send_image ? 1 : 0);
07973       ast_data_add_bool(data_type, "send_html", cl->tech->send_html ? 1 : 0);
07974       ast_data_add_bool(data_type, "exception", cl->tech->exception ? 1 : 0);
07975       ast_data_add_bool(data_type, "bridge", cl->tech->bridge ? 1 : 0);
07976       ast_data_add_bool(data_type, "early_bridge", cl->tech->early_bridge ? 1 : 0);
07977       ast_data_add_bool(data_type, "fixup", cl->tech->fixup ? 1 : 0);
07978       ast_data_add_bool(data_type, "setoption", cl->tech->setoption ? 1 : 0);
07979       ast_data_add_bool(data_type, "queryoption", cl->tech->queryoption ? 1 : 0);
07980       ast_data_add_bool(data_type, "write_video", cl->tech->write_video ? 1 : 0);
07981       ast_data_add_bool(data_type, "write_text", cl->tech->write_text ? 1 : 0);
07982       ast_data_add_bool(data_type, "bridged_channel", cl->tech->bridged_channel ? 1 : 0);
07983       ast_data_add_bool(data_type, "func_channel_read", cl->tech->func_channel_read ? 1 : 0);
07984       ast_data_add_bool(data_type, "func_channel_write", cl->tech->func_channel_write ? 1 : 0);
07985       ast_data_add_bool(data_type, "get_base_channel", cl->tech->get_base_channel ? 1 : 0);
07986       ast_data_add_bool(data_type, "set_base_channel", cl->tech->set_base_channel ? 1 : 0);
07987       ast_data_add_bool(data_type, "get_pvt_uniqueid", cl->tech->get_pvt_uniqueid ? 1 : 0);
07988       ast_data_add_bool(data_type, "cc_callback", cl->tech->cc_callback ? 1 : 0);
07989 
07990       ast_data_add_codecs(data_type, "capabilities", cl->tech->capabilities);
07991 
07992       if (!ast_data_search_match(search, data_type)) {
07993          ast_data_remove_node(data_root, data_type);
07994       }
07995    }
07996    AST_RWLIST_UNLOCK(&backends);
07997 
07998    return 0;
07999 }

static void destroy_hooks ( struct ast_channel chan  )  [static]

Definition at line 2760 of file channel.c.

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

Referenced by ast_hangup().

02761 {
02762    if (chan->audiohooks) {
02763       ast_audiohook_detach_list(chan->audiohooks);
02764       chan->audiohooks = NULL;
02765    }
02766 
02767    ast_framehook_list_destroy(chan);
02768 }

static void free_translation ( struct ast_channel clonechan  )  [static]

Definition at line 2724 of file channel.c.

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

02725 {
02726    if (clonechan->writetrans)
02727       ast_translator_free_path(clonechan->writetrans);
02728    if (clonechan->readtrans)
02729       ast_translator_free_path(clonechan->readtrans);
02730    clonechan->writetrans = NULL;
02731    clonechan->readtrans = NULL;
02732    clonechan->rawwriteformat = clonechan->nativeformats;
02733    clonechan->rawreadformat = clonechan->nativeformats;
02734 }

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

Definition at line 3070 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_deactivate_generator(), ast_debug, AST_FORMAT_AUDIO_MASK, ast_format_rate(), and chanlist::chan.

Referenced by ast_activate_generator(), and ast_read_generator_actions().

03071 {
03072    /* Called if generator doesn't have data */
03073    void *tmp;
03074    int res;
03075    int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = NULL;
03076    struct ast_channel *chan = (struct ast_channel *)data;
03077 
03078    ast_channel_lock(chan);
03079    tmp = chan->generatordata;
03080    chan->generatordata = NULL;
03081    if (chan->generator)
03082       generate = chan->generator->generate;
03083    ast_channel_unlock(chan);
03084 
03085    if (!tmp || !generate)
03086       return 0;
03087 
03088    res = generate(chan, tmp, 0, ast_format_rate(chan->writeformat & AST_FORMAT_AUDIO_MASK) / 50);
03089 
03090    chan->generatordata = tmp;
03091 
03092    if (res) {
03093       ast_debug(1, "Auto-deactivating generator\n");
03094       ast_deactivate_generator(chan);
03095    }
03096 
03097    return 0;
03098 }

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

Definition at line 5221 of file channel.c.

References AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CONTROL_BUSY, and AST_CONTROL_CONGESTION.

05222 {
05223    if (outstate) {
05224       /* compute error and return */
05225       if (cause == AST_CAUSE_BUSY)
05226          *outstate = AST_CONTROL_BUSY;
05227       else if (cause == AST_CAUSE_CONGESTION)
05228          *outstate = AST_CONTROL_CONGESTION;
05229       else
05230          *outstate = 0;
05231    }
05232 }

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 552 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, chanlist::list, 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.

00553 {
00554    struct chanlist *cl = NULL;
00555    char buf[512];
00556 
00557    switch (cmd) {
00558    case CLI_INIT:
00559       e->command = "core show channeltype";
00560       e->usage =
00561          "Usage: core show channeltype <name>\n"
00562          "  Show details about the specified channel type, <name>.\n";
00563       return NULL;
00564    case CLI_GENERATE:
00565       return complete_channeltypes(a);
00566    }
00567 
00568    if (a->argc != 4)
00569       return CLI_SHOWUSAGE;
00570    
00571    AST_RWLIST_RDLOCK(&backends);
00572 
00573    AST_RWLIST_TRAVERSE(&backends, cl, list) {
00574       if (!strncasecmp(cl->tech->type, a->argv[3], strlen(cl->tech->type)))
00575          break;
00576    }
00577 
00578 
00579    if (!cl) {
00580       ast_cli(a->fd, "\n%s is not a registered channel driver.\n", a->argv[3]);
00581       AST_RWLIST_UNLOCK(&backends);
00582       return CLI_FAILURE;
00583    }
00584 
00585    ast_cli(a->fd,
00586       "-- Info about channel driver: %s --\n"
00587       "  Device State: %s\n"
00588       "    Indication: %s\n"
00589       "     Transfer : %s\n"
00590       "  Capabilities: %s\n"
00591       "   Digit Begin: %s\n"
00592       "     Digit End: %s\n"
00593       "    Send HTML : %s\n"
00594       " Image Support: %s\n"
00595       "  Text Support: %s\n",
00596       cl->tech->type,
00597       (cl->tech->devicestate) ? "yes" : "no",
00598       (cl->tech->indicate) ? "yes" : "no",
00599       (cl->tech->transfer) ? "yes" : "no",
00600       ast_getformatname_multiple(buf, sizeof(buf), (cl->tech->capabilities) ? cl->tech->capabilities : -1),
00601       (cl->tech->send_digit_begin) ? "yes" : "no",
00602       (cl->tech->send_digit_end) ? "yes" : "no",
00603       (cl->tech->send_html) ? "yes" : "no",
00604       (cl->tech->send_image) ? "yes" : "no",
00605       (cl->tech->send_text) ? "yes" : "no"
00606       
00607    );
00608 
00609    AST_RWLIST_UNLOCK(&backends);
00610 
00611    return CLI_SUCCESS;
00612 }

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 486 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::list, chanlist::tech, ast_channel_tech::transfer, ast_channel_tech::type, and ast_cli_entry::usage.

00487 {
00488 #define FORMAT  "%-10.10s  %-40.40s %-12.12s %-12.12s %-12.12s\n"
00489    struct chanlist *cl;
00490    int count_chan = 0;
00491 
00492    switch (cmd) {
00493    case CLI_INIT:
00494       e->command = "core show channeltypes";
00495       e->usage =
00496          "Usage: core show channeltypes\n"
00497          "       Lists available channel types registered in your\n"
00498          "       Asterisk server.\n";
00499       return NULL;
00500    case CLI_GENERATE:
00501       return NULL;
00502    }
00503 
00504    if (a->argc != 3)
00505       return CLI_SHOWUSAGE;
00506 
00507    ast_cli(a->fd, FORMAT, "Type", "Description",       "Devicestate", "Indications", "Transfer");
00508    ast_cli(a->fd, FORMAT, "----------", "-----------", "-----------", "-----------", "--------");
00509 
00510    AST_RWLIST_RDLOCK(&backends);
00511    AST_RWLIST_TRAVERSE(&backends, cl, list) {
00512       ast_cli(a->fd, FORMAT, cl->tech->type, cl->tech->description,
00513          (cl->tech->devicestate) ? "yes" : "no",
00514          (cl->tech->indicate) ? "yes" : "no",
00515          (cl->tech->transfer) ? "yes" : "no");
00516       count_chan++;
00517    }
00518    AST_RWLIST_UNLOCK(&backends);
00519 
00520    ast_cli(a->fd, "----------\n%d channel drivers registered.\n", count_chan);
00521 
00522    return CLI_SUCCESS;
00523 
00524 #undef FORMAT
00525 }

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

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

04302 {
04303    /* Don't include a default case here so that we get compiler warnings
04304     * when a new type is added. */
04305 
04306    switch (condition) {
04307    case AST_CONTROL_PROGRESS:
04308    case AST_CONTROL_PROCEEDING:
04309    case AST_CONTROL_VIDUPDATE:
04310    case AST_CONTROL_SRCUPDATE:
04311    case AST_CONTROL_SRCCHANGE:
04312    case AST_CONTROL_RADIO_KEY:
04313    case AST_CONTROL_RADIO_UNKEY:
04314    case AST_CONTROL_OPTION:
04315    case AST_CONTROL_WINK:
04316    case AST_CONTROL_FLASH:
04317    case AST_CONTROL_OFFHOOK:
04318    case AST_CONTROL_TAKEOFFHOOK:
04319    case AST_CONTROL_ANSWER:
04320    case AST_CONTROL_HANGUP:
04321    case AST_CONTROL_CONNECTED_LINE:
04322    case AST_CONTROL_REDIRECTING:
04323    case AST_CONTROL_TRANSFER:
04324    case AST_CONTROL_T38_PARAMETERS:
04325    case _XXX_AST_CONTROL_T38:
04326    case AST_CONTROL_CC:
04327    case AST_CONTROL_READ_ACTION:
04328    case AST_CONTROL_AOC:
04329    case AST_CONTROL_END_OF_Q:
04330    case AST_CONTROL_UPDATE_RTP_PEER:
04331       break;
04332 
04333    case AST_CONTROL_INCOMPLETE:
04334    case AST_CONTROL_CONGESTION:
04335    case AST_CONTROL_BUSY:
04336    case AST_CONTROL_RINGING:
04337    case AST_CONTROL_RING:
04338    case AST_CONTROL_HOLD:
04339       /* You can hear these */
04340       return 1;
04341 
04342    case AST_CONTROL_UNHOLD:
04343       /* This is a special case.  You stop hearing this. */
04344       break;
04345    }
04346 
04347    return 0;
04348 }

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

Definition at line 625 of file channel.c.

00626 {
00627    /* Hangup channel. */
00628    return NULL;
00629 }

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

Definition at line 637 of file channel.c.

00638 {
00639    /* No problem fixing up the channel. */
00640    return 0;
00641 }

static int kill_hangup ( struct ast_channel chan  )  [static]

Definition at line 643 of file channel.c.

References chanlist::chan, and ast_channel::tech_pvt.

00644 {
00645    chan->tech_pvt = NULL;
00646    return 0;
00647 }

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

Definition at line 619 of file channel.c.

00620 {
00621    /* Hangup channel. */
00622    return NULL;
00623 }

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

Definition at line 631 of file channel.c.

00632 {
00633    /* Hangup channel. */
00634    return -1;
00635 }

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

References ast_manager_event_multichan, ast_channel::caller, EVENT_FLAG_CALL, ast_party_caller::id, ast_channel::name, ast_party_id::number, S_COR, ast_party_number::str, ast_channel::uniqueid, and ast_party_number::valid.

Referenced by ast_channel_bridge().

07253 {
07254    struct ast_channel *chans[2] = { c0, c1 };
07255    ast_manager_event_multichan(EVENT_FLAG_CALL, "Bridge", 2, chans,
07256       "Bridgestate: %s\r\n"
07257       "Bridgetype: %s\r\n"
07258       "Channel1: %s\r\n"
07259       "Channel2: %s\r\n"
07260       "Uniqueid1: %s\r\n"
07261       "Uniqueid2: %s\r\n"
07262       "CallerID1: %s\r\n"
07263       "CallerID2: %s\r\n",
07264       onoff ? "Link" : "Unlink",
07265       type == 1 ? "core" : "native",
07266       c0->name, c1->name,
07267       c0->uniqueid, c1->uniqueid,
07268       S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, ""),
07269       S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, ""));
07270 }

static void masquerade_colp_transfer ( struct ast_channel transferee,
struct xfer_masquerade_ds colp 
) [static]

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

06382 {
06383    struct ast_control_read_action_payload *frame_payload;
06384    int payload_size;
06385    int frame_size;
06386    unsigned char connected_line_data[1024];
06387 
06388    /* Release any hold on the target. */
06389    if (colp->target_held) {
06390       ast_queue_control(transferee, AST_CONTROL_UNHOLD);
06391    }
06392 
06393    /*
06394     * Since transferee may not actually be bridged to another channel,
06395     * there is no way for us to queue a frame so that its connected
06396     * line status will be updated.  Instead, we use the somewhat
06397     * hackish approach of using a special control frame type that
06398     * instructs ast_read() to perform a specific action.  In this
06399     * case, the frame we queue tells ast_read() to call the
06400     * connected line interception macro configured for transferee.
06401     */
06402    payload_size = ast_connected_line_build_data(connected_line_data,
06403       sizeof(connected_line_data), &colp->target_id, NULL);
06404    if (payload_size != -1) {
06405       frame_size = payload_size + sizeof(*frame_payload);
06406       frame_payload = alloca(frame_size);
06407       frame_payload->action = AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO;
06408       frame_payload->payload_size = payload_size;
06409       memcpy(frame_payload->payload, connected_line_data, payload_size);
06410       ast_queue_control_data(transferee, AST_CONTROL_READ_ACTION, frame_payload,
06411          frame_size);
06412    }
06413    /*
06414     * In addition to queueing the read action frame so that the
06415     * connected line info on transferee will be updated, we also are
06416     * going to queue a plain old connected line update on transferee to
06417     * update the target.
06418     */
06419    ast_channel_queue_connected_line_update(transferee, &colp->transferee_id, NULL);
06420 }

static const char* oldest_linkedid ( const char *  a,
const char *  b 
) [static]

Definition at line 6203 of file channel.c.

References ast_strlen_zero().

Referenced by ast_channel_set_linkgroup().

06204 {
06205    const char *satime, *saseq;
06206    const char *sbtime, *sbseq;
06207    const char *dash;
06208 
06209    unsigned int atime, aseq, btime, bseq;
06210 
06211    if (ast_strlen_zero(a))
06212       return b;
06213 
06214    if (ast_strlen_zero(b))
06215       return a;
06216 
06217    satime = a;
06218    sbtime = b;
06219 
06220    /* jump over the system name */
06221    if ((dash = strrchr(satime, '-'))) {
06222       satime = dash+1;
06223    }
06224    if ((dash = strrchr(sbtime, '-'))) {
06225       sbtime = dash+1;
06226    }
06227 
06228    /* the sequence comes after the '.' */
06229    saseq = strchr(satime, '.');
06230    sbseq = strchr(sbtime, '.');
06231    if (!saseq || !sbseq)
06232       return NULL;
06233    saseq++;
06234    sbseq++;
06235 
06236    /* convert it all to integers */
06237    atime = atoi(satime); /* note that atoi is ignoring the '.' after the time string */
06238    btime = atoi(sbtime); /* note that atoi is ignoring the '.' after the time string */
06239    aseq = atoi(saseq);
06240    bseq = atoi(sbseq);
06241 
06242    /* and finally compare */
06243    if (atime == btime) {
06244       return (aseq < bseq) ? a : b;
06245    }
06246    else {
06247       return (atime < btime) ? a : b;
06248    }
06249 }

static void party_connected_line_copy_transfer ( struct ast_party_connected_line dest,
const struct ast_party_connected_line src 
) [static]

Definition at line 6009 of file channel.c.

References AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, ast_party_connected_line_copy(), chanlist::connected, and ast_party_connected_line::source.

Referenced by ast_channel_transfer_masquerade().

06010 {
06011    struct ast_party_connected_line connected;
06012 
06013    connected = *((struct ast_party_connected_line *) src);
06014    connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
06015 
06016    /* Make sure empty strings will be erased. */
06017    if (!connected.id.name.str) {
06018       connected.id.name.str = "";
06019    }
06020    if (!connected.id.number.str) {
06021       connected.id.number.str = "";
06022    }
06023    if (!connected.id.subaddress.str) {
06024       connected.id.subaddress.str = "";
06025    }
06026    if (!connected.id.tag) {
06027       connected.id.tag = "";
06028    }
06029 
06030    ast_party_connected_line_copy(dest, &connected);
06031 }

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

References ast_log(), ast_party_id_presentation(), ast_party_id_ies::combined_presentation, id, LOG_WARNING, ast_party_id_ies::name, ast_party_id_ies::number, party_name_build_data(), party_number_build_data(), party_subaddress_build_data(), ast_party_id_ies::subaddress, ast_party_id_ies::tag, and update().

Referenced by ast_connected_line_build_data(), and ast_redirecting_build_data().

08503 {
08504    size_t length;
08505    size_t pos = 0;
08506    int res;
08507 
08508    /*
08509     * The size of integer values must be fixed in case the frame is
08510     * shipped to another machine.
08511     */
08512 
08513    if (!update || update->name) {
08514       res = party_name_build_data(data + pos, datalen - pos, &id->name, label,
08515          &ies->name);
08516       if (res < 0) {
08517          return -1;
08518       }
08519       pos += res;
08520    }
08521 
08522    if (!update || update->number) {
08523       res = party_number_build_data(data + pos, datalen - pos, &id->number, label,
08524          &ies->number);
08525       if (res < 0) {
08526          return -1;
08527       }
08528       pos += res;
08529    }
08530 
08531    if (!update || update->subaddress) {
08532       res = party_subaddress_build_data(data + pos, datalen - pos, &id->subaddress,
08533          label, &ies->subaddress);
08534       if (res < 0) {
08535          return -1;
08536       }
08537       pos += res;
08538    }
08539 
08540    /* *************** Party id user tag **************************** */
08541    if (id->tag) {
08542       length = strlen(id->tag);
08543       if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08544          ast_log(LOG_WARNING, "No space left for %s tag\n", label);
08545          return -1;
08546       }
08547       data[pos++] = ies->tag;
08548       data[pos++] = length;
08549       memcpy(data + pos, id->tag, length);
08550       pos += length;
08551    }
08552 
08553    /* *************** Party id combined presentation *************** */
08554    if (!update || update->number) {
08555       int presentation;
08556 
08557       if (!update || update->name) {
08558          presentation = ast_party_id_presentation(id);
08559       } else {
08560          /*
08561           * We must compromise because not all the information is available
08562           * to determine a combined presentation value.
08563           * We will only send the number presentation instead.
08564           */
08565          presentation = id->number.presentation;
08566       }
08567 
08568       if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08569          ast_log(LOG_WARNING, "No space left for %s combined presentation\n", label);
08570          return -1;
08571       }
08572       data[pos++] = ies->combined_presentation;
08573       data[pos++] = 1;
08574       data[pos++] = presentation;
08575    }
08576 
08577    return pos;
08578 }

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

References ast_log(), ast_party_name_ies::char_set, LOG_WARNING, name, ast_party_name_ies::presentation, ast_party_name_ies::str, and ast_party_name_ies::valid.

Referenced by party_id_build_data().

08275 {
08276    size_t length;
08277    size_t pos = 0;
08278 
08279    /*
08280     * The size of integer values must be fixed in case the frame is
08281     * shipped to another machine.
08282     */
08283    if (name->str) {
08284       length = strlen(name->str);
08285       if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08286          ast_log(LOG_WARNING, "No space left for %s name\n", label);
08287          return -1;
08288       }
08289       data[pos++] = ies->str;
08290       data[pos++] = length;
08291       memcpy(data + pos, name->str, length);
08292       pos += length;
08293    }
08294 
08295    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08296       ast_log(LOG_WARNING, "No space left for %s name char set\n", label);
08297       return -1;
08298    }
08299    data[pos++] = ies->char_set;
08300    data[pos++] = 1;
08301    data[pos++] = name->char_set;
08302 
08303    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08304       ast_log(LOG_WARNING, "No space left for %s name presentation\n", label);
08305       return -1;
08306    }
08307    data[pos++] = ies->presentation;
08308    data[pos++] = 1;
08309    data[pos++] = name->presentation;
08310 
08311    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08312       ast_log(LOG_WARNING, "No space left for %s name valid\n", label);
08313       return -1;
08314    }
08315    data[pos++] = ies->valid;
08316    data[pos++] = 1;
08317    data[pos++] = name->valid;
08318 
08319    return pos;
08320 }

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

08349 {
08350    size_t length;
08351    size_t pos = 0;
08352 
08353    /*
08354     * The size of integer values must be fixed in case the frame is
08355     * shipped to another machine.
08356     */
08357    if (number->str) {
08358       length = strlen(number->str);
08359       if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08360          ast_log(LOG_WARNING, "No space left for %s number\n", label);
08361          return -1;
08362       }
08363       data[pos++] = ies->str;
08364       data[pos++] = length;
08365       memcpy(data + pos, number->str, length);
08366       pos += length;
08367    }
08368 
08369    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08370       ast_log(LOG_WARNING, "No space left for %s numbering plan\n", label);
08371       return -1;
08372    }
08373    data[pos++] = ies->plan;
08374    data[pos++] = 1;
08375    data[pos++] = number->plan;
08376 
08377    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08378       ast_log(LOG_WARNING, "No space left for %s number presentation\n", label);
08379       return -1;
08380    }
08381    data[pos++] = ies->presentation;
08382    data[pos++] = 1;
08383    data[pos++] = number->presentation;
08384 
08385    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08386       ast_log(LOG_WARNING, "No space left for %s number valid\n", label);
08387       return -1;
08388    }
08389    data[pos++] = ies->valid;
08390    data[pos++] = 1;
08391    data[pos++] = number->valid;
08392 
08393    return pos;
08394 }

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

08423 {
08424    size_t length;
08425    size_t pos = 0;
08426 
08427    /*
08428     * The size of integer values must be fixed in case the frame is
08429     * shipped to another machine.
08430     */
08431    if (subaddress->str) {
08432       length = strlen(subaddress->str);
08433       if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08434          ast_log(LOG_WARNING, "No space left for %s subaddress\n", label);
08435          return -1;
08436       }
08437       data[pos++] = ies->str;
08438       data[pos++] = length;
08439       memcpy(data + pos, subaddress->str, length);
08440       pos += length;
08441    }
08442 
08443    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08444       ast_log(LOG_WARNING, "No space left for %s type of subaddress\n", label);
08445       return -1;
08446    }
08447    data[pos++] = ies->type;
08448    data[pos++] = 1;
08449    data[pos++] = subaddress->type;
08450 
08451    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08452       ast_log(LOG_WARNING,
08453          "No space left for %s subaddress odd-even indicator\n", label);
08454       return -1;
08455    }
08456    data[pos++] = ies->odd_even_indicator;
08457    data[pos++] = 1;
08458    data[pos++] = subaddress->odd_even_indicator;
08459 
08460    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08461       ast_log(LOG_WARNING, "No space left for %s subaddress valid\n", label);
08462       return -1;
08463    }
08464    data[pos++] = ies->valid;
08465    data[pos++] = 1;
08466    data[pos++] = subaddress->valid;
08467 
08468    return pos;
08469 }

static void plc_ds_destroy ( void *  data  )  [static]

Definition at line 4710 of file channel.c.

References ast_free, and plc_ds::samples_buf.

04711 {
04712    struct plc_ds *plc = data;
04713    ast_free(plc->samples_buf);
04714    ast_free(plc);
04715 }

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

Definition at line 3692 of file channel.c.

References AST_FRAME_DTMF_END, ast_queue_frame(), chanlist::chan, ast_channel::dtmff, f, ast_frame::frametype, ast_frame_subclass::integer, ast_frame::len, and ast_frame::subclass.

Referenced by __ast_read().

03693 {
03694    struct ast_frame *fr = &chan->dtmff;
03695 
03696    fr->frametype = AST_FRAME_DTMF_END;
03697    fr->subclass.integer = f->subclass.integer;
03698    fr->len = f->len;
03699 
03700    /* The only time this function will be called is for a frame that just came
03701     * out of the channel driver.  So, we want to stick it on the tail of the
03702     * readq. */
03703 
03704    ast_queue_frame(chan, fr);
03705 }

static void report_new_callerid ( struct ast_channel chan  )  [static]

Precondition:
chan is locked

Definition at line 6351 of file channel.c.

References ast_describe_caller_presentation(), ast_manager_event, ast_party_id_presentation(), ast_channel::caller, chanlist::chan, EVENT_FLAG_CALL, ast_party_caller::id, ast_party_id::name, ast_channel::name, ast_party_id::number, S_COR, ast_party_name::str, ast_party_number::str, ast_channel::uniqueid, ast_party_name::valid, and ast_party_number::valid.

Referenced by ast_channel_set_caller_event(), ast_do_masquerade(), and ast_set_callerid().

06352 {
06353    int pres;
06354 
06355    pres = ast_party_id_presentation(&chan->caller.id);
06356    ast_manager_event(chan, EVENT_FLAG_CALL, "NewCallerid",
06357       "Channel: %s\r\n"
06358       "CallerIDNum: %s\r\n"
06359       "CallerIDName: %s\r\n"
06360       "Uniqueid: %s\r\n"
06361       "CID-CallingPres: %d (%s)\r\n",
06362       chan->name,
06363       S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
06364       S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""),
06365       chan->uniqueid,
06366       pres,
06367       ast_describe_caller_presentation(pres)
06368       );
06369 }

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

References ast_manager_event, chanlist::chan, EVENT_FLAG_DTMF, ast_channel::name, and ast_channel::uniqueid.

Referenced by __ast_read(), and ast_write().

03632 {
03633    ast_manager_event(chan, EVENT_FLAG_DTMF,
03634          "DTMF",
03635          "Channel: %s\r\n"
03636          "Uniqueid: %s\r\n"
03637          "Digit: %c\r\n"
03638          "Direction: %s\r\n"
03639          "Begin: %s\r\n"
03640          "End: %s\r\n",
03641          chan->name, chan->uniqueid, digit, direction, begin, end);
03642 }

static int set_format ( struct ast_channel chan,
format_t  fmt,
format_t rawformat,
format_t format,
struct ast_trans_pvt **  trans,
const int  direction 
) [static]

Definition at line 5103 of file channel.c.

References ast_best_codec(), ast_channel_lock, ast_channel_setoption(), ast_channel_unlock, ast_debug, AST_FORMAT_AUDIO_MASK, 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(), chanlist::chan, LOG_WARNING, ast_channel::name, and ast_channel::nativeformats.

Referenced by ast_set_read_format(), and ast_set_write_format().

05105 {
05106    format_t native, native_fmt = ast_best_codec(fmt);
05107    int res;
05108    char from[200], to[200];
05109    
05110    /* Make sure we only consider audio */
05111    fmt &= AST_FORMAT_AUDIO_MASK;
05112    
05113    native = chan->nativeformats;
05114 
05115    if (!fmt || !native) /* No audio requested */
05116       return 0;   /* Let's try a call without any sounds (video, text) */
05117 
05118    /* See if the underlying channel driver is capable of performing transcoding for us */
05119    if (!ast_channel_setoption(chan, direction ? AST_OPTION_FORMAT_WRITE : AST_OPTION_FORMAT_READ, &native_fmt, sizeof(int*), 0)) {
05120       ast_debug(1, "Channel driver natively set channel %s to %s format %s\n", chan->name,
05121            direction ? "write" : "read", ast_getformatname(native_fmt));
05122       chan->nativeformats = *rawformat = *format = native_fmt;
05123       if (*trans) {
05124          ast_translator_free_path(*trans);
05125       }
05126       *trans = NULL;
05127       return 0;
05128    }
05129 
05130    /* Find a translation path from the native format to one of the desired formats */
05131    if (!direction)
05132       /* reading */
05133       res = ast_translator_best_choice(&fmt, &native);
05134    else
05135       /* writing */
05136       res = ast_translator_best_choice(&native, &fmt);
05137 
05138    if (res < 0) {
05139       ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n",
05140          ast_getformatname_multiple(from, sizeof(from), native),
05141          ast_getformatname_multiple(to, sizeof(to), fmt));
05142       return -1;
05143    }
05144    
05145    /* Now we have a good choice for both. */
05146    ast_channel_lock(chan);
05147 
05148    if ((*rawformat == native) && (*format == fmt) && ((*rawformat == *format) || (*trans))) {
05149       /* the channel is already in these formats, so nothing to do */
05150       ast_channel_unlock(chan);
05151       return 0;
05152    }
05153 
05154    *rawformat = native;
05155    /* User perspective is fmt */
05156    *format = fmt;
05157    /* Free any read translation we have right now */
05158    if (*trans) {
05159       ast_translator_free_path(*trans);
05160       *trans = NULL;
05161    }
05162    /* Build a translation path from the raw format to the desired format */
05163    if (*format == *rawformat) {
05164       /*
05165        * If we were able to swap the native format to the format that
05166        * has been requested, then there is no need to try to build
05167        * a translation path.
05168        */
05169       res = 0;
05170    } else {
05171       if (!direction) {
05172          /* reading */
05173          *trans = ast_translator_build_path(*format, *rawformat);
05174       } else {
05175          /* writing */
05176          *trans = ast_translator_build_path(*rawformat, *format);
05177       }
05178       res = *trans ? 0 : -1;
05179    }
05180    ast_channel_unlock(chan);
05181    ast_debug(1, "Set channel %s to %s format %s\n", chan->name,
05182       direction ? "write" : "read", ast_getformatname(fmt));
05183    return res;
05184 }

static int set_security_requirements ( const struct ast_channel requestor,
struct ast_channel out 
) [static]

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

05540 {
05541    int ops[2][2] = {
05542       {AST_OPTION_SECURE_SIGNALING, 0},
05543       {AST_OPTION_SECURE_MEDIA, 0},
05544    };
05545    int i;
05546    struct ast_channel *r = (struct ast_channel *) requestor; /* UGLY */
05547    struct ast_datastore *ds;
05548 
05549    if (!requestor || !out) {
05550       return 0;
05551    }
05552 
05553    ast_channel_lock(r);
05554    if ((ds = ast_channel_datastore_find(r, &secure_call_info, NULL))) {
05555       struct ast_secure_call_store *encrypt = ds->data;
05556       ops[0][1] = encrypt->signaling;
05557       ops[1][1] = encrypt->media;
05558    } else {
05559       ast_channel_unlock(r);
05560       return 0;
05561    }
05562    ast_channel_unlock(r);
05563 
05564    for (i = 0; i < 2; i++) {
05565       if (ops[i][1]) {
05566          if (ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0)) {
05567             /* We require a security feature, but the channel won't provide it */
05568             return -1;
05569          }
05570       } else {
05571          /* We don't care if we can't clear the option on a channel that doesn't support it */
05572          ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0);
05573       }
05574    }
05575 
05576    return 0;
05577 }

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 3710 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(), chanlist::chan, and ast_channel::dtmf_tv.

Referenced by __ast_read().

03711 {
03712    if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF)) {
03713       /* We're in the middle of emulating a digit, or DTMF has been
03714        * explicitly deferred.  Skip this digit, then. */
03715       return 1;
03716    }
03717          
03718    if (!ast_tvzero(chan->dtmf_tv) && 
03719          ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) {
03720       /* We're not in the middle of a digit, but it hasn't been long enough
03721        * since the last digit, so we'll have to skip DTMF for now. */
03722       return 1;
03723    }
03724 
03725    return 0;
03726 }

static void* silence_generator_alloc ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 8070 of file channel.c.

08071 {
08072    /* just store the data pointer in the channel structure */
08073    return data;
08074 }

static int silence_generator_generate ( struct ast_channel chan,
void *  data,
int  len,
int  samples 
) [static]

Definition at line 8081 of file channel.c.

References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_write(), and ast_frame::frametype.

08082 {
08083    short buf[samples];
08084    struct ast_frame frame = {
08085       .frametype = AST_FRAME_VOICE,
08086       .subclass.codec = AST_FORMAT_SLINEAR,
08087       .data.ptr = buf,
08088       .samples = samples,
08089       .datalen = sizeof(buf),
08090    };
08091 
08092    memset(buf, 0, sizeof(buf));
08093 
08094    if (ast_write(chan, &frame))
08095       return -1;
08096 
08097    return 0;
08098 }

static void silence_generator_release ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 8076 of file channel.c.

08077 {
08078    /* nothing to do */
08079 }

static void* tonepair_alloc ( struct ast_channel chan,
void *  params 
) [static]

Definition at line 7682 of file channel.c.

References ast_calloc, AST_FLAG_WRITE_INT, AST_FORMAT_SLINEAR, ast_log(), ast_set_flag, ast_set_write_format(), chanlist::chan, cos, tonepair_def::duration, tonepair_def::freq1, tonepair_def::freq2, LOG_WARNING, M_PI, ast_channel::name, tonepair_release(), tonepair_def::vol, and ast_channel::writeformat.

07683 {
07684    struct tonepair_state *ts;
07685    struct tonepair_def *td = params;
07686 
07687    if (!(ts = ast_calloc(1, sizeof(*ts))))
07688       return NULL;
07689    ts->origwfmt = chan->writeformat;
07690    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
07691       ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
07692       tonepair_release(NULL, ts);
07693       ts = NULL;
07694    } else {
07695       ts->fac1 = 2.0 * cos(2.0 * M_PI * (td->freq1 / 8000.0)) * 32768.0;
07696       ts->v1_1 = 0;
07697       ts->v2_1 = sin(-4.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
07698       ts->v3_1 = sin(-2.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
07699       ts->v2_1 = 0;
07700       ts->fac2 = 2.0 * cos(2.0 * M_PI * (td->freq2 / 8000.0)) * 32768.0;
07701       ts->v2_2 = sin(-4.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
07702       ts->v3_2 = sin(-2.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
07703       ts->duration = td->duration;
07704       ts->modulate = 0;
07705    }
07706    /* Let interrupts interrupt :) */
07707    ast_set_flag(chan, AST_FLAG_WRITE_INT);
07708    return ts;
07709 }

static int tonepair_generator ( struct ast_channel chan,
void *  data,
int  len,
int  samples 
) [static]

Definition at line 7711 of file channel.c.

References ast_log(), tonepair_state::data, tonepair_state::f, tonepair_state::fac1, tonepair_state::fac2, LOG_WARNING, tonepair_state::modulate, 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.

07712 {
07713    struct tonepair_state *ts = data;
07714    int x;
07715 
07716    /* we need to prepare a frame with 16 * timelen samples as we're
07717     * generating SLIN audio
07718     */
07719    len = samples * 2;
07720 
07721    if (len > sizeof(ts->data) / 2 - 1) {
07722       ast_log(LOG_WARNING, "Can't generate that much data!\n");
07723       return -1;
07724    }
07725    memset(&ts->f, 0, sizeof(ts->f));
07726    for (x=0;x<len/2;x++) {
07727       ts->v1_1 = ts->v2_1;
07728       ts->v2_1 = ts->v3_1;
07729       ts->v3_1 = (ts->fac1 * ts->v2_1 >> 15) - ts->v1_1;
07730       
07731       ts->v1_2 = ts->v2_2;
07732       ts->v2_2 = ts->v3_2;
07733       ts->v3_2 = (ts->fac2 * ts->v2_2 >> 15) - ts->v1_2;
07734       if (ts->modulate) {
07735          int p;
07736          p = ts->v3_2 - 32768;
07737          if (p < 0) p = -p;
07738          p = ((p * 9) / 10) + 1;
07739          ts->data[x] = (ts->v3_1 * p) >> 15;
07740       } else
07741          ts->data[x] = ts->v3_1 + ts->v3_2; 
07742    }
07743    ts->f.frametype = AST_FRAME_VOICE;
07744    ts->f.subclass.codec = AST_FORMAT_SLINEAR;
07745    ts->f.datalen = len;
07746    ts->f.samples = samples;
07747    ts->f.offset = AST_FRIENDLY_OFFSET;
07748    ts->f.data.ptr = ts->data;
07749    ast_write(chan, &ts->f);
07750    ts->pos += x;
07751    if (ts->duration > 0) {
07752       if (ts->pos >= ts->duration * 8)
07753          return -1;
07754    }
07755    return 0;
07756 }

static void tonepair_release ( struct ast_channel chan,
void *  params 
) [static]

Definition at line 7673 of file channel.c.

References ast_free, ast_set_write_format(), chanlist::chan, and tonepair_state::origwfmt.

Referenced by tonepair_alloc().

07674 {
07675    struct tonepair_state *ts = params;
07676 
07677    if (chan)
07678       ast_set_write_format(chan, ts->origwfmt);
07679    ast_free(ts);
07680 }

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

Definition at line 7272 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_strdupa, ast_strlen_zero(), ast_channel_tech::get_pvt_uniqueid, ast_channel::name, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and ast_channel::tech.

Referenced by ast_channel_bridge().

07273 {
07274    const char *c0_name;
07275    const char *c1_name;
07276    const char *c0_pvtid = NULL;
07277    const char *c1_pvtid = NULL;
07278 
07279    ast_channel_lock(c1);
07280    c1_name = ast_strdupa(c1->name);
07281    if (c1->tech->get_pvt_uniqueid) {
07282       c1_pvtid = ast_strdupa(c1->tech->get_pvt_uniqueid(c1));
07283    }
07284    ast_channel_unlock(c1);
07285 
07286    ast_channel_lock(c0);
07287    if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER"))) {
07288       pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1_name);
07289    }
07290    if (c1_pvtid) {
07291       pbx_builtin_setvar_helper(c0, "BRIDGEPVTCALLID", c1_pvtid);
07292    }
07293    c0_name = ast_strdupa(c0->name);
07294    if (c0->tech->get_pvt_uniqueid) {
07295       c0_pvtid = ast_strdupa(c0->tech->get_pvt_uniqueid(c0));
07296    }
07297    ast_channel_unlock(c0);
07298 
07299    ast_channel_lock(c1);
07300    if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER"))) {
07301       pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0_name);
07302    }
07303    if (c0_pvtid) {
07304       pbx_builtin_setvar_helper(c1, "BRIDGEPVTCALLID", c0_pvtid);
07305    }
07306    ast_channel_unlock(c1);
07307 }

static void xfer_ds_destroy ( void *  data  )  [static]

Definition at line 6054 of file channel.c.

References ast_free, ast_party_connected_line_free(), xfer_masquerade_ds::target_id, and xfer_masquerade_ds::transferee_id.

06055 {
06056    struct xfer_masquerade_ds *ds = data;
06057 
06058    ast_party_connected_line_free(&ds->target_id);
06059    ast_party_connected_line_free(&ds->transferee_id);
06060    ast_free(ds);
06061 }


Variable Documentation

struct ast_channel_tech ast_kill_tech

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

Referenced by ast_do_masquerade().

void(*) ast_moh_cleanup_ptr(struct ast_channel *) = NULL [static]

Definition at line 7834 of file channel.c.

Referenced by ast_install_music_functions(), ast_moh_cleanup(), and ast_uninstall_music_functions().

int(*) ast_moh_start_ptr(struct ast_channel *, const char *, const char *) = NULL [static]

Definition at line 7832 of file channel.c.

Referenced by ast_install_music_functions(), ast_moh_start(), and ast_uninstall_music_functions().

void(*) ast_moh_stop_ptr(struct ast_channel *) = NULL [static]

Definition at line 7833 of file channel.c.

Referenced by ast_install_music_functions(), ast_moh_stop(), and ast_uninstall_music_functions().

int cause

Definition at line 202 of file channel.c.

Referenced by __ast_read(), __ast_request_and_dial(), action_hangup(), ast_call_forward(), cb_events(), dial_exec_full(), dial_transfer(), do_forward(), dump_cause(), feature_request_and_dial(), oh323_hangup(), ospfinished_exec(), ospnext_exec(), parse_disconnect(), parse_release(), parse_release_complete(), parse_status(), pbx_builtin_hangup(), play_sound_file(), sig_pri_hangup(), sms_messagerx(), and sms_messagerx2().

struct { ... } causes[] [static]

map AST_CAUSE's to readable string representations

causes.h

Referenced by ast_cause2str(), ast_str2cause(), and dump_cause().

const struct ast_datastore_info cc_channel_datastore_info [static]

Initial value:

 {
   .type = "Call Completion",
   .duplicate = channel_cc_params_copy,
   .destroy = channel_cc_params_destroy,
}

Definition at line 9503 of file channel.c.

Referenced by ast_channel_cc_params_init(), and ast_channel_get_cc_config_params().

int chancount [static]

Definition at line 100 of file channel.c.

Referenced by generic_fax_exec().

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

Referenced by ast_channels_init().

struct ao2_container* channels [static]

All active channels on the system.

Definition at line 195 of file channel.c.

struct ast_data_handler channels_provider [static]

Initial value:

Definition at line 8005 of file channel.c.

struct ast_data_handler channeltypes_provider [static]

Initial value:

Definition at line 8014 of file channel.c.

struct ast_cli_entry cli_channel[] [static]

Initial value:

 {
   { .handler =  handle_cli_core_show_channeltypes , .summary =  "List available channel types" ,__VA_ARGS__ },
   { .handler =  handle_cli_core_show_channeltype , .summary =  "Give more details on that channel type" ,__VA_ARGS__ }
}

Definition at line 614 of file channel.c.

Referenced by ast_channels_init().

const char* desc

Definition at line 204 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 102 of file channel.c.

Referenced by handle_core_set_debug_channel().

unsigned long global_fout

Definition at line 102 of file channel.c.

Referenced by handle_core_set_debug_channel().

const char* name

Definition at line 203 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 1109 of file channel.c.

Referenced by __ast_channel_alloc_ap(), and do_notify().

struct ast_datastore_info plc_ds_info [static]

Initial value:

 {
   .type = "plc",
   .destroy = plc_ds_destroy,
}

Definition at line 4717 of file channel.c.

Referenced by apply_plc().

int shutting_down [static]

Prevent new channel allocation if shutting down.

Definition at line 97 of file channel.c.

struct ast_generator silence_generator [static]

Initial value:

Definition at line 8100 of file channel.c.

Referenced by ast_channel_start_silence_generator().

struct ast_threadstorage state2str_threadbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_state2str_threadbuf , .custom_init = NULL , } [static]

Definition at line 104 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 7758 of file channel.c.

Referenced by ast_tonepair_start().

int uniqueint [static]

Definition at line 99 of file channel.c.

const struct ast_datastore_info xfer_ds_info [static]

Initial value:

 {
   .type = "xfer_colp",
   .destroy = xfer_ds_destroy,
}

Definition at line 6063 of file channel.c.

Referenced by ast_channel_transfer_masquerade(), and ast_do_masquerade().


Generated on Mon Oct 8 12:39:20 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7