Sat Mar 10 01:55:14 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 struct ast_datastore_info *info, const char *uid)
 Create a channel data store object.
ast_datastoreast_channel_datastore_find (struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
 Find a datastore on a channel.
int ast_channel_datastore_free (struct ast_datastore *datastore)
 Free a channel data store object.
int ast_channel_datastore_inherit (struct ast_channel *from, struct ast_channel *to)
 Inherit datastores from a parent to a child.
int ast_channel_datastore_remove (struct ast_channel *chan, struct ast_datastore *datastore)
 Remove a datastore from a channel.
int ast_channel_defer_dtmf (struct ast_channel *chan)
 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.
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 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 struct ast_datastore_info cc_channel_datastore_info
static struct ast_data_entry channel_providers []
static struct ao2_containerchannels
 All active channels on the system.
static struct ast_data_handler channels_provider
static struct ast_data_handler channeltypes_provider
static struct ast_cli_entry cli_channel []
unsigned long global_fin
unsigned long global_fout
static struct ast_channel_tech null_tech
static struct ast_datastore_info plc_ds_info
static int shutting_down
 Prevent new channel allocation if shutting down.
static struct ast_generator silence_generator
static struct ast_threadstorage state2str_threadbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_state2str_threadbuf , .custom_init = NULL , }
static struct ast_generator tonepair
static int uniqueint
static struct ast_datastore_info xfer_ds_info


Detailed Description

Channel Management.

Author:
Mark Spencer <markster@digium.com>

Definition in file channel.c.


Define Documentation

#define AST_DEFAULT_EMULATE_DTMF_DURATION   100

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

Definition at line 104 of file channel.c.

Referenced by __ast_read(), and ast_senddigit().

#define AST_MIN_DTMF_DURATION   80

Minimum allowed digit length - 80ms

Definition at line 107 of file channel.c.

Referenced by __ast_read().

#define AST_MIN_DTMF_GAP   45

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

Definition at line 111 of file channel.c.

Referenced by __ast_read(), and should_skip_dtmf().

#define DATA_EXPORT_CHANNEL ( MEMBER   ) 

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

Referenced by ast_channels_init().

#define STATE2STR_BUFSIZE   32

Definition at line 100 of file channel.c.

Referenced by ast_state2str().


Enumeration Type Documentation

anonymous enum

Element identifiers for connected line indication frame data.

Note:
Only add to the end of this enum.
Enumerator:
AST_CONNECTED_LINE_NUMBER 
AST_CONNECTED_LINE_NAME 
AST_CONNECTED_LINE_NUMBER_PLAN 
AST_CONNECTED_LINE_ID_PRESENTATION 
AST_CONNECTED_LINE_SOURCE 
AST_CONNECTED_LINE_SUBADDRESS 
AST_CONNECTED_LINE_SUBADDRESS_TYPE 
AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN 
AST_CONNECTED_LINE_SUBADDRESS_VALID 
AST_CONNECTED_LINE_TAG 
AST_CONNECTED_LINE_VERSION 
AST_CONNECTED_LINE_NAME_VALID 
AST_CONNECTED_LINE_NAME_CHAR_SET 
AST_CONNECTED_LINE_NAME_PRESENTATION 
AST_CONNECTED_LINE_NUMBER_VALID 
AST_CONNECTED_LINE_NUMBER_PRESENTATION 

Definition at line 8510 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 8831 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 2923 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().

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

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

06073 {
06074    ast_manager_event(chan, EVENT_FLAG_CALL, "Rename", "Channel: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", chan->name, newname, chan->uniqueid);
06075    ast_string_field_set(chan, name, newname);
06076 }

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

References __ast_channel_alloc_ap().

01350 {
01351    va_list ap1, ap2;
01352    struct ast_channel *result;
01353 
01354    va_start(ap1, name_fmt);
01355    va_start(ap2, name_fmt);
01356    result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context,
01357                linkedid, amaflag, file, line, function, name_fmt, ap1, ap2);
01358    va_end(ap1);
01359    va_end(ap2);
01360 
01361    return result;
01362 }

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

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

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

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

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

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

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

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

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

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

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

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

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

static void __init_state2str_threadbuf ( void   )  [static]

Definition at line 99 of file channel.c.

00114 {

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

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

04689 {
04690    int num_new_samples = frame->samples;
04691    struct plc_ds *plc = datastore->data;
04692 
04693    /* As a general note, let me explain the somewhat odd calculations used when taking
04694     * the frame offset into account here. According to documentation in frame.h, the frame's
04695     * offset field indicates the number of bytes that the audio is offset. The plc->samples_buf
04696     * is not an array of bytes, but rather an array of 16-bit integers since it holds SLIN
04697     * samples. So I had two choices to make here with the offset.
04698     * 
04699     * 1. Make the offset AST_FRIENDLY_OFFSET bytes. The main downside for this is that
04700     *    I can't just add AST_FRIENDLY_OFFSET to the plc->samples_buf and have the pointer
04701     *    arithmetic come out right. I would have to do some odd casting or division for this to
04702     *    work as I wanted.
04703     * 2. Make the offset AST_FRIENDLY_OFFSET * 2 bytes. This allows the pointer arithmetic
04704     *    to work out better with the plc->samples_buf. The downside here is that the buffer's
04705     *    allocation contains an extra 64 bytes of unused space.
04706     * 
04707     * I decided to go with option 2. This is why in the calloc statement and the statement that
04708     * sets the frame's offset, AST_FRIENDLY_OFFSET is multiplied by 2.
04709     */
04710 
04711    /* If this audio frame has no samples to fill in, ignore it */
04712    if (!num_new_samples) {
04713       return;
04714    }
04715 
04716    /* First, we need to be sure that our buffer is large enough to accomodate
04717     * the samples we need to fill in. This will likely only occur on the first
04718     * frame we write.
04719     */
04720    if (plc->num_samples < num_new_samples) {
04721       ast_free(plc->samples_buf);
04722       plc->samples_buf = ast_calloc(1, (num_new_samples * sizeof(*plc->samples_buf)) + (AST_FRIENDLY_OFFSET * 2));
04723       if (!plc->samples_buf) {
04724          ast_channel_datastore_remove(chan, datastore);
04725          ast_datastore_free(datastore);
04726          return;
04727       }
04728       plc->num_samples = num_new_samples;
04729    }
04730 
04731    if (frame->datalen == 0) {
04732       plc_fillin(&plc->plc_state, plc->samples_buf + AST_FRIENDLY_OFFSET, frame->samples);
04733       frame->data.ptr = plc->samples_buf + AST_FRIENDLY_OFFSET;
04734       frame->datalen = num_new_samples * 2;
04735       frame->offset = AST_FRIENDLY_OFFSET * 2;
04736    } else {
04737       plc_rx(&plc->plc_state, frame->data.ptr, frame->samples);
04738    }
04739 }

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

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

04742 {
04743    struct ast_datastore *datastore;
04744    struct plc_ds *plc;
04745 
04746    datastore = ast_channel_datastore_find(chan, &plc_ds_info, NULL);
04747    if (datastore) {
04748       plc = datastore->data;
04749       adjust_frame_for_plc(chan, frame, datastore);
04750       return;
04751    }
04752 
04753    datastore = ast_datastore_alloc(&plc_ds_info, NULL);
04754    if (!datastore) {
04755       return;
04756    }
04757    plc = ast_calloc(1, sizeof(*plc));
04758    if (!plc) {
04759       ast_datastore_free(datastore);
04760       return;
04761    }
04762    datastore->data = plc;
04763    ast_channel_datastore_add(chan, datastore);
04764    adjust_frame_for_plc(chan, frame, datastore);
04765 }

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

Activate a given generator

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

03075 {
03076    int res = 0;
03077 
03078    ast_channel_lock(chan);
03079    if (chan->generatordata) {
03080       if (chan->generator && chan->generator->release)
03081          chan->generator->release(chan, chan->generatordata);
03082       chan->generatordata = NULL;
03083    }
03084    if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) {
03085       res = -1;
03086    }
03087    if (!res) {
03088       ast_settimeout(chan, 50, generator_force, chan);
03089       chan->generator = gen;
03090    }
03091    ast_channel_unlock(chan);
03092 
03093    ast_prod(chan);
03094 
03095    return res;
03096 }

int ast_active_channels ( void   ) 

returns number of active/allocated channels

Returns:
number of active/allocated channels

Definition at line 832 of file channel.c.

References ao2_container_count(), and channels.

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

00833 {
00834    return channels ? ao2_container_count(channels) : 0;
00835 }

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 3024 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(), rpt_exec(), sayunixtime_exec(), send_waveform_to_channel(), sendfax_exec(), setup_privacy_args(), skel_exec(), sla_station_exec(), speech_background(), testclient_exec(), testserver_exec(), transmit(), vm_exec(), vm_execmain(), waitfor_exec(), and zapateller_exec().

03025 {
03026    return __ast_answer(chan, 0, 1);
03027 }

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

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

Referenced by can_safely_quit().

00823 {
00824    shutting_down = 1;
00825 
00826    if (hangup) {
00827       ao2_callback(channels, OBJ_NODATA | OBJ_MULTIPLE, ast_channel_softhangup_cb, NULL);
00828    }
00829 }

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

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

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 6920 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(), sig_pri_handle_hold(), sip_hangup(), sip_set_rtp_peer(), skinny_transfer(), socket_process(), start_spying(), startmon(), TransferCallStep1(), and unistim_hangup().

06921 {
06922    struct ast_channel *bridged;
06923    bridged = chan->_bridge;
06924    if (bridged && bridged->tech->bridged_channel)
06925       bridged = bridged->tech->bridged_channel(chan, bridged);
06926    return bridged;
06927 }

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

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

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

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

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

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

void ast_cancel_shutdown ( void   ) 

Cancel a shutdown in progress.

Cancels an existing shutdown and returns to normal operation

Definition at line 838 of file channel.c.

Referenced by handle_abort_shutdown().

00839 {
00840    shutting_down = 0;
00841 }

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

00960 {
00961    int x;
00962 
00963    for (x = 0; x < ARRAY_LEN(causes); x++) {
00964       if (causes[x].cause == cause)
00965          return causes[x].desc;
00966    }
00967 
00968    return "Unknown";
00969 }

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

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

Referenced by update_name().

06079 {
06080    /* We must re-link, as the hash value will change here. */
06081    ao2_unlink(channels, chan);
06082    ast_channel_lock(chan);
06083    __ast_change_name_nolink(chan, newname);
06084    ast_channel_unlock(chan);
06085    ao2_link(channels, chan);
06086 }

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

References __ast_channel_alloc_ap().

09523 {
09524    va_list ap1, ap2;
09525    struct ast_channel *result;
09526 
09527 
09528    va_start(ap1, name_fmt);
09529    va_start(ap2, name_fmt);
09530    result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context,
09531                linkedid, amaflag, __FILE__, __LINE__, __FUNCTION__, name_fmt, ap1, ap2);
09532    va_end(ap1);
09533    va_end(ap2);
09534 
09535    return result;
09536 }

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

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

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

References ao2_callback_data, and channels.

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

01597 {
01598    return ao2_callback_data(channels, ao2_flags, cb_fn, arg, data);
01599 }

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

09426 {
09427    struct ast_cc_config_params *cc_params;
09428    struct ast_datastore *cc_datastore;
09429 
09430    if (!(cc_params = ast_cc_config_params_init())) {
09431       return -1;
09432    }
09433 
09434    if (!(cc_datastore = ast_datastore_alloc(&cc_channel_datastore_info, NULL))) {
09435       ast_cc_config_params_destroy(cc_params);
09436       return -1;
09437    }
09438 
09439    if (base_params) {
09440       ast_cc_copy_config_params(cc_params, base_params);
09441    }
09442    cc_datastore->data = cc_params;
09443    ast_channel_datastore_add(chan, cc_datastore);
09444    return 0;
09445 }

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

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

Referenced by ast_channel_set_linkgroup().

06218 {
06219    /* if the linkedid for this channel is being changed from something, check... */
06220    if (!ast_strlen_zero(chan->linkedid) && 0 != strcmp(chan->linkedid, linkedid)) {
06221       ast_cel_check_retire_linkedid(chan);
06222    }
06223 
06224    ast_string_field_set(chan, linkedid, linkedid);
06225 }

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

02653 {
02654    ast_channel_lock(chan);
02655 
02656    chan->_softhangup &= ~flag;
02657 
02658    if (!chan->_softhangup) {
02659       struct ast_frame *fr;
02660 
02661       /* If we have completely cleared the softhangup flag,
02662        * then we need to fully abort the hangup process.  This requires
02663        * pulling the END_OF_Q frame out of the channel frame queue if it
02664        * still happens to be there. */
02665 
02666       fr = AST_LIST_LAST(&chan->readq);
02667       if (fr && fr->frametype == AST_FRAME_CONTROL &&
02668             fr->subclass.integer == AST_CONTROL_END_OF_Q) {
02669          AST_LIST_REMOVE(&chan->readq, fr, frame_list);
02670          ast_frfree(fr);
02671       }
02672    }
02673 
02674    ast_channel_unlock(chan);
02675 }

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

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

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

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

References ast_channel_cmpwhentohangup_tv(), and chanlist::chan.

00880 {
00881    struct timeval when = { offset, };
00882    return ast_channel_cmpwhentohangup_tv(chan, when);
00883 }

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

00865 {
00866    struct timeval whentohangup;
00867 
00868    if (ast_tvzero(chan->whentohangup))
00869       return ast_tvzero(offset) ? 0 : -1;
00870 
00871    if (ast_tvzero(offset))
00872       return 1;
00873 
00874    whentohangup = ast_tvadd(offset, ast_tvnow());
00875 
00876    return ast_tvdiff_ms(whentohangup, chan->whentohangup);
00877 }

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

References ast_app_run_macro(), ast_channel_lock, ast_channel_unlock, ast_channel_update_connected_line(), ast_connected_line_parse_data(), ast_party_connected_line_copy(), ast_strdupa, ast_strlen_zero(), 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().

09323 {
09324    const char *macro;
09325    const char *macro_args;
09326    int retval;
09327 
09328    ast_channel_lock(macro_chan);
09329    macro = pbx_builtin_getvar_helper(macro_chan, is_caller
09330       ? "CONNECTED_LINE_CALLER_SEND_MACRO" : "CONNECTED_LINE_CALLEE_SEND_MACRO");
09331    macro = ast_strdupa(S_OR(macro, ""));
09332    macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller
09333       ? "CONNECTED_LINE_CALLER_SEND_MACRO_ARGS" : "CONNECTED_LINE_CALLEE_SEND_MACRO_ARGS");
09334    macro_args = ast_strdupa(S_OR(macro_args, ""));
09335 
09336    if (ast_strlen_zero(macro)) {
09337       ast_channel_unlock(macro_chan);
09338       return -1;
09339    }
09340 
09341    if (is_frame) {
09342       const struct ast_frame *frame = connected_info;
09343 
09344       ast_connected_line_parse_data(frame->data.ptr, frame->datalen, &macro_chan->connected);
09345    } else {
09346       const struct ast_party_connected_line *connected = connected_info;
09347 
09348       ast_party_connected_line_copy(&macro_chan->connected, connected);
09349    }
09350    ast_channel_unlock(macro_chan);
09351 
09352    if (!(retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args))) {
09353       ast_channel_lock(macro_chan);
09354       ast_channel_update_connected_line(macro_chan, &macro_chan->connected, NULL);
09355       ast_channel_unlock(macro_chan);
09356    }
09357 
09358    return retval;
09359 }

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

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

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

References ast_data_search_cmp_structure, and chanlist::chan.

00476 {
00477    return ast_data_search_cmp_structure(tree, ast_channel, chan, structure_name);
00478 }

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 2535 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_datastores(), add_to_agi(), apply_plc(), 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(), 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().

02536 {
02537    int res = 0;
02538 
02539    AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry);
02540 
02541    return res;
02542 }

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

Create a channel data store object.

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

Definition at line 2508 of file channel.c.

References ast_datastore_alloc, and ast_datastore::info.

02509 {
02510    return ast_datastore_alloc(info, uid);
02511 }

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

Find a datastore on a channel.

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

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

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

Definition at line 2549 of file channel.c.

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

Referenced by _macro_exec(), acf_curl_helper(), acf_curlopt_helper(), acf_curlopt_write(), acf_exception_read(), acf_fetch(), acf_iaxvar_read(), acf_iaxvar_write(), add_agi_cmd(), add_features_datastores(), add_to_agi(), apply_plc(), ast_can_pickup(), ast_cc_agent_set_interfaces_chanvar(), ast_cc_call_init(), ast_cc_completed(), ast_cc_extension_monitor_add_dialstring(), ast_cc_get_current_core_id(), ast_cc_is_recall(), ast_cc_offer(), ast_channel_get_cc_config_params(), ast_do_masquerade(), ast_handle_cc_control_frame(), ast_ignore_cc(), ast_odbc_retrieve_transaction_obj(), ast_set_cc_interfaces_chanvar(), attended_transfer_occurred(), audiohook_volume_callback(), audiohook_volume_get(), builtin_atxfer(), calendar_event_read(), calendar_query_exec(), calendar_query_result_exec(), cc_build_payload(), clear_dialed_interfaces(), dial_exec_full(), disable_jack_hook(), dundi_result_read(), enable_jack_hook(), enum_result_read(), exec_odbcfinish(), find_details(), find_speech(), find_transaction(), frame_trace_helper(), func_channel_read(), func_channel_write_real(), func_inheritance_write(), func_mute_write(), get_agi_cmd(), get_lock(), gosub_exec(), handle_gosub(), iax2_call(), jack_hook_callback(), local_read(), local_write(), lock_fixup(), lua_get_state(), manage_parked_call(), manager_mutestream(), mark_transaction_active(), mute_callback(), parked_call_exec(), pitchshift_cb(), pitchshift_helper(), pop_exec(), queue_transfer_fixup(), raise_exception(), release_transaction(), return_exec(), set_security_requirements(), shared_read(), shared_write(), smdi_msg_read(), speech_background(), speech_destroy(), speex_callback(), speex_read(), speex_write(), srv_query_read(), srv_result_read(), stop_mixmonitor_exec(), try_calling(), unlock_read(), volume_callback(), and volume_write().

