Wed Apr 6 11:30:01 2011

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/sha1.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)
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 * 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 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

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 105 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 108 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 112 of file channel.c.

Referenced by __ast_read(), and should_skip_dtmf().

#define DATA_EXPORT_CHANNEL ( MEMBER   ) 

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

Referenced by ast_channels_init().

#define STATE2STR_BUFSIZE   32

Definition at line 101 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 8248 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 8569 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 2825 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(), dial_exec_full(), pbx_builtin_answer(), and pbx_builtin_incomplete().

02826 {
02827    int res = 0;
02828    enum ast_channel_state old_state;
02829 
02830    old_state = chan->_state;
02831    if ((res = ast_raw_answer(chan, cdr_answer))) {
02832       return res;
02833    }
02834 
02835    switch (old_state) {
02836    case AST_STATE_RINGING:
02837    case AST_STATE_RING:
02838       /* wait for media to start flowing, but don't wait any longer
02839        * than 'delay' or 500 milliseconds, whichever is longer
02840        */
02841       do {
02842          AST_LIST_HEAD_NOLOCK(, ast_frame) frames;
02843          struct ast_frame *cur, *new;
02844          int ms = MAX(delay, 500);
02845          unsigned int done = 0;
02846 
02847          AST_LIST_HEAD_INIT_NOLOCK(&frames);
02848 
02849          for (;;) {
02850             ms = ast_waitfor(chan, ms);
02851             if (ms < 0) {
02852                ast_log(LOG_WARNING, "Error condition occurred when polling channel %s for a voice frame: %s\n", chan->name, strerror(errno));
02853                res = -1;
02854                break;
02855             }
02856             if (ms == 0) {
02857                ast_debug(2, "Didn't receive a media frame from %s within %d ms of answering. Continuing anyway\n", chan->name, MAX(delay, 500));
02858                break;
02859             }
02860             cur = ast_read(chan);
02861             if (!cur || ((cur->frametype == AST_FRAME_CONTROL) &&
02862                     (cur->subclass.integer == AST_CONTROL_HANGUP))) {
02863                if (cur) {
02864                   ast_frfree(cur);
02865                }
02866                res = -1;
02867                ast_debug(2, "Hangup of channel %s detected in answer routine\n", chan->name);
02868                break;
02869             }
02870 
02871             if ((new = ast_frisolate(cur)) != cur) {
02872                ast_frfree(cur);
02873             }
02874 
02875             AST_LIST_INSERT_HEAD(&frames, new, frame_list);
02876 
02877             /* if a specific delay period was requested, continue
02878              * until that delay has passed. don't stop just because
02879              * incoming media has arrived.
02880              */
02881             if (delay) {
02882                continue;
02883             }
02884 
02885             switch (new->frametype) {
02886                /* all of these frametypes qualify as 'media' */
02887             case AST_FRAME_VOICE:
02888             case AST_FRAME_VIDEO:
02889             case AST_FRAME_TEXT:
02890             case AST_FRAME_DTMF_BEGIN:
02891             case AST_FRAME_DTMF_END:
02892             case AST_FRAME_IMAGE:
02893             case AST_FRAME_HTML:
02894             case AST_FRAME_MODEM:
02895                done = 1;
02896                break;
02897             case AST_FRAME_CONTROL:
02898             case AST_FRAME_IAX:
02899             case AST_FRAME_NULL:
02900             case AST_FRAME_CNG:
02901                break;
02902             }
02903 
02904             if (done) {
02905                break;
02906             }
02907          }
02908 
02909          if (res == 0) {
02910             ast_channel_lock(chan);
02911             while ((cur = AST_LIST_REMOVE_HEAD(&frames, frame_list))) {
02912                ast_queue_frame_head(chan, cur);
02913                ast_frfree(cur);
02914             }
02915             ast_channel_unlock(chan);
02916          }
02917       } while (0);
02918       break;
02919    default:
02920       break;
02921    }
02922 
02923    return res;
02924 }

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

05851 {
05852    ast_manager_event(chan, EVENT_FLAG_CALL, "Rename", "Channel: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", chan->name, newname, chan->uniqueid);
05853    ast_string_field_set(chan, name, newname);
05854 }

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:
By default, new channels are set to the "s" extension and "default" context.

Definition at line 1295 of file channel.c.

References __ast_channel_alloc_ap().

01301 {
01302    va_list ap1, ap2;
01303    struct ast_channel *result;
01304 
01305    va_start(ap1, name_fmt);
01306    va_start(ap2, name_fmt);
01307    result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context,
01308                linkedid, amaflag, file, line, function, name_fmt, ap1, ap2);
01309    va_end(ap1);
01310    va_end(ap2);
01311 
01312    return result;
01313 }

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

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

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

Definition at line 5647 of file channel.c.

References ast_channel::_bridge, ast_bridged_channel(), ast_channel_datastore_add(), ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_debug, ast_log(), ast_null_frame, ast_queue_frame(), 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().

05648 {
05649    int res = -1;
05650    struct ast_channel *final_orig, *final_clone, *base;
05651 
05652 retrymasq:
05653    final_orig = original;
05654    final_clone = clonechan;
05655 
05656    ast_channel_lock(original);
05657    while (ast_channel_trylock(clonechan)) {
05658       ast_channel_unlock(original);
05659       usleep(1);
05660       ast_channel_lock(original);
05661    }
05662 
05663    /* each of these channels may be sitting behind a channel proxy (i.e. chan_agent)
05664       and if so, we don't really want to masquerade it, but its proxy */
05665    if (original->_bridge && (original->_bridge != ast_bridged_channel(original)) && (original->_bridge->_bridge != original))
05666       final_orig = original->_bridge;
05667 
05668    if (clonechan->_bridge && (clonechan->_bridge != ast_bridged_channel(clonechan)) && (clonechan->_bridge->_bridge != clonechan))
05669       final_clone = clonechan->_bridge;
05670    
05671    if (final_clone->tech->get_base_channel && (base = final_clone->tech->get_base_channel(final_clone))) {
05672       final_clone = base;
05673    }
05674 
05675    if ((final_orig != original) || (final_clone != clonechan)) {
05676       /* Lots and lots of deadlock avoidance.  The main one we're competing with
05677        * is ast_write(), which locks channels recursively, when working with a
05678        * proxy channel. */
05679       if (ast_channel_trylock(final_orig)) {
05680          ast_channel_unlock(clonechan);
05681          ast_channel_unlock(original);
05682          goto retrymasq;
05683       }
05684       if (ast_channel_trylock(final_clone)) {
05685          ast_channel_unlock(final_orig);
05686          ast_channel_unlock(clonechan);
05687          ast_channel_unlock(original);
05688          goto retrymasq;
05689       }
05690       ast_channel_unlock(clonechan);
05691       ast_channel_unlock(original);
05692       original = final_orig;
05693       clonechan = final_clone;
05694    }
05695 
05696    if (original == clonechan) {
05697       ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name);
05698       ast_channel_unlock(clonechan);
05699       ast_channel_unlock(original);
05700       return -1;
05701    }
05702 
05703    ast_debug(1, "Planning to masquerade channel %s into the structure of %s\n",
05704       clonechan->name, original->name);
05705 
05706    if (!original->masqr && !original->masq && !clonechan->masq && !clonechan->masqr) {
05707       original->masq = clonechan;
05708       clonechan->masqr = original;
05709       if (xfer_ds) {
05710          ast_channel_datastore_add(original, xfer_ds);
05711       }
05712       ast_queue_frame(original, &ast_null_frame);
05713       ast_queue_frame(clonechan, &ast_null_frame);
05714       ast_debug(1, "Done planning to masquerade channel %s into the structure of %s\n", clonechan->name, original->name);
05715       res = 0;
05716    } else if (original->masq) {
05717       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
05718          original->masq->name, original->name);
05719    } else if (original->masqr) {
05720       /* not yet as a previously planned masq hasn't yet happened */
05721       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
05722          original->name, original->masqr->name);
05723    } else if (clonechan->masq) {
05724       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
05725          clonechan->masq->name, clonechan->name);
05726    } else { /* (clonechan->masqr) */
05727       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
05728       clonechan->name, clonechan->masqr->name);
05729    }
05730 
05731    ast_channel_unlock(clonechan);
05732    ast_channel_unlock(original);
05733 
05734    return res;
05735 }

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

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

01351 {
01352    struct ast_frame *f;
01353    struct ast_frame *cur;
01354    int blah = 1;
01355    unsigned int new_frames = 0;
01356    unsigned int new_voice_frames = 0;
01357    unsigned int queued_frames = 0;
01358    unsigned int queued_voice_frames = 0;
01359    AST_LIST_HEAD_NOLOCK(, ast_frame) frames;
01360 
01361    ast_channel_lock(chan);
01362 
01363    /*
01364     * Check the last frame on the queue if we are queuing the new
01365     * frames after it.
01366     */
01367    cur = AST_LIST_LAST(&chan->readq);
01368    if (cur && cur->frametype == AST_FRAME_CONTROL && !head && (!after || after == cur)) {
01369       switch (cur->subclass.integer) {
01370       case AST_CONTROL_END_OF_Q:
01371          if (fin->frametype == AST_FRAME_CONTROL
01372             && fin->subclass.integer == AST_CONTROL_HANGUP) {
01373             /*
01374              * Destroy the end-of-Q marker frame so we can queue the hangup
01375              * frame in its place.
01376              */
01377             AST_LIST_REMOVE(&chan->readq, cur, frame_list);
01378             ast_frfree(cur);
01379 
01380             /*
01381              * This has degenerated to a normal queue append anyway.  Since
01382              * we just destroyed the last frame in the queue we must make
01383              * sure that "after" is NULL or bad things will happen.
01384              */
01385             after = NULL;
01386             break;
01387          }
01388          /* Fall through */
01389       case AST_CONTROL_HANGUP:
01390          /* Don't queue anything. */
01391          ast_channel_unlock(chan);
01392          return 0;
01393       default:
01394          break;
01395       }
01396    }
01397 
01398    /* Build copies of all the new frames and count them */
01399    AST_LIST_HEAD_INIT_NOLOCK(&frames);
01400    for (cur = fin; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
01401       if (!(f = ast_frdup(cur))) {
01402          if (AST_LIST_FIRST(&frames)) {
01403             ast_frfree(AST_LIST_FIRST(&frames));
01404          }
01405          ast_channel_unlock(chan);
01406          return -1;
01407       }
01408 
01409       AST_LIST_INSERT_TAIL(&frames, f, frame_list);
01410       new_frames++;
01411       if (f->frametype == AST_FRAME_VOICE) {
01412          new_voice_frames++;
01413       }
01414    }
01415 
01416    /* Count how many frames exist on the queue */
01417    AST_LIST_TRAVERSE(&chan->readq, cur, frame_list) {
01418       queued_frames++;
01419       if (cur->frametype == AST_FRAME_VOICE) {
01420          queued_voice_frames++;
01421       }
01422    }
01423 
01424    if ((queued_frames + new_frames > 128 || queued_voice_frames + new_voice_frames > 96)) {
01425       int count = 0;
01426       ast_log(LOG_WARNING, "Exceptionally long %squeue length queuing to %s\n", queued_frames + new_frames > 128 ? "" : "voice ", chan->name);
01427       AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->readq, cur, frame_list) {
01428          /* Save the most recent frame */
01429          if (!AST_LIST_NEXT(cur, frame_list)) {
01430             break;
01431          } else if (cur->frametype == AST_FRAME_VOICE || cur->frametype == AST_FRAME_VIDEO || cur->frametype == AST_FRAME_NULL) {
01432             if (++count > 64) {
01433                break;
01434             }
01435             AST_LIST_REMOVE_CURRENT(frame_list);
01436             ast_frfree(cur);
01437          }
01438       }
01439       AST_LIST_TRAVERSE_SAFE_END;
01440    }
01441 
01442    if (after) {
01443       AST_LIST_INSERT_LIST_AFTER(&chan->readq, &frames, after, frame_list);
01444    } else {
01445       if (head) {
01446          AST_LIST_APPEND_LIST(&frames, &chan->readq, frame_list);
01447          AST_LIST_HEAD_INIT_NOLOCK(&chan->readq);
01448       }
01449       AST_LIST_APPEND_LIST(&chan->readq, &frames, frame_list);
01450    }
01451 
01452    if (chan->alertpipe[1] > -1) {
01453       if (write(chan->alertpipe[1], &blah, new_frames * sizeof(blah)) != (new_frames * sizeof(blah))) {
01454          ast_log(LOG_WARNING, "Unable to write to alert pipe on %s (qlen = %d): %s!\n",
01455             chan->name, queued_frames, strerror(errno));
01456       }
01457    } else if (chan->timingfd > -1) {
01458       ast_timer_enable_continuous(chan->timer);
01459    } else if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
01460       pthread_kill(chan->blocker, SIGURG);
01461    }
01462 
01463    ast_channel_unlock(chan);
01464 
01465    return 0;
01466 }

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

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

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

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 5151 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_set_connected_line(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CC, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, 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().

05152 {
05153    int dummy_outstate;
05154    int cause = 0;
05155    struct ast_channel *chan;
05156    int res = 0;
05157    int last_subclass = 0;
05158    struct ast_party_connected_line connected;
05159    
05160    if (outstate)
05161       *outstate = 0;
05162    else
05163       outstate = &dummy_outstate;   /* make outstate always a valid pointer */
05164 
05165    chan = ast_request(type, format, requestor, data, &cause);
05166    if (!chan) {
05167       ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
05168       handle_cause(cause, outstate);
05169       return NULL;
05170    }
05171 
05172    if (oh) {
05173       if (oh->vars)  
05174          ast_set_variables(chan, oh->vars);
05175       /* XXX why is this necessary, for the parent_channel perhaps ? */
05176       if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name))
05177          ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num);
05178       if (oh->parent_channel) {
05179          ast_channel_inherit_variables(oh->parent_channel, chan);
05180          ast_channel_datastore_inherit(oh->parent_channel, chan);
05181       }
05182       if (oh->account)
05183          ast_cdr_setaccount(chan, oh->account); 
05184    }
05185 
05186    ast_set_callerid(chan, cid_num, cid_name, cid_num);
05187    ast_set_flag(chan->cdr, AST_CDR_FLAG_ORIGINATED);
05188    ast_party_connected_line_set_init(&connected, &chan->connected);
05189    if (cid_num) {
05190       connected.id.number.valid = 1;
05191       connected.id.number.str = (char *) cid_num;
05192       connected.id.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
05193    }
05194    if (cid_name) {
05195       connected.id.name.valid = 1;
05196       connected.id.name.str = (char *) cid_name;
05197       connected.id.name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
05198    }
05199    ast_channel_set_connected_line(chan, &connected, NULL);
05200 
05201    if (ast_call(chan, data, 0)) {   /* ast_call failed... */
05202       ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
05203    } else {
05204       res = 1; /* mark success in case chan->_state is already AST_STATE_UP */
05205       while (timeout && chan->_state != AST_STATE_UP) {
05206          struct ast_frame *f;
05207          res = ast_waitfor(chan, timeout);
05208          if (res == 0) { /* timeout, treat it like ringing */
05209             *outstate = AST_CONTROL_RINGING;
05210             break;
05211          }
05212          if (res < 0) /* error or done */
05213             break;
05214          if (timeout > -1)
05215             timeout = res;
05216          if (!ast_strlen_zero(chan->call_forward)) {
05217             if (!(chan = ast_call_forward(NULL, chan, NULL, format, oh, outstate))) {
05218                return NULL;
05219             }
05220             continue;
05221          }
05222 
05223          f = ast_read(chan);
05224          if (!f) {
05225             *outstate = AST_CONTROL_HANGUP;
05226             res = 0;
05227             break;
05228          }
05229          if (f->frametype == AST_FRAME_CONTROL) {
05230             switch (f->subclass.integer) {
05231             case AST_CONTROL_RINGING:  /* record but keep going */
05232                *outstate = f->subclass.integer;
05233                break;
05234 
05235             case AST_CONTROL_BUSY:
05236                ast_cdr_busy(chan->cdr);
05237                *outstate = f->subclass.integer;
05238                timeout = 0;
05239                break;
05240 
05241             case AST_CONTROL_CONGESTION:
05242                ast_cdr_failed(chan->cdr);
05243                *outstate = f->subclass.integer;
05244                timeout = 0;
05245                break;
05246 
05247             case AST_CONTROL_ANSWER:
05248                ast_cdr_answer(chan->cdr);
05249                *outstate = f->subclass.integer;
05250                timeout = 0;      /* trick to force exit from the while() */
05251                break;
05252 
05253             /* Ignore these */
05254             case AST_CONTROL_PROGRESS:
05255             case AST_CONTROL_PROCEEDING:
05256             case AST_CONTROL_HOLD:
05257             case AST_CONTROL_UNHOLD:
05258             case AST_CONTROL_VIDUPDATE:
05259             case AST_CONTROL_SRCUPDATE:
05260             case AST_CONTROL_SRCCHANGE:
05261             case AST_CONTROL_CONNECTED_LINE:
05262             case AST_CONTROL_REDIRECTING:
05263             case AST_CONTROL_CC:
05264             case -1:       /* Ignore -- just stopping indications */
05265                break;
05266 
05267             default:
05268                ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass.integer);
05269             }
05270             last_subclass = f->subclass.integer;
05271          }
05272          ast_frfree(f);
05273       }
05274    }
05275 
05276    /* Final fixups */
05277    if (oh) {
05278       if (!ast_strlen_zero(oh->context))
05279          ast_copy_string(chan->context, oh->context, sizeof(chan->context));
05280       if (!ast_strlen_zero(oh->exten))
05281          ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten));
05282       if (oh->priority) 
05283          chan->priority = oh->priority;
05284    }
05285    if (chan->_state == AST_STATE_UP)
05286       *outstate = AST_CONTROL_ANSWER;
05287 
05288    if (res <= 0) {
05289       if ( AST_CONTROL_RINGING == last_subclass ) 
05290          chan->hangupcause = AST_CAUSE_NO_ANSWER;
05291       if (!chan->cdr && (chan->cdr = ast_cdr_alloc()))
05292          ast_cdr_init(chan->cdr, chan);
05293       if (chan->cdr) {
05294          char tmp[256];
05295          snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data);
05296          ast_cdr_setapp(chan->cdr,"Dial",tmp);
05297          ast_cdr_update(chan);
05298          ast_cdr_start(chan->cdr);
05299          ast_cdr_end(chan->cdr);
05300          /* If the cause wasn't handled properly */
05301          if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
05302             ast_cdr_failed(chan->cdr);
05303       }
05304       ast_hangup(chan);
05305       chan = NULL;
05306    }
05307    return chan;
05308 }

static void __init_state2str_threadbuf ( void   )  [static]

Definition at line 100 of file channel.c.

00115 {

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

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

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

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

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

04628 {
04629    struct ast_datastore *datastore;
04630    struct plc_ds *plc;
04631 
04632    datastore = ast_channel_datastore_find(chan, &plc_ds_info, NULL);
04633    if (datastore) {
04634       plc = datastore->data;
04635       adjust_frame_for_plc(chan, frame, datastore);
04636       return;
04637    }
04638 
04639    datastore = ast_datastore_alloc(&plc_ds_info, NULL);
04640    if (!datastore) {
04641       return;
04642    }
04643    plc = ast_calloc(1, sizeof(*plc));
04644    if (!plc) {
04645       ast_datastore_free(datastore);
04646       return;
04647    }
04648    datastore->data = plc;
04649    ast_channel_datastore_add(chan, datastore);
04650    adjust_frame_for_plc(chan, frame, datastore);
04651 }

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

Activate a given generator

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

02977 {
02978    int res = 0;
02979 
02980    ast_channel_lock(chan);
02981    if (chan->generatordata) {
02982       if (chan->generator && chan->generator->release)
02983          chan->generator->release(chan, chan->generatordata);
02984       chan->generatordata = NULL;
02985    }
02986    if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) {
02987       res = -1;
02988    }
02989    if (!res) {
02990       ast_settimeout(chan, 50, generator_force, chan);
02991       chan->generator = gen;
02992    }
02993    ast_channel_unlock(chan);
02994 
02995    ast_prod(chan);
02996 
02997    return res;
02998 }

int ast_active_channels ( void   ) 

returns number of active/allocated channels

Returns:
number of active/allocated channels

Definition at line 783 of file channel.c.

References ao2_container_count(), and channels.

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

00784 {
00785    return channels ? ao2_container_count(channels) : 0;
00786 }

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 2926 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_pickup_call(), auth_exec(), background_detect_exec(), bridge_exec(), 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(), park_exec_full(), parkcall_helper(), pbx_builtin_background(), pickup_do(), 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().

02927 {
02928    return __ast_answer(chan, 0, 1);
02929 }

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

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

Referenced by quit_handler().

00774 {
00775    shutting_down = 1;
00776 
00777    if (hangup) {
00778       ao2_callback(channels, OBJ_NODATA | OBJ_MULTIPLE, ast_channel_softhangup_cb, NULL);
00779    }
00780 }

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

00993 {
00994    /* This just our opinion, expressed in code.  We are asked to choose
00995       the best codec to use, given no information */
00996    int x;
00997    static const format_t prefs[] =
00998    {
00999       /*! Okay, ulaw is used by all telephony equipment, so start with it */
01000       AST_FORMAT_ULAW,
01001       /*! Unless of course, you're a silly European, so then prefer ALAW */
01002       AST_FORMAT_ALAW,
01003       AST_FORMAT_G719,
01004       AST_FORMAT_SIREN14,
01005       AST_FORMAT_SIREN7,
01006       AST_FORMAT_TESTLAW,
01007       /*! G.722 is better then all below, but not as common as the above... so give ulaw and alaw priority */
01008       AST_FORMAT_G722,
01009       /*! Okay, well, signed linear is easy to translate into other stuff */
01010       AST_FORMAT_SLINEAR16,
01011       AST_FORMAT_SLINEAR,
01012       /*! G.726 is standard ADPCM, in RFC3551 packing order */
01013       AST_FORMAT_G726,
01014       /*! G.726 is standard ADPCM, in AAL2 packing order */
01015       AST_FORMAT_G726_AAL2,
01016       /*! ADPCM has great sound quality and is still pretty easy to translate */
01017       AST_FORMAT_ADPCM,
01018       /*! Okay, we're down to vocoders now, so pick GSM because it's small and easier to
01019           translate and sounds pretty good */
01020       AST_FORMAT_GSM,
01021       /*! iLBC is not too bad */
01022       AST_FORMAT_ILBC,
01023       /*! Speex is free, but computationally more expensive than GSM */
01024       AST_FORMAT_SPEEX16,
01025       AST_FORMAT_SPEEX,
01026       /*! Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough
01027           to use it */
01028       AST_FORMAT_LPC10,
01029       /*! G.729a is faster than 723 and slightly less expensive */
01030       AST_FORMAT_G729A,
01031       /*! Down to G.723.1 which is proprietary but at least designed for voice */
01032       AST_FORMAT_G723_1,
01033    };
01034    char buf[512];
01035 
01036    /* Strip out video */
01037    fmts &= AST_FORMAT_AUDIO_MASK;
01038    
01039    /* Find the first preferred codec in the format given */
01040    for (x = 0; x < ARRAY_LEN(prefs); x++) {
01041       if (fmts & prefs[x])
01042          return prefs[x];
01043    }
01044 
01045    ast_log(LOG_WARNING, "Don't know any of %s formats\n", ast_getformatname_multiple(buf, sizeof(buf), fmts));
01046 
01047    return 0;
01048 }

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

06675 {
06676    struct ast_channel *bridged;
06677    bridged = chan->_bridge;
06678    if (bridged && bridged->tech->bridged_channel)
06679       bridged = bridged->tech->bridged_channel(chan, bridged);
06680    return bridged;
06681 }

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

Make a call.

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

05422 {
05423    /* Place an outgoing call, but don't wait any longer than timeout ms before returning.
05424       If the remote end does not answer within the timeout, then do NOT hang up, but
05425       return anyway.  */
05426    int res = -1;
05427    /* Stop if we're a zombie or need a soft hangup */
05428    ast_channel_lock(chan);
05429    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
05430       if (chan->cdr) {
05431          ast_set_flag(chan->cdr, AST_CDR_FLAG_DIALED);
05432       }
05433       if (chan->tech->call)
05434          res = chan->tech->call(chan, addr, timeout);
05435       ast_set_flag(chan, AST_FLAG_OUTGOING);
05436    }
05437    ast_channel_unlock(chan);
05438    return res;
05439 }

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

References outgoing_helper::account, ast_channel::accountcode, accountcode, ast_call(), AST_CDR_FLAG_ORIGINATED, ast_cdr_setaccount(), ast_channel_datastore_inherit(), ast_channel_inherit_variables(), ast_channel_lock, ast_channel_set_redirecting(), ast_channel_trylock, ast_channel_unlock, ast_channel_update_redirecting(), ast_copy_flags, ast_copy_string(), ast_hangup(), ast_log(), ast_party_caller_copy(), ast_party_connected_line_copy(), ast_request(), ast_set_callerid(), ast_set_variables(), ast_string_field_set, ast_strlen_zero(), ast_channel::call_forward, ast_channel::caller, cause, ast_channel::cdr, CHANNEL_DEADLOCK_AVOIDANCE, outgoing_helper::cid_name, outgoing_helper::cid_num, 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().

05071 {
05072    char tmpchan[256];
05073    struct ast_channel *new = NULL;
05074    struct ast_party_redirecting *apr = &orig->redirecting;
05075    char *data, *type;
05076    int cause = 0;
05077    int res;
05078 
05079    /* gather data and request the new forward channel */
05080    ast_copy_string(tmpchan, orig->call_forward, sizeof(tmpchan));
05081    if ((data = strchr(tmpchan, '/'))) {
05082       *data++ = '\0';
05083       type = tmpchan;
05084    } else {
05085       const char *forward_context;
05086       ast_channel_lock(orig);
05087       forward_context = pbx_builtin_getvar_helper(orig, "FORWARD_CONTEXT");
05088       snprintf(tmpchan, sizeof(tmpchan), "%s@%s", orig->call_forward, S_OR(forward_context, orig->context));
05089       ast_channel_unlock(orig);
05090       data = tmpchan;
05091       type = "Local";
05092    }
05093    if (!(new = ast_request(type, format, orig, data, &cause))) {
05094       ast_log(LOG_NOTICE, "Unable to create channel for call forward to '%s/%s' (cause = %d)\n", type, data, cause);
05095       handle_cause(cause, outstate);
05096       ast_hangup(orig);
05097       return NULL;
05098    }
05099 
05100    ast_channel_set_redirecting(new, apr, NULL);
05101 
05102    /* Copy/inherit important information into new channel */
05103    if (oh) {
05104       if (oh->vars) {
05105          ast_set_variables(new, oh->vars);
05106       }
05107       if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) {
05108          ast_set_callerid(new, oh->cid_num, oh->cid_name, oh->cid_num);
05109       }
05110       if (oh->parent_channel) {
05111          ast_channel_update_redirecting(oh->parent_channel, apr, NULL);
05112          ast_channel_inherit_variables(oh->parent_channel, new);
05113          ast_channel_datastore_inherit(oh->parent_channel, new);
05114       }
05115       if (oh->account) {
05116          ast_cdr_setaccount(new, oh->account);
05117       }
05118    } else if (caller) { /* no outgoing helper so use caller if avaliable */
05119       ast_channel_update_redirecting(caller, apr, NULL);
05120       ast_channel_inherit_variables(caller, new);
05121       ast_channel_datastore_inherit(caller, new);
05122    }
05123 
05124    ast_channel_lock(orig);
05125    while (ast_channel_trylock(new)) {
05126       CHANNEL_DEADLOCK_AVOIDANCE(orig);
05127    }
05128    ast_copy_flags(new->cdr, orig->cdr, AST_CDR_FLAG_ORIGINATED);
05129    ast_string_field_set(new, accountcode, orig->accountcode);
05130    ast_party_caller_copy(&new->caller, &orig->caller);
05131    ast_party_connected_line_copy(&new->connected, &orig->connected);
05132    ast_channel_unlock(new);
05133    ast_channel_unlock(orig);
05134 
05135    /* call new channel */
05136    res = ast_call(new, data, 0);
05137    if (timeout) {
05138       *timeout = res;
05139    }
05140    if (res) {
05141       ast_log(LOG_NOTICE, "Unable to call forward to channel %s/%s\n", type, (char *)data);
05142       ast_hangup(orig);
05143       ast_hangup(new);
05144       return NULL;
05145    }
05146    ast_hangup(orig);
05147 
05148    return new;
05149 }

void ast_cancel_shutdown ( void   ) 

Cancel a shutdown in progress.

Cancels an existing shutdown and returns to normal operation

Definition at line 789 of file channel.c.

Referenced by handle_abort_shutdown().

00790 {
00791    shutting_down = 0;
00792 }

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

00911 {
00912    int x;
00913 
00914    for (x = 0; x < ARRAY_LEN(causes); x++) {
00915       if (causes[x].cause == cause)
00916          return causes[x].desc;
00917    }
00918 
00919    return "Unknown";
00920 }

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