02550 {
02551    struct ast_datastore *datastore = NULL;
02552    
02553    if (info == NULL)
02554       return NULL;
02555 
02556    AST_LIST_TRAVERSE(&chan->datastores, datastore, entry) {
02557       if (datastore->info != info) {
02558          continue;
02559       }
02560 
02561       if (uid == NULL) {
02562          /* matched by type only */
02563          break;
02564       }
02565 
02566       if ((datastore->uid != NULL) && !strcasecmp(uid, datastore->uid)) {
02567          /* Matched by type AND uid */
02568          break;
02569       }
02570    }
02571 
02572    return datastore;
02573 }

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

References ast_datastore_free().

02514 {
02515    return ast_datastore_free(datastore);
02516 }

int ast_channel_datastore_inherit ( struct ast_channel from,
struct ast_channel to 
)

Inherit datastores from a parent to a child.

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

02519 {
02520    struct ast_datastore *datastore = NULL, *datastore2;
02521 
02522    AST_LIST_TRAVERSE(&from->datastores, datastore, entry) {
02523       if (datastore->inheritance > 0) {
02524          datastore2 = ast_datastore_alloc(datastore->info, datastore->uid);
02525          if (datastore2) {
02526             datastore2->data = datastore->info->duplicate ? datastore->info->duplicate(datastore->data) : NULL;
02527             datastore2->inheritance = datastore->inheritance == DATASTORE_INHERIT_FOREVER ? DATASTORE_INHERIT_FOREVER : datastore->inheritance - 1;
02528             AST_LIST_INSERT_TAIL(&to->datastores, datastore2, entry);
02529          }
02530       }
02531    }
02532    return 0;
02533 }

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

02545 {
02546    return AST_LIST_REMOVE(&chan->datastores, datastore, entry) ? 0 : -1;
02547 }

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

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

Referenced by find_cache().

01578 {
01579    int pre = 0;
01580 
01581    if (chan) {
01582       pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF);
01583       ast_set_flag(chan, AST_FLAG_DEFER_DTMF);
01584    }
01585    return pre;
01586 }

static void ast_channel_destructor ( void *  obj  )  [static]

Free a channel structure.

Definition at line 2357 of file channel.c.

References ast_channel::alertpipe, ast_app_group_discard(), ast_cdr_discard(), AST_CEL_CHANNEL_END, ast_cel_check_retire_linkedid(), ast_cel_report_event(), ast_channel_lock, AST_CHANNEL_NAME, ast_channel_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().

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

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

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

Referenced by dial_exec_full().

07164 {
07165    /* Make sure we can early bridge, if not error out */
07166    if (!c0->tech->early_bridge || (c1 && (!c1->tech->early_bridge || c0->tech->early_bridge != c1->tech->early_bridge)))
07167       return -1;
07168 
07169    return c0->tech->early_bridge(c0, c1);
07170 }

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

References ast_channel_get_full().

01775 {
01776    return ast_channel_get_full(NULL, 0, exten, context);
01777 }

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

01765 {
01766    return ast_channel_get_full(name, 0, NULL, NULL);
01767 }

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

01770 {
01771    return ast_channel_get_full(name, name_len, NULL, NULL);
01772 }

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

09487 {
09488    int len = size;
09489    char *slash;
09490 
09491    if (!ast_channel_queryoption(chan, AST_OPTION_CC_AGENT_TYPE, agent_type, &len, 0)) {
09492       return 0;
09493    }
09494 
09495    ast_copy_string(agent_type, chan->name, size);
09496    if ((slash = strchr(agent_type, '/'))) {
09497       *slash = '\0';
09498    }
09499    return 0;
09500 }

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

09448 {
09449    struct ast_datastore *cc_datastore;
09450 
09451    if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) {
09452       /* If we can't find the datastore, it almost definitely means that the channel type being
09453        * used has not had its driver modified to parse CC config parameters. The best action
09454        * to take here is to create the parameters on the spot with the defaults set.
09455        */
09456       if (ast_channel_cc_params_init(chan, NULL)) {
09457          return NULL;
09458       }
09459       if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) {
09460          /* Should be impossible */
09461          return NULL;
09462       }
09463    }
09464 
09465    ast_assert(cc_datastore->data != NULL);
09466    return cc_datastore->data;
09467 }

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

09470 {
09471    int len = name_buffer_length;
09472    char *dash;
09473    if (!ast_channel_queryoption(chan, AST_OPTION_DEVICE_NAME, device_name, &len, 0)) {
09474       return 0;
09475    }
09476 
09477    /* Dang. Do it the old-fashioned way */
09478    ast_copy_string(device_name, chan->name, name_buffer_length);
09479    if ((dash = strrchr(device_name, '-'))) {
09480       *dash = '\0';
09481    }
09482 
09483    return 0;
09484 }

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

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

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

Definition at line 7802 of file channel.c.

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

07803 {
07804    const struct ast_channel *chan = obj;
07805 
07806    /* If the name isn't set, return 0 so that the ao2_find() search will
07807     * start in the first bucket. */
07808    if (ast_strlen_zero(chan->name)) {
07809       return 0;
07810    }
07811 
07812    return ast_str_case_hash(chan->name);
07813 }

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

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

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

01663 {
01664    struct ast_channel_iterator *i;
01665 
01666    if (!(i = ast_calloc(1, sizeof(*i)))) {
01667       return NULL;
01668    }
01669 
01670    i->simple_iterator = ao2_iterator_init(channels, 0);
01671    i->active_iterator = &i->simple_iterator;
01672 
01673    return i;
01674 }

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

References channel_iterator_search().

Referenced by common_exec(), and pickup_by_exten().

01653 {
01654    return channel_iterator_search(NULL, 0, exten, context);
01655 }

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

References channel_iterator_search().

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

01658 {
01659    return channel_iterator_search(name, name_len, NULL, NULL);
01660 }

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

01611 {
01612    ao2_iterator_destroy(i->active_iterator);
01613    ast_free(i);
01614 
01615    return NULL;
01616 }

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

01677 {
01678    return ao2_iterator_next(i->active_iterator);
01679 }

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

05820 {
05821    /* Some callers do not check return code, and we must try to set all call legs correctly */
05822    int rc = 0;
05823 
05824    /* Set up translation from the chan to the peer */
05825    rc = ast_channel_make_compatible_helper(chan, peer);
05826 
05827    if (rc < 0)
05828       return rc;
05829 
05830    /* Set up translation from the peer to the chan */
05831    rc = ast_channel_make_compatible_helper(peer, chan);
05832 
05833    return rc;
05834 }

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

Set up translation from one channel to another.

Definition at line 5769 of file channel.c.

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

05770 {
05771    format_t src, dst;
05772    int use_slin;
05773 
05774    /* See if the channel driver can natively make these two channels compatible */
05775    if (from->tech->bridge && from->tech->bridge == to->tech->bridge &&
05776        !ast_channel_setoption(from, AST_OPTION_MAKE_COMPATIBLE, to, sizeof(struct ast_channel *), 0)) {
05777       return 0;
05778    }
05779 
05780    if (from->readformat == to->writeformat && from->writeformat == to->readformat) {
05781       /* Already compatible!  Moving on ... */
05782       return 0;
05783    }
05784 
05785    /* Set up translation from the 'from' channel to the 'to' channel */
05786    src = from->nativeformats;
05787    dst = to->nativeformats;
05788 
05789    /* If there's no audio in this call, don't bother with trying to find a translation path */
05790    if ((src & AST_FORMAT_AUDIO_MASK) == 0 || (dst & AST_FORMAT_AUDIO_MASK) == 0)
05791       return 0;
05792 
05793    if (ast_translator_best_choice(&dst, &src) < 0) {
05794       ast_log(LOG_WARNING, "No path to translate from %s to %s\n", from->name, to->name);
05795       return -1;
05796    }
05797 
05798    /* if the best path is not 'pass through', then
05799     * transcoding is needed; if desired, force transcode path
05800     * to use SLINEAR between channels, but only if there is
05801     * no direct conversion available. If generic PLC is
05802     * desired, then transcoding via SLINEAR is a requirement
05803     */
05804    use_slin = (src == AST_FORMAT_SLINEAR || dst == AST_FORMAT_SLINEAR);
05805    if ((src != dst) && (ast_opt_generic_plc || ast_opt_transcode_via_slin) &&
05806        (ast_translate_path_steps(dst, src) != 1 || use_slin))
05807       dst = AST_FORMAT_SLINEAR;
05808    if (ast_set_read_format(from, dst) < 0) {
05809       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %s\n", from->name, ast_getformatname(dst));
05810       return -1;
05811    }
05812    if (ast_set_write_format(to, dst) < 0) {
05813       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %s\n", to->name, ast_getformatname(dst));
05814       return -1;
05815    }
05816    return 0;
05817 }

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

05960 {
05961    return __ast_channel_masquerade(original, clone, NULL);
05962 }

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

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

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

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

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

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

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

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

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

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

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

09362 {
09363    const char *macro;
09364    const char *macro_args;
09365    int retval;
09366 
09367    ast_channel_lock(macro_chan);
09368    macro = pbx_builtin_getvar_helper(macro_chan, is_caller
09369       ? "REDIRECTING_CALLER_SEND_MACRO" : "REDIRECTING_CALLEE_SEND_MACRO");
09370    macro = ast_strdupa(S_OR(macro, ""));
09371    macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller
09372       ? "REDIRECTING_CALLER_SEND_MACRO_ARGS" : "REDIRECTING_CALLEE_SEND_MACRO_ARGS");
09373    macro_args = ast_strdupa(S_OR(macro_args, ""));
09374 
09375    if (ast_strlen_zero(macro)) {
09376       ast_channel_unlock(macro_chan);
09377       return -1;
09378    }
09379 
09380    if (is_frame) {
09381       const struct ast_frame *frame = redirecting_info;
09382 
09383       ast_redirecting_parse_data(frame->data.ptr, frame->datalen, &macro_chan->redirecting);
09384    } else {
09385       const struct ast_party_redirecting *redirecting = redirecting_info;
09386 
09387       ast_party_redirecting_copy(&macro_chan->redirecting, redirecting);
09388    }
09389    ast_channel_unlock(macro_chan);
09390 
09391    retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args);
09392    if (!retval) {
09393       ast_channel_lock(macro_chan);
09394       ast_channel_update_redirecting(macro_chan, &macro_chan->redirecting, NULL);
09395       ast_channel_unlock(macro_chan);
09396    }
09397 
09398    return retval;
09399 }

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

00887 {
00888    struct chanlist *chan;
00889 
00890    AST_RWLIST_WRLOCK(&backends);
00891 
00892    AST_RWLIST_TRAVERSE(&backends, chan, list) {
00893       if (!strcasecmp(tech->type, chan->tech->type)) {
00894          ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type);
00895          AST_RWLIST_UNLOCK(&backends);
00896          return -1;
00897       }
00898    }
00899    
00900    if (!(chan = ast_calloc(1, sizeof(*chan)))) {
00901       AST_RWLIST_UNLOCK(&backends);
00902       return -1;
00903    }
00904    chan->tech = tech;
00905    AST_RWLIST_INSERT_HEAD(&backends, chan, list);
00906 
00907    ast_debug(1, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description);
00908 
00909    ast_verb(2, "Registered channel type '%s' (%s)\n", chan->tech->type, chan->tech->description);
00910 
00911    AST_RWLIST_UNLOCK(&backends);
00912 
00913    return 0;
00914 }

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

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

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

01879 {
01880    /* Safe, even if already unlinked. */
01881    ao2_unlink(channels, chan);
01882    return ast_channel_unref(chan);
01883 }

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

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

Returns:
0 on success or -1 on failure

Definition at line 5756 of file channel.c.

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

Referenced by agent_sendhtml(), and ast_channel_sendurl().

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

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

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

Returns:
0 on success or -1 on failure

Definition at line 5763 of file channel.c.

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

Referenced by dial_exec_full(), and sendurl_exec().

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

void ast_channel_set_caller ( struct ast_channel chan,
const struct ast_party_caller caller,
const struct ast_set_party_caller update 
)

Set the caller id information in the Asterisk channel.

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

Definition at line 6839 of file channel.c.

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

06840 {
06841    if (&chan->caller == caller) {
06842       /* Don't set to self */
06843       return;
06844    }
06845 
06846    ast_channel_lock(chan);
06847    ast_party_caller_set(&chan->caller, caller, update);
06848    ast_channel_unlock(chan);
06849 }

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

06852 {
06853    const char *pre_set_number;
06854    const char *pre_set_name;
06855 
06856    if (&chan->caller == caller) {
06857       /* Don't set to self */
06858       return;
06859    }
06860 
06861    ast_channel_lock(chan);
06862    pre_set_number =
06863       S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL);
06864    pre_set_name = S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL);
06865    ast_party_caller_set(&chan->caller, caller, update);
06866    if (S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL)
06867          != pre_set_number
06868       || S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL)
06869          != pre_set_name) {
06870       /* The caller id name or number changed. */
06871       report_new_callerid(chan);
06872    }
06873    if (chan->cdr) {
06874       ast_cdr_setcid(chan->cdr, chan);
06875    }
06876    ast_channel_unlock(chan);
06877 }

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

08163 {
08164    if (&chan->connected == connected) {
08165       /* Don't set to self */
08166       return;
08167    }
08168 
08169    ast_channel_lock(chan);
08170    ast_party_connected_line_set(&chan->connected, connected, update);
08171    ast_channel_unlock(chan);
08172 }

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

Set the file descriptor on the channel

Definition at line 2576 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(), skinny_new(), start_rtp(), and swap_subs().

02577 {
02578 #ifdef HAVE_EPOLL
02579    struct epoll_event ev;
02580    struct ast_epoll_data *aed = NULL;
02581 
02582    if (chan->fds[which] > -1) {
02583       epoll_ctl(chan->epfd, EPOLL_CTL_DEL, chan->fds[which], &ev);
02584       aed = chan->epfd_data[which];
02585    }
02586 
02587    /* If this new fd is valid, add it to the epoll */
02588    if (fd > -1) {
02589       if (!aed && (!(aed = ast_calloc(1, sizeof(*aed)))))
02590          return;
02591       
02592       chan->epfd_data[which] = aed;
02593       aed->chan = chan;
02594       aed->which = which;
02595       
02596       ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP;
02597       ev.data.ptr = aed;
02598       epoll_ctl(chan->epfd, EPOLL_CTL_ADD, fd, &ev);
02599    } else if (aed) {
02600       /* We don't have to keep around this epoll data structure now */
02601       free(aed);
02602       chan->epfd_data[which] = NULL;
02603    }
02604 #endif
02605    chan->fds[which] = fd;
02606    return;
02607 }

void ast_channel_set_linkgroup ( struct ast_channel chan,
struct ast_channel peer 
)

propagate the linked id between chan and peer

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

06233 {
06234    const char* linkedid=NULL;
06235    struct ast_channel *bridged;
06236 
06237    linkedid = oldest_linkedid(chan->linkedid, peer->linkedid);
06238    linkedid = oldest_linkedid(linkedid, chan->uniqueid);
06239    linkedid = oldest_linkedid(linkedid, peer->uniqueid);
06240    if (chan->_bridge) {
06241       bridged = ast_bridged_channel(chan);
06242       if (bridged != peer) {
06243          linkedid = oldest_linkedid(linkedid, bridged->linkedid);
06244          linkedid = oldest_linkedid(linkedid, bridged->uniqueid);
06245       }
06246    }
06247    if (peer->_bridge) {
06248       bridged = ast_bridged_channel(peer);
06249       if (bridged != chan) {
06250          linkedid = oldest_linkedid(linkedid, bridged->linkedid);
06251          linkedid = oldest_linkedid(linkedid, bridged->uniqueid);
06252       }
06253    }
06254 
06255    /* just in case setting a stringfield to itself causes problems */
06256    linkedid = ast_strdupa(linkedid);
06257 
06258    ast_channel_change_linkedid(chan, linkedid);
06259    ast_channel_change_linkedid(peer, linkedid);
06260    if (chan->_bridge) {
06261       bridged = ast_bridged_channel(chan);
06262       if (bridged != peer) {
06263          ast_channel_change_linkedid(bridged, linkedid);
06264       }
06265    }
06266    if (peer->_bridge) {
06267       bridged = ast_bridged_channel(peer);
06268       if (bridged != chan) {
06269          ast_channel_change_linkedid(bridged, linkedid);
06270       }
06271    }
06272 }

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 8815 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(), do_forward(), handle_request_invite(), handle_response(), misdn_copy_redirecting_to_ast(), redirecting_write(), and sig_pri_handle_subcmds().

08816 {
08817    if (&chan->redirecting == redirecting) {
08818       /* Don't set to self */
08819       return;
08820    }
08821 
08822    ast_channel_lock(chan);
08823    ast_party_redirecting_set(&chan->redirecting, redirecting, update);
08824    ast_channel_unlock(chan);
08825 }

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 7534 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(), rpt(), rpt_exec(), set_format(), set_listen_volume(), set_security_requirements(), set_talk_volume(), sndfax_exec(), and vm_forwardoptions().

07535 {
07536    int res;
07537 
07538    ast_channel_lock(chan);
07539    if (!chan->tech->setoption) {
07540       errno = ENOSYS;
07541       ast_channel_unlock(chan);
07542       return -1;
07543    }
07544 
07545    if (block)
07546       ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
07547 
07548    res = chan->tech->setoption(chan, option, data, datalen);
07549    ast_channel_unlock(chan);
07550 
07551    return res;
07552 }

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

References ast_channel_setwhentohangup_tv(), and chanlist::chan.

00858 {
00859    struct timeval when = { offset, };
00860    ast_channel_setwhentohangup_tv(chan, when);
00861 }

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

00851 {
00852    chan->whentohangup = ast_tvzero(offset) ? offset : ast_tvadd(offset, ast_tvnow());
00853    ast_queue_frame(chan, &ast_null_frame);
00854    return;
00855 }

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

Definition at line 813 of file channel.c.

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

Referenced by ast_begin_shutdown().

00814 {
00815    struct ast_channel *chan = obj;
00816 
00817    ast_softhangup(chan, AST_SOFTHANGUP_SHUTDOWN);
00818 
00819    return 0;
00820 }

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

08037 {
08038    struct ast_silence_generator *state;
08039 
08040    if (!(state = ast_calloc(1, sizeof(*state)))) {
08041       return NULL;
08042    }
08043 
08044    state->old_write_format = chan->writeformat;
08045 
08046    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
08047       ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
08048       ast_free(state);
08049       return NULL;
08050    }
08051 
08052    ast_activate_generator(chan, &silence_generator, state);
08053 
08054    ast_debug(1, "Started silence generator on '%s'\n", chan->name);
08055 
08056    return state;
08057 }

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

08060 {
08061    if (!state)
08062       return;
08063 
08064    ast_deactivate_generator(chan);
08065 
08066    ast_debug(1, "Stopped silence generator on '%s'\n", chan->name);
08067 
08068    if (ast_set_write_format(chan, state->old_write_format) < 0)
08069       ast_log(LOG_ERROR, "Could not return write format to its original state\n");
08070 
08071    ast_free(state);
08072 }

int ast_channel_supports_html ( struct ast_channel channel  ) 

Checks for HTML support on a channel.

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

Definition at line 5751 of file channel.c.

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

Referenced by dial_exec_full(), and sendurl_exec().

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

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

Setup a masquerade to transfer a call.

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

Party B transfers A to C.

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

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

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

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

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

06040 {
06041    struct ast_datastore *xfer_ds;
06042    struct xfer_masquerade_ds *xfer_colp;
06043    int res;
06044 
06045    xfer_ds = ast_datastore_alloc(&xfer_ds_info, NULL);
06046    if (!xfer_ds) {
06047       return -1;
06048    }
06049 
06050    xfer_colp = ast_calloc(1, sizeof(*xfer_colp));
06051    if (!xfer_colp) {
06052       ast_datastore_free(xfer_ds);
06053       return -1;
06054    }
06055    party_connected_line_copy_transfer(&xfer_colp->target_id, target_id);
06056    xfer_colp->target_held = target_held;
06057    party_connected_line_copy_transfer(&xfer_colp->transferee_id, transferee_id);
06058    xfer_colp->transferee_held = transferee_held;
06059    xfer_ds->data = xfer_colp;
06060 
06061    res = __ast_channel_masquerade(target_chan, transferee_chan, xfer_ds);
06062    if (res) {
06063       ast_datastore_free(xfer_ds);
06064    }
06065    return res;
06066 }

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

References ast_clear_flag, AST_FLAG_DEFER_DTMF, and chanlist::chan.

Referenced by find_cache(), and rpt_call().

01590 {
01591    if (chan)
01592       ast_clear_flag(chan, AST_FLAG_DEFER_DTMF);
01593 }

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

00918 {
00919    struct chanlist *chan;
00920 
00921    ast_debug(1, "Unregistering channel type '%s'\n", tech->type);
00922 
00923    AST_RWLIST_WRLOCK(&backends);
00924 
00925    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) {
00926       if (chan->tech == tech) {
00927          AST_LIST_REMOVE_CURRENT(list);
00928          ast_free(chan);
00929          ast_verb(2, "Unregistered channel type '%s'\n", tech->type);
00930          break;   
00931       }
00932    }
00933    AST_LIST_TRAVERSE_SAFE_END;
00934 
00935    AST_RWLIST_UNLOCK(&backends);
00936 }

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

08790 {
08791    unsigned char data[1024];  /* This should be large enough */
08792    size_t datalen;
08793 
08794    datalen = ast_connected_line_build_data(data, sizeof(data), connected, update);
08795    if (datalen == (size_t) -1) {
08796       return;
08797    }
08798 
08799    ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen);
08800 }

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

09297 {
09298    unsigned char data[1024];  /* This should be large enough */
09299    size_t datalen;
09300 
09301    datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update);
09302    if (datalen == (size_t) -1) {
09303       return;
09304    }
09305 
09306    ast_indicate_data(chan, AST_CONTROL_REDIRECTING, data, datalen);
09307 }

void ast_channels_init ( void   ) 

Provided by channel.c

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

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

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 791 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(), rpt(), run_agi(), and run_ras().

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

int ast_check_hangup_locked ( struct ast_channel chan  ) 

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

00805 {
00806    int res;
00807    ast_channel_lock(chan);
00808    res = ast_check_hangup(chan);
00809    ast_channel_unlock(chan);
00810    return res;
00811 }

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

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

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

08148 {
08149    ast_party_id_copy(&dest->id, &src->id);
08150    ast_party_id_copy(&dest->ani, &src->ani);
08151    dest->ani2 = src->ani2;
08152 }

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

08155 {
08156    ast_party_id_copy(&dest->id, &src->id);
08157    ast_party_id_copy(&dest->ani, &src->ani);
08158 
08159    dest->ani2 = src->ani2;
08160 }

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

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

AST_DATA_STRUCTURE ( ast_channel  ,
DATA_EXPORT_CHANNEL   
)

void ast_deactivate_generator ( struct ast_channel chan  ) 

Deactivate an active generator

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

03030 {
03031    ast_channel_lock(chan);
03032    if (chan->generatordata) {
03033       if (chan->generator && chan->generator->release)
03034          chan->generator->release(chan, chan->generatordata);
03035       chan->generatordata = NULL;
03036       chan->generator = NULL;
03037       ast_channel_set_fd(chan, AST_GENERATOR_FD, -1);
03038       ast_clear_flag(chan, AST_FLAG_WRITE_INT);
03039       ast_settimeout(chan, 0, NULL, NULL);
03040    }
03041    ast_channel_unlock(chan);
03042 }

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.

Definition at line 6391 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_NAME, ast_channel_release(), ast_channel_set_fd(), ast_channel_set_linkgroup(), ast_channel_trylock, ast_channel_unlock, AST_CONTROL_SRCCHANGE, AST_CONTROL_UNHOLD, ast_copy_string(), ast_datastore_free(), ast_debug, AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, AST_GENERATOR_FD, ast_getformatname(), ast_indicate(), ast_kill_tech, AST_LIST_APPEND_LIST, AST_LIST_FIRST, AST_LIST_HEAD_NOLOCK, AST_LIST_HEAD_SET_NOLOCK, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), ast_manager_event, ast_manager_event_multichan, AST_MAX_FDS, ast_null_frame, ast_queue_frame(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_SOFTHANGUP_DEV, ast_state2str(), ast_string_field_set, ast_test_flag, AST_TIMING_FD, ast_channel::blocker, ast_channel::caller, ast_channel::cdr, ast_datastore_info::chan_fixup, CHANNEL_DEADLOCK_AVOIDANCE, channels, clone_variables(), ast_channel::connected, 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_channel_tech::hangup, 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_goto_on_transfer(), do_bridge_masquerade(), handle_invite_replaces(), iax_park(), local_attended_transfer(), masq_park_call(), and sip_park().

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

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

01371 {
01372    struct ast_channel *tmp;
01373    struct varshead *headp;
01374 
01375 #if defined(REF_DEBUG)
01376    tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel",
01377       file, line, function, 1);
01378 #elif defined(__AST_DEBUG_MALLOC)
01379    tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel",
01380       file, line, function, 0);
01381 #else
01382    tmp = ao2_alloc(sizeof(*tmp), ast_dummy_channel_destructor);
01383 #endif
01384    if (!tmp) {
01385       /* Dummy channel structure allocation failure. */
01386       return NULL;
01387    }
01388 
01389    if ((ast_string_field_init(tmp, 128))) {
01390       return ast_channel_unref(tmp);
01391    }
01392 
01393    headp = &tmp->varshead;
01394    AST_LIST_HEAD_INIT_NOLOCK(headp);
01395 
01396    return tmp;
01397 }

static void ast_dummy_channel_destructor ( void *  obj  )  [static]

Free a dummy channel structure.

Definition at line 2482 of file channel.c.

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

Referenced by ast_dummy_channel_alloc().

02483 {
02484    struct ast_channel *chan = obj;
02485    struct ast_var_t *vardata;
02486    struct varshead *headp;
02487 
02488    headp = &chan->varshead;
02489 
02490    ast_party_dialed_free(&chan->dialed);
02491    ast_party_caller_free(&chan->caller);
02492    ast_party_connected_line_free(&chan->connected);
02493    ast_party_redirecting_free(&chan->redirecting);
02494 
02495    /* loop over the variables list, freeing all data and deleting list items */
02496    /* no need to lock the list, as the channel is already locked */
02497    while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
02498       ast_var_delete(vardata);
02499 
02500    if (chan->cdr) {
02501       ast_cdr_discard(chan->cdr);
02502       chan->cdr = NULL;
02503    }
02504 
02505    ast_string_field_free_memory(chan);
02506 }

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

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

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

00940 {
00941    struct chanlist *chanls;
00942    const struct ast_channel_tech *ret = NULL;
00943 
00944    AST_RWLIST_RDLOCK(&backends);
00945 
00946    AST_RWLIST_TRAVERSE(&backends, chanls, list) {
00947       if (!strcasecmp(name, chanls->tech->type)) {
00948          ret = chanls->tech;
00949          break;
00950       }
00951    }
00952 
00953    AST_RWLIST_UNLOCK(&backends);
00954    
00955    return ret;
00956 }

ast_group_t ast_get_group ( const char *  s  ) 

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

07727 {
07728    char *piece;
07729    char *c;
07730    int start=0, finish=0, x;
07731    ast_group_t group = 0;
07732 
07733    if (ast_strlen_zero(s))
07734       return 0;
07735 
07736    c = ast_strdupa(s);
07737    
07738    while ((piece = strsep(&c, ","))) {
07739       if (sscanf(piece, "%30d-%30d", &start, &finish) == 2) {
07740          /* Range */
07741       } else if (sscanf(piece, "%30d", &start)) {
07742          /* Just one */
07743          finish = start;
07744       } else {
07745          ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece);
07746          continue;
07747       }
07748       for (x = start; x <= finish; x++) {
07749          if ((x > 63) || (x < 0)) {
07750             ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x);
07751          } else
07752             group |= ((ast_group_t) 1 << x);
07753       }
07754    }
07755    return group;
07756 }

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

References ao2_lock, ao2_unlink, ao2_unlock, ast_assert, ast_audiohook_detach_list(), 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_framehook_list_destroy(), ast_log(), ast_manager_event, ast_set_flag, ast_test_flag, ast_channel::audiohooks, ast_channel::blocker, ast_channel::blockproc, ast_channel::caller, ast_channel::cdr, chanlist::chan, channels, ast_channel::connected, 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_channel_thread(), bridge_exec(), build_conf(), builtin_atxfer(), chanavail_exec(), check_availability(), check_compat(), check_goto_on_transfer(), clear_caller(), conf_run(), connect_link(), 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(), rpt(), rpt_call(), rpt_tele_thread(), sip_park(), sip_park_thread(), sip_pickup_thread(), skinny_new(), skinny_ss(), ss7_start_call(), unistim_new(), usbradio_new(), and wait_for_winner().

02734 {
02735    char extra_str[64]; /* used for cel logging below */
02736 
02737    ast_autoservice_stop(chan);
02738 
02739    ao2_lock(channels);
02740    ast_channel_lock(chan);
02741 
02742    if (chan->audiohooks) {
02743       ast_audiohook_detach_list(chan->audiohooks);
02744       chan->audiohooks = NULL;
02745    }
02746    ast_framehook_list_destroy(chan);
02747 
02748    /*
02749     * Do the masquerade if someone is setup to masquerade into us.
02750     *
02751     * NOTE: We must hold the channel lock after testing for a
02752     * pending masquerade and setting the channel as a zombie to
02753     * prevent __ast_channel_masquerade() from setting up a
02754     * masquerade with a dead channel.
02755     */
02756    while (chan->masq) {
02757       ast_channel_unlock(chan);
02758       ao2_unlock(channels);
02759       if (ast_do_masquerade(chan)) {
02760          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
02761 
02762          /* Abort the loop or we might never leave. */
02763          ao2_lock(channels);
02764          ast_channel_lock(chan);
02765          break;
02766       }
02767       ao2_lock(channels);
02768       ast_channel_lock(chan);
02769    }
02770 
02771    if (chan->masqr) {
02772       /*
02773        * This channel is one which will be masqueraded into something.
02774        * Mark it as a zombie already so ast_do_masquerade() will know
02775        * to free it later.
02776        */
02777       ast_set_flag(chan, AST_FLAG_ZOMBIE);
02778       ast_channel_unlock(chan);
02779       ao2_unlock(channels);
02780       return 0;
02781    }
02782 
02783    ao2_unlink(channels, chan);
02784    ao2_unlock(channels);
02785 
02786    free_translation(chan);
02787    /* Close audio stream */
02788    if (chan->stream) {
02789       ast_closestream(chan->stream);
02790       chan->stream = NULL;
02791    }
02792    /* Close video stream */
02793    if (chan->vstream) {
02794       ast_closestream(chan->vstream);
02795       chan->vstream = NULL;
02796    }
02797    if (chan->sched) {
02798       sched_context_destroy(chan->sched);
02799       chan->sched = NULL;
02800    }
02801 
02802    if (chan->generatordata) { /* Clear any tone stuff remaining */
02803       if (chan->generator && chan->generator->release) {
02804          chan->generator->release(chan, chan->generatordata);
02805       }
02806    }
02807    chan->generatordata = NULL;
02808    chan->generator = NULL;
02809 
02810    snprintf(extra_str, sizeof(extra_str), "%d,%s,%s", chan->hangupcause, chan->hangupsource, S_OR(pbx_builtin_getvar_helper(chan, "DIALSTATUS"), ""));
02811    ast_cel_report_event(chan, AST_CEL_HANGUP, NULL, extra_str, NULL);
02812 
02813    if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
02814       ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
02815          "is blocked by thread %ld in procedure %s!  Expect a failure\n",
02816          (long) pthread_self(), chan->name, (long)chan->blocker, chan->blockproc);
02817       ast_assert(ast_test_flag(chan, AST_FLAG_BLOCKING) == 0);
02818    }
02819    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) {
02820       ast_debug(1, "Hanging up channel '%s'\n", chan->name);
02821 
02822       /*
02823        * This channel is now dead so mark it as a zombie so anyone
02824        * left holding a reference to this channel will not use it.
02825        */
02826       ast_set_flag(chan, AST_FLAG_ZOMBIE);
02827       if (chan->tech->hangup) {
02828          chan->tech->hangup(chan);
02829       }
02830    } else {
02831       ast_debug(1, "Hanging up zombie '%s'\n", chan->name);
02832    }
02833 
02834    ast_channel_unlock(chan);
02835 
02836    ast_cc_offer(chan);
02837    ast_manager_event(chan, EVENT_FLAG_CALL, "Hangup",
02838       "Channel: %s\r\n"
02839       "Uniqueid: %s\r\n"
02840       "CallerIDNum: %s\r\n"
02841       "CallerIDName: %s\r\n"
02842       "ConnectedLineNum: %s\r\n"
02843       "ConnectedLineName: %s\r\n"
02844       "Cause: %d\r\n"
02845       "Cause-txt: %s\r\n",
02846       chan->name,
02847       chan->uniqueid,
02848       S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "<unknown>"),
02849       S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, "<unknown>"),
02850       S_COR(chan->connected.id.number.valid, chan->connected.id.number.str, "<unknown>"),
02851       S_COR(chan->connected.id.name.valid, chan->connected.id.name.str, "<unknown>"),
02852       chan->hangupcause,
02853       ast_cause2str(chan->hangupcause)
02854       );
02855 
02856    if (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_BRIDGED) &&
02857       !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED) &&
02858       (chan->cdr->disposition != AST_CDR_NULL || ast_test_flag(chan->cdr, AST_CDR_FLAG_DIALED))) {
02859       ast_channel_lock(chan);
02860       ast_cdr_end(chan->cdr);
02861       ast_cdr_detach(chan->cdr);
02862       chan->cdr = NULL;
02863       ast_channel_unlock(chan);
02864    }
02865 
02866    ast_channel_unref(chan);
02867 
02868    return 0;
02869 }

int ast_indicate ( struct ast_channel chan,
int  condition 
)

Indicates condition of channel.

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

Definition at line 4262 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(), function_remote(), handle_callforward_button(), handle_frame(), handle_recordfile(), handle_request_refer(), local_attended_transfer(), manage_parked_call(), mgcp_ss(), monitor_dial(), oss_call(), park_call_full(), parked_call_exec(), pbx_builtin_busy(), pbx_builtin_congestion(), pbx_builtin_incomplete(), pbx_builtin_proceeding(), pbx_builtin_progress(), pbx_builtin_ringing(), pbx_builtin_waitexten(), queue_exec(), rna(), rpt(), rpt_exec(), say_periodic_announcement(), say_position(), send_waveform_to_channel(), skinny_ss(), sla_handle_hold_event(), sla_station_exec(), and sla_trunk_exec().