05857 {
05858    /* We must re-link, as the hash value will change here. */
05859    ao2_unlink(channels, chan);
05860    ast_channel_lock(chan);
05861    __ast_change_name_nolink(chan, newname);
05862    ast_channel_unlock(chan);
05863    ao2_link(channels, chan);
05864 }

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

References __ast_channel_alloc_ap().

09261 {
09262    va_list ap1, ap2;
09263    struct ast_channel *result;
09264 
09265 
09266    va_start(ap1, name_fmt);
09267    va_start(ap2, name_fmt);
09268    result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context,
09269                linkedid, amaflag, __FILE__, __LINE__, __FUNCTION__, name_fmt, ap1, ap2);
09270    va_end(ap1);
09271    va_end(ap2);
09272 
09273    return result;
09274 }

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

07019 {
07020    struct ast_channel *chans[2] = { c0, c1 };
07021    enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
07022    format_t o0nativeformats;
07023    format_t o1nativeformats;
07024    long time_left_ms=0;
07025    char caller_warning = 0;
07026    char callee_warning = 0;
07027 
07028    if (c0->_bridge) {
07029       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
07030          c0->name, c0->_bridge->name);
07031       return -1;
07032    }
07033    if (c1->_bridge) {
07034       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
07035          c1->name, c1->_bridge->name);
07036       return -1;
07037    }
07038    
07039    /* Stop if we're a zombie or need a soft hangup */
07040    if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
07041        ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1))
07042       return -1;
07043 
07044    *fo = NULL;
07045 
07046    if (ast_tvzero(config->start_time)) {
07047       config->start_time = ast_tvnow();
07048       if (config->start_sound) {
07049          if (caller_warning) {
07050             bridge_playfile(c0, c1, config->start_sound, config->timelimit / 1000);
07051          }
07052          if (callee_warning) {
07053             bridge_playfile(c1, c0, config->start_sound, config->timelimit / 1000);
07054          }
07055       }
07056    }
07057 
07058    /* Keep track of bridge */
07059    c0->_bridge = c1;
07060    c1->_bridge = c0;
07061 
07062    ast_set_owners_and_peers(c0, c1);
07063 
07064    o0nativeformats = c0->nativeformats;
07065    o1nativeformats = c1->nativeformats;
07066 
07067    if (config->feature_timer && !ast_tvzero(config->nexteventts)) {
07068       config->nexteventts = ast_tvadd(config->feature_start_time, ast_samp2tv(config->feature_timer, 1000));
07069    } else if (config->timelimit) {
07070       time_left_ms = config->timelimit - ast_tvdiff_ms(ast_tvnow(), config->start_time);
07071       caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING);
07072       callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING);
07073       config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
07074       if ((caller_warning || callee_warning) && config->play_warning) {
07075          long next_warn = config->play_warning;
07076          if (time_left_ms < config->play_warning) {
07077             /* At least one warning was played, which means we are returning after feature */
07078             long warns_passed = (config->play_warning - time_left_ms) / config->warning_freq;
07079             /* It is 'warns_passed * warning_freq' NOT '(warns_passed + 1) * warning_freq',
07080                because nexteventts will be updated once again in the 'if (!to)' block */
07081             next_warn = config->play_warning - warns_passed * config->warning_freq;
07082          }
07083          config->nexteventts = ast_tvsub(config->nexteventts, ast_samp2tv(next_warn, 1000));
07084       }
07085    } else {
07086       config->nexteventts.tv_sec = 0;
07087       config->nexteventts.tv_usec = 0;
07088    }
07089 
07090    if (!c0->tech->send_digit_begin)
07091       ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY);
07092    if (!c1->tech->send_digit_begin)
07093       ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY);
07094    manager_bridge_event(1, 1, c0, c1);
07095 
07096    /* Before we enter in and bridge these two together tell them both the source of audio has changed */
07097    ast_indicate(c0, AST_CONTROL_SRCUPDATE);
07098    ast_indicate(c1, AST_CONTROL_SRCUPDATE);
07099 
07100    for (/* ever */;;) {
07101       struct timeval now = { 0, };
07102       int to;
07103 
07104       to = -1;
07105 
07106       if (!ast_tvzero(config->nexteventts)) {
07107          now = ast_tvnow();
07108          to = ast_tvdiff_ms(config->nexteventts, now);
07109          if (to <= 0) {
07110             if (!config->timelimit) {
07111                res = AST_BRIDGE_COMPLETE;
07112                break;
07113             }
07114             to = 0;
07115          }
07116       }
07117 
07118       if (config->timelimit) {
07119          time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time);
07120          if (time_left_ms < to)
07121             to = time_left_ms;
07122 
07123          if (time_left_ms <= 0) {
07124             if (caller_warning && config->end_sound)
07125                bridge_playfile(c0, c1, config->end_sound, 0);
07126             if (callee_warning && config->end_sound)
07127                bridge_playfile(c1, c0, config->end_sound, 0);
07128             *fo = NULL;
07129             res = 0;
07130             break;
07131          }
07132 
07133          if (!to) {
07134             if (time_left_ms >= 5000 && config->warning_sound && config->play_warning && ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) {
07135                int t = (time_left_ms + 500) / 1000; /* round to nearest second */
07136                if (caller_warning)
07137                   bridge_playfile(c0, c1, config->warning_sound, t);
07138                if (callee_warning)
07139                   bridge_playfile(c1, c0, config->warning_sound, t);
07140             }
07141 
07142             if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000))) {
07143                config->nexteventts = ast_tvadd(config->nexteventts, ast_samp2tv(config->warning_freq, 1000));
07144             } else {
07145                config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
07146             }
07147          }
07148          ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE);
07149       }
07150 
07151       if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */
07152          if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
07153             c0->_softhangup &= ~AST_SOFTHANGUP_UNBRIDGE;
07154          }
07155          if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
07156             c1->_softhangup &= ~AST_SOFTHANGUP_UNBRIDGE;
07157          }
07158          c0->_bridge = c1;
07159          c1->_bridge = c0;
07160          ast_debug(1, "Unbridge signal received. Ending native bridge.\n");
07161          continue;
07162       }
07163 
07164       /* Stop if we're a zombie or need a soft hangup */
07165       if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
07166           ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) {
07167          *fo = NULL;
07168          res = 0;
07169          ast_debug(1, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n",
07170             c0->name, c1->name,
07171             ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No",
07172             ast_check_hangup(c0) ? "Yes" : "No",
07173             ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No",
07174             ast_check_hangup(c1) ? "Yes" : "No");
07175          break;
07176       }
07177 
07178       update_bridge_vars(c0, c1);
07179 
07180       bridge_play_sounds(c0, c1);
07181 
07182       if (c0->tech->bridge &&
07183          /* if < 1 ms remains use generic bridging for accurate timing */
07184          (!config->timelimit || to > 1000 || to == 0) &&
07185           (c0->tech->bridge == c1->tech->bridge) &&
07186           !c0->monitor && !c1->monitor &&
07187           !c0->audiohooks && !c1->audiohooks &&
07188           !c0->masq && !c0->masqr && !c1->masq && !c1->masqr) {
07189          int timeoutms = to - 1000 > 0 ? to - 1000 : to;
07190          /* Looks like they share a bridge method and nothing else is in the way */
07191          ast_set_flag(c0, AST_FLAG_NBRIDGE);
07192          ast_set_flag(c1, AST_FLAG_NBRIDGE);
07193          if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, timeoutms)) == AST_BRIDGE_COMPLETE) {
07194             ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans,
07195                "Channel1: %s\r\n"
07196                "Channel2: %s\r\n"
07197                "Uniqueid1: %s\r\n"
07198                "Uniqueid2: %s\r\n"
07199                "CallerID1: %s\r\n"
07200                "CallerID2: %s\r\n",
07201                c0->name, c1->name,
07202                c0->uniqueid, c1->uniqueid,
07203                S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"),
07204                S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>"));
07205 
07206             ast_debug(1, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name);
07207 
07208             ast_clear_flag(c0, AST_FLAG_NBRIDGE);
07209             ast_clear_flag(c1, AST_FLAG_NBRIDGE);
07210 
07211             if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */
07212                continue;
07213             }
07214 
07215             c0->_bridge = NULL;
07216             c1->_bridge = NULL;
07217             return res;
07218          } else {
07219             ast_clear_flag(c0, AST_FLAG_NBRIDGE);
07220             ast_clear_flag(c1, AST_FLAG_NBRIDGE);
07221          }
07222          switch (res) {
07223          case AST_BRIDGE_RETRY:
07224             if (config->play_warning) {
07225                ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
07226             }
07227             continue;
07228          default:
07229             ast_verb(3, "Native bridging %s and %s ended\n", c0->name, c1->name);
07230             /* fallthrough */
07231          case AST_BRIDGE_FAILED_NOWARN:
07232             break;
07233          }
07234       }
07235 
07236       if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) ||
07237           (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) &&
07238           !(c0->generator || c1->generator)) {
07239          if (ast_channel_make_compatible(c0, c1)) {
07240             ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
07241             manager_bridge_event(0, 1, c0, c1);
07242             return AST_BRIDGE_FAILED;
07243          }
07244          o0nativeformats = c0->nativeformats;
07245          o1nativeformats = c1->nativeformats;
07246       }
07247 
07248       update_bridge_vars(c0, c1);
07249 
07250       res = ast_generic_bridge(c0, c1, config, fo, rc);
07251       if (res != AST_BRIDGE_RETRY) {
07252          break;
07253       } else if (config->feature_timer) {
07254          /* feature timer expired but has not been updated, sending to ast_bridge_call to do so */
07255          break;
07256       }
07257    }
07258 
07259    ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY);
07260    ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY);
07261 
07262    /* Now that we have broken the bridge the source will change yet again */
07263    ast_indicate(c0, AST_CONTROL_SRCUPDATE);
07264    ast_indicate(c1, AST_CONTROL_SRCUPDATE);
07265 
07266    c0->_bridge = NULL;
07267    c1->_bridge = NULL;
07268 
07269    ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans,
07270       "Channel1: %s\r\n"
07271       "Channel2: %s\r\n"
07272       "Uniqueid1: %s\r\n"
07273       "Uniqueid2: %s\r\n"
07274       "CallerID1: %s\r\n"
07275       "CallerID2: %s\r\n",
07276       c0->name, c1->name,
07277       c0->uniqueid, c1->uniqueid,
07278       S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"),
07279       S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>"));
07280    ast_debug(1, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name);
07281 
07282    return res;
07283 }

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.

Since:
1.8

Definition at line 1544 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_mark(), pickup_by_part(), and state_notify_build_xml().

01546 {
01547    return ao2_callback_data(channels, ao2_flags, cb_fn, arg, data);
01548 }

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

09164 {
09165    struct ast_cc_config_params *cc_params;
09166    struct ast_datastore *cc_datastore;
09167 
09168    if (!(cc_params = ast_cc_config_params_init())) {
09169       return -1;
09170    }
09171 
09172    if (!(cc_datastore = ast_datastore_alloc(&cc_channel_datastore_info, NULL))) {
09173       ast_cc_config_params_destroy(cc_params);
09174       return -1;
09175    }
09176 
09177    if (base_params) {
09178       ast_cc_copy_config_params(cc_params, base_params);
09179    }
09180    cc_datastore->data = cc_params;
09181    ast_channel_datastore_add(chan, cc_datastore);
09182    return 0;
09183 }

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

05996 {
05997    /* if the linkedid for this channel is being changed from something, check... */
05998    if (!ast_strlen_zero(chan->linkedid) && 0 != strcmp(chan->linkedid, linkedid)) {
05999       ast_cel_check_retire_linkedid(chan);
06000    }
06001 
06002    ast_string_field_set(chan, linkedid, linkedid);
06003 }

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

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

01631 {
01632    struct ast_channel *chan = obj, *cmp_args = arg;
01633    size_t name_len;
01634    int ret = CMP_MATCH;
01635 
01636    /* This is sort of a hack.  Basically, we're using an arbitrary field
01637     * in ast_channel to pass the name_len for a prefix match.  If this
01638     * gets changed, then the uses of ao2_find() must be changed, too. */
01639    name_len = cmp_args->rings;
01640 
01641    ast_channel_lock(chan);
01642 
01643    if (!ast_strlen_zero(cmp_args->name)) { /* match by name */
01644       if ((!name_len && strcasecmp(chan->name, cmp_args->name)) ||
01645             (name_len && strncasecmp(chan->name, cmp_args->name, name_len))) {
01646          ret = 0; /* name match failed */
01647       }
01648    } else if (!ast_strlen_zero(cmp_args->exten)) {
01649       if (cmp_args->context && strcasecmp(chan->context, cmp_args->context) &&
01650             strcasecmp(chan->macrocontext, cmp_args->context)) {
01651          ret = 0; /* context match failed */
01652       }
01653       if (ret && strcasecmp(chan->exten, cmp_args->exten) &&
01654             strcasecmp(chan->macroexten, cmp_args->exten)) {
01655          ret = 0; /* exten match failed */
01656       }
01657    } else if (!ast_strlen_zero(cmp_args->uniqueid)) {
01658       if ((!name_len && strcasecmp(chan->uniqueid, cmp_args->uniqueid)) ||
01659             (name_len && strncasecmp(chan->uniqueid, cmp_args->uniqueid, name_len))) {
01660          ret = 0; /* uniqueid match failed */
01661       }
01662    } else {
01663       ret = 0;
01664    }
01665 
01666    ast_channel_unlock(chan);
01667 
01668    return ret;
01669 }

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

References ast_channel_cmpwhentohangup_tv(), and chanlist::chan.

00831 {
00832    struct timeval when = { offset, };
00833    return ast_channel_cmpwhentohangup_tv(chan, when);
00834 }

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

00816 {
00817    struct timeval whentohangup;
00818 
00819    if (ast_tvzero(chan->whentohangup))
00820       return ast_tvzero(offset) ? 0 : -1;
00821 
00822    if (ast_tvzero(offset))
00823       return 1;
00824 
00825    whentohangup = ast_tvadd(offset, ast_tvnow());
00826 
00827    return ast_tvdiff_ms(whentohangup, chan->whentohangup);
00828 }

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 9060 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(), ast_bridge_call(), ast_pickup_call(), atxfer_fail_cleanup(), builtin_atxfer(), builtin_blindtransfer(), feature_request_and_dial(), handle_frame(), pickup_do(), remote_bridge_loop(), and wait_for_answer().

09061 {
09062    const char *macro;
09063    const char *macro_args;
09064    int retval;
09065 
09066    ast_channel_lock(macro_chan);
09067    macro = pbx_builtin_getvar_helper(macro_chan, is_caller
09068       ? "CONNECTED_LINE_CALLER_SEND_MACRO" : "CONNECTED_LINE_CALLEE_SEND_MACRO");
09069    macro = ast_strdupa(S_OR(macro, ""));
09070    macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller
09071       ? "CONNECTED_LINE_CALLER_SEND_MACRO_ARGS" : "CONNECTED_LINE_CALLEE_SEND_MACRO_ARGS");
09072    macro_args = ast_strdupa(S_OR(macro_args, ""));
09073 
09074    if (ast_strlen_zero(macro)) {
09075       ast_channel_unlock(macro_chan);
09076       return -1;
09077    }
09078 
09079    if (is_frame) {
09080       const struct ast_frame *frame = connected_info;
09081 
09082       ast_connected_line_parse_data(frame->data.ptr, frame->datalen, &macro_chan->connected);
09083    } else {
09084       const struct ast_party_connected_line *connected = connected_info;
09085 
09086       ast_party_connected_line_copy(&macro_chan->connected, connected);
09087    }
09088    ast_channel_unlock(macro_chan);
09089 
09090    if (!(retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args))) {
09091       ast_channel_lock(macro_chan);
09092       ast_channel_update_connected_line(macro_chan, &macro_chan->connected, NULL);
09093       ast_channel_unlock(macro_chan);
09094    }
09095 
09096    return retval;
09097 }

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

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

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

References ast_data_search_cmp_structure, and chanlist::chan.

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

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 2484 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_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(), pbx_builtin_raise_exception(), pitchshift_helper(), 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().

02485 {
02486    int res = 0;
02487 
02488    AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry);
02489 
02490    return res;
02491 }

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

References ast_datastore_alloc, and ast_datastore::info.

02458 {
02459    return ast_datastore_alloc(info, uid);
02460 }

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

References AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, 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_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(), 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_parkinglot(), manager_mutestream(), mark_transaction_active(), mute_callback(), park_exec_full(), pbx_builtin_raise_exception(), pitchshift_cb(), pitchshift_helper(), pop_exec(), queue_transfer_fixup(), 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().

02499 {
02500    struct ast_datastore *datastore = NULL;
02501    
02502    if (info == NULL)
02503       return NULL;
02504 
02505    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore, entry) {
02506       if (datastore->info != info) {
02507          continue;
02508       }
02509 
02510       if (uid == NULL) {
02511          /* matched by type only */
02512          break;
02513       }
02514 
02515       if ((datastore->uid != NULL) && !strcasecmp(uid, datastore->uid)) {
02516          /* Matched by type AND uid */
02517          break;
02518       }
02519    }
02520    AST_LIST_TRAVERSE_SAFE_END;
02521 
02522    return datastore;
02523 }

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

References ast_datastore_free().

02463 {
02464    return ast_datastore_free(datastore);
02465 }

int ast_channel_datastore_inherit ( struct ast_channel from,
struct ast_channel to 
)

Inherit datastores from a parent to a child.

Definition at line 2467 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(), ast_call_forward(), begin_dial_channel(), dial_exec_full(), do_forward(), findmeexec(), local_call(), and ring_entry().

02468 {
02469    struct ast_datastore *datastore = NULL, *datastore2;
02470 
02471    AST_LIST_TRAVERSE(&from->datastores, datastore, entry) {
02472       if (datastore->inheritance > 0) {
02473          datastore2 = ast_datastore_alloc(datastore->info, datastore->uid);
02474          if (datastore2) {
02475             datastore2->data = datastore->info->duplicate ? datastore->info->duplicate(datastore->data) : NULL;
02476             datastore2->inheritance = datastore->inheritance == DATASTORE_INHERIT_FOREVER ? DATASTORE_INHERIT_FOREVER : datastore->inheritance - 1;
02477             AST_LIST_INSERT_TAIL(&to->datastores, datastore2, entry);
02478          }
02479       }
02480    }
02481    return 0;
02482 }

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

02494 {
02495    return AST_LIST_REMOVE(&chan->datastores, datastore, entry) ? 0 : -1;
02496 }

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

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

Referenced by find_cache().

01527 {
01528    int pre = 0;
01529 
01530    if (chan) {
01531       pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF);
01532       ast_set_flag(chan, AST_FLAG_DEFER_DTMF);
01533    }
01534    return pre;
01535 }

static void ast_channel_destructor ( void *  obj  )  [static]

Free a channel structure.

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

02307 {
02308    struct ast_channel *chan = obj;
02309    int fd;
02310 #ifdef HAVE_EPOLL
02311    int i;
02312 #endif
02313    struct ast_var_t *vardata;
02314    struct ast_frame *f;
02315    struct varshead *headp;
02316    struct ast_datastore *datastore;
02317    char device_name[AST_CHANNEL_NAME];
02318 
02319    if (chan->name) {
02320       /* The string fields were initialized. */
02321       ast_cel_report_event(chan, AST_CEL_CHANNEL_END, NULL, NULL, NULL);
02322       ast_cel_check_retire_linkedid(chan);
02323    }
02324 
02325    /* Get rid of each of the data stores on the channel */
02326    ast_channel_lock(chan);
02327    while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry)))
02328       /* Free the data store */
02329       ast_datastore_free(datastore);
02330    ast_channel_unlock(chan);
02331 
02332    /* Lock and unlock the channel just to be sure nobody has it locked still
02333       due to a reference that was stored in a datastore. (i.e. app_chanspy) */
02334    ast_channel_lock(chan);
02335    ast_channel_unlock(chan);
02336 
02337    if (chan->tech_pvt) {
02338       ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
02339       ast_free(chan->tech_pvt);
02340    }
02341 
02342    if (chan->sched)
02343       sched_context_destroy(chan->sched);
02344 
02345    if (chan->name) {
02346       char *dashptr;
02347 
02348       /* The string fields were initialized. */
02349       ast_copy_string(device_name, chan->name, sizeof(device_name));
02350       if ((dashptr = strrchr(device_name, '-'))) {
02351          *dashptr = '\0';
02352       }
02353    } else {
02354       device_name[0] = '\0';
02355    }
02356 
02357    /* Stop monitoring */
02358    if (chan->monitor)
02359       chan->monitor->stop( chan, 0 );
02360 
02361    /* If there is native format music-on-hold state, free it */
02362    if (chan->music_state)
02363       ast_moh_cleanup(chan);
02364 
02365    /* Free translators */
02366    if (chan->readtrans)
02367       ast_translator_free_path(chan->readtrans);
02368    if (chan->writetrans)
02369       ast_translator_free_path(chan->writetrans);
02370    if (chan->pbx)
02371       ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
02372 
02373    ast_party_dialed_free(&chan->dialed);
02374    ast_party_caller_free(&chan->caller);
02375    ast_party_connected_line_free(&chan->connected);
02376    ast_party_redirecting_free(&chan->redirecting);
02377 
02378    /* Close pipes if appropriate */
02379    if ((fd = chan->alertpipe[0]) > -1)
02380       close(fd);
02381    if ((fd = chan->alertpipe[1]) > -1)
02382       close(fd);
02383    if (chan->timer) {
02384       ast_timer_close(chan->timer);
02385    }
02386 #ifdef HAVE_EPOLL
02387    for (i = 0; i < AST_MAX_FDS; i++) {
02388       if (chan->epfd_data[i])
02389          free(chan->epfd_data[i]);
02390    }
02391    close(chan->epfd);
02392 #endif
02393    while ((f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list)))
02394       ast_frfree(f);
02395    
02396    /* loop over the variables list, freeing all data and deleting list items */
02397    /* no need to lock the list, as the channel is already locked */
02398    headp = &chan->varshead;
02399    while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
02400       ast_var_delete(vardata);
02401 
02402    ast_app_group_discard(chan);
02403 
02404    /* Destroy the jitterbuffer */
02405    ast_jb_destroy(chan);
02406 
02407    if (chan->cdr) {
02408       ast_cdr_discard(chan->cdr);
02409       chan->cdr = NULL;
02410    }
02411 
02412    if (chan->zone) {
02413       chan->zone = ast_tone_zone_unref(chan->zone);
02414    }
02415 
02416    ast_string_field_free_memory(chan);
02417 
02418    if (device_name[0]) {
02419       /*
02420        * We have a device name to notify of a new state.
02421        *
02422        * Queue an unknown state, because, while we know that this particular
02423        * instance is dead, we don't know the state of all other possible
02424        * instances.
02425        */
02426       ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, device_name);
02427    }
02428 }

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

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

Referenced by dial_exec_full().

06918 {
06919    /* Make sure we can early bridge, if not error out */
06920    if (!c0->tech->early_bridge || (c1 && (!c1->tech->early_bridge || c0->tech->early_bridge != c1->tech->early_bridge)))
06921       return -1;
06922 
06923    return c0->tech->early_bridge(c0, c1);
06924 }

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

References ast_channel_get_full().

01724 {
01725    return ast_channel_get_full(NULL, 0, exten, context);
01726 }

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

01714 {
01715    return ast_channel_get_full(name, 0, NULL, NULL);
01716 }

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

01719 {
01720    return ast_channel_get_full(name, name_len, NULL, NULL);
01721 }

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

09225 {
09226    int len = size;
09227    char *slash;
09228 
09229    if (!ast_channel_queryoption(chan, AST_OPTION_CC_AGENT_TYPE, agent_type, &len, 0)) {
09230       return 0;
09231    }
09232 
09233    ast_copy_string(agent_type, chan->name, size);
09234    if ((slash = strchr(agent_type, '/'))) {
09235       *slash = '\0';
09236    }
09237    return 0;
09238 }

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 9185 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(), and sig_pri_cc_generic_check().

09186 {
09187    struct ast_datastore *cc_datastore;
09188 
09189    if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) {
09190       /* If we can't find the datastore, it almost definitely means that the channel type being
09191        * used has not had its driver modified to parse CC config parameters. The best action
09192        * to take here is to create the parameters on the spot with the defaults set.
09193        */
09194       if (ast_channel_cc_params_init(chan, NULL)) {
09195          return NULL;
09196       }
09197       if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) {
09198          /* Should be impossible */
09199          return NULL;
09200       }
09201    }
09202 
09203    ast_assert(cc_datastore->data != NULL);
09204    return cc_datastore->data;
09205 }

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 9207 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_generic_check(), sip_call(), and sip_handle_cc().

09208 {
09209    int len = name_buffer_length;
09210    char *dash;
09211    if (!ast_channel_queryoption(chan, AST_OPTION_DEVICE_NAME, device_name, &len, 0)) {
09212       return 0;
09213    }
09214 
09215    /* Dang. Do it the old-fashioned way */
09216    ast_copy_string(device_name, chan->name, name_buffer_length);
09217    if ((dash = strrchr(device_name, '-'))) {
09218       *dash = '\0';
09219    }
09220 
09221    return 0;
09222 }

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

01673 {
01674    struct ast_channel tmp_chan = {
01675       .name = name,
01676       /* This is sort of a hack.  Basically, we're using an arbitrary field
01677        * in ast_channel to pass the name_len for a prefix match.  If this
01678        * gets changed, then the compare callback must be changed, too. */
01679       .rings = name_len,
01680    };
01681    struct ast_channel *chan;
01682 
01683    if (exten) {
01684       ast_copy_string(tmp_chan.exten, exten, sizeof(tmp_chan.exten));
01685    }
01686 
01687    if (context) {
01688       ast_copy_string(tmp_chan.context, context, sizeof(tmp_chan.context));
01689    }
01690 
01691    if ((chan = ao2_find(channels, &tmp_chan,
01692               (!ast_strlen_zero(name) && (name_len == 0)) ? OBJ_POINTER : 0))) {
01693       return chan;
01694    }
01695 
01696    if (!name) {
01697       return NULL;
01698    }
01699 
01700    /* If name was specified, but the result was NULL, 
01701     * try a search on uniqueid, instead. */
01702 
01703    {
01704       struct ast_channel tmp_chan2 = {
01705          .uniqueid = name,
01706          .rings = name_len,
01707       };
01708 
01709       return ao2_find(channels, &tmp_chan2, 0);
01710    }
01711 }

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

Definition at line 7540 of file channel.c.

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

07541 {
07542    const struct ast_channel *chan = obj;
07543 
07544    /* If the name isn't set, return 0 so that the ao2_find() search will
07545     * start in the first bucket. */
07546    if (ast_strlen_zero(chan->name)) {
07547       return 0;
07548    }
07549 
07550    return ast_str_case_hash(chan->name);
07551 }

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 5866 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(), ast_call_forward(), begin_dial_channel(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), and ring_entry().

05867 {
05868    struct ast_var_t *current, *newvar;
05869    const char *varname;
05870 
05871    AST_LIST_TRAVERSE(&parent->varshead, current, entries) {
05872       int vartype = 0;
05873 
05874       varname = ast_var_full_name(current);
05875       if (!varname)
05876          continue;
05877 
05878       if (varname[0] == '_') {
05879          vartype = 1;
05880          if (varname[1] == '_')
05881             vartype = 2;
05882       }
05883 
05884       switch (vartype) {
05885       case 1:
05886          newvar = ast_var_assign(&varname[1], ast_var_value(current));
05887          if (newvar) {
05888             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
05889             ast_debug(1, "Copying soft-transferable variable %s.\n", ast_var_name(newvar));
05890          }
05891          break;
05892       case 2:
05893          newvar = ast_var_assign(varname, ast_var_value(current));
05894          if (newvar) {
05895             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
05896             ast_debug(1, "Copying hard-transferable variable %s.\n", ast_var_name(newvar));
05897          }
05898          break;
05899       default:
05900          ast_debug(1, "Not copying variable %s.\n", ast_var_name(current));
05901          break;
05902       }
05903    }
05904 }

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

01612 {
01613    struct ast_channel_iterator *i;
01614 
01615    if (!(i = ast_calloc(1, sizeof(*i)))) {
01616       return NULL;
01617    }
01618 
01619    i->simple_iterator = ao2_iterator_init(channels, 0);
01620    i->active_iterator = &i->simple_iterator;
01621 
01622    return i;
01623 }

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

References channel_iterator_search().

Referenced by common_exec(), and pickup_by_exten().

01602 {
01603    return channel_iterator_search(NULL, 0, exten, context);
01604 }

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

References channel_iterator_search().

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

01607 {
01608    return channel_iterator_search(name, name_len, NULL, NULL);
01609 }

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

01560 {
01561    ao2_iterator_destroy(i->active_iterator);
01562    ast_free(i);
01563 
01564    return NULL;
01565 }

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

01626 {
01627    return ao2_iterator_next(i->active_iterator);
01628 }

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 5630 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(), park_exec_full(), simple_bridge_join(), and wait_for_answer().