04263 {
04264    return ast_indicate_data(chan, condition, NULL, 0);
04265 }

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

Indicates condition of channel, with payload.

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

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

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

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

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

References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.

Referenced by load_module().

07765 {
07766    ast_moh_start_ptr = start_ptr;
07767    ast_moh_stop_ptr = stop_ptr;
07768    ast_moh_cleanup_ptr = cleanup_ptr;
07769 }

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

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

Referenced by add_sdp(), and ast_read_generator_actions().

04248 {
04249    return (ast_opt_internal_timing && chan->timingfd > -1);
04250 }

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

01780 {
01781    /* Do not add a default entry in this switch statement.  Each new
01782     * frame type should be addressed directly as to whether it should
01783     * be queued up or not.
01784     */
01785    switch (frame->frametype) {
01786    case AST_FRAME_CONTROL:
01787    case AST_FRAME_TEXT:
01788    case AST_FRAME_IMAGE:
01789    case AST_FRAME_HTML:
01790       return 1;
01791 
01792    case AST_FRAME_DTMF_END:
01793    case AST_FRAME_DTMF_BEGIN:
01794    case AST_FRAME_VOICE:
01795    case AST_FRAME_VIDEO:
01796    case AST_FRAME_NULL:
01797    case AST_FRAME_IAX:
01798    case AST_FRAME_CNG:
01799    case AST_FRAME_MODEM:
01800       return 0;
01801    }
01802    return 0;
01803 }

void ast_moh_cleanup ( struct ast_channel chan  ) 

Definition at line 7796 of file channel.c.

References ast_moh_cleanup_ptr.

Referenced by ast_channel_destructor().

07797 {
07798    if (ast_moh_cleanup_ptr)
07799       ast_moh_cleanup_ptr(chan);
07800 }

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

References ast_moh_start_ptr, and ast_verb.

Referenced by alsa_indicate(), app_exec(), conf_run(), 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(), sig_ss7_indicate(), sip_indicate(), skinny_indicate(), start_moh_exec(), TransferCallStep1(), unistim_indicate(), usbradio_indicate(), and wait_moh_exec().

07780 {
07781    if (ast_moh_start_ptr)
07782       return ast_moh_start_ptr(chan, mclass, interpclass);
07783 
07784    ast_verb(3, "Music class %s requested but no musiconhold loaded.\n", mclass ? mclass : (interpclass ? interpclass : "default"));
07785 
07786    return 0;
07787 }

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 7790 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(), sig_ss7_indicate(), sip_indicate(), skinny_indicate(), stop_moh_exec(), unistim_hangup(), unistim_indicate(), usbradio_indicate(), and wait_moh_exec().

07791 {
07792    if (ast_moh_stop_ptr)
07793       ast_moh_stop_ptr(chan);
07794 }

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

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

02231 {
02232    if (dest == src) {
02233       /* Don't copy to self */
02234       return;
02235    }
02236 
02237    ast_party_id_copy(&dest->id, &src->id);
02238    ast_party_id_copy(&dest->ani, &src->ani);
02239    dest->ani2 = src->ani2;
02240 }

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

02257 {
02258    ast_party_id_free(&doomed->id);
02259    ast_party_id_free(&doomed->ani);
02260 }

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 2223 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(), sig_ss7_set_caller_id(), and sla_ring_station().

02224 {
02225    ast_party_id_init(&init->id);
02226    ast_party_id_init(&init->ani);
02227    init->ani2 = 0;
02228 }

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

02250 {
02251    ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL);
02252    ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL);
02253    dest->ani2 = src->ani2;
02254 }

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

02243 {
02244    ast_party_id_set_init(&init->id, &guide->id);
02245    ast_party_id_set_init(&init->ani, &guide->ani);
02246    init->ani2 = guide->ani2;
02247 }

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

02300 {
02301    connected->id = caller->id;
02302    connected->ani = caller->ani;
02303    connected->ani2 = caller->ani2;
02304    connected->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN;
02305 }

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

02271 {
02272    if (dest == src) {
02273       /* Don't copy to self */
02274       return;
02275    }
02276 
02277    ast_party_id_copy(&dest->id, &src->id);
02278    ast_party_id_copy(&dest->ani, &src->ani);
02279    dest->ani2 = src->ani2;
02280    dest->source = src->source;
02281 }

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

02308 {
02309    ast_party_id_free(&doomed->id);
02310    ast_party_id_free(&doomed->ani);
02311 }

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

02263 {
02264    ast_party_id_init(&init->id);
02265    ast_party_id_init(&init->ani);
02266    init->ani2 = 0;
02267    init->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN;
02268 }

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

02292 {
02293    ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL);
02294    ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL);
02295    dest->ani2 = src->ani2;
02296    dest->source = src->source;
02297 }

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

02284 {
02285    ast_party_id_set_init(&init->id, &guide->id);
02286    ast_party_id_set_init(&init->ani, &guide->ani);
02287    init->ani2 = guide->ani2;
02288    init->source = guide->source;
02289 }

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

02182 {
02183    if (dest == src) {
02184       /* Don't copy to self */
02185       return;
02186    }
02187 
02188    ast_free(dest->number.str);
02189    dest->number.str = ast_strdup(src->number.str);
02190    dest->number.plan = src->number.plan;
02191    ast_party_subaddress_copy(&dest->subaddress, &src->subaddress);
02192    dest->transit_network_select = src->transit_network_select;
02193 }

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

02217 {
02218    ast_free(doomed->number.str);
02219    doomed->number.str = NULL;
02220    ast_party_subaddress_free(&doomed->subaddress);
02221 }

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

02174 {
02175    init->number.str = NULL;
02176    init->number.plan = 0;/* Unknown */
02177    ast_party_subaddress_init(&init->subaddress);
02178    init->transit_network_select = 0;
02179 }

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

02204 {
02205    if (src->number.str && src->number.str != dest->number.str) {
02206       ast_free(dest->number.str);
02207       dest->number.str = ast_strdup(src->number.str);
02208    }
02209    dest->number.plan = src->number.plan;
02210 
02211    ast_party_subaddress_set(&dest->subaddress, &src->subaddress);
02212 
02213    dest->transit_network_select = src->transit_network_select;
02214 }

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

02196 {
02197    init->number.str = NULL;
02198    init->number.plan = guide->number.plan;
02199    ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress);
02200    init->transit_network_select = guide->transit_network_select;
02201 }

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

02053 {
02054    if (dest == src) {
02055       /* Don't copy to self */
02056       return;
02057    }
02058 
02059    ast_party_name_copy(&dest->name, &src->name);
02060    ast_party_number_copy(&dest->number, &src->number);
02061    ast_party_subaddress_copy(&dest->subaddress, &src->subaddress);
02062 
02063    ast_free(dest->tag);
02064    dest->tag = ast_strdup(src->tag);
02065 }

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

02099 {
02100    ast_party_name_free(&doomed->name);
02101    ast_party_number_free(&doomed->number);
02102    ast_party_subaddress_free(&doomed->subaddress);
02103 
02104    ast_free(doomed->tag);
02105    doomed->tag = NULL;
02106 }

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

02045 {
02046    ast_party_name_init(&init->name);
02047    ast_party_number_init(&init->number);
02048    ast_party_subaddress_init(&init->subaddress);
02049    init->tag = NULL;
02050 }

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

References AST_PRES_ALLOWED, AST_PRES_NUMBER_TYPE, AST_PRES_RESTRICTED, AST_PRES_RESTRICTION, AST_PRES_UNAVAILABLE, AST_PRES_USER_NUMBER_UNSCREENED, 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().

02109 {
02110    int number_priority;
02111    int number_value;
02112    int number_screening;
02113    int name_priority;
02114    int name_value;
02115 
02116    /* Determine name presentation priority. */
02117    if (!id->name.valid) {
02118       name_value = AST_PRES_UNAVAILABLE;
02119       name_priority = 3;
02120    } else {
02121       name_value = id->name.presentation & AST_PRES_RESTRICTION;
02122       switch (name_value) {
02123       case AST_PRES_RESTRICTED:
02124          name_priority = 0;
02125          break;
02126       case AST_PRES_ALLOWED:
02127          name_priority = 1;
02128          break;
02129       case AST_PRES_UNAVAILABLE:
02130          name_priority = 2;
02131          break;
02132       default:
02133          name_value = AST_PRES_UNAVAILABLE;
02134          name_priority = 3;
02135          break;
02136       }
02137    }
02138 
02139    /* Determine number presentation priority. */
02140    if (!id->number.valid) {
02141       number_screening = AST_PRES_USER_NUMBER_UNSCREENED;
02142       number_value = AST_PRES_UNAVAILABLE;
02143       number_priority = 3;
02144    } else {
02145       number_screening = id->number.presentation & AST_PRES_NUMBER_TYPE;
02146       number_value = id->number.presentation & AST_PRES_RESTRICTION;
02147       switch (number_value) {
02148       case AST_PRES_RESTRICTED:
02149          number_priority = 0;
02150          break;
02151       case AST_PRES_ALLOWED:
02152          number_priority = 1;
02153          break;
02154       case AST_PRES_UNAVAILABLE:
02155          number_priority = 2;
02156          break;
02157       default:
02158          number_screening = AST_PRES_USER_NUMBER_UNSCREENED;
02159          number_value = AST_PRES_UNAVAILABLE;
02160          number_priority = 3;
02161          break;
02162       }
02163    }
02164 
02165    /* Select the wining presentation value. */
02166    if (name_priority < number_priority) {
02167       number_value = name_value;
02168    }
02169 
02170    return number_value | number_screening;
02171 }

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

02076 {
02077    if (dest == src) {
02078       /* Don't set to self */
02079       return;
02080    }
02081 
02082    if (!update || update->name) {
02083       ast_party_name_set(&dest->name, &src->name);
02084    }
02085    if (!update || update->number) {
02086       ast_party_number_set(&dest->number, &src->number);
02087    }
02088    if (!update || update->subaddress) {
02089       ast_party_subaddress_set(&dest->subaddress, &src->subaddress);
02090    }
02091 
02092    if (src->tag && src->tag != dest->tag) {
02093       ast_free(dest->tag);
02094       dest->tag = ast_strdup(src->tag);
02095    }
02096 }

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

02068 {
02069    ast_party_name_set_init(&init->name, &guide->name);
02070    ast_party_number_set_init(&init->number, &guide->number);
02071    ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress);
02072    init->tag = NULL;
02073 }

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

01894 {
01895    if (dest == src) {
01896       /* Don't copy to self */
01897       return;
01898    }
01899 
01900    ast_free(dest->str);
01901    dest->str = ast_strdup(src->str);
01902    dest->char_set = src->char_set;
01903    dest->presentation = src->presentation;
01904    dest->valid = src->valid;
01905 }

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

01933 {
01934    ast_free(doomed->str);
01935    doomed->str = NULL;
01936 }

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

01886 {
01887    init->str = NULL;
01888    init->char_set = AST_PARTY_CHAR_SET_ISO8859_1;
01889    init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
01890    init->valid = 0;
01891 }

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

01916 {
01917    if (dest == src) {
01918       /* Don't set to self */
01919       return;
01920    }
01921 
01922    if (src->str && src->str != dest->str) {
01923       ast_free(dest->str);
01924       dest->str = ast_strdup(src->str);
01925    }
01926 
01927    dest->char_set = src->char_set;
01928    dest->presentation = src->presentation;
01929    dest->valid = src->valid;
01930 }

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

01908 {
01909    init->str = NULL;
01910    init->char_set = guide->char_set;
01911    init->presentation = guide->presentation;
01912    init->valid = guide->valid;
01913 }

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

01947 {
01948    if (dest == src) {
01949       /* Don't copy to self */
01950       return;
01951    }
01952 
01953    ast_free(dest->str);
01954    dest->str = ast_strdup(src->str);
01955    dest->plan = src->plan;
01956    dest->presentation = src->presentation;
01957    dest->valid = src->valid;
01958 }

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

01986 {
01987    ast_free(doomed->str);
01988    doomed->str = NULL;
01989 }

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

01939 {
01940    init->str = NULL;
01941    init->plan = 0;/* Unknown */
01942    init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
01943    init->valid = 0;
01944 }

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

01969 {
01970    if (dest == src) {
01971       /* Don't set to self */
01972       return;
01973    }
01974 
01975    if (src->str && src->str != dest->str) {
01976       ast_free(dest->str);
01977       dest->str = ast_strdup(src->str);
01978    }
01979 
01980    dest->plan = src->plan;
01981    dest->presentation = src->presentation;
01982    dest->valid = src->valid;
01983 }

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

01961 {
01962    init->str = NULL;
01963    init->plan = guide->plan;
01964    init->presentation = guide->presentation;
01965    init->valid = guide->valid;
01966 }

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

02322 {
02323    if (dest == src) {
02324       /* Don't copy to self */
02325       return;
02326    }
02327 
02328    ast_party_id_copy(&dest->from, &src->from);
02329    ast_party_id_copy(&dest->to, &src->to);
02330    dest->count = src->count;
02331    dest->reason = src->reason;
02332 }

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

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

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

02351 {
02352    ast_party_id_free(&doomed->from);
02353    ast_party_id_free(&doomed->to);
02354 }

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

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

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

02314 {
02315    ast_party_id_init(&init->from);
02316    ast_party_id_init(&init->to);
02317    init->count = 0;
02318    init->reason = AST_REDIRECTING_REASON_UNKNOWN;
02319 }

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

02343 {
02344    ast_party_id_set(&dest->from, &src->from, update ? &update->from : NULL);
02345    ast_party_id_set(&dest->to, &src->to, update ? &update->to : NULL);
02346    dest->reason = src->reason;
02347    dest->count = src->count;
02348 }

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

02335 {
02336    ast_party_id_set_init(&init->from, &guide->from);
02337    ast_party_id_set_init(&init->to, &guide->to);
02338    init->count = guide->count;
02339    init->reason = guide->reason;
02340 }

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

02000 {
02001    if (dest == src) {
02002       /* Don't copy to self */
02003       return;
02004    }
02005 
02006    ast_free(dest->str);
02007    dest->str = ast_strdup(src->str);
02008    dest->type = src->type;
02009    dest->odd_even_indicator = src->odd_even_indicator;
02010    dest->valid = src->valid;
02011 }

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

References ast_free, and ast_party_subaddress::str.

Referenced by ast_party_dialed_free(), and ast_party_id_free().

02039 {
02040    ast_free(doomed->str);
02041    doomed->str = NULL;
02042 }

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

01992 {
01993    init->str = NULL;
01994    init->type = 0;
01995    init->odd_even_indicator = 0;
01996    init->valid = 0;
01997 }

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

02022 {
02023    if (dest == src) {
02024       /* Don't set to self */
02025       return;
02026    }
02027 
02028    if (src->str && src->str != dest->str) {
02029       ast_free(dest->str);
02030       dest->str = ast_strdup(src->str);
02031    }
02032 
02033    dest->type = src->type;
02034    dest->odd_even_indicator = src->odd_even_indicator;
02035    dest->valid = src->valid;
02036 }

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

02014 {
02015    init->str = NULL;
02016    init->type = guide->type;
02017    init->odd_even_indicator = guide->odd_even_indicator;
02018    init->valid = guide->valid;
02019 }

int ast_plc_reload ( void   ) 

Reload genericplc configuration value from codecs.conf.

Implementation is in main/channel.c

Definition at line 7815 of file channel.c.

References ast_config_load, AST_OPT_FLAG_GENERIC_PLC, ast_options, ast_set2_flag, ast_true(), ast_variable_browse(), config_flags, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, and var.

Referenced by ast_channels_init().

07816 {
07817    struct ast_variable *var;
07818    struct ast_flags config_flags = { 0 };
07819    struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
07820    if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID)
07821       return 0;
07822    for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
07823       if (!strcasecmp(var->name, "genericplc")) {
07824          ast_set2_flag(&ast_options, ast_true(var->value), AST_OPT_FLAG_GENERIC_PLC);
07825       }
07826    }
07827    ast_config_destroy(cfg);
07828    return 0;
07829 }

void ast_poll_channel_add ( struct ast_channel chan0,
struct ast_channel chan1 
)

Add a channel to an optimized waitfor

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

02611 {
02612 #ifdef HAVE_EPOLL
02613    struct epoll_event ev;
02614    int i = 0;
02615 
02616    if (chan0->epfd == -1)
02617       return;
02618 
02619    /* Iterate through the file descriptors on chan1, adding them to chan0 */
02620    for (i = 0; i < AST_MAX_FDS; i++) {
02621       if (chan1->fds[i] == -1)
02622          continue;
02623       ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP;
02624       ev.data.ptr = chan1->epfd_data[i];
02625       epoll_ctl(chan0->epfd, EPOLL_CTL_ADD, chan1->fds[i], &ev);
02626    }
02627 
02628 #endif
02629    return;
02630 }

void ast_poll_channel_del ( struct ast_channel chan0,
struct ast_channel chan1 
)

Delete a channel from an optimized waitfor

Definition at line 2633 of file channel.c.

References AST_MAX_FDS, and ast_channel::fds.

Referenced by feature_request_and_dial(), and monitor_dial().

02634 {
02635 #ifdef HAVE_EPOLL
02636    struct epoll_event ev;
02637    int i = 0;
02638 
02639    if (chan0->epfd == -1)
02640       return;
02641 
02642    for (i = 0; i < AST_MAX_FDS; i++) {
02643       if (chan1->fds[i] == -1)
02644          continue;
02645       epoll_ctl(chan0->epfd, EPOLL_CTL_DEL, chan1->fds[i], &ev);
02646    }
02647 
02648 #endif
02649    return;
02650 }

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

print call- and pickup groups into buffer

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

07964 {
07965    unsigned int i;
07966    int first = 1;
07967    char num[3];
07968 
07969    buf[0] = '\0';
07970    
07971    if (!group) /* Return empty string if no group */
07972       return buf;
07973 
07974    for (i = 0; i <= 63; i++) {   /* Max group is 63 */
07975       if (group & ((ast_group_t) 1 << i)) {
07976             if (!first) {
07977             strncat(buf, ", ", buflen - strlen(buf) - 1);
07978          } else {
07979             first = 0;
07980          }
07981          snprintf(num, sizeof(num), "%u", i);
07982          strncat(buf, num, buflen - strlen(buf) - 1);
07983       }
07984    }
07985    return buf;
07986 }

int ast_prod ( struct ast_channel chan  ) 

Send empty audio to prime a channel driver.

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

04636 {
04637    struct ast_frame a = { AST_FRAME_VOICE };
04638    char nothing[128];
04639 
04640    /* Send an empty audio frame to get things moving */
04641    if (chan->_state != AST_STATE_UP) {
04642       ast_debug(1, "Prodding channel '%s'\n", chan->name);
04643       a.subclass.codec = chan->rawwriteformat;
04644       a.data.ptr = nothing + AST_FRIENDLY_OFFSET;
04645       a.src = "ast_prod"; /* this better match check in ast_write */
04646       if (ast_write(chan, &a))
04647          ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name);
04648    }
04649    return 0;
04650 }

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

01563 {
01564    struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control };
01565    return ast_queue_frame(chan, &f);
01566 }

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

01571 {
01572    struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control, .data.ptr = (void *) data, .datalen = datalen };
01573    return ast_queue_frame(chan, &f);
01574 }

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 1519 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(), rpt_call(), sig_pri_handle_hold(), sig_pri_handle_subcmds(), sig_ss7_queue_frame(), stream_monitor(), unistim_do_senddigit(), unistim_senddigit_end(), usbradio_read(), and wakeup_sub().

01520 {
01521    return __ast_queue_frame(chan, fin, 0, NULL);
01522 }

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

01525 {
01526    return __ast_queue_frame(chan, fin, 1, NULL);
01527 }

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 1530 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_request_cancel(), handle_soft_key_event_message(), iax2_destroy(), iax2_queue_hangup(), jingle_hangup_farend(), local_fixup(), local_hangup(), and mgcp_queue_hangup().

01531 {
01532    struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP };
01533    /* Yeah, let's not change a lock-critical value without locking */
01534    if (!ast_channel_trylock(chan)) {
01535       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01536       ast_channel_unlock(chan);
01537    }
01538    return ast_queue_frame(chan, &f);
01539 }

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 1542 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(), and TransferCallStep1().

01543 {
01544    struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP };
01545 
01546    if (cause >= 0)
01547       f.data.uint32 = cause;
01548 
01549    /* Yeah, let's not change a lock-critical value without locking */
01550    if (!ast_channel_trylock(chan)) {
01551       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01552       if (cause < 0)
01553          f.data.uint32 = chan->hangupcause;
01554 
01555       ast_channel_unlock(chan);
01556    }
01557 
01558    return ast_queue_frame(chan, &f);
01559 }

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

02872 {
02873    int res = 0;
02874 
02875    ast_channel_lock(chan);
02876 
02877    /* You can't answer an outbound call */
02878    if (ast_test_flag(chan, AST_FLAG_OUTGOING)) {
02879       ast_channel_unlock(chan);
02880       return 0;
02881    }
02882 
02883    /* Stop if we're a zombie or need a soft hangup */
02884    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
02885       ast_channel_unlock(chan);
02886       return -1;
02887    }
02888 
02889    ast_channel_unlock(chan);
02890 
02891    switch (chan->_state) {
02892    case AST_STATE_RINGING:
02893    case AST_STATE_RING:
02894       ast_channel_lock(chan);
02895       if (chan->tech->answer) {
02896          res = chan->tech->answer(chan);
02897       }
02898       ast_setstate(chan, AST_STATE_UP);
02899       if (cdr_answer) {
02900          ast_cdr_answer(chan->cdr);
02901       }
02902       ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL);
02903       ast_channel_unlock(chan);
02904       break;
02905    case AST_STATE_UP:
02906       ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL);
02907       /* Calling ast_cdr_answer when it it has previously been called
02908        * is essentially a no-op, so it is safe.
02909        */
02910       if (cdr_answer) {
02911          ast_cdr_answer(chan->cdr);
02912       }
02913       break;
02914    default:
02915       break;
02916    }
02917 
02918    ast_indicate(chan, -1);
02919 
02920    return res;
02921 }

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

04253 {
04254    return __ast_read(chan, 0);
04255 }

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

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

03610 {
03611    if (chan->generator && chan->generator->generate && chan->generatordata &&  !ast_internal_timing_enabled(chan)) {
03612       void *tmp = chan->generatordata;
03613       int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = chan->generator->generate;
03614       int res;
03615       int samples;
03616 
03617       if (chan->timingfunc) {
03618          ast_debug(1, "Generator got voice, switching to phase locked mode\n");
03619          ast_settimeout(chan, 0, NULL, NULL);
03620       }
03621 
03622       chan->generatordata = NULL;     /* reset, to let writes go through */
03623 
03624       if (f->subclass.codec != chan->writeformat) {
03625          float factor;
03626          factor = ((float) ast_format_rate(chan->writeformat)) / ((float) ast_format_rate(f->subclass.codec));
03627          samples = (int) ( ((float) f->samples) * factor );
03628       } else {
03629          samples = f->samples;
03630       }
03631       
03632       /* This unlock is here based on two assumptions that hold true at this point in the
03633        * code. 1) this function is only called from within __ast_read() and 2) all generators
03634        * call ast_write() in their generate callback.
03635        *
03636        * The reason this is added is so that when ast_write is called, the lock that occurs 
03637        * there will not recursively lock the channel. Doing this will cause intended deadlock 
03638        * avoidance not to work in deeper functions
03639        */
03640       ast_channel_unlock(chan);
03641       res = generate(chan, tmp, f->datalen, samples);
03642       ast_channel_lock(chan);
03643       chan->generatordata = tmp;
03644       if (res) {
03645          ast_debug(1, "Auto-deactivating generator\n");
03646          ast_deactivate_generator(chan);
03647       }
03648 
03649    } else if (f->frametype == AST_FRAME_CNG) {
03650       if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) {
03651          ast_debug(1, "Generator got CNG, switching to timed mode\n");
03652          ast_settimeout(chan, 50, generator_force, chan);
03653       }
03654    }
03655 }

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

References __ast_read(), and chanlist::chan.

Referenced by ast_bridge_handle_trip(), and conf_run().

04258 {
04259    return __ast_read(chan, 1);
04260 }

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

Reads multiple digits.

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

Definition at line 5686 of file channel.c.

References ast_readstring_full().

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

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

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

Definition at line 5691 of file channel.c.

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

Referenced by ast_app_getdata_full(), and ast_readstring().

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

int ast_recvchar ( struct ast_channel chan,
int  timeout 
)

Receives a text character from a channel.

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

Definition at line 4511 of file channel.c.

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

Referenced by handle_recvchar().

04512 {
04513    int c;
04514    char *buf = ast_recvtext(chan, timeout);
04515    if (buf == NULL)
04516       return -1;  /* error or timeout */
04517    c = *(unsigned char *)buf;
04518    ast_free(buf);
04519    return c;
04520 }

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

04523 {
04524    int res, done = 0;
04525    char *buf = NULL;
04526    
04527    while (!done) {
04528       struct ast_frame *f;
04529       if (ast_check_hangup(chan))
04530          break;
04531       res = ast_waitfor(chan, timeout);
04532       if (res <= 0) /* timeout or error */
04533          break;
04534       timeout = res; /* update timeout */
04535       f = ast_read(chan);
04536       if (f == NULL)
04537          break; /* no frame */
04538       if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_HANGUP)
04539          done = 1;   /* force a break */
04540       else if (f->frametype == AST_FRAME_TEXT) {      /* what we want */
04541          buf = ast_strndup((char *) f->data.ptr, f->datalen);  /* dup and break */
04542          done = 1;
04543       }
04544       ast_frfree(f);
04545    }
04546    return buf;
04547 }

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

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

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

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

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
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 5544 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(), attempt_reconnect(), begin_dial_channel(), build_conf(), chanavail_exec(), conf_run(), connect_link(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), play_sound_file(), ring_entry(), rpt(), rpt_call(), rpt_exec(), and rpt_tele_thread().

05545 {
05546    struct chanlist *chan;
05547    struct ast_channel *c;
05548    format_t capabilities;
05549    format_t fmt;
05550    int res;
05551    int foo;
05552    format_t videoformat = format & AST_FORMAT_VIDEO_MASK;
05553    format_t textformat = format & AST_FORMAT_TEXT_MASK;
05554 
05555    if (!cause)
05556       cause = &foo;
05557    *cause = AST_CAUSE_NOTDEFINED;
05558 
05559    if (AST_RWLIST_RDLOCK(&backends)) {
05560       ast_log(LOG_WARNING, "Unable to lock technology backend list\n");
05561       return NULL;
05562    }
05563 
05564    AST_RWLIST_TRAVERSE(&backends, chan, list) {
05565       if (strcasecmp(type, chan->tech->type))
05566          continue;
05567 
05568       capabilities = chan->tech->capabilities;
05569       fmt = format & AST_FORMAT_AUDIO_MASK;
05570       if (fmt) {
05571          /* We have audio - is it possible to connect the various calls to each other? 
05572             (Avoid this check for calls without audio, like text+video calls)
05573          */
05574          res = ast_translator_best_choice(&fmt, &capabilities);
05575          if (res < 0) {
05576             char tmp1[256], tmp2[256];
05577             ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %s) to %s\n", type,
05578                ast_getformatname_multiple(tmp1, sizeof(tmp1), chan->tech->capabilities),
05579                ast_getformatname_multiple(tmp2, sizeof(tmp2), format));
05580             *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05581             AST_RWLIST_UNLOCK(&backends);
05582             return NULL;
05583          }
05584       }
05585       AST_RWLIST_UNLOCK(&backends);
05586       if (!chan->tech->requester)
05587          return NULL;
05588 
05589       if (!(c = chan->tech->requester(type, capabilities | videoformat | textformat, requestor, data, cause)))
05590          return NULL;
05591 
05592       if (set_security_requirements(requestor, c)) {
05593          ast_log(LOG_WARNING, "Setting security requirements failed\n");
05594          c = ast_channel_release(c);
05595          *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05596          return NULL;
05597       }
05598 
05599       /* no need to generate a Newchannel event here; it is done in the channel_alloc call */
05600       return c;
05601    }
05602 
05603    ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
05604    *cause = AST_CAUSE_NOSUCHDRIVER;
05605    AST_RWLIST_UNLOCK(&backends);
05606 
05607    return NULL;
05608 }

struct ast_channel* ast_request_and_dial ( const char *  type,
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 5499 of file channel.c.

References __ast_request_and_dial().

Referenced by ast_pbx_outgoing_exten(), and generic_recall().

05500 {
05501    return __ast_request_and_dial(type, format, requestor, data, timeout, outstate, cidnum, cidname, NULL);
05502 }

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

References ast_safe_sleep_conditional(), and chanlist::chan.

Referenced by __analog_ss_thread(), alarmreceiver_exec(), analog_ss_thread(), ast_adsi_transmit_message_full(), ast_dtmf_stream(), ast_senddigit(), builtin_atxfer(), builtin_parkcall(), conf_run(), dictate_exec(), flash_exec(), function_ilink(), handle_callforward_button(), login_exec(), mgcp_ss(), milliwatt_exec(), misdn_check_l2l1(), old_milliwatt_exec(), park_call_exec(), pbx_builtin_wait(), play_moh_exec(), play_tone_pair(), playtone(), privacy_exec(), receive_ademco_contact_id(), rpt_call(), rpt_exec(), rpt_tele_thread(), send_morse(), send_tone_telemetry(), skinny_ss(), testclient_exec(), testserver_exec(), wait_for_hangup(), wait_interval(), wait_moh_exec(), waituntil_exec(), and zapateller_exec().

01874 {
01875    return ast_safe_sleep_conditional(chan, ms, NULL, NULL);
01876 }

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

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

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

Definition at line 8125 of file channel.c.

References ast_say_character_str_full.

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

08127 {
08128    return ast_say_character_str_full(chan, str, ints, lang, -1, -1);
08129 }

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

08121 {
08122    return ast_say_digit_str_full(chan, str, ints, lang, -1, -1);
08123 }

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

References ast_say_digits_full().

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

08115 {
08116    return ast_say_digits_full(chan, num, ints, lang, -1, -1);
08117 }

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

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

08139 {
08140    char buf[256];
08141 
08142    snprintf(buf, sizeof(buf), "%d", num);
08143 
08144    return ast_say_digit_str_full(chan, buf, ints, lang, audiofd, ctrlfd);
08145 }

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

08109 {
08110    return ast_say_enumeration_full(chan, num, ints, language, options, -1, -1);
08111 }

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

08103 {
08104    return ast_say_number_full(chan, num, ints, language, options, -1, -1);
08105 }

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

Definition at line 8131 of file channel.c.

References ast_say_phonetic_str_full.

Referenced by pbx_builtin_sayphonetic().

08133 {
08134    return ast_say_phonetic_str_full(chan, str, ints, lang, -1, -1);
08135 }

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 4625 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(), do_dtmf_phone(), manager_play_dtmf(), and rpt_call().

04626 {
04627    if (chan->tech->send_digit_begin) {
04628       ast_senddigit_begin(chan, digit);
04629       ast_safe_sleep(chan, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION));
04630    }
04631    
04632    return ast_senddigit_end(chan, digit, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION));
04633 }

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

04568 {
04569    /* Device does not support DTMF tones, lets fake
04570     * it by doing our own generation. */
04571    static const char * const dtmf_tones[] = {
04572       "941+1336", /* 0 */
04573       "697+1209", /* 1 */
04574       "697+1336", /* 2 */
04575       "697+1477", /* 3 */
04576       "770+1209", /* 4 */
04577       "770+1336", /* 5 */
04578       "770+1477", /* 6 */
04579       "852+1209", /* 7 */
04580       "852+1336", /* 8 */
04581       "852+1477", /* 9 */
04582       "697+1633", /* A */
04583       "770+1633", /* B */
04584       "852+1633", /* C */
04585       "941+1633", /* D */
04586       "941+1209", /* * */
04587       "941+1477"  /* # */
04588    };
04589 
04590    if (!chan->tech->send_digit_begin)
04591       return 0;
04592 
04593    if (!chan->tech->send_digit_begin(chan, digit))
04594       return 0;
04595 
04596    if (digit >= '0' && digit <='9')
04597       ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0);
04598    else if (digit >= 'A' && digit <= 'D')
04599       ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0);
04600    else if (digit == '*')
04601       ast_playtones_start(chan, 0, dtmf_tones[14], 0);
04602    else if (digit == '#')
04603       ast_playtones_start(chan, 0, dtmf_tones[15], 0);
04604    else {
04605       /* not handled */
04606       ast_debug(1, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name);
04607    }
04608 
04609    return 0;
04610 }

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

04613 {
04614    int res = -1;
04615 
04616    if (chan->tech->send_digit_end)
04617       res = chan->tech->send_digit_end(chan, digit, duration);
04618 
04619    if (res && chan->generator)
04620       ast_playtones_stop(chan);
04621    
04622    return 0;
04623 }

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 4549 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(), send_newkey(), and sendtext_exec().

04550 {
04551    int res = 0;
04552 
04553    ast_channel_lock(chan);
04554    /* Stop if we're a zombie or need a soft hangup */
04555    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
04556       ast_channel_unlock(chan);
04557       return -1;
04558    }
04559    CHECK_BLOCKING(chan);
04560    if (chan->tech->send_text)
04561       res = chan->tech->send_text(chan, text);
04562    ast_clear_flag(chan, AST_FLAG_BLOCKING);
04563    ast_channel_unlock(chan);
04564    return res;
04565 }

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 6811 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(), rpt_exec(), skinny_newcall(), and socket_process().

06812 {
06813    ast_channel_lock(chan);
06814 
06815    if (cid_num) {
06816       chan->caller.id.number.valid = 1;
06817       ast_free(chan->caller.id.number.str);
06818       chan->caller.id.number.str = ast_strdup(cid_num);
06819    }
06820    if (cid_name) {
06821       chan->caller.id.name.valid = 1;
06822       ast_free(chan->caller.id.name.str);
06823       chan->caller.id.name.str = ast_strdup(cid_name);
06824    }
06825    if (cid_ani) {
06826       chan->caller.ani.number.valid = 1;
06827       ast_free(chan->caller.ani.number.str);
06828       chan->caller.ani.number.str = ast_strdup(cid_ani);
06829    }
06830    if (chan->cdr) {
06831       ast_cdr_setcid(chan->cdr, chan);
06832    }
06833 
06834    report_new_callerid(chan);
06835 
06836    ast_channel_unlock(chan);
06837 }

void ast_set_hangupsource ( struct ast_channel chan,
const char *  source,
int  force 
)

Set the source of the hangup in this channel and it's bridge.

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

Definition at line 2714 of file channel.c.

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

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

02715 {
02716    struct ast_channel *bridge;
02717 
02718    ast_channel_lock(chan);
02719    if (force || ast_strlen_zero(chan->hangupsource)) {
02720       ast_string_field_set(chan, hangupsource, source);
02721    }
02722    bridge = ast_bridged_channel(chan);
02723    ast_channel_unlock(chan);
02724 
02725    if (bridge && (force || ast_strlen_zero(bridge->hangupsource))) {
02726       ast_channel_lock(bridge);
02727       ast_string_field_set(chan, hangupsource, source);
02728       ast_channel_unlock(bridge);
02729    }
02730 }

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

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