05631 {
05632    /* Some callers do not check return code, and we must try to set all call legs correctly */
05633    int rc = 0;
05634 
05635    /* Set up translation from the chan to the peer */
05636    rc = ast_channel_make_compatible_helper(chan, peer);
05637 
05638    if (rc < 0)
05639       return rc;
05640 
05641    /* Set up translation from the peer to the chan */
05642    rc = ast_channel_make_compatible_helper(peer, chan);
05643 
05644    return rc;
05645 }

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

05581 {
05582    format_t src, dst;
05583    int use_slin;
05584 
05585    /* See if the channel driver can natively make these two channels compatible */
05586    if (from->tech->bridge && from->tech->bridge == to->tech->bridge &&
05587        !ast_channel_setoption(from, AST_OPTION_MAKE_COMPATIBLE, to, sizeof(struct ast_channel *), 0)) {
05588       return 0;
05589    }
05590 
05591    if (from->readformat == to->writeformat && from->writeformat == to->readformat) {
05592       /* Already compatible!  Moving on ... */
05593       return 0;
05594    }
05595 
05596    /* Set up translation from the 'from' channel to the 'to' channel */
05597    src = from->nativeformats;
05598    dst = to->nativeformats;
05599 
05600    /* If there's no audio in this call, don't bother with trying to find a translation path */
05601    if ((src & AST_FORMAT_AUDIO_MASK) == 0 || (dst & AST_FORMAT_AUDIO_MASK) == 0)
05602       return 0;
05603 
05604    if (ast_translator_best_choice(&dst, &src) < 0) {
05605       ast_log(LOG_WARNING, "No path to translate from %s to %s\n", from->name, to->name);
05606       return -1;
05607    }
05608 
05609    /* if the best path is not 'pass through', then
05610     * transcoding is needed; if desired, force transcode path
05611     * to use SLINEAR between channels, but only if there is
05612     * no direct conversion available. If generic PLC is
05613     * desired, then transcoding via SLINEAR is a requirement
05614     */
05615    use_slin = (src == AST_FORMAT_SLINEAR || dst == AST_FORMAT_SLINEAR);
05616    if ((src != dst) && (ast_opt_generic_plc || ast_opt_transcode_via_slin) &&
05617        (ast_translate_path_steps(dst, src) != 1 || use_slin))
05618       dst = AST_FORMAT_SLINEAR;
05619    if (ast_set_read_format(from, dst) < 0) {
05620       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %s\n", from->name, ast_getformatname(dst));
05621       return -1;
05622    }
05623    if (ast_set_write_format(to, dst) < 0) {
05624       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %s\n", to->name, ast_getformatname(dst));
05625       return -1;
05626    }
05627    return 0;
05628 }

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 needs to be locked before calling this function.

Definition at line 5737 of file channel.c.

References __ast_channel_masquerade().

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

05738 {
05739    return __ast_channel_masquerade(original, clone, NULL);
05740 }

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

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

07300 {
07301    if (!chan->tech->queryoption) {
07302       errno = ENOSYS;
07303       return -1;
07304    }
07305 
07306    if (block)
07307       ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
07308 
07309    return chan->tech->queryoption(chan, option, data, datalen);
07310 }

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

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

Referenced by ast_pickup_call(), handle_request_invite(), handle_request_update(), handle_response_invite(), local_attended_transfer(), masquerade_colp_transfer(), misdn_queue_connected_line_update(), pickup_do(), and sig_pri_handle_subcmds().

08541 {
08542    unsigned char data[1024];  /* This should be large enough */
08543    size_t datalen;
08544 
08545    datalen = ast_connected_line_build_data(data, sizeof(data), connected, update);
08546    if (datalen == (size_t) -1) {
08547       return;
08548    }
08549 
08550    ast_queue_control_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen);
08551 }

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

09048 {
09049    unsigned char data[1024];  /* This should be large enough */
09050    size_t datalen;
09051 
09052    datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update);
09053    if (datalen == (size_t) -1) {
09054       return;
09055    }
09056 
09057    ast_queue_control_data(chan, AST_CONTROL_REDIRECTING, data, datalen);
09058 }

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

05035 {
05036    switch (reason) /* the following appear to be the only ones actually returned by request_and_dial */
05037    {
05038    case 0:
05039       return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)";
05040    case AST_CONTROL_HANGUP:
05041       return "Hangup";
05042    case AST_CONTROL_RING:
05043       return "Local Ring";
05044    case AST_CONTROL_RINGING:
05045       return "Remote end Ringing";
05046    case AST_CONTROL_ANSWER:
05047       return "Remote end has Answered";
05048    case AST_CONTROL_BUSY:
05049       return "Remote end is Busy";
05050    case AST_CONTROL_CONGESTION:
05051       return "Congestion (circuits busy)";
05052    default:
05053       return "Unknown Reason!!";
05054    }
05055 }

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 9099 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(), do_forward(), feature_request_and_dial(), handle_frame(), and remote_bridge_loop().

09100 {
09101    const char *macro;
09102    const char *macro_args;
09103    int retval;
09104 
09105    ast_channel_lock(macro_chan);
09106    macro = pbx_builtin_getvar_helper(macro_chan, is_caller
09107       ? "REDIRECTING_CALLER_SEND_MACRO" : "REDIRECTING_CALLEE_SEND_MACRO");
09108    macro = ast_strdupa(S_OR(macro, ""));
09109    macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller
09110       ? "REDIRECTING_CALLER_SEND_MACRO_ARGS" : "REDIRECTING_CALLEE_SEND_MACRO_ARGS");
09111    macro_args = ast_strdupa(S_OR(macro_args, ""));
09112 
09113    if (ast_strlen_zero(macro)) {
09114       ast_channel_unlock(macro_chan);
09115       return -1;
09116    }
09117 
09118    if (is_frame) {
09119       const struct ast_frame *frame = redirecting_info;
09120 
09121       ast_redirecting_parse_data(frame->data.ptr, frame->datalen, &macro_chan->redirecting);
09122    } else {
09123       const struct ast_party_redirecting *redirecting = redirecting_info;
09124 
09125       ast_party_redirecting_copy(&macro_chan->redirecting, redirecting);
09126    }
09127    ast_channel_unlock(macro_chan);
09128 
09129    retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args);
09130    if (!retval) {
09131       ast_channel_lock(macro_chan);
09132       ast_channel_update_redirecting(macro_chan, &macro_chan->redirecting, NULL);
09133       ast_channel_unlock(macro_chan);
09134    }
09135 
09136    return retval;
09137 }

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

00838 {
00839    struct chanlist *chan;
00840 
00841    AST_RWLIST_WRLOCK(&backends);
00842 
00843    AST_RWLIST_TRAVERSE(&backends, chan, list) {
00844       if (!strcasecmp(tech->type, chan->tech->type)) {
00845          ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type);
00846          AST_RWLIST_UNLOCK(&backends);
00847          return -1;
00848       }
00849    }
00850    
00851    if (!(chan = ast_calloc(1, sizeof(*chan)))) {
00852       AST_RWLIST_UNLOCK(&backends);
00853       return -1;
00854    }
00855    chan->tech = tech;
00856    AST_RWLIST_INSERT_HEAD(&backends, chan, list);
00857 
00858    ast_debug(1, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description);
00859 
00860    ast_verb(2, "Registered channel type '%s' (%s)\n", chan->tech->type, chan->tech->description);
00861 
00862    AST_RWLIST_UNLOCK(&backends);
00863 
00864    return 0;
00865 }

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
Since:
1.8

Definition at line 1827 of file channel.c.

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

Referenced by acf_odbc_read(), acf_odbc_write(), action_getvar(), agent_cleanup(), agent_new(), ast_add_extension2_lockopt(), ast_cel_fabricate_channel_from_event(), ast_do_masquerade(), ast_hangup(), ast_iax2_new(), ast_pbx_outgoing_cdr_failed(), ast_request(), ast_str_substitute_variables_full(), bridge_request(), custom_log(), do_notify(), gtalk_newcall(), local_new(), local_request(), make_email_file(), manager_log(), pbx_substitute_variables_helper_full(), rotate_file(), sendmail(), sendpage(), syslog_log(), and write_cdr().

01828 {
01829    /* Safe, even if already unlinked. */
01830    ao2_unlink(channels, chan);
01831    return ast_channel_unref(chan);
01832 }

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

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

Referenced by agent_sendhtml(), and ast_channel_sendurl().

05568 {
05569    if (chan->tech->send_html)
05570       return chan->tech->send_html(chan, subclass, data, datalen);
05571    return -1;
05572 }

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

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

Referenced by dial_exec_full(), and sendurl_exec().

05575 {
05576    return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1);
05577 }

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

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

06601 {
06602    if (&chan->caller == caller) {
06603       /* Don't set to self */
06604       return;
06605    }
06606 
06607    ast_channel_lock(chan);
06608    ast_party_caller_set(&chan->caller, caller, update);
06609    ast_channel_unlock(chan);
06610 }

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

06613 {
06614    struct ast_party_caller pre_set;
06615 
06616    if (&chan->caller == caller) {
06617       /* Don't set to self */
06618       return;
06619    }
06620 
06621    ast_channel_lock(chan);
06622    pre_set = chan->caller;
06623    ast_party_caller_set(&chan->caller, caller, update);
06624    if (S_COR(pre_set.id.number.valid, pre_set.id.number.str, NULL)
06625          != S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL)
06626       || S_COR(pre_set.id.name.valid, pre_set.id.name.str, NULL)
06627          != S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL)) {
06628       /* The caller id name or number changed. */
06629       report_new_callerid(chan);
06630    }
06631    if (chan->cdr) {
06632       ast_cdr_setcid(chan->cdr, chan);
06633    }
06634    ast_channel_unlock(chan);
06635 }

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

07901 {
07902    if (&chan->connected == connected) {
07903       /* Don't set to self */
07904       return;
07905    }
07906 
07907    ast_channel_lock(chan);
07908    ast_party_connected_line_set(&chan->connected, connected, update);
07909    ast_channel_unlock(chan);
07910 }

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

Set the file descriptor on the channel

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

02527 {
02528 #ifdef HAVE_EPOLL
02529    struct epoll_event ev;
02530    struct ast_epoll_data *aed = NULL;
02531 
02532    if (chan->fds[which] > -1) {
02533       epoll_ctl(chan->epfd, EPOLL_CTL_DEL, chan->fds[which], &ev);
02534       aed = chan->epfd_data[which];
02535    }
02536 
02537    /* If this new fd is valid, add it to the epoll */
02538    if (fd > -1) {
02539       if (!aed && (!(aed = ast_calloc(1, sizeof(*aed)))))
02540          return;
02541       
02542       chan->epfd_data[which] = aed;
02543       aed->chan = chan;
02544       aed->which = which;
02545       
02546       ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP;
02547       ev.data.ptr = aed;
02548       epoll_ctl(chan->epfd, EPOLL_CTL_ADD, fd, &ev);
02549    } else if (aed) {
02550       /* We don't have to keep around this epoll data structure now */
02551       free(aed);
02552       chan->epfd_data[which] = NULL;
02553    }
02554 #endif
02555    chan->fds[which] = fd;
02556    return;
02557 }

void ast_channel_set_linkgroup ( struct ast_channel chan,
struct ast_channel peer 
)

propagate the linked id between chan and peer

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

06011 {
06012    const char* linkedid=NULL;
06013    struct ast_channel *bridged;
06014 
06015    linkedid = oldest_linkedid(chan->linkedid, peer->linkedid);
06016    linkedid = oldest_linkedid(linkedid, chan->uniqueid);
06017    linkedid = oldest_linkedid(linkedid, peer->uniqueid);
06018    if (chan->_bridge) {
06019       bridged = ast_bridged_channel(chan);
06020       if (bridged != peer) {
06021          linkedid = oldest_linkedid(linkedid, bridged->linkedid);
06022          linkedid = oldest_linkedid(linkedid, bridged->uniqueid);
06023       }
06024    }
06025    if (peer->_bridge) {
06026       bridged = ast_bridged_channel(peer);
06027       if (bridged != chan) {
06028          linkedid = oldest_linkedid(linkedid, bridged->linkedid);
06029          linkedid = oldest_linkedid(linkedid, bridged->uniqueid);
06030       }
06031    }
06032 
06033    /* just in case setting a stringfield to itself causes problems */
06034    linkedid = ast_strdupa(linkedid);
06035 
06036    ast_channel_change_linkedid(chan, linkedid);
06037    ast_channel_change_linkedid(peer, linkedid);
06038    if (chan->_bridge) {
06039       bridged = ast_bridged_channel(chan);
06040       if (bridged != peer) {
06041          ast_channel_change_linkedid(bridged, linkedid);
06042       }
06043    }
06044    if (peer->_bridge) {
06045       bridged = ast_bridged_channel(peer);
06046       if (bridged != chan) {
06047          ast_channel_change_linkedid(bridged, linkedid);
06048       }
06049    }
06050 }

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

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

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

08554 {
08555    if (&chan->redirecting == redirecting) {
08556       /* Don't set to self */
08557       return;
08558    }
08559 
08560    ast_channel_lock(chan);
08561    ast_party_redirecting_set(&chan->redirecting, redirecting, update);
08562    ast_channel_unlock(chan);
08563 }

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

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

07287 {
07288    if (!chan->tech->setoption) {
07289       errno = ENOSYS;
07290       return -1;
07291    }
07292 
07293    if (block)
07294       ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
07295 
07296    return chan->tech->setoption(chan, option, data, datalen);
07297 }

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

References ast_channel_setwhentohangup_tv(), and chanlist::chan.

00809 {
00810    struct timeval when = { offset, };
00811    ast_channel_setwhentohangup_tv(chan, when);
00812 }

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 801 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(), and timeout_write().

00802 {
00803    chan->whentohangup = ast_tvzero(offset) ? offset : ast_tvadd(offset, ast_tvnow());
00804    ast_queue_frame(chan, &ast_null_frame);
00805    return;
00806 }

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

Definition at line 764 of file channel.c.

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

Referenced by ast_begin_shutdown().

00765 {
00766    struct ast_channel *chan = obj;
00767 
00768    ast_softhangup(chan, AST_SOFTHANGUP_SHUTDOWN);
00769 
00770    return 0;
00771 }

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 7774 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_dtmf_stream(), ast_readstring_full(), ast_safe_sleep_conditional(), channel_spy(), TransferCallStep1(), waitfor_exec(), and waitforring_exec().

07775 {
07776    struct ast_silence_generator *state;
07777 
07778    if (!(state = ast_calloc(1, sizeof(*state)))) {
07779       return NULL;
07780    }
07781 
07782    state->old_write_format = chan->writeformat;
07783 
07784    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
07785       ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
07786       ast_free(state);
07787       return NULL;
07788    }
07789 
07790    ast_activate_generator(chan, &silence_generator, state);
07791 
07792    ast_debug(1, "Started silence generator on '%s'\n", chan->name);
07793 
07794    return state;
07795 }

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 7797 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_dtmf_stream(), ast_readstring_full(), ast_safe_sleep_conditional(), channel_spy(), HandleCallOutgoing(), key_dial_page(), unistim_hangup(), waitfor_exec(), and waitforring_exec().

07798 {
07799    if (!state)
07800       return;
07801 
07802    ast_deactivate_generator(chan);
07803 
07804    ast_debug(1, "Stopped silence generator on '%s'\n", chan->name);
07805 
07806    if (ast_set_write_format(chan, state->old_write_format) < 0)
07807       ast_log(LOG_ERROR, "Could not return write format to its original state\n");
07808 
07809    ast_free(state);
07810 }

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

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

Referenced by dial_exec_full(), and sendurl_exec().

05563 {
05564    return (chan->tech->send_html) ? 1 : 0;
05565 }

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

05818 {
05819    struct ast_datastore *xfer_ds;
05820    struct xfer_masquerade_ds *xfer_colp;
05821    int res;
05822 
05823    xfer_ds = ast_datastore_alloc(&xfer_ds_info, NULL);
05824    if (!xfer_ds) {
05825       return -1;
05826    }
05827 
05828    xfer_colp = ast_calloc(1, sizeof(*xfer_colp));
05829    if (!xfer_colp) {
05830       ast_datastore_free(xfer_ds);
05831       return -1;
05832    }
05833    party_connected_line_copy_transfer(&xfer_colp->target_id, target_id);
05834    xfer_colp->target_held = target_held;
05835    party_connected_line_copy_transfer(&xfer_colp->transferee_id, transferee_id);
05836    xfer_colp->transferee_held = transferee_held;
05837    xfer_ds->data = xfer_colp;
05838 
05839    res = __ast_channel_masquerade(target_chan, transferee_chan, xfer_ds);
05840    if (res) {
05841       ast_datastore_free(xfer_ds);
05842    }
05843    return res;
05844 }

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

References ast_clear_flag, AST_FLAG_DEFER_DTMF, and chanlist::chan.

Referenced by find_cache(), and rpt_call().

01539 {
01540    if (chan)
01541       ast_clear_flag(chan, AST_FLAG_DEFER_DTMF);
01542 }

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

00869 {
00870    struct chanlist *chan;
00871 
00872    ast_debug(1, "Unregistering channel type '%s'\n", tech->type);
00873 
00874    AST_RWLIST_WRLOCK(&backends);
00875 
00876    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) {
00877       if (chan->tech == tech) {
00878          AST_LIST_REMOVE_CURRENT(list);
00879          ast_free(chan);
00880          ast_verb(2, "Unregistered channel type '%s'\n", tech->type);
00881          break;   
00882       }
00883    }
00884    AST_LIST_TRAVERSE_SAFE_END;
00885 
00886    AST_RWLIST_UNLOCK(&backends);
00887 }

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

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

Referenced by ast_channel_connected_line_macro(), ast_pickup_call(), atxfer_fail_cleanup(), builtin_atxfer(), builtin_blindtransfer(), connectedline_write(), pickup_do(), and wait_for_answer().

08528 {
08529    unsigned char data[1024];  /* This should be large enough */
08530    size_t datalen;
08531 
08532    datalen = ast_connected_line_build_data(data, sizeof(data), connected, update);
08533    if (datalen == (size_t) -1) {
08534       return;
08535    }
08536 
08537    ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen);
08538 }

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

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

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

09035 {
09036    unsigned char data[1024];  /* This should be large enough */
09037    size_t datalen;
09038 
09039    datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update);
09040    if (datalen == (size_t) -1) {
09041       return;
09042    }
09043 
09044    ast_indicate_data(chan, AST_CONTROL_REDIRECTING, data, datalen);
09045 }

void ast_channels_init ( void   ) 

Provided by channel.c

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

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

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 742 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(), 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_exec(), read_exec(), readexten_exec(), remote_bridge_loop(), rpt(), and run_ras().

00743 {
00744    if (chan->_softhangup)     /* yes if soft hangup flag set */
00745       return 1;
00746    if (ast_tvzero(chan->whentohangup)) /* no if no hangup scheduled */
00747       return 0;
00748    if (ast_tvdiff_ms(chan->whentohangup, ast_tvnow()) > 0)  /* no if hangup time has not come yet. */
00749       return 0;
00750    ast_debug(4, "Hangup time has come: %" PRIi64 "\n", ast_tvdiff_ms(chan->whentohangup, ast_tvnow()));
00751    chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT; /* record event */
00752    return 1;
00753 }

int ast_check_hangup_locked ( struct ast_channel chan  ) 

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

00756 {
00757    int res;
00758    ast_channel_lock(chan);
00759    res = ast_check_hangup(chan);
00760    ast_channel_unlock(chan);
00761    return res;
00762 }

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

08268 {
08269    int32_t value;
08270    size_t pos = 0;
08271    int res;
08272 
08273    static const struct ast_party_id_ies ies = {
08274       .name.str = AST_CONNECTED_LINE_NAME,
08275       .name.char_set = AST_CONNECTED_LINE_NAME_CHAR_SET,
08276       .name.presentation = AST_CONNECTED_LINE_NAME_PRESENTATION,
08277       .name.valid = AST_CONNECTED_LINE_NAME_VALID,
08278 
08279       .number.str = AST_CONNECTED_LINE_NUMBER,
08280       .number.plan = AST_CONNECTED_LINE_NUMBER_PLAN,
08281       .number.presentation = AST_CONNECTED_LINE_NUMBER_PRESENTATION,
08282       .number.valid = AST_CONNECTED_LINE_NUMBER_VALID,
08283 
08284       .subaddress.str = AST_CONNECTED_LINE_SUBADDRESS,
08285       .subaddress.type = AST_CONNECTED_LINE_SUBADDRESS_TYPE,
08286       .subaddress.odd_even_indicator = AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN,
08287       .subaddress.valid = AST_CONNECTED_LINE_SUBADDRESS_VALID,
08288 
08289       .tag = AST_CONNECTED_LINE_TAG,
08290       .combined_presentation = AST_CONNECTED_LINE_ID_PRESENTATION,
08291    };
08292 
08293    /*
08294     * The size of integer values must be fixed in case the frame is
08295     * shipped to another machine.
08296     */
08297 
08298    /* Connected line frame version */
08299    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08300       ast_log(LOG_WARNING, "No space left for connected line frame version\n");
08301       return -1;
08302    }
08303    data[pos++] = AST_CONNECTED_LINE_VERSION;
08304    data[pos++] = 1;
08305    data[pos++] = 2;/* Version 1 did not have a version ie */
08306 
08307    res = party_id_build_data(data + pos, datalen - pos, &connected->id,
08308       "connected line", &ies, update ? &update->id : NULL);
08309    if (res < 0) {
08310       return -1;
08311    }
08312    pos += res;
08313 
08314    /* Connected line source */
08315    if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
08316       ast_log(LOG_WARNING, "No space left for connected line source\n");
08317       return -1;
08318    }
08319    data[pos++] = AST_CONNECTED_LINE_SOURCE;
08320    data[pos++] = sizeof(value);
08321    value = htonl(connected->source);
08322    memcpy(data + pos, &value, sizeof(value));
08323    pos += sizeof(value);
08324 
08325    return pos;
08326 }

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 7885 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 begin_dial_channel(), builtin_atxfer(), dial_exec_full(), feature_request_and_dial(), local_call(), pickup_do(), ring_entry(), and wait_for_answer().

07886 {
07887    ast_party_id_copy(&dest->id, &src->id);
07888    ast_party_id_copy(&dest->ani, &src->ani);
07889    dest->ani2 = src->ani2;
07890 }

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

07893 {
07894    ast_party_id_copy(&dest->id, &src->id);
07895    ast_party_id_copy(&dest->ani, &src->ani);
07896 
07897    dest->ani2 = src->ani2;
07898 }

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 8328 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(), and socket_process().

08329 {
08330    size_t pos;
08331    unsigned char ie_len;
08332    unsigned char ie_id;
08333    int32_t value;
08334    int frame_version = 1;
08335    int combined_presentation = 0;
08336    int got_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */
08337 
08338    for (pos = 0; pos < datalen; pos += ie_len) {
08339       if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) {
08340          ast_log(LOG_WARNING, "Invalid connected line update\n");
08341          return -1;
08342       }
08343       ie_id = data[pos++];
08344       ie_len = data[pos++];
08345       if (datalen < pos + ie_len) {
08346          ast_log(LOG_WARNING, "Invalid connected line update\n");
08347          return -1;
08348       }
08349 
08350       switch (ie_id) {
08351 /* Connected line party frame version */
08352       case AST_CONNECTED_LINE_VERSION:
08353          if (ie_len != 1) {
08354             ast_log(LOG_WARNING, "Invalid connected line frame version (%u)\n",
08355                (unsigned) ie_len);
08356             break;
08357          }
08358          frame_version = data[pos];
08359          break;
08360 /* Connected line party id name */
08361       case AST_CONNECTED_LINE_NAME:
08362          ast_free(connected->id.name.str);
08363          connected->id.name.str = ast_malloc(ie_len + 1);
08364          if (connected->id.name.str) {
08365             memcpy(connected->id.name.str, data + pos, ie_len);
08366             connected->id.name.str[ie_len] = 0;
08367          }
08368          break;
08369       case AST_CONNECTED_LINE_NAME_CHAR_SET:
08370          if (ie_len != 1) {
08371             ast_log(LOG_WARNING, "Invalid connected line name char set (%u)\n",
08372                (unsigned) ie_len);
08373             break;
08374          }
08375          connected->id.name.char_set = data[pos];
08376          break;
08377       case AST_CONNECTED_LINE_NAME_PRESENTATION:
08378          if (ie_len != 1) {
08379             ast_log(LOG_WARNING, "Invalid connected line name presentation (%u)\n",
08380                (unsigned) ie_len);
08381             break;
08382          }
08383          connected->id.name.presentation = data[pos];
08384          break;
08385       case AST_CONNECTED_LINE_NAME_VALID:
08386          if (ie_len != 1) {
08387             ast_log(LOG_WARNING, "Invalid connected line name valid (%u)\n",
08388                (unsigned) ie_len);
08389             break;
08390          }
08391          connected->id.name.valid = data[pos];
08392          break;
08393 /* Connected line party id number */
08394       case AST_CONNECTED_LINE_NUMBER:
08395          ast_free(connected->id.number.str);
08396          connected->id.number.str = ast_malloc(ie_len + 1);
08397          if (connected->id.number.str) {
08398             memcpy(connected->id.number.str, data + pos, ie_len);
08399             connected->id.number.str[ie_len] = 0;
08400          }
08401          break;
08402       case AST_CONNECTED_LINE_NUMBER_PLAN:
08403          if (ie_len != 1) {
08404             ast_log(LOG_WARNING, "Invalid connected line numbering plan (%u)\n",
08405                (unsigned) ie_len);
08406             break;
08407          }
08408          connected->id.number.plan = data[pos];
08409          break;
08410       case AST_CONNECTED_LINE_NUMBER_PRESENTATION:
08411          if (ie_len != 1) {
08412             ast_log(LOG_WARNING, "Invalid connected line number presentation (%u)\n",
08413                (unsigned) ie_len);
08414             break;
08415          }
08416          connected->id.number.presentation = data[pos];
08417          break;
08418       case AST_CONNECTED_LINE_NUMBER_VALID:
08419          if (ie_len != 1) {
08420             ast_log(LOG_WARNING, "Invalid connected line number valid (%u)\n",
08421                (unsigned) ie_len);
08422             break;
08423          }
08424          connected->id.number.valid = data[pos];
08425          break;
08426 /* Connected line party id combined presentation */
08427       case AST_CONNECTED_LINE_ID_PRESENTATION:
08428          if (ie_len != 1) {
08429             ast_log(LOG_WARNING, "Invalid connected line combined presentation (%u)\n",
08430                (unsigned) ie_len);
08431             break;
08432          }
08433          combined_presentation = data[pos];
08434          got_combined_presentation = 1;
08435          break;
08436 /* Connected line party id subaddress */
08437       case AST_CONNECTED_LINE_SUBADDRESS:
08438          ast_free(connected->id.subaddress.str);
08439          connected->id.subaddress.str = ast_malloc(ie_len + 1);
08440          if (connected->id.subaddress.str) {
08441             memcpy(connected->id.subaddress.str, data + pos, ie_len);
08442             connected->id.subaddress.str[ie_len] = 0;
08443          }
08444          break;
08445       case AST_CONNECTED_LINE_SUBADDRESS_TYPE:
08446          if (ie_len != 1) {
08447             ast_log(LOG_WARNING, "Invalid connected line type of subaddress (%u)\n",
08448                (unsigned) ie_len);
08449             break;
08450          }
08451          connected->id.subaddress.type = data[pos];
08452          break;
08453       case AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN:
08454          if (ie_len != 1) {
08455             ast_log(LOG_WARNING,
08456                "Invalid connected line subaddress odd-even indicator (%u)\n",
08457                (unsigned) ie_len);
08458             break;
08459          }
08460          connected->id.subaddress.odd_even_indicator = data[pos];
08461          break;
08462       case AST_CONNECTED_LINE_SUBADDRESS_VALID:
08463          if (ie_len != 1) {
08464             ast_log(LOG_WARNING, "Invalid connected line subaddress valid (%u)\n",
08465                (unsigned) ie_len);
08466             break;
08467          }
08468          connected->id.subaddress.valid = data[pos];
08469          break;
08470 /* Connected line party tag */
08471       case AST_CONNECTED_LINE_TAG:
08472          ast_free(connected->id.tag);
08473          connected->id.tag = ast_malloc(ie_len + 1);
08474          if (connected->id.tag) {
08475             memcpy(connected->id.tag, data + pos, ie_len);
08476             connected->id.tag[ie_len] = 0;
08477          }
08478          break;
08479 /* Connected line party source */
08480       case AST_CONNECTED_LINE_SOURCE:
08481          if (ie_len != sizeof(value)) {
08482             ast_log(LOG_WARNING, "Invalid connected line source (%u)\n",
08483                (unsigned) ie_len);
08484             break;
08485          }
08486          memcpy(&value, data + pos, sizeof(value));
08487          connected->source = ntohl(value);
08488          break;
08489 /* Connected line party unknown element */
08490       default:
08491          ast_log(LOG_DEBUG, "Unknown connected line element: %u (%u)\n",
08492             (unsigned) ie_id, (unsigned) ie_len);
08493          break;
08494       }
08495    }
08496 
08497    switch (frame_version) {
08498    case 1:
08499       /*
08500        * The other end is an earlier version that we need to adjust
08501        * for compatibility.
08502        */
08503       connected->id.name.valid = 1;
08504       connected->id.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
08505       connected->id.number.valid = 1;
08506       if (got_combined_presentation) {
08507          connected->id.name.presentation = combined_presentation;
08508          connected->id.number.presentation = combined_presentation;
08509       }
08510       break;
08511    case 2:
08512       /* The other end is at the same level as we are. */
08513       break;
08514    default:
08515       /*
08516        * The other end is newer than we are.
08517        * We need to assume that they are compatible with us.
08518        */
08519       ast_log(LOG_DEBUG, "Connected line frame has newer version: %u\n",
08520          (unsigned) frame_version);
08521       break;
08522    }
08523 
08524    return 0;
08525 }