06277 {
06278    if (!ast_strlen_zero(chan1->accountcode) && ast_strlen_zero(chan2->peeraccount)) {
06279       ast_log(LOG_DEBUG, "setting peeraccount to %s for %s from data on channel %s\n",
06280             chan1->accountcode, chan2->name, chan1->name);
06281       ast_string_field_set(chan2, peeraccount, chan1->accountcode);
06282    }
06283    if (!ast_strlen_zero(chan2->accountcode) && ast_strlen_zero(chan1->peeraccount)) {
06284       ast_log(LOG_DEBUG, "setting peeraccount to %s for %s from data on channel %s\n",
06285             chan2->accountcode, chan1->name, chan2->name);
06286       ast_string_field_set(chan1, peeraccount, chan2->accountcode);
06287    }
06288    if (!ast_strlen_zero(chan1->peeraccount) && ast_strlen_zero(chan2->accountcode)) {
06289       ast_log(LOG_DEBUG, "setting accountcode to %s for %s from data on channel %s\n",
06290             chan1->peeraccount, chan2->name, chan1->name);
06291       ast_string_field_set(chan2, accountcode, chan1->peeraccount);
06292    }
06293    if (!ast_strlen_zero(chan2->peeraccount) && ast_strlen_zero(chan1->accountcode)) {
06294       ast_log(LOG_DEBUG, "setting accountcode to %s for %s from data on channel %s\n",
06295             chan2->peeraccount, chan1->name, chan2->name);
06296       ast_string_field_set(chan1, accountcode, chan2->peeraccount);
06297    }
06298    if (0 != strcmp(chan1->accountcode, chan2->peeraccount)) {
06299       ast_log(LOG_DEBUG, "changing peeraccount from %s to %s on %s to match channel %s\n",
06300             chan2->peeraccount, chan1->peeraccount, chan2->name, chan1->name);
06301       ast_string_field_set(chan2, peeraccount, chan1->accountcode);
06302    }
06303    if (0 != strcmp(chan2->accountcode, chan1->peeraccount)) {
06304       ast_log(LOG_DEBUG, "changing peeraccount from %s to %s on %s to match channel %s\n",
06305             chan1->peeraccount, chan2->peeraccount, chan1->name, chan2->name);
06306       ast_string_field_set(chan1, peeraccount, chan2->accountcode);
06307    }
06308 }

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 5151 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(), agent_call(), alarmreceiver_exec(), ast_adsi_transmit_message_full(), ast_channel_make_compatible_helper(), ast_do_masquerade(), attempt_reconnect(), background_detect_exec(), bridge_channel_join(), bridge_make_compatible(), build_conf(), conf_run(), connect_link(), 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(), rpt(), rpt_exec(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_process(), speech_background(), transmit_audio(), and unistim_rtp_read().

05152 {
05153    return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat,
05154            &chan->readtrans, 0);
05155 }

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

07989 {
07990    struct ast_variable *cur;
07991 
07992    for (cur = vars; cur; cur = cur->next)
07993       pbx_builtin_setvar_helper(chan, cur->name, cur->value);  
07994 }

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

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

Referenced by __oh323_update_info(), agent_call(), alarmreceiver_exec(), ast_adsi_transmit_message_full(), 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(), attempt_reconnect(), bridge_channel_join(), bridge_make_compatible(), build_conf(), chanspy_exec(), conf_run(), connect_link(), 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(), rpt(), rpt_exec(), 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().

05158 {
05159    return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat,
05160            &chan->writetrans, 1);
05161 }

int ast_setstate ( struct ast_channel chan,
enum ast_channel_state  state 
)

Change the state of a channel.

Definition at line 6879 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(), sig_ss7_call(), sig_ss7_indicate(), sip_answer(), skinny_answer(), skinny_call(), skinny_newcall(), unistim_answer(), unistim_call(), unistim_new(), unistim_ss(), update_state(), usbradio_answer(), and usbradio_call().

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

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

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

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

03480 {
03481    int res;
03482    unsigned int real_rate = rate, max_rate;
03483 
03484    ast_channel_lock(c);
03485 
03486    if (c->timingfd == -1) {
03487       ast_channel_unlock(c);
03488       return -1;
03489    }
03490 
03491    if (!func) {
03492       rate = 0;
03493       data = NULL;
03494    }
03495 
03496    if (rate && rate > (max_rate = ast_timer_get_max_rate(c->timer))) {
03497       real_rate = max_rate;
03498    }
03499 
03500    ast_debug(1, "Scheduling timer at (%u requested / %u actual) timer ticks per second\n", rate, real_rate);
03501 
03502    res = ast_timer_set_rate(c->timer, real_rate);
03503 
03504    c->timingfunc = func;
03505    c->timingdata = data;
03506 
03507    ast_channel_unlock(c);
03508 
03509    return res;
03510 }

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

Referenced by handle_request_options().

00845 {
00846    return shutting_down;
00847 }

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 2691 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(), birdbath(), cc_generic_agent_stop_ringing(), conf_free(), connect_link(), dahdi_handle_event(), flush_telem(), function_ilink(), handle_hangup(), handle_link_data(), handle_softhangup(), login_exec(), manager_park(), mgcp_pktcgate_remove(), read_agent_config(), rpt(), rpt_call(), rpt_do_restart(), rpt_exec(), sla_handle_hold_event(), softhangup_exec(), start_spying(), startmon(), and unload_module().

02692 {
02693    int res;
02694 
02695    ast_channel_lock(chan);
02696    res = ast_softhangup_nolock(chan, cause);
02697    ast_channel_unlock(chan);
02698 
02699    return res;
02700 }

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

02679 {
02680    ast_debug(1, "Soft-Hanging up channel '%s'\n", chan->name);
02681    /* Inform channel driver that we need to be hung up, if it cares */
02682    chan->_softhangup |= cause;
02683    ast_queue_frame(chan, &ast_null_frame);
02684    /* Interrupt any poll call or such */
02685    if (ast_test_flag(chan, AST_FLAG_BLOCKING))
02686       pthread_kill(chan->blocker, SIGURG);
02687    return 0;
02688 }

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

00987 {
00988    char *buf;
00989 
00990    switch (state) {
00991    case AST_STATE_DOWN:
00992       return "Down";
00993    case AST_STATE_RESERVED:
00994       return "Rsrvd";
00995    case AST_STATE_OFFHOOK:
00996       return "OffHook";
00997    case AST_STATE_DIALING:
00998       return "Dialing";
00999    case AST_STATE_RING:
01000       return "Ring";
01001    case AST_STATE_RINGING:
01002       return "Ringing";
01003    case AST_STATE_UP:
01004       return "Up";
01005    case AST_STATE_BUSY:
01006       return "Busy";
01007    case AST_STATE_DIALING_OFFHOOK:
01008       return "Dialing Offhook";
01009    case AST_STATE_PRERING:
01010       return "Pre-ring";
01011    default:
01012       if (!(buf = ast_threadstorage_get(&state2str_threadbuf, STATE2STR_BUFSIZE)))
01013          return "Unknown";
01014       snprintf(buf, STATE2STR_BUFSIZE, "Unknown (%d)", state);
01015       return buf;
01016    }
01017 }

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

References ARRAY_LEN, and causes.

Referenced by pbx_builtin_hangup().

00973 {
00974    int x;
00975 
00976    for (x = 0; x < ARRAY_LEN(causes); x++)
00977       if (!strncasecmp(causes[x].name, name, strlen(causes[x].name)))
00978          return causes[x].cause;
00979 
00980    return -1;
00981 }

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

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

Referenced by zapateller_exec().

07709 {
07710    int res;
07711 
07712    if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
07713       return res;
07714 
07715    /* Give us some wiggle room */
07716    while (chan->generatordata && ast_waitfor(chan, 100) >= 0) {
07717       struct ast_frame *f = ast_read(chan);
07718       if (f)
07719          ast_frfree(f);
07720       else
07721          return -1;
07722    }
07723    return 0;
07724 }

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

Start a tone going

Definition at line 7690 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(), play_tone_pair(), rpt_tele_thread(), and sendnoise().

07691 {
07692    struct tonepair_def d = { 0, };
07693 
07694    d.freq1 = freq1;
07695    d.freq2 = freq2;
07696    d.duration = duration;
07697    d.vol = (vol < 1) ? 8192 : vol; /* force invalid to 8192 */
07698    if (ast_activate_generator(chan, &tonepair, &d))
07699       return -1;
07700    return 0;
07701 }

void ast_tonepair_stop ( struct ast_channel chan  ) 

Stop a tone from playing

Definition at line 7703 of file channel.c.

References ast_deactivate_generator().

Referenced by sendnoise().

07704 {
07705    ast_deactivate_generator(chan);
07706 }

int ast_transfer ( struct ast_channel chan,
char *  dest 
)

Transfer a channel (if supported).

Called by:

Definition at line 5637 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_CONTROL_TRANSFER, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, ast_frfree, ast_read(), ast_test_flag, AST_TRANSFER_SUCCESS, ast_waitfor(), chanlist::chan, ast_channel::tech, and ast_channel_tech::transfer.

Referenced by transfer_exec().

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

char* ast_transfercapability2str ( int  transfercapability  )  const

Gives the string form of a given transfer capability.

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

Definition at line 1020 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(), sig_pri_new_ast_channel(), and sig_ss7_new_ast_channel().

01021 {
01022    switch (transfercapability) {
01023    case AST_TRANS_CAP_SPEECH:
01024       return "SPEECH";
01025    case AST_TRANS_CAP_DIGITAL:
01026       return "DIGITAL";
01027    case AST_TRANS_CAP_RESTRICTED_DIGITAL:
01028       return "RESTRICTED_DIGITAL";
01029    case AST_TRANS_CAP_3_1K_AUDIO:
01030       return "3K1AUDIO";
01031    case AST_TRANS_CAP_DIGITAL_W_TONES:
01032       return "DIGITAL_W_TONES";
01033    case AST_TRANS_CAP_VIDEO:
01034       return "VIDEO";
01035    default:
01036       return "UNKNOWN";
01037    }
01038 }

void ast_uninstall_music_functions ( void   ) 

Definition at line 7771 of file channel.c.

References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.

Referenced by unload_module().

07772 {
07773    ast_moh_start_ptr = NULL;
07774    ast_moh_stop_ptr = NULL;
07775    ast_moh_cleanup_ptr = NULL;
07776 }

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

03464 {
03465    int oldms = ms;   /* -1 if no timeout */
03466 
03467    ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms);
03468    if ((ms < 0) && (oldms < 0))
03469       ms = 0;
03470    return ms;
03471 }

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 3458 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(), rpt(), wait_for_answer(), and wait_for_winner().

03459 {
03460    return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
03461 }

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

References ast_waitfor_nandfds().

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

03100 {
03101    int winner = -1;
03102    ast_waitfor_nandfds(NULL, 0, fds, n, exception, &winner, ms);
03103    return winner;
03104 }

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

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

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

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

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

References ast_waitfordigit_full().

Referenced by __analog_ss_thread(), _while_exec(), advanced_options(), analog_my_getsigstr(), analog_ss_thread(), ast_adsi_get_cpeid(), ast_adsi_get_cpeinfo(), ast_adsi_print(), ast_adsi_read_encoded_dtmf(), ast_adsi_transmit_message_full(), 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().

03475 {
03476    return ast_waitfordigit_full(c, ms, -1, -1);
03477 }

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

References ast_check_hangup(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UPDATE_RTP_PEER, AST_FLAG_END_DTMF_ONLY, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_frfree, ast_log(), ast_read(), ast_set_flag, ast_test_flag, ast_waitfor_nandfds(), errno, f, and LOG_WARNING.

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

03513 {
03514    /* Stop if we're a zombie or need a soft hangup */
03515    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
03516       return -1;
03517 
03518    /* Only look for the end of DTMF, don't bother with the beginning and don't emulate things */
03519    ast_set_flag(c, AST_FLAG_END_DTMF_ONLY);
03520 
03521    /* Wait for a digit, no more than ms milliseconds total. */
03522    
03523    while (ms) {
03524       struct ast_channel *rchan;
03525       int outfd=-1;
03526 
03527       errno = 0;
03528       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
03529       
03530       if (!rchan && outfd < 0 && ms) {
03531          if (errno == 0 || errno == EINTR)
03532             continue;
03533          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
03534          ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03535          return -1;
03536       } else if (outfd > -1) {
03537          /* The FD we were watching has something waiting */
03538          ast_log(LOG_WARNING, "The FD we were waiting for has something waiting. Waitfordigit returning numeric 1\n");
03539          ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03540          return 1;
03541       } else if (rchan) {
03542          int res;
03543          struct ast_frame *f = ast_read(c);
03544          if (!f)
03545             return -1;
03546 
03547          switch (f->frametype) {
03548          case AST_FRAME_DTMF_BEGIN:
03549             break;
03550          case AST_FRAME_DTMF_END:
03551             res = f->subclass.integer;
03552             ast_frfree(f);
03553             ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03554             return res;
03555          case AST_FRAME_CONTROL:
03556             switch (f->subclass.integer) {
03557             case AST_CONTROL_HANGUP:
03558                ast_frfree(f);
03559                ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03560                return -1;
03561             case AST_CONTROL_RINGING:
03562             case AST_CONTROL_ANSWER:
03563             case AST_CONTROL_SRCUPDATE:
03564             case AST_CONTROL_SRCCHANGE:
03565             case AST_CONTROL_CONNECTED_LINE:
03566             case AST_CONTROL_REDIRECTING:
03567             case AST_CONTROL_UPDATE_RTP_PEER:
03568             case -1:
03569                /* Unimportant */
03570                break;
03571             default:
03572                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass.integer);
03573                break;
03574             }
03575             break;
03576          case AST_FRAME_VOICE:
03577             /* Write audio if appropriate */
03578             if (audiofd > -1) {
03579                if (write(audiofd, f->data.ptr, f->datalen) < 0) {
03580                   ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
03581                }
03582             }
03583          default:
03584             /* Ignore */
03585             break;
03586          }
03587          ast_frfree(f);
03588       }
03589    }
03590 
03591    ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03592 
03593    return 0; /* Time is up */
03594 }

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 4767 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(), function_ilink(), gen_generate(), generic_fax_exec(), handle_jack_audio(), handle_link_data(), 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(), rpt(), send_link_dtmf(), send_link_keyquery(), send_tone_burst(), send_usb_txt(), send_waveform_to_channel(), silence_generator_generate(), simple_bridge_write(), softmix_bridge_poke(), softmix_bridge_write(), spy_generate(), and t38_tx_packet_handler().

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

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

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

04653 {
04654    int res;
04655    if (!chan->tech->write_video)
04656       return 0;
04657    res = ast_write(chan, fr);
04658    if (!res)
04659       res = 1;
04660    return res;
04661 }

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

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

07236 {
07237    const char *s, *sound;
07238 
07239    /* See if we need to play an audio file to any side of the bridge */
07240 
07241    ast_channel_lock(c0);
07242    if ((s = pbx_builtin_getvar_helper(c0, "BRIDGE_PLAY_SOUND"))) {
07243       sound = ast_strdupa(s);
07244       ast_channel_unlock(c0);
07245       bridge_playfile(c0, c1, sound, 0);
07246       pbx_builtin_setvar_helper(c0, "BRIDGE_PLAY_SOUND", NULL);
07247    } else {
07248       ast_channel_unlock(c0);
07249    }
07250 
07251    ast_channel_lock(c1);
07252    if ((s = pbx_builtin_getvar_helper(c1, "BRIDGE_PLAY_SOUND"))) {
07253       sound = ast_strdupa(s);
07254       ast_channel_unlock(c1);
07255       bridge_playfile(c1, c0, sound, 0);
07256       pbx_builtin_setvar_helper(c1, "BRIDGE_PLAY_SOUND", NULL);
07257    } else {
07258       ast_channel_unlock(c1);
07259    }
07260 }

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

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

06930 {
06931    int min = 0, sec = 0, check;
06932 
06933    check = ast_autoservice_start(peer);
06934    if (check)
06935       return;
06936 
06937    if (remain > 0) {
06938       if (remain / 60 > 1) {
06939          min = remain / 60;
06940          sec = remain % 60;
06941       } else {
06942          sec = remain;
06943       }
06944    }
06945    
06946    if (!strcmp(sound,"timeleft")) { /* Queue support */
06947       ast_stream_and_wait(chan, "vm-youhave", "");
06948       if (min) {
06949          ast_say_number(chan, min, AST_DIGIT_ANY, chan->language, NULL);
06950          ast_stream_and_wait(chan, "queue-minutes", "");
06951       }
06952       if (sec) {
06953          ast_say_number(chan, sec, AST_DIGIT_ANY, chan->language, NULL);
06954          ast_stream_and_wait(chan, "queue-seconds", "");
06955       }
06956    } else {
06957       ast_stream_and_wait(chan, sound, "");
06958    }
06959 
06960    ast_autoservice_stop(peer);
06961 }

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

Referenced by __ast_read(), and ast_write().

03703 {
03704    int diff = sample_rate - seek_rate;
03705 
03706    if (diff > 0) {
03707       samples = samples / (float) (sample_rate / seek_rate);
03708    } else if (diff < 0) {
03709       samples = samples * (float) (seek_rate / sample_rate);
03710    }
03711 
03712    return samples;
03713 }

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

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

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

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

Definition at line 9401 of file channel.c.

References ast_cc_config_params_init, and ast_cc_copy_config_params().

09402 {
09403    const struct ast_cc_config_params *src = data;
09404    struct ast_cc_config_params *dest = ast_cc_config_params_init();
09405    if (!dest) {
09406       return NULL;
09407    }
09408    ast_cc_copy_config_params(dest, src);
09409    return dest;
09410 }