AST_DATA_STRUCTURE ( ast_channel  ,
DATA_EXPORT_CHANNEL   
)

void ast_deactivate_generator ( struct ast_channel chan  ) 

Deactivate an active generator

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

02932 {
02933    ast_channel_lock(chan);
02934    if (chan->generatordata) {
02935       if (chan->generator && chan->generator->release)
02936          chan->generator->release(chan, chan->generatordata);
02937       chan->generatordata = NULL;
02938       chan->generator = NULL;
02939       ast_channel_set_fd(chan, AST_GENERATOR_FD, -1);
02940       ast_clear_flag(chan, AST_FLAG_WRITE_INT);
02941       ast_settimeout(chan, 0, NULL, NULL);
02942    }
02943    ast_channel_unlock(chan);
02944 }

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 6169 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_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_hangup(), ast_waitfor_nandfds(), ast_write(), builtin_atxfer(), do_bridge_masquerade(), handle_invite_replaces(), iax_park(), local_attended_transfer(), sip_park(), and sip_park_thread().

06170 {
06171    format_t x;
06172    int i;
06173    int res=0;
06174    int origstate;
06175    int visible_indication;
06176    struct ast_frame *current;
06177    const struct ast_channel_tech *t;
06178    void *t_pvt;
06179    union {
06180       struct ast_party_dialed dialed;
06181       struct ast_party_caller caller;
06182       struct ast_party_connected_line connected;
06183       struct ast_party_redirecting redirecting;
06184    } exchange;
06185    struct ast_channel *clonechan, *chans[2];
06186    struct ast_channel *bridged;
06187    struct ast_cdr *cdr;
06188    struct ast_datastore *xfer_ds;
06189    struct xfer_masquerade_ds *xfer_colp;
06190    format_t rformat = original->readformat;
06191    format_t wformat = original->writeformat;
06192    char newn[AST_CHANNEL_NAME];
06193    char orig[AST_CHANNEL_NAME];
06194    char masqn[AST_CHANNEL_NAME];
06195    char zombn[AST_CHANNEL_NAME];
06196 
06197    /* XXX This operation is a bit odd.  We're essentially putting the guts of
06198     * the clone channel into the original channel.  Start by killing off the
06199     * original channel's backend.  While the features are nice, which is the
06200     * reason we're keeping it, it's still awesomely weird. XXX */
06201 
06202    /* The reasoning for the channels ao2_container lock here is complex.
06203     * 
06204     * In order to check for a race condition, the original channel must
06205     * be locked.  If it is determined that the masquerade should proceed
06206     * the original channel can absolutely not be unlocked until the end
06207     * of the function.  Since after determining the masquerade should
06208     * continue requires the channels to be unlinked from the ao2_container,
06209     * the container lock must be held first to achieve proper locking order.
06210     */
06211    ao2_lock(channels);
06212 
06213    /* lock the original channel to determine if the masquerade is require or not */
06214    ast_channel_lock(original);
06215 
06216    /* This checks to see if the masquerade has already happened or not.  There is a
06217     * race condition that exists for this function. Since all pvt and channel locks
06218     * must be let go before calling do_masquerade, it is possible that it could be
06219     * called multiple times for the same channel.  This check verifies whether
06220     * or not the masquerade has already been completed by another thread */
06221    if (!original->masq) {
06222       ast_channel_unlock(original);
06223       ao2_unlock(channels);
06224       return 0; /* masq already completed by another thread, or never needed to be done to begin with */
06225    }
06226 
06227    /* now that we have verified no race condition exists, set the clone channel */
06228    clonechan = original->masq;
06229 
06230    /* since this function already holds the global container lock, unlocking original
06231     * for deadlock avoidance will not result in any sort of masquerade race condition.
06232     * If masq is called by a different thread while this happens, it will be stuck waiting
06233     * until we unlock the container. */
06234    while (ast_channel_trylock(clonechan)) {
06235       CHANNEL_DEADLOCK_AVOIDANCE(original);
06236    }
06237 
06238    /* Get any transfer masquerade connected line exchange data. */
06239    xfer_ds = ast_channel_datastore_find(original, &xfer_ds_info, NULL);
06240    if (xfer_ds) {
06241       ast_channel_datastore_remove(original, xfer_ds);
06242       xfer_colp = xfer_ds->data;
06243    } else {
06244       xfer_colp = NULL;
06245    }
06246 
06247    /*
06248     * Release any hold on the transferee channel before proceeding
06249     * with the masquerade.
06250     */
06251    if (xfer_colp && xfer_colp->transferee_held) {
06252       ast_indicate(clonechan, AST_CONTROL_UNHOLD);
06253    }
06254 
06255    /* clear the masquerade channels */
06256    original->masq = NULL;
06257    clonechan->masqr = NULL;
06258 
06259    /* unlink from channels container as name (which is the hash value) will change */
06260    ao2_unlink(channels, original);
06261    ao2_unlink(channels, clonechan);
06262 
06263    ast_debug(4, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",
06264       clonechan->name, clonechan->_state, original->name, original->_state);
06265 
06266    /*
06267     * Stop any visible indiction on the original channel so we can
06268     * transfer it to the clonechan taking the original's place.
06269     */
06270    visible_indication = original->visible_indication;
06271    ast_indicate(original, -1);
06272 
06273    chans[0] = clonechan;
06274    chans[1] = original;
06275    ast_manager_event_multichan(EVENT_FLAG_CALL, "Masquerade", 2, chans,
06276       "Clone: %s\r\n"
06277       "CloneState: %s\r\n"
06278       "Original: %s\r\n"
06279       "OriginalState: %s\r\n",
06280       clonechan->name, ast_state2str(clonechan->_state), original->name, ast_state2str(original->_state));
06281 
06282    /* Having remembered the original read/write formats, we turn off any translation on either
06283       one */
06284    free_translation(clonechan);
06285    free_translation(original);
06286 
06287    /* Save the original name */
06288    ast_copy_string(orig, original->name, sizeof(orig));
06289    /* Save the new name */
06290    ast_copy_string(newn, clonechan->name, sizeof(newn));
06291    /* Create the masq name */
06292    snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn);
06293 
06294    /* Mangle the name of the clone channel */
06295    __ast_change_name_nolink(clonechan, masqn);
06296 
06297    /* Copy the name from the clone channel */
06298    __ast_change_name_nolink(original, newn);
06299 
06300    /* share linked id's */
06301    ast_channel_set_linkgroup(original, clonechan);
06302 
06303    /* Swap the technologies */
06304    t = original->tech;
06305    original->tech = clonechan->tech;
06306    clonechan->tech = t;
06307 
06308    /* Swap the cdrs */
06309    cdr = original->cdr;
06310    original->cdr = clonechan->cdr;
06311    clonechan->cdr = cdr;
06312 
06313    t_pvt = original->tech_pvt;
06314    original->tech_pvt = clonechan->tech_pvt;
06315    clonechan->tech_pvt = t_pvt;
06316 
06317    /* Swap the alertpipes */
06318    for (i = 0; i < 2; i++) {
06319       x = original->alertpipe[i];
06320       original->alertpipe[i] = clonechan->alertpipe[i];
06321       clonechan->alertpipe[i] = x;
06322    }
06323 
06324    /* 
06325     * Swap the readq's.  The end result should be this:
06326     *
06327     *  1) All frames should be on the new (original) channel.
06328     *  2) Any frames that were already on the new channel before this
06329     *     masquerade need to be at the end of the readq, after all of the
06330     *     frames on the old (clone) channel.
06331     *  3) The alertpipe needs to get poked for every frame that was already
06332     *     on the new channel, since we are now using the alert pipe from the
06333     *     old (clone) channel.
06334     */
06335    {
06336       AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq;
06337       AST_LIST_HEAD_SET_NOLOCK(&tmp_readq, NULL);
06338 
06339       AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list);
06340       AST_LIST_APPEND_LIST(&original->readq, &clonechan->readq, frame_list);
06341 
06342       while ((current = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) {
06343          AST_LIST_INSERT_TAIL(&original->readq, current, frame_list);
06344          if (original->alertpipe[1] > -1) {
06345             int poke = 0;
06346 
06347             if (write(original->alertpipe[1], &poke, sizeof(poke)) < 0) {
06348                ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
06349             }
06350          }
06351       }
06352    }
06353 
06354    /* Swap the raw formats */
06355    x = original->rawreadformat;
06356    original->rawreadformat = clonechan->rawreadformat;
06357    clonechan->rawreadformat = x;
06358    x = original->rawwriteformat;
06359    original->rawwriteformat = clonechan->rawwriteformat;
06360    clonechan->rawwriteformat = x;
06361 
06362    clonechan->_softhangup = AST_SOFTHANGUP_DEV;
06363 
06364    /* And of course, so does our current state.  Note we need not
06365       call ast_setstate since the event manager doesn't really consider
06366       these separate.  We do this early so that the clone has the proper
06367       state of the original channel. */
06368    origstate = original->_state;
06369    original->_state = clonechan->_state;
06370    clonechan->_state = origstate;
06371 
06372    if (clonechan->tech->fixup && clonechan->tech->fixup(original, clonechan)) {
06373       ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clonechan->name);
06374    }
06375 
06376    /* Start by disconnecting the original's physical side */
06377    if (clonechan->tech->hangup && clonechan->tech->hangup(clonechan)) {
06378       ast_log(LOG_WARNING, "Hangup failed!  Strange things may happen!\n");
06379       res = -1;
06380       goto done;
06381    }
06382 
06383    /* Mangle the name of the clone channel */
06384    snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig); /* quick, hide the brains! */
06385    __ast_change_name_nolink(clonechan, zombn);
06386 
06387    /* Update the type. */
06388    t_pvt = original->monitor;
06389    original->monitor = clonechan->monitor;
06390    clonechan->monitor = t_pvt;
06391 
06392    /* Keep the same language.  */
06393    ast_string_field_set(original, language, clonechan->language);
06394    /* Copy the FD's other than the generator fd */
06395    for (x = 0; x < AST_MAX_FDS; x++) {
06396       if (x != AST_GENERATOR_FD)
06397          ast_channel_set_fd(original, x, clonechan->fds[x]);
06398    }
06399 
06400    ast_app_group_update(clonechan, original);
06401 
06402    /* Move data stores over */
06403    if (AST_LIST_FIRST(&clonechan->datastores)) {
06404       struct ast_datastore *ds;
06405       /* We use a safe traversal here because some fixup routines actually
06406        * remove the datastore from the list and free them.
06407        */
06408       AST_LIST_TRAVERSE_SAFE_BEGIN(&clonechan->datastores, ds, entry) {
06409          if (ds->info->chan_fixup)
06410             ds->info->chan_fixup(ds->data, clonechan, original);
06411       }
06412       AST_LIST_TRAVERSE_SAFE_END;
06413       AST_LIST_APPEND_LIST(&original->datastores, &clonechan->datastores, entry);
06414    }
06415 
06416    ast_autochan_new_channel(clonechan, original);
06417 
06418    clone_variables(original, clonechan);
06419    /* Presense of ADSI capable CPE follows clone */
06420    original->adsicpe = clonechan->adsicpe;
06421    /* Bridge remains the same */
06422    /* CDR fields remain the same */
06423    /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */
06424    /* Application and data remain the same */
06425    /* Clone exception  becomes real one, as with fdno */
06426    ast_set_flag(original, ast_test_flag(clonechan, AST_FLAG_EXCEPTION | AST_FLAG_OUTGOING));
06427    original->fdno = clonechan->fdno;
06428    /* Schedule context remains the same */
06429    /* Stream stuff stays the same */
06430    /* Keep the original state.  The fixup code will need to work with it most likely */
06431 
06432    /*
06433     * Just swap the whole structures, nevermind the allocations,
06434     * they'll work themselves out.
06435     */
06436    exchange.dialed = original->dialed;
06437    original->dialed = clonechan->dialed;
06438    clonechan->dialed = exchange.dialed;
06439 
06440    exchange.caller = original->caller;
06441    original->caller = clonechan->caller;
06442    clonechan->caller = exchange.caller;
06443 
06444    exchange.connected = original->connected;
06445    original->connected = clonechan->connected;
06446    clonechan->connected = exchange.connected;
06447 
06448    exchange.redirecting = original->redirecting;
06449    original->redirecting = clonechan->redirecting;
06450    clonechan->redirecting = exchange.redirecting;
06451 
06452    report_new_callerid(original);
06453 
06454    /* Restore original timing file descriptor */
06455    ast_channel_set_fd(original, AST_TIMING_FD, original->timingfd);
06456 
06457    /* Our native formats are different now */
06458    original->nativeformats = clonechan->nativeformats;
06459 
06460    /* Context, extension, priority, app data, jump table,  remain the same */
06461    /* pvt switches.  pbx stays the same, as does next */
06462 
06463    /* Set the write format */
06464    ast_set_write_format(original, wformat);
06465 
06466    /* Set the read format */
06467    ast_set_read_format(original, rformat);
06468 
06469    /* Copy the music class */
06470    ast_string_field_set(original, musicclass, clonechan->musicclass);
06471 
06472    /* copy over accuntcode and set peeraccount across the bridge */
06473    ast_string_field_set(original, accountcode, S_OR(clonechan->accountcode, ""));
06474    if (original->_bridge) {
06475       /* XXX - should we try to lock original->_bridge here? */
06476       ast_string_field_set(original->_bridge, peeraccount, S_OR(clonechan->accountcode, ""));
06477       ast_cel_report_event(original, AST_CEL_BRIDGE_UPDATE, NULL, NULL, NULL);
06478    }
06479 
06480    ast_debug(1, "Putting channel %s in %s/%s formats\n", original->name,
06481       ast_getformatname(wformat), ast_getformatname(rformat));
06482 
06483    /* Okay.  Last thing is to let the channel driver know about all this mess, so he
06484       can fix up everything as best as possible */
06485    if (original->tech->fixup) {
06486       if (original->tech->fixup(clonechan, original)) {
06487          ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n",
06488             original->tech->type, original->name);
06489          res = -1;
06490          goto done;
06491       }
06492    } else
06493       ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)!  Bad things may happen.\n",
06494          original->tech->type, original->name);
06495 
06496    /* 
06497     * If an indication is currently playing, maintain it on the channel 
06498     * that is taking the place of original 
06499     *
06500     * This is needed because the masquerade is swapping out in the internals
06501     * of this channel, and the new channel private data needs to be made
06502     * aware of the current visible indication (RINGING, CONGESTION, etc.)
06503     */
06504    if (visible_indication) {
06505       ast_indicate(original, visible_indication);
06506    }
06507 
06508    /* Now, at this point, the "clone" channel is totally F'd up.  We mark it as
06509       a zombie so nothing tries to touch it.  If it's already been marked as a
06510       zombie, then free it now (since it already is considered invalid). */
06511    if (ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) {
06512       ast_debug(1, "Destroying channel clone '%s'\n", clonechan->name);
06513       ast_channel_unlock(clonechan);
06514       ast_manager_event(clonechan, EVENT_FLAG_CALL, "Hangup",
06515          "Channel: %s\r\n"
06516          "Uniqueid: %s\r\n"
06517          "Cause: %d\r\n"
06518          "Cause-txt: %s\r\n",
06519          clonechan->name,
06520          clonechan->uniqueid,
06521          clonechan->hangupcause,
06522          ast_cause2str(clonechan->hangupcause)
06523          );
06524       clonechan = ast_channel_release(clonechan);
06525    } else {
06526       ast_debug(1, "Released clone lock on '%s'\n", clonechan->name);
06527       ast_set_flag(clonechan, AST_FLAG_ZOMBIE);
06528       ast_queue_frame(clonechan, &ast_null_frame);
06529    }
06530 
06531    /* Signal any blocker */
06532    if (ast_test_flag(original, AST_FLAG_BLOCKING))
06533       pthread_kill(original->blocker, SIGURG);
06534    ast_debug(1, "Done Masquerading %s (%d)\n", original->name, original->_state);
06535 
06536    if ((bridged = ast_bridged_channel(original))) {
06537       ast_channel_lock(bridged);
06538       ast_indicate(bridged, AST_CONTROL_SRCCHANGE);
06539       ast_channel_unlock(bridged);
06540    }
06541    ast_indicate(original, AST_CONTROL_SRCCHANGE);
06542 
06543    if (xfer_colp) {
06544       /*
06545        * After the masquerade, the original channel pointer actually
06546        * points to the new transferee channel and the bridged channel
06547        * is still the intended transfer target party.
06548        */
06549       masquerade_colp_transfer(original, xfer_colp);
06550    }
06551 
06552 done:
06553    if (xfer_ds) {
06554       ast_datastore_free(xfer_ds);
06555    }
06556    /* it is possible for the clone channel to disappear during this */
06557    if (clonechan) {
06558       ast_channel_unlock(original);
06559       ast_channel_unlock(clonechan);
06560       ao2_link(channels, clonechan);
06561       ao2_link(channels, original);
06562    } else {
06563       ast_channel_unlock(original);
06564       ao2_link(channels, original);
06565    }
06566 
06567    ao2_unlock(channels);
06568 
06569    return res;
06570 }

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.

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

01322 {
01323    struct ast_channel *tmp;
01324    struct varshead *headp;
01325 
01326 #if defined(REF_DEBUG)
01327    tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel",
01328       file, line, function, 1);
01329 #elif defined(__AST_DEBUG_MALLOC)
01330    tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel",
01331       file, line, function, 0);
01332 #else
01333    tmp = ao2_alloc(sizeof(*tmp), ast_dummy_channel_destructor);
01334 #endif
01335    if (!tmp) {
01336       /* Dummy channel structure allocation failure. */
01337       return NULL;
01338    }
01339 
01340    if ((ast_string_field_init(tmp, 128))) {
01341       return ast_channel_unref(tmp);
01342    }
01343 
01344    headp = &tmp->varshead;
01345    AST_LIST_HEAD_INIT_NOLOCK(headp);
01346 
01347    return tmp;
01348 }

static void ast_dummy_channel_destructor ( void *  obj  )  [static]

Free a dummy channel structure.

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

02432 {
02433    struct ast_channel *chan = obj;
02434    struct ast_var_t *vardata;
02435    struct varshead *headp;
02436 
02437    headp = &chan->varshead;
02438 
02439    ast_party_dialed_free(&chan->dialed);
02440    ast_party_caller_free(&chan->caller);
02441    ast_party_connected_line_free(&chan->connected);
02442    ast_party_redirecting_free(&chan->redirecting);
02443 
02444    /* loop over the variables list, freeing all data and deleting list items */
02445    /* no need to lock the list, as the channel is already locked */
02446    while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
02447       ast_var_delete(vardata);
02448 
02449    if (chan->cdr) {
02450       ast_cdr_discard(chan->cdr);
02451       chan->cdr = NULL;
02452    }
02453 
02454    ast_string_field_free_memory(chan);
02455 }

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

06720 {
06721    /* Copy voice back and forth between the two channels. */
06722    struct ast_channel *cs[3];
06723    struct ast_frame *f;
06724    enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
06725    format_t o0nativeformats;
06726    format_t o1nativeformats;
06727    int watch_c0_dtmf;
06728    int watch_c1_dtmf;
06729    void *pvt0, *pvt1;
06730    /* Indicates whether a frame was queued into a jitterbuffer */
06731    int frame_put_in_jb = 0;
06732    int jb_in_use;
06733    int to;
06734    
06735    cs[0] = c0;
06736    cs[1] = c1;
06737    pvt0 = c0->tech_pvt;
06738    pvt1 = c1->tech_pvt;
06739    o0nativeformats = c0->nativeformats;
06740    o1nativeformats = c1->nativeformats;
06741    watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0;
06742    watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1;
06743 
06744    /* Check the need of a jitterbuffer for each channel */
06745    jb_in_use = ast_jb_do_usecheck(c0, c1);
06746    if (jb_in_use)
06747       ast_jb_empty_and_reset(c0, c1);
06748 
06749    ast_poll_channel_add(c0, c1);
06750 
06751    if (config->feature_timer > 0 && ast_tvzero(config->nexteventts)) {
06752       /* nexteventts is not set when the bridge is not scheduled to
06753        * break, so calculate when the bridge should possibly break
06754        * if a partial feature match timed out */
06755       config->nexteventts = ast_tvadd(ast_tvnow(), ast_samp2tv(config->feature_timer, 1000));
06756    }
06757 
06758    for (;;) {
06759       struct ast_channel *who, *other;
06760 
06761       if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) ||
06762           (o0nativeformats != c0->nativeformats) ||
06763           (o1nativeformats != c1->nativeformats)) {
06764          /* Check for Masquerade, codec changes, etc */
06765          res = AST_BRIDGE_RETRY;
06766          break;
06767       }
06768       if (config->nexteventts.tv_sec) {
06769          to = ast_tvdiff_ms(config->nexteventts, ast_tvnow());
06770          if (to <= 0) {
06771             if (config->timelimit && !config->feature_timer && !ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) {
06772                res = AST_BRIDGE_RETRY;
06773                /* generic bridge ending to play warning */
06774                ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
06775             } else if (config->feature_timer) {
06776                /* feature timer expired - make sure we do not play warning */
06777                ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE);
06778                res = AST_BRIDGE_RETRY;
06779             } else {
06780                res = AST_BRIDGE_COMPLETE;
06781             }
06782             break;
06783          }
06784       } else {
06785          /* If a feature has been started and the bridge is configured to 
06786           * to not break, leave the channel bridge when the feature timer
06787           * time has elapsed so the DTMF will be sent to the other side. 
06788           */
06789          if (!ast_tvzero(config->nexteventts)) {
06790             int diff = ast_tvdiff_ms(config->nexteventts, ast_tvnow());
06791             if (diff <= 0) {
06792                res = AST_BRIDGE_RETRY;
06793                break;
06794             }
06795          }
06796          to = -1;
06797       }
06798       /* Calculate the appropriate max sleep interval - in general, this is the time,
06799          left to the closest jb delivery moment */
06800       if (jb_in_use)
06801          to = ast_jb_get_when_to_wakeup(c0, c1, to);
06802       who = ast_waitfor_n(cs, 2, &to);
06803       if (!who) {
06804          /* No frame received within the specified timeout - check if we have to deliver now */
06805          if (jb_in_use)
06806             ast_jb_get_and_deliver(c0, c1);
06807          if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */
06808             if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
06809                c0->_softhangup &= ~AST_SOFTHANGUP_UNBRIDGE;
06810             }
06811             if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
06812                c1->_softhangup &= ~AST_SOFTHANGUP_UNBRIDGE;
06813             }
06814             c0->_bridge = c1;
06815             c1->_bridge = c0;
06816          }
06817          continue;
06818       }
06819       f = ast_read(who);
06820       if (!f) {
06821          *fo = NULL;
06822          *rc = who;
06823          ast_debug(1, "Didn't get a frame from channel: %s\n",who->name);
06824          break;
06825       }
06826 
06827       other = (who == c0) ? c1 : c0; /* the 'other' channel */
06828       /* Try add the frame info the who's bridged channel jitterbuff */
06829       if (jb_in_use)
06830          frame_put_in_jb = !ast_jb_put(other, f);
06831 
06832       if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) {
06833          int bridge_exit = 0;
06834 
06835          switch (f->subclass.integer) {
06836          case AST_CONTROL_AOC:
06837             ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
06838             break;
06839          case AST_CONTROL_REDIRECTING:
06840             if (ast_channel_redirecting_macro(who, other, f, other == c0, 1)) {
06841                ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
06842             }
06843             break;
06844          case AST_CONTROL_CONNECTED_LINE:
06845             if (ast_channel_connected_line_macro(who, other, f, other == c0, 1)) {
06846                ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
06847             }
06848             break;
06849          case AST_CONTROL_HOLD:
06850          case AST_CONTROL_UNHOLD:
06851          case AST_CONTROL_VIDUPDATE:
06852          case AST_CONTROL_SRCUPDATE:
06853          case AST_CONTROL_SRCCHANGE:
06854          case AST_CONTROL_T38_PARAMETERS:
06855             ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
06856             if (jb_in_use) {
06857                ast_jb_empty_and_reset(c0, c1);
06858             }
06859             break;
06860          default:
06861             *fo = f;
06862             *rc = who;
06863             bridge_exit = 1;
06864             ast_debug(1, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass.integer, who->name);
06865             break;
06866          }
06867          if (bridge_exit)
06868             break;
06869       }
06870       if ((f->frametype == AST_FRAME_VOICE) ||
06871           (f->frametype == AST_FRAME_DTMF_BEGIN) ||
06872           (f->frametype == AST_FRAME_DTMF) ||
06873           (f->frametype == AST_FRAME_VIDEO) ||
06874           (f->frametype == AST_FRAME_IMAGE) ||
06875           (f->frametype == AST_FRAME_HTML) ||
06876           (f->frametype == AST_FRAME_MODEM) ||
06877           (f->frametype == AST_FRAME_TEXT)) {
06878          /* monitored dtmf causes exit from bridge */
06879          int monitored_source = (who == c0) ? watch_c0_dtmf : watch_c1_dtmf;
06880 
06881          if (monitored_source &&
06882             (f->frametype == AST_FRAME_DTMF_END ||
06883             f->frametype == AST_FRAME_DTMF_BEGIN)) {
06884             *fo = f;
06885             *rc = who;
06886             ast_debug(1, "Got DTMF %s on channel (%s)\n", 
06887                f->frametype == AST_FRAME_DTMF_END ? "end" : "begin",
06888                who->name);
06889 
06890             break;
06891          }
06892          /* Write immediately frames, not passed through jb */
06893          if (!frame_put_in_jb)
06894             ast_write(other, f);
06895             
06896          /* Check if we have to deliver now */
06897          if (jb_in_use)
06898             ast_jb_get_and_deliver(c0, c1);
06899       }
06900       /* XXX do we want to pass on also frames not matched above ? */
06901       ast_frfree(f);
06902 
06903 #ifndef HAVE_EPOLL
06904       /* Swap who gets priority */
06905       cs[2] = cs[0];
06906       cs[0] = cs[1];
06907       cs[1] = cs[2];
06908 #endif
06909    }
06910 
06911    ast_poll_channel_del(c0, c1);
06912 
06913    return res;
06914 }

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

00891 {
00892    struct chanlist *chanls;
00893    const struct ast_channel_tech *ret = NULL;
00894 
00895    AST_RWLIST_RDLOCK(&backends);
00896 
00897    AST_RWLIST_TRAVERSE(&backends, chanls, list) {
00898       if (!strcasecmp(name, chanls->tech->type)) {
00899          ret = chanls->tech;
00900          break;
00901       }
00902    }
00903 
00904    AST_RWLIST_UNLOCK(&backends);
00905    
00906    return ret;
00907 }

ast_group_t ast_get_group ( const char *  s  ) 

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

07465 {
07466    char *piece;
07467    char *c;
07468    int start=0, finish=0, x;
07469    ast_group_t group = 0;
07470 
07471    if (ast_strlen_zero(s))
07472       return 0;
07473 
07474    c = ast_strdupa(s);
07475    
07476    while ((piece = strsep(&c, ","))) {
07477       if (sscanf(piece, "%30d-%30d", &start, &finish) == 2) {
07478          /* Range */
07479       } else if (sscanf(piece, "%30d", &start)) {
07480          /* Just one */
07481          finish = start;
07482       } else {
07483          ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece);
07484          continue;
07485       }
07486       for (x = start; x <= finish; x++) {
07487          if ((x > 63) || (x < 0)) {
07488             ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x);
07489          } else
07490             group |= ((ast_group_t) 1 << x);
07491       }
07492    }
07493    return group;
07494 }

int ast_hangup ( struct ast_channel chan  ) 

Hang up a channel.

Note:
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 2658 of file channel.c.

References ao2_unlink, 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_release(), ast_channel_unlock, 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_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_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_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_parkinglot(), mgcp_new(), mgcp_ss(), monitor_dial(), mwi_thread(), my_distinctive_ring(), my_handle_notify_message(), nbs_new(), oss_new(), park_exec_full(), parkandannounce_exec(), phone_new(), play_sound_file(), pri_dchannel(), pri_ss_thread(), rpt(), rpt_call(), rpt_tele_thread(), sip_new(), sip_park(), sip_park_thread(), skinny_new(), skinny_ss(), ss7_start_call(), unistim_new(), usbradio_new(), and wait_for_winner().

02659 {
02660    int res = 0;
02661    char extra_str[64]; /* used for cel logging below */
02662 
02663    /* Don't actually hang up a channel that will masquerade as someone else, or
02664       if someone is going to masquerade as us */
02665    ast_channel_lock(chan);
02666 
02667    if (chan->audiohooks) {
02668       ast_audiohook_detach_list(chan->audiohooks);
02669       chan->audiohooks = NULL;
02670    }
02671 
02672    ast_framehook_list_destroy(chan);
02673 
02674    ast_autoservice_stop(chan);
02675 
02676    if (chan->masq) {
02677       ast_channel_unlock(chan);
02678       if (ast_do_masquerade(chan)) {
02679          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
02680       }
02681       ast_channel_lock(chan);
02682    }
02683 
02684    if (chan->masq) {
02685       ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name);
02686       ast_channel_unlock(chan);
02687       return 0;
02688    }
02689    /* If this channel is one which will be masqueraded into something,
02690       mark it as a zombie already, so we know to free it later */
02691    if (chan->masqr) {
02692       ast_set_flag(chan, AST_FLAG_ZOMBIE);
02693       ast_channel_unlock(chan);
02694       return 0;
02695    }
02696    ast_channel_unlock(chan);
02697 
02698    ao2_unlink(channels, chan);
02699 
02700    ast_channel_lock(chan);
02701    free_translation(chan);
02702    /* Close audio stream */
02703    if (chan->stream) {
02704       ast_closestream(chan->stream);
02705       chan->stream = NULL;
02706    }
02707    /* Close video stream */
02708    if (chan->vstream) {
02709       ast_closestream(chan->vstream);
02710       chan->vstream = NULL;
02711    }
02712    if (chan->sched) {
02713       sched_context_destroy(chan->sched);
02714       chan->sched = NULL;
02715    }
02716 
02717    if (chan->generatordata)   /* Clear any tone stuff remaining */
02718       if (chan->generator && chan->generator->release)
02719          chan->generator->release(chan, chan->generatordata);
02720    chan->generatordata = NULL;
02721    chan->generator = NULL;
02722 
02723    snprintf(extra_str, sizeof(extra_str), "%d,%s,%s", chan->hangupcause, chan->hangupsource, S_OR(pbx_builtin_getvar_helper(chan, "DIALSTATUS"), ""));
02724    ast_cel_report_event(chan, AST_CEL_HANGUP, NULL, extra_str, NULL);
02725 
02726    if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
02727       ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
02728                "is blocked by thread %ld in procedure %s!  Expect a failure\n",
02729                (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc);
02730       ast_assert(ast_test_flag(chan, AST_FLAG_BLOCKING) == 0);
02731    }
02732    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) {
02733       ast_debug(1, "Hanging up channel '%s'\n", chan->name);
02734       if (chan->tech->hangup)
02735          res = chan->tech->hangup(chan);
02736    } else {
02737       ast_debug(1, "Hanging up zombie '%s'\n", chan->name);
02738    }
02739          
02740    ast_channel_unlock(chan);
02741    ast_cc_offer(chan);
02742    ast_manager_event(chan, EVENT_FLAG_CALL, "Hangup",
02743       "Channel: %s\r\n"
02744       "Uniqueid: %s\r\n"
02745       "CallerIDNum: %s\r\n"
02746       "CallerIDName: %s\r\n"
02747       "Cause: %d\r\n"
02748       "Cause-txt: %s\r\n",
02749       chan->name,
02750       chan->uniqueid,
02751       S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "<unknown>"),
02752       S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, "<unknown>"),
02753       chan->hangupcause,
02754       ast_cause2str(chan->hangupcause)
02755       );
02756 
02757    if (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_BRIDGED) && 
02758       !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED) && 
02759        (chan->cdr->disposition != AST_CDR_NULL || ast_test_flag(chan->cdr, AST_CDR_FLAG_DIALED))) {
02760       ast_channel_lock(chan);
02761          
02762       ast_cdr_end(chan->cdr);
02763       ast_cdr_detach(chan->cdr);
02764       chan->cdr = NULL;
02765       ast_channel_unlock(chan);
02766    }
02767 
02768    chan = ast_channel_release(chan);
02769 
02770    return res;
02771 }

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

References ast_indicate_data(), and chanlist::chan.

Referenced by __ast_play_and_record(), agent_new(), 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_parkinglot(), mgcp_ss(), monitor_dial(), oss_call(), park_call_full(), park_exec_full(), pbx_builtin_busy(), pbx_builtin_congestion(), 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().

04160 {
04161    return ast_indicate_data(chan, condition, NULL, 0);
04162 }

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 4211 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_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_VIDUPDATE, AST_CONTROL_WINK, ast_debug, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, ast_framehook_list_is_empty(), ast_framehook_list_read_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_parkinglot(), 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().

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

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

References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.

Referenced by load_module().

07503 {
07504    ast_moh_start_ptr = start_ptr;
07505    ast_moh_stop_ptr = stop_ptr;
07506    ast_moh_cleanup_ptr = cleanup_ptr;
07507 }

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

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

Referenced by add_sdp(), and ast_read_generator_actions().

04145 {
04146    return (ast_opt_internal_timing && chan->timingfd > -1);
04147 }

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

01729 {
01730    /* Do not add a default entry in this switch statement.  Each new
01731     * frame type should be addressed directly as to whether it should
01732     * be queued up or not.
01733     */
01734    switch (frame->frametype) {
01735    case AST_FRAME_CONTROL:
01736    case AST_FRAME_TEXT:
01737    case AST_FRAME_IMAGE:
01738    case AST_FRAME_HTML:
01739       return 1;
01740 
01741    case AST_FRAME_DTMF_END:
01742    case AST_FRAME_DTMF_BEGIN:
01743    case AST_FRAME_VOICE:
01744    case AST_FRAME_VIDEO:
01745    case AST_FRAME_NULL:
01746    case AST_FRAME_IAX:
01747    case AST_FRAME_CNG:
01748    case AST_FRAME_MODEM:
01749       return 0;
01750    }
01751    return 0;
01752 }

void ast_moh_cleanup ( struct ast_channel chan  ) 

Definition at line 7534 of file channel.c.

References ast_moh_cleanup_ptr.

Referenced by ast_channel_destructor().

07535 {
07536    if (ast_moh_cleanup_ptr)
07537       ast_moh_cleanup_ptr(chan);
07538 }

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

07518 {
07519    if (ast_moh_start_ptr)
07520       return ast_moh_start_ptr(chan, mclass, interpclass);
07521 
07522    ast_verb(3, "Music class %s requested but no musiconhold loaded.\n", mclass ? mclass : (interpclass ? interpclass : "default"));
07523 
07524    return 0;
07525 }

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

07529 {
07530    if (ast_moh_stop_ptr)
07531       ast_moh_stop_ptr(chan);
07532 }

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

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

Referenced by ast_call_forward(), and do_forward().

02180 {
02181    if (dest == src) {
02182       /* Don't copy to self */
02183       return;
02184    }
02185 
02186    ast_party_id_copy(&dest->id, &src->id);
02187    ast_party_id_copy(&dest->ani, &src->ani);
02188    dest->ani2 = src->ani2;
02189 }

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

02206 {
02207    ast_party_id_free(&doomed->id);
02208    ast_party_id_free(&doomed->ani);
02209 }

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

02173 {
02174    ast_party_id_init(&init->id);
02175    ast_party_id_init(&init->ani);
02176    init->ani2 = 0;
02177 }

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

02199 {
02200    ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL);
02201    ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL);
02202    dest->ani2 = src->ani2;
02203 }

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

02192 {
02193    ast_party_id_set_init(&init->id, &guide->id);
02194    ast_party_id_set_init(&init->ani, &guide->ani);
02195    init->ani2 = guide->ani2;
02196 }

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

Referenced by ast_pickup_call().

02249 {
02250    connected->id = caller->id;
02251    connected->ani = caller->ani;
02252    connected->ani2 = caller->ani2;
02253    connected->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN;
02254 }

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 2219 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(), builtin_atxfer(), dial_exec_full(), do_forward(), local_attended_transfer(), misdn_attempt_transfer(), party_connected_line_copy_transfer(), and pickup_do().

02220 {
02221    if (dest == src) {
02222       /* Don't copy to self */
02223       return;
02224    }
02225 
02226    ast_party_id_copy(&dest->id, &src->id);
02227    ast_party_id_copy(&dest->ani, &src->ani);
02228    dest->ani2 = src->ani2;
02229    dest->source = src->source;
02230 }

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

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

Referenced by __ast_read(), ast_channel_destructor(), ast_dummy_channel_destructor(), ast_indicate_data(), atxfer_fail_cleanup(), builtin_atxfer(), callattempt_free(), chanlist_free(), connectedline_write(), feature_request_and_dial(), local_attended_transfer(), misdn_attempt_transfer(), pickup_do(), sig_pri_handle_subcmds(), socket_process(), wait_for_answer(), and xfer_ds_destroy().

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

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 2211 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(), builtin_atxfer(), handle_request_invite(), handle_request_update(), handle_response_invite(), local_attended_transfer(), misdn_attempt_transfer(), misdn_queue_connected_line_update(), pickup_do(), sig_pri_handle_subcmds(), socket_process(), and wait_for_answer().

02212 {
02213    ast_party_id_init(&init->id);
02214    ast_party_id_init(&init->ani);
02215    init->ani2 = 0;
02216    init->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN;
02217 }

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

02241 {
02242    ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL);
02243    ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL);
02244    dest->ani2 = src->ani2;
02245    dest->source = src->source;
02246 }

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 2232 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(), and feature_request_and_dial().

02233 {
02234    ast_party_id_set_init(&init->id, &guide->id);
02235    ast_party_id_set_init(&init->ani, &guide->ani);
02236    init->ani2 = guide->ani2;
02237    init->source = guide->source;
02238 }

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

02131 {
02132    if (dest == src) {
02133       /* Don't copy to self */
02134       return;
02135    }
02136 
02137    ast_free(dest->number.str);
02138    dest->number.str = ast_strdup(src->number.str);
02139    dest->number.plan = src->number.plan;
02140    ast_party_subaddress_copy(&dest->subaddress, &src->subaddress);
02141    dest->transit_network_select = src->transit_network_select;
02142 }

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

02166 {
02167    ast_free(doomed->number.str);
02168    doomed->number.str = NULL;
02169    ast_party_subaddress_free(&doomed->subaddress);
02170 }

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

02123 {
02124    init->number.str = NULL;
02125    init->number.plan = 0;/* Unknown */
02126    ast_party_subaddress_init(&init->subaddress);
02127    init->transit_network_select = 0;
02128 }

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

02153 {
02154    if (src->number.str && src->number.str != dest->number.str) {
02155       ast_free(dest->number.str);
02156       dest->number.str = ast_strdup(src->number.str);
02157    }
02158    dest->number.plan = src->number.plan;
02159 
02160    ast_party_subaddress_set(&dest->subaddress, &src->subaddress);
02161 
02162    dest->transit_network_select = src->transit_network_select;
02163 }

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

02145 {
02146    init->number.str = NULL;
02147    init->number.plan = guide->number.plan;
02148    ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress);
02149    init->transit_network_select = guide->transit_network_select;
02150 }

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 2001 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(), and ast_party_redirecting_copy().

02002 {
02003    if (dest == src) {
02004       /* Don't copy to self */
02005       return;
02006    }
02007 
02008    ast_party_name_copy(&dest->name, &src->name);
02009    ast_party_number_copy(&dest->number, &src->number);
02010    ast_party_subaddress_copy(&dest->subaddress, &src->subaddress);
02011 
02012    ast_free(dest->tag);
02013    dest->tag = ast_strdup(src->tag);
02014 }

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

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

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

02048 {
02049    ast_party_name_free(&doomed->name);
02050    ast_party_number_free(&doomed->number);
02051    ast_party_subaddress_free(&doomed->subaddress);
02052 
02053    ast_free(doomed->tag);
02054    doomed->tag = NULL;
02055 }

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 1993 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(), and do_forward().

01994 {
01995    ast_party_name_init(&init->name);
01996    ast_party_number_init(&init->number);
01997    ast_party_subaddress_init(&init->subaddress);
01998    init->tag = NULL;
01999 }

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 2057 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_handle_subcmds(), sip_call(), and socket_process().

02058 {
02059    int number_priority;
02060    int number_value;
02061    int number_screening;
02062    int name_priority;
02063    int name_value;
02064 
02065    /* Determine name presentation priority. */
02066    if (!id->name.valid) {
02067       name_value = AST_PRES_UNAVAILABLE;
02068       name_priority = 3;
02069    } else {
02070       name_value = id->name.presentation & AST_PRES_RESTRICTION;
02071       switch (name_value) {
02072       case AST_PRES_RESTRICTED:
02073          name_priority = 0;
02074          break;
02075       case AST_PRES_ALLOWED:
02076          name_priority = 1;
02077          break;
02078       case AST_PRES_UNAVAILABLE:
02079          name_priority = 2;
02080          break;
02081       default:
02082          name_value = AST_PRES_UNAVAILABLE;
02083          name_priority = 3;
02084          break;
02085       }
02086    }
02087 
02088    /* Determine number presentation priority. */
02089    if (!id->number.valid) {
02090       number_screening = AST_PRES_USER_NUMBER_UNSCREENED;
02091       number_value = AST_PRES_UNAVAILABLE;
02092       number_priority = 3;
02093    } else {
02094       number_screening = id->number.presentation & AST_PRES_NUMBER_TYPE;
02095       number_value = id->number.presentation & AST_PRES_RESTRICTION;
02096       switch (number_value) {
02097       case AST_PRES_RESTRICTED:
02098          number_priority = 0;
02099          break;
02100       case AST_PRES_ALLOWED:
02101          number_priority = 1;
02102          break;
02103       case AST_PRES_UNAVAILABLE:
02104          number_priority = 2;
02105          break;
02106       default:
02107          number_screening = AST_PRES_USER_NUMBER_UNSCREENED;
02108          number_value = AST_PRES_UNAVAILABLE;
02109          number_priority = 3;
02110          break;
02111       }
02112    }
02113 
02114    /* Select the wining presentation value. */
02115    if (name_priority < number_priority) {
02116       number_value = name_value;
02117    }
02118 
02119    return number_value | number_screening;
02120 }

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

02025 {
02026    if (dest == src) {
02027       /* Don't set to self */
02028       return;
02029    }
02030 
02031    if (!update || update->name) {
02032       ast_party_name_set(&dest->name, &src->name);
02033    }
02034    if (!update || update->number) {
02035       ast_party_number_set(&dest->number, &src->number);
02036    }
02037    if (!update || update->subaddress) {
02038       ast_party_subaddress_set(&dest->subaddress, &src->subaddress);
02039    }
02040 
02041    if (src->tag && src->tag != dest->tag) {
02042       ast_free(dest->tag);
02043       dest->tag = ast_strdup(src->tag);
02044    }
02045 }

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 2016 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(), and ast_party_redirecting_set_init().

02017 {
02018    ast_party_name_set_init(&init->name, &guide->name);
02019    ast_party_number_set_init(&init->number, &guide->number);
02020    ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress);
02021    init->tag = NULL;
02022 }

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

01843 {
01844    if (dest == src) {
01845       /* Don't copy to self */
01846       return;
01847    }
01848 
01849    ast_free(dest->str);
01850    dest->str = ast_strdup(src->str);
01851    dest->char_set = src->char_set;
01852    dest->presentation = src->presentation;
01853    dest->valid = src->valid;
01854 }

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

01882 {
01883    ast_free(doomed->str);
01884    doomed->str = NULL;
01885 }

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

01835 {
01836    init->str = NULL;
01837    init->char_set = AST_PARTY_CHAR_SET_ISO8859_1;
01838    init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
01839    init->valid = 0;
01840 }

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

01865 {
01866    if (dest == src) {
01867       /* Don't set to self */
01868       return;
01869    }
01870 
01871    if (src->str && src->str != dest->str) {
01872       ast_free(dest->str);
01873       dest->str = ast_strdup(src->str);
01874    }
01875 
01876    dest->char_set = src->char_set;
01877    dest->presentation = src->presentation;
01878    dest->valid = src->valid;
01879 }

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

01857 {
01858    init->str = NULL;
01859    init->char_set = guide->char_set;
01860    init->presentation = guide->presentation;
01861    init->valid = guide->valid;
01862 }

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

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

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

01935 {
01936    ast_free(doomed->str);
01937    doomed->str = NULL;
01938 }

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

01888 {
01889    init->str = NULL;
01890    init->plan = 0;/* Unknown */
01891    init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
01892    init->valid = 0;
01893 }

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

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

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

01910 {
01911    init->str = NULL;
01912    init->plan = guide->plan;
01913    init->presentation = guide->presentation;
01914    init->valid = guide->valid;
01915 }

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 2270 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_channel_redirecting_macro(), begin_dial_channel(), dial_exec_full(), do_forward(), local_call(), and ring_entry().

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

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

02300 {
02301    ast_party_id_free(&doomed->from);
02302    ast_party_id_free(&doomed->to);
02303 }

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

02263 {
02264    ast_party_id_init(&init->from);
02265    ast_party_id_init(&init->to);
02266    init->count = 0;
02267    init->reason = AST_REDIRECTING_REASON_UNKNOWN;
02268 }

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

02292 {
02293    ast_party_id_set(&dest->from, &src->from, update ? &update->from : NULL);
02294    ast_party_id_set(&dest->to, &src->to, update ? &update->to : NULL);
02295    dest->reason = src->reason;
02296    dest->count = src->count;
02297 }

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

02284 {
02285    ast_party_id_set_init(&init->from, &guide->from);
02286    ast_party_id_set_init(&init->to, &guide->to);
02287    init->count = guide->count;
02288    init->reason = guide->reason;
02289 }

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

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

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

References ast_free, and ast_party_subaddress::str.

Referenced by ast_party_dialed_free(), and ast_party_id_free().

01988 {
01989    ast_free(doomed->str);
01990    doomed->str = NULL;
01991 }

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

01941 {
01942    init->str = NULL;
01943    init->type = 0;
01944    init->odd_even_indicator = 0;
01945    init->valid = 0;
01946 }

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

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

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

01963 {
01964    init->str = NULL;
01965    init->type = guide->type;
01966    init->odd_even_indicator = guide->odd_even_indicator;
01967    init->valid = guide->valid;
01968 }

int ast_plc_reload ( void   ) 

Reload genericplc configuration value from codecs.conf.

Implementation is in main/channel.c

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

07554 {
07555    struct ast_variable *var;
07556    struct ast_flags config_flags = { 0 };
07557    struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
07558    if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID)
07559       return 0;
07560    for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
07561       if (!strcasecmp(var->name, "genericplc")) {
07562          ast_set2_flag(&ast_options, ast_true(var->value), AST_OPT_FLAG_GENERIC_PLC);
07563       }
07564    }
07565    ast_config_destroy(cfg);
07566    return 0;
07567 }

void ast_poll_channel_add ( struct ast_channel chan0,
struct ast_channel chan1 
)

Add a channel to an optimized waitfor

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

02561 {
02562 #ifdef HAVE_EPOLL
02563    struct epoll_event ev;
02564    int i = 0;
02565 
02566    if (chan0->epfd == -1)
02567       return;
02568 
02569    /* Iterate through the file descriptors on chan1, adding them to chan0 */
02570    for (i = 0; i < AST_MAX_FDS; i++) {
02571       if (chan1->fds[i] == -1)
02572          continue;
02573       ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP;
02574       ev.data.ptr = chan1->epfd_data[i];
02575       epoll_ctl(chan0->epfd, EPOLL_CTL_ADD, chan1->fds[i], &ev);
02576    }
02577 
02578 #endif
02579    return;
02580 }

void ast_poll_channel_del ( struct ast_channel chan0,
struct ast_channel chan1 
)

Delete a channel from an optimized waitfor

Definition at line 2583 of file channel.c.

References AST_MAX_FDS, and ast_channel::fds.

Referenced by feature_request_and_dial(), and monitor_dial().

02584 {
02585 #ifdef HAVE_EPOLL
02586    struct epoll_event ev;
02587    int i = 0;
02588 
02589    if (chan0->epfd == -1)
02590       return;
02591 
02592    for (i = 0; i < AST_MAX_FDS; i++) {
02593       if (chan1->fds[i] == -1)
02594          continue;
02595       epoll_ctl(chan0->epfd, EPOLL_CTL_DEL, chan1->fds[i], &ev);
02596    }
02597 
02598 #endif
02599    return;
02600 }

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

print call- and pickup groups into buffer

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

07702 {
07703    unsigned int i;
07704    int first = 1;
07705    char num[3];
07706 
07707    buf[0] = '\0';
07708    
07709    if (!group) /* Return empty string if no group */
07710       return buf;
07711 
07712    for (i = 0; i <= 63; i++) {   /* Max group is 63 */
07713       if (group & ((ast_group_t) 1 << i)) {
07714             if (!first) {
07715             strncat(buf, ", ", buflen - strlen(buf) - 1);
07716          } else {
07717             first = 0;
07718          }
07719          snprintf(num, sizeof(num), "%u", i);
07720          strncat(buf, num, buflen - strlen(buf) - 1);
07721       }
07722    }
07723    return buf;
07724 }

int ast_prod ( struct ast_channel chan  ) 

Send empty audio to prime a channel driver.

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

04522 {
04523    struct ast_frame a = { AST_FRAME_VOICE };
04524    char nothing[128];
04525 
04526    /* Send an empty audio frame to get things moving */
04527    if (chan->_state != AST_STATE_UP) {
04528       ast_debug(1, "Prodding channel '%s'\n", chan->name);
04529       a.subclass.codec = chan->rawwriteformat;
04530       a.data.ptr = nothing + AST_FRIENDLY_OFFSET;
04531       a.src = "ast_prod"; /* this better match check in ast_write */
04532       if (ast_write(chan, &a))
04533          ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name);
04534    }
04535    return 0;
04536 }

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 1511 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_pickup_call(), 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(), pickup_do(), process_sdp(), receive_digit(), remote_hold(), send_cause2ast(), setup_rtp_connection(), sig_pri_handle_subcmds(), skinny_call(), skinny_transfer(), skinny_unhold(), unistim_call(), and update_state().

01512 {
01513    struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control };
01514    return ast_queue_frame(chan, &f);
01515 }

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 1518 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(), sip_sipredirect(), and skinny_hold().

01520 {
01521    struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control, .data.ptr = (void *) data, .datalen = datalen };
01522    return ast_queue_frame(chan, &f);
01523 }

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 1468 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_new(), 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_ss7_queue_frame(), stream_monitor(), unistim_do_senddigit(), unistim_senddigit_end(), usbradio_read(), and wakeup_sub().

01469 {
01470    return __ast_queue_frame(chan, fin, 0, NULL);
01471 }

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

01474 {
01475    return __ast_queue_frame(chan, fin, 1, NULL);
01476 }

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

01480 {
01481    struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP };
01482    /* Yeah, let's not change a lock-critical value without locking */
01483    if (!ast_channel_trylock(chan)) {
01484       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01485       ast_channel_unlock(chan);
01486    }
01487    return ast_queue_frame(chan, &f);
01488 }

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 1491 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(), handle_response_notify(), HandleCallOutgoing(), hangup_chan(), hangup_connection(), misdn_answer(), retrans_pkt(), and TransferCallStep1().

01492 {
01493    struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP };
01494 
01495    if (cause >= 0)
01496       f.data.uint32 = cause;
01497 
01498    /* Yeah, let's not change a lock-critical value without locking */
01499    if (!ast_channel_trylock(chan)) {
01500       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01501       if (cause < 0)
01502          f.data.uint32 = chan->hangupcause;
01503 
01504       ast_channel_unlock(chan);
01505    }
01506 
01507    return ast_queue_frame(chan, &f);
01508 }

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

02774 {
02775    int res = 0;
02776 
02777    ast_channel_lock(chan);
02778 
02779    /* You can't answer an outbound call */
02780    if (ast_test_flag(chan, AST_FLAG_OUTGOING)) {
02781       ast_channel_unlock(chan);
02782       return 0;
02783    }
02784 
02785    /* Stop if we're a zombie or need a soft hangup */
02786    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
02787       ast_channel_unlock(chan);
02788       return -1;
02789    }
02790 
02791    ast_channel_unlock(chan);
02792 
02793    switch (chan->_state) {
02794    case AST_STATE_RINGING:
02795    case AST_STATE_RING:
02796       ast_channel_lock(chan);
02797       if (chan->tech->answer) {
02798          res = chan->tech->answer(chan);
02799       }
02800       ast_setstate(chan, AST_STATE_UP);
02801       if (cdr_answer) {
02802          ast_cdr_answer(chan->cdr);
02803       }
02804       ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL);
02805       ast_channel_unlock(chan);
02806       break;
02807    case AST_STATE_UP:
02808       ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL);
02809       /* Calling ast_cdr_answer when it it has previously been called
02810        * is essentially a no-op, so it is safe.
02811        */
02812       if (cdr_answer) {
02813          ast_cdr_answer(chan->cdr);
02814       }
02815       break;
02816    default:
02817       break;
02818    }
02819 
02820    ast_indicate(chan, -1);
02821 
02822    return res;
02823 }

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 4149 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_wait(), autoservice_run(), background_detect_exec(), channel_spy(), check_goto_on_transfer(), 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(), iax_park_thread(), ices_exec(), isAnsweringMachine(), jack_exec(), launch_asyncagi(), local_bridge_loop(), manage_parkinglot(), masq_park_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().

04150 {
04151    return __ast_read(chan, 0);
04152 }

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

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

03511 {
03512    if (chan->generator && chan->generator->generate && chan->generatordata &&  !ast_internal_timing_enabled(chan)) {
03513       void *tmp = chan->generatordata;
03514       int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = chan->generator->generate;
03515       int res;
03516       int samples;
03517 
03518       if (chan->timingfunc) {
03519          ast_debug(1, "Generator got voice, switching to phase locked mode\n");
03520          ast_settimeout(chan, 0, NULL, NULL);
03521       }
03522 
03523       chan->generatordata = NULL;     /* reset, to let writes go through */
03524 
03525       if (f->subclass.codec != chan->writeformat) {
03526          float factor;
03527          factor = ((float) ast_format_rate(chan->writeformat)) / ((float) ast_format_rate(f->subclass.codec));
03528          samples = (int) ( ((float) f->samples) * factor );
03529       } else {
03530          samples = f->samples;
03531       }
03532       
03533       /* This unlock is here based on two assumptions that hold true at this point in the
03534        * code. 1) this function is only called from within __ast_read() and 2) all generators
03535        * call ast_write() in their generate callback.
03536        *
03537        * The reason this is added is so that when ast_write is called, the lock that occurs 
03538        * there will not recursively lock the channel. Doing this will cause intended deadlock 
03539        * avoidance not to work in deeper functions
03540        */
03541       ast_channel_unlock(chan);
03542       res = generate(chan, tmp, f->datalen, samples);
03543       ast_channel_lock(chan);
03544       chan->generatordata = tmp;
03545       if (res) {
03546          ast_debug(1, "Auto-deactivating generator\n");
03547          ast_deactivate_generator(chan);
03548       }
03549 
03550    } else if (f->frametype == AST_FRAME_CNG) {
03551       if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) {
03552          ast_debug(1, "Generator got CNG, switching to timed mode\n");
03553          ast_settimeout(chan, 50, generator_force, chan);
03554       }
03555    }
03556 }

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

References __ast_read(), and chanlist::chan.

Referenced by ast_bridge_handle_trip(), and conf_run().

04155 {
04156    return __ast_read(chan, 1);
04157 }

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

05498 {
05499    return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1);
05500 }

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

05503 {
05504    int pos = 0;   /* index in the buffer where we accumulate digits */
05505    int to = ftimeout;
05506 
05507    struct ast_silence_generator *silgen = NULL;
05508 
05509    /* Stop if we're a zombie or need a soft hangup */
05510    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
05511       return -1;
05512    if (!len)
05513       return -1;
05514    for (;;) {
05515       int d;
05516       if (c->stream) {
05517          d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
05518          ast_stopstream(c);
05519          if (!silgen && ast_opt_transmit_silence)
05520             silgen = ast_channel_start_silence_generator(c);
05521          usleep(1000);
05522          if (!d)
05523             d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
05524       } else {
05525          if (!silgen && ast_opt_transmit_silence)
05526             silgen = ast_channel_start_silence_generator(c);
05527          d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
05528       }
05529       if (d < 0) {
05530          ast_channel_stop_silence_generator(c, silgen);
05531          return AST_GETDATA_FAILED;
05532       }
05533       if (d == 0) {
05534          s[pos] = '\0';
05535          ast_channel_stop_silence_generator(c, silgen);
05536          return AST_GETDATA_TIMEOUT;
05537       }
05538       if (d == 1) {
05539          s[pos] = '\0';
05540          ast_channel_stop_silence_generator(c, silgen);
05541          return AST_GETDATA_INTERRUPTED;
05542       }
05543       if (strchr(enders, d) && (pos == 0)) {
05544          s[pos] = '\0';
05545          ast_channel_stop_silence_generator(c, silgen);
05546          return AST_GETDATA_EMPTY_END_TERMINATED;
05547       }
05548       if (!strchr(enders, d)) {
05549          s[pos++] = d;
05550       }
05551       if (strchr(enders, d) || (pos >= len)) {
05552          s[pos] = '\0';
05553          ast_channel_stop_silence_generator(c, silgen);
05554          return AST_GETDATA_COMPLETE;
05555       }
05556       to = timeout;
05557    }
05558    /* Never reached */
05559    return 0;
05560 }

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

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