static void channel_cc_params_destroy ( void *  data  )  [static]

Definition at line 9412 of file channel.c.

References ast_cc_config_params_destroy().

09413 {
09414    struct ast_cc_config_params *cc_params = data;
09415    ast_cc_config_params_destroy(cc_params);
09416 }

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

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

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

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

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

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

References CHANNEL_CLI_RELOAD, CHANNEL_MODULE_LOAD, and CHANNEL_MODULE_RELOAD.

08077 {
08078    switch (reason) {
08079    case CHANNEL_MODULE_LOAD:
08080       return "LOAD (Channel module load)";
08081 
08082    case CHANNEL_MODULE_RELOAD:
08083       return "RELOAD (Channel module reload)";
08084 
08085    case CHANNEL_CLI_RELOAD:
08086       return "CLIRELOAD (Channel module reload by CLI command)";
08087 
08088    default:
08089       return "MANAGERRELOAD (Channel module reload by manager)";
08090    }
08091 };

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

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

Referenced by ast_do_masquerade().

06138 {
06139    struct ast_var_t *current, *newvar;
06140    /* Append variables from clone channel into original channel */
06141    /* XXX Is this always correct?  We have to in order to keep MACROS working XXX */
06142    if (AST_LIST_FIRST(&clonechan->varshead))
06143       AST_LIST_APPEND_LIST(&original->varshead, &clonechan->varshead, entries);
06144 
06145    /* then, dup the varshead list into the clone */
06146    
06147    AST_LIST_TRAVERSE(&original->varshead, current, entries) {
06148       newvar = ast_var_assign(current->name, current->value);
06149       if (newvar)
06150          AST_LIST_INSERT_TAIL(&clonechan->varshead, newvar, entries);
06151    }
06152 }

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

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

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

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

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

07837 {
07838    struct ast_channel *c;
07839    struct ast_channel_iterator *iter = NULL;
07840    struct ast_data *data_channel;
07841 
07842    for (iter = ast_channel_iterator_all_new();
07843       iter && (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) {
07844       ast_channel_lock(c);
07845 
07846       data_channel = ast_data_add_node(root, "channel");
07847       if (!data_channel) {
07848          ast_channel_unlock(c);
07849          continue;
07850       }
07851 
07852       if (ast_channel_data_add_structure(data_channel, c, 1) < 0) {
07853          ast_log(LOG_ERROR, "Unable to add channel structure for channel: %s\n", c->name);
07854       }
07855 
07856       ast_channel_unlock(c);
07857 
07858       if (!ast_data_search_match(search, data_channel)) {
07859          ast_data_remove_node(root, data_channel);
07860       }
07861    }
07862    if (iter) {
07863       ast_channel_iterator_destroy(iter);
07864    }
07865 
07866    return 0;
07867 }

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

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

07875 {
07876    struct chanlist *cl;
07877    struct ast_data *data_type;
07878 
07879    AST_RWLIST_RDLOCK(&backends);
07880    AST_RWLIST_TRAVERSE(&backends, cl, list) {
07881       data_type = ast_data_add_node(data_root, "type");
07882       if (!data_type) {
07883          continue;
07884       }
07885       ast_data_add_str(data_type, "name", cl->tech->type);
07886       ast_data_add_str(data_type, "description", cl->tech->description);
07887       ast_data_add_bool(data_type, "devicestate", cl->tech->devicestate ? 1 : 0);
07888       ast_data_add_bool(data_type, "indications", cl->tech->indicate ? 1 : 0);
07889       ast_data_add_bool(data_type, "transfer", cl->tech->transfer ? 1 : 0);
07890       ast_data_add_bool(data_type, "send_digit_begin", cl->tech->send_digit_begin ? 1 : 0);
07891       ast_data_add_bool(data_type, "send_digit_end", cl->tech->send_digit_end ? 1 : 0);
07892       ast_data_add_bool(data_type, "call", cl->tech->call ? 1 : 0);
07893       ast_data_add_bool(data_type, "hangup", cl->tech->hangup ? 1 : 0);
07894       ast_data_add_bool(data_type, "answer", cl->tech->answer ? 1 : 0);
07895       ast_data_add_bool(data_type, "read", cl->tech->read ? 1 : 0);
07896       ast_data_add_bool(data_type, "write", cl->tech->write ? 1 : 0);
07897       ast_data_add_bool(data_type, "send_text", cl->tech->send_text ? 1 : 0);
07898       ast_data_add_bool(data_type, "send_image", cl->tech->send_image ? 1 : 0);
07899       ast_data_add_bool(data_type, "send_html", cl->tech->send_html ? 1 : 0);
07900       ast_data_add_bool(data_type, "exception", cl->tech->exception ? 1 : 0);
07901       ast_data_add_bool(data_type, "bridge", cl->tech->bridge ? 1 : 0);
07902       ast_data_add_bool(data_type, "early_bridge", cl->tech->early_bridge ? 1 : 0);
07903       ast_data_add_bool(data_type, "fixup", cl->tech->fixup ? 1 : 0);
07904       ast_data_add_bool(data_type, "setoption", cl->tech->setoption ? 1 : 0);
07905       ast_data_add_bool(data_type, "queryoption", cl->tech->queryoption ? 1 : 0);
07906       ast_data_add_bool(data_type, "write_video", cl->tech->write_video ? 1 : 0);
07907       ast_data_add_bool(data_type, "write_text", cl->tech->write_text ? 1 : 0);
07908       ast_data_add_bool(data_type, "bridged_channel", cl->tech->bridged_channel ? 1 : 0);
07909       ast_data_add_bool(data_type, "func_channel_read", cl->tech->func_channel_read ? 1 : 0);
07910       ast_data_add_bool(data_type, "func_channel_write", cl->tech->func_channel_write ? 1 : 0);
07911       ast_data_add_bool(data_type, "get_base_channel", cl->tech->get_base_channel ? 1 : 0);
07912       ast_data_add_bool(data_type, "set_base_channel", cl->tech->set_base_channel ? 1 : 0);
07913       ast_data_add_bool(data_type, "get_pvt_uniqueid", cl->tech->get_pvt_uniqueid ? 1 : 0);
07914       ast_data_add_bool(data_type, "cc_callback", cl->tech->cc_callback ? 1 : 0);
07915 
07916       ast_data_add_codecs(data_type, "capabilities", cl->tech->capabilities);
07917 
07918       if (!ast_data_search_match(search, data_type)) {
07919          ast_data_remove_node(data_root, data_type);
07920       }
07921    }
07922    AST_RWLIST_UNLOCK(&backends);
07923 
07924    return 0;
07925 }

static void free_translation ( struct ast_channel clonechan  )  [static]

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

02703 {
02704    if (clonechan->writetrans)
02705       ast_translator_free_path(clonechan->writetrans);
02706    if (clonechan->readtrans)
02707       ast_translator_free_path(clonechan->readtrans);
02708    clonechan->writetrans = NULL;
02709    clonechan->readtrans = NULL;
02710    clonechan->rawwriteformat = clonechan->nativeformats;
02711    clonechan->rawreadformat = clonechan->nativeformats;
02712 }

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

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

03045 {
03046    /* Called if generator doesn't have data */
03047    void *tmp;
03048    int res;
03049    int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = NULL;
03050    struct ast_channel *chan = (struct ast_channel *)data;
03051 
03052    ast_channel_lock(chan);
03053    tmp = chan->generatordata;
03054    chan->generatordata = NULL;
03055    if (chan->generator)
03056       generate = chan->generator->generate;
03057    ast_channel_unlock(chan);
03058 
03059    if (!tmp || !generate)
03060       return 0;
03061 
03062    res = generate(chan, tmp, 0, ast_format_rate(chan->writeformat & AST_FORMAT_AUDIO_MASK) / 50);
03063 
03064    chan->generatordata = tmp;
03065 
03066    if (res) {
03067       ast_debug(1, "Auto-deactivating generator\n");
03068       ast_deactivate_generator(chan);
03069    }
03070 
03071    return 0;
03072 }

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

Definition at line 5186 of file channel.c.

References AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CONTROL_BUSY, and AST_CONTROL_CONGESTION.

05187 {
05188    if (outstate) {
05189       /* compute error and return */
05190       if (cause == AST_CAUSE_BUSY)
05191          *outstate = AST_CONTROL_BUSY;
05192       else if (cause == AST_CAUSE_CONGESTION)
05193          *outstate = AST_CONTROL_CONGESTION;
05194       else
05195          *outstate = 0;
05196    }
05197 }

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

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

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

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

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

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

04268 {
04269    /* Don't include a default case here so that we get compiler warnings
04270     * when a new type is added. */
04271 
04272    switch (condition) {
04273    case AST_CONTROL_PROGRESS:
04274    case AST_CONTROL_PROCEEDING:
04275    case AST_CONTROL_VIDUPDATE:
04276    case AST_CONTROL_SRCUPDATE:
04277    case AST_CONTROL_SRCCHANGE:
04278    case AST_CONTROL_RADIO_KEY:
04279    case AST_CONTROL_RADIO_UNKEY:
04280    case AST_CONTROL_OPTION:
04281    case AST_CONTROL_WINK:
04282    case AST_CONTROL_FLASH:
04283    case AST_CONTROL_OFFHOOK:
04284    case AST_CONTROL_TAKEOFFHOOK:
04285    case AST_CONTROL_ANSWER:
04286    case AST_CONTROL_HANGUP:
04287    case AST_CONTROL_CONNECTED_LINE:
04288    case AST_CONTROL_REDIRECTING:
04289    case AST_CONTROL_TRANSFER:
04290    case AST_CONTROL_T38_PARAMETERS:
04291    case _XXX_AST_CONTROL_T38:
04292    case AST_CONTROL_CC:
04293    case AST_CONTROL_READ_ACTION:
04294    case AST_CONTROL_AOC:
04295    case AST_CONTROL_END_OF_Q:
04296    case AST_CONTROL_UPDATE_RTP_PEER:
04297       break;
04298 
04299    case AST_CONTROL_INCOMPLETE:
04300    case AST_CONTROL_CONGESTION:
04301    case AST_CONTROL_BUSY:
04302    case AST_CONTROL_RINGING:
04303    case AST_CONTROL_RING:
04304    case AST_CONTROL_HOLD:
04305       /* You can hear these */
04306       return 1;
04307 
04308    case AST_CONTROL_UNHOLD:
04309       /* This is a special case.  You stop hearing this. */
04310       break;
04311    }
04312 
04313    return 0;
04314 }

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

Definition at line 620 of file channel.c.

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

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

Definition at line 632 of file channel.c.

00633 {
00634    /* No problem fixing up the channel. */
00635    return 0;
00636 }

static int kill_hangup ( struct ast_channel chan  )  [static]

Definition at line 638 of file channel.c.

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

00639 {
00640    chan->tech_pvt = NULL;
00641    return 0;
00642 }

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

Definition at line 614 of file channel.c.

00615 {
00616    /* Hangup channel. */
00617    return NULL;
00618 }

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

Definition at line 626 of file channel.c.

00627 {
00628    /* Hangup channel. */
00629    return -1;
00630 }

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

07179 {
07180    struct ast_channel *chans[2] = { c0, c1 };
07181    ast_manager_event_multichan(EVENT_FLAG_CALL, "Bridge", 2, chans,
07182       "Bridgestate: %s\r\n"
07183       "Bridgetype: %s\r\n"
07184       "Channel1: %s\r\n"
07185       "Channel2: %s\r\n"
07186       "Uniqueid1: %s\r\n"
07187       "Uniqueid2: %s\r\n"
07188       "CallerID1: %s\r\n"
07189       "CallerID2: %s\r\n",
07190       onoff ? "Link" : "Unlink",
07191       type == 1 ? "core" : "native",
07192       c0->name, c1->name,
07193       c0->uniqueid, c1->uniqueid,
07194       S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, ""),
07195       S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, ""));
07196 }

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

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

06344 {
06345    struct ast_control_read_action_payload *frame_payload;
06346    int payload_size;
06347    int frame_size;
06348    unsigned char connected_line_data[1024];
06349 
06350    /* Release any hold on the target. */
06351    if (colp->target_held) {
06352       ast_queue_control(transferee, AST_CONTROL_UNHOLD);
06353    }
06354 
06355    /*
06356     * Since transferee may not actually be bridged to another channel,
06357     * there is no way for us to queue a frame so that its connected
06358     * line status will be updated.  Instead, we use the somewhat
06359     * hackish approach of using a special control frame type that
06360     * instructs ast_read() to perform a specific action.  In this
06361     * case, the frame we queue tells ast_read() to call the
06362     * connected line interception macro configured for transferee.
06363     */
06364    payload_size = ast_connected_line_build_data(connected_line_data,
06365       sizeof(connected_line_data), &colp->target_id, NULL);
06366    if (payload_size != -1) {
06367       frame_size = payload_size + sizeof(*frame_payload);
06368       frame_payload = alloca(frame_size);
06369       frame_payload->action = AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO;
06370       frame_payload->payload_size = payload_size;
06371       memcpy(frame_payload->payload, connected_line_data, payload_size);
06372       ast_queue_control_data(transferee, AST_CONTROL_READ_ACTION, frame_payload,
06373          frame_size);
06374    }
06375    /*
06376     * In addition to queueing the read action frame so that the
06377     * connected line info on transferee will be updated, we also are
06378     * going to queue a plain old connected line update on transferee to
06379     * update the target.
06380     */
06381    ast_channel_queue_connected_line_update(transferee, &colp->transferee_id, NULL);
06382 }

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

Definition at line 6167 of file channel.c.

References ast_strlen_zero().

Referenced by ast_channel_set_linkgroup().

06168 {
06169    const char *satime, *saseq;
06170    const char *sbtime, *sbseq;
06171    const char *dash;
06172 
06173    unsigned int atime, aseq, btime, bseq;
06174 
06175    if (ast_strlen_zero(a))
06176       return b;
06177 
06178    if (ast_strlen_zero(b))
06179       return a;
06180 
06181    satime = a;
06182    sbtime = b;
06183 
06184    /* jump over the system name */
06185    if ((dash = strrchr(satime, '-'))) {
06186       satime = dash+1;
06187    }
06188    if ((dash = strrchr(sbtime, '-'))) {
06189       sbtime = dash+1;
06190    }
06191 
06192    /* the sequence comes after the '.' */
06193    saseq = strchr(satime, '.');
06194    sbseq = strchr(sbtime, '.');
06195    if (!saseq || !sbseq)
06196       return NULL;
06197    saseq++;
06198    sbseq++;
06199 
06200    /* convert it all to integers */
06201    atime = atoi(satime); /* note that atoi is ignoring the '.' after the time string */
06202    btime = atoi(sbtime); /* note that atoi is ignoring the '.' after the time string */
06203    aseq = atoi(saseq);
06204    bseq = atoi(sbseq);
06205 
06206    /* and finally compare */
06207    if (atime == btime) {
06208       return (aseq < bseq) ? a : b;
06209    }
06210    else {
06211       return (atime < btime) ? a : b;
06212    }
06213 }

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

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

05975 {
05976    struct ast_party_connected_line connected;
05977 
05978    connected = *((struct ast_party_connected_line *) src);
05979    connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
05980 
05981    /* Make sure empty strings will be erased. */
05982    if (!connected.id.name.str) {
05983       connected.id.name.str = "";
05984    }
05985    if (!connected.id.number.str) {
05986       connected.id.number.str = "";
05987    }
05988    if (!connected.id.subaddress.str) {
05989       connected.id.subaddress.str = "";
05990    }
05991    if (!connected.id.tag) {
05992       connected.id.tag = "";
05993    }
05994 
05995    ast_party_connected_line_copy(dest, &connected);
05996 }

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

08429 {
08430    size_t length;
08431    size_t pos = 0;
08432    int res;
08433 
08434    /*
08435     * The size of integer values must be fixed in case the frame is
08436     * shipped to another machine.
08437     */
08438 
08439    if (!update || update->name) {
08440       res = party_name_build_data(data + pos, datalen - pos, &id->name, label,
08441          &ies->name);
08442       if (res < 0) {
08443          return -1;
08444       }
08445       pos += res;
08446    }
08447 
08448    if (!update || update->number) {
08449       res = party_number_build_data(data + pos, datalen - pos, &id->number, label,
08450          &ies->number);
08451       if (res < 0) {
08452          return -1;
08453       }
08454       pos += res;
08455    }
08456 
08457    if (!update || update->subaddress) {
08458       res = party_subaddress_build_data(data + pos, datalen - pos, &id->subaddress,
08459          label, &ies->subaddress);
08460       if (res < 0) {
08461          return -1;
08462       }
08463       pos += res;
08464    }
08465 
08466    /* *************** Party id user tag **************************** */
08467    if (id->tag) {
08468       length = strlen(id->tag);
08469       if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08470          ast_log(LOG_WARNING, "No space left for %s tag\n", label);
08471          return -1;
08472       }
08473       data[pos++] = ies->tag;
08474       data[pos++] = length;
08475       memcpy(data + pos, id->tag, length);
08476       pos += length;
08477    }
08478 
08479    /* *************** Party id combined presentation *************** */
08480    if (!update || update->number) {
08481       int presentation;
08482 
08483       if (!update || update->name) {
08484          presentation = ast_party_id_presentation(id);
08485       } else {
08486          /*
08487           * We must compromise because not all the information is available
08488           * to determine a combined presentation value.
08489           * We will only send the number presentation instead.
08490           */
08491          presentation = id->number.presentation;
08492       }
08493 
08494       if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08495          ast_log(LOG_WARNING, "No space left for %s combined presentation\n", label);
08496          return -1;
08497       }
08498       data[pos++] = ies->combined_presentation;
08499       data[pos++] = 1;
08500       data[pos++] = presentation;
08501    }
08502 
08503    return pos;
08504 }

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