Referenced by handle_recvchar().

04403 {
04404    int c;
04405    char *buf = ast_recvtext(chan, timeout);
04406    if (buf == NULL)
04407       return -1;  /* error or timeout */
04408    c = *(unsigned char *)buf;
04409    ast_free(buf);
04410    return c;
04411 }

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

04414 {
04415    int res, done = 0;
04416    char *buf = NULL;
04417    
04418    while (!done) {
04419       struct ast_frame *f;
04420       if (ast_check_hangup(chan))
04421          break;
04422       res = ast_waitfor(chan, timeout);
04423       if (res <= 0) /* timeout or error */
04424          break;
04425       timeout = res; /* update timeout */
04426       f = ast_read(chan);
04427       if (f == NULL)
04428          break; /* no frame */
04429       if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_HANGUP)
04430          done = 1;   /* force a break */
04431       else if (f->frametype == AST_FRAME_TEXT) {      /* what we want */
04432          buf = ast_strndup((char *) f->data.ptr, f->datalen);  /* dup and break */
04433          done = 1;
04434       }
04435       ast_frfree(f);
04436    }
04437    return buf;
04438 }

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

08604 {
08605    int32_t value;
08606    size_t pos = 0;
08607    int res;
08608 
08609    static const struct ast_party_id_ies from_ies = {
08610       .name.str = AST_REDIRECTING_FROM_NAME,
08611       .name.char_set = AST_REDIRECTING_FROM_NAME_CHAR_SET,
08612       .name.presentation = AST_REDIRECTING_FROM_NAME_PRESENTATION,
08613       .name.valid = AST_REDIRECTING_FROM_NAME_VALID,
08614 
08615       .number.str = AST_REDIRECTING_FROM_NUMBER,
08616       .number.plan = AST_REDIRECTING_FROM_NUMBER_PLAN,
08617       .number.presentation = AST_REDIRECTING_FROM_NUMBER_PRESENTATION,
08618       .number.valid = AST_REDIRECTING_FROM_NUMBER_VALID,
08619 
08620       .subaddress.str = AST_REDIRECTING_FROM_SUBADDRESS,
08621       .subaddress.type = AST_REDIRECTING_FROM_SUBADDRESS_TYPE,
08622       .subaddress.odd_even_indicator = AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN,
08623       .subaddress.valid = AST_REDIRECTING_FROM_SUBADDRESS_VALID,
08624 
08625       .tag = AST_REDIRECTING_FROM_TAG,
08626       .combined_presentation = AST_REDIRECTING_FROM_ID_PRESENTATION,
08627    };
08628    static const struct ast_party_id_ies to_ies = {
08629       .name.str = AST_REDIRECTING_TO_NAME,
08630       .name.char_set = AST_REDIRECTING_TO_NAME_CHAR_SET,
08631       .name.presentation = AST_REDIRECTING_TO_NAME_PRESENTATION,
08632       .name.valid = AST_REDIRECTING_TO_NAME_VALID,
08633 
08634       .number.str = AST_REDIRECTING_TO_NUMBER,
08635       .number.plan = AST_REDIRECTING_TO_NUMBER_PLAN,
08636       .number.presentation = AST_REDIRECTING_TO_NUMBER_PRESENTATION,
08637       .number.valid = AST_REDIRECTING_TO_NUMBER_VALID,
08638 
08639       .subaddress.str = AST_REDIRECTING_TO_SUBADDRESS,
08640       .subaddress.type = AST_REDIRECTING_TO_SUBADDRESS_TYPE,
08641       .subaddress.odd_even_indicator = AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN,
08642       .subaddress.valid = AST_REDIRECTING_TO_SUBADDRESS_VALID,
08643 
08644       .tag = AST_REDIRECTING_TO_TAG,
08645       .combined_presentation = AST_REDIRECTING_TO_ID_PRESENTATION,
08646    };
08647 
08648    /* Redirecting frame version */
08649    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08650       ast_log(LOG_WARNING, "No space left for redirecting frame version\n");
08651       return -1;
08652    }
08653    data[pos++] = AST_REDIRECTING_VERSION;
08654    data[pos++] = 1;
08655    data[pos++] = 2;/* Version 1 did not have a version ie */
08656 
08657    res = party_id_build_data(data + pos, datalen - pos, &redirecting->from,
08658       "redirecting-from", &from_ies, update ? &update->from : NULL);
08659    if (res < 0) {
08660       return -1;
08661    }
08662    pos += res;
08663 
08664    res = party_id_build_data(data + pos, datalen - pos, &redirecting->to,
08665       "redirecting-to", &to_ies, update ? &update->to : NULL);
08666    if (res < 0) {
08667       return -1;
08668    }
08669    pos += res;
08670 
08671    /* Redirecting reason */
08672    if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
08673       ast_log(LOG_WARNING, "No space left for redirecting reason\n");
08674       return -1;
08675    }
08676    data[pos++] = AST_REDIRECTING_REASON;
08677    data[pos++] = sizeof(value);
08678    value = htonl(redirecting->reason);
08679    memcpy(data + pos, &value, sizeof(value));
08680    pos += sizeof(value);
08681 
08682    /* Redirecting count */
08683    if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
08684       ast_log(LOG_WARNING, "No space left for redirecting count\n");
08685       return -1;
08686    }
08687    data[pos++] = AST_REDIRECTING_COUNT;
08688    data[pos++] = sizeof(value);
08689    value = htonl(redirecting->count);
08690    memcpy(data + pos, &value, sizeof(value));
08691    pos += sizeof(value);
08692 
08693    return pos;
08694 }

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

08697 {
08698    size_t pos;
08699    unsigned char ie_len;
08700    unsigned char ie_id;
08701    int32_t value;
08702    int frame_version = 1;
08703    int from_combined_presentation = 0;
08704    int got_from_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */
08705    int to_combined_presentation = 0;
08706    int got_to_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */
08707 
08708    for (pos = 0; pos < datalen; pos += ie_len) {
08709       if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) {
08710          ast_log(LOG_WARNING, "Invalid redirecting update\n");
08711          return -1;
08712       }
08713       ie_id = data[pos++];
08714       ie_len = data[pos++];
08715       if (datalen < pos + ie_len) {
08716          ast_log(LOG_WARNING, "Invalid redirecting update\n");
08717          return -1;
08718       }
08719 
08720       switch (ie_id) {
08721 /* Redirecting frame version */
08722       case AST_REDIRECTING_VERSION:
08723          if (ie_len != 1) {
08724             ast_log(LOG_WARNING, "Invalid redirecting frame version (%u)\n",
08725                (unsigned) ie_len);
08726             break;
08727          }
08728          frame_version = data[pos];
08729          break;
08730 /* Redirecting-from party id name */
08731       case AST_REDIRECTING_FROM_NAME:
08732          ast_free(redirecting->from.name.str);
08733          redirecting->from.name.str = ast_malloc(ie_len + 1);
08734          if (redirecting->from.name.str) {
08735             memcpy(redirecting->from.name.str, data + pos, ie_len);
08736             redirecting->from.name.str[ie_len] = 0;
08737          }
08738          break;
08739       case AST_REDIRECTING_FROM_NAME_CHAR_SET:
08740          if (ie_len != 1) {
08741             ast_log(LOG_WARNING, "Invalid redirecting-from name char set (%u)\n",
08742                (unsigned) ie_len);
08743             break;
08744          }
08745          redirecting->from.name.char_set = data[pos];
08746          break;
08747       case AST_REDIRECTING_FROM_NAME_PRESENTATION:
08748          if (ie_len != 1) {
08749             ast_log(LOG_WARNING, "Invalid redirecting-from name presentation (%u)\n",
08750                (unsigned) ie_len);
08751             break;
08752          }
08753          redirecting->from.name.presentation = data[pos];
08754          break;
08755       case AST_REDIRECTING_FROM_NAME_VALID:
08756          if (ie_len != 1) {
08757             ast_log(LOG_WARNING, "Invalid redirecting-from name valid (%u)\n",
08758                (unsigned) ie_len);
08759             break;
08760          }
08761          redirecting->from.name.valid = data[pos];
08762          break;
08763 /* Redirecting-from party id number */
08764       case AST_REDIRECTING_FROM_NUMBER:
08765          ast_free(redirecting->from.number.str);
08766          redirecting->from.number.str = ast_malloc(ie_len + 1);
08767          if (redirecting->from.number.str) {
08768             memcpy(redirecting->from.number.str, data + pos, ie_len);
08769             redirecting->from.number.str[ie_len] = 0;
08770          }
08771          break;
08772       case AST_REDIRECTING_FROM_NUMBER_PLAN:
08773          if (ie_len != 1) {
08774             ast_log(LOG_WARNING, "Invalid redirecting-from numbering plan (%u)\n",
08775                (unsigned) ie_len);
08776             break;
08777          }
08778          redirecting->from.number.plan = data[pos];
08779          break;
08780       case AST_REDIRECTING_FROM_NUMBER_PRESENTATION:
08781          if (ie_len != 1) {
08782             ast_log(LOG_WARNING, "Invalid redirecting-from number presentation (%u)\n",
08783                (unsigned) ie_len);
08784             break;
08785          }
08786          redirecting->from.number.presentation = data[pos];
08787          break;
08788       case AST_REDIRECTING_FROM_NUMBER_VALID:
08789          if (ie_len != 1) {
08790             ast_log(LOG_WARNING, "Invalid redirecting-from number valid (%u)\n",
08791                (unsigned) ie_len);
08792             break;
08793          }
08794          redirecting->from.number.valid = data[pos];
08795          break;
08796 /* Redirecting-from party id combined presentation */
08797       case AST_REDIRECTING_FROM_ID_PRESENTATION:
08798          if (ie_len != 1) {
08799             ast_log(LOG_WARNING, "Invalid redirecting-from combined presentation (%u)\n",
08800                (unsigned) ie_len);
08801             break;
08802          }
08803          from_combined_presentation = data[pos];
08804          got_from_combined_presentation = 1;
08805          break;
08806 /* Redirecting-from party id subaddress */
08807       case AST_REDIRECTING_FROM_SUBADDRESS:
08808          ast_free(redirecting->from.subaddress.str);
08809          redirecting->from.subaddress.str = ast_malloc(ie_len + 1);
08810          if (redirecting->from.subaddress.str) {
08811             memcpy(redirecting->from.subaddress.str, data + pos, ie_len);
08812             redirecting->from.subaddress.str[ie_len] = 0;
08813          }
08814          break;
08815       case AST_REDIRECTING_FROM_SUBADDRESS_TYPE:
08816          if (ie_len != 1) {
08817             ast_log(LOG_WARNING, "Invalid redirecting-from type of subaddress (%u)\n",
08818                (unsigned) ie_len);
08819             break;
08820          }
08821          redirecting->from.subaddress.type = data[pos];
08822          break;
08823       case AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN:
08824          if (ie_len != 1) {
08825             ast_log(LOG_WARNING,
08826                "Invalid redirecting-from subaddress odd-even indicator (%u)\n",
08827                (unsigned) ie_len);
08828             break;
08829          }
08830          redirecting->from.subaddress.odd_even_indicator = data[pos];
08831          break;
08832       case AST_REDIRECTING_FROM_SUBADDRESS_VALID:
08833          if (ie_len != 1) {
08834             ast_log(LOG_WARNING, "Invalid redirecting-from subaddress valid (%u)\n",
08835                (unsigned) ie_len);
08836             break;
08837          }
08838          redirecting->from.subaddress.valid = data[pos];
08839          break;
08840 /* Redirecting-from party id tag */
08841       case AST_REDIRECTING_FROM_TAG:
08842          ast_free(redirecting->from.tag);
08843          redirecting->from.tag = ast_malloc(ie_len + 1);
08844          if (redirecting->from.tag) {
08845             memcpy(redirecting->from.tag, data + pos, ie_len);
08846             redirecting->from.tag[ie_len] = 0;
08847          }
08848          break;
08849 /* Redirecting-to party id name */
08850       case AST_REDIRECTING_TO_NAME:
08851          ast_free(redirecting->to.name.str);
08852          redirecting->to.name.str = ast_malloc(ie_len + 1);
08853          if (redirecting->to.name.str) {
08854             memcpy(redirecting->to.name.str, data + pos, ie_len);
08855             redirecting->to.name.str[ie_len] = 0;
08856          }
08857          break;
08858       case AST_REDIRECTING_TO_NAME_CHAR_SET:
08859          if (ie_len != 1) {
08860             ast_log(LOG_WARNING, "Invalid redirecting-to name char set (%u)\n",
08861                (unsigned) ie_len);
08862             break;
08863          }
08864          redirecting->to.name.char_set = data[pos];
08865          break;
08866       case AST_REDIRECTING_TO_NAME_PRESENTATION:
08867          if (ie_len != 1) {
08868             ast_log(LOG_WARNING, "Invalid redirecting-to name presentation (%u)\n",
08869                (unsigned) ie_len);
08870             break;
08871          }
08872          redirecting->to.name.presentation = data[pos];
08873          break;
08874       case AST_REDIRECTING_TO_NAME_VALID:
08875          if (ie_len != 1) {
08876             ast_log(LOG_WARNING, "Invalid redirecting-to name valid (%u)\n",
08877                (unsigned) ie_len);
08878             break;
08879          }
08880          redirecting->to.name.valid = data[pos];
08881          break;
08882 /* Redirecting-to party id number */
08883       case AST_REDIRECTING_TO_NUMBER:
08884          ast_free(redirecting->to.number.str);
08885          redirecting->to.number.str = ast_malloc(ie_len + 1);
08886          if (redirecting->to.number.str) {
08887             memcpy(redirecting->to.number.str, data + pos, ie_len);
08888             redirecting->to.number.str[ie_len] = 0;
08889          }
08890          break;
08891       case AST_REDIRECTING_TO_NUMBER_PLAN:
08892          if (ie_len != 1) {
08893             ast_log(LOG_WARNING, "Invalid redirecting-to numbering plan (%u)\n",
08894                (unsigned) ie_len);
08895             break;
08896          }
08897          redirecting->to.number.plan = data[pos];
08898          break;
08899       case AST_REDIRECTING_TO_NUMBER_PRESENTATION:
08900          if (ie_len != 1) {
08901             ast_log(LOG_WARNING, "Invalid redirecting-to number presentation (%u)\n",
08902                (unsigned) ie_len);
08903             break;
08904          }
08905          redirecting->to.number.presentation = data[pos];
08906          break;
08907       case AST_REDIRECTING_TO_NUMBER_VALID:
08908          if (ie_len != 1) {
08909             ast_log(LOG_WARNING, "Invalid redirecting-to number valid (%u)\n",
08910                (unsigned) ie_len);
08911             break;
08912          }
08913          redirecting->to.number.valid = data[pos];
08914          break;
08915 /* Redirecting-to party id combined presentation */
08916       case AST_REDIRECTING_TO_ID_PRESENTATION:
08917          if (ie_len != 1) {
08918             ast_log(LOG_WARNING, "Invalid redirecting-to combined presentation (%u)\n",
08919                (unsigned) ie_len);
08920             break;
08921          }
08922          to_combined_presentation = data[pos];
08923          got_to_combined_presentation = 1;
08924          break;
08925 /* Redirecting-to party id subaddress */
08926       case AST_REDIRECTING_TO_SUBADDRESS:
08927          ast_free(redirecting->to.subaddress.str);
08928          redirecting->to.subaddress.str = ast_malloc(ie_len + 1);
08929          if (redirecting->to.subaddress.str) {
08930             memcpy(redirecting->to.subaddress.str, data + pos, ie_len);
08931             redirecting->to.subaddress.str[ie_len] = 0;
08932          }
08933          break;
08934       case AST_REDIRECTING_TO_SUBADDRESS_TYPE:
08935          if (ie_len != 1) {
08936             ast_log(LOG_WARNING, "Invalid redirecting-to type of subaddress (%u)\n",
08937                (unsigned) ie_len);
08938             break;
08939          }
08940          redirecting->to.subaddress.type = data[pos];
08941          break;
08942       case AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN:
08943          if (ie_len != 1) {
08944             ast_log(LOG_WARNING,
08945                "Invalid redirecting-to subaddress odd-even indicator (%u)\n",
08946                (unsigned) ie_len);
08947             break;
08948          }
08949          redirecting->to.subaddress.odd_even_indicator = data[pos];
08950          break;
08951       case AST_REDIRECTING_TO_SUBADDRESS_VALID:
08952          if (ie_len != 1) {
08953             ast_log(LOG_WARNING, "Invalid redirecting-to subaddress valid (%u)\n",
08954                (unsigned) ie_len);
08955             break;
08956          }
08957          redirecting->to.subaddress.valid = data[pos];
08958          break;
08959 /* Redirecting-to party id tag */
08960       case AST_REDIRECTING_TO_TAG:
08961          ast_free(redirecting->to.tag);
08962          redirecting->to.tag = ast_malloc(ie_len + 1);
08963          if (redirecting->to.tag) {
08964             memcpy(redirecting->to.tag, data + pos, ie_len);
08965             redirecting->to.tag[ie_len] = 0;
08966          }
08967          break;
08968 /* Redirecting reason */
08969       case AST_REDIRECTING_REASON:
08970          if (ie_len != sizeof(value)) {
08971             ast_log(LOG_WARNING, "Invalid redirecting reason (%u)\n",
08972                (unsigned) ie_len);
08973             break;
08974          }
08975          memcpy(&value, data + pos, sizeof(value));
08976          redirecting->reason = ntohl(value);
08977          break;
08978 /* Redirecting count */
08979       case AST_REDIRECTING_COUNT:
08980          if (ie_len != sizeof(value)) {
08981             ast_log(LOG_WARNING, "Invalid redirecting count (%u)\n",
08982                (unsigned) ie_len);
08983             break;
08984          }
08985          memcpy(&value, data + pos, sizeof(value));
08986          redirecting->count = ntohl(value);
08987          break;
08988 /* Redirecting unknown element */
08989       default:
08990          ast_log(LOG_DEBUG, "Unknown redirecting element: %u (%u)\n",
08991             (unsigned) ie_id, (unsigned) ie_len);
08992          break;
08993       }
08994    }
08995 
08996    switch (frame_version) {
08997    case 1:
08998       /*
08999        * The other end is an earlier version that we need to adjust
09000        * for compatibility.
09001        */
09002       redirecting->from.name.valid = 1;
09003       redirecting->from.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
09004       redirecting->from.number.valid = 1;
09005       if (got_from_combined_presentation) {
09006          redirecting->from.name.presentation = from_combined_presentation;
09007          redirecting->from.number.presentation = from_combined_presentation;
09008       }
09009 
09010       redirecting->to.name.valid = 1;
09011       redirecting->to.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
09012       redirecting->to.number.valid = 1;
09013       if (got_to_combined_presentation) {
09014          redirecting->to.name.presentation = to_combined_presentation;
09015          redirecting->to.number.presentation = to_combined_presentation;
09016       }
09017       break;
09018    case 2:
09019       /* The other end is at the same level as we are. */
09020       break;
09021    default:
09022       /*
09023        * The other end is newer than we are.
09024        * We need to assume that they are compatible with us.
09025        */
09026       ast_log(LOG_DEBUG, "Redirecting frame has newer version: %u\n",
09027          (unsigned) frame_version);
09028       break;
09029    }
09030 
09031    return 0;
09032 }

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

05356 {
05357    struct chanlist *chan;
05358    struct ast_channel *c;
05359    format_t capabilities;
05360    format_t fmt;
05361    int res;
05362    int foo;
05363    format_t videoformat = format & AST_FORMAT_VIDEO_MASK;
05364    format_t textformat = format & AST_FORMAT_TEXT_MASK;
05365 
05366    if (!cause)
05367       cause = &foo;
05368    *cause = AST_CAUSE_NOTDEFINED;
05369 
05370    if (AST_RWLIST_RDLOCK(&backends)) {
05371       ast_log(LOG_WARNING, "Unable to lock technology backend list\n");
05372       return NULL;
05373    }
05374 
05375    AST_RWLIST_TRAVERSE(&backends, chan, list) {
05376       if (strcasecmp(type, chan->tech->type))
05377          continue;
05378 
05379       capabilities = chan->tech->capabilities;
05380       fmt = format & AST_FORMAT_AUDIO_MASK;
05381       if (fmt) {
05382          /* We have audio - is it possible to connect the various calls to each other? 
05383             (Avoid this check for calls without audio, like text+video calls)
05384          */
05385          res = ast_translator_best_choice(&fmt, &capabilities);
05386          if (res < 0) {
05387             char tmp1[256], tmp2[256];
05388             ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %s) to %s\n", type,
05389                ast_getformatname_multiple(tmp1, sizeof(tmp1), chan->tech->capabilities),
05390                ast_getformatname_multiple(tmp2, sizeof(tmp2), format));
05391             *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05392             AST_RWLIST_UNLOCK(&backends);
05393             return NULL;
05394          }
05395       }
05396       AST_RWLIST_UNLOCK(&backends);
05397       if (!chan->tech->requester)
05398          return NULL;
05399 
05400       if (!(c = chan->tech->requester(type, capabilities | videoformat | textformat, requestor, data, cause)))
05401          return NULL;
05402 
05403       if (set_security_requirements(requestor, c)) {
05404          ast_log(LOG_WARNING, "Setting security requirements failed\n");
05405          c = ast_channel_release(c);
05406          *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05407          return NULL;
05408       }
05409 
05410       /* no need to generate a Newchannel event here; it is done in the channel_alloc call */
05411       return c;
05412    }
05413 
05414    ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
05415    *cause = AST_CAUSE_NOSUCHDRIVER;
05416    AST_RWLIST_UNLOCK(&backends);
05417 
05418    return NULL;
05419 }

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

References __ast_request_and_dial().

Referenced by ast_pbx_outgoing_exten(), and generic_recall().

05311 {
05312    return __ast_request_and_dial(type, format, requestor, data, timeout, outstate, cidnum, cidname, NULL);
05313 }

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

01823 {
01824    return ast_safe_sleep_conditional(chan, ms, NULL, NULL);
01825 }

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

01756 {
01757    struct ast_frame *f;
01758    struct ast_silence_generator *silgen = NULL;
01759    int res = 0;
01760    AST_LIST_HEAD_NOLOCK(, ast_frame) deferred_frames;
01761 
01762    AST_LIST_HEAD_INIT_NOLOCK(&deferred_frames);
01763 
01764    /* If no other generator is present, start silencegen while waiting */
01765    if (ast_opt_transmit_silence && !chan->generatordata) {
01766       silgen = ast_channel_start_silence_generator(chan);
01767    }
01768 
01769    while (ms > 0) {
01770       struct ast_frame *dup_f = NULL;
01771       if (cond && ((*cond)(data) == 0)) {
01772          break;
01773       }
01774       ms = ast_waitfor(chan, ms);
01775       if (ms < 0) {
01776          res = -1;
01777          break;
01778       }
01779       if (ms > 0) {
01780          f = ast_read(chan);
01781          if (!f) {
01782             res = -1;
01783             break;
01784          }
01785 
01786          if (!ast_is_deferrable_frame(f)) {
01787             ast_frfree(f);
01788             continue;
01789          }
01790          
01791          if ((dup_f = ast_frisolate(f))) {
01792             if (dup_f != f) {
01793                ast_frfree(f);
01794             }
01795             AST_LIST_INSERT_HEAD(&deferred_frames, dup_f, frame_list);
01796          }
01797       }
01798    }
01799 
01800    /* stop silgen if present */
01801    if (silgen) {
01802       ast_channel_stop_silence_generator(chan, silgen);
01803    }
01804 
01805    /* We need to free all the deferred frames, but we only need to
01806     * queue the deferred frames if there was no error and no
01807     * hangup was received
01808     */
01809    ast_channel_lock(chan);
01810    while ((f = AST_LIST_REMOVE_HEAD(&deferred_frames, frame_list))) {
01811       if (!res) {
01812          ast_queue_frame_head(chan, f);
01813       }
01814       ast_frfree(f);
01815    }
01816    ast_channel_unlock(chan);
01817 
01818    return res;
01819 }

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

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

07865 {
07866    return ast_say_character_str_full(chan, str, ints, lang, -1, -1);
07867 }

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

07859 {
07860    return ast_say_digit_str_full(chan, str, ints, lang, -1, -1);
07861 }

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

07853 {
07854    return ast_say_digits_full(chan, num, ints, lang, -1, -1);
07855 }

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

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

07877 {
07878    char buf[256];
07879 
07880    snprintf(buf, sizeof(buf), "%d", num);
07881 
07882    return ast_say_digit_str_full(chan, buf, ints, lang, audiofd, ctrlfd);
07883 }

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

07847 {
07848    return ast_say_enumeration_full(chan, num, ints, language, options, -1, -1);
07849 }

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

07841 {
07842    return ast_say_number_full(chan, num, ints, language, options, -1, -1);
07843 }

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

Definition at line 7869 of file channel.c.

References ast_say_phonetic_str_full.

Referenced by pbx_builtin_sayphonetic().

07871 {
07872    return ast_say_phonetic_str_full(chan, str, ints, lang, -1, -1);
07873 }

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

04512 {
04513    if (chan->tech->send_digit_begin) {
04514       ast_senddigit_begin(chan, digit);
04515       ast_safe_sleep(chan, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION));
04516    }
04517    
04518    return ast_senddigit_end(chan, digit, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION));
04519 }

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

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

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

04499 {
04500    int res = -1;
04501 
04502    if (chan->tech->send_digit_end)
04503       res = chan->tech->send_digit_end(chan, digit, duration);
04504 
04505    if (res && chan->generator)
04506       ast_playtones_stop(chan);
04507    
04508    return 0;
04509 }

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

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

04441 {
04442    int res = 0;
04443    /* Stop if we're a zombie or need a soft hangup */
04444    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
04445       return -1;
04446    CHECK_BLOCKING(chan);
04447    if (chan->tech->send_text)
04448       res = chan->tech->send_text(chan, text);
04449    ast_clear_flag(chan, AST_FLAG_BLOCKING);
04450    return res;
04451 }

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 6572 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(), ast_call_forward(), cb_events(), dial_exec_full(), do_forward(), findmeexec(), get_pai(), get_rpid(), handle_setcallerid(), mgcp_ss(), ring_entry(), rpt_exec(), skinny_newcall(), and socket_process().

06573 {
06574    ast_channel_lock(chan);
06575 
06576    if (cid_num) {
06577       chan->caller.id.number.valid = 1;
06578       ast_free(chan->caller.id.number.str);
06579       chan->caller.id.number.str = ast_strdup(cid_num);
06580    }
06581    if (cid_name) {
06582       chan->caller.id.name.valid = 1;
06583       ast_free(chan->caller.id.name.str);
06584       chan->caller.id.name.str = ast_strdup(cid_name);
06585    }
06586    if (cid_ani) {
06587       chan->caller.ani.number.valid = 1;
06588       ast_free(chan->caller.ani.number.str);
06589       chan->caller.ani.number.str = ast_strdup(cid_ani);
06590    }
06591    if (chan->cdr) {
06592       ast_cdr_setcid(chan->cdr, chan);
06593    }
06594 
06595    report_new_callerid(chan);
06596 
06597    ast_channel_unlock(chan);
06598 }

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

02640 {
02641    struct ast_channel *bridge;
02642 
02643    ast_channel_lock(chan);
02644    if (force || ast_strlen_zero(chan->hangupsource)) {
02645       ast_string_field_set(chan, hangupsource, source);
02646    }
02647    bridge = ast_bridged_channel(chan);
02648    ast_channel_unlock(chan);
02649 
02650    if (bridge && (force || ast_strlen_zero(bridge->hangupsource))) {
02651       ast_channel_lock(bridge);
02652       ast_string_field_set(chan, hangupsource, source);
02653       ast_channel_unlock(bridge);
02654    }
02655 }

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

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