08201 {
08202    size_t length;
08203    size_t pos = 0;
08204 
08205    /*
08206     * The size of integer values must be fixed in case the frame is
08207     * shipped to another machine.
08208     */
08209    if (name->str) {
08210       length = strlen(name->str);
08211       if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08212          ast_log(LOG_WARNING, "No space left for %s name\n", label);
08213          return -1;
08214       }
08215       data[pos++] = ies->str;
08216       data[pos++] = length;
08217       memcpy(data + pos, name->str, length);
08218       pos += length;
08219    }
08220 
08221    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08222       ast_log(LOG_WARNING, "No space left for %s name char set\n", label);
08223       return -1;
08224    }
08225    data[pos++] = ies->char_set;
08226    data[pos++] = 1;
08227    data[pos++] = name->char_set;
08228 
08229    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08230       ast_log(LOG_WARNING, "No space left for %s name presentation\n", label);
08231       return -1;
08232    }
08233    data[pos++] = ies->presentation;
08234    data[pos++] = 1;
08235    data[pos++] = name->presentation;
08236 
08237    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08238       ast_log(LOG_WARNING, "No space left for %s name valid\n", label);
08239       return -1;
08240    }
08241    data[pos++] = ies->valid;
08242    data[pos++] = 1;
08243    data[pos++] = name->valid;
08244 
08245    return pos;
08246 }

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

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 (number->str) {
08284       length = strlen(number->str);
08285       if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08286          ast_log(LOG_WARNING, "No space left for %s number\n", label);
08287          return -1;
08288       }
08289       data[pos++] = ies->str;
08290       data[pos++] = length;
08291       memcpy(data + pos, number->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 numbering plan\n", label);
08297       return -1;
08298    }
08299    data[pos++] = ies->plan;
08300    data[pos++] = 1;
08301    data[pos++] = number->plan;
08302 
08303    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08304       ast_log(LOG_WARNING, "No space left for %s number presentation\n", label);
08305       return -1;
08306    }
08307    data[pos++] = ies->presentation;
08308    data[pos++] = 1;
08309    data[pos++] = number->presentation;
08310 
08311    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08312       ast_log(LOG_WARNING, "No space left for %s number valid\n", label);
08313       return -1;
08314    }
08315    data[pos++] = ies->valid;
08316    data[pos++] = 1;
08317    data[pos++] = number->valid;
08318 
08319    return pos;
08320 }

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

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 (subaddress->str) {
08358       length = strlen(subaddress->str);
08359       if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08360          ast_log(LOG_WARNING, "No space left for %s subaddress\n", label);
08361          return -1;
08362       }
08363       data[pos++] = ies->str;
08364       data[pos++] = length;
08365       memcpy(data + pos, subaddress->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 type of subaddress\n", label);
08371       return -1;
08372    }
08373    data[pos++] = ies->type;
08374    data[pos++] = 1;
08375    data[pos++] = subaddress->type;
08376 
08377    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08378       ast_log(LOG_WARNING,
08379          "No space left for %s subaddress odd-even indicator\n", label);
08380       return -1;
08381    }
08382    data[pos++] = ies->odd_even_indicator;
08383    data[pos++] = 1;
08384    data[pos++] = subaddress->odd_even_indicator;
08385 
08386    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08387       ast_log(LOG_WARNING, "No space left for %s subaddress valid\n", label);
08388       return -1;
08389    }
08390    data[pos++] = ies->valid;
08391    data[pos++] = 1;
08392    data[pos++] = subaddress->valid;
08393 
08394    return pos;
08395 }

static void plc_ds_destroy ( void *  data  )  [static]

Definition at line 4676 of file channel.c.

References ast_free, and plc_ds::samples_buf.

04677 {
04678    struct plc_ds *plc = data;
04679    ast_free(plc->samples_buf);
04680    ast_free(plc);
04681 }

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

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

03658 {
03659    struct ast_frame *fr = &chan->dtmff;
03660 
03661    fr->frametype = AST_FRAME_DTMF_END;
03662    fr->subclass.integer = f->subclass.integer;
03663    fr->len = f->len;
03664 
03665    /* The only time this function will be called is for a frame that just came
03666     * out of the channel driver.  So, we want to stick it on the tail of the
03667     * readq. */
03668 
03669    ast_queue_frame(chan, fr);
03670 }

static void report_new_callerid ( struct ast_channel chan  )  [static]

Precondition:
chan is locked

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

06314 {
06315    int pres;
06316 
06317    pres = ast_party_id_presentation(&chan->caller.id);
06318    ast_manager_event(chan, EVENT_FLAG_CALL, "NewCallerid",
06319       "Channel: %s\r\n"
06320       "CallerIDNum: %s\r\n"
06321       "CallerIDName: %s\r\n"
06322       "Uniqueid: %s\r\n"
06323       "CID-CallingPres: %d (%s)\r\n",
06324       chan->name,
06325       S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
06326       S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""),
06327       chan->uniqueid,
06328       pres,
06329       ast_describe_caller_presentation(pres)
06330       );
06331 }

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

03597 {
03598    ast_manager_event(chan, EVENT_FLAG_DTMF,
03599          "DTMF",
03600          "Channel: %s\r\n"
03601          "Uniqueid: %s\r\n"
03602          "Digit: %c\r\n"
03603          "Direction: %s\r\n"
03604          "Begin: %s\r\n"
03605          "End: %s\r\n",
03606          chan->name, chan->uniqueid, digit, direction, begin, end);
03607 }

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

05070 {
05071    format_t native, native_fmt = ast_best_codec(fmt);
05072    int res;
05073    char from[200], to[200];
05074    
05075    /* Make sure we only consider audio */
05076    fmt &= AST_FORMAT_AUDIO_MASK;
05077    
05078    native = chan->nativeformats;
05079 
05080    if (!fmt || !native) /* No audio requested */
05081       return 0;   /* Let's try a call without any sounds (video, text) */
05082 
05083    /* See if the underlying channel driver is capable of performing transcoding for us */
05084    if (!ast_channel_setoption(chan, direction ? AST_OPTION_FORMAT_WRITE : AST_OPTION_FORMAT_READ, &native_fmt, sizeof(int*), 0)) {
05085       ast_debug(1, "Channel driver natively set channel %s to %s format %s\n", chan->name,
05086            direction ? "write" : "read", ast_getformatname(native_fmt));
05087       chan->nativeformats = *rawformat = *format = native_fmt;
05088       if (*trans) {
05089          ast_translator_free_path(*trans);
05090       }
05091       *trans = NULL;
05092       return 0;
05093    }
05094 
05095    /* Find a translation path from the native format to one of the desired formats */
05096    if (!direction)
05097       /* reading */
05098       res = ast_translator_best_choice(&fmt, &native);
05099    else
05100       /* writing */
05101       res = ast_translator_best_choice(&native, &fmt);
05102 
05103    if (res < 0) {
05104       ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n",
05105          ast_getformatname_multiple(from, sizeof(from), native),
05106          ast_getformatname_multiple(to, sizeof(to), fmt));
05107       return -1;
05108    }
05109    
05110    /* Now we have a good choice for both. */
05111    ast_channel_lock(chan);
05112 
05113    if ((*rawformat == native) && (*format == fmt) && ((*rawformat == *format) || (*trans))) {
05114       /* the channel is already in these formats, so nothing to do */
05115       ast_channel_unlock(chan);
05116       return 0;
05117    }
05118 
05119    *rawformat = native;
05120    /* User perspective is fmt */
05121    *format = fmt;
05122    /* Free any read translation we have right now */
05123    if (*trans) {
05124       ast_translator_free_path(*trans);
05125       *trans = NULL;
05126    }
05127    /* Build a translation path from the raw format to the desired format */
05128    if (*format == *rawformat) {
05129       /*
05130        * If we were able to swap the native format to the format that
05131        * has been requested, then there is no need to try to build
05132        * a translation path.
05133        */
05134       res = 0;
05135    } else {
05136       if (!direction) {
05137          /* reading */
05138          *trans = ast_translator_build_path(*format, *rawformat);
05139       } else {
05140          /* writing */
05141          *trans = ast_translator_build_path(*rawformat, *format);
05142       }
05143       res = *trans ? 0 : -1;
05144    }
05145    ast_channel_unlock(chan);
05146    ast_debug(1, "Set channel %s to %s format %s\n", chan->name,
05147       direction ? "write" : "read", ast_getformatname(fmt));
05148    return res;
05149 }

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

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

05505 {
05506    int ops[2][2] = {
05507       {AST_OPTION_SECURE_SIGNALING, 0},
05508       {AST_OPTION_SECURE_MEDIA, 0},
05509    };
05510    int i;
05511    struct ast_channel *r = (struct ast_channel *) requestor; /* UGLY */
05512    struct ast_datastore *ds;
05513 
05514    if (!requestor || !out) {
05515       return 0;
05516    }
05517 
05518    ast_channel_lock(r);
05519    if ((ds = ast_channel_datastore_find(r, &secure_call_info, NULL))) {
05520       struct ast_secure_call_store *encrypt = ds->data;
05521       ops[0][1] = encrypt->signaling;
05522       ops[1][1] = encrypt->media;
05523    } else {
05524       ast_channel_unlock(r);
05525       return 0;
05526    }
05527    ast_channel_unlock(r);
05528 
05529    for (i = 0; i < 2; i++) {
05530       if (ops[i][1]) {
05531          if (ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0)) {
05532             /* We require a security feature, but the channel won't provide it */
05533             return -1;
05534          }
05535       } else {
05536          /* We don't care if we can't clear the option on a channel that doesn't support it */
05537          ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0);
05538       }
05539    }
05540 
05541    return 0;
05542 }

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

03676 {
03677    if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF)) {
03678       /* We're in the middle of emulating a digit, or DTMF has been
03679        * explicitly deferred.  Skip this digit, then. */
03680       return 1;
03681    }
03682          
03683    if (!ast_tvzero(chan->dtmf_tv) && 
03684          ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) {
03685       /* We're not in the middle of a digit, but it hasn't been long enough
03686        * since the last digit, so we'll have to skip DTMF for now. */
03687       return 1;
03688    }
03689 
03690    return 0;
03691 }

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

Definition at line 7996 of file channel.c.

07997 {
07998    /* just store the data pointer in the channel structure */
07999    return data;
08000 }

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

Definition at line 8007 of file channel.c.

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

08008 {
08009    short buf[samples];
08010    struct ast_frame frame = {
08011       .frametype = AST_FRAME_VOICE,
08012       .subclass.codec = AST_FORMAT_SLINEAR,
08013       .data.ptr = buf,
08014       .samples = samples,
08015       .datalen = sizeof(buf),
08016    };
08017 
08018    memset(buf, 0, sizeof(buf));
08019 
08020    if (ast_write(chan, &frame))
08021       return -1;
08022 
08023    return 0;
08024 }

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

Definition at line 8002 of file channel.c.

08003 {
08004    /* nothing to do */
08005 }

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

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

07609 {
07610    struct tonepair_state *ts;
07611    struct tonepair_def *td = params;
07612 
07613    if (!(ts = ast_calloc(1, sizeof(*ts))))
07614       return NULL;
07615    ts->origwfmt = chan->writeformat;
07616    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
07617       ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
07618       tonepair_release(NULL, ts);
07619       ts = NULL;
07620    } else {
07621       ts->fac1 = 2.0 * cos(2.0 * M_PI * (td->freq1 / 8000.0)) * 32768.0;
07622       ts->v1_1 = 0;
07623       ts->v2_1 = sin(-4.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
07624       ts->v3_1 = sin(-2.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
07625       ts->v2_1 = 0;
07626       ts->fac2 = 2.0 * cos(2.0 * M_PI * (td->freq2 / 8000.0)) * 32768.0;
07627       ts->v2_2 = sin(-4.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
07628       ts->v3_2 = sin(-2.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
07629       ts->duration = td->duration;
07630       ts->modulate = 0;
07631    }
07632    /* Let interrupts interrupt :) */
07633    ast_set_flag(chan, AST_FLAG_WRITE_INT);
07634    return ts;
07635 }

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

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

07638 {
07639    struct tonepair_state *ts = data;
07640    int x;
07641 
07642    /* we need to prepare a frame with 16 * timelen samples as we're
07643     * generating SLIN audio
07644     */
07645    len = samples * 2;
07646 
07647    if (len > sizeof(ts->data) / 2 - 1) {
07648       ast_log(LOG_WARNING, "Can't generate that much data!\n");
07649       return -1;
07650    }
07651    memset(&ts->f, 0, sizeof(ts->f));
07652    for (x=0;x<len/2;x++) {
07653       ts->v1_1 = ts->v2_1;
07654       ts->v2_1 = ts->v3_1;
07655       ts->v3_1 = (ts->fac1 * ts->v2_1 >> 15) - ts->v1_1;
07656       
07657       ts->v1_2 = ts->v2_2;
07658       ts->v2_2 = ts->v3_2;
07659       ts->v3_2 = (ts->fac2 * ts->v2_2 >> 15) - ts->v1_2;
07660       if (ts->modulate) {
07661          int p;
07662          p = ts->v3_2 - 32768;
07663          if (p < 0) p = -p;
07664          p = ((p * 9) / 10) + 1;
07665          ts->data[x] = (ts->v3_1 * p) >> 15;
07666       } else
07667          ts->data[x] = ts->v3_1 + ts->v3_2; 
07668    }
07669    ts->f.frametype = AST_FRAME_VOICE;
07670    ts->f.subclass.codec = AST_FORMAT_SLINEAR;
07671    ts->f.datalen = len;
07672    ts->f.samples = samples;
07673    ts->f.offset = AST_FRIENDLY_OFFSET;
07674    ts->f.data.ptr = ts->data;
07675    ast_write(chan, &ts->f);
07676    ts->pos += x;
07677    if (ts->duration > 0) {
07678       if (ts->pos >= ts->duration * 8)
07679          return -1;
07680    }
07681    return 0;
07682 }

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

Definition at line 7599 of file channel.c.

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

Referenced by tonepair_alloc().

07600 {
07601    struct tonepair_state *ts = params;
07602 
07603    if (chan)
07604       ast_set_write_format(chan, ts->origwfmt);
07605    ast_free(ts);
07606 }

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

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

07199 {
07200    const char *c0_name;
07201    const char *c1_name;
07202    const char *c0_pvtid = NULL;
07203    const char *c1_pvtid = NULL;
07204 
07205    ast_channel_lock(c1);
07206    c1_name = ast_strdupa(c1->name);
07207    if (c1->tech->get_pvt_uniqueid) {
07208       c1_pvtid = ast_strdupa(c1->tech->get_pvt_uniqueid(c1));
07209    }
07210    ast_channel_unlock(c1);
07211 
07212    ast_channel_lock(c0);
07213    if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER"))) {
07214       pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1_name);
07215    }
07216    if (c1_pvtid) {
07217       pbx_builtin_setvar_helper(c0, "BRIDGEPVTCALLID", c1_pvtid);
07218    }
07219    c0_name = ast_strdupa(c0->name);
07220    if (c0->tech->get_pvt_uniqueid) {
07221       c0_pvtid = ast_strdupa(c0->tech->get_pvt_uniqueid(c0));
07222    }
07223    ast_channel_unlock(c0);
07224 
07225    ast_channel_lock(c1);
07226    if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER"))) {
07227       pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0_name);
07228    }
07229    if (c0_pvtid) {
07230       pbx_builtin_setvar_helper(c1, "BRIDGEPVTCALLID", c0_pvtid);
07231    }
07232    ast_channel_unlock(c1);
07233 }

static void xfer_ds_destroy ( void *  data  )  [static]

Definition at line 6019 of file channel.c.

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

06020 {
06021    struct xfer_masquerade_ds *ds = data;
06022 
06023    ast_party_connected_line_free(&ds->target_id);
06024    ast_party_connected_line_free(&ds->transferee_id);
06025    ast_free(ds);
06026 }


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

Referenced by ast_do_masquerade().

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

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

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

int cause

Definition at line 197 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(), sig_ss7_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().

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

Referenced by ast_channel_cc_params_init(), and ast_channel_get_cc_config_params().

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

Referenced by ast_channels_init().

struct ao2_container* channels [static]

All active channels on the system.

Definition at line 190 of file channel.c.

struct ast_data_handler channels_provider [static]

Initial value:

Definition at line 7931 of file channel.c.

struct ast_data_handler channeltypes_provider [static]

Initial value:

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

Referenced by ast_channels_init().

const char* desc

Definition at line 199 of file channel.c.

unsigned long global_fin

The current value of the debug flags is stored in the two variables global_fin and global_fout (declared in main/channel.c)

Definition at line 97 of file channel.c.

Referenced by handle_core_set_debug_channel().

unsigned long global_fout

Definition at line 97 of file channel.c.

Referenced by handle_core_set_debug_channel().

const char* name

Definition at line 198 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 1099 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 4683 of file channel.c.

Referenced by apply_plc().

int shutting_down [static]

Prevent new channel allocation if shutting down.

Definition at line 93 of file channel.c.

struct ast_generator silence_generator [static]

Initial value:

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

Referenced by ast_state2str().

struct ast_generator tonepair [static]

Initial value:

 {
   alloc: tonepair_alloc,
   release: tonepair_release,
   generate: tonepair_generator,
}

Definition at line 7684 of file channel.c.

Referenced by ast_tonepair_start().

int uniqueint [static]

Definition at line 95 of file channel.c.

struct ast_datastore_info xfer_ds_info [static]

Initial value:

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

Definition at line 6028 of file channel.c.

Referenced by ast_channel_transfer_masquerade(), and ast_do_masquerade().


Generated on Sat Mar 10 01:55:16 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7