06055 {
06056    if (!ast_strlen_zero(chan1->accountcode) && ast_strlen_zero(chan2->peeraccount)) {
06057       ast_log(LOG_DEBUG, "setting peeraccount to %s for %s from data on channel %s\n",
06058             chan1->accountcode, chan2->name, chan1->name);
06059       ast_string_field_set(chan2, peeraccount, chan1->accountcode);
06060    }
06061    if (!ast_strlen_zero(chan2->accountcode) && ast_strlen_zero(chan1->peeraccount)) {
06062       ast_log(LOG_DEBUG, "setting peeraccount to %s for %s from data on channel %s\n",
06063             chan2->accountcode, chan1->name, chan2->name);
06064       ast_string_field_set(chan1, peeraccount, chan2->accountcode);
06065    }
06066    if (!ast_strlen_zero(chan1->peeraccount) && ast_strlen_zero(chan2->accountcode)) {
06067       ast_log(LOG_DEBUG, "setting accountcode to %s for %s from data on channel %s\n",
06068             chan1->peeraccount, chan2->name, chan1->name);
06069       ast_string_field_set(chan2, accountcode, chan1->peeraccount);
06070    }
06071    if (!ast_strlen_zero(chan2->peeraccount) && ast_strlen_zero(chan1->accountcode)) {
06072       ast_log(LOG_DEBUG, "setting accountcode to %s for %s from data on channel %s\n",
06073             chan2->peeraccount, chan1->name, chan2->name);
06074       ast_string_field_set(chan1, accountcode, chan2->peeraccount);
06075    }
06076    if (0 != strcmp(chan1->accountcode, chan2->peeraccount)) {
06077       ast_log(LOG_DEBUG, "changing peeraccount from %s to %s on %s to match channel %s\n",
06078             chan2->peeraccount, chan1->peeraccount, chan2->name, chan1->name);
06079       ast_string_field_set(chan2, peeraccount, chan1->accountcode);
06080    }
06081    if (0 != strcmp(chan2->accountcode, chan1->peeraccount)) {
06082       ast_log(LOG_DEBUG, "changing peeraccount from %s to %s on %s to match channel %s\n",
06083             chan1->peeraccount, chan2->peeraccount, chan1->name, chan2->name);
06084       ast_string_field_set(chan1, peeraccount, chan2->accountcode);
06085    }
06086 }

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

05023 {
05024    return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat,
05025            &chan->readtrans, 0);
05026 }

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

07727 {
07728    struct ast_variable *cur;
07729 
07730    for (cur = vars; cur; cur = cur->next)
07731       pbx_builtin_setvar_helper(chan, cur->name, cur->value);  
07732 }

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

05029 {
05030    return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat,
05031            &chan->writetrans, 1);
05032 }

int ast_setstate ( struct ast_channel chan,
enum ast_channel_state  state 
)

Change the state of a channel.

Definition at line 6637 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, EVENT_FLAG_CALL, 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().

06638 {
06639    int oldstate = chan->_state;
06640    char name[AST_CHANNEL_NAME], *dashptr;
06641 
06642    if (oldstate == state)
06643       return 0;
06644 
06645    ast_copy_string(name, chan->name, sizeof(name));
06646    if ((dashptr = strrchr(name, '-'))) {
06647       *dashptr = '\0';
06648    }
06649 
06650    chan->_state = state;
06651 
06652    /* We have to pass AST_DEVICE_UNKNOWN here because it is entirely possible that the channel driver
06653     * for this channel is using the callback method for device state. If we pass in an actual state here
06654     * we override what they are saying the state is and things go amuck. */
06655    ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, name);
06656 
06657    /* setstate used to conditionally report Newchannel; this is no more */
06658    ast_manager_event(chan, EVENT_FLAG_CALL, "Newstate",
06659       "Channel: %s\r\n"
06660       "ChannelState: %d\r\n"
06661       "ChannelStateDesc: %s\r\n"
06662       "CallerIDNum: %s\r\n"
06663       "CallerIDName: %s\r\n"
06664       "Uniqueid: %s\r\n",
06665       chan->name, chan->_state, ast_state2str(chan->_state),
06666       S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
06667       S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""),
06668       chan->uniqueid);
06669 
06670    return 0;
06671 }

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 3381 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_closestream(), ast_deactivate_generator(), ast_read_generator_actions(), ast_readaudio_callback(), and filestream_destructor().

03382 {
03383    int res;
03384    unsigned int real_rate = rate, max_rate;
03385 
03386    ast_channel_lock(c);
03387 
03388    if (c->timingfd == -1) {
03389       ast_channel_unlock(c);
03390       return -1;
03391    }
03392 
03393    if (!func) {
03394       rate = 0;
03395       data = NULL;
03396    }
03397 
03398    if (rate && rate > (max_rate = ast_timer_get_max_rate(c->timer))) {
03399       real_rate = max_rate;
03400    }
03401 
03402    ast_debug(1, "Scheduling timer at (%u requested / %u actual) timer ticks per second\n", rate, real_rate);
03403 
03404    res = ast_timer_set_rate(c->timer, real_rate);
03405 
03406    c->timingfunc = func;
03407    c->timingdata = data;
03408 
03409    ast_channel_unlock(c);
03410 
03411    return res;
03412 }

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

Referenced by handle_request_options().

00796 {
00797    return shutting_down;
00798 }

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

02617 {
02618    int res;
02619 
02620    ast_channel_lock(chan);
02621    res = ast_softhangup_nolock(chan, cause);
02622    ast_channel_unlock(chan);
02623 
02624    return res;
02625 }

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

02604 {
02605    ast_debug(1, "Soft-Hanging up channel '%s'\n", chan->name);
02606    /* Inform channel driver that we need to be hung up, if it cares */
02607    chan->_softhangup |= cause;
02608    ast_queue_frame(chan, &ast_null_frame);
02609    /* Interrupt any poll call or such */
02610    if (ast_test_flag(chan, AST_FLAG_BLOCKING))
02611       pthread_kill(chan->blocker, SIGURG);
02612    return 0;
02613 }

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

00938 {
00939    char *buf;
00940 
00941    switch (state) {
00942    case AST_STATE_DOWN:
00943       return "Down";
00944    case AST_STATE_RESERVED:
00945       return "Rsrvd";
00946    case AST_STATE_OFFHOOK:
00947       return "OffHook";
00948    case AST_STATE_DIALING:
00949       return "Dialing";
00950    case AST_STATE_RING:
00951       return "Ring";
00952    case AST_STATE_RINGING:
00953       return "Ringing";
00954    case AST_STATE_UP:
00955       return "Up";
00956    case AST_STATE_BUSY:
00957       return "Busy";
00958    case AST_STATE_DIALING_OFFHOOK:
00959       return "Dialing Offhook";
00960    case AST_STATE_PRERING:
00961       return "Pre-ring";
00962    default:
00963       if (!(buf = ast_threadstorage_get(&state2str_threadbuf, STATE2STR_BUFSIZE)))
00964          return "Unknown";
00965       snprintf(buf, STATE2STR_BUFSIZE, "Unknown (%d)", state);
00966       return buf;
00967    }
00968 }

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

References ARRAY_LEN, and causes.

Referenced by pbx_builtin_hangup().

00924 {
00925    int x;
00926 
00927    for (x = 0; x < ARRAY_LEN(causes); x++)
00928       if (!strncasecmp(causes[x].name, name, strlen(causes[x].name)))
00929          return causes[x].cause;
00930 
00931    return -1;
00932 }

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

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

Referenced by zapateller_exec().

07447 {
07448    int res;
07449 
07450    if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
07451       return res;
07452 
07453    /* Give us some wiggle room */
07454    while (chan->generatordata && ast_waitfor(chan, 100) >= 0) {
07455       struct ast_frame *f = ast_read(chan);
07456       if (f)
07457          ast_frfree(f);
07458       else
07459          return -1;
07460    }
07461    return 0;
07462 }

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

Start a tone going

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

07429 {
07430    struct tonepair_def d = { 0, };
07431 
07432    d.freq1 = freq1;
07433    d.freq2 = freq2;
07434    d.duration = duration;
07435    d.vol = (vol < 1) ? 8192 : vol; /* force invalid to 8192 */
07436    if (ast_activate_generator(chan, &tonepair, &d))
07437       return -1;
07438    return 0;
07439 }

void ast_tonepair_stop ( struct ast_channel chan  ) 

Stop a tone from playing

Definition at line 7441 of file channel.c.

References ast_deactivate_generator().

Referenced by sendnoise().

07442 {
07443    ast_deactivate_generator(chan);
07444 }

int ast_transfer ( struct ast_channel chan,
char *  dest 
)

Transfer a channel (if supported).

Called by:

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

05449 {
05450    int res = -1;
05451 
05452    /* Stop if we're a zombie or need a soft hangup */
05453    ast_channel_lock(chan);
05454    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
05455       if (chan->tech->transfer) {
05456          res = chan->tech->transfer(chan, dest);
05457          if (!res)
05458             res = 1;
05459       } else
05460          res = 0;
05461    }
05462    ast_channel_unlock(chan);
05463 
05464    if (res <= 0) {
05465       return res;
05466    }
05467 
05468    for (;;) {
05469       struct ast_frame *fr;
05470 
05471       res = ast_waitfor(chan, -1);
05472 
05473       if (res < 0 || !(fr = ast_read(chan))) {
05474          res = -1;
05475          break;
05476       }
05477 
05478       if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_TRANSFER) {
05479          enum ast_control_transfer *message = fr->data.ptr;
05480 
05481          if (*message == AST_TRANSFER_SUCCESS) {
05482             res = 1;
05483          } else {
05484             res = -1;
05485          }
05486 
05487          ast_frfree(fr);
05488          break;
05489       }
05490 
05491       ast_frfree(fr);
05492    }
05493 
05494    return res;
05495 }

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

00972 {
00973    switch (transfercapability) {
00974    case AST_TRANS_CAP_SPEECH:
00975       return "SPEECH";
00976    case AST_TRANS_CAP_DIGITAL:
00977       return "DIGITAL";
00978    case AST_TRANS_CAP_RESTRICTED_DIGITAL:
00979       return "RESTRICTED_DIGITAL";
00980    case AST_TRANS_CAP_3_1K_AUDIO:
00981       return "3K1AUDIO";
00982    case AST_TRANS_CAP_DIGITAL_W_TONES:
00983       return "DIGITAL_W_TONES";
00984    case AST_TRANS_CAP_VIDEO:
00985       return "VIDEO";
00986    default:
00987       return "UNKNOWN";
00988    }
00989 }

void ast_uninstall_music_functions ( void   ) 

Definition at line 7509 of file channel.c.

References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.

Referenced by unload_module().

07510 {
07511    ast_moh_start_ptr = NULL;
07512    ast_moh_stop_ptr = NULL;
07513    ast_moh_cleanup_ptr = NULL;
07514 }

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

03366 {
03367    int oldms = ms;   /* -1 if no timeout */
03368 
03369    ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms);
03370    if ((ms < 0) && (oldms < 0))
03371       ms = 0;
03372    return ms;
03373 }

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

03361 {
03362    return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
03363 }

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

References ast_waitfor_nandfds().

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

03002 {
03003    int winner = -1;
03004    ast_waitfor_nandfds(NULL, 0, fds, n, exception, &winner, ms);
03005    return winner;
03006 }

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

03016 {
03017    struct timeval start = { 0 , 0 };
03018    struct pollfd *pfds = NULL;
03019    int res;
03020    long rms;
03021    int x, y, max;
03022    int sz;
03023    struct timeval now = { 0, 0 };
03024    struct timeval whentohangup = { 0, 0 }, diff;
03025    struct ast_channel *winner = NULL;
03026    struct fdmap {
03027       int chan;
03028       int fdno;
03029    } *fdmap = NULL;
03030 
03031    if ((sz = n * AST_MAX_FDS + nfds)) {
03032       pfds = alloca(sizeof(*pfds) * sz);
03033       fdmap = alloca(sizeof(*fdmap) * sz);
03034    }
03035 
03036    if (outfd)
03037       *outfd = -99999;
03038    if (exception)
03039       *exception = 0;
03040    
03041    /* Perform any pending masquerades */
03042    for (x = 0; x < n; x++) {
03043       if (c[x]->masq && ast_do_masquerade(c[x])) {
03044          ast_log(LOG_WARNING, "Masquerade failed\n");
03045          *ms = -1;
03046          return NULL;
03047       }
03048 
03049       ast_channel_lock(c[x]);
03050       if (!ast_tvzero(c[x]->whentohangup)) {
03051          if (ast_tvzero(whentohangup))
03052             now = ast_tvnow();
03053          diff = ast_tvsub(c[x]->whentohangup, now);
03054          if (diff.tv_sec < 0 || ast_tvzero(diff)) {
03055             /* Should already be hungup */
03056             c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03057             ast_channel_unlock(c[x]);
03058             return c[x];
03059          }
03060          if (ast_tvzero(whentohangup) || ast_tvcmp(diff, whentohangup) < 0)
03061             whentohangup = diff;
03062       }
03063       ast_channel_unlock(c[x]);
03064    }
03065    /* Wait full interval */
03066    rms = *ms;
03067    /* INT_MAX, not LONG_MAX, because it matters on 64-bit */
03068    if (!ast_tvzero(whentohangup) && whentohangup.tv_sec < INT_MAX / 1000) {
03069       rms = whentohangup.tv_sec * 1000 + whentohangup.tv_usec / 1000;              /* timeout in milliseconds */
03070       if (*ms >= 0 && *ms < rms) {                                                 /* original *ms still smaller */
03071          rms =  *ms;
03072       }
03073    } else if (!ast_tvzero(whentohangup) && rms < 0) {
03074       /* Tiny corner case... call would need to last >24 days */
03075       rms = INT_MAX;
03076    }
03077    /*
03078     * Build the pollfd array, putting the channels' fds first,
03079     * followed by individual fds. Order is important because
03080     * individual fd's must have priority over channel fds.
03081     */
03082    max = 0;
03083    for (x = 0; x < n; x++) {
03084       for (y = 0; y < AST_MAX_FDS; y++) {
03085          fdmap[max].fdno = y;  /* fd y is linked to this pfds */
03086          fdmap[max].chan = x;  /* channel x is linked to this pfds */
03087          max += ast_add_fd(&pfds[max], c[x]->fds[y]);
03088       }
03089       CHECK_BLOCKING(c[x]);
03090    }
03091    /* Add the individual fds */
03092    for (x = 0; x < nfds; x++) {
03093       fdmap[max].chan = -1;
03094       max += ast_add_fd(&pfds[max], fds[x]);
03095    }
03096 
03097    if (*ms > 0)
03098       start = ast_tvnow();
03099    
03100    if (sizeof(int) == 4) { /* XXX fix timeout > 600000 on linux x86-32 */
03101       do {
03102          int kbrms = rms;
03103          if (kbrms > 600000)
03104             kbrms = 600000;
03105          res = ast_poll(pfds, max, kbrms);
03106          if (!res)
03107             rms -= kbrms;
03108       } while (!res && (rms > 0));
03109    } else {
03110       res = ast_poll(pfds, max, rms);
03111    }
03112    for (x = 0; x < n; x++)
03113       ast_clear_flag(c[x], AST_FLAG_BLOCKING);
03114    if (res < 0) { /* Simulate a timeout if we were interrupted */
03115       if (errno != EINTR)
03116          *ms = -1;
03117       return NULL;
03118    }
03119    if (!ast_tvzero(whentohangup)) {   /* if we have a timeout, check who expired */
03120       now = ast_tvnow();
03121       for (x = 0; x < n; x++) {
03122          if (!ast_tvzero(c[x]->whentohangup) && ast_tvcmp(c[x]->whentohangup, now) <= 0) {
03123             c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03124             if (winner == NULL)
03125                winner = c[x];
03126          }
03127       }
03128    }
03129    if (res == 0) { /* no fd ready, reset timeout and done */
03130       *ms = 0; /* XXX use 0 since we may not have an exact timeout. */
03131       return winner;
03132    }
03133    /*
03134     * Then check if any channel or fd has a pending event.
03135     * Remember to check channels first and fds last, as they
03136     * must have priority on setting 'winner'
03137     */
03138    for (x = 0; x < max; x++) {
03139       res = pfds[x].revents;
03140       if (res == 0)
03141          continue;
03142       if (fdmap[x].chan >= 0) {  /* this is a channel */
03143          winner = c[fdmap[x].chan]; /* override previous winners */
03144          if (res & POLLPRI)
03145             ast_set_flag(winner, AST_FLAG_EXCEPTION);
03146          else
03147             ast_clear_flag(winner, AST_FLAG_EXCEPTION);
03148          winner->fdno = fdmap[x].fdno;
03149       } else {       /* this is an fd */
03150          if (outfd)
03151             *outfd = pfds[x].fd;
03152          if (exception)
03153             *exception = (res & POLLPRI) ? -1 : 0;
03154          winner = NULL;
03155       }
03156    }
03157    if (*ms > 0) {
03158       *ms -= ast_tvdiff_ms(ast_tvnow(), start);
03159       if (*ms < 0)
03160          *ms = 0;
03161    }
03162    return winner;
03163 }

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

03377 {
03378    return ast_waitfordigit_full(c, ms, -1, -1);
03379 }

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

03415 {
03416    /* Stop if we're a zombie or need a soft hangup */
03417    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
03418       return -1;
03419 
03420    /* Only look for the end of DTMF, don't bother with the beginning and don't emulate things */
03421    ast_set_flag(c, AST_FLAG_END_DTMF_ONLY);
03422 
03423    /* Wait for a digit, no more than ms milliseconds total. */
03424    
03425    while (ms) {
03426       struct ast_channel *rchan;
03427       int outfd=-1;
03428 
03429       errno = 0;
03430       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
03431       
03432       if (!rchan && outfd < 0 && ms) {
03433          if (errno == 0 || errno == EINTR)
03434             continue;
03435          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
03436          ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03437          return -1;
03438       } else if (outfd > -1) {
03439          /* The FD we were watching has something waiting */
03440          ast_log(LOG_WARNING, "The FD we were waiting for has something waiting. Waitfordigit returning numeric 1\n");
03441          ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03442          return 1;
03443       } else if (rchan) {
03444          int res;
03445          struct ast_frame *f = ast_read(c);
03446          if (!f)
03447             return -1;
03448 
03449          switch (f->frametype) {
03450          case AST_FRAME_DTMF_BEGIN:
03451             break;
03452          case AST_FRAME_DTMF_END:
03453             res = f->subclass.integer;
03454             ast_frfree(f);
03455             ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03456             return res;
03457          case AST_FRAME_CONTROL:
03458             switch (f->subclass.integer) {
03459             case AST_CONTROL_HANGUP:
03460                ast_frfree(f);
03461                ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03462                return -1;
03463             case AST_CONTROL_RINGING:
03464             case AST_CONTROL_ANSWER:
03465             case AST_CONTROL_SRCUPDATE:
03466             case AST_CONTROL_SRCCHANGE:
03467             case AST_CONTROL_CONNECTED_LINE:
03468             case AST_CONTROL_REDIRECTING:
03469             case -1:
03470                /* Unimportant */
03471                break;
03472             default:
03473                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass.integer);
03474                break;
03475             }
03476             break;
03477          case AST_FRAME_VOICE:
03478             /* Write audio if appropriate */
03479             if (audiofd > -1) {
03480                if (write(audiofd, f->data.ptr, f->datalen) < 0) {
03481                   ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
03482                }
03483             }
03484          default:
03485             /* Ignore */
03486             break;
03487          }
03488          ast_frfree(f);
03489       }
03490    }
03491 
03492    ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03493 
03494    return 0; /* Time is up */
03495 }

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 4653 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_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_LIST_NEXT, ast_log(), AST_MONITOR_RUNNING, ast_opt_generic_plc, ast_seekstream(), ast_senddigit_begin(), ast_senddigit_end(), 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, 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, and ast_channel::writetrans.

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

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

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

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

04539 {
04540    int res;
04541    if (!chan->tech->write_video)
04542       return 0;
04543    res = ast_write(chan, fr);
04544    if (!res)
04545       res = 1;
04546    return res;
04547 }

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

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

06990 {
06991    const char *s, *sound;
06992 
06993    /* See if we need to play an audio file to any side of the bridge */
06994 
06995    ast_channel_lock(c0);
06996    if ((s = pbx_builtin_getvar_helper(c0, "BRIDGE_PLAY_SOUND"))) {
06997       sound = ast_strdupa(s);
06998       ast_channel_unlock(c0);
06999       bridge_playfile(c0, c1, sound, 0);
07000       pbx_builtin_setvar_helper(c0, "BRIDGE_PLAY_SOUND", NULL);
07001    } else {
07002       ast_channel_unlock(c0);
07003    }
07004 
07005    ast_channel_lock(c1);
07006    if ((s = pbx_builtin_getvar_helper(c1, "BRIDGE_PLAY_SOUND"))) {
07007       sound = ast_strdupa(s);
07008       ast_channel_unlock(c1);
07009       bridge_playfile(c1, c0, sound, 0);
07010       pbx_builtin_setvar_helper(c1, "BRIDGE_PLAY_SOUND", NULL);
07011    } else {
07012       ast_channel_unlock(c1);
07013    }
07014 }

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

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

06684 {
06685    int min = 0, sec = 0, check;
06686 
06687    check = ast_autoservice_start(peer);
06688    if (check)
06689       return;
06690 
06691    if (remain > 0) {
06692       if (remain / 60 > 1) {
06693          min = remain / 60;
06694          sec = remain % 60;
06695       } else {
06696          sec = remain;
06697       }
06698    }
06699    
06700    if (!strcmp(sound,"timeleft")) { /* Queue support */
06701       ast_stream_and_wait(chan, "vm-youhave", "");
06702       if (min) {
06703          ast_say_number(chan, min, AST_DIGIT_ANY, chan->language, NULL);
06704          ast_stream_and_wait(chan, "queue-minutes", "");
06705       }
06706       if (sec) {
06707          ast_say_number(chan, sec, AST_DIGIT_ANY, chan->language, NULL);
06708          ast_stream_and_wait(chan, "queue-seconds", "");
06709       }
06710    } else {
06711       ast_stream_and_wait(chan, sound, "");
06712    }
06713 
06714    ast_autoservice_stop(peer);
06715 }

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

Referenced by __ast_read(), and ast_write().

03604 {
03605    int diff = sample_rate - seek_rate;
03606 
03607    if (diff > 0) {
03608       samples = samples / (float) (sample_rate / seek_rate);
03609    } else if (diff < 0) {
03610       samples = samples * (float) (seek_rate / sample_rate);
03611    }
03612 
03613    return samples;
03614 }

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

Definition at line 9139 of file channel.c.

References ast_cc_config_params_init, and ast_cc_copy_config_params().

09140 {
09141    const struct ast_cc_config_params *src = data;
09142    struct ast_cc_config_params *dest = ast_cc_config_params_init();
09143    if (!dest) {
09144       return NULL;
09145    }
09146    ast_cc_copy_config_params(dest, src);
09147    return dest;
09148 }

static void channel_cc_params_destroy ( void *  data  )  [static]

Definition at line 9150 of file channel.c.

References ast_cc_config_params_destroy().

09151 {
09152    struct ast_cc_config_params *cc_params = data;
09153    ast_cc_config_params_destroy(cc_params);
09154 }

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

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

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

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

01570 {
01571    struct ast_channel_iterator *i;
01572    struct ast_channel tmp_chan = {
01573       .name = name,
01574       /* This is sort of a hack.  Basically, we're using an arbitrary field
01575        * in ast_channel to pass the name_len for a prefix match.  If this
01576        * gets changed, then the compare callback must be changed, too. */
01577       .rings = name_len,
01578    };
01579 
01580    if (!(i = ast_calloc(1, sizeof(*i)))) {
01581       return NULL;
01582    }
01583 
01584    if (exten) {
01585       ast_copy_string(tmp_chan.exten, exten, sizeof(tmp_chan.exten));
01586    }
01587 
01588    if (context) {
01589       ast_copy_string(tmp_chan.context, context, sizeof(tmp_chan.context));
01590    }
01591 
01592    if (!(i->active_iterator = ao2_find(channels, &tmp_chan,
01593                    OBJ_MULTIPLE | ((!ast_strlen_zero(name) && (name_len == 0)) ? OBJ_POINTER : 0)))) {
01594           ast_free(i);
01595           return NULL;
01596    }
01597 
01598    return i;
01599 }

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

References CHANNEL_CLI_RELOAD, CHANNEL_MODULE_LOAD, and CHANNEL_MODULE_RELOAD.

07815 {
07816    switch (reason) {
07817    case CHANNEL_MODULE_LOAD:
07818       return "LOAD (Channel module load)";
07819 
07820    case CHANNEL_MODULE_RELOAD:
07821       return "RELOAD (Channel module reload)";
07822 
07823    case CHANNEL_CLI_RELOAD:
07824       return "CLIRELOAD (Channel module reload by CLI command)";
07825 
07826    default:
07827       return "MANAGERRELOAD (Channel module reload by manager)";
07828    }
07829 };

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

05916 {
05917    struct ast_var_t *current, *newvar;
05918    /* Append variables from clone channel into original channel */
05919    /* XXX Is this always correct?  We have to in order to keep MACROS working XXX */
05920    if (AST_LIST_FIRST(&clonechan->varshead))
05921       AST_LIST_APPEND_LIST(&original->varshead, &clonechan->varshead, entries);
05922 
05923    /* then, dup the varshead list into the clone */
05924    
05925    AST_LIST_TRAVERSE(&original->varshead, current, entries) {
05926       newvar = ast_var_assign(current->name, current->value);
05927       if (newvar)
05928          AST_LIST_INSERT_TAIL(&clonechan->varshead, newvar, entries);
05929    }
05930 }

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

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

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

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

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

07575 {
07576    struct ast_channel *c;
07577    struct ast_channel_iterator *iter = NULL;
07578    struct ast_data *data_channel;
07579 
07580    for (iter = ast_channel_iterator_all_new();
07581       iter && (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) {
07582       ast_channel_lock(c);
07583 
07584       data_channel = ast_data_add_node(root, "channel");
07585       if (!data_channel) {
07586          ast_channel_unlock(c);
07587          continue;
07588       }
07589 
07590       if (ast_channel_data_add_structure(data_channel, c, 1) < 0) {
07591          ast_log(LOG_ERROR, "Unable to add channel structure for channel: %s\n", c->name);
07592       }
07593 
07594       ast_channel_unlock(c);
07595 
07596       if (!ast_data_search_match(search, data_channel)) {
07597          ast_data_remove_node(root, data_channel);
07598       }
07599    }
07600    if (iter) {
07601       ast_channel_iterator_destroy(iter);
07602    }
07603 
07604    return 0;
07605 }

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

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

07613 {
07614    struct chanlist *cl;
07615    struct ast_data *data_type;
07616 
07617    AST_RWLIST_RDLOCK(&backends);
07618    AST_RWLIST_TRAVERSE(&backends, cl, list) {
07619       data_type = ast_data_add_node(data_root, "type");
07620       if (!data_type) {
07621          continue;
07622       }
07623       ast_data_add_str(data_type, "name", cl->tech->type);
07624       ast_data_add_str(data_type, "description", cl->tech->description);
07625       ast_data_add_bool(data_type, "devicestate", cl->tech->devicestate ? 1 : 0);
07626       ast_data_add_bool(data_type, "indications", cl->tech->indicate ? 1 : 0);
07627       ast_data_add_bool(data_type, "transfer", cl->tech->transfer ? 1 : 0);
07628       ast_data_add_bool(data_type, "send_digit_begin", cl->tech->send_digit_begin ? 1 : 0);
07629       ast_data_add_bool(data_type, "send_digit_end", cl->tech->send_digit_end ? 1 : 0);
07630       ast_data_add_bool(data_type, "call", cl->tech->call ? 1 : 0);
07631       ast_data_add_bool(data_type, "hangup", cl->tech->hangup ? 1 : 0);
07632       ast_data_add_bool(data_type, "answer", cl->tech->answer ? 1 : 0);
07633       ast_data_add_bool(data_type, "read", cl->tech->read ? 1 : 0);
07634       ast_data_add_bool(data_type, "write", cl->tech->write ? 1 : 0);
07635       ast_data_add_bool(data_type, "send_text", cl->tech->send_text ? 1 : 0);
07636       ast_data_add_bool(data_type, "send_image", cl->tech->send_image ? 1 : 0);
07637       ast_data_add_bool(data_type, "send_html", cl->tech->send_html ? 1 : 0);
07638       ast_data_add_bool(data_type, "exception", cl->tech->exception ? 1 : 0);
07639       ast_data_add_bool(data_type, "bridge", cl->tech->bridge ? 1 : 0);
07640       ast_data_add_bool(data_type, "early_bridge", cl->tech->early_bridge ? 1 : 0);
07641       ast_data_add_bool(data_type, "fixup", cl->tech->fixup ? 1 : 0);
07642       ast_data_add_bool(data_type, "setoption", cl->tech->setoption ? 1 : 0);
07643       ast_data_add_bool(data_type, "queryoption", cl->tech->queryoption ? 1 : 0);
07644       ast_data_add_bool(data_type, "write_video", cl->tech->write_video ? 1 : 0);
07645       ast_data_add_bool(data_type, "write_text", cl->tech->write_text ? 1 : 0);
07646       ast_data_add_bool(data_type, "bridged_channel", cl->tech->bridged_channel ? 1 : 0);
07647       ast_data_add_bool(data_type, "func_channel_read", cl->tech->func_channel_read ? 1 : 0);
07648       ast_data_add_bool(data_type, "func_channel_write", cl->tech->func_channel_write ? 1 : 0);
07649       ast_data_add_bool(data_type, "get_base_channel", cl->tech->get_base_channel ? 1 : 0);
07650       ast_data_add_bool(data_type, "set_base_channel", cl->tech->set_base_channel ? 1 : 0);
07651       ast_data_add_bool(data_type, "get_pvt_uniqueid", cl->tech->get_pvt_uniqueid ? 1 : 0);
07652       ast_data_add_bool(data_type, "cc_callback", cl->tech->cc_callback ? 1 : 0);
07653 
07654       ast_data_add_codecs(data_type, "capabilities", cl->tech->capabilities);
07655 
07656       if (!ast_data_search_match(search, data_type)) {
07657          ast_data_remove_node(data_root, data_type);
07658       }
07659    }
07660    AST_RWLIST_UNLOCK(&backends);
07661 
07662    return 0;
07663 }

static void free_translation ( struct ast_channel clonechan  )  [static]

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

02628 {
02629    if (clonechan->writetrans)
02630       ast_translator_free_path(clonechan->writetrans);
02631    if (clonechan->readtrans)
02632       ast_translator_free_path(clonechan->readtrans);
02633    clonechan->writetrans = NULL;
02634    clonechan->readtrans = NULL;
02635    clonechan->rawwriteformat = clonechan->nativeformats;
02636    clonechan->rawreadformat = clonechan->nativeformats;
02637 }

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

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

02947 {
02948    /* Called if generator doesn't have data */
02949    void *tmp;
02950    int res;
02951    int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = NULL;
02952    struct ast_channel *chan = (struct ast_channel *)data;
02953 
02954    ast_channel_lock(chan);
02955    tmp = chan->generatordata;
02956    chan->generatordata = NULL;
02957    if (chan->generator)
02958       generate = chan->generator->generate;
02959    ast_channel_unlock(chan);
02960 
02961    if (!tmp || !generate)
02962       return 0;
02963 
02964    res = generate(chan, tmp, 0, ast_format_rate(chan->writeformat & AST_FORMAT_AUDIO_MASK) / 50);
02965 
02966    chan->generatordata = tmp;
02967 
02968    if (res) {
02969       ast_debug(1, "Auto-deactivating generator\n");
02970       ast_deactivate_generator(chan);
02971    }
02972 
02973    return 0;
02974 }

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

Definition at line 5057 of file channel.c.

References AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CONTROL_BUSY, and AST_CONTROL_CONGESTION.

05058 {
05059    if (outstate) {
05060       /* compute error and return */
05061       if (cause == AST_CAUSE_BUSY)
05062          *outstate = AST_CONTROL_BUSY;
05063       else if (cause == AST_CAUSE_CONGESTION)
05064          *outstate = AST_CONTROL_CONGESTION;
05065       else
05066          *outstate = 0;
05067    }
05068 }

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

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

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

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

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

Definition at line 4164 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_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_VIDUPDATE, and AST_CONTROL_WINK.

Referenced by ast_indicate_data().

04165 {
04166    /* Don't include a default case here so that we get compiler warnings
04167     * when a new type is added. */
04168 
04169    switch (condition) {
04170    case AST_CONTROL_PROGRESS:
04171    case AST_CONTROL_PROCEEDING:
04172    case AST_CONTROL_VIDUPDATE:
04173    case AST_CONTROL_SRCUPDATE:
04174    case AST_CONTROL_SRCCHANGE:
04175    case AST_CONTROL_RADIO_KEY:
04176    case AST_CONTROL_RADIO_UNKEY:
04177    case AST_CONTROL_OPTION:
04178    case AST_CONTROL_WINK:
04179    case AST_CONTROL_FLASH:
04180    case AST_CONTROL_OFFHOOK:
04181    case AST_CONTROL_TAKEOFFHOOK:
04182    case AST_CONTROL_ANSWER:
04183    case AST_CONTROL_HANGUP:
04184    case AST_CONTROL_CONNECTED_LINE:
04185    case AST_CONTROL_REDIRECTING:
04186    case AST_CONTROL_TRANSFER:
04187    case AST_CONTROL_T38_PARAMETERS:
04188    case _XXX_AST_CONTROL_T38:
04189    case AST_CONTROL_CC:
04190    case AST_CONTROL_READ_ACTION:
04191    case AST_CONTROL_AOC:
04192    case AST_CONTROL_END_OF_Q:
04193       break;
04194 
04195    case AST_CONTROL_CONGESTION:
04196    case AST_CONTROL_BUSY:
04197    case AST_CONTROL_RINGING:
04198    case AST_CONTROL_RING:
04199    case AST_CONTROL_HOLD:
04200       /* You can hear these */
04201       return 1;
04202 
04203    case AST_CONTROL_UNHOLD:
04204       /* This is a special case.  You stop hearing this. */
04205       break;
04206    }
04207 
04208    return 0;
04209 }

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

06933 {
06934    struct ast_channel *chans[2] = { c0, c1 };
06935    ast_manager_event_multichan(EVENT_FLAG_CALL, "Bridge", 2, chans,
06936       "Bridgestate: %s\r\n"
06937       "Bridgetype: %s\r\n"
06938       "Channel1: %s\r\n"
06939       "Channel2: %s\r\n"
06940       "Uniqueid1: %s\r\n"
06941       "Uniqueid2: %s\r\n"
06942       "CallerID1: %s\r\n"
06943       "CallerID2: %s\r\n",
06944       onoff ? "Link" : "Unlink",
06945       type == 1 ? "core" : "native",
06946       c0->name, c1->name,
06947       c0->uniqueid, c1->uniqueid,
06948       S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, ""),
06949       S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, ""));
06950 }

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

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

06122 {
06123    struct ast_control_read_action_payload *frame_payload;
06124    int payload_size;
06125    int frame_size;
06126    unsigned char connected_line_data[1024];
06127 
06128    /* Release any hold on the target. */
06129    if (colp->target_held) {
06130       ast_queue_control(transferee, AST_CONTROL_UNHOLD);
06131    }
06132 
06133    /*
06134     * Since transferee may not actually be bridged to another channel,
06135     * there is no way for us to queue a frame so that its connected
06136     * line status will be updated.  Instead, we use the somewhat
06137     * hackish approach of using a special control frame type that
06138     * instructs ast_read() to perform a specific action.  In this
06139     * case, the frame we queue tells ast_read() to call the
06140     * connected line interception macro configured for transferee.
06141     */
06142    payload_size = ast_connected_line_build_data(connected_line_data,
06143       sizeof(connected_line_data), &colp->target_id, NULL);
06144    if (payload_size != -1) {
06145       frame_size = payload_size + sizeof(*frame_payload);
06146       frame_payload = alloca(frame_size);
06147       frame_payload->action = AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO;
06148       frame_payload->payload_size = payload_size;
06149       memcpy(frame_payload->payload, connected_line_data, payload_size);
06150       ast_queue_control_data(transferee, AST_CONTROL_READ_ACTION, frame_payload,
06151          frame_size);
06152    }
06153    /*
06154     * In addition to queueing the read action frame so that the
06155     * connected line info on transferee will be updated, we also are
06156     * going to queue a plain old connected line update on transferee to
06157     * update the target.
06158     */
06159    ast_channel_queue_connected_line_update(transferee, &colp->transferee_id, NULL);
06160 }

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

Definition at line 5945 of file channel.c.

References ast_strlen_zero().

Referenced by ast_channel_set_linkgroup().

05946 {
05947    const char *satime, *saseq;
05948    const char *sbtime, *sbseq;
05949    const char *dash;
05950 
05951    unsigned int atime, aseq, btime, bseq;
05952 
05953    if (ast_strlen_zero(a))
05954       return b;
05955 
05956    if (ast_strlen_zero(b))
05957       return a;
05958 
05959    satime = a;
05960    sbtime = b;
05961 
05962    /* jump over the system name */
05963    if ((dash = strrchr(satime, '-'))) {
05964       satime = dash+1;
05965    }
05966    if ((dash = strrchr(sbtime, '-'))) {
05967       sbtime = dash+1;
05968    }
05969 
05970    /* the sequence comes after the '.' */
05971    saseq = strchr(satime, '.');
05972    sbseq = strchr(sbtime, '.');
05973    if (!saseq || !sbseq)
05974       return NULL;
05975    saseq++;
05976    sbseq++;
05977 
05978    /* convert it all to integers */
05979    atime = atoi(satime); /* note that atoi is ignoring the '.' after the time string */
05980    btime = atoi(sbtime); /* note that atoi is ignoring the '.' after the time string */
05981    aseq = atoi(saseq);
05982    bseq = atoi(sbseq);
05983 
05984    /* and finally compare */
05985    if (atime == btime) {
05986       return (aseq < bseq) ? a : b;
05987    }
05988    else {
05989       return (atime < btime) ? a : b;
05990    }
05991 }

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

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

05753 {
05754    struct ast_party_connected_line connected;
05755 
05756    connected = *((struct ast_party_connected_line *) src);
05757    connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
05758 
05759    /* Make sure empty strings will be erased. */
05760    if (!connected.id.name.str) {
05761       connected.id.name.str = "";
05762    }
05763    if (!connected.id.number.str) {
05764       connected.id.number.str = "";
05765    }
05766    if (!connected.id.subaddress.str) {
05767       connected.id.subaddress.str = "";
05768    }
05769    if (!connected.id.tag) {
05770       connected.id.tag = "";
05771    }
05772 
05773    ast_party_connected_line_copy(dest, &connected);
05774 }

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

08167 {
08168    size_t length;
08169    size_t pos = 0;
08170    int res;
08171 
08172    /*
08173     * The size of integer values must be fixed in case the frame is
08174     * shipped to another machine.
08175     */
08176 
08177    if (!update || update->name) {
08178       res = party_name_build_data(data + pos, datalen - pos, &id->name, label,
08179          &ies->name);
08180       if (res < 0) {
08181          return -1;
08182       }
08183       pos += res;
08184    }
08185 
08186    if (!update || update->number) {
08187       res = party_number_build_data(data + pos, datalen - pos, &id->number, label,
08188          &ies->number);
08189       if (res < 0) {
08190          return -1;
08191       }
08192       pos += res;
08193    }
08194 
08195    if (!update || update->subaddress) {
08196       res = party_subaddress_build_data(data + pos, datalen - pos, &id->subaddress,
08197          label, &ies->subaddress);
08198       if (res < 0) {
08199          return -1;
08200       }
08201       pos += res;
08202    }
08203 
08204    /* *************** Party id user tag **************************** */
08205    if (id->tag) {
08206       length = strlen(id->tag);
08207       if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08208          ast_log(LOG_WARNING, "No space left for %s tag\n", label);
08209          return -1;
08210       }
08211       data[pos++] = ies->tag;
08212       data[pos++] = length;
08213       memcpy(data + pos, id->tag, length);
08214       pos += length;
08215    }
08216 
08217    /* *************** Party id combined presentation *************** */
08218    if (!update || update->number) {
08219       int presentation;
08220 
08221       if (!update || update->name) {
08222          presentation = ast_party_id_presentation(id);
08223       } else {
08224          /*
08225           * We must compromise because not all the information is available
08226           * to determine a combined presentation value.
08227           * We will only send the number presentation instead.
08228           */
08229          presentation = id->number.presentation;
08230       }
08231 
08232       if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08233          ast_log(LOG_WARNING, "No space left for %s combined presentation\n", label);
08234          return -1;
08235       }
08236       data[pos++] = ies->combined_presentation;
08237       data[pos++] = 1;
08238       data[pos++] = presentation;
08239    }
08240 
08241    return pos;
08242 }

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

07939 {
07940    size_t length;
07941    size_t pos = 0;
07942 
07943    /*
07944     * The size of integer values must be fixed in case the frame is
07945     * shipped to another machine.
07946     */
07947    if (name->str) {
07948       length = strlen(name->str);
07949       if (datalen < pos + (sizeof(data[0]) * 2) + length) {
07950          ast_log(LOG_WARNING, "No space left for %s name\n", label);
07951          return -1;
07952       }
07953       data[pos++] = ies->str;
07954       data[pos++] = length;
07955       memcpy(data + pos, name->str, length);
07956       pos += length;
07957    }
07958 
07959    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
07960       ast_log(LOG_WARNING, "No space left for %s name char set\n", label);
07961       return -1;
07962    }
07963    data[pos++] = ies->char_set;
07964    data[pos++] = 1;
07965    data[pos++] = name->char_set;
07966 
07967    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
07968       ast_log(LOG_WARNING, "No space left for %s name presentation\n", label);
07969       return -1;
07970    }
07971    data[pos++] = ies->presentation;
07972    data[pos++] = 1;
07973    data[pos++] = name->presentation;
07974 
07975    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
07976       ast_log(LOG_WARNING, "No space left for %s name valid\n", label);
07977       return -1;
07978    }
07979    data[pos++] = ies->valid;
07980    data[pos++] = 1;
07981    data[pos++] = name->valid;
07982 
07983    return pos;
07984 }

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

08013 {
08014    size_t length;
08015    size_t pos = 0;
08016 
08017    /*
08018     * The size of integer values must be fixed in case the frame is
08019     * shipped to another machine.
08020     */
08021    if (number->str) {
08022       length = strlen(number->str);
08023       if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08024          ast_log(LOG_WARNING, "No space left for %s number\n", label);
08025          return -1;
08026       }
08027       data[pos++] = ies->str;
08028       data[pos++] = length;
08029       memcpy(data + pos, number->str, length);
08030       pos += length;
08031    }
08032 
08033    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08034       ast_log(LOG_WARNING, "No space left for %s numbering plan\n", label);
08035       return -1;
08036    }
08037    data[pos++] = ies->plan;
08038    data[pos++] = 1;
08039    data[pos++] = number->plan;
08040 
08041    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08042       ast_log(LOG_WARNING, "No space left for %s number presentation\n", label);
08043       return -1;
08044    }
08045    data[pos++] = ies->presentation;
08046    data[pos++] = 1;
08047    data[pos++] = number->presentation;
08048 
08049    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08050       ast_log(LOG_WARNING, "No space left for %s number valid\n", label);
08051       return -1;
08052    }
08053    data[pos++] = ies->valid;
08054    data[pos++] = 1;
08055    data[pos++] = number->valid;
08056 
08057    return pos;
08058 }

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

08087 {
08088    size_t length;
08089    size_t pos = 0;
08090 
08091    /*
08092     * The size of integer values must be fixed in case the frame is
08093     * shipped to another machine.
08094     */
08095    if (subaddress->str) {
08096       length = strlen(subaddress->str);
08097       if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08098          ast_log(LOG_WARNING, "No space left for %s subaddress\n", label);
08099          return -1;
08100       }
08101       data[pos++] = ies->str;
08102       data[pos++] = length;
08103       memcpy(data + pos, subaddress->str, length);
08104       pos += length;
08105    }
08106 
08107    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08108       ast_log(LOG_WARNING, "No space left for %s type of subaddress\n", label);
08109       return -1;
08110    }
08111    data[pos++] = ies->type;
08112    data[pos++] = 1;
08113    data[pos++] = subaddress->type;
08114 
08115    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08116       ast_log(LOG_WARNING,
08117          "No space left for %s subaddress odd-even indicator\n", label);
08118       return -1;
08119    }
08120    data[pos++] = ies->odd_even_indicator;
08121    data[pos++] = 1;
08122    data[pos++] = subaddress->odd_even_indicator;
08123 
08124    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08125       ast_log(LOG_WARNING, "No space left for %s subaddress valid\n", label);
08126       return -1;
08127    }
08128    data[pos++] = ies->valid;
08129    data[pos++] = 1;
08130    data[pos++] = subaddress->valid;
08131 
08132    return pos;
08133 }

static void plc_ds_destroy ( void *  data  )  [static]

Definition at line 4562 of file channel.c.

References ast_free, and plc_ds::samples_buf.

04563 {
04564    struct plc_ds *plc = data;
04565    ast_free(plc->samples_buf);
04566    ast_free(plc);
04567 }

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

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

03559 {
03560    struct ast_frame *fr = &chan->dtmff;
03561 
03562    fr->frametype = AST_FRAME_DTMF_END;
03563    fr->subclass.integer = f->subclass.integer;
03564    fr->len = f->len;
03565 
03566    /* The only time this function will be called is for a frame that just came
03567     * out of the channel driver.  So, we want to stick it on the tail of the
03568     * readq. */
03569 
03570    ast_queue_frame(chan, fr);
03571 }

static void report_new_callerid ( struct ast_channel chan  )  [static]

Precondition:
chan is locked

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

06092 {
06093    int pres;
06094 
06095    pres = ast_party_id_presentation(&chan->caller.id);
06096    ast_manager_event(chan, EVENT_FLAG_CALL, "NewCallerid",
06097       "Channel: %s\r\n"
06098       "CallerIDNum: %s\r\n"
06099       "CallerIDName: %s\r\n"
06100       "Uniqueid: %s\r\n"
06101       "CID-CallingPres: %d (%s)\r\n",
06102       chan->name,
06103       S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
06104       S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""),
06105       chan->uniqueid,
06106       pres,
06107       ast_describe_caller_presentation(pres)
06108       );
06109 }

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

03498 {
03499    ast_manager_event(chan, EVENT_FLAG_DTMF,
03500          "DTMF",
03501          "Channel: %s\r\n"
03502          "Uniqueid: %s\r\n"
03503          "Digit: %c\r\n"
03504          "Direction: %s\r\n"
03505          "Begin: %s\r\n"
03506          "End: %s\r\n",
03507          chan->name, chan->uniqueid, digit, direction, begin, end);
03508 }

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

04941 {
04942    format_t native, native_fmt = ast_best_codec(fmt);
04943    int res;
04944    char from[200], to[200];
04945    
04946    /* Make sure we only consider audio */
04947    fmt &= AST_FORMAT_AUDIO_MASK;
04948    
04949    native = chan->nativeformats;
04950 
04951    if (!fmt || !native) /* No audio requested */
04952       return 0;   /* Let's try a call without any sounds (video, text) */
04953 
04954    /* See if the underlying channel driver is capable of performing transcoding for us */
04955    if (!ast_channel_setoption(chan, direction ? AST_OPTION_FORMAT_WRITE : AST_OPTION_FORMAT_READ, &native_fmt, sizeof(int*), 0)) {
04956       ast_debug(1, "Channel driver natively set channel %s to %s format %s\n", chan->name,
04957            direction ? "write" : "read", ast_getformatname(native_fmt));
04958       chan->nativeformats = *rawformat = *format = native_fmt;
04959       if (*trans) {
04960          ast_translator_free_path(*trans);
04961       }
04962       *trans = NULL;
04963       return 0;
04964    }
04965 
04966    /* Find a translation path from the native format to one of the desired formats */
04967    if (!direction)
04968       /* reading */
04969       res = ast_translator_best_choice(&fmt, &native);
04970    else
04971       /* writing */
04972       res = ast_translator_best_choice(&native, &fmt);
04973 
04974    if (res < 0) {
04975       ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n",
04976          ast_getformatname_multiple(from, sizeof(from), native),
04977          ast_getformatname_multiple(to, sizeof(to), fmt));
04978       return -1;
04979    }
04980    
04981    /* Now we have a good choice for both. */
04982    ast_channel_lock(chan);
04983 
04984    if ((*rawformat == native) && (*format == fmt) && ((*rawformat == *format) || (*trans))) {
04985       /* the channel is already in these formats, so nothing to do */
04986       ast_channel_unlock(chan);
04987       return 0;
04988    }
04989 
04990    *rawformat = native;
04991    /* User perspective is fmt */
04992    *format = fmt;
04993    /* Free any read translation we have right now */
04994    if (*trans) {
04995       ast_translator_free_path(*trans);
04996       *trans = NULL;
04997    }
04998    /* Build a translation path from the raw format to the desired format */
04999    if (*format == *rawformat) {
05000       /*
05001        * If we were able to swap the native format to the format that
05002        * has been requested, then there is no need to try to build
05003        * a translation path.
05004        */
05005       res = 0;
05006    } else {
05007       if (!direction) {
05008          /* reading */
05009          *trans = ast_translator_build_path(*format, *rawformat);
05010       } else {
05011          /* writing */
05012          *trans = ast_translator_build_path(*rawformat, *format);
05013       }
05014       res = *trans ? 0 : -1;
05015    }
05016    ast_channel_unlock(chan);
05017    ast_debug(1, "Set channel %s to %s format %s\n", chan->name,
05018       direction ? "write" : "read", ast_getformatname(fmt));
05019    return res;
05020 }

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

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

05316 {
05317    int ops[2][2] = {
05318       {AST_OPTION_SECURE_SIGNALING, 0},
05319       {AST_OPTION_SECURE_MEDIA, 0},
05320    };
05321    int i;
05322    struct ast_channel *r = (struct ast_channel *) requestor; /* UGLY */
05323    struct ast_datastore *ds;
05324 
05325    if (!requestor || !out) {
05326       return 0;
05327    }
05328 
05329    ast_channel_lock(r);
05330    if ((ds = ast_channel_datastore_find(r, &secure_call_info, NULL))) {
05331       struct ast_secure_call_store *encrypt = ds->data;
05332       ops[0][1] = encrypt->signaling;
05333       ops[1][1] = encrypt->media;
05334    } else {
05335       ast_channel_unlock(r);
05336       return 0;
05337    }
05338    ast_channel_unlock(r);
05339 
05340    for (i = 0; i < 2; i++) {
05341       if (ops[i][1]) {
05342          if (ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0)) {
05343             /* We require a security feature, but the channel won't provide it */
05344             return -1;
05345          }
05346       } else {
05347          /* We don't care if we can't clear the option on a channel that doesn't support it */
05348          ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0);
05349       }
05350    }
05351 
05352    return 0;
05353 }

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

03577 {
03578    if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF)) {
03579       /* We're in the middle of emulating a digit, or DTMF has been
03580        * explicitly deferred.  Skip this digit, then. */
03581       return 1;
03582    }
03583          
03584    if (!ast_tvzero(chan->dtmf_tv) && 
03585          ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) {
03586       /* We're not in the middle of a digit, but it hasn't been long enough
03587        * since the last digit, so we'll have to skip DTMF for now. */
03588       return 1;
03589    }
03590 
03591    return 0;
03592 }

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

Definition at line 7734 of file channel.c.

07735 {
07736    /* just store the data pointer in the channel structure */
07737    return data;
07738 }

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

Definition at line 7745 of file channel.c.

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

07746 {
07747    short buf[samples];
07748    struct ast_frame frame = {
07749       .frametype = AST_FRAME_VOICE,
07750       .subclass.codec = AST_FORMAT_SLINEAR,
07751       .data.ptr = buf,
07752       .samples = samples,
07753       .datalen = sizeof(buf),
07754    };
07755 
07756    memset(buf, 0, sizeof(buf));
07757 
07758    if (ast_write(chan, &frame))
07759       return -1;
07760 
07761    return 0;
07762 }

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

Definition at line 7740 of file channel.c.

07741 {
07742    /* nothing to do */
07743 }

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

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

07347 {
07348    struct tonepair_state *ts;
07349    struct tonepair_def *td = params;
07350 
07351    if (!(ts = ast_calloc(1, sizeof(*ts))))
07352       return NULL;
07353    ts->origwfmt = chan->writeformat;
07354    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
07355       ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
07356       tonepair_release(NULL, ts);
07357       ts = NULL;
07358    } else {
07359       ts->fac1 = 2.0 * cos(2.0 * M_PI * (td->freq1 / 8000.0)) * 32768.0;
07360       ts->v1_1 = 0;
07361       ts->v2_1 = sin(-4.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
07362       ts->v3_1 = sin(-2.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
07363       ts->v2_1 = 0;
07364       ts->fac2 = 2.0 * cos(2.0 * M_PI * (td->freq2 / 8000.0)) * 32768.0;
07365       ts->v2_2 = sin(-4.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
07366       ts->v3_2 = sin(-2.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
07367       ts->duration = td->duration;
07368       ts->modulate = 0;
07369    }
07370    /* Let interrupts interrupt :) */
07371    ast_set_flag(chan, AST_FLAG_WRITE_INT);
07372    return ts;
07373 }

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

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

07376 {
07377    struct tonepair_state *ts = data;
07378    int x;
07379 
07380    /* we need to prepare a frame with 16 * timelen samples as we're
07381     * generating SLIN audio
07382     */
07383    len = samples * 2;
07384 
07385    if (len > sizeof(ts->data) / 2 - 1) {
07386       ast_log(LOG_WARNING, "Can't generate that much data!\n");
07387       return -1;
07388    }
07389    memset(&ts->f, 0, sizeof(ts->f));
07390    for (x=0;x<len/2;x++) {
07391       ts->v1_1 = ts->v2_1;
07392       ts->v2_1 = ts->v3_1;
07393       ts->v3_1 = (ts->fac1 * ts->v2_1 >> 15) - ts->v1_1;
07394       
07395       ts->v1_2 = ts->v2_2;
07396       ts->v2_2 = ts->v3_2;
07397       ts->v3_2 = (ts->fac2 * ts->v2_2 >> 15) - ts->v1_2;
07398       if (ts->modulate) {
07399          int p;
07400          p = ts->v3_2 - 32768;
07401          if (p < 0) p = -p;
07402          p = ((p * 9) / 10) + 1;
07403          ts->data[x] = (ts->v3_1 * p) >> 15;
07404       } else
07405          ts->data[x] = ts->v3_1 + ts->v3_2; 
07406    }
07407    ts->f.frametype = AST_FRAME_VOICE;
07408    ts->f.subclass.codec = AST_FORMAT_SLINEAR;
07409    ts->f.datalen = len;
07410    ts->f.samples = samples;
07411    ts->f.offset = AST_FRIENDLY_OFFSET;
07412    ts->f.data.ptr = ts->data;
07413    ast_write(chan, &ts->f);
07414    ts->pos += x;
07415    if (ts->duration > 0) {
07416       if (ts->pos >= ts->duration * 8)
07417          return -1;
07418    }
07419    return 0;
07420 }

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

Definition at line 7337 of file channel.c.

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

Referenced by tonepair_alloc().

07338 {
07339    struct tonepair_state *ts = params;
07340 
07341    if (chan)
07342       ast_set_write_format(chan, ts->origwfmt);
07343    ast_free(ts);
07344 }

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

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

06953 {
06954    const char *c0_name;
06955    const char *c1_name;
06956    const char *c0_pvtid = NULL;
06957    const char *c1_pvtid = NULL;
06958 
06959    ast_channel_lock(c1);
06960    c1_name = ast_strdupa(c1->name);
06961    if (c1->tech->get_pvt_uniqueid) {
06962       c1_pvtid = ast_strdupa(c1->tech->get_pvt_uniqueid(c1));
06963    }
06964    ast_channel_unlock(c1);
06965 
06966    ast_channel_lock(c0);
06967    if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER"))) {
06968       pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1_name);
06969    }
06970    if (c1_pvtid) {
06971       pbx_builtin_setvar_helper(c0, "BRIDGEPVTCALLID", c1_pvtid);
06972    }
06973    c0_name = ast_strdupa(c0->name);
06974    if (c0->tech->get_pvt_uniqueid) {
06975       c0_pvtid = ast_strdupa(c0->tech->get_pvt_uniqueid(c0));
06976    }
06977    ast_channel_unlock(c0);
06978 
06979    ast_channel_lock(c1);
06980    if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER"))) {
06981       pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0_name);
06982    }
06983    if (c0_pvtid) {
06984       pbx_builtin_setvar_helper(c1, "BRIDGEPVTCALLID", c0_pvtid);
06985    }
06986    ast_channel_unlock(c1);
06987 }

static void xfer_ds_destroy ( void *  data  )  [static]

Definition at line 5797 of file channel.c.

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

05798 {
05799    struct xfer_masquerade_ds *ds = data;
05800 
05801    ast_party_connected_line_free(&ds->target_id);
05802    ast_party_connected_line_free(&ds->transferee_id);
05803    ast_free(ds);
05804 }


Variable Documentation

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

Definition at line 7498 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 7496 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 7497 of file channel.c.

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

int cause

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

Referenced by ast_channels_init().

struct ao2_container* channels [static]

All active channels on the system.

Definition at line 191 of file channel.c.

struct ast_data_handler channels_provider [static]

Initial value:

Definition at line 7669 of file channel.c.

struct ast_data_handler channeltypes_provider [static]

Initial value:

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

Referenced by ast_channels_init().

const char* desc

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

Referenced by handle_core_set_debug_channel().

unsigned long global_fout

Definition at line 98 of file channel.c.

Referenced by handle_core_set_debug_channel().

const char* name

Definition at line 199 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 1050 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 4569 of file channel.c.

Referenced by apply_plc().

int shutting_down [static]

Prevent new channel allocation if shutting down.

Definition at line 94 of file channel.c.

struct ast_generator silence_generator [static]

Initial value:

Definition at line 7764 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 100 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 7422 of file channel.c.

Referenced by ast_tonepair_start().

int uniqueint [static]

Definition at line 96 of file channel.c.

struct ast_datastore_info xfer_ds_info [static]

Initial value:

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

Definition at line 5806 of file channel.c.

Referenced by ast_channel_transfer_masquerade(), and ast_do_masquerade().


Generated on Wed Apr 6 11:30:02 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7