#include "asterisk/abstract_jb.h"
#include "asterisk/astobj2.h"
#include "asterisk/poll-compat.h"
#include "asterisk/frame.h"
#include "asterisk/sched.h"
#include "asterisk/chanvars.h"
#include "asterisk/config.h"
#include "asterisk/lock.h"
#include "asterisk/cdr.h"
#include "asterisk/utils.h"
#include "asterisk/linkedlists.h"
#include "asterisk/stringfields.h"
#include "asterisk/datastore.h"
#include "asterisk/data.h"
#include "asterisk/channelstate.h"
#include "asterisk/ccss.h"
#include "asterisk/framehook.h"
Go to the source code of this file.
Data Structures | |
struct | ast_bridge_config |
bridge configuration More... | |
struct | ast_chan_write_info_t |
Structure to handle passing func_channel_write info to channels via setoption. More... | |
struct | ast_channel |
Main Channel structure associated with a channel. More... | |
struct | ast_channel::autochans |
struct | ast_channel::datastores |
struct | ast_channel_tech |
Structure to describe a channel "technology", ie a channel driver See for examples:. More... | |
struct | ast_generator |
struct | ast_group_info |
channel group info More... | |
struct | ast_party_caller |
Caller Party information. More... | |
struct | ast_party_connected_line |
Connected Line/Party information. More... | |
struct | ast_party_dialed |
Dialed/Called Party information. More... | |
struct | ast_party_id |
Information needed to identify an endpoint in a call. More... | |
struct | ast_party_name |
Information needed to specify a name in a call. More... | |
struct | ast_party_number |
Information needed to specify a number in a call. More... | |
struct | ast_party_redirecting |
Redirecting Line information. RDNIS (Redirecting Directory Number Information Service) Where a call diversion or transfer was invoked. More... | |
struct | ast_party_subaddress |
Information needed to specify a subaddress in a call. More... | |
struct | ast_set_party_caller |
Indicate what information in ast_party_caller should be set. More... | |
struct | ast_set_party_connected_line |
Indicate what information in ast_party_connected_line should be set. More... | |
struct | ast_set_party_id |
Indicate what information in ast_party_id should be set. More... | |
struct | ast_set_party_redirecting |
Indicate what information in ast_party_redirecting should be set. More... | |
struct | outgoing_helper |
ast_channel * | ast_channel_get_by_exten (const char *exten, const char *context) |
Find a channel by extension and context. | |
ast_channel * | ast_channel_get_by_name (const char *name) |
Find a channel by name. | |
ast_channel * | ast_channel_get_by_name_prefix (const char *name, size_t name_len) |
Find a channel by a name prefix. | |
ast_channel_iterator * | ast_channel_iterator_all_new (void) |
Create a new channel iterator. | |
ast_channel_iterator * | ast_channel_iterator_by_exten_new (const char *exten, const char *context) |
Create a new channel iterator based on extension. | |
ast_channel_iterator * | ast_channel_iterator_by_name_new (const char *name, size_t name_len) |
Create a new channel iterator based on name. | |
ast_channel_iterator * | ast_channel_iterator_destroy (struct ast_channel_iterator *i) |
Destroy a channel iterator. | |
ast_channel * | ast_channel_iterator_next (struct ast_channel_iterator *i) |
Get the next channel for a channel iterator. | |
Defines | |
#define | AST_AGENT_FD (AST_MAX_FDS-3) |
#define | AST_ALERT_FD (AST_MAX_FDS-1) |
#define | AST_BRIDGE_DTMF_CHANNEL_0 (1 << 0) |
Report DTMF on channel 0. | |
#define | AST_BRIDGE_DTMF_CHANNEL_1 (1 << 1) |
Report DTMF on channel 1. | |
#define | AST_BRIDGE_IGNORE_SIGS (1 << 4) |
Ignore all signal frames except NULL. | |
#define | AST_BRIDGE_REC_CHANNEL_0 (1 << 2) |
Return all voice frames on channel 0. | |
#define | AST_BRIDGE_REC_CHANNEL_1 (1 << 3) |
Return all voice frames on channel 1. | |
#define | AST_CHAN_WRITE_INFO_T_VERSION 1 |
ast_chan_write_info_t version. Must be incremented if structure is changed | |
#define | ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, linkedid, amaflag,) |
Create a channel structure. | |
#define | ast_channel_lock(chan) ao2_lock(chan) |
#define | ast_channel_lock_both(chan1, chan2) |
Lock two channels. | |
#define | AST_CHANNEL_NAME 80 |
#define | ast_channel_ref(c) ({ ao2_ref(c, +1); (c); }) |
Increase channel reference count. | |
#define | ast_channel_trylock(chan) ao2_trylock(chan) |
#define | ast_channel_unlock(chan) ao2_unlock(chan) |
#define | ast_channel_unref(c) ({ ao2_ref(c, -1); (struct ast_channel *) (NULL); }) |
Decrease channel reference count. | |
#define | AST_GENERATOR_FD (AST_MAX_FDS-4) |
#define | AST_MAX_CONTEXT 80 |
#define | AST_MAX_EXTENSION 80 |
#define | AST_MAX_FDS 10 |
#define | AST_TIMING_FD (AST_MAX_FDS-2) |
#define | CHECK_BLOCKING(c) |
#define | DATASTORE_INHERIT_FOREVER INT_MAX |
#define | DEBUGCHAN_FLAG 0x80000000 |
#define | FRAMECOUNT_INC(x) ( ((x) & DEBUGCHAN_FLAG) | (((x)+1) & ~DEBUGCHAN_FLAG) ) |
#define | MAX_LANGUAGE 40 |
#define | MAX_MUSICCLASS 80 |
Typedefs | |
typedef int(*) | ast_acf_read2_fn_t (struct ast_channel *, const char *, char *, struct ast_str **, ssize_t) |
Typedef for a custom read2 function. | |
typedef int(*) | ast_acf_read_fn_t (struct ast_channel *, const char *, char *, char *, size_t) |
Typedef for a custom read function. | |
typedef int(*) | ast_acf_write_fn_t (struct ast_channel *, const char *, char *, const char *) |
Typedef for a custom write function. | |
typedef unsigned long long | ast_group_t |
Enumerations | |
enum | { AST_CHAN_TP_WANTSJITTER = (1 << 0), AST_CHAN_TP_CREATESJITTER = (1 << 1) } |
ast_channel_tech Properties More... | |
enum | { AST_FLAG_DEFER_DTMF = (1 << 1), AST_FLAG_WRITE_INT = (1 << 2), AST_FLAG_BLOCKING = (1 << 3), AST_FLAG_ZOMBIE = (1 << 4), AST_FLAG_EXCEPTION = (1 << 5), AST_FLAG_MOH = (1 << 6), AST_FLAG_SPYING = (1 << 7), AST_FLAG_NBRIDGE = (1 << 8), AST_FLAG_IN_AUTOLOOP = (1 << 9), AST_FLAG_OUTGOING = (1 << 10), AST_FLAG_IN_DTMF = (1 << 12), AST_FLAG_EMULATE_DTMF = (1 << 13), AST_FLAG_END_DTMF_ONLY = (1 << 14), AST_FLAG_ANSWERED_ELSEWHERE = (1 << 15), AST_FLAG_MASQ_NOSTREAM = (1 << 16), AST_FLAG_BRIDGE_HANGUP_RUN = (1 << 17), AST_FLAG_BRIDGE_HANGUP_DONT = (1 << 18), AST_FLAG_DISABLE_WORKAROUNDS = (1 << 20) } |
ast_channel flags More... | |
enum | { AST_FEATURE_PLAY_WARNING = (1 << 0), AST_FEATURE_REDIRECT = (1 << 1), AST_FEATURE_DISCONNECT = (1 << 2), AST_FEATURE_ATXFER = (1 << 3), AST_FEATURE_AUTOMON = (1 << 4), AST_FEATURE_PARKCALL = (1 << 5), AST_FEATURE_AUTOMIXMON = (1 << 6), AST_FEATURE_NO_H_EXTEN = (1 << 7), AST_FEATURE_WARNING_ACTIVE = (1 << 8) } |
ast_bridge_config flags More... | |
enum | { AST_SOFTHANGUP_DEV = (1 << 0), AST_SOFTHANGUP_ASYNCGOTO = (1 << 1), AST_SOFTHANGUP_SHUTDOWN = (1 << 2), AST_SOFTHANGUP_TIMEOUT = (1 << 3), AST_SOFTHANGUP_APPUNLOAD = (1 << 4), AST_SOFTHANGUP_EXPLICIT = (1 << 5), AST_SOFTHANGUP_UNBRIDGE = (1 << 6), AST_SOFTHANGUP_ALL = (0xFFFFFFFF) } |
enum | ast_bridge_result { AST_BRIDGE_COMPLETE = 0, AST_BRIDGE_FAILED = -1, AST_BRIDGE_FAILED_NOWARN = -2, AST_BRIDGE_RETRY = -3 } |
enum | ast_channel_adsicpe { AST_ADSI_UNKNOWN, AST_ADSI_AVAILABLE, AST_ADSI_UNAVAILABLE, AST_ADSI_OFFHOOKONLY } |
enum | AST_PARTY_CHAR_SET { AST_PARTY_CHAR_SET_UNKNOWN = 0, AST_PARTY_CHAR_SET_ISO8859_1 = 1, AST_PARTY_CHAR_SET_WITHDRAWN = 2, AST_PARTY_CHAR_SET_ISO8859_2 = 3, AST_PARTY_CHAR_SET_ISO8859_3 = 4, AST_PARTY_CHAR_SET_ISO8859_4 = 5, AST_PARTY_CHAR_SET_ISO8859_5 = 6, AST_PARTY_CHAR_SET_ISO8859_7 = 7, AST_PARTY_CHAR_SET_ISO10646_BMPSTRING = 8, AST_PARTY_CHAR_SET_ISO10646_UTF_8STRING = 9 } |
enum | ast_t38_state { T38_STATE_UNAVAILABLE, T38_STATE_UNKNOWN, T38_STATE_NEGOTIATING, T38_STATE_REJECTED, T38_STATE_NEGOTIATED } |
Possible T38 states on channels. More... | |
enum | channelreloadreason { CHANNEL_MODULE_LOAD, CHANNEL_MODULE_RELOAD, CHANNEL_CLI_RELOAD, CHANNEL_MANAGER_RELOAD } |
Channel reload reasons for manager events at load or reload of configuration. More... | |
Functions | |
int | __ast_answer (struct ast_channel *chan, unsigned int delay, int cdr_answer) |
Answer a channel, with a selectable delay before returning. | |
ast_channel *attribute_malloc | __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. | |
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. | |
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 | |
static int | ast_add_fd (struct pollfd *pfd, int fd) |
if fd is a valid descriptor, set *pfd with the descriptor | |
int | ast_answer (struct ast_channel *chan) |
Answer a channel. | |
int | ast_autoservice_ignore (struct ast_channel *chan, enum ast_frame_type ftype) |
Ignore certain frame types. | |
int | ast_autoservice_start (struct ast_channel *chan) |
Automatically service a channel for us... | |
int | ast_autoservice_stop (struct ast_channel *chan) |
Stop servicing a channel for us... | |
void | ast_begin_shutdown (int hangup) |
format_t | ast_best_codec (format_t fmts) |
Pick the best audio codec. | |
ast_channel * | ast_bridged_channel (struct ast_channel *chan) |
Find bridged channel. | |
int | ast_call (struct ast_channel *chan, char *addr, int timeout) |
Make a call. | |
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. | |
void | ast_cancel_shutdown (void) |
Cancel a shutdown in progress. | |
const char * | ast_cause2str (int state) attribute_pure |
Gives the string form of a given cause code. | |
void | ast_change_name (struct ast_channel *chan, const char *newname) |
Change channel name. | |
int | 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_channel * | ast_channel_callback (ao2_callback_data_fn *cb_fn, void *arg, void *data, int ao2_flags) |
Call a function with every active channel. | |
int | ast_channel_cc_params_init (struct ast_channel *chan, const struct ast_cc_config_params *base_params) |
Set up datastore with CCSS parameters for a channel. | |
void | ast_channel_clear_softhangup (struct ast_channel *chan, int flag) |
Clear a set of softhangup flags from a channel. | |
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 caller, int 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_datastore *attribute_malloc | ast_channel_datastore_alloc (const struct ast_datastore_info *info, const char *uid) |
Create a channel data store object. | |
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. | |
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. | |
int | ast_channel_early_bridge (struct ast_channel *c0, struct ast_channel *c1) |
Bridge two channels together (early). | |
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_params * | ast_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 enum ast_t38_state | ast_channel_get_t38_state (struct ast_channel *chan) |
Retrieves the current T38 state of a channel. | |
void | ast_channel_inherit_variables (const struct ast_channel *parent, struct ast_channel *child) |
Inherits channel variable from parent to child channel. | |
int | ast_channel_make_compatible (struct ast_channel *c0, struct ast_channel *c1) |
Makes two channel formats compatible. | |
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 *channel, 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_channel * | ast_channel_release (struct ast_channel *chan) |
Unlink and release reference to a channel. | |
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. | |
int | ast_channel_sendurl (struct ast_channel *channel, 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 *channel, 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. | |
ast_silence_generator * | ast_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 *channel) |
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. | |
ast_variable * | ast_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. | |
void | ast_deactivate_generator (struct ast_channel *chan) |
int | ast_do_masquerade (struct ast_channel *chan) |
Start masquerading a channel. | |
ast_channel * | ast_dummy_channel_alloc (void) |
Create a fake channel structure. | |
static int | ast_fdisset (struct pollfd *pfds, int fd, int maximum, int *start) |
Helper function for migrating select to poll. | |
ast_channel_tech * | ast_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. | |
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_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. | |
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 *f) |
Queue one or more frames to a channel's frame queue. | |
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. | |
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_frame * | ast_read (struct ast_channel *chan) |
Reads a frame. | |
ast_frame * | ast_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 rtimeout, char *enders) |
Reads multiple digits. | |
int | ast_readstring_full (struct ast_channel *c, char *s, int len, int timeout, int rtimeout, 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_channel * | ast_request (const char *type, format_t format, const struct ast_channel *requestor, void *data, int *status) |
Requests a channel. | |
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. | |
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_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. | |
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. | |
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 format) |
Sets write format on channel chan Set write format for channel to whichever component of "format" is best. | |
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 reason) |
Softly hangup up a channel. | |
int | ast_softhangup_nolock (struct ast_channel *chan, int reason) |
Softly hangup up a channel (no channel lock). | |
const char * | ast_state2str (enum ast_channel_state) |
Gives the string form of a given channel state. | |
int | ast_str2cause (const char *name) attribute_pure |
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) attribute_const |
Gives the string form of a given transfer capability. | |
int | ast_waitfor (struct ast_channel *chan, int ms) |
Wait for input on a channel. | |
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. | |
int | ast_waitfor_n_fd (int *fds, int n, int *ms, int *exception) |
Waits for input on an fd. | |
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. | |
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 ctrlfd) |
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 *frame) |
Write a frame to a channel This function writes the given frame to the indicated channel. | |
int | ast_write_text (struct ast_channel *chan, struct ast_frame *frame) |
Write text 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 *frame) |
Write video frame to a channel This function writes the given frame to the indicated channel. | |
const char * | channelreloadreason2txt (enum channelreloadreason reason) |
Convert enum channelreloadreason to text string for manager event. | |
Variables | |
ast_channel_tech | ast_kill_tech |
Kill the channel channel driver technology descriptor. | |
unsigned long | global_fin |
unsigned long | global_fout |
Definition in file channel.h.
#define AST_AGENT_FD (AST_MAX_FDS-3) |
used by agents for pass through
Definition at line 165 of file channel.h.
Referenced by agent_read().
#define AST_ALERT_FD (AST_MAX_FDS-1) |
used for alertpipe
Definition at line 163 of file channel.h.
Referenced by __ast_channel_alloc_ap().
#define AST_BRIDGE_DTMF_CHANNEL_0 (1 << 0) |
Report DTMF on channel 0.
Definition at line 1903 of file channel.h.
Referenced by ast_generic_bridge(), dahdi_bridge(), iax2_bridge(), misdn_bridge(), and set_config_flags().
#define AST_BRIDGE_DTMF_CHANNEL_1 (1 << 1) |
Report DTMF on channel 1.
Definition at line 1905 of file channel.h.
Referenced by ast_generic_bridge(), dahdi_bridge(), iax2_bridge(), misdn_bridge(), and set_config_flags().
#define AST_BRIDGE_IGNORE_SIGS (1 << 4) |
#define AST_BRIDGE_REC_CHANNEL_0 (1 << 2) |
#define AST_BRIDGE_REC_CHANNEL_1 (1 << 3) |
#define AST_CHAN_WRITE_INFO_T_VERSION 1 |
ast_chan_write_info_t version. Must be incremented if structure is changed
Definition at line 484 of file channel.h.
Referenced by func_channel_write(), and local_setoption().
#define ast_channel_alloc | ( | needqueue, | |||
state, | |||||
cid_num, | |||||
cid_name, | |||||
acctcode, | |||||
exten, | |||||
context, | |||||
linkedid, | |||||
amaflag | ) |
Value:
__ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, linkedid, amaflag, \ __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
NULL | failure | |
non-NULL | successfully allocated channel |
By default, new channels are set to the "s" extension and "default" context.
Definition at line 1129 of file channel.h.
Referenced by __oh323_new(), action_bridge(), agent_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_pbx_outgoing_exten(), bridge_exec(), bridge_request(), builtin_atxfer(), check_goto_on_transfer(), console_new(), dahdi_new(), do_notify(), gtalk_new(), iax_park(), jingle_new(), local_new(), masq_park_call(), mgcp_new(), misdn_new(), multicast_rtp_request(), nbs_new(), oss_new(), phone_new(), sip_new(), sip_park(), skinny_new(), unistim_new(), and usbradio_new().
#define ast_channel_lock | ( | chan | ) | ao2_lock(chan) |
Definition at line 2433 of file channel.h.
Referenced by __ast_answer(), __ast_pbx_run(), __ast_queue_frame(), __ast_read(), __ast_request_and_dial(), __oh323_destroy(), __sip_destroy(), _macro_exec(), _while_exec(), acf_cc_read(), acf_cc_write(), acf_fetch(), action_add_agi_cmd(), action_coreshowchannels(), action_hangup(), action_redirect(), action_status(), action_timeout(), add_features_datastores(), add_to_agi(), agent_hangup(), agent_indicate(), agent_lock_owner(), app_exec(), ast_activate_generator(), ast_async_goto(), ast_audiohook_attach(), ast_audiohook_detach_source(), ast_audiohook_remove(), ast_audiohook_set_mute(), ast_autochan_destroy(), ast_autochan_setup(), ast_autoservice_start(), ast_autoservice_stop(), ast_bridge_call(), ast_bridge_timelimit(), ast_call(), ast_call_forward(), 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_cel_report_event(), ast_change_name(), ast_channel_clear_softhangup(), ast_channel_cmp_cb(), ast_channel_connected_line_macro(), ast_channel_destructor(), ast_channel_queryoption(), ast_channel_redirecting_macro(), ast_channel_set_caller(), ast_channel_set_caller_event(), ast_channel_set_connected_line(), ast_channel_set_redirecting(), ast_channel_setoption(), ast_check_hangup_locked(), ast_complete_channels(), ast_deactivate_generator(), ast_dial_join(), ast_do_masquerade(), ast_do_pickup(), ast_eivr_getvariable(), ast_explicit_goto(), ast_handle_cc_control_frame(), ast_hangup(), ast_ignore_cc(), ast_indicate_data(), ast_odbc_retrieve_transaction_obj(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_raw_answer(), ast_read_generator_actions(), ast_rtp_instance_bridge(), ast_rtp_instance_early_bridge(), ast_rtp_instance_early_bridge_make_compatible(), ast_rtp_instance_make_compatible(), ast_safe_sleep_conditional(), ast_sendtext(), ast_set_callerid(), ast_set_cc_interfaces_chanvar(), ast_set_hangupsource(), ast_settimeout(), ast_setup_cc_recall_datastore(), ast_softhangup(), ast_stopstream(), ast_str_retrieve_variable(), ast_transfer(), ast_udptl_bridge(), ast_var_channel_bridge(), ast_var_channels_table(), ast_waitfor_nandfds(), ast_write(), bridge_play_sounds(), builtin_atxfer(), builtin_automixmonitor(), builtin_blindtransfer(), calendar_event_read(), calendar_query_exec(), calendar_query_result_exec(), call_forward_inherit(), callerid_read(), callerid_write(), cb_events(), cc_build_payload(), cc_interfaces_datastore_init(), cdr_read(), cdr_write(), channel_set_debug(), channel_spy(), check_goto_on_transfer(), clear_caller(), clear_dialed_interfaces(), common_exec(), conf_run(), conf_start_moh(), confbridge_exec(), connectedline_read(), connectedline_write(), create_dynamic_parkinglot(), crement_function_read(), dahdi_bridge(), dahdi_handle_dtmf(), data_channels_provider_handler(), dial_exec_full(), disable_jack_hook(), do_forward(), dundi_query_read(), dundi_result_read(), enable_jack_hook(), end_bridge_callback(), enum_query_read(), enum_result_read(), exec_odbcfinish(), feature_check(), feature_interpret(), feature_request_and_dial(), find_by_mark(), find_by_part(), find_calling_channel(), find_channel_by_group(), find_details(), find_or_create_details(), find_transaction(), findmeexec(), frame_trace_helper(), func_channel_read(), func_channel_write_real(), func_channels_read(), func_header_read(), func_inheritance_write(), func_mute_write(), function_agent(), function_sipchaninfo_read(), generator_force(), generic_fax_exec(), get_agi_cmd(), get_cid_name(), handle_chanlist(), handle_cli_agi_add_cmd(), handle_cli_mixmonitor(), handle_invite_replaces(), handle_request_bye(), handle_request_refer(), handle_showchan(), handle_softhangup(), import_ch(), import_helper(), init_jack_data(), jack_hook_callback(), leave_voicemail(), linkedid_match(), listfilter(), local_ast_moh_stop(), local_call(), local_hangup(), local_queryoption(), local_queue_frame(), local_read(), local_setoption(), login_exec(), lua_get_state(), manage_parked_call(), manager_mutestream(), mark_transaction_active(), minivm_delete_exec(), minivm_notify_exec(), misdn_answer(), misdn_attempt_transfer(), misdn_update_caller_id(), moh_files_generator(), morsecode_exec(), mute_callback(), my_handle_dtmf(), notify_new_message(), park_call_full(), parkandannounce_exec(), parked_call_exec(), pbx_builtin_background(), pbx_builtin_getvar_helper(), pbx_builtin_gotoiftime(), pbx_builtin_pushvar_helper(), pbx_builtin_serialize_variables(), pbx_builtin_setamaflags(), pbx_builtin_setvar_helper(), peek_read(), pickup_by_exten(), pickup_by_name_cb(), pitchshift_helper(), process_sdp(), queue_exec(), receivefax_exec(), redirecting_read(), redirecting_write(), release_transaction(), report_fax_status(), retrydial_exec(), run_agi(), sendfax_exec(), sendtext_exec(), set_ext_pri(), set_format(), set_security_requirements(), setup_inheritance_datastore(), setup_mixmonitor_ds(), setup_transfer_datastore(), shared_read(), shared_write(), sip_addheader(), sip_dtmfmode(), sip_new(), sip_pvt_lock_full(), sip_read(), sip_removeheader(), sip_set_rtp_peer(), sip_set_udptl_peer(), smdi_msg_read(), smdi_msg_retrieve_read(), softhangup_exec(), speech_background(), speex_read(), speex_write(), srv_datastore_setup(), srv_query_read(), srv_result_read(), ss7_start_call(), start_monitor_action(), start_monitor_exec(), state_notify_build_xml(), stop_mixmonitor_exec(), transmit_invite(), try_calling(), update_bridge_vars(), volume_write(), and wait_for_answer().
#define ast_channel_lock_both | ( | chan1, | |||
chan2 | ) |
Lock two channels.
Definition at line 2440 of file channel.h.
Referenced by __ast_channel_masquerade(), __ast_request_and_dial(), ast_bridge_call(), ast_call_forward(), call_forward_inherit(), dial_transfer(), do_bridge_masquerade(), findmeexec(), and ring_entry().
#define AST_CHANNEL_NAME 80 |
Max length of an ast_channel name
Definition at line 137 of file channel.h.
Referenced by ast_bridge_call(), ast_cc_call_failed(), ast_cc_is_recall(), ast_channel_destructor(), ast_do_masquerade(), ast_parse_device_state(), ast_queue_cc_frame(), ast_setstate(), cc_core_init_instance(), cc_unique_append(), cccancel_exec(), ccreq_exec(), common_exec(), create_jb(), dahdi_cc_callback(), dahdi_new(), dial_exec_full(), fast_originate(), page_exec(), park_call_full(), sig_pri_call(), sig_pri_cc_available(), sig_pri_cc_generic_check(), sip_call(), sip_handle_cc(), and softhangup_exec().
#define ast_channel_ref | ( | c | ) | ({ ao2_ref(c, +1); (c); }) |
Increase channel reference count.
c | the channel |
c | always |
Definition at line 2458 of file channel.h.
Referenced by agent_hangup(), agent_lock_owner(), ast_autochan_new_channel(), ast_autochan_setup(), ast_cel_report_event(), awesome_locking(), check_bridge(), handle_getvariablefull(), handle_incoming(), handle_invite_replaces(), handle_request_refer(), local_attended_transfer(), local_queryoption(), local_queue_frame(), local_setoption(), sip_pickup(), sip_pvt_lock_full(), and socket_process().
#define ast_channel_trylock | ( | chan | ) | ao2_trylock(chan) |
Definition at line 2435 of file channel.h.
Referenced by __ast_channel_masquerade(), __oh323_rtp_create(), agent_indicate(), agent_logoff(), agent_read(), analog_lock_sub_owner(), ast_do_masquerade(), ast_queue_hangup(), ast_queue_hangup_with_cause(), ast_rtp_instance_bridge(), ast_rtp_instance_early_bridge(), ast_rtp_instance_early_bridge_make_compatible(), ast_udptl_bridge(), ast_write(), auto_congest(), bridge_queue_hangup(), bridge_write(), check_bridge(), check_rtp_timeout(), cleanup_connection(), dahdi_bridge(), dahdi_handle_event(), dahdi_lock_sub_owner(), dahdi_queue_frame(), dahdi_softhangup_all(), dial_exec_full(), do_forward(), get_sip_pvt_byid_locked(), grab_owner(), handle_request_bye(), hangup_connection(), iax2_destroy(), iax2_lock_owner(), mgcp_queue_frame(), mgcp_queue_hangup(), misdn_attempt_transfer(), oh323_rtp_read(), oh323_simulate_dtmf_end(), proc_session_timer(), receive_digit(), release_chan(), release_chan_early(), remote_hold(), retrans_pkt(), setup_rtp_connection(), sig_pri_lock_owner(), sig_ss7_lock_owner(), sip_hangup(), sip_reinvite_retry(), and update_state().
#define ast_channel_unlock | ( | chan | ) | ao2_unlock(chan) |
Definition at line 2434 of file channel.h.
Referenced by __analog_handle_event(), __ast_answer(), __ast_channel_masquerade(), __ast_pbx_run(), __ast_queue_frame(), __ast_read(), __ast_request_and_dial(), __oh323_destroy(), __oh323_rtp_create(), __sip_autodestruct(), __sip_destroy(), _macro_exec(), _while_exec(), acf_cc_read(), acf_cc_write(), acf_fetch(), action_add_agi_cmd(), action_agents(), action_coreshowchannels(), action_hangup(), action_redirect(), action_timeout(), add_features_datastores(), add_to_agi(), agent_hangup(), agent_indicate(), agent_lock_owner(), agent_logoff(), agent_read(), agents_data_provider_get(), agents_show(), agents_show_online(), alsa_call(), analog_attempt_transfer(), analog_hangup(), app_exec(), ast_activate_generator(), ast_async_goto(), ast_audiohook_attach(), ast_audiohook_detach_source(), ast_audiohook_remove(), ast_audiohook_set_mute(), ast_autochan_destroy(), ast_autochan_setup(), ast_autoservice_start(), ast_autoservice_stop(), ast_bridge_call(), ast_bridge_timelimit(), ast_call(), ast_call_forward(), 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_cel_report_event(), ast_change_name(), ast_channel_clear_softhangup(), ast_channel_cmp_cb(), ast_channel_connected_line_macro(), ast_channel_destructor(), ast_channel_queryoption(), ast_channel_redirecting_macro(), ast_channel_set_caller(), ast_channel_set_caller_event(), ast_channel_set_connected_line(), ast_channel_set_redirecting(), ast_channel_setoption(), ast_check_hangup_locked(), ast_complete_channels(), ast_deactivate_generator(), ast_dial_join(), ast_do_masquerade(), ast_do_pickup(), ast_eivr_getvariable(), ast_explicit_goto(), ast_handle_cc_control_frame(), ast_hangup(), ast_ignore_cc(), ast_indicate_data(), ast_odbc_retrieve_transaction_obj(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pickup_call(), ast_queue_hangup(), ast_queue_hangup_with_cause(), ast_raw_answer(), ast_read_generator_actions(), ast_rtp_instance_bridge(), ast_rtp_instance_early_bridge(), ast_rtp_instance_early_bridge_make_compatible(), ast_rtp_instance_make_compatible(), ast_safe_sleep_conditional(), ast_sendtext(), ast_set_callerid(), ast_set_cc_interfaces_chanvar(), ast_set_hangupsource(), ast_settimeout(), ast_setup_cc_recall_datastore(), ast_softhangup(), ast_stopstream(), ast_str_retrieve_variable(), ast_transfer(), ast_udptl_bridge(), ast_var_channel_bridge(), ast_var_channels_table(), ast_waitfor_nandfds(), ast_write(), attempt_transfer(), auto_congest(), bridge_play_sounds(), bridge_queue_hangup(), bridge_write(), builtin_atxfer(), builtin_automixmonitor(), builtin_blindtransfer(), calendar_event_read(), calendar_query_exec(), calendar_query_result_exec(), call_forward_inherit(), callerid_read(), callerid_write(), cb_events(), cc_build_payload(), cc_interfaces_datastore_init(), cdr_read(), cdr_write(), channel_set_debug(), channel_spy(), check_bridge(), check_goto_on_transfer(), check_rtp_timeout(), cleanup_connection(), clear_caller(), clear_dialed_interfaces(), common_exec(), conf_run(), conf_start_moh(), confbridge_exec(), connectedline_read(), connectedline_write(), console_answer(), console_hangup(), console_sendtext(), create_dynamic_parkinglot(), crement_function_read(), dahdi_bridge(), dahdi_handle_dtmf(), dahdi_handle_event(), dahdi_queue_frame(), dahdi_softhangup_all(), data_channels_provider_handler(), dial_exec_full(), dial_transfer(), dialog_unlink_all(), disable_jack_hook(), do_bridge_masquerade(), do_forward(), dundi_query_read(), dundi_result_read(), enable_jack_hook(), end_bridge_callback(), enum_query_read(), enum_result_read(), exec_odbcfinish(), fast_originate(), feature_check(), feature_interpret(), feature_request_and_dial(), find_by_mark(), find_by_part(), find_calling_channel(), find_channel_by_group(), find_details(), find_or_create_details(), find_transaction(), findmeexec(), frame_trace_helper(), func_channel_read(), func_channel_write_real(), func_channels_read(), func_header_read(), func_inheritance_write(), func_mute_write(), function_agent(), function_sipchaninfo_read(), generator_force(), generic_fax_exec(), get_agi_cmd(), get_cid_name(), handle_chanlist(), handle_cli_agi_add_cmd(), handle_cli_mixmonitor(), handle_incoming(), handle_invite_replaces(), handle_request_bye(), handle_request_do(), handle_request_invite(), handle_request_refer(), handle_showchan(), handle_softhangup(), hangup_connection(), iax2_destroy(), iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), import_ch(), import_helper(), init_jack_data(), jack_hook_callback(), leave_voicemail(), linkedid_match(), listfilter(), local_ast_moh_stop(), local_attended_transfer(), local_bridge_loop(), local_call(), local_hangup(), local_queryoption(), local_queue_frame(), local_read(), local_setoption(), login_exec(), lua_get_state(), manage_parked_call(), manager_mutestream(), mark_transaction_active(), mgcp_pktcgate_remove(), mgcp_queue_frame(), mgcp_queue_hangup(), minivm_delete_exec(), minivm_notify_exec(), misdn_answer(), misdn_attempt_transfer(), misdn_update_caller_id(), moh_files_generator(), morsecode_exec(), mute_callback(), my_handle_dtmf(), notify_new_message(), oh323_rtp_read(), oh323_simulate_dtmf_end(), park_call_full(), parkandannounce_exec(), parked_call_exec(), pbx_builtin_background(), pbx_builtin_getvar_helper(), pbx_builtin_gotoiftime(), pbx_builtin_pushvar_helper(), pbx_builtin_serialize_variables(), pbx_builtin_setamaflags(), pbx_builtin_setvar_helper(), peek_read(), pickup_by_channel(), pickup_by_exten(), pickup_by_group(), pickup_by_mark(), pickup_by_name_cb(), pickup_by_part(), pitchshift_helper(), pri_fixup_principle(), pri_queue_frame(), proc_session_timer(), process_sdp(), queue_exec(), receive_digit(), receivefax_exec(), redirecting_read(), redirecting_write(), release_chan(), release_chan_early(), release_transaction(), remote_bridge_loop(), remote_hold(), report_fax_status(), retrans_pkt(), retrydial_exec(), ring_entry(), run_agi(), schedule_delivery(), send_provisional_keepalive_full(), sendfax_exec(), sendtext_exec(), set_ext_pri(), set_format(), set_hangup_source_and_cause(), set_security_requirements(), setup_inheritance_datastore(), setup_mixmonitor_ds(), setup_rtp_connection(), setup_transfer_datastore(), shared_read(), shared_write(), sig_pri_attempt_transfer(), sig_pri_cc_generic_check(), sig_pri_cli_show_channels(), sig_pri_handle_hold(), sig_pri_handle_subcmds(), sig_pri_send_aoce_termination_request(), sig_ss7_cli_show_channels(), sig_ss7_queue_frame(), sip_addheader(), sip_dtmfmode(), sip_hangup(), sip_new(), sip_pvt_lock_full(), sip_read(), sip_reinvite_retry(), sip_removeheader(), sip_request_call(), sip_set_rtp_peer(), sip_set_udptl_peer(), smdi_msg_read(), smdi_msg_retrieve_read(), socket_process(), softhangup_exec(), speech_background(), speex_read(), speex_write(), srv_datastore_setup(), srv_query_read(), srv_result_read(), ss7_start_call(), start_monitor_action(), start_monitor_exec(), state_notify_build_xml(), stop_mixmonitor_exec(), transmit_invite(), try_calling(), update_bridge_vars(), update_state(), volume_write(), wait_for_answer(), and wakeup_sub().
#define ast_channel_unref | ( | c | ) | ({ ao2_ref(c, -1); (struct ast_channel *) (NULL); }) |
Decrease channel reference count.
c | the channel |
NULL | always |
Definition at line 2469 of file channel.h.
Referenced by __ast_channel_alloc_ap(), __sip_autodestruct(), acf_odbc_read(), acf_odbc_write(), action_add_agi_cmd(), action_agents(), action_aocmessage(), action_atxfer(), action_bridge(), action_coreshowchannels(), action_getvar(), action_hangup(), action_redirect(), action_sendtext(), action_setvar(), action_timeout(), agent_hangup(), agent_lock_owner(), agent_logoff(), agent_read(), agents_data_provider_get(), agents_show(), agents_show_online(), ast_add_extension2_lockopt(), ast_async_goto_by_name(), ast_autochan_destroy(), ast_autochan_new_channel(), ast_bridge_call(), ast_cel_check_retire_linkedid(), ast_cel_fabricate_channel_from_event(), ast_cel_report_event(), ast_channel_release(), ast_complete_channels(), ast_dummy_channel_alloc(), ast_hangup(), ast_parse_device_state(), ast_pbx_outgoing_cdr_failed(), ast_pickup_call(), ast_str_substitute_variables_full(), ast_var_channel_bridge(), ast_var_channel_types_table(), ast_var_channels_table(), asyncgoto_exec(), bridge_exec(), change_monitor_action(), check_bridge(), common_exec(), custom_log(), data_channels_provider_handler(), dialog_unlink_all(), do_pause_or_unpause(), func_channels_read(), func_mchan_read(), func_mchan_write(), handle_chanlist(), handle_channelstatus(), handle_cli_agi_add_cmd(), handle_cli_mixmonitor(), handle_core_set_debug_channel(), handle_getvariablefull(), handle_hangup(), handle_incoming(), handle_invite_replaces(), handle_redirect(), handle_request_do(), handle_request_refer(), handle_set_chanvar(), handle_show_chanvar(), handle_showchan(), handle_softhangup(), import_helper(), local_attended_transfer(), local_call(), local_hangup(), local_queryoption(), local_queue_frame(), local_setoption(), make_email_file(), manager_log(), manager_mute_mixmonitor(), manager_mutestream(), manager_optimize_away(), manager_park(), manager_play_dtmf(), next_channel(), park_call_full(), pbx_builtin_importvar(), pbx_substitute_variables_helper_full(), pickup_by_channel(), pickup_by_exten(), pickup_by_group(), pickup_by_mark(), pickup_by_part(), rotate_file(), send_provisional_keepalive_full(), senddtmf_exec(), sendmail(), sendpage(), shared_read(), shared_write(), sip_pickup(), sip_pickup_thread(), sip_pvt_lock_full(), socket_process(), softhangup_exec(), start_monitor_action(), state_notify_build_xml(), stop_monitor_action(), syslog_log(), and write_cdr().
#define AST_GENERATOR_FD (AST_MAX_FDS-4) |
used by generator
Definition at line 166 of file channel.h.
Referenced by __ast_read(), ast_deactivate_generator(), and ast_do_masquerade().
#define AST_MAX_CONTEXT 80 |
Max length of a context
Definition at line 136 of file channel.h.
Referenced by _macro_exec(), aji_publish_mwi(), ast_bridge_call(), cleanup_stale_contexts(), common_exec(), conf_run(), config_parse_variables(), dial_transfer(), do_magic_pickup(), gtalk_load_config(), handle_gosub(), handle_request_invite(), handle_statechange(), park_call_full(), parkinglot_activate(), reload_config(), and try_calling().
#define AST_MAX_EXTENSION 80 |
Max length of an extension
Definition at line 135 of file channel.h.
Referenced by __analog_ss_thread(), __ast_context_destroy(), add_extensions(), advanced_options(), aji_publish_mwi(), analog_ss_thread(), ast_bridge_call(), ast_device_state_changed(), ast_devstate_changed(), ast_ivr_menu_run_internal(), begin_dial_channel(), build_device(), cc_extension_monitor_init(), conf_run(), destroy_space(), destroy_station(), dial_exec_full(), dial_transfer(), disa_exec(), do_magic_pickup(), dundi_lookup_local(), feature_attended_transfer(), feature_blind_transfer(), find_conf_realtime(), forward_message(), function_enum(), get_destination(), handle_gosub(), handle_request_invite(), handle_statechange(), load_module(), log_exec(), manage_parked_call(), manager_show_dialplan_helper(), mgcp_ss(), park_add_hints(), park_call_exec(), park_call_full(), phone_check_exception(), pri_dchannel(), pri_ss_thread(), realtime_common(), realtime_switch_common(), search_directory_sub(), show_dialplan_helper(), sig_pri_party_number_convert(), skinny_extensionstate_cb(), skinny_ss(), speech_background(), state_notify_build_xml(), try_calling(), vm_authenticate(), and vmauthenticate().
#define AST_MAX_FDS 10 |
Definition at line 158 of file channel.h.
Referenced by ast_channel_destructor(), ast_do_masquerade(), ast_poll_channel_add(), ast_poll_channel_del(), and ast_waitfor_nandfds().
#define AST_TIMING_FD (AST_MAX_FDS-2) |
used for timingfd
Definition at line 164 of file channel.h.
Referenced by __ast_channel_alloc_ap(), __ast_read(), agent_read(), and ast_do_masquerade().
#define CHECK_BLOCKING | ( | c | ) |
Definition at line 2394 of file channel.h.
Referenced by ast_sendtext(), ast_waitfor_nandfds(), ast_write(), dahdi_read(), and phone_read().
#define DATASTORE_INHERIT_FOREVER INT_MAX |
Definition at line 156 of file channel.h.
Referenced by _macro_exec(), acf_iaxvar_write(), add_features_datastores(), ast_channel_datastore_inherit(), ast_iax2_new(), ast_setup_cc_recall_datastore(), authenticate_reply(), calendar_query_exec(), cc_interfaces_datastore_init(), dial_exec_full(), do_notify(), and socket_process().
#define DEBUGCHAN_FLAG 0x80000000 |
The high bit of the frame count is used as a debug marker, so increments of the counters must be done with care. Please use c->fin = FRAMECOUNT_INC(c->fin) and the same for c->fout.
Definition at line 642 of file channel.h.
Referenced by __ast_read(), ast_write(), channel_set_debug(), handle_core_set_debug_channel(), handle_showchan(), and serialize_showchan().
#define FRAMECOUNT_INC | ( | x | ) | ( ((x) & DEBUGCHAN_FLAG) | (((x)+1) & ~DEBUGCHAN_FLAG) ) |
#define MAX_LANGUAGE 40 |
#define MAX_MUSICCLASS 80 |
typedef int(*) ast_acf_read2_fn_t(struct ast_channel *, const char *, char *, struct ast_str **, ssize_t) |
typedef int(*) ast_acf_read_fn_t(struct ast_channel *, const char *, char *, char *, size_t) |
typedef int(*) ast_acf_write_fn_t(struct ast_channel *, const char *, char *, const char *) |
typedef unsigned long long ast_group_t |
anonymous enum |
ast_channel_tech Properties
Definition at line 870 of file channel.h.
00870 { 00871 /*! 00872 * \brief Channels have this property if they can accept input with jitter; 00873 * i.e. most VoIP channels 00874 */ 00875 AST_CHAN_TP_WANTSJITTER = (1 << 0), 00876 /*! 00877 * \brief Channels have this property if they can create jitter; 00878 * i.e. most VoIP channels 00879 */ 00880 AST_CHAN_TP_CREATESJITTER = (1 << 1), 00881 };
anonymous enum |
ast_channel flags
Definition at line 884 of file channel.h.
00884 { 00885 /*! Queue incoming DTMF, to be released when this flag is turned off */ 00886 AST_FLAG_DEFER_DTMF = (1 << 1), 00887 /*! write should be interrupt generator */ 00888 AST_FLAG_WRITE_INT = (1 << 2), 00889 /*! a thread is blocking on this channel */ 00890 AST_FLAG_BLOCKING = (1 << 3), 00891 /*! This is a zombie channel */ 00892 AST_FLAG_ZOMBIE = (1 << 4), 00893 /*! There is an exception pending */ 00894 AST_FLAG_EXCEPTION = (1 << 5), 00895 /*! Listening to moh XXX anthm promises me this will disappear XXX */ 00896 AST_FLAG_MOH = (1 << 6), 00897 /*! This channel is spying on another channel */ 00898 AST_FLAG_SPYING = (1 << 7), 00899 /*! This channel is in a native bridge */ 00900 AST_FLAG_NBRIDGE = (1 << 8), 00901 /*! the channel is in an auto-incrementing dialplan processor, 00902 * so when ->priority is set, it will get incremented before 00903 * finding the next priority to run */ 00904 AST_FLAG_IN_AUTOLOOP = (1 << 9), 00905 /*! This is an outgoing call */ 00906 AST_FLAG_OUTGOING = (1 << 10), 00907 /*! A DTMF_BEGIN frame has been read from this channel, but not yet an END */ 00908 AST_FLAG_IN_DTMF = (1 << 12), 00909 /*! A DTMF_END was received when not IN_DTMF, so the length of the digit is 00910 * currently being emulated */ 00911 AST_FLAG_EMULATE_DTMF = (1 << 13), 00912 /*! This is set to tell the channel not to generate DTMF begin frames, and 00913 * to instead only generate END frames. */ 00914 AST_FLAG_END_DTMF_ONLY = (1 << 14), 00915 /*! Flag to show channels that this call is hangup due to the fact that the call 00916 was indeed answered, but in another channel */ 00917 AST_FLAG_ANSWERED_ELSEWHERE = (1 << 15), 00918 /*! This flag indicates that on a masquerade, an active stream should not 00919 * be carried over */ 00920 AST_FLAG_MASQ_NOSTREAM = (1 << 16), 00921 /*! This flag indicates that the hangup exten was run when the bridge terminated, 00922 * a message aimed at preventing a subsequent hangup exten being run at the pbx_run 00923 * level */ 00924 AST_FLAG_BRIDGE_HANGUP_RUN = (1 << 17), 00925 /*! This flag indicates that the hangup exten should NOT be run when the 00926 * bridge terminates, this will allow the hangup in the pbx loop to be run instead. 00927 * */ 00928 AST_FLAG_BRIDGE_HANGUP_DONT = (1 << 18), 00929 /*! Disable certain workarounds. This reintroduces certain bugs, but allows 00930 * some non-traditional dialplans (like AGI) to continue to function. 00931 */ 00932 AST_FLAG_DISABLE_WORKAROUNDS = (1 << 20), 00933 };
anonymous enum |
ast_bridge_config flags
Definition at line 936 of file channel.h.
00936 { 00937 AST_FEATURE_PLAY_WARNING = (1 << 0), 00938 AST_FEATURE_REDIRECT = (1 << 1), 00939 AST_FEATURE_DISCONNECT = (1 << 2), 00940 AST_FEATURE_ATXFER = (1 << 3), 00941 AST_FEATURE_AUTOMON = (1 << 4), 00942 AST_FEATURE_PARKCALL = (1 << 5), 00943 AST_FEATURE_AUTOMIXMON = (1 << 6), 00944 AST_FEATURE_NO_H_EXTEN = (1 << 7), 00945 AST_FEATURE_WARNING_ACTIVE = (1 << 8), 00946 };
anonymous enum |
Definition at line 984 of file channel.h.
00984 { 00985 /*! 00986 * Soft hangup requested by device or other internal reason. 00987 * Actual hangup needed. 00988 */ 00989 AST_SOFTHANGUP_DEV = (1 << 0), 00990 /*! 00991 * Used to break the normal frame flow so an async goto can be 00992 * done instead of actually hanging up. 00993 */ 00994 AST_SOFTHANGUP_ASYNCGOTO = (1 << 1), 00995 /*! 00996 * Soft hangup requested by system shutdown. Actual hangup 00997 * needed. 00998 */ 00999 AST_SOFTHANGUP_SHUTDOWN = (1 << 2), 01000 /*! 01001 * Used to break the normal frame flow after a timeout so an 01002 * implicit async goto can be done to the 'T' exten if it exists 01003 * instead of actually hanging up. If the exten does not exist 01004 * then actually hangup. 01005 */ 01006 AST_SOFTHANGUP_TIMEOUT = (1 << 3), 01007 /*! 01008 * Soft hangup requested by application/channel-driver being 01009 * unloaded. Actual hangup needed. 01010 */ 01011 AST_SOFTHANGUP_APPUNLOAD = (1 << 4), 01012 /*! 01013 * Soft hangup requested by non-associated party. Actual hangup 01014 * needed. 01015 */ 01016 AST_SOFTHANGUP_EXPLICIT = (1 << 5), 01017 /*! 01018 * Used to break a bridge so the channel can be spied upon 01019 * instead of actually hanging up. 01020 */ 01021 AST_SOFTHANGUP_UNBRIDGE = (1 << 6), 01022 01023 01024 /*! 01025 * \brief All softhangup flags. 01026 * 01027 * This can be used as an argument to ast_channel_softhangup_clear 01028 * to clear all softhangup flags from a channel. 01029 */ 01030 AST_SOFTHANGUP_ALL = (0xFFFFFFFF) 01031 };
enum ast_bridge_result |
Definition at line 168 of file channel.h.
00168 { 00169 AST_BRIDGE_COMPLETE = 0, 00170 AST_BRIDGE_FAILED = -1, 00171 AST_BRIDGE_FAILED_NOWARN = -2, 00172 AST_BRIDGE_RETRY = -3, 00173 };
enum ast_channel_adsicpe |
Definition at line 653 of file channel.h.
00653 { 00654 AST_ADSI_UNKNOWN, 00655 AST_ADSI_AVAILABLE, 00656 AST_ADSI_UNAVAILABLE, 00657 AST_ADSI_OFFHOOKONLY, 00658 };
enum AST_PARTY_CHAR_SET |
Party name character set enumeration values (values from Q.SIG)
Definition at line 192 of file channel.h.
00192 { 00193 AST_PARTY_CHAR_SET_UNKNOWN = 0, 00194 AST_PARTY_CHAR_SET_ISO8859_1 = 1, 00195 AST_PARTY_CHAR_SET_WITHDRAWN = 2,/* ITU withdrew this enum value. */ 00196 AST_PARTY_CHAR_SET_ISO8859_2 = 3, 00197 AST_PARTY_CHAR_SET_ISO8859_3 = 4, 00198 AST_PARTY_CHAR_SET_ISO8859_4 = 5, 00199 AST_PARTY_CHAR_SET_ISO8859_5 = 6, 00200 AST_PARTY_CHAR_SET_ISO8859_7 = 7, 00201 AST_PARTY_CHAR_SET_ISO10646_BMPSTRING = 8, 00202 AST_PARTY_CHAR_SET_ISO10646_UTF_8STRING = 9, 00203 };
enum ast_t38_state |
Possible T38 states on channels.
Definition at line 663 of file channel.h.
00663 { 00664 T38_STATE_UNAVAILABLE, /*!< T38 is unavailable on this channel or disabled by configuration */ 00665 T38_STATE_UNKNOWN, /*!< The channel supports T38 but the current status is unknown */ 00666 T38_STATE_NEGOTIATING, /*!< T38 is being negotiated */ 00667 T38_STATE_REJECTED, /*!< Remote side has rejected our offer */ 00668 T38_STATE_NEGOTIATED, /*!< T38 established */ 00669 };
enum channelreloadreason |
Channel reload reasons for manager events at load or reload of configuration.
Definition at line 1035 of file channel.h.
01035 { 01036 CHANNEL_MODULE_LOAD, 01037 CHANNEL_MODULE_RELOAD, 01038 CHANNEL_CLI_RELOAD, 01039 CHANNEL_MANAGER_RELOAD, 01040 };
int __ast_answer | ( | struct ast_channel * | chan, | |
unsigned int | delay, | |||
int | cdr_answer | |||
) |
Answer a channel, with a selectable delay before returning.
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 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.
0 | on success | |
non-zero | on failure |
Definition at line 2923 of file channel.c.
References ast_channel::_state, ast_channel_lock, ast_channel_unlock, AST_CONTROL_HANGUP, ast_debug, AST_FRAME_CNG, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_HTML, AST_FRAME_IAX, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_frisolate(), AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_HEAD_NOLOCK, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_HEAD, ast_log(), ast_queue_frame_head(), ast_raw_answer(), ast_read(), AST_STATE_RING, AST_STATE_RINGING, ast_waitfor(), chanlist::chan, errno, frames, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, MAX, ast_channel::name, and ast_frame::subclass.
Referenced by ast_answer(), pbx_builtin_answer(), and pbx_builtin_incomplete().
02924 { 02925 int res = 0; 02926 enum ast_channel_state old_state; 02927 02928 old_state = chan->_state; 02929 if ((res = ast_raw_answer(chan, cdr_answer))) { 02930 return res; 02931 } 02932 02933 switch (old_state) { 02934 case AST_STATE_RINGING: 02935 case AST_STATE_RING: 02936 /* wait for media to start flowing, but don't wait any longer 02937 * than 'delay' or 500 milliseconds, whichever is longer 02938 */ 02939 do { 02940 AST_LIST_HEAD_NOLOCK(, ast_frame) frames; 02941 struct ast_frame *cur, *new; 02942 int ms = MAX(delay, 500); 02943 unsigned int done = 0; 02944 02945 AST_LIST_HEAD_INIT_NOLOCK(&frames); 02946 02947 for (;;) { 02948 ms = ast_waitfor(chan, ms); 02949 if (ms < 0) { 02950 ast_log(LOG_WARNING, "Error condition occurred when polling channel %s for a voice frame: %s\n", chan->name, strerror(errno)); 02951 res = -1; 02952 break; 02953 } 02954 if (ms == 0) { 02955 ast_debug(2, "Didn't receive a media frame from %s within %d ms of answering. Continuing anyway\n", chan->name, MAX(delay, 500)); 02956 break; 02957 } 02958 cur = ast_read(chan); 02959 if (!cur || ((cur->frametype == AST_FRAME_CONTROL) && 02960 (cur->subclass.integer == AST_CONTROL_HANGUP))) { 02961 if (cur) { 02962 ast_frfree(cur); 02963 } 02964 res = -1; 02965 ast_debug(2, "Hangup of channel %s detected in answer routine\n", chan->name); 02966 break; 02967 } 02968 02969 if ((new = ast_frisolate(cur)) != cur) { 02970 ast_frfree(cur); 02971 } 02972 02973 AST_LIST_INSERT_HEAD(&frames, new, frame_list); 02974 02975 /* if a specific delay period was requested, continue 02976 * until that delay has passed. don't stop just because 02977 * incoming media has arrived. 02978 */ 02979 if (delay) { 02980 continue; 02981 } 02982 02983 switch (new->frametype) { 02984 /* all of these frametypes qualify as 'media' */ 02985 case AST_FRAME_VOICE: 02986 case AST_FRAME_VIDEO: 02987 case AST_FRAME_TEXT: 02988 case AST_FRAME_DTMF_BEGIN: 02989 case AST_FRAME_DTMF_END: 02990 case AST_FRAME_IMAGE: 02991 case AST_FRAME_HTML: 02992 case AST_FRAME_MODEM: 02993 done = 1; 02994 break; 02995 case AST_FRAME_CONTROL: 02996 case AST_FRAME_IAX: 02997 case AST_FRAME_NULL: 02998 case AST_FRAME_CNG: 02999 break; 03000 } 03001 03002 if (done) { 03003 break; 03004 } 03005 } 03006 03007 if (res == 0) { 03008 ast_channel_lock(chan); 03009 while ((cur = AST_LIST_REMOVE_HEAD(&frames, frame_list))) { 03010 ast_queue_frame_head(chan, cur); 03011 ast_frfree(cur); 03012 } 03013 ast_channel_unlock(chan); 03014 } 03015 } while (0); 03016 break; 03017 default: 03018 break; 03019 } 03020 03021 return res; 03022 }
struct ast_channel* attribute_malloc __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.
NULL | failure | |
non-NULL | successfully allocated channel |
By default, new channels are set to the "s" extension and "default" context.
Definition at line 1344 of file channel.c.
References __ast_channel_alloc_ap().
01350 { 01351 va_list ap1, ap2; 01352 struct ast_channel *result; 01353 01354 va_start(ap1, name_fmt); 01355 va_start(ap2, name_fmt); 01356 result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context, 01357 linkedid, amaflag, file, line, function, name_fmt, ap1, ap2); 01358 va_end(ap1); 01359 va_end(ap2); 01360 01361 return result; 01362 }
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.
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 |
Definition at line 5306 of file channel.c.
References ast_channel::_state, outgoing_helper::account, ast_call(), ast_call_forward(), AST_CAUSE_NO_ANSWER, ast_cdr_alloc(), ast_cdr_answer(), ast_cdr_busy(), ast_cdr_disposition(), ast_cdr_end(), ast_cdr_failed(), AST_CDR_FLAG_ORIGINATED, ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_setapp(), ast_cdr_start(), ast_cdr_update(), ast_channel_datastore_inherit(), ast_channel_inherit_variables(), ast_channel_lock, ast_channel_lock_both, ast_channel_set_connected_line(), ast_channel_unlock, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CC, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_copy_string(), AST_FRAME_CONTROL, ast_frfree, ast_hangup(), ast_log(), ast_party_connected_line_set_init(), AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, ast_read(), ast_request(), ast_set_callerid(), ast_set_flag, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_waitfor(), ast_channel::call_forward, cause, ast_channel::cdr, chanlist::chan, outgoing_helper::cid_name, outgoing_helper::cid_num, chanlist::connected, ast_channel::connected, outgoing_helper::context, ast_channel::context, outgoing_helper::exten, ast_channel::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_number::presentation, ast_party_name::presentation, outgoing_helper::priority, ast_channel::priority, ast_party_number::str, ast_party_name::str, ast_party_number::valid, ast_party_name::valid, and outgoing_helper::vars.
Referenced by ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_request_and_dial(), and parkandannounce_exec().
05307 { 05308 int dummy_outstate; 05309 int cause = 0; 05310 struct ast_channel *chan; 05311 int res = 0; 05312 int last_subclass = 0; 05313 struct ast_party_connected_line connected; 05314 05315 if (outstate) 05316 *outstate = 0; 05317 else 05318 outstate = &dummy_outstate; /* make outstate always a valid pointer */ 05319 05320 chan = ast_request(type, format, requestor, data, &cause); 05321 if (!chan) { 05322 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data); 05323 handle_cause(cause, outstate); 05324 return NULL; 05325 } 05326 05327 if (oh) { 05328 if (oh->vars) { 05329 ast_set_variables(chan, oh->vars); 05330 } 05331 if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) { 05332 /* 05333 * Use the oh values instead of the function parameters for the 05334 * outgoing CallerID. 05335 */ 05336 cid_num = oh->cid_num; 05337 cid_name = oh->cid_name; 05338 } 05339 if (oh->parent_channel) { 05340 /* Safely inherit variables and datastores from the parent channel. */ 05341 ast_channel_lock_both(oh->parent_channel, chan); 05342 ast_channel_inherit_variables(oh->parent_channel, chan); 05343 ast_channel_datastore_inherit(oh->parent_channel, chan); 05344 ast_channel_unlock(oh->parent_channel); 05345 ast_channel_unlock(chan); 05346 } 05347 if (oh->account) { 05348 ast_channel_lock(chan); 05349 ast_cdr_setaccount(chan, oh->account); 05350 ast_channel_unlock(chan); 05351 } 05352 } 05353 05354 /* 05355 * I seems strange to set the CallerID on an outgoing call leg 05356 * to whom we are calling, but this function's callers are doing 05357 * various Originate methods. This call leg goes to the local 05358 * user. Once the local user answers, the dialplan needs to be 05359 * able to access the CallerID from the CALLERID function as if 05360 * the local user had placed this call. 05361 */ 05362 ast_set_callerid(chan, cid_num, cid_name, cid_num); 05363 05364 ast_set_flag(chan->cdr, AST_CDR_FLAG_ORIGINATED); 05365 ast_party_connected_line_set_init(&connected, &chan->connected); 05366 if (cid_num) { 05367 connected.id.number.valid = 1; 05368 connected.id.number.str = (char *) cid_num; 05369 connected.id.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 05370 } 05371 if (cid_name) { 05372 connected.id.name.valid = 1; 05373 connected.id.name.str = (char *) cid_name; 05374 connected.id.name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 05375 } 05376 ast_channel_set_connected_line(chan, &connected, NULL); 05377 05378 if (ast_call(chan, data, 0)) { /* ast_call failed... */ 05379 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data); 05380 } else { 05381 res = 1; /* mark success in case chan->_state is already AST_STATE_UP */ 05382 while (timeout && chan->_state != AST_STATE_UP) { 05383 struct ast_frame *f; 05384 res = ast_waitfor(chan, timeout); 05385 if (res == 0) { /* timeout, treat it like ringing */ 05386 *outstate = AST_CONTROL_RINGING; 05387 break; 05388 } 05389 if (res < 0) /* error or done */ 05390 break; 05391 if (timeout > -1) 05392 timeout = res; 05393 if (!ast_strlen_zero(chan->call_forward)) { 05394 if (!(chan = ast_call_forward(NULL, chan, NULL, format, oh, outstate))) { 05395 return NULL; 05396 } 05397 continue; 05398 } 05399 05400 f = ast_read(chan); 05401 if (!f) { 05402 *outstate = AST_CONTROL_HANGUP; 05403 res = 0; 05404 break; 05405 } 05406 if (f->frametype == AST_FRAME_CONTROL) { 05407 switch (f->subclass.integer) { 05408 case AST_CONTROL_RINGING: /* record but keep going */ 05409 *outstate = f->subclass.integer; 05410 break; 05411 05412 case AST_CONTROL_BUSY: 05413 ast_cdr_busy(chan->cdr); 05414 *outstate = f->subclass.integer; 05415 timeout = 0; 05416 break; 05417 05418 case AST_CONTROL_INCOMPLETE: 05419 ast_cdr_failed(chan->cdr); 05420 *outstate = AST_CONTROL_CONGESTION; 05421 timeout = 0; 05422 break; 05423 05424 case AST_CONTROL_CONGESTION: 05425 ast_cdr_failed(chan->cdr); 05426 *outstate = f->subclass.integer; 05427 timeout = 0; 05428 break; 05429 05430 case AST_CONTROL_ANSWER: 05431 ast_cdr_answer(chan->cdr); 05432 *outstate = f->subclass.integer; 05433 timeout = 0; /* trick to force exit from the while() */ 05434 break; 05435 05436 /* Ignore these */ 05437 case AST_CONTROL_PROGRESS: 05438 case AST_CONTROL_PROCEEDING: 05439 case AST_CONTROL_HOLD: 05440 case AST_CONTROL_UNHOLD: 05441 case AST_CONTROL_VIDUPDATE: 05442 case AST_CONTROL_SRCUPDATE: 05443 case AST_CONTROL_SRCCHANGE: 05444 case AST_CONTROL_CONNECTED_LINE: 05445 case AST_CONTROL_REDIRECTING: 05446 case AST_CONTROL_CC: 05447 case -1: /* Ignore -- just stopping indications */ 05448 break; 05449 05450 default: 05451 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass.integer); 05452 } 05453 last_subclass = f->subclass.integer; 05454 } 05455 ast_frfree(f); 05456 } 05457 } 05458 05459 /* Final fixups */ 05460 if (oh) { 05461 if (!ast_strlen_zero(oh->context)) 05462 ast_copy_string(chan->context, oh->context, sizeof(chan->context)); 05463 if (!ast_strlen_zero(oh->exten)) 05464 ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten)); 05465 if (oh->priority) 05466 chan->priority = oh->priority; 05467 } 05468 if (chan->_state == AST_STATE_UP) 05469 *outstate = AST_CONTROL_ANSWER; 05470 05471 if (res <= 0) { 05472 ast_channel_lock(chan); 05473 if (AST_CONTROL_RINGING == last_subclass) { 05474 chan->hangupcause = AST_CAUSE_NO_ANSWER; 05475 } 05476 if (!chan->cdr && (chan->cdr = ast_cdr_alloc())) { 05477 ast_cdr_init(chan->cdr, chan); 05478 } 05479 if (chan->cdr) { 05480 char tmp[256]; 05481 05482 snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data); 05483 ast_cdr_setapp(chan->cdr, "Dial", tmp); 05484 ast_cdr_update(chan); 05485 ast_cdr_start(chan->cdr); 05486 ast_cdr_end(chan->cdr); 05487 /* If the cause wasn't handled properly */ 05488 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) { 05489 ast_cdr_failed(chan->cdr); 05490 } 05491 } 05492 ast_channel_unlock(chan); 05493 ast_hangup(chan); 05494 chan = NULL; 05495 } 05496 return chan; 05497 }
int ast_activate_generator | ( | struct ast_channel * | chan, | |
struct ast_generator * | gen, | |||
void * | params | |||
) |
Activate a given generator
Definition at line 3074 of file channel.c.
References ast_generator::alloc, ast_channel_lock, ast_channel_unlock, ast_prod(), ast_settimeout(), chanlist::chan, gen, ast_channel::generator, generator_force(), ast_channel::generatordata, and ast_generator::release.
Referenced by ast_channel_start_silence_generator(), ast_linear_stream(), ast_playtones_start(), ast_tonepair_start(), channel_spy(), eivr_comm(), old_milliwatt_exec(), and transmit_audio().
03075 { 03076 int res = 0; 03077 03078 ast_channel_lock(chan); 03079 if (chan->generatordata) { 03080 if (chan->generator && chan->generator->release) 03081 chan->generator->release(chan, chan->generatordata); 03082 chan->generatordata = NULL; 03083 } 03084 if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) { 03085 res = -1; 03086 } 03087 if (!res) { 03088 ast_settimeout(chan, 50, generator_force, chan); 03089 chan->generator = gen; 03090 } 03091 ast_channel_unlock(chan); 03092 03093 ast_prod(chan); 03094 03095 return res; 03096 }
int ast_active_channels | ( | void | ) |
returns number of active/allocated channels
Definition at line 832 of file channel.c.
References ao2_container_count(), and channels.
Referenced by action_corestatus(), ast_var_channels(), ast_var_channels_table(), can_safely_quit(), handle_chanlist(), handle_show_settings(), and really_quit().
00833 { 00834 return channels ? ao2_container_count(channels) : 0; 00835 }
static int ast_add_fd | ( | struct pollfd * | pfd, | |
int | fd | |||
) | [inline, static] |
if fd is a valid descriptor, set *pfd with the descriptor
Definition at line 2357 of file channel.h.
Referenced by ast_waitfor_nandfds().
int ast_answer | ( | struct ast_channel * | chan | ) |
Answer a channel.
chan | channel to answer |
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.
0 | on success | |
non-zero | on failure |
Definition at line 3024 of file channel.c.
References __ast_answer(), and chanlist::chan.
Referenced by action_bridge(), agi_exec_full(), alarmreceiver_exec(), answer_trunk_chan(), app_exec(), ast_control_streamfile(), ast_do_pickup(), ast_pickup_call(), auth_exec(), background_detect_exec(), bridge_exec(), builtin_parkcall(), common_exec(), conf_exec(), count_exec(), dahdiras_exec(), dial_exec_full(), dictate_exec(), directory_exec(), disa_exec(), eivr_comm(), handle_answer(), ices_exec(), login_exec(), minivm_accmess_exec(), minivm_greet_exec(), minivm_record_exec(), old_milliwatt_exec(), park_call_exec(), parked_call_exec(), pbx_builtin_background(), playback_exec(), privacy_exec(), read_exec(), readexten_exec(), receivefax_exec(), rpt_exec(), sayunixtime_exec(), send_waveform_to_channel(), sendfax_exec(), setup_privacy_args(), skel_exec(), sla_station_exec(), speech_background(), testclient_exec(), testserver_exec(), transmit(), vm_exec(), vm_execmain(), waitfor_exec(), and zapateller_exec().
03025 { 03026 return __ast_answer(chan, 0, 1); 03027 }
int ast_autoservice_ignore | ( | struct ast_channel * | chan, | |
enum ast_frame_type | ftype | |||
) |
Ignore certain frame types.
0 | success | |
-1 | channel is not in autoservice |
Definition at line 302 of file autoservice.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, asent::chan, asent::ignore_frame_types, and asent::list.
Referenced by builtin_automixmonitor(), feature_exec_app(), and play_message_on_chan().
00303 { 00304 struct asent *as; 00305 int res = -1; 00306 00307 AST_LIST_LOCK(&aslist); 00308 AST_LIST_TRAVERSE(&aslist, as, list) { 00309 if (as->chan == chan) { 00310 res = 0; 00311 as->ignore_frame_types |= (1 << ftype); 00312 break; 00313 } 00314 } 00315 AST_LIST_UNLOCK(&aslist); 00316 return res; 00317 }
int ast_autoservice_start | ( | struct ast_channel * | chan | ) |
Automatically service a channel for us...
0 | success | |
-1 | failure, or the channel is already being autoserviced |
Definition at line 174 of file autoservice.c.
References as_cond, ast_calloc, ast_channel_lock, ast_channel_unlock, ast_cond_signal, AST_FLAG_END_DTMF_ONLY, AST_LIST_EMPTY, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_pthread_create_background, AST_PTHREADT_NULL, ast_set_flag, ast_test_flag, asthread, autoservice_run(), asent::chan, free, asent::list, LOG_WARNING, and asent::use_count.
Referenced by _macro_exec(), acf_curl_helper(), acf_jabberreceive_read(), acf_odbc_read(), acf_odbc_write(), ast_app_run_macro(), ast_dtmf_stream(), ast_get_enum(), ast_get_srv(), ast_get_txt(), ast_masq_park_call_exten(), ast_park_call_exten(), bridge_playfile(), builtin_atxfer(), builtin_automixmonitor(), builtin_blindtransfer(), conf_play(), confbridge_exec(), dial_exec_full(), exec(), feature_exec_app(), feature_request_and_dial(), function_realtime_read(), function_realtime_readdestroy(), function_realtime_store(), function_realtime_write(), leave_conference_bridge(), lock_read(), lua_autoservice_start(), lua_get_variable_value(), lua_pbx_exec(), lua_set_variable(), lua_set_variable_value(), originate_exec(), osplookup_exec(), pbx_find_extension(), play_message_on_chan(), post_join_marked(), realtimefield_read(), senddtmf_exec(), shell_helper(), sla_station_exec(), smdi_msg_retrieve_read(), srv_datastore_setup(), system_exec_helper(), and trylock_read().
00175 { 00176 int res = 0; 00177 struct asent *as; 00178 00179 AST_LIST_LOCK(&aslist); 00180 AST_LIST_TRAVERSE(&aslist, as, list) { 00181 if (as->chan == chan) { 00182 as->use_count++; 00183 break; 00184 } 00185 } 00186 AST_LIST_UNLOCK(&aslist); 00187 00188 if (as) { 00189 /* Entry exists, autoservice is already handling this channel */ 00190 return 0; 00191 } 00192 00193 if (!(as = ast_calloc(1, sizeof(*as)))) 00194 return -1; 00195 00196 /* New entry created */ 00197 as->chan = chan; 00198 as->use_count = 1; 00199 00200 ast_channel_lock(chan); 00201 as->orig_end_dtmf_flag = ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY) ? 1 : 0; 00202 if (!as->orig_end_dtmf_flag) 00203 ast_set_flag(chan, AST_FLAG_END_DTMF_ONLY); 00204 ast_channel_unlock(chan); 00205 00206 AST_LIST_LOCK(&aslist); 00207 00208 if (AST_LIST_EMPTY(&aslist) && asthread != AST_PTHREADT_NULL) { 00209 ast_cond_signal(&as_cond); 00210 } 00211 00212 AST_LIST_INSERT_HEAD(&aslist, as, list); 00213 00214 if (asthread == AST_PTHREADT_NULL) { /* need start the thread */ 00215 if (ast_pthread_create_background(&asthread, NULL, autoservice_run, NULL)) { 00216 ast_log(LOG_WARNING, "Unable to create autoservice thread :(\n"); 00217 /* There will only be a single member in the list at this point, 00218 the one we just added. */ 00219 AST_LIST_REMOVE(&aslist, as, list); 00220 free(as); 00221 asthread = AST_PTHREADT_NULL; 00222 res = -1; 00223 } else { 00224 pthread_kill(asthread, SIGURG); 00225 } 00226 } 00227 00228 AST_LIST_UNLOCK(&aslist); 00229 00230 return res; 00231 }
int ast_autoservice_stop | ( | struct ast_channel * | chan | ) |
Stop servicing a channel for us...
chan |
0 | success | |
-1 | error, or the channel has been hungup |
Definition at line 233 of file autoservice.c.
References ast_channel::_softhangup, as_chan_list_state, ast_channel_lock, ast_channel_unlock, ast_clear_flag, AST_FLAG_END_DTMF_ONLY, ast_frfree, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, AST_PTHREADT_NULL, ast_queue_frame_head(), asthread, asent::chan, asent::deferred_frames, f, free, asent::ignore_frame_types, asent::list, asent::orig_end_dtmf_flag, and asent::use_count.
Referenced by _macro_exec(), acf_curl_helper(), acf_jabberreceive_read(), acf_odbc_read(), acf_odbc_write(), array(), ast_app_run_macro(), ast_dtmf_stream(), ast_get_srv(), ast_get_txt(), ast_hangup(), ast_masq_park_call_exten(), ast_park_call_exten(), bridge_playfile(), builtin_atxfer(), builtin_automixmonitor(), conf_play(), confbridge_exec(), dial_exec_full(), exec(), feature_exec_app(), feature_request_and_dial(), finishup(), function_realtime_read(), function_realtime_readdestroy(), function_realtime_store(), function_realtime_write(), leave_conference_bridge(), lock_read(), lua_autoservice_stop(), lua_get_variable_value(), lua_pbx_exec(), lua_set_variable(), lua_set_variable_value(), originate_exec(), osplookup_exec(), pbx_find_extension(), play_message_on_chan(), post_join_marked(), realtimefield_read(), senddtmf_exec(), shell_helper(), sla_station_exec(), smdi_msg_retrieve_read(), srv_datastore_setup(), system_exec_helper(), and trylock_read().
00234 { 00235 int res = -1; 00236 struct asent *as, *removed = NULL; 00237 struct ast_frame *f; 00238 int chan_list_state; 00239 00240 AST_LIST_LOCK(&aslist); 00241 00242 /* Save the autoservice channel list state. We _must_ verify that the channel 00243 * list has been rebuilt before we return. Because, after we return, the channel 00244 * could get destroyed and we don't want our poor autoservice thread to step on 00245 * it after its gone! */ 00246 chan_list_state = as_chan_list_state; 00247 00248 /* Find the entry, but do not free it because it still can be in the 00249 autoservice thread array */ 00250 AST_LIST_TRAVERSE_SAFE_BEGIN(&aslist, as, list) { 00251 if (as->chan == chan) { 00252 as->use_count--; 00253 if (as->use_count < 1) { 00254 AST_LIST_REMOVE_CURRENT(list); 00255 removed = as; 00256 } 00257 break; 00258 } 00259 } 00260 AST_LIST_TRAVERSE_SAFE_END; 00261 00262 if (removed && asthread != AST_PTHREADT_NULL) { 00263 pthread_kill(asthread, SIGURG); 00264 } 00265 00266 AST_LIST_UNLOCK(&aslist); 00267 00268 if (!removed) { 00269 return 0; 00270 } 00271 00272 /* Wait while autoservice thread rebuilds its list. */ 00273 while (chan_list_state == as_chan_list_state) { 00274 usleep(1000); 00275 } 00276 00277 /* Now autoservice thread should have no references to our entry 00278 and we can safely destroy it */ 00279 00280 if (!chan->_softhangup) { 00281 res = 0; 00282 } 00283 00284 if (!as->orig_end_dtmf_flag) { 00285 ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY); 00286 } 00287 00288 ast_channel_lock(chan); 00289 while ((f = AST_LIST_REMOVE_HEAD(&as->deferred_frames, frame_list))) { 00290 if (!((1 << f->frametype) & as->ignore_frame_types)) { 00291 ast_queue_frame_head(chan, f); 00292 } 00293 ast_frfree(f); 00294 } 00295 ast_channel_unlock(chan); 00296 00297 free(as); 00298 00299 return res; 00300 }
void ast_begin_shutdown | ( | int | hangup | ) |
Initiate system shutdown -- prevents new channels from being allocated.
hangup | If "hangup" is non-zero, all existing channels will receive soft hangups |
Definition at line 822 of file channel.c.
References ao2_callback, ast_channel_softhangup_cb(), channels, OBJ_MULTIPLE, and OBJ_NODATA.
Referenced by can_safely_quit().
00823 { 00824 shutting_down = 1; 00825 00826 if (hangup) { 00827 ao2_callback(channels, OBJ_NODATA | OBJ_MULTIPLE, ast_channel_softhangup_cb, NULL); 00828 } 00829 }
Pick the best audio codec.
Pick the best codec Choose the best codec... Uhhh... Yah.
Okay, ulaw is used by all telephony equipment, so start with it
Unless of course, you're a silly European, so then prefer ALAW
G.722 is better then all below, but not as common as the above... so give ulaw and alaw priority
Okay, well, signed linear is easy to translate into other stuff
G.726 is standard ADPCM, in RFC3551 packing order
G.726 is standard ADPCM, in AAL2 packing order
ADPCM has great sound quality and is still pretty easy to translate
Okay, we're down to vocoders now, so pick GSM because it's small and easier to translate and sounds pretty good
iLBC is not too bad
Speex is free, but computationally more expensive than GSM
Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough to use it
G.729a is faster than 723 and slightly less expensive
Down to G.723.1 which is proprietary but at least designed for voice
Definition at line 1041 of file channel.c.
References ARRAY_LEN, AST_FORMAT_ADPCM, AST_FORMAT_ALAW, AST_FORMAT_AUDIO_MASK, AST_FORMAT_G719, AST_FORMAT_G722, AST_FORMAT_G723_1, AST_FORMAT_G726, AST_FORMAT_G726_AAL2, AST_FORMAT_G729A, AST_FORMAT_GSM, AST_FORMAT_ILBC, AST_FORMAT_LPC10, AST_FORMAT_SIREN14, AST_FORMAT_SIREN7, AST_FORMAT_SLINEAR, AST_FORMAT_SLINEAR16, AST_FORMAT_SPEEX, AST_FORMAT_SPEEX16, AST_FORMAT_TESTLAW, AST_FORMAT_ULAW, ast_getformatname_multiple(), ast_log(), LOG_WARNING, and prefs.
Referenced by __oh323_new(), agent_call(), ast_codec_choose(), ast_iax2_new(), ast_speech_new(), bridge_make_compatible(), builtin_atxfer(), echo_exec(), findmeexec(), gtalk_new(), handle_open_receive_channel_ack_message(), iax2_request(), jingle_new(), local_new(), login_exec(), mgcp_new(), multicast_rtp_request(), set_format(), sip_new(), skinny_new(), skinny_set_rtp_peer(), socket_process(), start_rtp(), transmit_connect(), and unistim_new().
01042 { 01043 /* This just our opinion, expressed in code. We are asked to choose 01044 the best codec to use, given no information */ 01045 int x; 01046 static const format_t prefs[] = 01047 { 01048 /*! Okay, ulaw is used by all telephony equipment, so start with it */ 01049 AST_FORMAT_ULAW, 01050 /*! Unless of course, you're a silly European, so then prefer ALAW */ 01051 AST_FORMAT_ALAW, 01052 AST_FORMAT_G719, 01053 AST_FORMAT_SIREN14, 01054 AST_FORMAT_SIREN7, 01055 AST_FORMAT_TESTLAW, 01056 /*! G.722 is better then all below, but not as common as the above... so give ulaw and alaw priority */ 01057 AST_FORMAT_G722, 01058 /*! Okay, well, signed linear is easy to translate into other stuff */ 01059 AST_FORMAT_SLINEAR16, 01060 AST_FORMAT_SLINEAR, 01061 /*! G.726 is standard ADPCM, in RFC3551 packing order */ 01062 AST_FORMAT_G726, 01063 /*! G.726 is standard ADPCM, in AAL2 packing order */ 01064 AST_FORMAT_G726_AAL2, 01065 /*! ADPCM has great sound quality and is still pretty easy to translate */ 01066 AST_FORMAT_ADPCM, 01067 /*! Okay, we're down to vocoders now, so pick GSM because it's small and easier to 01068 translate and sounds pretty good */ 01069 AST_FORMAT_GSM, 01070 /*! iLBC is not too bad */ 01071 AST_FORMAT_ILBC, 01072 /*! Speex is free, but computationally more expensive than GSM */ 01073 AST_FORMAT_SPEEX16, 01074 AST_FORMAT_SPEEX, 01075 /*! Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough 01076 to use it */ 01077 AST_FORMAT_LPC10, 01078 /*! G.729a is faster than 723 and slightly less expensive */ 01079 AST_FORMAT_G729A, 01080 /*! Down to G.723.1 which is proprietary but at least designed for voice */ 01081 AST_FORMAT_G723_1, 01082 }; 01083 char buf[512]; 01084 01085 /* Strip out video */ 01086 fmts &= AST_FORMAT_AUDIO_MASK; 01087 01088 /* Find the first preferred codec in the format given */ 01089 for (x = 0; x < ARRAY_LEN(prefs); x++) { 01090 if (fmts & prefs[x]) 01091 return prefs[x]; 01092 } 01093 01094 ast_log(LOG_WARNING, "Don't know any of %s formats\n", ast_getformatname_multiple(buf, sizeof(buf), fmts)); 01095 01096 return 0; 01097 }
struct ast_channel* ast_bridged_channel | ( | struct ast_channel * | chan | ) |
Find bridged channel.
chan | Current channel |
Definition at line 6920 of file channel.c.
References ast_channel::_bridge, ast_channel_tech::bridged_channel, chanlist::chan, and ast_channel::tech.
Referenced by __analog_handle_event(), __analog_ss_thread(), __ast_channel_masquerade(), __ast_read(), __dahdi_exception(), _skinny_show_lines(), action_agents(), action_coreshowchannels(), agents_data_provider_get(), agents_show(), agents_show_online(), analog_attempt_transfer(), analog_exception(), analog_hangup(), analog_ss_thread(), ast_bridge_call(), ast_cel_report_event(), ast_channel_data_add_structure(), ast_channel_set_linkgroup(), ast_do_masquerade(), ast_rtp_instance_set_stats_vars(), ast_set_hangupsource(), ast_var_channel_bridge(), ast_var_channels_table(), attempt_transfer(), cb_events(), channel_spy(), check_bridge(), common_exec(), console_transfer(), create_jb(), dahdi_handle_event(), dahdi_hangup(), export_aoc_vars(), func_channel_read(), get_refer_info(), handle_chanlist(), handle_hd_hf(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_refer(), handle_showchan(), handle_soft_key_event_message(), handle_stimulus_message(), key_call(), key_dial_page(), local_attended_transfer(), local_queryoption(), mgcp_hangup(), mgcp_ss(), misdn_attempt_transfer(), mixmonitor_thread(), my_get_sigpvt_bridged_channel(), park_call_full(), schedule_delivery(), serialize_showchan(), sig_pri_attempt_transfer(), sig_pri_handle_hold(), sip_hangup(), sip_set_rtp_peer(), skinny_transfer(), socket_process(), start_spying(), startmon(), TransferCallStep1(), and unistim_hangup().
06921 { 06922 struct ast_channel *bridged; 06923 bridged = chan->_bridge; 06924 if (bridged && bridged->tech->bridged_channel) 06925 bridged = bridged->tech->bridged_channel(chan, bridged); 06926 return bridged; 06927 }
int ast_call | ( | struct ast_channel * | chan, | |
char * | addr, | |||
int | timeout | |||
) |
Make a call.
chan | which channel to make the call on | |
addr | destination of the call | |
timeout | time to wait on for connect |
Definition at line 5610 of file channel.c.
References AST_CDR_FLAG_DIALED, ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, ast_set_flag, ast_test_flag, ast_channel_tech::call, ast_channel::cdr, chanlist::chan, and ast_channel::tech.
Referenced by __ast_request_and_dial(), ast_call_forward(), attempt_reconnect(), begin_dial_channel(), connect_link(), dial_exec_full(), dial_transfer(), do_forward(), do_idle_thread(), feature_request_and_dial(), findmeexec(), play_sound_file(), ring_entry(), and rpt().
05611 { 05612 /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 05613 If the remote end does not answer within the timeout, then do NOT hang up, but 05614 return anyway. */ 05615 int res = -1; 05616 /* Stop if we're a zombie or need a soft hangup */ 05617 ast_channel_lock(chan); 05618 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) { 05619 if (chan->cdr) { 05620 ast_set_flag(chan->cdr, AST_CDR_FLAG_DIALED); 05621 } 05622 if (chan->tech->call) 05623 res = chan->tech->call(chan, addr, timeout); 05624 ast_set_flag(chan, AST_FLAG_OUTGOING); 05625 } 05626 ast_channel_unlock(chan); 05627 return res; 05628 }
struct ast_channel* ast_call_forward | ( | struct ast_channel * | caller, | |
struct ast_channel * | orig, | |||
int * | timeout, | |||
format_t | format, | |||
struct outgoing_helper * | oh, | |||
int * | outstate | |||
) |
Forwards a call to a new channel specified by the original channel's call_forward str. If possible, the new forwarded channel is created and returned while the original one is terminated.
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) |
Definition at line 5236 of file channel.c.
References outgoing_helper::account, accountcode, ast_channel::accountcode, ast_call(), AST_CDR_FLAG_ORIGINATED, ast_cdr_setaccount(), ast_channel_lock, ast_channel_lock_both, ast_channel_unlock, ast_copy_flags, ast_copy_string(), ast_hangup(), ast_log(), ast_party_connected_line_copy(), ast_party_redirecting_copy(), ast_request(), ast_set_variables(), ast_string_field_set, ast_channel::call_forward, call_forward_inherit(), ast_channel::caller, cause, ast_channel::cdr, ast_channel::connected, ast_channel::context, handle_cause(), LOG_NOTICE, outgoing_helper::parent_channel, pbx_builtin_getvar_helper(), ast_channel::redirecting, S_OR, type, and outgoing_helper::vars.
Referenced by __ast_request_and_dial(), and feature_request_and_dial().
05237 { 05238 char tmpchan[256]; 05239 struct ast_channel *new_chan = NULL; 05240 char *data, *type; 05241 int cause = 0; 05242 int res; 05243 05244 /* gather data and request the new forward channel */ 05245 ast_copy_string(tmpchan, orig->call_forward, sizeof(tmpchan)); 05246 if ((data = strchr(tmpchan, '/'))) { 05247 *data++ = '\0'; 05248 type = tmpchan; 05249 } else { 05250 const char *forward_context; 05251 ast_channel_lock(orig); 05252 forward_context = pbx_builtin_getvar_helper(orig, "FORWARD_CONTEXT"); 05253 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", orig->call_forward, S_OR(forward_context, orig->context)); 05254 ast_channel_unlock(orig); 05255 data = tmpchan; 05256 type = "Local"; 05257 } 05258 if (!(new_chan = ast_request(type, format, orig, data, &cause))) { 05259 ast_log(LOG_NOTICE, "Unable to create channel for call forward to '%s/%s' (cause = %d)\n", type, data, cause); 05260 handle_cause(cause, outstate); 05261 ast_hangup(orig); 05262 return NULL; 05263 } 05264 05265 /* Copy/inherit important information into new channel */ 05266 if (oh) { 05267 if (oh->vars) { 05268 ast_set_variables(new_chan, oh->vars); 05269 } 05270 if (oh->parent_channel) { 05271 call_forward_inherit(new_chan, oh->parent_channel, orig); 05272 } 05273 if (oh->account) { 05274 ast_channel_lock(new_chan); 05275 ast_cdr_setaccount(new_chan, oh->account); 05276 ast_channel_unlock(new_chan); 05277 } 05278 } else if (caller) { /* no outgoing helper so use caller if avaliable */ 05279 call_forward_inherit(new_chan, caller, orig); 05280 } 05281 05282 ast_channel_lock_both(orig, new_chan); 05283 ast_copy_flags(new_chan->cdr, orig->cdr, AST_CDR_FLAG_ORIGINATED); 05284 ast_string_field_set(new_chan, accountcode, orig->accountcode); 05285 ast_party_connected_line_copy(&new_chan->connected, &orig->connected); 05286 ast_party_redirecting_copy(&new_chan->redirecting, &orig->redirecting); 05287 ast_channel_unlock(new_chan); 05288 ast_channel_unlock(orig); 05289 05290 /* call new channel */ 05291 res = ast_call(new_chan, data, 0); 05292 if (timeout) { 05293 *timeout = res; 05294 } 05295 if (res) { 05296 ast_log(LOG_NOTICE, "Unable to call forward to channel %s/%s\n", type, (char *)data); 05297 ast_hangup(orig); 05298 ast_hangup(new_chan); 05299 return NULL; 05300 } 05301 ast_hangup(orig); 05302 05303 return new_chan; 05304 }
void ast_cancel_shutdown | ( | void | ) |
Cancel a shutdown in progress.
Cancels an existing shutdown and returns to normal operation
Definition at line 838 of file channel.c.
Referenced by handle_abort_shutdown().
00839 { 00840 shutting_down = 0; 00841 }
const char* ast_cause2str | ( | int | state | ) |
Gives the string form of a given cause code.
state | cause to get the description of |
Definition at line 959 of file channel.c.
References ARRAY_LEN, and causes.
Referenced by __transmit_response(), ast_channel_data_add_structure(), ast_do_masquerade(), ast_hangup(), dial_exec_full(), findmeexec(), sip_hangup(), and transmit_request_with_auth().
00960 { 00961 int x; 00962 00963 for (x = 0; x < ARRAY_LEN(causes); x++) { 00964 if (causes[x].cause == cause) 00965 return causes[x].desc; 00966 } 00967 00968 return "Unknown"; 00969 }
void ast_change_name | ( | struct ast_channel * | chan, | |
const char * | newname | |||
) |
Change channel name.
chan | the channel to change the name of | |
newname | the name to change to |
Definition at line 6078 of file channel.c.
References __ast_change_name_nolink(), ao2_link, ao2_unlink, ast_channel_lock, ast_channel_unlock, chanlist::chan, and channels.
Referenced by update_name().
06079 { 06080 /* We must re-link, as the hash value will change here. */ 06081 ao2_unlink(channels, chan); 06082 ast_channel_lock(chan); 06083 __ast_change_name_nolink(chan, newname); 06084 ast_channel_unlock(chan); 06085 ao2_link(channels, chan); 06086 }
int 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.
c0 | first channel to bridge | |
c1 | second channel to bridge | |
config | config for the channels | |
fo | destination frame(?) | |
rc | destination channel(?) |
Definition at line 7263 of file channel.c.
References ast_channel::_bridge, ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_RETRY, ast_channel_clear_softhangup(), ast_channel_make_compatible(), ast_check_hangup(), ast_check_hangup_locked(), ast_clear_flag, AST_CONTROL_SRCUPDATE, ast_debug, AST_FEATURE_PLAY_WARNING, AST_FEATURE_WARNING_ACTIVE, AST_FLAG_END_DTMF_ONLY, AST_FLAG_NBRIDGE, AST_FLAG_ZOMBIE, ast_framehook_list_is_empty(), ast_generic_bridge(), ast_indicate(), ast_log(), ast_manager_event_multichan, ast_samp2tv(), ast_set_flag, ast_set_owners_and_peers(), AST_SOFTHANGUP_UNBRIDGE, ast_test_flag, ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), ast_verb, ast_channel::audiohooks, ast_channel_tech::bridge, bridge_play_sounds(), bridge_playfile(), ast_channel::caller, config, EVENT_FLAG_CALL, ast_channel::framehooks, ast_channel::generator, ast_party_caller::id, LOG_WARNING, manager_bridge_event(), ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::name, ast_channel::nativeformats, ast_party_id::number, ast_channel::readformat, S_COR, ast_channel_tech::send_digit_begin, ast_party_number::str, ast_channel::tech, ast_channel::uniqueid, update_bridge_vars(), ast_party_number::valid, and ast_channel::writeformat.
Referenced by ast_bridge_call().
07265 { 07266 struct ast_channel *chans[2] = { c0, c1 }; 07267 enum ast_bridge_result res = AST_BRIDGE_COMPLETE; 07268 format_t o0nativeformats; 07269 format_t o1nativeformats; 07270 long time_left_ms=0; 07271 char caller_warning = 0; 07272 char callee_warning = 0; 07273 07274 *fo = NULL; 07275 07276 if (c0->_bridge) { 07277 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 07278 c0->name, c0->_bridge->name); 07279 return -1; 07280 } 07281 if (c1->_bridge) { 07282 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 07283 c1->name, c1->_bridge->name); 07284 return -1; 07285 } 07286 07287 /* Stop if we're a zombie or need a soft hangup */ 07288 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 07289 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) 07290 return -1; 07291 07292 caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING); 07293 callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING); 07294 07295 if (ast_tvzero(config->start_time)) { 07296 config->start_time = ast_tvnow(); 07297 if (config->start_sound) { 07298 if (caller_warning) { 07299 bridge_playfile(c0, c1, config->start_sound, config->timelimit / 1000); 07300 } 07301 if (callee_warning) { 07302 bridge_playfile(c1, c0, config->start_sound, config->timelimit / 1000); 07303 } 07304 } 07305 } 07306 07307 /* Keep track of bridge */ 07308 c0->_bridge = c1; 07309 c1->_bridge = c0; 07310 07311 ast_set_owners_and_peers(c0, c1); 07312 07313 o0nativeformats = c0->nativeformats; 07314 o1nativeformats = c1->nativeformats; 07315 07316 if (config->feature_timer && !ast_tvzero(config->nexteventts)) { 07317 config->nexteventts = ast_tvadd(config->feature_start_time, ast_samp2tv(config->feature_timer, 1000)); 07318 } else if (config->timelimit) { 07319 time_left_ms = config->timelimit - ast_tvdiff_ms(ast_tvnow(), config->start_time); 07320 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 07321 if ((caller_warning || callee_warning) && config->play_warning) { 07322 long next_warn = config->play_warning; 07323 if (time_left_ms < config->play_warning && config->warning_freq > 0) { 07324 /* At least one warning was played, which means we are returning after feature */ 07325 long warns_passed = (config->play_warning - time_left_ms) / config->warning_freq; 07326 /* It is 'warns_passed * warning_freq' NOT '(warns_passed + 1) * warning_freq', 07327 because nexteventts will be updated once again in the 'if (!to)' block */ 07328 next_warn = config->play_warning - warns_passed * config->warning_freq; 07329 } 07330 config->nexteventts = ast_tvsub(config->nexteventts, ast_samp2tv(next_warn, 1000)); 07331 } 07332 } else { 07333 config->nexteventts.tv_sec = 0; 07334 config->nexteventts.tv_usec = 0; 07335 } 07336 07337 if (!c0->tech->send_digit_begin) 07338 ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY); 07339 if (!c1->tech->send_digit_begin) 07340 ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY); 07341 manager_bridge_event(1, 1, c0, c1); 07342 07343 /* Before we enter in and bridge these two together tell them both the source of audio has changed */ 07344 ast_indicate(c0, AST_CONTROL_SRCUPDATE); 07345 ast_indicate(c1, AST_CONTROL_SRCUPDATE); 07346 07347 for (/* ever */;;) { 07348 struct timeval now = { 0, }; 07349 int to; 07350 07351 to = -1; 07352 07353 if (!ast_tvzero(config->nexteventts)) { 07354 now = ast_tvnow(); 07355 to = ast_tvdiff_ms(config->nexteventts, now); 07356 if (to <= 0) { 07357 if (!config->timelimit) { 07358 res = AST_BRIDGE_COMPLETE; 07359 break; 07360 } 07361 to = 0; 07362 } 07363 } 07364 07365 if (config->timelimit) { 07366 time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time); 07367 if (time_left_ms < to) 07368 to = time_left_ms; 07369 07370 if (time_left_ms <= 0) { 07371 if (caller_warning && config->end_sound) 07372 bridge_playfile(c0, c1, config->end_sound, 0); 07373 if (callee_warning && config->end_sound) 07374 bridge_playfile(c1, c0, config->end_sound, 0); 07375 *fo = NULL; 07376 res = 0; 07377 break; 07378 } 07379 07380 if (!to) { 07381 if (time_left_ms >= 5000 && config->warning_sound && config->play_warning && ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) { 07382 int t = (time_left_ms + 500) / 1000; /* round to nearest second */ 07383 if (caller_warning) 07384 bridge_playfile(c0, c1, config->warning_sound, t); 07385 if (callee_warning) 07386 bridge_playfile(c1, c0, config->warning_sound, t); 07387 } 07388 07389 if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000))) { 07390 config->nexteventts = ast_tvadd(config->nexteventts, ast_samp2tv(config->warning_freq, 1000)); 07391 } else { 07392 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 07393 } 07394 } 07395 ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE); 07396 } 07397 07398 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */ 07399 if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) { 07400 ast_channel_clear_softhangup(c0, AST_SOFTHANGUP_UNBRIDGE); 07401 } 07402 if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) { 07403 ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE); 07404 } 07405 c0->_bridge = c1; 07406 c1->_bridge = c0; 07407 ast_debug(1, "Unbridge signal received. Ending native bridge.\n"); 07408 continue; 07409 } 07410 07411 /* Stop if we're a zombie or need a soft hangup */ 07412 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 07413 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) { 07414 *fo = NULL; 07415 res = 0; 07416 ast_debug(1, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n", 07417 c0->name, c1->name, 07418 ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No", 07419 ast_check_hangup(c0) ? "Yes" : "No", 07420 ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No", 07421 ast_check_hangup(c1) ? "Yes" : "No"); 07422 break; 07423 } 07424 07425 update_bridge_vars(c0, c1); 07426 07427 bridge_play_sounds(c0, c1); 07428 07429 if (c0->tech->bridge && 07430 /* if < 1 ms remains use generic bridging for accurate timing */ 07431 (!config->timelimit || to > 1000 || to == 0) && 07432 (c0->tech->bridge == c1->tech->bridge) && 07433 !c0->monitor && !c1->monitor && 07434 !c0->audiohooks && !c1->audiohooks && 07435 ast_framehook_list_is_empty(c0->framehooks) && ast_framehook_list_is_empty(c1->framehooks) && 07436 !c0->masq && !c0->masqr && !c1->masq && !c1->masqr) { 07437 int timeoutms = to - 1000 > 0 ? to - 1000 : to; 07438 /* Looks like they share a bridge method and nothing else is in the way */ 07439 ast_set_flag(c0, AST_FLAG_NBRIDGE); 07440 ast_set_flag(c1, AST_FLAG_NBRIDGE); 07441 if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, timeoutms)) == AST_BRIDGE_COMPLETE) { 07442 ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans, 07443 "Channel1: %s\r\n" 07444 "Channel2: %s\r\n" 07445 "Uniqueid1: %s\r\n" 07446 "Uniqueid2: %s\r\n" 07447 "CallerID1: %s\r\n" 07448 "CallerID2: %s\r\n", 07449 c0->name, c1->name, 07450 c0->uniqueid, c1->uniqueid, 07451 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"), 07452 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>")); 07453 07454 ast_debug(1, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name); 07455 07456 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 07457 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 07458 07459 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */ 07460 continue; 07461 } 07462 07463 c0->_bridge = NULL; 07464 c1->_bridge = NULL; 07465 return res; 07466 } else { 07467 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 07468 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 07469 } 07470 switch (res) { 07471 case AST_BRIDGE_RETRY: 07472 if (config->play_warning) { 07473 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE); 07474 } 07475 continue; 07476 default: 07477 ast_verb(3, "Native bridging %s and %s ended\n", c0->name, c1->name); 07478 /* fallthrough */ 07479 case AST_BRIDGE_FAILED_NOWARN: 07480 break; 07481 } 07482 } 07483 07484 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) || 07485 (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) && 07486 !(c0->generator || c1->generator)) { 07487 if (ast_channel_make_compatible(c0, c1)) { 07488 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name); 07489 manager_bridge_event(0, 1, c0, c1); 07490 return AST_BRIDGE_FAILED; 07491 } 07492 o0nativeformats = c0->nativeformats; 07493 o1nativeformats = c1->nativeformats; 07494 } 07495 07496 update_bridge_vars(c0, c1); 07497 07498 res = ast_generic_bridge(c0, c1, config, fo, rc); 07499 if (res != AST_BRIDGE_RETRY) { 07500 break; 07501 } else if (config->feature_timer) { 07502 /* feature timer expired but has not been updated, sending to ast_bridge_call to do so */ 07503 break; 07504 } 07505 } 07506 07507 ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY); 07508 ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY); 07509 07510 /* Now that we have broken the bridge the source will change yet again */ 07511 ast_indicate(c0, AST_CONTROL_SRCUPDATE); 07512 ast_indicate(c1, AST_CONTROL_SRCUPDATE); 07513 07514 c0->_bridge = NULL; 07515 c1->_bridge = NULL; 07516 07517 ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans, 07518 "Channel1: %s\r\n" 07519 "Channel2: %s\r\n" 07520 "Uniqueid1: %s\r\n" 07521 "Uniqueid2: %s\r\n" 07522 "CallerID1: %s\r\n" 07523 "CallerID2: %s\r\n", 07524 c0->name, c1->name, 07525 c0->uniqueid, c1->uniqueid, 07526 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"), 07527 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>")); 07528 ast_debug(1, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name); 07529 07530 return res; 07531 }
struct ast_channel* ast_channel_callback | ( | ao2_callback_data_fn * | cb_fn, | |
void * | arg, | |||
void * | data, | |||
int | ao2_flags | |||
) |
Call a function with every active channel.
This function executes a callback one time for each active channel on the system. The channel is provided as an argument to the function.
Definition at line 1595 of file channel.c.
References ao2_callback_data, and channels.
Referenced by ast_cel_check_retire_linkedid(), ast_pickup_call(), handle_core_set_debug_channel(), my_ast_get_channel_by_name_locked(), pickup_by_group(), pickup_by_mark(), pickup_by_part(), and state_notify_build_xml().
01597 { 01598 return ao2_callback_data(channels, ao2_flags, cb_fn, arg, data); 01599 }
int ast_channel_cc_params_init | ( | struct ast_channel * | chan, | |
const struct ast_cc_config_params * | base_params | |||
) |
Set up datastore with CCSS parameters for a channel.
chan | The channel to create the datastore on | |
base_params | CCSS parameters we wish to copy into the channel |
0 | Success | |
-1 | Failure |
Definition at line 9424 of file channel.c.
References ast_cc_config_params_destroy(), ast_cc_config_params_init, ast_cc_copy_config_params(), ast_channel_datastore_add(), ast_datastore_alloc, cc_channel_datastore_info, and ast_datastore::data.
Referenced by ast_channel_get_cc_config_params(), dahdi_new(), local_call(), local_request(), and sip_new().
09426 { 09427 struct ast_cc_config_params *cc_params; 09428 struct ast_datastore *cc_datastore; 09429 09430 if (!(cc_params = ast_cc_config_params_init())) { 09431 return -1; 09432 } 09433 09434 if (!(cc_datastore = ast_datastore_alloc(&cc_channel_datastore_info, NULL))) { 09435 ast_cc_config_params_destroy(cc_params); 09436 return -1; 09437 } 09438 09439 if (base_params) { 09440 ast_cc_copy_config_params(cc_params, base_params); 09441 } 09442 cc_datastore->data = cc_params; 09443 ast_channel_datastore_add(chan, cc_datastore); 09444 return 0; 09445 }
void ast_channel_clear_softhangup | ( | struct ast_channel * | chan, | |
int | flag | |||
) |
Clear a set of softhangup flags from a channel.
Never clear a softhangup flag from a channel directly. Instead, use this function. This ensures that all aspects of the softhangup process are aborted.
chan | the channel to clear the flag on | |
flag | the flag or flags to clear |
Definition at line 2652 of file channel.c.
References ast_channel::_softhangup, ast_channel_lock, ast_channel_unlock, AST_CONTROL_END_OF_Q, AST_FRAME_CONTROL, ast_frfree, AST_LIST_LAST, AST_LIST_REMOVE, chanlist::chan, ast_frame::frametype, ast_frame_subclass::integer, ast_channel::readq, and ast_frame::subclass.
Referenced by __ast_pbx_run(), ast_channel_bridge(), check_goto_on_transfer(), and collect_digits().
02653 { 02654 ast_channel_lock(chan); 02655 02656 chan->_softhangup &= ~flag; 02657 02658 if (!chan->_softhangup) { 02659 struct ast_frame *fr; 02660 02661 /* If we have completely cleared the softhangup flag, 02662 * then we need to fully abort the hangup process. This requires 02663 * pulling the END_OF_Q frame out of the channel frame queue if it 02664 * still happens to be there. */ 02665 02666 fr = AST_LIST_LAST(&chan->readq); 02667 if (fr && fr->frametype == AST_FRAME_CONTROL && 02668 fr->subclass.integer == AST_CONTROL_END_OF_Q) { 02669 AST_LIST_REMOVE(&chan->readq, fr, frame_list); 02670 ast_frfree(fr); 02671 } 02672 } 02673 02674 ast_channel_unlock(chan); 02675 }
int ast_channel_cmpwhentohangup | ( | struct ast_channel * | chan, | |
time_t | offset | |||
) |
Compare a offset with the settings of when to hang a channel up.
chan | channel on which to check for hang up | |
offset | offset in seconds from current time |
Definition at line 879 of file channel.c.
References ast_channel_cmpwhentohangup_tv(), and chanlist::chan.
00880 { 00881 struct timeval when = { offset, }; 00882 return ast_channel_cmpwhentohangup_tv(chan, when); 00883 }
int ast_channel_cmpwhentohangup_tv | ( | struct ast_channel * | chan, | |
struct timeval | offset | |||
) |
Compare a offset with the settings of when to hang a channel up.
chan | channel on which to check for hangup | |
offset | offset in seconds and microseconds from current time |
Definition at line 864 of file channel.c.
References ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), chanlist::chan, and ast_channel::whentohangup.
Referenced by ast_channel_cmpwhentohangup().
00865 { 00866 struct timeval whentohangup; 00867 00868 if (ast_tvzero(chan->whentohangup)) 00869 return ast_tvzero(offset) ? 0 : -1; 00870 00871 if (ast_tvzero(offset)) 00872 return 1; 00873 00874 whentohangup = ast_tvadd(offset, ast_tvnow()); 00875 00876 return ast_tvdiff_ms(whentohangup, chan->whentohangup); 00877 }
int ast_channel_connected_line_macro | ( | struct ast_channel * | autoservice_chan, | |
struct ast_channel * | macro_chan, | |||
const void * | connected_info, | |||
int | caller, | |||
int | frame | |||
) |
Run a connected line interception macro and update a channel's connected line information.
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. |
0 | Success | |
-1 | Either the macro does not exist, or there was an error while attempting to run the macro |
Make constants so that caller and frame can be more expressive than just '1' and '0'
Definition at line 9322 of file channel.c.
References ast_app_run_macro(), ast_channel_lock, ast_channel_unlock, ast_channel_update_connected_line(), ast_connected_line_parse_data(), ast_party_connected_line_copy(), ast_strdupa, ast_strlen_zero(), ast_channel::connected, connected, ast_frame::data, ast_frame::datalen, pbx_builtin_getvar_helper(), ast_frame::ptr, and S_OR.
Referenced by __ast_read(), app_exec(), ast_bridge_call(), ast_do_pickup(), atxfer_fail_cleanup(), builtin_atxfer(), feature_request_and_dial(), handle_frame(), parked_call_exec(), remote_bridge_loop(), and wait_for_answer().
09323 { 09324 const char *macro; 09325 const char *macro_args; 09326 int retval; 09327 09328 ast_channel_lock(macro_chan); 09329 macro = pbx_builtin_getvar_helper(macro_chan, is_caller 09330 ? "CONNECTED_LINE_CALLER_SEND_MACRO" : "CONNECTED_LINE_CALLEE_SEND_MACRO"); 09331 macro = ast_strdupa(S_OR(macro, "")); 09332 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller 09333 ? "CONNECTED_LINE_CALLER_SEND_MACRO_ARGS" : "CONNECTED_LINE_CALLEE_SEND_MACRO_ARGS"); 09334 macro_args = ast_strdupa(S_OR(macro_args, "")); 09335 09336 if (ast_strlen_zero(macro)) { 09337 ast_channel_unlock(macro_chan); 09338 return -1; 09339 } 09340 09341 if (is_frame) { 09342 const struct ast_frame *frame = connected_info; 09343 09344 ast_connected_line_parse_data(frame->data.ptr, frame->datalen, ¯o_chan->connected); 09345 } else { 09346 const struct ast_party_connected_line *connected = connected_info; 09347 09348 ast_party_connected_line_copy(¯o_chan->connected, connected); 09349 } 09350 ast_channel_unlock(macro_chan); 09351 09352 if (!(retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args))) { 09353 ast_channel_lock(macro_chan); 09354 ast_channel_update_connected_line(macro_chan, ¯o_chan->connected, NULL); 09355 ast_channel_unlock(macro_chan); 09356 } 09357 09358 return retval; 09359 }
int ast_channel_data_add_structure | ( | struct ast_data * | tree, | |
struct ast_channel * | chan, | |||
int | add_bridged | |||
) |
Insert into an astdata tree, the channel structure.
[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. |
<0 | on error. | |
0 | on success. |
Definition at line 342 of file channel.c.
References ast_channel::_softhangup, ast_channel::_state, ast_channel::amaflags, ast_bridged_channel(), ast_cause2str(), ast_cdr_data_add_structure(), ast_cdr_flags2str(), ast_channel_data_add_structure(), ast_data_add_bool(), ast_data_add_codecs(), ast_data_add_int(), ast_data_add_node(), ast_data_add_str(), ast_data_add_structure, ast_data_add_uint(), AST_SOFTHANGUP_APPUNLOAD, AST_SOFTHANGUP_ASYNCGOTO, AST_SOFTHANGUP_DEV, AST_SOFTHANGUP_EXPLICIT, AST_SOFTHANGUP_SHUTDOWN, AST_SOFTHANGUP_TIMEOUT, AST_SOFTHANGUP_UNBRIDGE, ast_state2str(), ast_tone_zone_data_add_structure(), ast_transfercapability2str(), ast_channel::cdr, chanlist::chan, channel_data_add_flags(), ast_channel::hangupcause, ast_channel::nativeformats, ast_channel::oldwriteformat, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::transfercapability, ast_channel::whentohangup, ast_channel::writeformat, and ast_channel::zone.
Referenced by agents_data_provider_get(), ast_channel_data_add_structure(), data_channels_provider_handler(), queues_data_provider_get_helper(), and user_add_provider_cb().
00344 { 00345 struct ast_channel *bc; 00346 struct ast_data *data_bridged; 00347 struct ast_data *data_cdr; 00348 struct ast_data *data_flags; 00349 struct ast_data *data_zones; 00350 struct ast_data *enum_node; 00351 struct ast_data *data_softhangup; 00352 #if 0 /* XXX AstData: ast_callerid no longer exists. (Equivalent code not readily apparent.) */ 00353 struct ast_data *data_callerid; 00354 char value_str[100]; 00355 #endif 00356 00357 if (!tree) { 00358 return -1; 00359 } 00360 00361 ast_data_add_structure(ast_channel, tree, chan); 00362 00363 if (add_bridged) { 00364 bc = ast_bridged_channel(chan); 00365 if (bc) { 00366 data_bridged = ast_data_add_node(tree, "bridged"); 00367 if (!data_bridged) { 00368 return -1; 00369 } 00370 ast_channel_data_add_structure(data_bridged, bc, 0); 00371 } 00372 } 00373 00374 ast_data_add_codecs(tree, "oldwriteformat", chan->oldwriteformat); 00375 ast_data_add_codecs(tree, "nativeformats", chan->nativeformats); 00376 ast_data_add_codecs(tree, "readformat", chan->readformat); 00377 ast_data_add_codecs(tree, "writeformat", chan->writeformat); 00378 ast_data_add_codecs(tree, "rawreadformat", chan->rawreadformat); 00379 ast_data_add_codecs(tree, "rawwriteformat", chan->rawwriteformat); 00380 00381 /* state */ 00382 enum_node = ast_data_add_node(tree, "state"); 00383 if (!enum_node) { 00384 return -1; 00385 } 00386 ast_data_add_str(enum_node, "text", ast_state2str(chan->_state)); 00387 ast_data_add_int(enum_node, "value", chan->_state); 00388 00389 /* hangupcause */ 00390 enum_node = ast_data_add_node(tree, "hangupcause"); 00391 if (!enum_node) { 00392 return -1; 00393 } 00394 ast_data_add_str(enum_node, "text", ast_cause2str(chan->hangupcause)); 00395 ast_data_add_int(enum_node, "value", chan->hangupcause); 00396 00397 /* amaflags */ 00398 enum_node = ast_data_add_node(tree, "amaflags"); 00399 if (!enum_node) { 00400 return -1; 00401 } 00402 ast_data_add_str(enum_node, "text", ast_cdr_flags2str(chan->amaflags)); 00403 ast_data_add_int(enum_node, "value", chan->amaflags); 00404 00405 /* transfercapability */ 00406 enum_node = ast_data_add_node(tree, "transfercapability"); 00407 if (!enum_node) { 00408 return -1; 00409 } 00410 ast_data_add_str(enum_node, "text", ast_transfercapability2str(chan->transfercapability)); 00411 ast_data_add_int(enum_node, "value", chan->transfercapability); 00412 00413 /* _softphangup */ 00414 data_softhangup = ast_data_add_node(tree, "softhangup"); 00415 if (!data_softhangup) { 00416 return -1; 00417 } 00418 ast_data_add_bool(data_softhangup, "dev", chan->_softhangup & AST_SOFTHANGUP_DEV); 00419 ast_data_add_bool(data_softhangup, "asyncgoto", chan->_softhangup & AST_SOFTHANGUP_ASYNCGOTO); 00420 ast_data_add_bool(data_softhangup, "shutdown", chan->_softhangup & AST_SOFTHANGUP_SHUTDOWN); 00421 ast_data_add_bool(data_softhangup, "timeout", chan->_softhangup & AST_SOFTHANGUP_TIMEOUT); 00422 ast_data_add_bool(data_softhangup, "appunload", chan->_softhangup & AST_SOFTHANGUP_APPUNLOAD); 00423 ast_data_add_bool(data_softhangup, "explicit", chan->_softhangup & AST_SOFTHANGUP_EXPLICIT); 00424 ast_data_add_bool(data_softhangup, "unbridge", chan->_softhangup & AST_SOFTHANGUP_UNBRIDGE); 00425 00426 /* channel flags */ 00427 data_flags = ast_data_add_node(tree, "flags"); 00428 if (!data_flags) { 00429 return -1; 00430 } 00431 channel_data_add_flags(data_flags, chan); 00432 00433 ast_data_add_uint(tree, "timetohangup", chan->whentohangup.tv_sec); 00434 00435 #if 0 /* XXX AstData: ast_callerid no longer exists. (Equivalent code not readily apparent.) */ 00436 /* callerid */ 00437 data_callerid = ast_data_add_node(tree, "callerid"); 00438 if (!data_callerid) { 00439 return -1; 00440 } 00441 ast_data_add_structure(ast_callerid, data_callerid, &(chan->cid)); 00442 /* insert the callerid ton */ 00443 enum_node = ast_data_add_node(data_callerid, "cid_ton"); 00444 if (!enum_node) { 00445 return -1; 00446 } 00447 ast_data_add_int(enum_node, "value", chan->cid.cid_ton); 00448 snprintf(value_str, sizeof(value_str), "TON: %s/Plan: %s", 00449 party_number_ton2str(chan->cid.cid_ton), 00450 party_number_plan2str(chan->cid.cid_ton)); 00451 ast_data_add_str(enum_node, "text", value_str); 00452 #endif 00453 00454 /* tone zone */ 00455 if (chan->zone) { 00456 data_zones = ast_data_add_node(tree, "zone"); 00457 if (!data_zones) { 00458 return -1; 00459 } 00460 ast_tone_zone_data_add_structure(data_zones, chan->zone); 00461 } 00462 00463 /* insert cdr */ 00464 data_cdr = ast_data_add_node(tree, "cdr"); 00465 if (!data_cdr) { 00466 return -1; 00467 } 00468 00469 ast_cdr_data_add_structure(data_cdr, chan->cdr, 1); 00470 00471 return 0; 00472 }
int ast_channel_data_cmp_structure | ( | const struct ast_data_search * | tree, | |
struct ast_channel * | chan, | |||
const char * | structure_name | |||
) |
Compare to channel structures using the data api.
[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. |
0 | The structure matches. | |
1 | The structure doesn't matches. |
Definition at line 474 of file channel.c.
References ast_data_search_cmp_structure, and chanlist::chan.
00476 { 00477 return ast_data_search_cmp_structure(tree, ast_channel, chan, structure_name); 00478 }
int ast_channel_datastore_add | ( | struct ast_channel * | chan, | |
struct ast_datastore * | datastore | |||
) |
Add a datastore to a channel.
0 | success | |
non-zero | failure |
Definition at line 2535 of file channel.c.
References AST_LIST_INSERT_HEAD, chanlist::chan, ast_channel::datastores, and ast_datastore::entry.
Referenced by __ast_channel_masquerade(), _macro_exec(), acf_curlopt_write(), acf_iaxvar_write(), add_features_datastores(), add_to_agi(), apply_plc(), ast_channel_cc_params_init(), ast_do_pickup(), ast_iax2_new(), ast_setup_cc_recall_datastore(), audiohook_volume_get(), authenticate_reply(), calendar_query_exec(), cc_interfaces_datastore_init(), dial_exec_full(), do_notify(), dundi_query_read(), enable_jack_hook(), enum_query_read(), find_or_create_details(), find_transaction(), frame_trace_helper(), func_channel_write_real(), get_lock(), gosub_exec(), lua_get_state(), mute_add_audiohook(), pitchshift_helper(), raise_exception(), setup_inheritance_datastore(), setup_mixmonitor_ds(), setup_transfer_datastore(), shared_write(), smdi_msg_retrieve_read(), socket_process(), speech_create(), speex_write(), srv_datastore_setup(), and volume_write().
02536 { 02537 int res = 0; 02538 02539 AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry); 02540 02541 return res; 02542 }
struct ast_datastore* attribute_malloc ast_channel_datastore_alloc | ( | const struct ast_datastore_info * | info, | |
const char * | uid | |||
) |
Create a channel data store object.
Definition at line 2508 of file channel.c.
References ast_datastore_alloc, and ast_datastore::info.
02509 { 02510 return ast_datastore_alloc(info, uid); 02511 }
struct ast_datastore* ast_channel_datastore_find | ( | struct ast_channel * | chan, | |
const struct ast_datastore_info * | info, | |||
const char * | uid | |||
) |
Find a datastore on a channel.
The datastore returned from this function must not be used if the reference to the channel is released.
pointer | to the datastore if found | |
NULL | if not found |
Definition at line 2549 of file channel.c.
References AST_LIST_TRAVERSE, chanlist::chan, ast_channel::datastores, ast_datastore::entry, ast_datastore::info, and ast_datastore::uid.
Referenced by _macro_exec(), acf_curl_helper(), acf_curlopt_helper(), acf_curlopt_write(), acf_exception_read(), acf_fetch(), acf_iaxvar_read(), acf_iaxvar_write(), add_agi_cmd(), add_features_datastores(), add_to_agi(), apply_plc(), ast_can_pickup(), ast_cc_agent_set_interfaces_chanvar(), ast_cc_call_init(), ast_cc_completed(), ast_cc_extension_monitor_add_dialstring(), ast_cc_get_current_core_id(), ast_cc_is_recall(), ast_cc_offer(), ast_channel_get_cc_config_params(), ast_do_masquerade(), ast_handle_cc_control_frame(), ast_ignore_cc(), ast_odbc_retrieve_transaction_obj(), ast_set_cc_interfaces_chanvar(), attended_transfer_occurred(), audiohook_volume_callback(), audiohook_volume_get(), builtin_atxfer(), calendar_event_read(), calendar_query_exec(), calendar_query_result_exec(), cc_build_payload(), clear_dialed_interfaces(), dial_exec_full(), disable_jack_hook(), dundi_result_read(), enable_jack_hook(), enum_result_read(), exec_odbcfinish(), find_details(), find_speech(), find_transaction(), frame_trace_helper(), func_channel_read(), func_channel_write_real(), func_inheritance_write(), func_mute_write(), get_agi_cmd(), get_lock(), gosub_exec(), handle_gosub(), iax2_call(), jack_hook_callback(), local_read(), local_write(), lock_fixup(), lua_get_state(), manage_parked_call(), manager_mutestream(), mark_transaction_active(), mute_callback(), parked_call_exec(), pitchshift_cb(), pitchshift_helper(), pop_exec(), queue_transfer_fixup(), raise_exception(), release_transaction(), return_exec(), set_security_requirements(), shared_read(), shared_write(), smdi_msg_read(), speech_background(), speech_destroy(), speex_callback(), speex_read(), speex_write(), srv_query_read(), srv_result_read(), stop_mixmonitor_exec(), try_calling(), unlock_read(), volume_callback(), and volume_write().
02550 { 02551 struct ast_datastore *datastore = NULL; 02552 02553 if (info == NULL) 02554 return NULL; 02555 02556 AST_LIST_TRAVERSE(&chan->datastores, datastore, entry) { 02557 if (datastore->info != info) { 02558 continue; 02559 } 02560 02561 if (uid == NULL) { 02562 /* matched by type only */ 02563 break; 02564 } 02565 02566 if ((datastore->uid != NULL) && !strcasecmp(uid, datastore->uid)) { 02567 /* Matched by type AND uid */ 02568 break; 02569 } 02570 } 02571 02572 return datastore; 02573 }
int ast_channel_datastore_free | ( | struct ast_datastore * | datastore | ) |
Free a channel data store object.
Definition at line 2513 of file channel.c.
References ast_datastore_free().
02514 { 02515 return ast_datastore_free(datastore); 02516 }
int ast_channel_datastore_inherit | ( | struct ast_channel * | from, | |
struct ast_channel * | to | |||
) |
Inherit datastores from a parent to a child.
Definition at line 2518 of file channel.c.
References ast_datastore_alloc, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_datastore::data, DATASTORE_INHERIT_FOREVER, ast_channel::datastores, ast_datastore_info::duplicate, ast_datastore::entry, ast_datastore::info, ast_datastore::inheritance, and ast_datastore::uid.
Referenced by __ast_request_and_dial(), begin_dial_channel(), call_forward_inherit(), dial_exec_full(), dial_transfer(), do_forward(), findmeexec(), local_call(), and ring_entry().
02519 { 02520 struct ast_datastore *datastore = NULL, *datastore2; 02521 02522 AST_LIST_TRAVERSE(&from->datastores, datastore, entry) { 02523 if (datastore->inheritance > 0) { 02524 datastore2 = ast_datastore_alloc(datastore->info, datastore->uid); 02525 if (datastore2) { 02526 datastore2->data = datastore->info->duplicate ? datastore->info->duplicate(datastore->data) : NULL; 02527 datastore2->inheritance = datastore->inheritance == DATASTORE_INHERIT_FOREVER ? DATASTORE_INHERIT_FOREVER : datastore->inheritance - 1; 02528 AST_LIST_INSERT_TAIL(&to->datastores, datastore2, entry); 02529 } 02530 } 02531 } 02532 return 0; 02533 }
int ast_channel_datastore_remove | ( | struct ast_channel * | chan, | |
struct ast_datastore * | datastore | |||
) |
Remove a datastore from a channel.
0 | success | |
non-zero | failure |
Definition at line 2544 of file channel.c.
References AST_LIST_REMOVE, chanlist::chan, ast_channel::datastores, and ast_datastore::entry.
Referenced by acf_fetch(), adjust_frame_for_plc(), ast_do_masquerade(), ast_do_pickup(), clear_dialed_interfaces(), dial_exec_full(), disable_jack_hook(), exec_odbcfinish(), frame_trace_helper(), lua_get_state(), queue_transfer_fixup(), speech_background(), speech_destroy(), speex_write(), srv_query_read(), and stop_mixmonitor_exec().
02545 { 02546 return AST_LIST_REMOVE(&chan->datastores, datastore, entry) ? 0 : -1; 02547 }
int ast_channel_defer_dtmf | ( | struct ast_channel * | chan | ) |
Defers DTMF so that you only read things like hangups and audio.
Definition at line 1577 of file channel.c.
References AST_FLAG_DEFER_DTMF, ast_set_flag, ast_test_flag, and chanlist::chan.
Referenced by find_cache().
01578 { 01579 int pre = 0; 01580 01581 if (chan) { 01582 pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF); 01583 ast_set_flag(chan, AST_FLAG_DEFER_DTMF); 01584 } 01585 return pre; 01586 }
int ast_channel_early_bridge | ( | struct ast_channel * | c0, | |
struct ast_channel * | c1 | |||
) |
Bridge two channels together (early).
c0 | first channel to bridge | |
c1 | second channel to bridge |
Definition at line 7163 of file channel.c.
References ast_channel_tech::early_bridge, and ast_channel::tech.
Referenced by dial_exec_full().
07164 { 07165 /* Make sure we can early bridge, if not error out */ 07166 if (!c0->tech->early_bridge || (c1 && (!c1->tech->early_bridge || c0->tech->early_bridge != c1->tech->early_bridge))) 07167 return -1; 07168 07169 return c0->tech->early_bridge(c0, c1); 07170 }
struct ast_channel* ast_channel_get_by_exten | ( | const char * | exten, | |
const char * | context | |||
) |
Find a channel by extension and context.
a | channel that is at the specified extension and context | |
NULL | if no channel was found |
Definition at line 1774 of file channel.c.
References ast_channel_get_full().
01775 { 01776 return ast_channel_get_full(NULL, 0, exten, context); 01777 }
struct ast_channel* ast_channel_get_by_name | ( | const char * | name | ) |
Find a channel by name.
a | channel with the name specified by the argument | |
NULL | if no channel was found |
Definition at line 1764 of file channel.c.
References ast_channel_get_full().
Referenced by action_add_agi_cmd(), action_aocmessage(), action_atxfer(), action_getvar(), action_hangup(), action_redirect(), action_sendtext(), action_setvar(), action_status(), action_timeout(), ast_async_goto_by_name(), ast_bridge_call(), asyncgoto_exec(), change_monitor_action(), do_pause_or_unpause(), func_mchan_read(), func_mchan_write(), handle_channelstatus(), handle_cli_agi_add_cmd(), handle_core_set_debug_channel(), handle_getvariablefull(), handle_hangup(), handle_redirect(), handle_set_chanvar(), handle_show_chanvar(), handle_showchan(), handle_softhangup(), import_helper(), manager_mute_mixmonitor(), manager_mutestream(), manager_optimize_away(), manager_park(), manager_play_dtmf(), park_call_full(), pbx_builtin_importvar(), senddtmf_exec(), shared_read(), shared_write(), start_monitor_action(), and stop_monitor_action().
01765 { 01766 return ast_channel_get_full(name, 0, NULL, NULL); 01767 }
struct ast_channel* ast_channel_get_by_name_prefix | ( | const char * | name, | |
size_t | name_len | |||
) |
Find a channel by a name prefix.
a | channel with the name prefix specified by the arguments | |
NULL | if no channel was found |
Definition at line 1769 of file channel.c.
References ast_channel_get_full().
Referenced by action_aocmessage(), action_bridge(), ast_parse_device_state(), bridge_exec(), cc_generic_agent_stop_ringing(), common_exec(), handle_cli_mixmonitor(), shared_read(), and shared_write().
01770 { 01771 return ast_channel_get_full(name, name_len, NULL, NULL); 01772 }
int ast_channel_get_cc_agent_type | ( | struct ast_channel * | chan, | |
char * | agent_type, | |||
size_t | size | |||
) |
Find the appropriate CC agent type to use given a channel.
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.
chan | The channel for which we wish to retrieve the agent type | |
[out] | agent_type | The type of agent the channel driver wants us to use |
size | The size of the buffer to write to |
Definition at line 9486 of file channel.c.
References ast_channel_queryoption(), ast_copy_string(), AST_OPTION_CC_AGENT_TYPE, and ast_channel::name.
Referenced by find_agent_callbacks().
09487 { 09488 int len = size; 09489 char *slash; 09490 09491 if (!ast_channel_queryoption(chan, AST_OPTION_CC_AGENT_TYPE, agent_type, &len, 0)) { 09492 return 0; 09493 } 09494 09495 ast_copy_string(agent_type, chan->name, size); 09496 if ((slash = strchr(agent_type, '/'))) { 09497 *slash = '\0'; 09498 } 09499 return 0; 09500 }
struct ast_cc_config_params* ast_channel_get_cc_config_params | ( | struct ast_channel * | chan | ) |
Get the CCSS parameters from a channel.
chan | Channel to retrieve parameters from |
NULL | Failure | |
non-NULL | The parameters desired |
Definition at line 9447 of file channel.c.
References ast_assert, ast_channel_cc_params_init(), ast_channel_datastore_find(), cc_channel_datastore_info, and ast_datastore::data.
Referenced by acf_cc_read(), acf_cc_write(), analog_call(), ast_cc_call_failed(), ast_cc_call_init(), ast_queue_cc_frame(), cc_agent_init(), cc_core_init_instance(), find_agent_callbacks(), local_call(), local_request(), sig_pri_cc_available(), and sig_pri_cc_generic_check().
09448 { 09449 struct ast_datastore *cc_datastore; 09450 09451 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) { 09452 /* If we can't find the datastore, it almost definitely means that the channel type being 09453 * used has not had its driver modified to parse CC config parameters. The best action 09454 * to take here is to create the parameters on the spot with the defaults set. 09455 */ 09456 if (ast_channel_cc_params_init(chan, NULL)) { 09457 return NULL; 09458 } 09459 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) { 09460 /* Should be impossible */ 09461 return NULL; 09462 } 09463 } 09464 09465 ast_assert(cc_datastore->data != NULL); 09466 return cc_datastore->data; 09467 }
int ast_channel_get_device_name | ( | struct ast_channel * | chan, | |
char * | device_name, | |||
size_t | name_buffer_length | |||
) |
Get a device name given its channel structure.
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.
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 |
Definition at line 9469 of file channel.c.
References ast_channel_queryoption(), ast_copy_string(), AST_OPTION_DEVICE_NAME, and ast_channel::name.
Referenced by ast_cc_call_failed(), ast_cc_is_recall(), ast_queue_cc_frame(), cc_core_init_instance(), cccancel_exec(), ccreq_exec(), dial_exec_full(), sig_pri_call(), sig_pri_cc_available(), sig_pri_cc_generic_check(), sip_call(), and sip_handle_cc().
09470 { 09471 int len = name_buffer_length; 09472 char *dash; 09473 if (!ast_channel_queryoption(chan, AST_OPTION_DEVICE_NAME, device_name, &len, 0)) { 09474 return 0; 09475 } 09476 09477 /* Dang. Do it the old-fashioned way */ 09478 ast_copy_string(device_name, chan->name, name_buffer_length); 09479 if ((dash = strrchr(device_name, '-'))) { 09480 *dash = '\0'; 09481 } 09482 09483 return 0; 09484 }
static enum ast_t38_state ast_channel_get_t38_state | ( | struct ast_channel * | chan | ) | [inline, static] |
Retrieves the current T38 state of a channel.
Definition at line 2384 of file channel.h.
References ast_channel_queryoption(), AST_OPTION_T38_STATE, and T38_STATE_UNAVAILABLE.
Referenced by generic_fax_exec(), receivefax_exec(), receivefax_t38_init(), sendfax_exec(), sendfax_t38_init(), set_fax_t38_caps(), transmit(), transmit_audio(), and transmit_t38().
02385 { 02386 enum ast_t38_state state = T38_STATE_UNAVAILABLE; 02387 int datalen = sizeof(state); 02388 02389 ast_channel_queryoption(chan, AST_OPTION_T38_STATE, &state, &datalen, 0); 02390 02391 return state; 02392 }
void ast_channel_inherit_variables | ( | const struct ast_channel * | parent, | |
struct ast_channel * | child | |||
) |
Inherits channel variable from parent to child channel.
parent | Parent channel | |
child | Child channel |
Definition at line 6088 of file channel.c.
References ast_debug, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_var_assign(), ast_var_full_name(), ast_var_name(), ast_var_value(), ast_var_t::entries, and ast_channel::varshead.
Referenced by __ast_request_and_dial(), begin_dial_channel(), call_forward_inherit(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), and ring_entry().
06089 { 06090 struct ast_var_t *current, *newvar; 06091 const char *varname; 06092 06093 AST_LIST_TRAVERSE(&parent->varshead, current, entries) { 06094 int vartype = 0; 06095 06096 varname = ast_var_full_name(current); 06097 if (!varname) 06098 continue; 06099 06100 if (varname[0] == '_') { 06101 vartype = 1; 06102 if (varname[1] == '_') 06103 vartype = 2; 06104 } 06105 06106 switch (vartype) { 06107 case 1: 06108 newvar = ast_var_assign(&varname[1], ast_var_value(current)); 06109 if (newvar) { 06110 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 06111 ast_debug(1, "Copying soft-transferable variable %s.\n", ast_var_name(newvar)); 06112 } 06113 break; 06114 case 2: 06115 newvar = ast_var_assign(varname, ast_var_value(current)); 06116 if (newvar) { 06117 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 06118 ast_debug(1, "Copying hard-transferable variable %s.\n", ast_var_name(newvar)); 06119 } 06120 break; 06121 default: 06122 ast_debug(1, "Not copying variable %s.\n", ast_var_name(current)); 06123 break; 06124 } 06125 } 06126 }
struct ast_channel_iterator* ast_channel_iterator_all_new | ( | void | ) |
Create a new channel iterator.
After creating an iterator using this function, the ast_channel_iterator_next() function can be used to iterate through all channels that exist.
NULL | on failure | |
a | new channel iterator |
Definition at line 1662 of file channel.c.
References ao2_iterator_init(), ast_calloc, channels, and ast_channel_iterator::simple_iterator.
Referenced by action_coreshowchannels(), action_status(), ast_complete_channels(), ast_var_channel_bridge(), ast_var_channel_types_table(), ast_var_channels_table(), common_exec(), data_channels_provider_handler(), func_channels_read(), handle_chanlist(), and handle_softhangup().
01663 { 01664 struct ast_channel_iterator *i; 01665 01666 if (!(i = ast_calloc(1, sizeof(*i)))) { 01667 return NULL; 01668 } 01669 01670 i->simple_iterator = ao2_iterator_init(channels, 0); 01671 i->active_iterator = &i->simple_iterator; 01672 01673 return i; 01674 }
struct ast_channel_iterator* ast_channel_iterator_by_exten_new | ( | const char * | exten, | |
const char * | context | |||
) |
Create a new channel iterator based on extension.
NULL | on failure | |
a | new channel iterator based on the specified parameters |
Definition at line 1652 of file channel.c.
References channel_iterator_search().
Referenced by common_exec(), and pickup_by_exten().
01653 { 01654 return channel_iterator_search(NULL, 0, exten, context); 01655 }
struct ast_channel_iterator* ast_channel_iterator_by_name_new | ( | const char * | name, | |
size_t | name_len | |||
) |
Create a new channel iterator based on name.
NULL | on failure | |
a | new channel iterator based on the specified parameters |
Definition at line 1657 of file channel.c.
References channel_iterator_search().
Referenced by ast_complete_channels(), common_exec(), and softhangup_exec().
01658 { 01659 return channel_iterator_search(name, name_len, NULL, NULL); 01660 }
struct ast_channel_iterator* ast_channel_iterator_destroy | ( | struct ast_channel_iterator * | i | ) |
Destroy a channel iterator.
Definition at line 1610 of file channel.c.
References ast_channel_iterator::active_iterator, ao2_iterator_destroy(), and ast_free.
Referenced by action_coreshowchannels(), ast_complete_channels(), ast_var_channel_bridge(), ast_var_channel_types_table(), ast_var_channels_table(), common_exec(), data_channels_provider_handler(), func_channels_read(), handle_chanlist(), handle_softhangup(), pickup_by_exten(), and softhangup_exec().
01611 { 01612 ao2_iterator_destroy(i->active_iterator); 01613 ast_free(i); 01614 01615 return NULL; 01616 }
struct ast_channel* ast_channel_iterator_next | ( | struct ast_channel_iterator * | i | ) |
Get the next channel for a channel iterator.
the | next channel that matches the parameters used when the iterator was created. | |
NULL,if | no more channels match the iterator parameters. |
Definition at line 1676 of file channel.c.
References ast_channel_iterator::active_iterator, and ao2_iterator_next.
Referenced by action_coreshowchannels(), action_status(), ast_complete_channels(), ast_var_channel_bridge(), ast_var_channel_types_table(), ast_var_channels_table(), data_channels_provider_handler(), func_channels_read(), handle_chanlist(), handle_softhangup(), next_channel(), pickup_by_exten(), and softhangup_exec().
01677 { 01678 return ao2_iterator_next(i->active_iterator); 01679 }
int ast_channel_make_compatible | ( | struct ast_channel * | c0, | |
struct ast_channel * | c1 | |||
) |
Makes two channel formats compatible.
c0 | first channel to make compatible | |
c1 | other channel to make compatible |
Definition at line 5819 of file channel.c.
References ast_channel_make_compatible_helper(), and chanlist::chan.
Referenced by action_bridge(), app_exec(), ast_channel_bridge(), bridge_exec(), check_compat(), dial_exec_full(), do_forward(), multiplexed_bridge_join(), parked_call_exec(), simple_bridge_join(), and wait_for_answer().
05820 { 05821 /* Some callers do not check return code, and we must try to set all call legs correctly */ 05822 int rc = 0; 05823 05824 /* Set up translation from the chan to the peer */ 05825 rc = ast_channel_make_compatible_helper(chan, peer); 05826 05827 if (rc < 0) 05828 return rc; 05829 05830 /* Set up translation from the peer to the chan */ 05831 rc = ast_channel_make_compatible_helper(peer, chan); 05832 05833 return rc; 05834 }
int ast_channel_masquerade | ( | struct ast_channel * | original, | |
struct ast_channel * | clone | |||
) |
Weird function made for call transfers.
original | channel to make a copy of | |
clone | copy of the original channel |
Definition at line 5959 of file channel.c.
References __ast_channel_masquerade().
Referenced by ast_async_goto(), ast_do_pickup(), attempt_transfer(), builtin_atxfer(), check_availability(), check_bridge(), check_goto_on_transfer(), do_bridge_masquerade(), handle_invite_replaces(), iax_park(), masq_park_call(), sip_park(), and skinny_transfer().
05960 { 05961 return __ast_channel_masquerade(original, clone, NULL); 05962 }
int ast_channel_queryoption | ( | struct ast_channel * | channel, | |
int | option, | |||
void * | data, | |||
int * | datalen, | |||
int | block | |||
) |
Checks the value of an option.
Query the value of an option Works similarly to setoption except only reads the options.
Definition at line 7554 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_log(), chanlist::chan, errno, LOG_ERROR, ast_channel_tech::queryoption, and ast_channel::tech.
Referenced by ast_channel_get_cc_agent_type(), ast_channel_get_device_name(), ast_channel_get_t38_state(), local_queryoption(), rcvfax_exec(), and sndfax_exec().
07555 { 07556 int res; 07557 07558 ast_channel_lock(chan); 07559 if (!chan->tech->queryoption) { 07560 errno = ENOSYS; 07561 ast_channel_unlock(chan); 07562 return -1; 07563 } 07564 07565 if (block) 07566 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 07567 07568 res = chan->tech->queryoption(chan, option, data, datalen); 07569 ast_channel_unlock(chan); 07570 07571 return res; 07572 }
void ast_channel_queue_connected_line_update | ( | struct ast_channel * | chan, | |
const struct ast_party_connected_line * | connected, | |||
const struct ast_set_party_connected_line * | update | |||
) |
Queue a connected line update frame on a channel.
chan | Asterisk channel to indicate connected line information | |
connected | Connected line information | |
update | What connected line information to update. NULL if all. |
Definition at line 8802 of file channel.c.
References ast_connected_line_build_data(), AST_CONTROL_CONNECTED_LINE, ast_queue_control_data(), connected, and update().
Referenced by ast_do_pickup(), handle_request_invite(), handle_request_update(), handle_response_invite(), local_attended_transfer(), masquerade_colp_transfer(), misdn_queue_connected_line_update(), sig_pri_handle_subcmds(), and sip_call().
08803 { 08804 unsigned char data[1024]; /* This should be large enough */ 08805 size_t datalen; 08806 08807 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update); 08808 if (datalen == (size_t) -1) { 08809 return; 08810 } 08811 08812 ast_queue_control_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen); 08813 }
void ast_channel_queue_redirecting_update | ( | struct ast_channel * | chan, | |
const struct ast_party_redirecting * | redirecting, | |||
const struct ast_set_party_redirecting * | update | |||
) |
Queue a redirecting update frame on a channel.
chan | Asterisk channel to indicate redirecting id information | |
redirecting | Redirecting id information | |
update | What redirecting information to update. NULL if all. |
Definition at line 9309 of file channel.c.
References AST_CONTROL_REDIRECTING, ast_queue_control_data(), ast_redirecting_build_data(), and update().
Referenced by cb_events(), handle_response_invite(), misdn_facility_ie_handler(), and sig_pri_handle_subcmds().
09310 { 09311 unsigned char data[1024]; /* This should be large enough */ 09312 size_t datalen; 09313 09314 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update); 09315 if (datalen == (size_t) -1) { 09316 return; 09317 } 09318 09319 ast_queue_control_data(chan, AST_CONTROL_REDIRECTING, data, datalen); 09320 }
const char* ast_channel_reason2str | ( | int | reason | ) |
return an english explanation of the code returned thru __ast_request_and_dial's 'outstate' argument
reason | The integer argument, usually taken from AST_CONTROL_ macros |
Definition at line 5163 of file channel.c.
References AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_RING, and AST_CONTROL_RINGING.
Referenced by attempt_thread().
05164 { 05165 switch (reason) /* the following appear to be the only ones actually returned by request_and_dial */ 05166 { 05167 case 0: 05168 return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)"; 05169 case AST_CONTROL_HANGUP: 05170 return "Hangup"; 05171 case AST_CONTROL_RING: 05172 return "Local Ring"; 05173 case AST_CONTROL_RINGING: 05174 return "Remote end Ringing"; 05175 case AST_CONTROL_ANSWER: 05176 return "Remote end has Answered"; 05177 case AST_CONTROL_BUSY: 05178 return "Remote end is Busy"; 05179 case AST_CONTROL_CONGESTION: 05180 return "Congestion (circuits busy)"; 05181 default: 05182 return "Unknown Reason!!"; 05183 } 05184 }
int ast_channel_redirecting_macro | ( | struct ast_channel * | autoservice_chan, | |
struct ast_channel * | macro_chan, | |||
const void * | redirecting_info, | |||
int | is_caller, | |||
int | is_frame | |||
) |
Run a redirecting interception macro and update a channel's redirecting information.
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. |
0 | Success | |
-1 | Either the macro does not exist, or there was an error while attempting to run the macro |
Make constants so that caller and frame can be more expressive than just '1' and '0'
Definition at line 9361 of file channel.c.
References ast_app_run_macro(), ast_channel_lock, ast_channel_unlock, ast_channel_update_redirecting(), ast_party_redirecting_copy(), ast_redirecting_parse_data(), ast_strdupa, ast_strlen_zero(), ast_frame::data, ast_frame::datalen, pbx_builtin_getvar_helper(), ast_frame::ptr, ast_channel::redirecting, and S_OR.
Referenced by ast_bridge_call(), call_forward_inherit(), do_forward(), feature_request_and_dial(), handle_frame(), and remote_bridge_loop().
09362 { 09363 const char *macro; 09364 const char *macro_args; 09365 int retval; 09366 09367 ast_channel_lock(macro_chan); 09368 macro = pbx_builtin_getvar_helper(macro_chan, is_caller 09369 ? "REDIRECTING_CALLER_SEND_MACRO" : "REDIRECTING_CALLEE_SEND_MACRO"); 09370 macro = ast_strdupa(S_OR(macro, "")); 09371 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller 09372 ? "REDIRECTING_CALLER_SEND_MACRO_ARGS" : "REDIRECTING_CALLEE_SEND_MACRO_ARGS"); 09373 macro_args = ast_strdupa(S_OR(macro_args, "")); 09374 09375 if (ast_strlen_zero(macro)) { 09376 ast_channel_unlock(macro_chan); 09377 return -1; 09378 } 09379 09380 if (is_frame) { 09381 const struct ast_frame *frame = redirecting_info; 09382 09383 ast_redirecting_parse_data(frame->data.ptr, frame->datalen, ¯o_chan->redirecting); 09384 } else { 09385 const struct ast_party_redirecting *redirecting = redirecting_info; 09386 09387 ast_party_redirecting_copy(¯o_chan->redirecting, redirecting); 09388 } 09389 ast_channel_unlock(macro_chan); 09390 09391 retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args); 09392 if (!retval) { 09393 ast_channel_lock(macro_chan); 09394 ast_channel_update_redirecting(macro_chan, ¯o_chan->redirecting, NULL); 09395 ast_channel_unlock(macro_chan); 09396 } 09397 09398 return retval; 09399 }
int ast_channel_register | ( | const struct ast_channel_tech * | tech | ) |
Register a channel technology (a new channel driver) Called by a channel module to register the kind of channels it supports.
tech | Structure defining channel technology or "type" |
Definition at line 886 of file channel.c.
References ast_calloc, ast_debug, ast_log(), AST_RWLIST_INSERT_HEAD, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, chanlist::chan, chanlist::list, LOG_WARNING, chanlist::tech, ast_channel::tech, and ast_channel_tech::type.
Referenced by load_module(), and unload_module().
00887 { 00888 struct chanlist *chan; 00889 00890 AST_RWLIST_WRLOCK(&backends); 00891 00892 AST_RWLIST_TRAVERSE(&backends, chan, list) { 00893 if (!strcasecmp(tech->type, chan->tech->type)) { 00894 ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type); 00895 AST_RWLIST_UNLOCK(&backends); 00896 return -1; 00897 } 00898 } 00899 00900 if (!(chan = ast_calloc(1, sizeof(*chan)))) { 00901 AST_RWLIST_UNLOCK(&backends); 00902 return -1; 00903 } 00904 chan->tech = tech; 00905 AST_RWLIST_INSERT_HEAD(&backends, chan, list); 00906 00907 ast_debug(1, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description); 00908 00909 ast_verb(2, "Registered channel type '%s' (%s)\n", chan->tech->type, chan->tech->description); 00910 00911 AST_RWLIST_UNLOCK(&backends); 00912 00913 return 0; 00914 }
struct ast_channel* ast_channel_release | ( | struct ast_channel * | chan | ) |
Unlink and release reference to a channel.
This function will unlink the channel from the global channels container if it is still there and also release the current reference to the channel.
Definition at line 1878 of file channel.c.
References ao2_unlink, ast_channel_unref, chanlist::chan, and channels.
Referenced by agent_cleanup(), ast_do_masquerade(), ast_iax2_new(), ast_request(), bridge_request(), do_notify(), gtalk_newcall(), local_new(), and local_request().
01879 { 01880 /* Safe, even if already unlinked. */ 01881 ao2_unlink(channels, chan); 01882 return ast_channel_unref(chan); 01883 }
int ast_channel_sendhtml | ( | struct ast_channel * | channel, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) |
Sends HTML on given channel Send HTML or URL on link.
Definition at line 5756 of file channel.c.
References chanlist::chan, ast_channel_tech::send_html, and ast_channel::tech.
Referenced by agent_sendhtml(), and ast_channel_sendurl().
05757 { 05758 if (chan->tech->send_html) 05759 return chan->tech->send_html(chan, subclass, data, datalen); 05760 return -1; 05761 }
int ast_channel_sendurl | ( | struct ast_channel * | channel, | |
const char * | url | |||
) |
Sends a URL on a given link Send URL on link.
Definition at line 5763 of file channel.c.
References ast_channel_sendhtml(), AST_HTML_URL, and chanlist::chan.
Referenced by dial_exec_full(), and sendurl_exec().
05764 { 05765 return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1); 05766 }
void ast_channel_set_caller | ( | struct ast_channel * | chan, | |
const struct ast_party_caller * | caller, | |||
const struct ast_set_party_caller * | update | |||
) |
Set the caller id information in the Asterisk channel.
chan | Asterisk channel to set caller id information | |
caller | Caller id information | |
update | What caller information to update. NULL if all. |
Definition at line 6839 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_party_caller_set(), ast_channel::caller, chanlist::chan, and update().
06840 { 06841 if (&chan->caller == caller) { 06842 /* Don't set to self */ 06843 return; 06844 } 06845 06846 ast_channel_lock(chan); 06847 ast_party_caller_set(&chan->caller, caller, update); 06848 ast_channel_unlock(chan); 06849 }
void ast_channel_set_caller_event | ( | struct ast_channel * | chan, | |
const struct ast_party_caller * | caller, | |||
const struct ast_set_party_caller * | update | |||
) |
Set the caller id information in the Asterisk channel and generate an AMI event if the caller id name or number changed.
chan | Asterisk channel to set caller id information | |
caller | Caller id information | |
update | What caller information to update. NULL if all. |
Definition at line 6851 of file channel.c.
References ast_cdr_setcid(), ast_channel_lock, ast_channel_unlock, ast_party_caller_set(), ast_channel::caller, ast_channel::cdr, chanlist::chan, ast_party_caller::id, ast_party_id::name, ast_party_id::number, report_new_callerid(), S_COR, ast_party_number::str, ast_party_name::str, update(), ast_party_number::valid, and ast_party_name::valid.
Referenced by callerid_write(), dial_exec_full(), do_forward(), misdn_update_caller_id(), ring_entry(), and sig_pri_handle_subcmds().
06852 { 06853 const char *pre_set_number; 06854 const char *pre_set_name; 06855 06856 if (&chan->caller == caller) { 06857 /* Don't set to self */ 06858 return; 06859 } 06860 06861 ast_channel_lock(chan); 06862 pre_set_number = 06863 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL); 06864 pre_set_name = S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL); 06865 ast_party_caller_set(&chan->caller, caller, update); 06866 if (S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL) 06867 != pre_set_number 06868 || S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL) 06869 != pre_set_name) { 06870 /* The caller id name or number changed. */ 06871 report_new_callerid(chan); 06872 } 06873 if (chan->cdr) { 06874 ast_cdr_setcid(chan->cdr, chan); 06875 } 06876 ast_channel_unlock(chan); 06877 }
void ast_channel_set_connected_line | ( | struct ast_channel * | chan, | |
const struct ast_party_connected_line * | connected, | |||
const struct ast_set_party_connected_line * | update | |||
) |
Set the connected line information in the Asterisk channel.
chan | Asterisk channel to set connected line information | |
connected | Connected line information | |
update | What connected line information to update. NULL if all. |
Definition at line 8162 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_party_connected_line_set(), ast_channel::connected, connected, and update().
Referenced by __ast_request_and_dial(), ast_indicate_data(), connectedline_write(), dial_exec_full(), and feature_request_and_dial().
08163 { 08164 if (&chan->connected == connected) { 08165 /* Don't set to self */ 08166 return; 08167 } 08168 08169 ast_channel_lock(chan); 08170 ast_party_connected_line_set(&chan->connected, connected, update); 08171 ast_channel_unlock(chan); 08172 }
void ast_channel_set_fd | ( | struct ast_channel * | chan, | |
int | which, | |||
int | fd | |||
) |
Set the file descriptor on the channel
Definition at line 2576 of file channel.c.
References ast_calloc, chanlist::chan, ast_channel::data, ast_channel::fds, and free.
Referenced by __ast_channel_alloc_ap(), __oh323_new(), __oh323_rtp_create(), __oh323_update_info(), alsa_new(), ast_deactivate_generator(), ast_do_masquerade(), dahdi_new(), gtalk_new(), initialize_udptl(), jingle_new(), mgcp_new(), misdn_new(), my_swap_subchannels(), nbs_new(), oss_new(), phone_new(), process_sdp(), setformat(), sip_new(), skinny_new(), start_rtp(), and swap_subs().
02577 { 02578 #ifdef HAVE_EPOLL 02579 struct epoll_event ev; 02580 struct ast_epoll_data *aed = NULL; 02581 02582 if (chan->fds[which] > -1) { 02583 epoll_ctl(chan->epfd, EPOLL_CTL_DEL, chan->fds[which], &ev); 02584 aed = chan->epfd_data[which]; 02585 } 02586 02587 /* If this new fd is valid, add it to the epoll */ 02588 if (fd > -1) { 02589 if (!aed && (!(aed = ast_calloc(1, sizeof(*aed))))) 02590 return; 02591 02592 chan->epfd_data[which] = aed; 02593 aed->chan = chan; 02594 aed->which = which; 02595 02596 ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP; 02597 ev.data.ptr = aed; 02598 epoll_ctl(chan->epfd, EPOLL_CTL_ADD, fd, &ev); 02599 } else if (aed) { 02600 /* We don't have to keep around this epoll data structure now */ 02601 free(aed); 02602 chan->epfd_data[which] = NULL; 02603 } 02604 #endif 02605 chan->fds[which] = fd; 02606 return; 02607 }
void ast_channel_set_linkgroup | ( | struct ast_channel * | chan, | |
struct ast_channel * | peer | |||
) |
propagate the linked id between chan and peer
Definition at line 6232 of file channel.c.
References ast_channel::_bridge, ast_bridged_channel(), ast_channel_change_linkedid(), ast_strdupa, chanlist::chan, ast_channel::linkedid, oldest_linkedid(), and ast_channel::uniqueid.
Referenced by ast_bridge_call(), and ast_do_masquerade().
06233 { 06234 const char* linkedid=NULL; 06235 struct ast_channel *bridged; 06236 06237 linkedid = oldest_linkedid(chan->linkedid, peer->linkedid); 06238 linkedid = oldest_linkedid(linkedid, chan->uniqueid); 06239 linkedid = oldest_linkedid(linkedid, peer->uniqueid); 06240 if (chan->_bridge) { 06241 bridged = ast_bridged_channel(chan); 06242 if (bridged != peer) { 06243 linkedid = oldest_linkedid(linkedid, bridged->linkedid); 06244 linkedid = oldest_linkedid(linkedid, bridged->uniqueid); 06245 } 06246 } 06247 if (peer->_bridge) { 06248 bridged = ast_bridged_channel(peer); 06249 if (bridged != chan) { 06250 linkedid = oldest_linkedid(linkedid, bridged->linkedid); 06251 linkedid = oldest_linkedid(linkedid, bridged->uniqueid); 06252 } 06253 } 06254 06255 /* just in case setting a stringfield to itself causes problems */ 06256 linkedid = ast_strdupa(linkedid); 06257 06258 ast_channel_change_linkedid(chan, linkedid); 06259 ast_channel_change_linkedid(peer, linkedid); 06260 if (chan->_bridge) { 06261 bridged = ast_bridged_channel(chan); 06262 if (bridged != peer) { 06263 ast_channel_change_linkedid(bridged, linkedid); 06264 } 06265 } 06266 if (peer->_bridge) { 06267 bridged = ast_bridged_channel(peer); 06268 if (bridged != chan) { 06269 ast_channel_change_linkedid(bridged, linkedid); 06270 } 06271 } 06272 }
void ast_channel_set_redirecting | ( | struct ast_channel * | chan, | |
const struct ast_party_redirecting * | redirecting, | |||
const struct ast_set_party_redirecting * | update | |||
) |
Set the redirecting id information in the Asterisk channel.
chan | Asterisk channel to set redirecting id information | |
redirecting | Redirecting id information | |
update | What redirecting information to update. NULL if all. |
Definition at line 8815 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_party_redirecting_set(), ast_channel::redirecting, and update().
Referenced by ast_indicate_data(), do_forward(), handle_request_invite(), handle_response(), misdn_copy_redirecting_to_ast(), redirecting_write(), and sig_pri_handle_subcmds().
08816 { 08817 if (&chan->redirecting == redirecting) { 08818 /* Don't set to self */ 08819 return; 08820 } 08821 08822 ast_channel_lock(chan); 08823 ast_party_redirecting_set(&chan->redirecting, redirecting, update); 08824 ast_channel_unlock(chan); 08825 }
int ast_channel_setoption | ( | struct ast_channel * | channel, | |
int | option, | |||
void * | data, | |||
int | datalen, | |||
int | block | |||
) |
Sets an option on a channel.
channel | channel to set options on | |
option | option to change | |
data | data specific to option | |
datalen | length of the data | |
block | blocking or not |
Definition at line 7534 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_log(), chanlist::chan, errno, LOG_ERROR, ast_channel_tech::setoption, and ast_channel::tech.
Referenced by analog_hangup(), ast_bridge_call(), ast_channel_make_compatible_helper(), common_exec(), conf_run(), dahdi_hangup(), dial_exec_full(), func_channel_write(), func_channel_write_real(), handle_tddmode(), play_record_review(), rcvfax_exec(), reset_volumes(), rpt(), rpt_exec(), set_format(), set_listen_volume(), set_security_requirements(), set_talk_volume(), sndfax_exec(), and vm_forwardoptions().
07535 { 07536 int res; 07537 07538 ast_channel_lock(chan); 07539 if (!chan->tech->setoption) { 07540 errno = ENOSYS; 07541 ast_channel_unlock(chan); 07542 return -1; 07543 } 07544 07545 if (block) 07546 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 07547 07548 res = chan->tech->setoption(chan, option, data, datalen); 07549 ast_channel_unlock(chan); 07550 07551 return res; 07552 }
void ast_channel_setwhentohangup | ( | struct ast_channel * | chan, | |
time_t | offset | |||
) |
Set when to hang a channel up.
chan | channel on which to check for hang up | |
offset | offset in seconds relative to the current time of when to hang up |
Definition at line 857 of file channel.c.
References ast_channel_setwhentohangup_tv(), and chanlist::chan.
00858 { 00859 struct timeval when = { offset, }; 00860 ast_channel_setwhentohangup_tv(chan, when); 00861 }
void ast_channel_setwhentohangup_tv | ( | struct ast_channel * | chan, | |
struct timeval | offset | |||
) |
Set when to hang a channel up.
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 |
Definition at line 850 of file channel.c.
References ast_null_frame, ast_queue_frame(), ast_tvadd(), ast_tvnow(), ast_tvzero(), chanlist::chan, and ast_channel::whentohangup.
Referenced by action_timeout(), ast_channel_setwhentohangup(), handle_autohangup(), sig_pri_send_aoce_termination_request(), and timeout_write().
00851 { 00852 chan->whentohangup = ast_tvzero(offset) ? offset : ast_tvadd(offset, ast_tvnow()); 00853 ast_queue_frame(chan, &ast_null_frame); 00854 return; 00855 }
struct ast_silence_generator* ast_channel_start_silence_generator | ( | struct ast_channel * | chan | ) |
Starts a silence generator on the given channel.
chan | The channel to generate silence on |
Definition at line 8036 of file channel.c.
References ast_activate_generator(), ast_calloc, ast_debug, AST_FORMAT_SLINEAR, ast_free, ast_log(), ast_set_write_format(), LOG_ERROR, ast_channel::name, ast_silence_generator::old_write_format, silence_generator, state, and ast_channel::writeformat.
Referenced by __ast_play_and_record(), ast_bridge_call(), ast_dtmf_stream(), ast_readstring_full(), ast_safe_sleep_conditional(), channel_spy(), TransferCallStep1(), waitfor_exec(), and waitforring_exec().
08037 { 08038 struct ast_silence_generator *state; 08039 08040 if (!(state = ast_calloc(1, sizeof(*state)))) { 08041 return NULL; 08042 } 08043 08044 state->old_write_format = chan->writeformat; 08045 08046 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) { 08047 ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n"); 08048 ast_free(state); 08049 return NULL; 08050 } 08051 08052 ast_activate_generator(chan, &silence_generator, state); 08053 08054 ast_debug(1, "Started silence generator on '%s'\n", chan->name); 08055 08056 return state; 08057 }
void ast_channel_stop_silence_generator | ( | struct ast_channel * | chan, | |
struct ast_silence_generator * | state | |||
) |
Stops a previously-started silence generator on the given channel.
chan | The channel to operate on | |
state | The ast_silence_generator pointer return by a previous call to ast_channel_start_silence_generator. |
Definition at line 8059 of file channel.c.
References ast_deactivate_generator(), ast_debug, ast_free, ast_log(), ast_set_write_format(), LOG_ERROR, ast_channel::name, and state.
Referenced by ast_bridge_call(), ast_dtmf_stream(), ast_readstring_full(), ast_safe_sleep_conditional(), channel_spy(), HandleCallOutgoing(), key_dial_page(), unistim_hangup(), waitfor_exec(), and waitforring_exec().
08060 { 08061 if (!state) 08062 return; 08063 08064 ast_deactivate_generator(chan); 08065 08066 ast_debug(1, "Stopped silence generator on '%s'\n", chan->name); 08067 08068 if (ast_set_write_format(chan, state->old_write_format) < 0) 08069 ast_log(LOG_ERROR, "Could not return write format to its original state\n"); 08070 08071 ast_free(state); 08072 }
int ast_channel_supports_html | ( | struct ast_channel * | channel | ) |
Checks for HTML support on a channel.
Definition at line 5751 of file channel.c.
References chanlist::chan, ast_channel_tech::send_html, and ast_channel::tech.
Referenced by dial_exec_full(), and sendurl_exec().
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.
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 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.
0 | on success. | |
-1 | on error. |
Definition at line 6033 of file channel.c.
References __ast_channel_masquerade(), ast_calloc, ast_datastore_alloc, ast_datastore_free(), ast_datastore::data, party_connected_line_copy_transfer(), xfer_masquerade_ds::target_id, xfer_masquerade_ds::transferee_id, and xfer_ds_info.
Referenced by analog_attempt_transfer(), misdn_attempt_transfer(), and sig_pri_attempt_transfer().
06040 { 06041 struct ast_datastore *xfer_ds; 06042 struct xfer_masquerade_ds *xfer_colp; 06043 int res; 06044 06045 xfer_ds = ast_datastore_alloc(&xfer_ds_info, NULL); 06046 if (!xfer_ds) { 06047 return -1; 06048 } 06049 06050 xfer_colp = ast_calloc(1, sizeof(*xfer_colp)); 06051 if (!xfer_colp) { 06052 ast_datastore_free(xfer_ds); 06053 return -1; 06054 } 06055 party_connected_line_copy_transfer(&xfer_colp->target_id, target_id); 06056 xfer_colp->target_held = target_held; 06057 party_connected_line_copy_transfer(&xfer_colp->transferee_id, transferee_id); 06058 xfer_colp->transferee_held = transferee_held; 06059 xfer_ds->data = xfer_colp; 06060 06061 res = __ast_channel_masquerade(target_chan, transferee_chan, xfer_ds); 06062 if (res) { 06063 ast_datastore_free(xfer_ds); 06064 } 06065 return res; 06066 }
void ast_channel_undefer_dtmf | ( | struct ast_channel * | chan | ) |
Unset defer DTMF flag on channel.
Undo defer. ast_read will return any DTMF characters that were queued
Definition at line 1589 of file channel.c.
References ast_clear_flag, AST_FLAG_DEFER_DTMF, and chanlist::chan.
Referenced by find_cache(), and rpt_call().
01590 { 01591 if (chan) 01592 ast_clear_flag(chan, AST_FLAG_DEFER_DTMF); 01593 }
void ast_channel_unregister | ( | const struct ast_channel_tech * | tech | ) |
Unregister a channel technology.
tech | Structure defining channel technology or "type" that was previously registered |
Definition at line 917 of file channel.c.
References ast_debug, ast_free, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_END, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, chanlist::chan, chanlist::list, chanlist::tech, ast_channel::tech, and ast_channel_tech::type.
Referenced by __unload_module(), load_module(), and unload_module().
00918 { 00919 struct chanlist *chan; 00920 00921 ast_debug(1, "Unregistering channel type '%s'\n", tech->type); 00922 00923 AST_RWLIST_WRLOCK(&backends); 00924 00925 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) { 00926 if (chan->tech == tech) { 00927 AST_LIST_REMOVE_CURRENT(list); 00928 ast_free(chan); 00929 ast_verb(2, "Unregistered channel type '%s'\n", tech->type); 00930 break; 00931 } 00932 } 00933 AST_LIST_TRAVERSE_SAFE_END; 00934 00935 AST_RWLIST_UNLOCK(&backends); 00936 }
void ast_channel_update_connected_line | ( | struct ast_channel * | chan, | |
const struct ast_party_connected_line * | connected, | |||
const struct ast_set_party_connected_line * | update | |||
) |
Indicate that the connected line information has changed.
chan | Asterisk channel to indicate connected line information | |
connected | Connected line information | |
update | What connected line information to update. NULL if all. |
Definition at line 8789 of file channel.c.
References ast_connected_line_build_data(), AST_CONTROL_CONNECTED_LINE, ast_indicate_data(), connected, and update().
Referenced by app_exec(), ast_channel_connected_line_macro(), ast_do_pickup(), atxfer_fail_cleanup(), builtin_atxfer(), connectedline_write(), parked_call_exec(), and wait_for_answer().
08790 { 08791 unsigned char data[1024]; /* This should be large enough */ 08792 size_t datalen; 08793 08794 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update); 08795 if (datalen == (size_t) -1) { 08796 return; 08797 } 08798 08799 ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen); 08800 }
void ast_channel_update_redirecting | ( | struct ast_channel * | chan, | |
const struct ast_party_redirecting * | redirecting, | |||
const struct ast_set_party_redirecting * | update | |||
) |
Indicate that the redirecting id has changed.
chan | Asterisk channel to indicate redirecting id information | |
redirecting | Redirecting id information | |
update | What redirecting information to update. NULL if all. |
Definition at line 9296 of file channel.c.
References AST_CONTROL_REDIRECTING, ast_indicate_data(), ast_redirecting_build_data(), and update().
Referenced by ast_channel_redirecting_macro(), call_forward_inherit(), do_forward(), and redirecting_write().
09297 { 09298 unsigned char data[1024]; /* This should be large enough */ 09299 size_t datalen; 09300 09301 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update); 09302 if (datalen == (size_t) -1) { 09303 return; 09304 } 09305 09306 ast_indicate_data(chan, AST_CONTROL_REDIRECTING, data, datalen); 09307 }
struct ast_variable* ast_channeltype_list | ( | void | ) |
return an ast_variable list of channeltypes
Definition at line 247 of file channel.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_variable_new(), ast_channel_tech::description, chanlist::list, chanlist::tech, ast_channel_tech::type, and var.
Referenced by ast_var_channel_types(), and ast_var_channel_types_table().
00248 { 00249 struct chanlist *cl; 00250 struct ast_variable *var = NULL, *prev = NULL; 00251 00252 AST_RWLIST_RDLOCK(&backends); 00253 AST_RWLIST_TRAVERSE(&backends, cl, list) { 00254 if (prev) { 00255 if ((prev->next = ast_variable_new(cl->tech->type, cl->tech->description, ""))) 00256 prev = prev->next; 00257 } else { 00258 var = ast_variable_new(cl->tech->type, cl->tech->description, ""); 00259 prev = var; 00260 } 00261 } 00262 AST_RWLIST_UNLOCK(&backends); 00263 00264 return var; 00265 }
int ast_check_hangup | ( | struct ast_channel * | chan | ) |
Check to see if a channel is needing hang up.
chan | channel on which to check for hang up This function determines if the channel is being requested to be hung up. |
Definition at line 791 of file channel.c.
References ast_channel::_softhangup, ast_debug, AST_SOFTHANGUP_TIMEOUT, ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), chanlist::chan, and ast_channel::whentohangup.
Referenced by __ast_pbx_run(), __ast_read(), _macro_exec(), agent_indicate(), agi_exec(), agi_handle_command(), announce_thread(), ast_bridge_call(), ast_call(), ast_channel_bridge(), ast_check_hangup_locked(), ast_indicate_data(), ast_raw_answer(), ast_readstring_full(), ast_recvtext(), ast_rtp_instance_bridge(), ast_sendtext(), ast_transfer(), ast_udptl_bridge(), ast_waitfordigit_full(), ast_write(), autoservice_run(), bridge_call_thread(), bridge_exec(), builtin_atxfer(), call_forward_inherit(), channel_spy(), check_bridge(), common_exec(), conf_play(), conf_run(), dahdi_sendtext(), dahdi_setoption(), dial_exec_full(), dundi_lookup_internal(), eagi_exec(), eivr_comm(), feature_request_and_dial(), findmeexec(), func_channel_read(), handle_sendimage(), launch_asyncagi(), local_fixup(), lua_check_hangup(), ospfinished_exec(), pbx_builtin_incomplete(), pbx_builtin_waitexten(), pbx_exec(), read_exec(), readexten_exec(), remote_bridge_loop(), rpt(), run_agi(), and run_ras().
00792 { 00793 if (chan->_softhangup) /* yes if soft hangup flag set */ 00794 return 1; 00795 if (ast_tvzero(chan->whentohangup)) /* no if no hangup scheduled */ 00796 return 0; 00797 if (ast_tvdiff_ms(chan->whentohangup, ast_tvnow()) > 0) /* no if hangup time has not come yet. */ 00798 return 0; 00799 ast_debug(4, "Hangup time has come: %" PRIi64 "\n", ast_tvdiff_ms(chan->whentohangup, ast_tvnow())); 00800 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT; /* record event */ 00801 return 1; 00802 }
int ast_check_hangup_locked | ( | struct ast_channel * | chan | ) |
Definition at line 804 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_check_hangup(), and chanlist::chan.
Referenced by action_redirect(), and ast_channel_bridge().
00805 { 00806 int res; 00807 ast_channel_lock(chan); 00808 res = ast_check_hangup(chan); 00809 ast_channel_unlock(chan); 00810 return res; 00811 }
int ast_connected_line_build_data | ( | unsigned char * | data, | |
size_t | datalen, | |||
const struct ast_party_connected_line * | connected, | |||
const struct ast_set_party_connected_line * | update | |||
) |
Build the connected line information data frame.
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. |
-1 | if error | |
Amount | of data buffer used |
Definition at line 8529 of file channel.c.
References AST_CONNECTED_LINE_ID_PRESENTATION, AST_CONNECTED_LINE_NAME, AST_CONNECTED_LINE_NAME_CHAR_SET, AST_CONNECTED_LINE_NAME_PRESENTATION, AST_CONNECTED_LINE_NAME_VALID, AST_CONNECTED_LINE_NUMBER, AST_CONNECTED_LINE_NUMBER_PLAN, AST_CONNECTED_LINE_NUMBER_PRESENTATION, AST_CONNECTED_LINE_NUMBER_VALID, AST_CONNECTED_LINE_SOURCE, AST_CONNECTED_LINE_SUBADDRESS, AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN, AST_CONNECTED_LINE_SUBADDRESS_TYPE, AST_CONNECTED_LINE_SUBADDRESS_VALID, AST_CONNECTED_LINE_TAG, AST_CONNECTED_LINE_VERSION, ast_log(), connected, LOG_WARNING, ast_party_id_ies::name, party_id_build_data(), ast_party_name_ies::str, update(), and value.
Referenced by ast_channel_queue_connected_line_update(), ast_channel_update_connected_line(), local_attended_transfer(), local_indicate(), and masquerade_colp_transfer().
08530 { 08531 int32_t value; 08532 size_t pos = 0; 08533 int res; 08534 08535 static const struct ast_party_id_ies ies = { 08536 .name.str = AST_CONNECTED_LINE_NAME, 08537 .name.char_set = AST_CONNECTED_LINE_NAME_CHAR_SET, 08538 .name.presentation = AST_CONNECTED_LINE_NAME_PRESENTATION, 08539 .name.valid = AST_CONNECTED_LINE_NAME_VALID, 08540 08541 .number.str = AST_CONNECTED_LINE_NUMBER, 08542 .number.plan = AST_CONNECTED_LINE_NUMBER_PLAN, 08543 .number.presentation = AST_CONNECTED_LINE_NUMBER_PRESENTATION, 08544 .number.valid = AST_CONNECTED_LINE_NUMBER_VALID, 08545 08546 .subaddress.str = AST_CONNECTED_LINE_SUBADDRESS, 08547 .subaddress.type = AST_CONNECTED_LINE_SUBADDRESS_TYPE, 08548 .subaddress.odd_even_indicator = AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN, 08549 .subaddress.valid = AST_CONNECTED_LINE_SUBADDRESS_VALID, 08550 08551 .tag = AST_CONNECTED_LINE_TAG, 08552 .combined_presentation = AST_CONNECTED_LINE_ID_PRESENTATION, 08553 }; 08554 08555 /* 08556 * The size of integer values must be fixed in case the frame is 08557 * shipped to another machine. 08558 */ 08559 08560 /* Connected line frame version */ 08561 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08562 ast_log(LOG_WARNING, "No space left for connected line frame version\n"); 08563 return -1; 08564 } 08565 data[pos++] = AST_CONNECTED_LINE_VERSION; 08566 data[pos++] = 1; 08567 data[pos++] = 2;/* Version 1 did not have a version ie */ 08568 08569 res = party_id_build_data(data + pos, datalen - pos, &connected->id, 08570 "connected line", &ies, update ? &update->id : NULL); 08571 if (res < 0) { 08572 return -1; 08573 } 08574 pos += res; 08575 08576 /* Connected line source */ 08577 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) { 08578 ast_log(LOG_WARNING, "No space left for connected line source\n"); 08579 return -1; 08580 } 08581 data[pos++] = AST_CONNECTED_LINE_SOURCE; 08582 data[pos++] = sizeof(value); 08583 value = htonl(connected->source); 08584 memcpy(data + pos, &value, sizeof(value)); 08585 pos += sizeof(value); 08586 08587 return pos; 08588 }
void ast_connected_line_copy_from_caller | ( | struct ast_party_connected_line * | dest, | |
const struct ast_party_caller * | src | |||
) |
Copy the caller information to the connected line information.
dest | Destination connected line information | |
src | Source caller information |
Definition at line 8147 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 app_exec(), ast_do_pickup(), begin_dial_channel(), builtin_atxfer(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), local_call(), parked_call_exec(), ring_entry(), and wait_for_answer().
08148 { 08149 ast_party_id_copy(&dest->id, &src->id); 08150 ast_party_id_copy(&dest->ani, &src->ani); 08151 dest->ani2 = src->ani2; 08152 }
void ast_connected_line_copy_to_caller | ( | struct ast_party_caller * | dest, | |
const struct ast_party_connected_line * | src | |||
) |
Copy the connected line information to the caller information.
dest | Destination caller information | |
src | Source connected line information |
Definition at line 8154 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 local_call(), and local_indicate().
08155 { 08156 ast_party_id_copy(&dest->id, &src->id); 08157 ast_party_id_copy(&dest->ani, &src->ani); 08158 08159 dest->ani2 = src->ani2; 08160 }
int ast_connected_line_parse_data | ( | const unsigned char * | data, | |
size_t | datalen, | |||
struct ast_party_connected_line * | connected | |||
) |
Parse connected line indication frame data.
data | Buffer with the frame data to parse | |
datalen | Size of the buffer | |
connected | Extracted connected line information |
0 | on success. | |
-1 | on error. |
The filled in connected line structure needs to be destroyed by ast_party_connected_line_free() when it is no longer needed.
Definition at line 8590 of file channel.c.
References AST_CONNECTED_LINE_ID_PRESENTATION, AST_CONNECTED_LINE_NAME, AST_CONNECTED_LINE_NAME_CHAR_SET, AST_CONNECTED_LINE_NAME_PRESENTATION, AST_CONNECTED_LINE_NAME_VALID, AST_CONNECTED_LINE_NUMBER, AST_CONNECTED_LINE_NUMBER_PLAN, AST_CONNECTED_LINE_NUMBER_PRESENTATION, AST_CONNECTED_LINE_NUMBER_VALID, AST_CONNECTED_LINE_SOURCE, AST_CONNECTED_LINE_SUBADDRESS, AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN, AST_CONNECTED_LINE_SUBADDRESS_TYPE, AST_CONNECTED_LINE_SUBADDRESS_VALID, AST_CONNECTED_LINE_TAG, AST_CONNECTED_LINE_VERSION, ast_free, ast_log(), ast_malloc, AST_PARTY_CHAR_SET_ISO8859_1, ast_party_id_ies::combined_presentation, connected, LOG_DEBUG, LOG_WARNING, and value.
Referenced by __ast_read(), ast_channel_connected_line_macro(), ast_indicate_data(), feature_request_and_dial(), socket_process(), and wait_for_winner().
08591 { 08592 size_t pos; 08593 unsigned char ie_len; 08594 unsigned char ie_id; 08595 int32_t value; 08596 int frame_version = 1; 08597 int combined_presentation = 0; 08598 int got_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */ 08599 08600 for (pos = 0; pos < datalen; pos += ie_len) { 08601 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) { 08602 ast_log(LOG_WARNING, "Invalid connected line update\n"); 08603 return -1; 08604 } 08605 ie_id = data[pos++]; 08606 ie_len = data[pos++]; 08607 if (datalen < pos + ie_len) { 08608 ast_log(LOG_WARNING, "Invalid connected line update\n"); 08609 return -1; 08610 } 08611 08612 switch (ie_id) { 08613 /* Connected line party frame version */ 08614 case AST_CONNECTED_LINE_VERSION: 08615 if (ie_len != 1) { 08616 ast_log(LOG_WARNING, "Invalid connected line frame version (%u)\n", 08617 (unsigned) ie_len); 08618 break; 08619 } 08620 frame_version = data[pos]; 08621 break; 08622 /* Connected line party id name */ 08623 case AST_CONNECTED_LINE_NAME: 08624 ast_free(connected->id.name.str); 08625 connected->id.name.str = ast_malloc(ie_len + 1); 08626 if (connected->id.name.str) { 08627 memcpy(connected->id.name.str, data + pos, ie_len); 08628 connected->id.name.str[ie_len] = 0; 08629 } 08630 break; 08631 case AST_CONNECTED_LINE_NAME_CHAR_SET: 08632 if (ie_len != 1) { 08633 ast_log(LOG_WARNING, "Invalid connected line name char set (%u)\n", 08634 (unsigned) ie_len); 08635 break; 08636 } 08637 connected->id.name.char_set = data[pos]; 08638 break; 08639 case AST_CONNECTED_LINE_NAME_PRESENTATION: 08640 if (ie_len != 1) { 08641 ast_log(LOG_WARNING, "Invalid connected line name presentation (%u)\n", 08642 (unsigned) ie_len); 08643 break; 08644 } 08645 connected->id.name.presentation = data[pos]; 08646 break; 08647 case AST_CONNECTED_LINE_NAME_VALID: 08648 if (ie_len != 1) { 08649 ast_log(LOG_WARNING, "Invalid connected line name valid (%u)\n", 08650 (unsigned) ie_len); 08651 break; 08652 } 08653 connected->id.name.valid = data[pos]; 08654 break; 08655 /* Connected line party id number */ 08656 case AST_CONNECTED_LINE_NUMBER: 08657 ast_free(connected->id.number.str); 08658 connected->id.number.str = ast_malloc(ie_len + 1); 08659 if (connected->id.number.str) { 08660 memcpy(connected->id.number.str, data + pos, ie_len); 08661 connected->id.number.str[ie_len] = 0; 08662 } 08663 break; 08664 case AST_CONNECTED_LINE_NUMBER_PLAN: 08665 if (ie_len != 1) { 08666 ast_log(LOG_WARNING, "Invalid connected line numbering plan (%u)\n", 08667 (unsigned) ie_len); 08668 break; 08669 } 08670 connected->id.number.plan = data[pos]; 08671 break; 08672 case AST_CONNECTED_LINE_NUMBER_PRESENTATION: 08673 if (ie_len != 1) { 08674 ast_log(LOG_WARNING, "Invalid connected line number presentation (%u)\n", 08675 (unsigned) ie_len); 08676 break; 08677 } 08678 connected->id.number.presentation = data[pos]; 08679 break; 08680 case AST_CONNECTED_LINE_NUMBER_VALID: 08681 if (ie_len != 1) { 08682 ast_log(LOG_WARNING, "Invalid connected line number valid (%u)\n", 08683 (unsigned) ie_len); 08684 break; 08685 } 08686 connected->id.number.valid = data[pos]; 08687 break; 08688 /* Connected line party id combined presentation */ 08689 case AST_CONNECTED_LINE_ID_PRESENTATION: 08690 if (ie_len != 1) { 08691 ast_log(LOG_WARNING, "Invalid connected line combined presentation (%u)\n", 08692 (unsigned) ie_len); 08693 break; 08694 } 08695 combined_presentation = data[pos]; 08696 got_combined_presentation = 1; 08697 break; 08698 /* Connected line party id subaddress */ 08699 case AST_CONNECTED_LINE_SUBADDRESS: 08700 ast_free(connected->id.subaddress.str); 08701 connected->id.subaddress.str = ast_malloc(ie_len + 1); 08702 if (connected->id.subaddress.str) { 08703 memcpy(connected->id.subaddress.str, data + pos, ie_len); 08704 connected->id.subaddress.str[ie_len] = 0; 08705 } 08706 break; 08707 case AST_CONNECTED_LINE_SUBADDRESS_TYPE: 08708 if (ie_len != 1) { 08709 ast_log(LOG_WARNING, "Invalid connected line type of subaddress (%u)\n", 08710 (unsigned) ie_len); 08711 break; 08712 } 08713 connected->id.subaddress.type = data[pos]; 08714 break; 08715 case AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN: 08716 if (ie_len != 1) { 08717 ast_log(LOG_WARNING, 08718 "Invalid connected line subaddress odd-even indicator (%u)\n", 08719 (unsigned) ie_len); 08720 break; 08721 } 08722 connected->id.subaddress.odd_even_indicator = data[pos]; 08723 break; 08724 case AST_CONNECTED_LINE_SUBADDRESS_VALID: 08725 if (ie_len != 1) { 08726 ast_log(LOG_WARNING, "Invalid connected line subaddress valid (%u)\n", 08727 (unsigned) ie_len); 08728 break; 08729 } 08730 connected->id.subaddress.valid = data[pos]; 08731 break; 08732 /* Connected line party tag */ 08733 case AST_CONNECTED_LINE_TAG: 08734 ast_free(connected->id.tag); 08735 connected->id.tag = ast_malloc(ie_len + 1); 08736 if (connected->id.tag) { 08737 memcpy(connected->id.tag, data + pos, ie_len); 08738 connected->id.tag[ie_len] = 0; 08739 } 08740 break; 08741 /* Connected line party source */ 08742 case AST_CONNECTED_LINE_SOURCE: 08743 if (ie_len != sizeof(value)) { 08744 ast_log(LOG_WARNING, "Invalid connected line source (%u)\n", 08745 (unsigned) ie_len); 08746 break; 08747 } 08748 memcpy(&value, data + pos, sizeof(value)); 08749 connected->source = ntohl(value); 08750 break; 08751 /* Connected line party unknown element */ 08752 default: 08753 ast_log(LOG_DEBUG, "Unknown connected line element: %u (%u)\n", 08754 (unsigned) ie_id, (unsigned) ie_len); 08755 break; 08756 } 08757 } 08758 08759 switch (frame_version) { 08760 case 1: 08761 /* 08762 * The other end is an earlier version that we need to adjust 08763 * for compatibility. 08764 */ 08765 connected->id.name.valid = 1; 08766 connected->id.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1; 08767 connected->id.number.valid = 1; 08768 if (got_combined_presentation) { 08769 connected->id.name.presentation = combined_presentation; 08770 connected->id.number.presentation = combined_presentation; 08771 } 08772 break; 08773 case 2: 08774 /* The other end is at the same level as we are. */ 08775 break; 08776 default: 08777 /* 08778 * The other end is newer than we are. 08779 * We need to assume that they are compatible with us. 08780 */ 08781 ast_log(LOG_DEBUG, "Connected line frame has newer version: %u\n", 08782 (unsigned) frame_version); 08783 break; 08784 } 08785 08786 return 0; 08787 }
void ast_deactivate_generator | ( | struct ast_channel * | chan | ) |
Deactivate an active generator
Definition at line 3029 of file channel.c.
References ast_channel_lock, ast_channel_set_fd(), ast_channel_unlock, ast_clear_flag, AST_FLAG_WRITE_INT, AST_GENERATOR_FD, ast_settimeout(), chanlist::chan, ast_channel::generator, ast_channel::generatordata, and ast_generator::release.
Referenced by __ast_read(), app_exec(), ast_channel_stop_silence_generator(), ast_openstream_full(), ast_playtones_stop(), ast_quiet_chan(), ast_read_generator_actions(), ast_tonepair_stop(), ast_write(), cb_events(), channel_spy(), dial_exec_full(), generator_force(), local_ast_moh_stop(), old_milliwatt_exec(), transmit_audio(), and wait_for_answer().
03030 { 03031 ast_channel_lock(chan); 03032 if (chan->generatordata) { 03033 if (chan->generator && chan->generator->release) 03034 chan->generator->release(chan, chan->generatordata); 03035 chan->generatordata = NULL; 03036 chan->generator = NULL; 03037 ast_channel_set_fd(chan, AST_GENERATOR_FD, -1); 03038 ast_clear_flag(chan, AST_FLAG_WRITE_INT); 03039 ast_settimeout(chan, 0, NULL, NULL); 03040 } 03041 ast_channel_unlock(chan); 03042 }
int ast_do_masquerade | ( | struct ast_channel * | original | ) |
Start masquerading a channel.
Definition at line 6391 of file channel.c.
References __ast_change_name_nolink(), ast_channel::_bridge, ast_channel::_softhangup, ast_channel::_state, accountcode, ast_channel::adsicpe, ast_channel::alertpipe, ao2_link, ao2_lock, ao2_unlink, ao2_unlock, ast_app_group_update(), ast_autochan_new_channel(), ast_bridged_channel(), ast_cause2str(), AST_CEL_BRIDGE_UPDATE, ast_cel_report_event(), ast_channel_datastore_find(), ast_channel_datastore_remove(), ast_channel_lock, AST_CHANNEL_NAME, ast_channel_release(), ast_channel_set_fd(), ast_channel_set_linkgroup(), ast_channel_trylock, ast_channel_unlock, AST_CONTROL_SRCCHANGE, AST_CONTROL_UNHOLD, ast_copy_string(), ast_datastore_free(), ast_debug, AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, AST_GENERATOR_FD, ast_getformatname(), ast_indicate(), ast_kill_tech, AST_LIST_APPEND_LIST, AST_LIST_FIRST, AST_LIST_HEAD_NOLOCK, AST_LIST_HEAD_SET_NOLOCK, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), ast_manager_event, ast_manager_event_multichan, AST_MAX_FDS, ast_null_frame, ast_queue_frame(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_SOFTHANGUP_DEV, ast_state2str(), ast_string_field_set, ast_test_flag, AST_TIMING_FD, ast_channel::blocker, ast_channel::caller, ast_channel::cdr, ast_datastore_info::chan_fixup, CHANNEL_DEADLOCK_AVOIDANCE, channels, clone_variables(), chanlist::connected, ast_channel::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, language, ast_channel::language, LOG_WARNING, ast_channel::masq, ast_channel::masqr, masquerade_colp_transfer(), ast_channel::monitor, musicclass, ast_channel::name, ast_channel::nativeformats, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::readq, ast_channel::redirecting, report_new_callerid(), S_OR, ast_channel::tech, ast_channel::tech_pvt, ast_channel::timingfd, xfer_masquerade_ds::transferee_held, ast_channel_tech::type, ast_channel::visible_indication, ast_channel::writeformat, and xfer_ds_info.
Referenced by __ast_read(), ast_async_goto(), ast_do_pickup(), ast_hangup(), ast_waitfor_nandfds(), ast_write(), builtin_atxfer(), check_goto_on_transfer(), do_bridge_masquerade(), handle_invite_replaces(), iax_park(), local_attended_transfer(), masq_park_call(), and sip_park().
06392 { 06393 format_t x; 06394 int i; 06395 int res=0; 06396 int origstate; 06397 int visible_indication; 06398 struct ast_frame *current; 06399 const struct ast_channel_tech *t; 06400 void *t_pvt; 06401 union { 06402 struct ast_party_dialed dialed; 06403 struct ast_party_caller caller; 06404 struct ast_party_connected_line connected; 06405 struct ast_party_redirecting redirecting; 06406 } exchange; 06407 struct ast_channel *clonechan, *chans[2]; 06408 struct ast_channel *bridged; 06409 struct ast_cdr *cdr; 06410 struct ast_datastore *xfer_ds; 06411 struct xfer_masquerade_ds *xfer_colp; 06412 format_t rformat = original->readformat; 06413 format_t wformat = original->writeformat; 06414 char newn[AST_CHANNEL_NAME]; 06415 char orig[AST_CHANNEL_NAME]; 06416 char masqn[AST_CHANNEL_NAME]; 06417 char zombn[AST_CHANNEL_NAME]; 06418 06419 /* XXX This operation is a bit odd. We're essentially putting the guts of 06420 * the clone channel into the original channel. Start by killing off the 06421 * original channel's backend. While the features are nice, which is the 06422 * reason we're keeping it, it's still awesomely weird. XXX */ 06423 06424 /* The reasoning for the channels ao2_container lock here is complex. 06425 * 06426 * In order to check for a race condition, the original channel must 06427 * be locked. If it is determined that the masquerade should proceed 06428 * the original channel can absolutely not be unlocked until the end 06429 * of the function. Since after determining the masquerade should 06430 * continue requires the channels to be unlinked from the ao2_container, 06431 * the container lock must be held first to achieve proper locking order. 06432 */ 06433 ao2_lock(channels); 06434 06435 /* lock the original channel to determine if the masquerade is required or not */ 06436 ast_channel_lock(original); 06437 06438 /* 06439 * This checks to see if the masquerade has already happened or 06440 * not. There is a race condition that exists for this 06441 * function. Since all pvt and channel locks must be let go 06442 * before calling do_masquerade, it is possible that it could be 06443 * called multiple times for the same channel. This check 06444 * verifies whether or not the masquerade has already been 06445 * completed by another thread. 06446 */ 06447 while ((clonechan = original->masq) && ast_channel_trylock(clonechan)) { 06448 /* 06449 * A masq is needed but we could not get the clonechan lock 06450 * immediately. Since this function already holds the global 06451 * container lock, unlocking original for deadlock avoidance 06452 * will not result in any sort of masquerade race condition. If 06453 * masq is called by a different thread while this happens, it 06454 * will be stuck waiting until we unlock the container. 06455 */ 06456 CHANNEL_DEADLOCK_AVOIDANCE(original); 06457 } 06458 06459 /* 06460 * A final masq check must be done after deadlock avoidance for 06461 * clonechan above or we could get a double masq. This is 06462 * posible with ast_hangup at least. 06463 */ 06464 if (!clonechan) { 06465 /* masq already completed by another thread, or never needed to be done to begin with */ 06466 ast_channel_unlock(original); 06467 ao2_unlock(channels); 06468 return 0; 06469 } 06470 06471 /* Get any transfer masquerade connected line exchange data. */ 06472 xfer_ds = ast_channel_datastore_find(original, &xfer_ds_info, NULL); 06473 if (xfer_ds) { 06474 ast_channel_datastore_remove(original, xfer_ds); 06475 xfer_colp = xfer_ds->data; 06476 } else { 06477 xfer_colp = NULL; 06478 } 06479 06480 /* 06481 * Release any hold on the transferee channel before proceeding 06482 * with the masquerade. 06483 */ 06484 if (xfer_colp && xfer_colp->transferee_held) { 06485 ast_indicate(clonechan, AST_CONTROL_UNHOLD); 06486 } 06487 06488 /* clear the masquerade channels */ 06489 original->masq = NULL; 06490 clonechan->masqr = NULL; 06491 06492 /* unlink from channels container as name (which is the hash value) will change */ 06493 ao2_unlink(channels, original); 06494 ao2_unlink(channels, clonechan); 06495 06496 ast_debug(4, "Actually Masquerading %s(%d) into the structure of %s(%d)\n", 06497 clonechan->name, clonechan->_state, original->name, original->_state); 06498 06499 /* 06500 * Stop any visible indiction on the original channel so we can 06501 * transfer it to the clonechan taking the original's place. 06502 */ 06503 visible_indication = original->visible_indication; 06504 ast_indicate(original, -1); 06505 06506 chans[0] = clonechan; 06507 chans[1] = original; 06508 ast_manager_event_multichan(EVENT_FLAG_CALL, "Masquerade", 2, chans, 06509 "Clone: %s\r\n" 06510 "CloneState: %s\r\n" 06511 "Original: %s\r\n" 06512 "OriginalState: %s\r\n", 06513 clonechan->name, ast_state2str(clonechan->_state), original->name, ast_state2str(original->_state)); 06514 06515 /* Having remembered the original read/write formats, we turn off any translation on either 06516 one */ 06517 free_translation(clonechan); 06518 free_translation(original); 06519 06520 /* Save the original name */ 06521 ast_copy_string(orig, original->name, sizeof(orig)); 06522 /* Save the new name */ 06523 ast_copy_string(newn, clonechan->name, sizeof(newn)); 06524 /* Create the masq name */ 06525 snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn); 06526 06527 /* Mangle the name of the clone channel */ 06528 __ast_change_name_nolink(clonechan, masqn); 06529 06530 /* Copy the name from the clone channel */ 06531 __ast_change_name_nolink(original, newn); 06532 06533 /* share linked id's */ 06534 ast_channel_set_linkgroup(original, clonechan); 06535 06536 /* Swap the technologies */ 06537 t = original->tech; 06538 original->tech = clonechan->tech; 06539 clonechan->tech = t; 06540 06541 /* Swap the cdrs */ 06542 cdr = original->cdr; 06543 original->cdr = clonechan->cdr; 06544 clonechan->cdr = cdr; 06545 06546 t_pvt = original->tech_pvt; 06547 original->tech_pvt = clonechan->tech_pvt; 06548 clonechan->tech_pvt = t_pvt; 06549 06550 /* Swap the alertpipes */ 06551 for (i = 0; i < 2; i++) { 06552 x = original->alertpipe[i]; 06553 original->alertpipe[i] = clonechan->alertpipe[i]; 06554 clonechan->alertpipe[i] = x; 06555 } 06556 06557 /* 06558 * Swap the readq's. The end result should be this: 06559 * 06560 * 1) All frames should be on the new (original) channel. 06561 * 2) Any frames that were already on the new channel before this 06562 * masquerade need to be at the end of the readq, after all of the 06563 * frames on the old (clone) channel. 06564 * 3) The alertpipe needs to get poked for every frame that was already 06565 * on the new channel, since we are now using the alert pipe from the 06566 * old (clone) channel. 06567 */ 06568 { 06569 AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq; 06570 AST_LIST_HEAD_SET_NOLOCK(&tmp_readq, NULL); 06571 06572 AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list); 06573 AST_LIST_APPEND_LIST(&original->readq, &clonechan->readq, frame_list); 06574 06575 while ((current = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) { 06576 AST_LIST_INSERT_TAIL(&original->readq, current, frame_list); 06577 if (original->alertpipe[1] > -1) { 06578 int poke = 0; 06579 06580 if (write(original->alertpipe[1], &poke, sizeof(poke)) < 0) { 06581 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 06582 } 06583 } 06584 } 06585 } 06586 06587 /* Swap the raw formats */ 06588 x = original->rawreadformat; 06589 original->rawreadformat = clonechan->rawreadformat; 06590 clonechan->rawreadformat = x; 06591 x = original->rawwriteformat; 06592 original->rawwriteformat = clonechan->rawwriteformat; 06593 clonechan->rawwriteformat = x; 06594 06595 clonechan->_softhangup = AST_SOFTHANGUP_DEV; 06596 06597 /* And of course, so does our current state. Note we need not 06598 call ast_setstate since the event manager doesn't really consider 06599 these separate. We do this early so that the clone has the proper 06600 state of the original channel. */ 06601 origstate = original->_state; 06602 original->_state = clonechan->_state; 06603 clonechan->_state = origstate; 06604 06605 if (clonechan->tech->fixup && clonechan->tech->fixup(original, clonechan)) { 06606 ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clonechan->name); 06607 } 06608 06609 /* Start by disconnecting the original's physical side */ 06610 if (clonechan->tech->hangup && clonechan->tech->hangup(clonechan)) { 06611 ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n"); 06612 res = -1; 06613 goto done; 06614 } 06615 06616 /* 06617 * We just hung up the physical side of the channel. Set the 06618 * new zombie to use the kill channel driver for safety. 06619 */ 06620 clonechan->tech = &ast_kill_tech; 06621 06622 /* Mangle the name of the clone channel */ 06623 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig); /* quick, hide the brains! */ 06624 __ast_change_name_nolink(clonechan, zombn); 06625 06626 /* Update the type. */ 06627 t_pvt = original->monitor; 06628 original->monitor = clonechan->monitor; 06629 clonechan->monitor = t_pvt; 06630 06631 /* Keep the same language. */ 06632 ast_string_field_set(original, language, clonechan->language); 06633 /* Copy the FD's other than the generator fd */ 06634 for (x = 0; x < AST_MAX_FDS; x++) { 06635 if (x != AST_GENERATOR_FD) 06636 ast_channel_set_fd(original, x, clonechan->fds[x]); 06637 } 06638 06639 ast_app_group_update(clonechan, original); 06640 06641 /* Move data stores over */ 06642 if (AST_LIST_FIRST(&clonechan->datastores)) { 06643 struct ast_datastore *ds; 06644 /* We use a safe traversal here because some fixup routines actually 06645 * remove the datastore from the list and free them. 06646 */ 06647 AST_LIST_TRAVERSE_SAFE_BEGIN(&clonechan->datastores, ds, entry) { 06648 if (ds->info->chan_fixup) 06649 ds->info->chan_fixup(ds->data, clonechan, original); 06650 } 06651 AST_LIST_TRAVERSE_SAFE_END; 06652 AST_LIST_APPEND_LIST(&original->datastores, &clonechan->datastores, entry); 06653 } 06654 06655 ast_autochan_new_channel(clonechan, original); 06656 06657 clone_variables(original, clonechan); 06658 /* Presense of ADSI capable CPE follows clone */ 06659 original->adsicpe = clonechan->adsicpe; 06660 /* Bridge remains the same */ 06661 /* CDR fields remain the same */ 06662 /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */ 06663 /* Application and data remain the same */ 06664 /* Clone exception becomes real one, as with fdno */ 06665 ast_set_flag(original, ast_test_flag(clonechan, AST_FLAG_EXCEPTION | AST_FLAG_OUTGOING)); 06666 original->fdno = clonechan->fdno; 06667 /* Schedule context remains the same */ 06668 /* Stream stuff stays the same */ 06669 /* Keep the original state. The fixup code will need to work with it most likely */ 06670 06671 /* 06672 * Just swap the whole structures, nevermind the allocations, 06673 * they'll work themselves out. 06674 */ 06675 exchange.dialed = original->dialed; 06676 original->dialed = clonechan->dialed; 06677 clonechan->dialed = exchange.dialed; 06678 06679 exchange.caller = original->caller; 06680 original->caller = clonechan->caller; 06681 clonechan->caller = exchange.caller; 06682 06683 exchange.connected = original->connected; 06684 original->connected = clonechan->connected; 06685 clonechan->connected = exchange.connected; 06686 06687 exchange.redirecting = original->redirecting; 06688 original->redirecting = clonechan->redirecting; 06689 clonechan->redirecting = exchange.redirecting; 06690 06691 report_new_callerid(original); 06692 06693 /* Restore original timing file descriptor */ 06694 ast_channel_set_fd(original, AST_TIMING_FD, original->timingfd); 06695 06696 /* Our native formats are different now */ 06697 original->nativeformats = clonechan->nativeformats; 06698 06699 /* Context, extension, priority, app data, jump table, remain the same */ 06700 /* pvt switches. pbx stays the same, as does next */ 06701 06702 /* Set the write format */ 06703 ast_set_write_format(original, wformat); 06704 06705 /* Set the read format */ 06706 ast_set_read_format(original, rformat); 06707 06708 /* Copy the music class */ 06709 ast_string_field_set(original, musicclass, clonechan->musicclass); 06710 06711 /* copy over accuntcode and set peeraccount across the bridge */ 06712 ast_string_field_set(original, accountcode, S_OR(clonechan->accountcode, "")); 06713 if (original->_bridge) { 06714 /* XXX - should we try to lock original->_bridge here? */ 06715 ast_string_field_set(original->_bridge, peeraccount, S_OR(clonechan->accountcode, "")); 06716 ast_cel_report_event(original, AST_CEL_BRIDGE_UPDATE, NULL, NULL, NULL); 06717 } 06718 06719 ast_debug(1, "Putting channel %s in %s/%s formats\n", original->name, 06720 ast_getformatname(wformat), ast_getformatname(rformat)); 06721 06722 /* Okay. Last thing is to let the channel driver know about all this mess, so he 06723 can fix up everything as best as possible */ 06724 if (original->tech->fixup) { 06725 if (original->tech->fixup(clonechan, original)) { 06726 ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n", 06727 original->tech->type, original->name); 06728 res = -1; 06729 goto done; 06730 } 06731 } else 06732 ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)! Bad things may happen.\n", 06733 original->tech->type, original->name); 06734 06735 /* 06736 * If an indication is currently playing, maintain it on the channel 06737 * that is taking the place of original 06738 * 06739 * This is needed because the masquerade is swapping out in the internals 06740 * of this channel, and the new channel private data needs to be made 06741 * aware of the current visible indication (RINGING, CONGESTION, etc.) 06742 */ 06743 if (visible_indication) { 06744 ast_indicate(original, visible_indication); 06745 } 06746 06747 /* Now, at this point, the "clone" channel is totally F'd up. We mark it as 06748 a zombie so nothing tries to touch it. If it's already been marked as a 06749 zombie, then free it now (since it already is considered invalid). */ 06750 if (ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) { 06751 ast_debug(1, "Destroying channel clone '%s'\n", clonechan->name); 06752 ast_channel_unlock(clonechan); 06753 ast_manager_event(clonechan, EVENT_FLAG_CALL, "Hangup", 06754 "Channel: %s\r\n" 06755 "Uniqueid: %s\r\n" 06756 "Cause: %d\r\n" 06757 "Cause-txt: %s\r\n", 06758 clonechan->name, 06759 clonechan->uniqueid, 06760 clonechan->hangupcause, 06761 ast_cause2str(clonechan->hangupcause) 06762 ); 06763 clonechan = ast_channel_release(clonechan); 06764 } else { 06765 ast_debug(1, "Released clone lock on '%s'\n", clonechan->name); 06766 ast_set_flag(clonechan, AST_FLAG_ZOMBIE); 06767 ast_queue_frame(clonechan, &ast_null_frame); 06768 } 06769 06770 /* Signal any blocker */ 06771 if (ast_test_flag(original, AST_FLAG_BLOCKING)) 06772 pthread_kill(original->blocker, SIGURG); 06773 ast_debug(1, "Done Masquerading %s (%d)\n", original->name, original->_state); 06774 06775 if ((bridged = ast_bridged_channel(original))) { 06776 ast_channel_lock(bridged); 06777 ast_indicate(bridged, AST_CONTROL_SRCCHANGE); 06778 ast_channel_unlock(bridged); 06779 } 06780 ast_indicate(original, AST_CONTROL_SRCCHANGE); 06781 06782 if (xfer_colp) { 06783 /* 06784 * After the masquerade, the original channel pointer actually 06785 * points to the new transferee channel and the bridged channel 06786 * is still the intended transfer target party. 06787 */ 06788 masquerade_colp_transfer(original, xfer_colp); 06789 } 06790 06791 done: 06792 if (xfer_ds) { 06793 ast_datastore_free(xfer_ds); 06794 } 06795 /* it is possible for the clone channel to disappear during this */ 06796 if (clonechan) { 06797 ast_channel_unlock(original); 06798 ast_channel_unlock(clonechan); 06799 ao2_link(channels, clonechan); 06800 ao2_link(channels, original); 06801 } else { 06802 ast_channel_unlock(original); 06803 ao2_link(channels, original); 06804 } 06805 06806 ao2_unlock(channels); 06807 06808 return res; 06809 }
struct ast_channel* ast_dummy_channel_alloc | ( | void | ) |
Create a fake channel structure.
NULL | failure | |
non-NULL | successfully allocated channel |
The created dummy channel should be destroyed by ast_channel_unref(). Using ast_channel_release() needlessly grabs the channel container lock and can cause a deadlock as a result. Also grabbing the channel container lock reduces system performance.
Definition at line 1369 of file channel.c.
References __ao2_alloc_debug(), ao2_alloc, ast_channel_unref, ast_dummy_channel_destructor(), AST_LIST_HEAD_INIT_NOLOCK, and ast_string_field_init.
Referenced by acf_odbc_read(), acf_odbc_write(), action_getvar(), ast_add_extension2_lockopt(), ast_cel_fabricate_channel_from_event(), ast_pbx_outgoing_cdr_failed(), ast_str_substitute_variables_full(), custom_log(), make_email_file(), manager_log(), pbx_substitute_variables_helper_full(), rotate_file(), sendmail(), sendpage(), syslog_log(), and write_cdr().
01371 { 01372 struct ast_channel *tmp; 01373 struct varshead *headp; 01374 01375 #if defined(REF_DEBUG) 01376 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel", 01377 file, line, function, 1); 01378 #elif defined(__AST_DEBUG_MALLOC) 01379 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel", 01380 file, line, function, 0); 01381 #else 01382 tmp = ao2_alloc(sizeof(*tmp), ast_dummy_channel_destructor); 01383 #endif 01384 if (!tmp) { 01385 /* Dummy channel structure allocation failure. */ 01386 return NULL; 01387 } 01388 01389 if ((ast_string_field_init(tmp, 128))) { 01390 return ast_channel_unref(tmp); 01391 } 01392 01393 headp = &tmp->varshead; 01394 AST_LIST_HEAD_INIT_NOLOCK(headp); 01395 01396 return tmp; 01397 }
static int ast_fdisset | ( | struct pollfd * | pfds, | |
int | fd, | |||
int | maximum, | |||
int * | start | |||
) | [inline, static] |
Helper function for migrating select to poll.
Definition at line 2365 of file channel.h.
References dummy().
02366 { 02367 int x; 02368 int dummy = 0; 02369 02370 if (fd < 0) 02371 return 0; 02372 if (!start) 02373 start = &dummy; 02374 for (x = *start; x < maximum; x++) 02375 if (pfds[x].fd == fd) { 02376 if (x == *start) 02377 (*start)++; 02378 return pfds[x].revents; 02379 } 02380 return 0; 02381 }
struct ast_channel_tech* ast_get_channel_tech | ( | const char * | name | ) |
Get a channel technology structure by name.
name | name of technology to find |
Definition at line 939 of file channel.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, chanlist::list, chanlist::tech, and ast_channel_tech::type.
Referenced by __ast_channel_alloc_ap(), _ast_device_state(), ast_cc_callback(), and ast_var_channel_types_table().
00940 { 00941 struct chanlist *chanls; 00942 const struct ast_channel_tech *ret = NULL; 00943 00944 AST_RWLIST_RDLOCK(&backends); 00945 00946 AST_RWLIST_TRAVERSE(&backends, chanls, list) { 00947 if (!strcasecmp(name, chanls->tech->type)) { 00948 ret = chanls->tech; 00949 break; 00950 } 00951 } 00952 00953 AST_RWLIST_UNLOCK(&backends); 00954 00955 return ret; 00956 }
ast_group_t ast_get_group | ( | const char * | s | ) |
Definition at line 7726 of file channel.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), LOG_ERROR, LOG_WARNING, and strsep().
Referenced by _parse(), build_device(), build_peer(), config_parse_variables(), func_channel_write_real(), and read_agent_config().
07727 { 07728 char *piece; 07729 char *c; 07730 int start=0, finish=0, x; 07731 ast_group_t group = 0; 07732 07733 if (ast_strlen_zero(s)) 07734 return 0; 07735 07736 c = ast_strdupa(s); 07737 07738 while ((piece = strsep(&c, ","))) { 07739 if (sscanf(piece, "%30d-%30d", &start, &finish) == 2) { 07740 /* Range */ 07741 } else if (sscanf(piece, "%30d", &start)) { 07742 /* Just one */ 07743 finish = start; 07744 } else { 07745 ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece); 07746 continue; 07747 } 07748 for (x = start; x <= finish; x++) { 07749 if ((x > 63) || (x < 0)) { 07750 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x); 07751 } else 07752 group |= ((ast_group_t) 1 << x); 07753 } 07754 } 07755 return group; 07756 }
int ast_hangup | ( | struct ast_channel * | chan | ) |
Hang up a channel.
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.
chan | channel to hang up |
Definition at line 2733 of file channel.c.
References ao2_lock, ao2_unlink, ao2_unlock, ast_assert, ast_audiohook_detach_list(), ast_autoservice_stop(), ast_cause2str(), ast_cc_offer(), ast_cdr_detach(), ast_cdr_end(), AST_CDR_FLAG_BRIDGED, AST_CDR_FLAG_DIALED, AST_CDR_FLAG_POST_DISABLED, AST_CDR_NULL, AST_CEL_HANGUP, ast_cel_report_event(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_closestream(), ast_debug, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_framehook_list_destroy(), ast_log(), ast_manager_event, ast_set_flag, ast_test_flag, ast_channel::audiohooks, ast_channel::blocker, ast_channel::blockproc, ast_channel::caller, ast_channel::cdr, chanlist::chan, channels, ast_channel::connected, ast_cdr::disposition, EVENT_FLAG_CALL, free_translation(), ast_channel::generator, ast_channel::generatordata, ast_channel_tech::hangup, ast_channel::hangupcause, ast_channel::hangupsource, ast_party_caller::id, ast_party_connected_line::id, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::name, ast_party_id::name, ast_party_id::number, pbx_builtin_getvar_helper(), ast_generator::release, S_COR, S_OR, ast_channel::sched, sched_context_destroy(), ast_party_number::str, ast_party_name::str, ast_channel::stream, ast_channel::tech, ast_channel::uniqueid, ast_party_number::valid, ast_party_name::valid, and ast_channel::vstream.
Referenced by __analog_handle_event(), __analog_ss_thread(), __ast_request_and_dial(), __oh323_new(), action_bridge(), alsa_new(), analog_handle_init_event(), analog_ss_thread(), answer_exec_run(), app_exec(), ast_async_goto(), ast_call_forward(), ast_dial_destroy(), ast_dial_hangup(), ast_iax2_new(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pbx_run_app(), async_wait(), begin_dial_channel(), bridge_call_thread(), bridge_channel_thread(), bridge_exec(), build_conf(), builtin_atxfer(), chanavail_exec(), check_availability(), check_compat(), check_goto_on_transfer(), clear_caller(), conf_run(), connect_link(), console_new(), dahdi_handle_event(), dahdi_new(), destroy_conference_bridge(), dial_exec_full(), dial_transfer(), do_forward(), do_hang(), do_idle_thread(), feature_attended_transfer(), feature_request_and_dial(), findmeexec(), generic_recall(), gtalk_new(), handle_call_forward(), handle_callforward_button(), handle_enbloc_call_message(), handle_frame(), handle_frame_ownerless(), handle_hd_hf(), handle_init_event(), handle_invite_replaces(), handle_offhook_message(), handle_request_invite(), handle_soft_key_event_message(), handle_stimulus_message(), handle_timeout_trip(), handle_transfer_button(), HandleCallOutgoing(), hangup_chan(), hangupcalls(), hanguptree(), iax2_request(), iax_park(), iax_park_thread(), jingle_new(), local_hangup(), manage_parked_call(), masq_park_call(), mgcp_new(), mgcp_ss(), monitor_dial(), mwi_thread(), my_distinctive_ring(), my_handle_notify_message(), nbs_new(), oss_new(), parkandannounce_exec(), parked_call_exec(), phone_new(), play_sound_file(), pri_dchannel(), pri_ss_thread(), rpt(), rpt_call(), rpt_tele_thread(), sip_park(), sip_park_thread(), sip_pickup_thread(), skinny_new(), skinny_ss(), ss7_start_call(), unistim_new(), usbradio_new(), and wait_for_winner().
02734 { 02735 char extra_str[64]; /* used for cel logging below */ 02736 02737 ast_autoservice_stop(chan); 02738 02739 ao2_lock(channels); 02740 ast_channel_lock(chan); 02741 02742 if (chan->audiohooks) { 02743 ast_audiohook_detach_list(chan->audiohooks); 02744 chan->audiohooks = NULL; 02745 } 02746 ast_framehook_list_destroy(chan); 02747 02748 /* 02749 * Do the masquerade if someone is setup to masquerade into us. 02750 * 02751 * NOTE: We must hold the channel lock after testing for a 02752 * pending masquerade and setting the channel as a zombie to 02753 * prevent __ast_channel_masquerade() from setting up a 02754 * masquerade with a dead channel. 02755 */ 02756 while (chan->masq) { 02757 ast_channel_unlock(chan); 02758 ao2_unlock(channels); 02759 if (ast_do_masquerade(chan)) { 02760 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 02761 02762 /* Abort the loop or we might never leave. */ 02763 ao2_lock(channels); 02764 ast_channel_lock(chan); 02765 break; 02766 } 02767 ao2_lock(channels); 02768 ast_channel_lock(chan); 02769 } 02770 02771 if (chan->masqr) { 02772 /* 02773 * This channel is one which will be masqueraded into something. 02774 * Mark it as a zombie already so ast_do_masquerade() will know 02775 * to free it later. 02776 */ 02777 ast_set_flag(chan, AST_FLAG_ZOMBIE); 02778 ast_channel_unlock(chan); 02779 ao2_unlock(channels); 02780 return 0; 02781 } 02782 02783 ao2_unlink(channels, chan); 02784 ao2_unlock(channels); 02785 02786 free_translation(chan); 02787 /* Close audio stream */ 02788 if (chan->stream) { 02789 ast_closestream(chan->stream); 02790 chan->stream = NULL; 02791 } 02792 /* Close video stream */ 02793 if (chan->vstream) { 02794 ast_closestream(chan->vstream); 02795 chan->vstream = NULL; 02796 } 02797 if (chan->sched) { 02798 sched_context_destroy(chan->sched); 02799 chan->sched = NULL; 02800 } 02801 02802 if (chan->generatordata) { /* Clear any tone stuff remaining */ 02803 if (chan->generator && chan->generator->release) { 02804 chan->generator->release(chan, chan->generatordata); 02805 } 02806 } 02807 chan->generatordata = NULL; 02808 chan->generator = NULL; 02809 02810 snprintf(extra_str, sizeof(extra_str), "%d,%s,%s", chan->hangupcause, chan->hangupsource, S_OR(pbx_builtin_getvar_helper(chan, "DIALSTATUS"), "")); 02811 ast_cel_report_event(chan, AST_CEL_HANGUP, NULL, extra_str, NULL); 02812 02813 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) { 02814 ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd " 02815 "is blocked by thread %ld in procedure %s! Expect a failure\n", 02816 (long) pthread_self(), chan->name, (long)chan->blocker, chan->blockproc); 02817 ast_assert(ast_test_flag(chan, AST_FLAG_BLOCKING) == 0); 02818 } 02819 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) { 02820 ast_debug(1, "Hanging up channel '%s'\n", chan->name); 02821 02822 /* 02823 * This channel is now dead so mark it as a zombie so anyone 02824 * left holding a reference to this channel will not use it. 02825 */ 02826 ast_set_flag(chan, AST_FLAG_ZOMBIE); 02827 if (chan->tech->hangup) { 02828 chan->tech->hangup(chan); 02829 } 02830 } else { 02831 ast_debug(1, "Hanging up zombie '%s'\n", chan->name); 02832 } 02833 02834 ast_channel_unlock(chan); 02835 02836 ast_cc_offer(chan); 02837 ast_manager_event(chan, EVENT_FLAG_CALL, "Hangup", 02838 "Channel: %s\r\n" 02839 "Uniqueid: %s\r\n" 02840 "CallerIDNum: %s\r\n" 02841 "CallerIDName: %s\r\n" 02842 "ConnectedLineNum: %s\r\n" 02843 "ConnectedLineName: %s\r\n" 02844 "Cause: %d\r\n" 02845 "Cause-txt: %s\r\n", 02846 chan->name, 02847 chan->uniqueid, 02848 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "<unknown>"), 02849 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, "<unknown>"), 02850 S_COR(chan->connected.id.number.valid, chan->connected.id.number.str, "<unknown>"), 02851 S_COR(chan->connected.id.name.valid, chan->connected.id.name.str, "<unknown>"), 02852 chan->hangupcause, 02853 ast_cause2str(chan->hangupcause) 02854 ); 02855 02856 if (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_BRIDGED) && 02857 !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED) && 02858 (chan->cdr->disposition != AST_CDR_NULL || ast_test_flag(chan->cdr, AST_CDR_FLAG_DIALED))) { 02859 ast_channel_lock(chan); 02860 ast_cdr_end(chan->cdr); 02861 ast_cdr_detach(chan->cdr); 02862 chan->cdr = NULL; 02863 ast_channel_unlock(chan); 02864 } 02865 02866 ast_channel_unref(chan); 02867 02868 return 0; 02869 }
int ast_indicate | ( | struct ast_channel * | chan, | |
int | condition | |||
) |
Indicates condition of channel.
chan | channel to change the indication | |
condition | which condition to indicate on the channel |
Definition at line 4262 of file channel.c.
References ast_indicate_data(), and chanlist::chan.
Referenced by __ast_play_and_record(), agent_request(), alsa_call(), answer_trunk_chan(), ast_bridge_call(), ast_channel_bridge(), ast_do_masquerade(), ast_dtmf_stream(), ast_raw_answer(), attempt_transfer(), builtin_atxfer(), builtin_blindtransfer(), cli_console_answer(), conf_run(), console_call(), dial_exec_full(), do_forward(), feature_request_and_dial(), finishup(), function_remote(), handle_callforward_button(), handle_frame(), handle_recordfile(), handle_request_refer(), local_attended_transfer(), manage_parked_call(), mgcp_ss(), monitor_dial(), oss_call(), park_call_full(), parked_call_exec(), pbx_builtin_busy(), pbx_builtin_congestion(), pbx_builtin_incomplete(), pbx_builtin_proceeding(), pbx_builtin_progress(), pbx_builtin_ringing(), pbx_builtin_waitexten(), queue_exec(), rna(), rpt(), rpt_exec(), say_periodic_announcement(), say_position(), send_waveform_to_channel(), skinny_ss(), sla_handle_hold_event(), sla_station_exec(), and sla_trunk_exec().
04263 { 04264 return ast_indicate_data(chan, condition, NULL, 0); 04265 }
int ast_indicate_data | ( | struct ast_channel * | chan, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) |
Indicates condition of channel, with payload.
chan | channel to change the indication | |
condition | which condition to indicate on the channel | |
data | pointer to payload data | |
datalen | size of payload data |
Definition at line 4316 of file channel.c.
References ast_channel::_state, _XXX_AST_CONTROL_T38, ast_channel_lock, ast_channel_set_connected_line(), ast_channel_set_redirecting(), ast_channel_unlock, ast_check_hangup(), ast_connected_line_parse_data(), AST_CONTROL_ANSWER, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CC, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_END_OF_Q, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_READ_ACTION, AST_CONTROL_REDIRECTING, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_TRANSFER, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_CONTROL_VIDUPDATE, AST_CONTROL_WINK, ast_debug, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, ast_framehook_list_is_empty(), ast_framehook_list_write_event(), ast_frdup(), ast_frfree, ast_get_indication_tone(), ast_log(), ast_party_connected_line_free(), ast_party_connected_line_set_init(), ast_party_redirecting_free(), ast_party_redirecting_set_init(), ast_playtones_start(), ast_playtones_stop(), ast_redirecting_parse_data(), AST_STATE_UP, ast_test_flag, ast_tone_zone_sound_unref(), chanlist::chan, chanlist::connected, ast_channel::connected, ast_frame::data, ast_tone_zone_sound::data, ast_frame::datalen, ast_channel::framehooks, ast_frame::frametype, ast_channel_tech::indicate, ast_frame_subclass::integer, is_visible_indication(), LOG_WARNING, ast_channel::name, ast_frame::ptr, ast_channel::redirecting, ast_frame::subclass, ast_channel::tech, ast_channel::visible_indication, and ast_channel::zone.
Referenced by __ast_read(), action_aocmessage(), agent_hangup(), ast_bridge_call(), ast_channel_update_connected_line(), ast_channel_update_redirecting(), ast_handle_cc_control_frame(), ast_indicate(), disable_t38(), feature_request_and_dial(), generic_fax_exec(), handle_frame(), login_exec(), manage_parked_call(), park_call_full(), pbx_builtin_waitexten(), receivefax_t38_init(), remote_bridge_loop(), sendfax_t38_init(), set_fax_t38_caps(), transmit_audio(), transmit_t38(), and wait_for_answer().
04318 { 04319 /* By using an enum, we'll get compiler warnings for values not handled 04320 * in switch statements. */ 04321 enum ast_control_frame_type condition = _condition; 04322 struct ast_tone_zone_sound *ts = NULL; 04323 int res; 04324 /* this frame is used by framehooks. if it is set, we must free it at the end of this function */ 04325 struct ast_frame *awesome_frame = NULL; 04326 04327 ast_channel_lock(chan); 04328 04329 /* Don't bother if the channel is about to go away, anyway. */ 04330 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 04331 res = -1; 04332 goto indicate_cleanup; 04333 } 04334 04335 if (!ast_framehook_list_is_empty(chan->framehooks)) { 04336 /* Do framehooks now, do it, go, go now */ 04337 struct ast_frame frame = { 04338 .frametype = AST_FRAME_CONTROL, 04339 .subclass.integer = condition, 04340 .data.ptr = (void *) data, /* this cast from const is only okay because we do the ast_frdup below */ 04341 .datalen = datalen 04342 }; 04343 04344 /* we have now committed to freeing this frame */ 04345 awesome_frame = ast_frdup(&frame); 04346 04347 /* who knows what we will get back! the anticipation is killing me. */ 04348 if (!(awesome_frame = ast_framehook_list_write_event(chan->framehooks, awesome_frame)) 04349 || awesome_frame->frametype != AST_FRAME_CONTROL) { 04350 04351 res = 0; 04352 goto indicate_cleanup; 04353 } 04354 04355 condition = awesome_frame->subclass.integer; 04356 data = awesome_frame->data.ptr; 04357 datalen = awesome_frame->datalen; 04358 } 04359 04360 switch (condition) { 04361 case AST_CONTROL_CONNECTED_LINE: 04362 { 04363 struct ast_party_connected_line connected; 04364 04365 ast_party_connected_line_set_init(&connected, &chan->connected); 04366 res = ast_connected_line_parse_data(data, datalen, &connected); 04367 if (!res) { 04368 ast_channel_set_connected_line(chan, &connected, NULL); 04369 } 04370 ast_party_connected_line_free(&connected); 04371 } 04372 break; 04373 04374 case AST_CONTROL_REDIRECTING: 04375 { 04376 struct ast_party_redirecting redirecting; 04377 04378 ast_party_redirecting_set_init(&redirecting, &chan->redirecting); 04379 res = ast_redirecting_parse_data(data, datalen, &redirecting); 04380 if (!res) { 04381 ast_channel_set_redirecting(chan, &redirecting, NULL); 04382 } 04383 ast_party_redirecting_free(&redirecting); 04384 } 04385 break; 04386 04387 default: 04388 break; 04389 } 04390 04391 if (is_visible_indication(condition)) { 04392 /* A new visible indication is requested. */ 04393 chan->visible_indication = condition; 04394 } else if (condition == AST_CONTROL_UNHOLD || _condition < 0) { 04395 /* Visible indication is cleared/stopped. */ 04396 chan->visible_indication = 0; 04397 } 04398 04399 if (chan->tech->indicate) { 04400 /* See if the channel driver can handle this condition. */ 04401 res = chan->tech->indicate(chan, condition, data, datalen); 04402 } else { 04403 res = -1; 04404 } 04405 04406 if (!res) { 04407 /* The channel driver successfully handled this indication */ 04408 res = 0; 04409 goto indicate_cleanup; 04410 } 04411 04412 /* The channel driver does not support this indication, let's fake 04413 * it by doing our own tone generation if applicable. */ 04414 04415 /*!\note If we compare the enumeration type, which does not have any 04416 * negative constants, the compiler may optimize this code away. 04417 * Therefore, we must perform an integer comparison here. */ 04418 if (_condition < 0) { 04419 /* Stop any tones that are playing */ 04420 ast_playtones_stop(chan); 04421 res = 0; 04422 goto indicate_cleanup; 04423 } 04424 04425 /* Handle conditions that we have tones for. */ 04426 switch (condition) { 04427 case _XXX_AST_CONTROL_T38: 04428 /* deprecated T.38 control frame */ 04429 res = -1; 04430 goto indicate_cleanup; 04431 case AST_CONTROL_T38_PARAMETERS: 04432 /* there is no way to provide 'default' behavior for these 04433 * control frames, so we need to return failure, but there 04434 * is also no value in the log message below being emitted 04435 * since failure to handle these frames is not an 'error' 04436 * so just return right now. in addition, we want to return 04437 * whatever value the channel driver returned, in case it 04438 * has some meaning.*/ 04439 goto indicate_cleanup; 04440 case AST_CONTROL_RINGING: 04441 ts = ast_get_indication_tone(chan->zone, "ring"); 04442 /* It is common practice for channel drivers to return -1 if trying 04443 * to indicate ringing on a channel which is up. The idea is to let the 04444 * core generate the ringing inband. However, we don't want the 04445 * warning message about not being able to handle the specific indication 04446 * to print nor do we want ast_indicate_data to return an "error" for this 04447 * condition 04448 */ 04449 if (chan->_state == AST_STATE_UP) { 04450 res = 0; 04451 } 04452 break; 04453 case AST_CONTROL_BUSY: 04454 ts = ast_get_indication_tone(chan->zone, "busy"); 04455 break; 04456 case AST_CONTROL_INCOMPLETE: 04457 case AST_CONTROL_CONGESTION: 04458 ts = ast_get_indication_tone(chan->zone, "congestion"); 04459 break; 04460 case AST_CONTROL_PROGRESS: 04461 case AST_CONTROL_PROCEEDING: 04462 case AST_CONTROL_VIDUPDATE: 04463 case AST_CONTROL_SRCUPDATE: 04464 case AST_CONTROL_SRCCHANGE: 04465 case AST_CONTROL_RADIO_KEY: 04466 case AST_CONTROL_RADIO_UNKEY: 04467 case AST_CONTROL_OPTION: 04468 case AST_CONTROL_WINK: 04469 case AST_CONTROL_FLASH: 04470 case AST_CONTROL_OFFHOOK: 04471 case AST_CONTROL_TAKEOFFHOOK: 04472 case AST_CONTROL_ANSWER: 04473 case AST_CONTROL_HANGUP: 04474 case AST_CONTROL_RING: 04475 case AST_CONTROL_HOLD: 04476 case AST_CONTROL_UNHOLD: 04477 case AST_CONTROL_TRANSFER: 04478 case AST_CONTROL_CONNECTED_LINE: 04479 case AST_CONTROL_REDIRECTING: 04480 case AST_CONTROL_CC: 04481 case AST_CONTROL_READ_ACTION: 04482 case AST_CONTROL_AOC: 04483 case AST_CONTROL_END_OF_Q: 04484 case AST_CONTROL_UPDATE_RTP_PEER: 04485 /* Nothing left to do for these. */ 04486 res = 0; 04487 break; 04488 } 04489 04490 if (ts) { 04491 /* We have a tone to play, yay. */ 04492 ast_debug(1, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition); 04493 res = ast_playtones_start(chan, 0, ts->data, 1); 04494 ts = ast_tone_zone_sound_unref(ts); 04495 } 04496 04497 if (res) { 04498 /* not handled */ 04499 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name); 04500 } 04501 04502 indicate_cleanup: 04503 ast_channel_unlock(chan); 04504 if (awesome_frame) { 04505 ast_frfree(awesome_frame); 04506 } 04507 04508 return res; 04509 }
int ast_internal_timing_enabled | ( | struct ast_channel * | chan | ) |
Check if the channel can run in internal timing mode.
chan | The channel to check |
Definition at line 4247 of file channel.c.
References ast_opt_internal_timing, chanlist::chan, and ast_channel::timingfd.
Referenced by add_sdp(), and ast_read_generator_actions().
04248 { 04249 return (ast_opt_internal_timing && chan->timingfd > -1); 04250 }
int ast_is_deferrable_frame | ( | const struct ast_frame * | frame | ) |
Should we keep this frame for later?
There are functions such as ast_safe_sleep which will service a channel to ensure that it does not have a large backlog of queued frames. When this happens, we want to hold on to specific frame types and just drop others. This function will tell if the frame we just read should be held onto.
frame | The frame we just read |
1 | frame should be kept | |
0 | frame should be dropped |
Definition at line 1779 of file channel.c.
References AST_FRAME_CNG, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_HTML, AST_FRAME_IAX, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, and ast_frame::frametype.
Referenced by ast_safe_sleep_conditional(), autoservice_run(), and feature_request_and_dial().
01780 { 01781 /* Do not add a default entry in this switch statement. Each new 01782 * frame type should be addressed directly as to whether it should 01783 * be queued up or not. 01784 */ 01785 switch (frame->frametype) { 01786 case AST_FRAME_CONTROL: 01787 case AST_FRAME_TEXT: 01788 case AST_FRAME_IMAGE: 01789 case AST_FRAME_HTML: 01790 return 1; 01791 01792 case AST_FRAME_DTMF_END: 01793 case AST_FRAME_DTMF_BEGIN: 01794 case AST_FRAME_VOICE: 01795 case AST_FRAME_VIDEO: 01796 case AST_FRAME_NULL: 01797 case AST_FRAME_IAX: 01798 case AST_FRAME_CNG: 01799 case AST_FRAME_MODEM: 01800 return 0; 01801 } 01802 return 0; 01803 }
void ast_party_caller_copy | ( | struct ast_party_caller * | dest, | |
const struct ast_party_caller * | src | |||
) |
Copy the source caller information to the destination caller.
dest | Destination caller | |
src | Source caller |
Definition at line 2230 of file channel.c.
References ast_party_caller::ani, ast_party_caller::ani2, ast_party_id_copy(), and ast_party_caller::id.
02231 { 02232 if (dest == src) { 02233 /* Don't copy to self */ 02234 return; 02235 } 02236 02237 ast_party_id_copy(&dest->id, &src->id); 02238 ast_party_id_copy(&dest->ani, &src->ani); 02239 dest->ani2 = src->ani2; 02240 }
void ast_party_caller_free | ( | struct ast_party_caller * | doomed | ) |
Destroy the caller party contents.
doomed | The caller party to destroy. |
Definition at line 2256 of file channel.c.
References ast_party_caller::ani, ast_party_id_free(), and ast_party_caller::id.
Referenced by ast_channel_destructor(), ast_dummy_channel_destructor(), callerid_write(), dial_trunk(), and sla_ring_station().
02257 { 02258 ast_party_id_free(&doomed->id); 02259 ast_party_id_free(&doomed->ani); 02260 }
void ast_party_caller_init | ( | struct ast_party_caller * | init | ) |
Initialize the given caller structure.
init | Caller structure to initialize. |
Definition at line 2223 of file channel.c.
References ast_party_caller::ani, ast_party_caller::ani2, ast_party_id_init(), and ast_party_caller::id.
Referenced by __ast_channel_alloc_ap(), dial_trunk(), sig_pri_set_caller_id(), sig_ss7_set_caller_id(), and sla_ring_station().
02224 { 02225 ast_party_id_init(&init->id); 02226 ast_party_id_init(&init->ani); 02227 init->ani2 = 0; 02228 }
void ast_party_caller_set | ( | struct ast_party_caller * | dest, | |
const struct ast_party_caller * | src, | |||
const struct ast_set_party_caller * | update | |||
) |
Set the caller information based on another caller source.
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. |
Definition at line 2249 of file channel.c.
References ast_party_caller::ani, ast_party_caller::ani2, ast_party_id_set(), ast_party_caller::id, and update().
Referenced by ast_channel_set_caller(), ast_channel_set_caller_event(), and callerid_write().
02250 { 02251 ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL); 02252 ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL); 02253 dest->ani2 = src->ani2; 02254 }
void ast_party_caller_set_init | ( | struct ast_party_caller * | init, | |
const struct ast_party_caller * | guide | |||
) |
Initialize the given caller structure using the given guide for a set update operation.
init | Caller structure to initialize. | |
guide | Source caller to use as a guide in initializing. |
Definition at line 2242 of file channel.c.
References ast_party_caller::ani, ast_party_caller::ani2, ast_party_id_set_init(), and ast_party_caller::id.
Referenced by callerid_write(), dial_exec_full(), do_forward(), misdn_update_caller_id(), ring_entry(), and sig_pri_handle_subcmds().
02243 { 02244 ast_party_id_set_init(&init->id, &guide->id); 02245 ast_party_id_set_init(&init->ani, &guide->ani); 02246 init->ani2 = guide->ani2; 02247 }
void ast_party_connected_line_collect_caller | ( | struct ast_party_connected_line * | connected, | |
struct ast_party_caller * | caller | |||
) |
Collect the caller party information into a connected line structure.
connected | Collected caller information for the connected line | |
caller | Caller information. |
DO NOT call ast_party_connected_line_free() on the filled in connected line structure!
Definition at line 2299 of file channel.c.
References ast_party_connected_line::ani, ast_party_caller::ani, ast_party_connected_line::ani2, ast_party_caller::ani2, AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN, ast_channel::caller, chanlist::connected, ast_party_connected_line::id, ast_party_caller::id, and ast_party_connected_line::source.
02300 { 02301 connected->id = caller->id; 02302 connected->ani = caller->ani; 02303 connected->ani2 = caller->ani2; 02304 connected->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN; 02305 }
void ast_party_connected_line_copy | ( | struct ast_party_connected_line * | dest, | |
const struct ast_party_connected_line * | src | |||
) |
Copy the source connected line information to the destination connected line.
dest | Destination connected line | |
src | Source connected line |
Definition at line 2270 of file channel.c.
References ast_party_connected_line::ani, ast_party_connected_line::ani2, ast_party_id_copy(), ast_party_connected_line::id, and ast_party_connected_line::source.
Referenced by __ast_read(), ast_call_forward(), ast_channel_connected_line_macro(), ast_do_pickup(), builtin_atxfer(), dial_exec_full(), do_forward(), local_attended_transfer(), misdn_attempt_transfer(), and party_connected_line_copy_transfer().
02271 { 02272 if (dest == src) { 02273 /* Don't copy to self */ 02274 return; 02275 } 02276 02277 ast_party_id_copy(&dest->id, &src->id); 02278 ast_party_id_copy(&dest->ani, &src->ani); 02279 dest->ani2 = src->ani2; 02280 dest->source = src->source; 02281 }
void ast_party_connected_line_free | ( | struct ast_party_connected_line * | doomed | ) |
Destroy the connected line information contents.
doomed | The connected line information to destroy. |
Definition at line 2307 of file channel.c.
References ast_party_connected_line::ani, ast_party_id_free(), and ast_party_connected_line::id.
Referenced by __ast_read(), app_exec(), ast_channel_destructor(), ast_do_pickup(), ast_dummy_channel_destructor(), ast_indicate_data(), atxfer_fail_cleanup(), builtin_atxfer(), callattempt_free(), chanlist_free(), connectedline_write(), destroy_calling_tree(), feature_request_and_dial(), local_attended_transfer(), misdn_attempt_transfer(), parked_call_exec(), sig_pri_handle_subcmds(), socket_process(), wait_for_answer(), wait_for_winner(), and xfer_ds_destroy().
02308 { 02309 ast_party_id_free(&doomed->id); 02310 ast_party_id_free(&doomed->ani); 02311 }
void ast_party_connected_line_init | ( | struct ast_party_connected_line * | init | ) |
Initialize the given connected line structure.
init | Connected line structure to initialize. |
Definition at line 2262 of file channel.c.
References ast_party_connected_line::ani, ast_party_connected_line::ani2, AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN, ast_party_id_init(), ast_party_connected_line::id, and ast_party_connected_line::source.
Referenced by __ast_channel_alloc_ap(), __ast_read(), ast_do_pickup(), builtin_atxfer(), do_forward(), handle_request_invite(), handle_request_update(), handle_response_invite(), local_attended_transfer(), misdn_attempt_transfer(), misdn_queue_connected_line_update(), parked_call_exec(), sig_pri_handle_subcmds(), sip_call(), socket_process(), and wait_for_answer().
02263 { 02264 ast_party_id_init(&init->id); 02265 ast_party_id_init(&init->ani); 02266 init->ani2 = 0; 02267 init->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN; 02268 }
void ast_party_connected_line_set | ( | struct ast_party_connected_line * | dest, | |
const struct ast_party_connected_line * | src, | |||
const struct ast_set_party_connected_line * | update | |||
) |
Set the connected line information based on another connected line source.
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. |
Definition at line 2291 of file channel.c.
References ast_party_connected_line::ani, ast_party_connected_line::ani2, ast_party_id_set(), ast_party_connected_line::id, ast_party_connected_line::source, and update().
Referenced by ast_channel_set_connected_line(), and wait_for_winner().
02292 { 02293 ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL); 02294 ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL); 02295 dest->ani2 = src->ani2; 02296 dest->source = src->source; 02297 }
void ast_party_connected_line_set_init | ( | struct ast_party_connected_line * | init, | |
const struct ast_party_connected_line * | guide | |||
) |
Initialize the given connected line structure using the given guide for a set update operation.
init | Connected line structure to initialize. | |
guide | Source connected line to use as a guide in initializing. |
Definition at line 2283 of file channel.c.
References ast_party_connected_line::ani, ast_party_connected_line::ani2, ast_party_id_set_init(), ast_party_connected_line::id, and ast_party_connected_line::source.
Referenced by __ast_request_and_dial(), ast_indicate_data(), connectedline_write(), dial_exec_full(), feature_request_and_dial(), and wait_for_winner().
02284 { 02285 ast_party_id_set_init(&init->id, &guide->id); 02286 ast_party_id_set_init(&init->ani, &guide->ani); 02287 init->ani2 = guide->ani2; 02288 init->source = guide->source; 02289 }
void ast_party_dialed_copy | ( | struct ast_party_dialed * | dest, | |
const struct ast_party_dialed * | src | |||
) |
Copy the source dialed party information to the destination dialed party.
dest | Destination dialed party | |
src | Source dialed party |
Definition at line 2181 of file channel.c.
References ast_free, ast_party_subaddress_copy(), ast_strdup, ast_party_dialed::number, ast_party_dialed::plan, ast_party_dialed::str, ast_party_dialed::subaddress, and ast_party_dialed::transit_network_select.
Referenced by local_call().
02182 { 02183 if (dest == src) { 02184 /* Don't copy to self */ 02185 return; 02186 } 02187 02188 ast_free(dest->number.str); 02189 dest->number.str = ast_strdup(src->number.str); 02190 dest->number.plan = src->number.plan; 02191 ast_party_subaddress_copy(&dest->subaddress, &src->subaddress); 02192 dest->transit_network_select = src->transit_network_select; 02193 }
void ast_party_dialed_free | ( | struct ast_party_dialed * | doomed | ) |
Destroy the dialed party contents.
doomed | The dialed party to destroy. |
Definition at line 2216 of file channel.c.
References ast_free, ast_party_subaddress_free(), ast_party_dialed::number, ast_party_dialed::str, and ast_party_dialed::subaddress.
Referenced by ast_channel_destructor(), ast_dummy_channel_destructor(), and callerid_write().
02217 { 02218 ast_free(doomed->number.str); 02219 doomed->number.str = NULL; 02220 ast_party_subaddress_free(&doomed->subaddress); 02221 }
void ast_party_dialed_init | ( | struct ast_party_dialed * | init | ) |
Initialize the given dialed structure.
init | Dialed structure to initialize. |
Definition at line 2173 of file channel.c.
References ast_party_subaddress_init(), ast_party_dialed::number, ast_party_dialed::plan, ast_party_dialed::str, ast_party_dialed::subaddress, and ast_party_dialed::transit_network_select.
Referenced by __ast_channel_alloc_ap().
02174 { 02175 init->number.str = NULL; 02176 init->number.plan = 0;/* Unknown */ 02177 ast_party_subaddress_init(&init->subaddress); 02178 init->transit_network_select = 0; 02179 }
void ast_party_dialed_set | ( | struct ast_party_dialed * | dest, | |
const struct ast_party_dialed * | src | |||
) |
Set the dialed information based on another dialed source.
dest | The dialed one wishes to update | |
src | The new dialed values to update the dest |
Definition at line 2203 of file channel.c.
References ast_free, ast_party_subaddress_set(), ast_strdup, ast_party_dialed::number, ast_party_dialed::plan, ast_party_dialed::str, ast_party_dialed::subaddress, and ast_party_dialed::transit_network_select.
Referenced by callerid_write().
02204 { 02205 if (src->number.str && src->number.str != dest->number.str) { 02206 ast_free(dest->number.str); 02207 dest->number.str = ast_strdup(src->number.str); 02208 } 02209 dest->number.plan = src->number.plan; 02210 02211 ast_party_subaddress_set(&dest->subaddress, &src->subaddress); 02212 02213 dest->transit_network_select = src->transit_network_select; 02214 }
void ast_party_dialed_set_init | ( | struct ast_party_dialed * | init, | |
const struct ast_party_dialed * | guide | |||
) |
Initialize the given dialed structure using the given guide for a set update operation.
init | Caller structure to initialize. | |
guide | Source dialed to use as a guide in initializing. |
Definition at line 2195 of file channel.c.
References ast_party_subaddress_set_init(), ast_party_dialed::number, ast_party_dialed::plan, ast_party_dialed::str, ast_party_dialed::subaddress, and ast_party_dialed::transit_network_select.
Referenced by callerid_write().
02196 { 02197 init->number.str = NULL; 02198 init->number.plan = guide->number.plan; 02199 ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress); 02200 init->transit_network_select = guide->transit_network_select; 02201 }
void ast_party_id_copy | ( | struct ast_party_id * | dest, | |
const struct ast_party_id * | src | |||
) |
Copy the source party id information to the destination party id.
dest | Destination party id | |
src | Source party id |
Definition at line 2052 of file channel.c.
References ast_free, ast_party_name_copy(), ast_party_number_copy(), ast_party_subaddress_copy(), ast_strdup, ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, and ast_party_id::tag.
Referenced by ast_connected_line_copy_from_caller(), ast_connected_line_copy_to_caller(), ast_party_caller_copy(), ast_party_connected_line_copy(), ast_party_redirecting_copy(), and parkandannounce_exec().
02053 { 02054 if (dest == src) { 02055 /* Don't copy to self */ 02056 return; 02057 } 02058 02059 ast_party_name_copy(&dest->name, &src->name); 02060 ast_party_number_copy(&dest->number, &src->number); 02061 ast_party_subaddress_copy(&dest->subaddress, &src->subaddress); 02062 02063 ast_free(dest->tag); 02064 dest->tag = ast_strdup(src->tag); 02065 }
void ast_party_id_free | ( | struct ast_party_id * | doomed | ) |
Destroy the party id contents.
doomed | The party id to destroy. |
Definition at line 2098 of file channel.c.
References ast_free, ast_party_name_free(), ast_party_number_free(), ast_party_subaddress_free(), ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, and ast_party_id::tag.
Referenced by ast_party_caller_free(), ast_party_connected_line_free(), ast_party_redirecting_free(), parkandannounce_exec(), and sig_pri_mcid_event().
02099 { 02100 ast_party_name_free(&doomed->name); 02101 ast_party_number_free(&doomed->number); 02102 ast_party_subaddress_free(&doomed->subaddress); 02103 02104 ast_free(doomed->tag); 02105 doomed->tag = NULL; 02106 }
void ast_party_id_init | ( | struct ast_party_id * | init | ) |
Initialize the given party id structure.
init | Party id structure to initialize. |
Definition at line 2044 of file channel.c.
References ast_party_name_init(), ast_party_number_init(), ast_party_subaddress_init(), ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, and ast_party_id::tag.
Referenced by ast_party_caller_init(), ast_party_connected_line_init(), ast_party_redirecting_init(), dial_exec_full(), parkandannounce_exec(), and sig_pri_mcid_event().
02045 { 02046 ast_party_name_init(&init->name); 02047 ast_party_number_init(&init->number); 02048 ast_party_subaddress_init(&init->subaddress); 02049 init->tag = NULL; 02050 }
int ast_party_id_presentation | ( | const struct ast_party_id * | id | ) |
Determine the overall presentation value for the given party.
id | Party to determine the overall presentation value. |
Definition at line 2108 of file channel.c.
References AST_PRES_ALLOWED, AST_PRES_NUMBER_TYPE, AST_PRES_RESTRICTED, AST_PRES_RESTRICTION, AST_PRES_UNAVAILABLE, AST_PRES_USER_NUMBER_UNSCREENED, and id.
Referenced by add_rpid(), ast_str_retrieve_variable(), ast_var_channels_table(), callerpres_read(), iax2_call(), initreqprep(), my_set_callerid(), oh323_call(), party_id_build_data(), party_id_read(), redirecting_read(), report_new_callerid(), setup_env(), sig_pri_event_party_id(), sig_pri_handle_subcmds(), sip_call(), and socket_process().
02109 { 02110 int number_priority; 02111 int number_value; 02112 int number_screening; 02113 int name_priority; 02114 int name_value; 02115 02116 /* Determine name presentation priority. */ 02117 if (!id->name.valid) { 02118 name_value = AST_PRES_UNAVAILABLE; 02119 name_priority = 3; 02120 } else { 02121 name_value = id->name.presentation & AST_PRES_RESTRICTION; 02122 switch (name_value) { 02123 case AST_PRES_RESTRICTED: 02124 name_priority = 0; 02125 break; 02126 case AST_PRES_ALLOWED: 02127 name_priority = 1; 02128 break; 02129 case AST_PRES_UNAVAILABLE: 02130 name_priority = 2; 02131 break; 02132 default: 02133 name_value = AST_PRES_UNAVAILABLE; 02134 name_priority = 3; 02135 break; 02136 } 02137 } 02138 02139 /* Determine number presentation priority. */ 02140 if (!id->number.valid) { 02141 number_screening = AST_PRES_USER_NUMBER_UNSCREENED; 02142 number_value = AST_PRES_UNAVAILABLE; 02143 number_priority = 3; 02144 } else { 02145 number_screening = id->number.presentation & AST_PRES_NUMBER_TYPE; 02146 number_value = id->number.presentation & AST_PRES_RESTRICTION; 02147 switch (number_value) { 02148 case AST_PRES_RESTRICTED: 02149 number_priority = 0; 02150 break; 02151 case AST_PRES_ALLOWED: 02152 number_priority = 1; 02153 break; 02154 case AST_PRES_UNAVAILABLE: 02155 number_priority = 2; 02156 break; 02157 default: 02158 number_screening = AST_PRES_USER_NUMBER_UNSCREENED; 02159 number_value = AST_PRES_UNAVAILABLE; 02160 number_priority = 3; 02161 break; 02162 } 02163 } 02164 02165 /* Select the wining presentation value. */ 02166 if (name_priority < number_priority) { 02167 number_value = name_value; 02168 } 02169 02170 return number_value | number_screening; 02171 }
void ast_party_id_set | ( | struct ast_party_id * | dest, | |
const struct ast_party_id * | src, | |||
const struct ast_set_party_id * | update | |||
) |
Set the source party id information into the destination party id.
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. |
Definition at line 2075 of file channel.c.
References ast_free, ast_party_name_set(), ast_party_number_set(), ast_party_subaddress_set(), ast_strdup, ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, ast_party_id::tag, and update().
Referenced by ast_party_caller_set(), ast_party_connected_line_set(), and ast_party_redirecting_set().
02076 { 02077 if (dest == src) { 02078 /* Don't set to self */ 02079 return; 02080 } 02081 02082 if (!update || update->name) { 02083 ast_party_name_set(&dest->name, &src->name); 02084 } 02085 if (!update || update->number) { 02086 ast_party_number_set(&dest->number, &src->number); 02087 } 02088 if (!update || update->subaddress) { 02089 ast_party_subaddress_set(&dest->subaddress, &src->subaddress); 02090 } 02091 02092 if (src->tag && src->tag != dest->tag) { 02093 ast_free(dest->tag); 02094 dest->tag = ast_strdup(src->tag); 02095 } 02096 }
void ast_party_id_set_init | ( | struct ast_party_id * | init, | |
const struct ast_party_id * | guide | |||
) |
Initialize the given party id structure using the given guide for a set update operation.
init | Party id structure to initialize. | |
guide | Source party id to use as a guide in initializing. |
Definition at line 2067 of file channel.c.
References ast_party_name_set_init(), ast_party_number_set_init(), ast_party_subaddress_set_init(), ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, and ast_party_id::tag.
Referenced by ast_party_caller_set_init(), ast_party_connected_line_set_init(), ast_party_redirecting_set_init(), and dial_exec_full().
02068 { 02069 ast_party_name_set_init(&init->name, &guide->name); 02070 ast_party_number_set_init(&init->number, &guide->number); 02071 ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress); 02072 init->tag = NULL; 02073 }
void ast_party_name_copy | ( | struct ast_party_name * | dest, | |
const struct ast_party_name * | src | |||
) |
Copy the source party name information to the destination party name.
dest | Destination party name | |
src | Source party name |
Definition at line 1893 of file channel.c.
References ast_free, ast_strdup, ast_party_name::char_set, ast_party_name::presentation, ast_party_name::str, and ast_party_name::valid.
Referenced by ast_party_id_copy().
01894 { 01895 if (dest == src) { 01896 /* Don't copy to self */ 01897 return; 01898 } 01899 01900 ast_free(dest->str); 01901 dest->str = ast_strdup(src->str); 01902 dest->char_set = src->char_set; 01903 dest->presentation = src->presentation; 01904 dest->valid = src->valid; 01905 }
void ast_party_name_free | ( | struct ast_party_name * | doomed | ) |
Destroy the party name contents.
doomed | The party name to destroy. |
Definition at line 1932 of file channel.c.
References ast_free, and ast_party_name::str.
Referenced by __analog_ss_thread(), analog_ss_thread(), ast_party_id_free(), and skinny_newcall().
void ast_party_name_init | ( | struct ast_party_name * | init | ) |
Initialize the given name structure.
init | Name structure to initialize. |
Definition at line 1885 of file channel.c.
References AST_PARTY_CHAR_SET_ISO8859_1, AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, ast_party_name::char_set, ast_party_name::presentation, ast_party_name::str, and ast_party_name::valid.
Referenced by __analog_ss_thread(), analog_ss_thread(), ast_party_id_init(), and skinny_newcall().
01886 { 01887 init->str = NULL; 01888 init->char_set = AST_PARTY_CHAR_SET_ISO8859_1; 01889 init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 01890 init->valid = 0; 01891 }
void ast_party_name_set | ( | struct ast_party_name * | dest, | |
const struct ast_party_name * | src | |||
) |
Set the source party name information into the destination party name.
dest | The name one wishes to update | |
src | The new name values to update the dest |
Definition at line 1915 of file channel.c.
References ast_free, ast_strdup, ast_party_name::char_set, ast_party_name::presentation, ast_party_name::str, and ast_party_name::valid.
Referenced by ast_party_id_set().
01916 { 01917 if (dest == src) { 01918 /* Don't set to self */ 01919 return; 01920 } 01921 01922 if (src->str && src->str != dest->str) { 01923 ast_free(dest->str); 01924 dest->str = ast_strdup(src->str); 01925 } 01926 01927 dest->char_set = src->char_set; 01928 dest->presentation = src->presentation; 01929 dest->valid = src->valid; 01930 }
void ast_party_name_set_init | ( | struct ast_party_name * | init, | |
const struct ast_party_name * | guide | |||
) |
Initialize the given party name structure using the given guide for a set update operation.
init | Party name structure to initialize. | |
guide | Source party name to use as a guide in initializing. |
Definition at line 1907 of file channel.c.
References ast_party_name::char_set, ast_party_name::presentation, ast_party_name::str, and ast_party_name::valid.
Referenced by ast_party_id_set_init().
01908 { 01909 init->str = NULL; 01910 init->char_set = guide->char_set; 01911 init->presentation = guide->presentation; 01912 init->valid = guide->valid; 01913 }
void ast_party_number_copy | ( | struct ast_party_number * | dest, | |
const struct ast_party_number * | src | |||
) |
Copy the source party number information to the destination party number.
dest | Destination party number | |
src | Source party number |
Definition at line 1946 of file channel.c.
References ast_free, ast_strdup, ast_party_number::plan, ast_party_number::presentation, ast_party_number::str, and ast_party_number::valid.
Referenced by ast_party_id_copy().
01947 { 01948 if (dest == src) { 01949 /* Don't copy to self */ 01950 return; 01951 } 01952 01953 ast_free(dest->str); 01954 dest->str = ast_strdup(src->str); 01955 dest->plan = src->plan; 01956 dest->presentation = src->presentation; 01957 dest->valid = src->valid; 01958 }
void ast_party_number_free | ( | struct ast_party_number * | doomed | ) |
Destroy the party number contents.
doomed | The party number to destroy. |
Definition at line 1985 of file channel.c.
References ast_free, and ast_party_number::str.
Referenced by __analog_ss_thread(), analog_ss_thread(), ast_party_id_free(), do_forward(), and skinny_newcall().
void ast_party_number_init | ( | struct ast_party_number * | init | ) |
Initialize the given number structure.
init | Number structure to initialize. |
Definition at line 1938 of file channel.c.
References AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, ast_party_number::plan, ast_party_number::presentation, ast_party_number::str, and ast_party_number::valid.
Referenced by __analog_ss_thread(), analog_ss_thread(), ast_party_id_init(), do_forward(), and skinny_newcall().
01939 { 01940 init->str = NULL; 01941 init->plan = 0;/* Unknown */ 01942 init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 01943 init->valid = 0; 01944 }
void ast_party_number_set | ( | struct ast_party_number * | dest, | |
const struct ast_party_number * | src | |||
) |
Set the source party number information into the destination party number.
dest | The number one wishes to update | |
src | The new number values to update the dest |
Definition at line 1968 of file channel.c.
References ast_free, ast_strdup, ast_party_number::plan, ast_party_number::presentation, ast_party_number::str, and ast_party_number::valid.
Referenced by ast_party_id_set().
01969 { 01970 if (dest == src) { 01971 /* Don't set to self */ 01972 return; 01973 } 01974 01975 if (src->str && src->str != dest->str) { 01976 ast_free(dest->str); 01977 dest->str = ast_strdup(src->str); 01978 } 01979 01980 dest->plan = src->plan; 01981 dest->presentation = src->presentation; 01982 dest->valid = src->valid; 01983 }
void ast_party_number_set_init | ( | struct ast_party_number * | init, | |
const struct ast_party_number * | guide | |||
) |
Initialize the given party number structure using the given guide for a set update operation.
init | Party number structure to initialize. | |
guide | Source party number to use as a guide in initializing. |
Definition at line 1960 of file channel.c.
References ast_party_number::plan, ast_party_number::presentation, ast_party_number::str, and ast_party_number::valid.
Referenced by ast_party_id_set_init().
01961 { 01962 init->str = NULL; 01963 init->plan = guide->plan; 01964 init->presentation = guide->presentation; 01965 init->valid = guide->valid; 01966 }
void ast_party_redirecting_copy | ( | struct ast_party_redirecting * | dest, | |
const struct ast_party_redirecting * | src | |||
) |
Copy the source redirecting information to the destination redirecting.
dest | Destination redirecting | |
src | Source redirecting |
Definition at line 2321 of file channel.c.
References ast_party_id_copy(), ast_party_redirecting::count, ast_party_redirecting::from, ast_party_redirecting::reason, and ast_party_redirecting::to.
Referenced by ast_call_forward(), ast_channel_redirecting_macro(), begin_dial_channel(), call_forward_inherit(), dial_exec_full(), do_forward(), local_call(), and ring_entry().
02322 { 02323 if (dest == src) { 02324 /* Don't copy to self */ 02325 return; 02326 } 02327 02328 ast_party_id_copy(&dest->from, &src->from); 02329 ast_party_id_copy(&dest->to, &src->to); 02330 dest->count = src->count; 02331 dest->reason = src->reason; 02332 }
void ast_party_redirecting_free | ( | struct ast_party_redirecting * | doomed | ) |
Destroy the redirecting information contents.
doomed | The redirecting information to destroy. |
Definition at line 2350 of file channel.c.
References ast_party_id_free(), ast_party_redirecting::from, and ast_party_redirecting::to.
Referenced by ast_channel_destructor(), ast_dummy_channel_destructor(), ast_indicate_data(), call_forward_inherit(), do_forward(), handle_request_invite(), handle_response(), handle_response_invite(), redirecting_write(), and sig_pri_handle_subcmds().
02351 { 02352 ast_party_id_free(&doomed->from); 02353 ast_party_id_free(&doomed->to); 02354 }
void ast_party_redirecting_init | ( | struct ast_party_redirecting * | init | ) |
Initialize the given redirecting structure.
init | Redirecting structure to initialize. |
Definition at line 2313 of file channel.c.
References ast_party_id_init(), AST_REDIRECTING_REASON_UNKNOWN, ast_party_redirecting::count, ast_party_redirecting::from, ast_party_redirecting::reason, and ast_party_redirecting::to.
Referenced by __ast_channel_alloc_ap(), call_forward_inherit(), do_forward(), handle_request_invite(), handle_response(), and handle_response_invite().
02314 { 02315 ast_party_id_init(&init->from); 02316 ast_party_id_init(&init->to); 02317 init->count = 0; 02318 init->reason = AST_REDIRECTING_REASON_UNKNOWN; 02319 }
void ast_party_redirecting_set | ( | struct ast_party_redirecting * | dest, | |
const struct ast_party_redirecting * | src, | |||
const struct ast_set_party_redirecting * | update | |||
) |
Set the redirecting information based on another redirecting source.
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. |
Definition at line 2342 of file channel.c.
References ast_party_id_set(), ast_party_redirecting::count, ast_party_redirecting::from, ast_party_redirecting::reason, ast_party_redirecting::to, and update().
Referenced by ast_channel_set_redirecting().
02343 { 02344 ast_party_id_set(&dest->from, &src->from, update ? &update->from : NULL); 02345 ast_party_id_set(&dest->to, &src->to, update ? &update->to : NULL); 02346 dest->reason = src->reason; 02347 dest->count = src->count; 02348 }
void ast_party_redirecting_set_init | ( | struct ast_party_redirecting * | init, | |
const struct ast_party_redirecting * | guide | |||
) |
Initialize the given redirecting id structure using the given guide for a set update operation.
init | Redirecting id structure to initialize. | |
guide | Source redirecting id to use as a guide in initializing. |
Definition at line 2334 of file channel.c.
References ast_party_id_set_init(), ast_party_redirecting::count, ast_party_redirecting::from, ast_party_redirecting::reason, and ast_party_redirecting::to.
Referenced by ast_indicate_data(), misdn_copy_redirecting_to_ast(), redirecting_write(), and sig_pri_redirecting_convert().
02335 { 02336 ast_party_id_set_init(&init->from, &guide->from); 02337 ast_party_id_set_init(&init->to, &guide->to); 02338 init->count = guide->count; 02339 init->reason = guide->reason; 02340 }
void ast_party_subaddress_copy | ( | struct ast_party_subaddress * | dest, | |
const struct ast_party_subaddress * | src | |||
) |
Copy the source party subaddress information to the destination party subaddress.
dest | Destination party subaddress | |
src | Source party subaddress |
Definition at line 1999 of file channel.c.
References ast_free, ast_strdup, ast_party_subaddress::odd_even_indicator, ast_party_subaddress::str, ast_party_subaddress::type, and ast_party_subaddress::valid.
Referenced by ast_party_dialed_copy(), and ast_party_id_copy().
02000 { 02001 if (dest == src) { 02002 /* Don't copy to self */ 02003 return; 02004 } 02005 02006 ast_free(dest->str); 02007 dest->str = ast_strdup(src->str); 02008 dest->type = src->type; 02009 dest->odd_even_indicator = src->odd_even_indicator; 02010 dest->valid = src->valid; 02011 }
void ast_party_subaddress_free | ( | struct ast_party_subaddress * | doomed | ) |
Destroy the party subaddress contents.
doomed | The party subaddress to destroy. |
Definition at line 2038 of file channel.c.
References ast_free, and ast_party_subaddress::str.
Referenced by ast_party_dialed_free(), and ast_party_id_free().
void ast_party_subaddress_init | ( | struct ast_party_subaddress * | init | ) |
Initialize the given subaddress structure.
init | Subaddress structure to initialize. |
Definition at line 1991 of file channel.c.
References ast_party_subaddress::odd_even_indicator, ast_party_subaddress::str, ast_party_subaddress::type, and ast_party_subaddress::valid.
Referenced by ast_party_dialed_init(), ast_party_id_init(), sig_pri_call(), and sig_pri_set_subaddress().
01992 { 01993 init->str = NULL; 01994 init->type = 0; 01995 init->odd_even_indicator = 0; 01996 init->valid = 0; 01997 }
void ast_party_subaddress_set | ( | struct ast_party_subaddress * | dest, | |
const struct ast_party_subaddress * | src | |||
) |
Set the source party subaddress information into the destination party subaddress.
dest | The subaddress one wishes to update | |
src | The new subaddress values to update the dest |
Definition at line 2021 of file channel.c.
References ast_free, ast_strdup, ast_party_subaddress::odd_even_indicator, ast_party_subaddress::str, ast_party_subaddress::type, and ast_party_subaddress::valid.
Referenced by ast_party_dialed_set(), ast_party_id_set(), and sig_pri_handle_subcmds().
02022 { 02023 if (dest == src) { 02024 /* Don't set to self */ 02025 return; 02026 } 02027 02028 if (src->str && src->str != dest->str) { 02029 ast_free(dest->str); 02030 dest->str = ast_strdup(src->str); 02031 } 02032 02033 dest->type = src->type; 02034 dest->odd_even_indicator = src->odd_even_indicator; 02035 dest->valid = src->valid; 02036 }
void ast_party_subaddress_set_init | ( | struct ast_party_subaddress * | init, | |
const struct ast_party_subaddress * | guide | |||
) |
Initialize the given party subaddress structure using the given guide for a set update operation.
init | Party subaddress structure to initialize. | |
guide | Source party subaddress to use as a guide in initializing. |
Definition at line 2013 of file channel.c.
References ast_party_subaddress::odd_even_indicator, ast_party_subaddress::str, ast_party_subaddress::type, and ast_party_subaddress::valid.
Referenced by ast_party_dialed_set_init(), and ast_party_id_set_init().
02014 { 02015 init->str = NULL; 02016 init->type = guide->type; 02017 init->odd_even_indicator = guide->odd_even_indicator; 02018 init->valid = guide->valid; 02019 }
void ast_poll_channel_add | ( | struct ast_channel * | chan0, | |
struct ast_channel * | chan1 | |||
) |
Add a channel to an optimized waitfor
Definition at line 2610 of file channel.c.
References AST_MAX_FDS, and ast_channel::fds.
Referenced by ast_generic_bridge(), begin_dial_channel(), feature_request_and_dial(), local_bridge_loop(), remote_bridge_loop(), and wait_for_answer().
02611 { 02612 #ifdef HAVE_EPOLL 02613 struct epoll_event ev; 02614 int i = 0; 02615 02616 if (chan0->epfd == -1) 02617 return; 02618 02619 /* Iterate through the file descriptors on chan1, adding them to chan0 */ 02620 for (i = 0; i < AST_MAX_FDS; i++) { 02621 if (chan1->fds[i] == -1) 02622 continue; 02623 ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP; 02624 ev.data.ptr = chan1->epfd_data[i]; 02625 epoll_ctl(chan0->epfd, EPOLL_CTL_ADD, chan1->fds[i], &ev); 02626 } 02627 02628 #endif 02629 return; 02630 }
void ast_poll_channel_del | ( | struct ast_channel * | chan0, | |
struct ast_channel * | chan1 | |||
) |
Delete a channel from an optimized waitfor
Definition at line 2633 of file channel.c.
References AST_MAX_FDS, and ast_channel::fds.
Referenced by feature_request_and_dial(), and monitor_dial().
02634 { 02635 #ifdef HAVE_EPOLL 02636 struct epoll_event ev; 02637 int i = 0; 02638 02639 if (chan0->epfd == -1) 02640 return; 02641 02642 for (i = 0; i < AST_MAX_FDS; i++) { 02643 if (chan1->fds[i] == -1) 02644 continue; 02645 epoll_ctl(chan0->epfd, EPOLL_CTL_DEL, chan1->fds[i], &ev); 02646 } 02647 02648 #endif 02649 return; 02650 }
char* ast_print_group | ( | char * | buf, | |
int | buflen, | |||
ast_group_t | group | |||
) |
print call- and pickup groups into buffer
Definition at line 7963 of file channel.c.
References first.
Referenced by _sip_show_peer(), _skinny_show_line(), func_channel_read(), function_sippeer(), misdn_cfg_get_config_string(), print_group(), read_config(), and serialize_showchan().
07964 { 07965 unsigned int i; 07966 int first = 1; 07967 char num[3]; 07968 07969 buf[0] = '\0'; 07970 07971 if (!group) /* Return empty string if no group */ 07972 return buf; 07973 07974 for (i = 0; i <= 63; i++) { /* Max group is 63 */ 07975 if (group & ((ast_group_t) 1 << i)) { 07976 if (!first) { 07977 strncat(buf, ", ", buflen - strlen(buf) - 1); 07978 } else { 07979 first = 0; 07980 } 07981 snprintf(num, sizeof(num), "%u", i); 07982 strncat(buf, num, buflen - strlen(buf) - 1); 07983 } 07984 } 07985 return buf; 07986 }
int ast_prod | ( | struct ast_channel * | chan | ) |
Send empty audio to prime a channel driver.
Definition at line 4635 of file channel.c.
References ast_channel::_state, ast_debug, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), AST_STATE_UP, ast_write(), chanlist::chan, ast_frame_subclass::codec, ast_frame::data, LOG_WARNING, ast_channel::name, ast_frame::ptr, ast_channel::rawwriteformat, ast_frame::src, and ast_frame::subclass.
Referenced by ast_activate_generator().
04636 { 04637 struct ast_frame a = { AST_FRAME_VOICE }; 04638 char nothing[128]; 04639 04640 /* Send an empty audio frame to get things moving */ 04641 if (chan->_state != AST_STATE_UP) { 04642 ast_debug(1, "Prodding channel '%s'\n", chan->name); 04643 a.subclass.codec = chan->rawwriteformat; 04644 a.data.ptr = nothing + AST_FRIENDLY_OFFSET; 04645 a.src = "ast_prod"; /* this better match check in ast_write */ 04646 if (ast_write(chan, &a)) 04647 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name); 04648 } 04649 return 0; 04650 }
int ast_queue_control | ( | struct ast_channel * | chan, | |
enum ast_control_frame_type | control | |||
) |
Queue a control frame with payload.
chan | channel to queue frame onto | |
control | type of control frame |
zero | on success | |
non-zero | on failure |
Definition at line 1562 of file channel.c.
References AST_FRAME_CONTROL, ast_queue_frame(), chanlist::chan, and f.
Referenced by __analog_handle_event(), __analog_ss_thread(), __ast_read(), __dahdi_exception(), __oh323_update_info(), analog_call(), analog_exception(), analog_hangup(), analog_ss_thread(), ast_do_pickup(), attempt_transfer(), auto_congest(), cb_events(), cli_console_answer(), cli_console_flash(), console_answer(), console_call(), console_sendtext(), dahdi_handle_event(), dahdi_hangup(), gtalk_is_answered(), gtalk_ringing_ack(), handle_hd_hf(), handle_offhook_message(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), handle_response_refer(), handle_soft_key_event_message(), handle_stimulus_message(), HandleCallIncoming(), jingle_is_answered(), jingle_ringing_ack(), masquerade_colp_transfer(), misdn_facility_ie_handler(), multicast_rtp_call(), nbs_call(), phone_call(), process_sdp(), receive_digit(), remote_hold(), send_cause2ast(), setup_rtp_connection(), skinny_call(), skinny_transfer(), skinny_unhold(), unistim_call(), and update_state().
01563 { 01564 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control }; 01565 return ast_queue_frame(chan, &f); 01566 }
int ast_queue_control_data | ( | struct ast_channel * | chan, | |
enum ast_control_frame_type | control, | |||
const void * | data, | |||
size_t | datalen | |||
) |
Queue a control frame with payload.
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 |
0 | success | |
non-zero | failure |
The channel does not need to be locked before calling this function.
Definition at line 1569 of file channel.c.
References AST_FRAME_CONTROL, ast_queue_frame(), chanlist::chan, and f.
Referenced by __analog_handle_event(), analog_hangup(), ast_channel_queue_connected_line_update(), ast_channel_queue_redirecting_update(), change_t38_state(), dahdi_handle_event(), dahdi_hangup(), handle_request_notify(), handle_response_refer(), iax2_queue_control_data(), iax2_transfer(), interpret_t38_parameters(), local_attended_transfer(), masquerade_colp_transfer(), process_sdp(), sig_pri_aoc_d_from_pri(), sig_pri_aoc_e_from_pri(), sig_pri_aoc_s_from_pri(), sig_pri_send_aoce_termination_request(), sip_sipredirect(), and skinny_hold().
01571 { 01572 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control, .data.ptr = (void *) data, .datalen = datalen }; 01573 return ast_queue_frame(chan, &f); 01574 }
int ast_queue_frame | ( | struct ast_channel * | chan, | |
struct ast_frame * | f | |||
) |
Queue one or more frames to a channel's frame queue.
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. |
0 | success | |
non-zero | failure |
Definition at line 1519 of file channel.c.
References __ast_queue_frame(), and chanlist::chan.
Referenced by __ast_channel_masquerade(), __ast_read(), __oh323_rtp_create(), __oh323_update_info(), action_atxfer(), agent_request(), alsa_call(), ast_channel_setwhentohangup_tv(), ast_do_masquerade(), ast_queue_cc_frame(), ast_queue_control(), ast_queue_control_data(), ast_queue_hangup(), ast_queue_hangup_with_cause(), ast_softhangup_nolock(), bridge_write(), cb_events(), cli_console_dial(), cli_console_sendtext(), console_dial(), console_do_answer(), console_flash(), console_sendtext(), dahdi_queue_frame(), dahdi_read(), dictate_exec(), do_immediate_setup(), gtalk_handle_dtmf(), handle_keypad_button_message(), handle_request_info(), handle_request_invite(), handle_response_invite(), iax2_queue_frame(), jingle_handle_dtmf(), keypad_digit(), local_queue_frame(), mgcp_queue_frame(), oh323_simulate_dtmf_end(), oss_call(), pri_queue_frame(), process_sdp(), queue_dtmf_readq(), receive_digit(), receive_message(), rpt_call(), sig_pri_handle_hold(), sig_pri_handle_subcmds(), sig_ss7_queue_frame(), stream_monitor(), unistim_do_senddigit(), unistim_senddigit_end(), usbradio_read(), and wakeup_sub().
01520 { 01521 return __ast_queue_frame(chan, fin, 0, NULL); 01522 }
int ast_queue_frame_head | ( | struct ast_channel * | chan, | |
struct ast_frame * | f | |||
) |
Queue one or more frames to the head of a channel's frame queue.
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. |
0 | success | |
non-zero | failure |
Definition at line 1524 of file channel.c.
References __ast_queue_frame(), and chanlist::chan.
Referenced by __ast_answer(), __ast_read(), ast_autoservice_stop(), ast_safe_sleep_conditional(), and feature_request_and_dial().
01525 { 01526 return __ast_queue_frame(chan, fin, 1, NULL); 01527 }
int ast_queue_hangup | ( | struct ast_channel * | chan | ) |
Queue a hangup frame.
Definition at line 1530 of file channel.c.
References ast_channel::_softhangup, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, ast_queue_frame(), AST_SOFTHANGUP_DEV, chanlist::chan, and f.
Referenced by bridge_queue_hangup(), cleanup_connection(), cli_console_hangup(), close_call(), gtalk_hangup_farend(), gtalk_is_answered(), handle_onhook_message(), handle_request_bye(), handle_request_cancel(), handle_soft_key_event_message(), iax2_destroy(), iax2_queue_hangup(), jingle_hangup_farend(), local_fixup(), local_hangup(), and mgcp_queue_hangup().
01531 { 01532 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP }; 01533 /* Yeah, let's not change a lock-critical value without locking */ 01534 if (!ast_channel_trylock(chan)) { 01535 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01536 ast_channel_unlock(chan); 01537 } 01538 return ast_queue_frame(chan, &f); 01539 }
int ast_queue_hangup_with_cause | ( | struct ast_channel * | chan, | |
int | cause | |||
) |
Queue a hangup frame with hangupcause set.
[in] | chan | channel to queue frame onto |
[in] | cause | the hangup cause |
Definition at line 1542 of file channel.c.
References ast_channel::_softhangup, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, ast_queue_frame(), AST_SOFTHANGUP_DEV, chanlist::chan, f, and ast_channel::hangupcause.
Referenced by __analog_handle_event(), __oh323_update_info(), __sip_autodestruct(), close_call(), close_client(), console_hangup(), dahdi_handle_event(), dahdi_r2_on_call_disconnect(), handle_request_bye(), handle_response(), handle_response_invite(), HandleCallOutgoing(), hangup_chan(), hangup_connection(), misdn_answer(), retrans_pkt(), and TransferCallStep1().
01543 { 01544 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP }; 01545 01546 if (cause >= 0) 01547 f.data.uint32 = cause; 01548 01549 /* Yeah, let's not change a lock-critical value without locking */ 01550 if (!ast_channel_trylock(chan)) { 01551 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01552 if (cause < 0) 01553 f.data.uint32 = chan->hangupcause; 01554 01555 ast_channel_unlock(chan); 01556 } 01557 01558 return ast_queue_frame(chan, &f); 01559 }
int ast_raw_answer | ( | struct ast_channel * | chan, | |
int | cdr_answer | |||
) |
Answer a channel.
chan | channel to answer | |
cdr_answer | flag to control whether any associated CDR should be marked as 'answered' |
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.
0 | on success | |
non-zero | on failure |
Definition at line 2871 of file channel.c.
References ast_channel::_state, ast_channel_tech::answer, ast_cdr_answer(), AST_CEL_ANSWER, ast_cel_report_event(), ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, ast_indicate(), ast_setstate(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_test_flag, ast_channel::cdr, chanlist::chan, and ast_channel::tech.
Referenced by __ast_answer(), and ast_bridge_call().
02872 { 02873 int res = 0; 02874 02875 ast_channel_lock(chan); 02876 02877 /* You can't answer an outbound call */ 02878 if (ast_test_flag(chan, AST_FLAG_OUTGOING)) { 02879 ast_channel_unlock(chan); 02880 return 0; 02881 } 02882 02883 /* Stop if we're a zombie or need a soft hangup */ 02884 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 02885 ast_channel_unlock(chan); 02886 return -1; 02887 } 02888 02889 ast_channel_unlock(chan); 02890 02891 switch (chan->_state) { 02892 case AST_STATE_RINGING: 02893 case AST_STATE_RING: 02894 ast_channel_lock(chan); 02895 if (chan->tech->answer) { 02896 res = chan->tech->answer(chan); 02897 } 02898 ast_setstate(chan, AST_STATE_UP); 02899 if (cdr_answer) { 02900 ast_cdr_answer(chan->cdr); 02901 } 02902 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL); 02903 ast_channel_unlock(chan); 02904 break; 02905 case AST_STATE_UP: 02906 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL); 02907 /* Calling ast_cdr_answer when it it has previously been called 02908 * is essentially a no-op, so it is safe. 02909 */ 02910 if (cdr_answer) { 02911 ast_cdr_answer(chan->cdr); 02912 } 02913 break; 02914 default: 02915 break; 02916 } 02917 02918 ast_indicate(chan, -1); 02919 02920 return res; 02921 }
struct ast_frame* ast_read | ( | struct ast_channel * | chan | ) |
Reads a frame.
chan | channel to read a frame from |
Definition at line 4252 of file channel.c.
References __ast_read(), and chanlist::chan.
Referenced by __adsi_transmit_messages(), __analog_ss_thread(), __ast_answer(), __ast_play_and_record(), __ast_request_and_dial(), adsi_careful_send(), agent_ack_sleep(), agent_read(), analog_ss_thread(), ast_bridge_handle_trip(), ast_recvtext(), ast_safe_sleep_conditional(), ast_tonepair(), ast_transfer(), ast_udptl_bridge(), ast_waitfordigit_full(), async_agi_read_frame(), async_wait(), autoservice_run(), background_detect_exec(), channel_spy(), conf_flush(), conf_run(), dahdi_bridge(), dial_exec_full(), dictate_exec(), disa_exec(), disable_t38(), do_idle_thread(), do_waiting(), echo_exec(), eivr_comm(), feature_request_and_dial(), find_cache(), generic_fax_exec(), handle_recordfile(), handle_speechrecognize(), ices_exec(), isAnsweringMachine(), jack_exec(), local_bridge_loop(), manage_parked_call(), measurenoise(), misdn_bridge(), monitor_dial(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), receivefax_t38_init(), recordthread(), remote_bridge_loop(), rpt(), run_agi(), send_tone_burst(), send_waveform_to_channel(), sendfax_t38_init(), sendurl_exec(), speech_background(), transmit_audio(), transmit_t38(), wait_for_hangup(), wait_for_winner(), waitforring_exec(), and waitstream_core().
04253 { 04254 return __ast_read(chan, 0); 04255 }
struct ast_frame* ast_read_noaudio | ( | struct ast_channel * | chan | ) |
Reads a frame, returning AST_FRAME_NULL frame if audio.
chan | channel to read a frame from |
Definition at line 4257 of file channel.c.
References __ast_read(), and chanlist::chan.
Referenced by ast_bridge_handle_trip(), and conf_run().
04258 { 04259 return __ast_read(chan, 1); 04260 }
int ast_readstring | ( | struct ast_channel * | c, | |
char * | s, | |||
int | len, | |||
int | timeout, | |||
int | rtimeout, | |||
char * | enders | |||
) |
Reads multiple digits.
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 |
Definition at line 5686 of file channel.c.
References ast_readstring_full().
Referenced by ast_adsi_begin_download(), ast_adsi_get_cpeinfo(), ast_adsi_load_session(), ast_app_getdata(), dialout(), do_directory(), forward_message(), privacy_exec(), vm_authenticate(), vm_newuser(), and vm_options().
05687 { 05688 return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1); 05689 }
int ast_readstring_full | ( | struct ast_channel * | c, | |
char * | s, | |||
int | len, | |||
int | timeout, | |||
int | rtimeout, | |||
char * | enders, | |||
int | audiofd, | |||
int | ctrlfd | |||
) |
Definition at line 5691 of file channel.c.
References ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_check_hangup(), AST_DIGIT_ANY, AST_FLAG_ZOMBIE, AST_GETDATA_COMPLETE, AST_GETDATA_EMPTY_END_TERMINATED, AST_GETDATA_FAILED, AST_GETDATA_INTERRUPTED, AST_GETDATA_TIMEOUT, ast_opt_transmit_silence, ast_stopstream(), ast_test_flag, ast_waitfordigit_full(), ast_waitstream_full(), and ast_channel::stream.
Referenced by ast_app_getdata_full(), and ast_readstring().
05692 { 05693 int pos = 0; /* index in the buffer where we accumulate digits */ 05694 int to = ftimeout; 05695 05696 struct ast_silence_generator *silgen = NULL; 05697 05698 /* Stop if we're a zombie or need a soft hangup */ 05699 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 05700 return -1; 05701 if (!len) 05702 return -1; 05703 for (;;) { 05704 int d; 05705 if (c->stream) { 05706 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd); 05707 ast_stopstream(c); 05708 if (!silgen && ast_opt_transmit_silence) 05709 silgen = ast_channel_start_silence_generator(c); 05710 usleep(1000); 05711 if (!d) 05712 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 05713 } else { 05714 if (!silgen && ast_opt_transmit_silence) 05715 silgen = ast_channel_start_silence_generator(c); 05716 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 05717 } 05718 if (d < 0) { 05719 ast_channel_stop_silence_generator(c, silgen); 05720 return AST_GETDATA_FAILED; 05721 } 05722 if (d == 0) { 05723 s[pos] = '\0'; 05724 ast_channel_stop_silence_generator(c, silgen); 05725 return AST_GETDATA_TIMEOUT; 05726 } 05727 if (d == 1) { 05728 s[pos] = '\0'; 05729 ast_channel_stop_silence_generator(c, silgen); 05730 return AST_GETDATA_INTERRUPTED; 05731 } 05732 if (strchr(enders, d) && (pos == 0)) { 05733 s[pos] = '\0'; 05734 ast_channel_stop_silence_generator(c, silgen); 05735 return AST_GETDATA_EMPTY_END_TERMINATED; 05736 } 05737 if (!strchr(enders, d)) { 05738 s[pos++] = d; 05739 } 05740 if (strchr(enders, d) || (pos >= len)) { 05741 s[pos] = '\0'; 05742 ast_channel_stop_silence_generator(c, silgen); 05743 return AST_GETDATA_COMPLETE; 05744 } 05745 to = timeout; 05746 } 05747 /* Never reached */ 05748 return 0; 05749 }
int ast_recvchar | ( | struct ast_channel * | chan, | |
int | timeout | |||
) |
Receives a text character from a channel.
chan | channel to act upon | |
timeout | timeout in milliseconds (0 for infinite wait) |
Definition at line 4511 of file channel.c.
References ast_free, ast_recvtext(), and chanlist::chan.
Referenced by handle_recvchar().
04512 { 04513 int c; 04514 char *buf = ast_recvtext(chan, timeout); 04515 if (buf == NULL) 04516 return -1; /* error or timeout */ 04517 c = *(unsigned char *)buf; 04518 ast_free(buf); 04519 return c; 04520 }
char* ast_recvtext | ( | struct ast_channel * | chan, | |
int | timeout | |||
) |
Receives a text string from a channel Read a string of text from a channel.
chan | channel to act upon | |
timeout | timeout in milliseconds (0 for infinite wait) |
Definition at line 4522 of file channel.c.
References ast_check_hangup(), AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_TEXT, ast_frfree, ast_read(), ast_strndup, ast_waitfor(), chanlist::chan, and f.
Referenced by ast_recvchar(), and handle_recvtext().
04523 { 04524 int res, done = 0; 04525 char *buf = NULL; 04526 04527 while (!done) { 04528 struct ast_frame *f; 04529 if (ast_check_hangup(chan)) 04530 break; 04531 res = ast_waitfor(chan, timeout); 04532 if (res <= 0) /* timeout or error */ 04533 break; 04534 timeout = res; /* update timeout */ 04535 f = ast_read(chan); 04536 if (f == NULL) 04537 break; /* no frame */ 04538 if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_HANGUP) 04539 done = 1; /* force a break */ 04540 else if (f->frametype == AST_FRAME_TEXT) { /* what we want */ 04541 buf = ast_strndup((char *) f->data.ptr, f->datalen); /* dup and break */ 04542 done = 1; 04543 } 04544 ast_frfree(f); 04545 } 04546 return buf; 04547 }
int ast_redirecting_build_data | ( | unsigned char * | data, | |
size_t | datalen, | |||
const struct ast_party_redirecting * | redirecting, | |||
const struct ast_set_party_redirecting * | update | |||
) |
Build the redirecting id data frame.
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. |
-1 | if error | |
Amount | of data buffer used |
Definition at line 8865 of file channel.c.
References ast_log(), AST_REDIRECTING_COUNT, AST_REDIRECTING_FROM_ID_PRESENTATION, AST_REDIRECTING_FROM_NAME, AST_REDIRECTING_FROM_NAME_CHAR_SET, AST_REDIRECTING_FROM_NAME_PRESENTATION, AST_REDIRECTING_FROM_NAME_VALID, AST_REDIRECTING_FROM_NUMBER, AST_REDIRECTING_FROM_NUMBER_PLAN, AST_REDIRECTING_FROM_NUMBER_PRESENTATION, AST_REDIRECTING_FROM_NUMBER_VALID, AST_REDIRECTING_FROM_SUBADDRESS, AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_FROM_SUBADDRESS_TYPE, AST_REDIRECTING_FROM_SUBADDRESS_VALID, AST_REDIRECTING_FROM_TAG, AST_REDIRECTING_TO_ID_PRESENTATION, AST_REDIRECTING_TO_NAME, AST_REDIRECTING_TO_NAME_CHAR_SET, AST_REDIRECTING_TO_NAME_PRESENTATION, AST_REDIRECTING_TO_NAME_VALID, AST_REDIRECTING_TO_NUMBER, AST_REDIRECTING_TO_NUMBER_PLAN, AST_REDIRECTING_TO_NUMBER_PRESENTATION, AST_REDIRECTING_TO_NUMBER_VALID, AST_REDIRECTING_TO_SUBADDRESS, AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_TO_SUBADDRESS_TYPE, AST_REDIRECTING_TO_SUBADDRESS_VALID, AST_REDIRECTING_TO_TAG, AST_REDIRECTING_VERSION, ast_party_redirecting::count, ast_party_redirecting::from, LOG_WARNING, ast_party_id_ies::name, party_id_build_data(), ast_party_redirecting::reason, ast_party_name_ies::str, ast_party_redirecting::to, update(), and value.
Referenced by ast_channel_queue_redirecting_update(), ast_channel_update_redirecting(), and local_indicate().
08866 { 08867 int32_t value; 08868 size_t pos = 0; 08869 int res; 08870 08871 static const struct ast_party_id_ies from_ies = { 08872 .name.str = AST_REDIRECTING_FROM_NAME, 08873 .name.char_set = AST_REDIRECTING_FROM_NAME_CHAR_SET, 08874 .name.presentation = AST_REDIRECTING_FROM_NAME_PRESENTATION, 08875 .name.valid = AST_REDIRECTING_FROM_NAME_VALID, 08876 08877 .number.str = AST_REDIRECTING_FROM_NUMBER, 08878 .number.plan = AST_REDIRECTING_FROM_NUMBER_PLAN, 08879 .number.presentation = AST_REDIRECTING_FROM_NUMBER_PRESENTATION, 08880 .number.valid = AST_REDIRECTING_FROM_NUMBER_VALID, 08881 08882 .subaddress.str = AST_REDIRECTING_FROM_SUBADDRESS, 08883 .subaddress.type = AST_REDIRECTING_FROM_SUBADDRESS_TYPE, 08884 .subaddress.odd_even_indicator = AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN, 08885 .subaddress.valid = AST_REDIRECTING_FROM_SUBADDRESS_VALID, 08886 08887 .tag = AST_REDIRECTING_FROM_TAG, 08888 .combined_presentation = AST_REDIRECTING_FROM_ID_PRESENTATION, 08889 }; 08890 static const struct ast_party_id_ies to_ies = { 08891 .name.str = AST_REDIRECTING_TO_NAME, 08892 .name.char_set = AST_REDIRECTING_TO_NAME_CHAR_SET, 08893 .name.presentation = AST_REDIRECTING_TO_NAME_PRESENTATION, 08894 .name.valid = AST_REDIRECTING_TO_NAME_VALID, 08895 08896 .number.str = AST_REDIRECTING_TO_NUMBER, 08897 .number.plan = AST_REDIRECTING_TO_NUMBER_PLAN, 08898 .number.presentation = AST_REDIRECTING_TO_NUMBER_PRESENTATION, 08899 .number.valid = AST_REDIRECTING_TO_NUMBER_VALID, 08900 08901 .subaddress.str = AST_REDIRECTING_TO_SUBADDRESS, 08902 .subaddress.type = AST_REDIRECTING_TO_SUBADDRESS_TYPE, 08903 .subaddress.odd_even_indicator = AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN, 08904 .subaddress.valid = AST_REDIRECTING_TO_SUBADDRESS_VALID, 08905 08906 .tag = AST_REDIRECTING_TO_TAG, 08907 .combined_presentation = AST_REDIRECTING_TO_ID_PRESENTATION, 08908 }; 08909 08910 /* Redirecting frame version */ 08911 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08912 ast_log(LOG_WARNING, "No space left for redirecting frame version\n"); 08913 return -1; 08914 } 08915 data[pos++] = AST_REDIRECTING_VERSION; 08916 data[pos++] = 1; 08917 data[pos++] = 2;/* Version 1 did not have a version ie */ 08918 08919 res = party_id_build_data(data + pos, datalen - pos, &redirecting->from, 08920 "redirecting-from", &from_ies, update ? &update->from : NULL); 08921 if (res < 0) { 08922 return -1; 08923 } 08924 pos += res; 08925 08926 res = party_id_build_data(data + pos, datalen - pos, &redirecting->to, 08927 "redirecting-to", &to_ies, update ? &update->to : NULL); 08928 if (res < 0) { 08929 return -1; 08930 } 08931 pos += res; 08932 08933 /* Redirecting reason */ 08934 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) { 08935 ast_log(LOG_WARNING, "No space left for redirecting reason\n"); 08936 return -1; 08937 } 08938 data[pos++] = AST_REDIRECTING_REASON; 08939 data[pos++] = sizeof(value); 08940 value = htonl(redirecting->reason); 08941 memcpy(data + pos, &value, sizeof(value)); 08942 pos += sizeof(value); 08943 08944 /* Redirecting count */ 08945 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) { 08946 ast_log(LOG_WARNING, "No space left for redirecting count\n"); 08947 return -1; 08948 } 08949 data[pos++] = AST_REDIRECTING_COUNT; 08950 data[pos++] = sizeof(value); 08951 value = htonl(redirecting->count); 08952 memcpy(data + pos, &value, sizeof(value)); 08953 pos += sizeof(value); 08954 08955 return pos; 08956 }
int ast_redirecting_parse_data | ( | const unsigned char * | data, | |
size_t | datalen, | |||
struct ast_party_redirecting * | redirecting | |||
) |
Parse redirecting indication frame data.
data | Buffer with the frame data to parse | |
datalen | Size of the buffer | |
redirecting | Extracted redirecting id information |
0 | on success. | |
-1 | on error. |
The filled in id structure needs to be destroyed by ast_party_redirecting_free() when it is no longer needed.
Definition at line 8958 of file channel.c.
References ast_free, ast_log(), ast_malloc, AST_PARTY_CHAR_SET_ISO8859_1, AST_REDIRECTING_COUNT, AST_REDIRECTING_FROM_ID_PRESENTATION, AST_REDIRECTING_FROM_NAME, AST_REDIRECTING_FROM_NAME_CHAR_SET, AST_REDIRECTING_FROM_NAME_PRESENTATION, AST_REDIRECTING_FROM_NAME_VALID, AST_REDIRECTING_FROM_NUMBER, AST_REDIRECTING_FROM_NUMBER_PLAN, AST_REDIRECTING_FROM_NUMBER_PRESENTATION, AST_REDIRECTING_FROM_NUMBER_VALID, AST_REDIRECTING_FROM_SUBADDRESS, AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_FROM_SUBADDRESS_TYPE, AST_REDIRECTING_FROM_SUBADDRESS_VALID, AST_REDIRECTING_FROM_TAG, AST_REDIRECTING_TO_ID_PRESENTATION, AST_REDIRECTING_TO_NAME, AST_REDIRECTING_TO_NAME_CHAR_SET, AST_REDIRECTING_TO_NAME_PRESENTATION, AST_REDIRECTING_TO_NAME_VALID, AST_REDIRECTING_TO_NUMBER, AST_REDIRECTING_TO_NUMBER_PLAN, AST_REDIRECTING_TO_NUMBER_PRESENTATION, AST_REDIRECTING_TO_NUMBER_VALID, AST_REDIRECTING_TO_SUBADDRESS, AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_TO_SUBADDRESS_TYPE, AST_REDIRECTING_TO_SUBADDRESS_VALID, AST_REDIRECTING_TO_TAG, AST_REDIRECTING_VERSION, ast_party_name::char_set, ast_party_redirecting::count, ast_party_redirecting::from, LOG_DEBUG, LOG_WARNING, ast_party_id::name, ast_party_id::number, ast_party_subaddress::odd_even_indicator, ast_party_number::plan, ast_party_name::presentation, ast_party_number::presentation, ast_party_redirecting::reason, ast_party_name::str, ast_party_number::str, ast_party_subaddress::str, ast_party_id::subaddress, ast_party_id::tag, ast_party_redirecting::to, ast_party_subaddress::type, ast_party_name::valid, ast_party_number::valid, ast_party_subaddress::valid, and value.
Referenced by ast_channel_redirecting_macro(), and ast_indicate_data().
08959 { 08960 size_t pos; 08961 unsigned char ie_len; 08962 unsigned char ie_id; 08963 int32_t value; 08964 int frame_version = 1; 08965 int from_combined_presentation = 0; 08966 int got_from_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */ 08967 int to_combined_presentation = 0; 08968 int got_to_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */ 08969 08970 for (pos = 0; pos < datalen; pos += ie_len) { 08971 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) { 08972 ast_log(LOG_WARNING, "Invalid redirecting update\n"); 08973 return -1; 08974 } 08975 ie_id = data[pos++]; 08976 ie_len = data[pos++]; 08977 if (datalen < pos + ie_len) { 08978 ast_log(LOG_WARNING, "Invalid redirecting update\n"); 08979 return -1; 08980 } 08981 08982 switch (ie_id) { 08983 /* Redirecting frame version */ 08984 case AST_REDIRECTING_VERSION: 08985 if (ie_len != 1) { 08986 ast_log(LOG_WARNING, "Invalid redirecting frame version (%u)\n", 08987 (unsigned) ie_len); 08988 break; 08989 } 08990 frame_version = data[pos]; 08991 break; 08992 /* Redirecting-from party id name */ 08993 case AST_REDIRECTING_FROM_NAME: 08994 ast_free(redirecting->from.name.str); 08995 redirecting->from.name.str = ast_malloc(ie_len + 1); 08996 if (redirecting->from.name.str) { 08997 memcpy(redirecting->from.name.str, data + pos, ie_len); 08998 redirecting->from.name.str[ie_len] = 0; 08999 } 09000 break; 09001 case AST_REDIRECTING_FROM_NAME_CHAR_SET: 09002 if (ie_len != 1) { 09003 ast_log(LOG_WARNING, "Invalid redirecting-from name char set (%u)\n", 09004 (unsigned) ie_len); 09005 break; 09006 } 09007 redirecting->from.name.char_set = data[pos]; 09008 break; 09009 case AST_REDIRECTING_FROM_NAME_PRESENTATION: 09010 if (ie_len != 1) { 09011 ast_log(LOG_WARNING, "Invalid redirecting-from name presentation (%u)\n", 09012 (unsigned) ie_len); 09013 break; 09014 } 09015 redirecting->from.name.presentation = data[pos]; 09016 break; 09017 case AST_REDIRECTING_FROM_NAME_VALID: 09018 if (ie_len != 1) { 09019 ast_log(LOG_WARNING, "Invalid redirecting-from name valid (%u)\n", 09020 (unsigned) ie_len); 09021 break; 09022 } 09023 redirecting->from.name.valid = data[pos]; 09024 break; 09025 /* Redirecting-from party id number */ 09026 case AST_REDIRECTING_FROM_NUMBER: 09027 ast_free(redirecting->from.number.str); 09028 redirecting->from.number.str = ast_malloc(ie_len + 1); 09029 if (redirecting->from.number.str) { 09030 memcpy(redirecting->from.number.str, data + pos, ie_len); 09031 redirecting->from.number.str[ie_len] = 0; 09032 } 09033 break; 09034 case AST_REDIRECTING_FROM_NUMBER_PLAN: 09035 if (ie_len != 1) { 09036 ast_log(LOG_WARNING, "Invalid redirecting-from numbering plan (%u)\n", 09037 (unsigned) ie_len); 09038 break; 09039 } 09040 redirecting->from.number.plan = data[pos]; 09041 break; 09042 case AST_REDIRECTING_FROM_NUMBER_PRESENTATION: 09043 if (ie_len != 1) { 09044 ast_log(LOG_WARNING, "Invalid redirecting-from number presentation (%u)\n", 09045 (unsigned) ie_len); 09046 break; 09047 } 09048 redirecting->from.number.presentation = data[pos]; 09049 break; 09050 case AST_REDIRECTING_FROM_NUMBER_VALID: 09051 if (ie_len != 1) { 09052 ast_log(LOG_WARNING, "Invalid redirecting-from number valid (%u)\n", 09053 (unsigned) ie_len); 09054 break; 09055 } 09056 redirecting->from.number.valid = data[pos]; 09057 break; 09058 /* Redirecting-from party id combined presentation */ 09059 case AST_REDIRECTING_FROM_ID_PRESENTATION: 09060 if (ie_len != 1) { 09061 ast_log(LOG_WARNING, "Invalid redirecting-from combined presentation (%u)\n", 09062 (unsigned) ie_len); 09063 break; 09064 } 09065 from_combined_presentation = data[pos]; 09066 got_from_combined_presentation = 1; 09067 break; 09068 /* Redirecting-from party id subaddress */ 09069 case AST_REDIRECTING_FROM_SUBADDRESS: 09070 ast_free(redirecting->from.subaddress.str); 09071 redirecting->from.subaddress.str = ast_malloc(ie_len + 1); 09072 if (redirecting->from.subaddress.str) { 09073 memcpy(redirecting->from.subaddress.str, data + pos, ie_len); 09074 redirecting->from.subaddress.str[ie_len] = 0; 09075 } 09076 break; 09077 case AST_REDIRECTING_FROM_SUBADDRESS_TYPE: 09078 if (ie_len != 1) { 09079 ast_log(LOG_WARNING, "Invalid redirecting-from type of subaddress (%u)\n", 09080 (unsigned) ie_len); 09081 break; 09082 } 09083 redirecting->from.subaddress.type = data[pos]; 09084 break; 09085 case AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN: 09086 if (ie_len != 1) { 09087 ast_log(LOG_WARNING, 09088 "Invalid redirecting-from subaddress odd-even indicator (%u)\n", 09089 (unsigned) ie_len); 09090 break; 09091 } 09092 redirecting->from.subaddress.odd_even_indicator = data[pos]; 09093 break; 09094 case AST_REDIRECTING_FROM_SUBADDRESS_VALID: 09095 if (ie_len != 1) { 09096 ast_log(LOG_WARNING, "Invalid redirecting-from subaddress valid (%u)\n", 09097 (unsigned) ie_len); 09098 break; 09099 } 09100 redirecting->from.subaddress.valid = data[pos]; 09101 break; 09102 /* Redirecting-from party id tag */ 09103 case AST_REDIRECTING_FROM_TAG: 09104 ast_free(redirecting->from.tag); 09105 redirecting->from.tag = ast_malloc(ie_len + 1); 09106 if (redirecting->from.tag) { 09107 memcpy(redirecting->from.tag, data + pos, ie_len); 09108 redirecting->from.tag[ie_len] = 0; 09109 } 09110 break; 09111 /* Redirecting-to party id name */ 09112 case AST_REDIRECTING_TO_NAME: 09113 ast_free(redirecting->to.name.str); 09114 redirecting->to.name.str = ast_malloc(ie_len + 1); 09115 if (redirecting->to.name.str) { 09116 memcpy(redirecting->to.name.str, data + pos, ie_len); 09117 redirecting->to.name.str[ie_len] = 0; 09118 } 09119 break; 09120 case AST_REDIRECTING_TO_NAME_CHAR_SET: 09121 if (ie_len != 1) { 09122 ast_log(LOG_WARNING, "Invalid redirecting-to name char set (%u)\n", 09123 (unsigned) ie_len); 09124 break; 09125 } 09126 redirecting->to.name.char_set = data[pos]; 09127 break; 09128 case AST_REDIRECTING_TO_NAME_PRESENTATION: 09129 if (ie_len != 1) { 09130 ast_log(LOG_WARNING, "Invalid redirecting-to name presentation (%u)\n", 09131 (unsigned) ie_len); 09132 break; 09133 } 09134 redirecting->to.name.presentation = data[pos]; 09135 break; 09136 case AST_REDIRECTING_TO_NAME_VALID: 09137 if (ie_len != 1) { 09138 ast_log(LOG_WARNING, "Invalid redirecting-to name valid (%u)\n", 09139 (unsigned) ie_len); 09140 break; 09141 } 09142 redirecting->to.name.valid = data[pos]; 09143 break; 09144 /* Redirecting-to party id number */ 09145 case AST_REDIRECTING_TO_NUMBER: 09146 ast_free(redirecting->to.number.str); 09147 redirecting->to.number.str = ast_malloc(ie_len + 1); 09148 if (redirecting->to.number.str) { 09149 memcpy(redirecting->to.number.str, data + pos, ie_len); 09150 redirecting->to.number.str[ie_len] = 0; 09151 } 09152 break; 09153 case AST_REDIRECTING_TO_NUMBER_PLAN: 09154 if (ie_len != 1) { 09155 ast_log(LOG_WARNING, "Invalid redirecting-to numbering plan (%u)\n", 09156 (unsigned) ie_len); 09157 break; 09158 } 09159 redirecting->to.number.plan = data[pos]; 09160 break; 09161 case AST_REDIRECTING_TO_NUMBER_PRESENTATION: 09162 if (ie_len != 1) { 09163 ast_log(LOG_WARNING, "Invalid redirecting-to number presentation (%u)\n", 09164 (unsigned) ie_len); 09165 break; 09166 } 09167 redirecting->to.number.presentation = data[pos]; 09168 break; 09169 case AST_REDIRECTING_TO_NUMBER_VALID: 09170 if (ie_len != 1) { 09171 ast_log(LOG_WARNING, "Invalid redirecting-to number valid (%u)\n", 09172 (unsigned) ie_len); 09173 break; 09174 } 09175 redirecting->to.number.valid = data[pos]; 09176 break; 09177 /* Redirecting-to party id combined presentation */ 09178 case AST_REDIRECTING_TO_ID_PRESENTATION: 09179 if (ie_len != 1) { 09180 ast_log(LOG_WARNING, "Invalid redirecting-to combined presentation (%u)\n", 09181 (unsigned) ie_len); 09182 break; 09183 } 09184 to_combined_presentation = data[pos]; 09185 got_to_combined_presentation = 1; 09186 break; 09187 /* Redirecting-to party id subaddress */ 09188 case AST_REDIRECTING_TO_SUBADDRESS: 09189 ast_free(redirecting->to.subaddress.str); 09190 redirecting->to.subaddress.str = ast_malloc(ie_len + 1); 09191 if (redirecting->to.subaddress.str) { 09192 memcpy(redirecting->to.subaddress.str, data + pos, ie_len); 09193 redirecting->to.subaddress.str[ie_len] = 0; 09194 } 09195 break; 09196 case AST_REDIRECTING_TO_SUBADDRESS_TYPE: 09197 if (ie_len != 1) { 09198 ast_log(LOG_WARNING, "Invalid redirecting-to type of subaddress (%u)\n", 09199 (unsigned) ie_len); 09200 break; 09201 } 09202 redirecting->to.subaddress.type = data[pos]; 09203 break; 09204 case AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN: 09205 if (ie_len != 1) { 09206 ast_log(LOG_WARNING, 09207 "Invalid redirecting-to subaddress odd-even indicator (%u)\n", 09208 (unsigned) ie_len); 09209 break; 09210 } 09211 redirecting->to.subaddress.odd_even_indicator = data[pos]; 09212 break; 09213 case AST_REDIRECTING_TO_SUBADDRESS_VALID: 09214 if (ie_len != 1) { 09215 ast_log(LOG_WARNING, "Invalid redirecting-to subaddress valid (%u)\n", 09216 (unsigned) ie_len); 09217 break; 09218 } 09219 redirecting->to.subaddress.valid = data[pos]; 09220 break; 09221 /* Redirecting-to party id tag */ 09222 case AST_REDIRECTING_TO_TAG: 09223 ast_free(redirecting->to.tag); 09224 redirecting->to.tag = ast_malloc(ie_len + 1); 09225 if (redirecting->to.tag) { 09226 memcpy(redirecting->to.tag, data + pos, ie_len); 09227 redirecting->to.tag[ie_len] = 0; 09228 } 09229 break; 09230 /* Redirecting reason */ 09231 case AST_REDIRECTING_REASON: 09232 if (ie_len != sizeof(value)) { 09233 ast_log(LOG_WARNING, "Invalid redirecting reason (%u)\n", 09234 (unsigned) ie_len); 09235 break; 09236 } 09237 memcpy(&value, data + pos, sizeof(value)); 09238 redirecting->reason = ntohl(value); 09239 break; 09240 /* Redirecting count */ 09241 case AST_REDIRECTING_COUNT: 09242 if (ie_len != sizeof(value)) { 09243 ast_log(LOG_WARNING, "Invalid redirecting count (%u)\n", 09244 (unsigned) ie_len); 09245 break; 09246 } 09247 memcpy(&value, data + pos, sizeof(value)); 09248 redirecting->count = ntohl(value); 09249 break; 09250 /* Redirecting unknown element */ 09251 default: 09252 ast_log(LOG_DEBUG, "Unknown redirecting element: %u (%u)\n", 09253 (unsigned) ie_id, (unsigned) ie_len); 09254 break; 09255 } 09256 } 09257 09258 switch (frame_version) { 09259 case 1: 09260 /* 09261 * The other end is an earlier version that we need to adjust 09262 * for compatibility. 09263 */ 09264 redirecting->from.name.valid = 1; 09265 redirecting->from.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1; 09266 redirecting->from.number.valid = 1; 09267 if (got_from_combined_presentation) { 09268 redirecting->from.name.presentation = from_combined_presentation; 09269 redirecting->from.number.presentation = from_combined_presentation; 09270 } 09271 09272 redirecting->to.name.valid = 1; 09273 redirecting->to.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1; 09274 redirecting->to.number.valid = 1; 09275 if (got_to_combined_presentation) { 09276 redirecting->to.name.presentation = to_combined_presentation; 09277 redirecting->to.number.presentation = to_combined_presentation; 09278 } 09279 break; 09280 case 2: 09281 /* The other end is at the same level as we are. */ 09282 break; 09283 default: 09284 /* 09285 * The other end is newer than we are. 09286 * We need to assume that they are compatible with us. 09287 */ 09288 ast_log(LOG_DEBUG, "Redirecting frame has newer version: %u\n", 09289 (unsigned) frame_version); 09290 break; 09291 } 09292 09293 return 0; 09294 }
struct ast_channel* ast_request | ( | const char * | type, | |
format_t | format, | |||
const struct ast_channel * | requestor, | |||
void * | data, | |||
int * | status | |||
) |
Requests a channel.
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 |
NULL | failure | |
non-NULL | channel on success |
Definition at line 5544 of file channel.c.
References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_NOSUCHDRIVER, AST_CAUSE_NOTDEFINED, ast_channel_release(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_translator_best_choice(), capabilities, ast_channel_tech::capabilities, chanlist::chan, chanlist::list, LOG_WARNING, ast_channel_tech::requester, set_security_requirements(), ast_channel::tech, and ast_channel_tech::type.
Referenced by __ast_request_and_dial(), ast_call_forward(), attempt_reconnect(), begin_dial_channel(), build_conf(), chanavail_exec(), conf_run(), connect_link(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), play_sound_file(), ring_entry(), rpt(), rpt_call(), rpt_exec(), and rpt_tele_thread().
05545 { 05546 struct chanlist *chan; 05547 struct ast_channel *c; 05548 format_t capabilities; 05549 format_t fmt; 05550 int res; 05551 int foo; 05552 format_t videoformat = format & AST_FORMAT_VIDEO_MASK; 05553 format_t textformat = format & AST_FORMAT_TEXT_MASK; 05554 05555 if (!cause) 05556 cause = &foo; 05557 *cause = AST_CAUSE_NOTDEFINED; 05558 05559 if (AST_RWLIST_RDLOCK(&backends)) { 05560 ast_log(LOG_WARNING, "Unable to lock technology backend list\n"); 05561 return NULL; 05562 } 05563 05564 AST_RWLIST_TRAVERSE(&backends, chan, list) { 05565 if (strcasecmp(type, chan->tech->type)) 05566 continue; 05567 05568 capabilities = chan->tech->capabilities; 05569 fmt = format & AST_FORMAT_AUDIO_MASK; 05570 if (fmt) { 05571 /* We have audio - is it possible to connect the various calls to each other? 05572 (Avoid this check for calls without audio, like text+video calls) 05573 */ 05574 res = ast_translator_best_choice(&fmt, &capabilities); 05575 if (res < 0) { 05576 char tmp1[256], tmp2[256]; 05577 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %s) to %s\n", type, 05578 ast_getformatname_multiple(tmp1, sizeof(tmp1), chan->tech->capabilities), 05579 ast_getformatname_multiple(tmp2, sizeof(tmp2), format)); 05580 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05581 AST_RWLIST_UNLOCK(&backends); 05582 return NULL; 05583 } 05584 } 05585 AST_RWLIST_UNLOCK(&backends); 05586 if (!chan->tech->requester) 05587 return NULL; 05588 05589 if (!(c = chan->tech->requester(type, capabilities | videoformat | textformat, requestor, data, cause))) 05590 return NULL; 05591 05592 if (set_security_requirements(requestor, c)) { 05593 ast_log(LOG_WARNING, "Setting security requirements failed\n"); 05594 c = ast_channel_release(c); 05595 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05596 return NULL; 05597 } 05598 05599 /* no need to generate a Newchannel event here; it is done in the channel_alloc call */ 05600 return c; 05601 } 05602 05603 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type); 05604 *cause = AST_CAUSE_NOSUCHDRIVER; 05605 AST_RWLIST_UNLOCK(&backends); 05606 05607 return NULL; 05608 }
struct ast_channel* ast_request_and_dial | ( | const char * | type, | |
format_t | format, | |||
const struct ast_channel * | requestor, | |||
void * | data, | |||
int | timeout, | |||
int * | reason, | |||
const char * | cid_num, | |||
const char * | cid_name | |||
) |
Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it.
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) |
Definition at line 5499 of file channel.c.
References __ast_request_and_dial().
Referenced by ast_pbx_outgoing_exten(), and generic_recall().
05500 { 05501 return __ast_request_and_dial(type, format, requestor, data, timeout, outstate, cidnum, cidname, NULL); 05502 }
int ast_safe_sleep | ( | struct ast_channel * | chan, | |
int | ms | |||
) |
Wait for a specified amount of time, looking for hangups.
chan | channel to wait for | |
ms | length of time in milliseconds to sleep |
Definition at line 1873 of file channel.c.
References ast_safe_sleep_conditional(), and chanlist::chan.
Referenced by __analog_ss_thread(), alarmreceiver_exec(), analog_ss_thread(), ast_adsi_transmit_message_full(), ast_dtmf_stream(), ast_senddigit(), builtin_atxfer(), builtin_parkcall(), conf_run(), dictate_exec(), flash_exec(), function_ilink(), handle_callforward_button(), login_exec(), mgcp_ss(), milliwatt_exec(), misdn_check_l2l1(), old_milliwatt_exec(), park_call_exec(), pbx_builtin_wait(), play_moh_exec(), play_tone_pair(), playtone(), privacy_exec(), receive_ademco_contact_id(), rpt_call(), rpt_exec(), rpt_tele_thread(), send_morse(), send_tone_telemetry(), skinny_ss(), testclient_exec(), testserver_exec(), wait_for_hangup(), wait_interval(), wait_moh_exec(), waituntil_exec(), and zapateller_exec().
01874 { 01875 return ast_safe_sleep_conditional(chan, ms, NULL, NULL); 01876 }
int ast_safe_sleep_conditional | ( | struct ast_channel * | chan, | |
int | ms, | |||
int(*)(void *) | cond, | |||
void * | data | |||
) |
Wait for a specified amount of time, looking for hangups and a condition argument.
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 |
Definition at line 1806 of file channel.c.
References ast_channel_lock, ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_channel_unlock, ast_frfree, ast_frisolate(), ast_is_deferrable_frame(), AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_HEAD_NOLOCK, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_HEAD, ast_opt_transmit_silence, ast_queue_frame_head(), ast_read(), ast_waitfor(), chanlist::chan, f, and ast_channel::generatordata.
Referenced by ast_safe_sleep(), and login_exec().
01807 { 01808 struct ast_frame *f; 01809 struct ast_silence_generator *silgen = NULL; 01810 int res = 0; 01811 AST_LIST_HEAD_NOLOCK(, ast_frame) deferred_frames; 01812 01813 AST_LIST_HEAD_INIT_NOLOCK(&deferred_frames); 01814 01815 /* If no other generator is present, start silencegen while waiting */ 01816 if (ast_opt_transmit_silence && !chan->generatordata) { 01817 silgen = ast_channel_start_silence_generator(chan); 01818 } 01819 01820 while (ms > 0) { 01821 struct ast_frame *dup_f = NULL; 01822 if (cond && ((*cond)(data) == 0)) { 01823 break; 01824 } 01825 ms = ast_waitfor(chan, ms); 01826 if (ms < 0) { 01827 res = -1; 01828 break; 01829 } 01830 if (ms > 0) { 01831 f = ast_read(chan); 01832 if (!f) { 01833 res = -1; 01834 break; 01835 } 01836 01837 if (!ast_is_deferrable_frame(f)) { 01838 ast_frfree(f); 01839 continue; 01840 } 01841 01842 if ((dup_f = ast_frisolate(f))) { 01843 if (dup_f != f) { 01844 ast_frfree(f); 01845 } 01846 AST_LIST_INSERT_HEAD(&deferred_frames, dup_f, frame_list); 01847 } 01848 } 01849 } 01850 01851 /* stop silgen if present */ 01852 if (silgen) { 01853 ast_channel_stop_silence_generator(chan, silgen); 01854 } 01855 01856 /* We need to free all the deferred frames, but we only need to 01857 * queue the deferred frames if there was no error and no 01858 * hangup was received 01859 */ 01860 ast_channel_lock(chan); 01861 while ((f = AST_LIST_REMOVE_HEAD(&deferred_frames, frame_list))) { 01862 if (!res) { 01863 ast_queue_frame_head(chan, f); 01864 } 01865 ast_frfree(f); 01866 } 01867 ast_channel_unlock(chan); 01868 01869 return res; 01870 }
int ast_senddigit | ( | struct ast_channel * | chan, | |
char | digit, | |||
unsigned int | duration | |||
) |
Send a DTMF digit to a channel.
chan | channel to act upon | |
digit | the DTMF digit to send, encoded in ASCII | |
duration | the duration of the digit ending in ms |
Definition at line 4625 of file channel.c.
References AST_DEFAULT_EMULATE_DTMF_DURATION, ast_safe_sleep(), ast_senddigit_begin(), ast_senddigit_end(), chanlist::chan, ast_channel_tech::send_digit_begin, and ast_channel::tech.
Referenced by ast_dtmf_stream(), dial_exec_full(), do_dtmf_phone(), manager_play_dtmf(), and rpt_call().
04626 { 04627 if (chan->tech->send_digit_begin) { 04628 ast_senddigit_begin(chan, digit); 04629 ast_safe_sleep(chan, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION)); 04630 } 04631 04632 return ast_senddigit_end(chan, digit, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION)); 04633 }
int ast_senddigit_begin | ( | struct ast_channel * | chan, | |
char | digit | |||
) |
Send a DTMF digit to a channel.
chan | channel to act upon | |
digit | the DTMF digit to send, encoded in ASCII |
Definition at line 4567 of file channel.c.
References ast_debug, ast_playtones_start(), chanlist::chan, ast_channel::name, ast_channel_tech::send_digit_begin, and ast_channel::tech.
Referenced by agent_digit_begin(), ast_senddigit(), and ast_write().
04568 { 04569 /* Device does not support DTMF tones, lets fake 04570 * it by doing our own generation. */ 04571 static const char * const dtmf_tones[] = { 04572 "941+1336", /* 0 */ 04573 "697+1209", /* 1 */ 04574 "697+1336", /* 2 */ 04575 "697+1477", /* 3 */ 04576 "770+1209", /* 4 */ 04577 "770+1336", /* 5 */ 04578 "770+1477", /* 6 */ 04579 "852+1209", /* 7 */ 04580 "852+1336", /* 8 */ 04581 "852+1477", /* 9 */ 04582 "697+1633", /* A */ 04583 "770+1633", /* B */ 04584 "852+1633", /* C */ 04585 "941+1633", /* D */ 04586 "941+1209", /* * */ 04587 "941+1477" /* # */ 04588 }; 04589 04590 if (!chan->tech->send_digit_begin) 04591 return 0; 04592 04593 if (!chan->tech->send_digit_begin(chan, digit)) 04594 return 0; 04595 04596 if (digit >= '0' && digit <='9') 04597 ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0); 04598 else if (digit >= 'A' && digit <= 'D') 04599 ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0); 04600 else if (digit == '*') 04601 ast_playtones_start(chan, 0, dtmf_tones[14], 0); 04602 else if (digit == '#') 04603 ast_playtones_start(chan, 0, dtmf_tones[15], 0); 04604 else { 04605 /* not handled */ 04606 ast_debug(1, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name); 04607 } 04608 04609 return 0; 04610 }
int ast_senddigit_end | ( | struct ast_channel * | chan, | |
char | digit, | |||
unsigned int | duration | |||
) |
Send a DTMF digit to a channel.
chan | channel to act upon | |
digit | the DTMF digit to send, encoded in ASCII | |
duration | the duration of the digit ending in ms |
Definition at line 4612 of file channel.c.
References ast_playtones_stop(), chanlist::chan, ast_channel::generator, ast_channel_tech::send_digit_end, and ast_channel::tech.
Referenced by agent_digit_end(), ast_senddigit(), and ast_write().
04613 { 04614 int res = -1; 04615 04616 if (chan->tech->send_digit_end) 04617 res = chan->tech->send_digit_end(chan, digit, duration); 04618 04619 if (res && chan->generator) 04620 ast_playtones_stop(chan); 04621 04622 return 0; 04623 }
int ast_sendtext | ( | struct ast_channel * | chan, | |
const char * | text | |||
) |
Sends text to a channel.
chan | channel to act upon | |
text | string of text to send on the channel |
0 | on success | |
-1 | on failure |
Definition at line 4549 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_test_flag, chanlist::chan, CHECK_BLOCKING, ast_channel_tech::send_text, and ast_channel::tech.
Referenced by action_sendtext(), agent_sendtext(), handle_sendtext(), send_newkey(), and sendtext_exec().
04550 { 04551 int res = 0; 04552 04553 ast_channel_lock(chan); 04554 /* Stop if we're a zombie or need a soft hangup */ 04555 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 04556 ast_channel_unlock(chan); 04557 return -1; 04558 } 04559 CHECK_BLOCKING(chan); 04560 if (chan->tech->send_text) 04561 res = chan->tech->send_text(chan, text); 04562 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04563 ast_channel_unlock(chan); 04564 return res; 04565 }
void ast_set_callerid | ( | struct ast_channel * | chan, | |
const char * | cid_num, | |||
const char * | cid_name, | |||
const char * | cid_ani | |||
) |
Set caller ID number, name and ANI and generate AMI event.
The channel does not need to be locked before calling this function.
Definition at line 6811 of file channel.c.
References ast_party_caller::ani, ast_cdr_setcid(), ast_channel_lock, ast_channel_unlock, ast_free, ast_strdup, ast_channel::caller, ast_channel::cdr, chanlist::chan, ast_party_caller::id, ast_party_id::name, ast_party_id::number, report_new_callerid(), ast_party_number::str, ast_party_name::str, ast_party_number::valid, and ast_party_name::valid.
Referenced by __analog_ss_thread(), __ast_request_and_dial(), analog_ss_thread(), cb_events(), get_pai(), get_rpid(), handle_setcallerid(), mgcp_ss(), ring_entry(), rpt_exec(), skinny_newcall(), and socket_process().
06812 { 06813 ast_channel_lock(chan); 06814 06815 if (cid_num) { 06816 chan->caller.id.number.valid = 1; 06817 ast_free(chan->caller.id.number.str); 06818 chan->caller.id.number.str = ast_strdup(cid_num); 06819 } 06820 if (cid_name) { 06821 chan->caller.id.name.valid = 1; 06822 ast_free(chan->caller.id.name.str); 06823 chan->caller.id.name.str = ast_strdup(cid_name); 06824 } 06825 if (cid_ani) { 06826 chan->caller.ani.number.valid = 1; 06827 ast_free(chan->caller.ani.number.str); 06828 chan->caller.ani.number.str = ast_strdup(cid_ani); 06829 } 06830 if (chan->cdr) { 06831 ast_cdr_setcid(chan->cdr, chan); 06832 } 06833 06834 report_new_callerid(chan); 06835 06836 ast_channel_unlock(chan); 06837 }
void ast_set_hangupsource | ( | struct ast_channel * | chan, | |
const char * | source, | |||
int | force | |||
) |
Set the source of the hangup in this channel and it's bridge.
chan | channel to set the field on | |
source | a string describing the source of the hangup for this channel | |
force |
Definition at line 2714 of file channel.c.
References ast_bridged_channel(), ast_channel_lock, ast_channel_unlock, ast_string_field_set, ast_strlen_zero(), ast_channel::bridge, chanlist::chan, and ast_channel::hangupsource.
Referenced by __dahdi_exception(), func_channel_write_real(), handle_hangup(), handle_request_bye(), handle_request_cancel(), handle_response_invite(), pbx_builtin_hangup(), and set_hangup_source_and_cause().
02715 { 02716 struct ast_channel *bridge; 02717 02718 ast_channel_lock(chan); 02719 if (force || ast_strlen_zero(chan->hangupsource)) { 02720 ast_string_field_set(chan, hangupsource, source); 02721 } 02722 bridge = ast_bridged_channel(chan); 02723 ast_channel_unlock(chan); 02724 02725 if (bridge && (force || ast_strlen_zero(bridge->hangupsource))) { 02726 ast_channel_lock(bridge); 02727 ast_string_field_set(chan, hangupsource, source); 02728 ast_channel_unlock(bridge); 02729 } 02730 }
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.
chan | channel to change | |
format | format to change to |
Definition at line 5151 of file channel.c.
References chanlist::chan, ast_channel::rawreadformat, ast_channel::readformat, ast_channel::readtrans, and set_format().
Referenced by __ast_play_and_record(), __oh323_update_info(), agent_call(), alarmreceiver_exec(), ast_adsi_transmit_message_full(), ast_channel_make_compatible_helper(), ast_do_masquerade(), attempt_reconnect(), background_detect_exec(), bridge_channel_join(), bridge_make_compatible(), build_conf(), conf_run(), connect_link(), dictate_exec(), do_waiting(), eagi_exec(), echo_exec(), generic_fax_exec(), gtalk_rtp_read(), handle_recordfile(), handle_speechrecognize(), ices_exec(), isAnsweringMachine(), jack_exec(), jingle_rtp_read(), login_exec(), measurenoise(), mgcp_rtp_read(), oh323_rtp_read(), old_milliwatt_exec(), process_sdp(), rpt(), rpt_exec(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_process(), speech_background(), transmit_audio(), and unistim_rtp_read().
05152 { 05153 return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat, 05154 &chan->readtrans, 0); 05155 }
void ast_set_variables | ( | struct ast_channel * | chan, | |
struct ast_variable * | vars | |||
) |
adds a list of channel variables to a channel
chan | the channel | |
vars | a linked list of variables |
Definition at line 7988 of file channel.c.
References ast_variable::name, ast_variable::next, pbx_builtin_setvar_helper(), and ast_variable::value.
Referenced by __ast_request_and_dial(), ast_call_forward(), ast_pbx_outgoing_app(), and ast_pbx_outgoing_exten().
07989 { 07990 struct ast_variable *cur; 07991 07992 for (cur = vars; cur; cur = cur->next) 07993 pbx_builtin_setvar_helper(chan, cur->name, cur->value); 07994 }
int ast_set_write_format | ( | struct ast_channel * | chan, | |
format_t | format | |||
) |
Sets write format on channel chan Set write format for channel to whichever component of "format" is best.
chan | channel to change | |
format | new format for writing |
Definition at line 5157 of file channel.c.
References chanlist::chan, ast_channel::rawwriteformat, set_format(), ast_channel::writeformat, and ast_channel::writetrans.
Referenced by __oh323_update_info(), agent_call(), alarmreceiver_exec(), ast_adsi_transmit_message_full(), ast_channel_make_compatible_helper(), ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_do_masquerade(), ast_openstream_full(), ast_stopstream(), ast_write(), attempt_reconnect(), bridge_channel_join(), bridge_make_compatible(), build_conf(), chanspy_exec(), conf_run(), connect_link(), dahdiscan_exec(), echo_exec(), extenspy_exec(), generic_fax_exec(), gtalk_rtp_read(), jack_exec(), jingle_rtp_read(), linear_alloc(), linear_release(), login_exec(), mgcp_rtp_read(), moh_alloc(), moh_files_release(), moh_release(), mp3_exec(), NBScat_exec(), oh323_rtp_read(), old_milliwatt_exec(), playtones_alloc(), playtones_release(), process_sdp(), rpt(), rpt_exec(), send_waveform_to_channel(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_process(), tonepair_alloc(), tonepair_release(), transmit_audio(), and unistim_rtp_read().
05158 { 05159 return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat, 05160 &chan->writetrans, 1); 05161 }
int ast_settimeout | ( | struct ast_channel * | c, | |
unsigned int | rate, | |||
int(*)(const void *data) | func, | |||
void * | data | |||
) |
Enable or disable timer ticks for a channel.
c | channel | |
rate | number of timer ticks per second | |
func | callback function | |
data |
Definition at line 3479 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_debug, ast_timer_get_max_rate(), ast_timer_set_rate(), ast_channel::timer, ast_channel::timingdata, ast_channel::timingfd, and ast_channel::timingfunc.
Referenced by ast_activate_generator(), ast_deactivate_generator(), ast_read_generator_actions(), ast_readaudio_callback(), and filestream_close().
03480 { 03481 int res; 03482 unsigned int real_rate = rate, max_rate; 03483 03484 ast_channel_lock(c); 03485 03486 if (c->timingfd == -1) { 03487 ast_channel_unlock(c); 03488 return -1; 03489 } 03490 03491 if (!func) { 03492 rate = 0; 03493 data = NULL; 03494 } 03495 03496 if (rate && rate > (max_rate = ast_timer_get_max_rate(c->timer))) { 03497 real_rate = max_rate; 03498 } 03499 03500 ast_debug(1, "Scheduling timer at (%u requested / %u actual) timer ticks per second\n", rate, real_rate); 03501 03502 res = ast_timer_set_rate(c->timer, real_rate); 03503 03504 c->timingfunc = func; 03505 c->timingdata = data; 03506 03507 ast_channel_unlock(c); 03508 03509 return res; 03510 }
int ast_shutting_down | ( | void | ) |
Returns non-zero if Asterisk is being shut down.
Definition at line 844 of file channel.c.
Referenced by handle_request_options().
00845 { 00846 return shutting_down; 00847 }
int ast_softhangup | ( | struct ast_channel * | chan, | |
int | reason | |||
) |
Softly hangup up a channel.
chan | channel to be soft-hung-up | |
reason | an AST_SOFTHANGUP_* reason code |
Definition at line 2691 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_softhangup_nolock(), and chanlist::chan.
Referenced by __analog_handle_event(), __ast_module_user_hangup_all(), __unload_module(), agent_hangup(), agent_logoff(), agent_read(), ast_bridge_call(), ast_channel_softhangup_cb(), ast_dial_join(), birdbath(), cc_generic_agent_stop_ringing(), conf_free(), connect_link(), dahdi_handle_event(), flush_telem(), function_ilink(), handle_hangup(), handle_link_data(), handle_softhangup(), login_exec(), manager_park(), mgcp_pktcgate_remove(), read_agent_config(), rpt(), rpt_call(), rpt_do_restart(), rpt_exec(), sla_handle_hold_event(), softhangup_exec(), start_spying(), startmon(), and unload_module().
02692 { 02693 int res; 02694 02695 ast_channel_lock(chan); 02696 res = ast_softhangup_nolock(chan, cause); 02697 ast_channel_unlock(chan); 02698 02699 return res; 02700 }
int ast_softhangup_nolock | ( | struct ast_channel * | chan, | |
int | reason | |||
) |
Softly hangup up a channel (no channel lock).
chan | channel to be soft-hung-up | |
reason | an AST_SOFTHANGUP_* reason code |
Definition at line 2678 of file channel.c.
References ast_channel::_softhangup, ast_debug, AST_FLAG_BLOCKING, ast_null_frame, ast_queue_frame(), ast_test_flag, ast_channel::blocker, chanlist::chan, and ast_channel::name.
Referenced by __analog_handle_event(), action_hangup(), ast_async_goto(), ast_softhangup(), attempt_transfer(), check_pendings(), check_rtp_timeout(), dahdi_softhangup_all(), oh323_indicate(), proc_session_timer(), sig_pri_indicate(), sig_pri_send_aoce_termination_request(), sip_indicate(), and skinny_indicate().
02679 { 02680 ast_debug(1, "Soft-Hanging up channel '%s'\n", chan->name); 02681 /* Inform channel driver that we need to be hung up, if it cares */ 02682 chan->_softhangup |= cause; 02683 ast_queue_frame(chan, &ast_null_frame); 02684 /* Interrupt any poll call or such */ 02685 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) 02686 pthread_kill(chan->blocker, SIGURG); 02687 return 0; 02688 }
const char* ast_state2str | ( | enum ast_channel_state | state | ) |
Gives the string form of a given channel state.
Definition at line 986 of file channel.c.
References AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DIALING_OFFHOOK, AST_STATE_DOWN, AST_STATE_OFFHOOK, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_threadstorage_get(), STATE2STR_BUFSIZE, and state2str_threadbuf.
Referenced by __ast_channel_alloc_ap(), action_coreshowchannels(), agent_hangup(), ast_channel_data_add_structure(), ast_do_masquerade(), ast_setstate(), attempt_transfer(), func_channel_read(), handle_chanlist(), handle_showchan(), local_attended_transfer(), mgcp_new(), serialize_showchan(), sip_hangup(), and update_connectedline().
00987 { 00988 char *buf; 00989 00990 switch (state) { 00991 case AST_STATE_DOWN: 00992 return "Down"; 00993 case AST_STATE_RESERVED: 00994 return "Rsrvd"; 00995 case AST_STATE_OFFHOOK: 00996 return "OffHook"; 00997 case AST_STATE_DIALING: 00998 return "Dialing"; 00999 case AST_STATE_RING: 01000 return "Ring"; 01001 case AST_STATE_RINGING: 01002 return "Ringing"; 01003 case AST_STATE_UP: 01004 return "Up"; 01005 case AST_STATE_BUSY: 01006 return "Busy"; 01007 case AST_STATE_DIALING_OFFHOOK: 01008 return "Dialing Offhook"; 01009 case AST_STATE_PRERING: 01010 return "Pre-ring"; 01011 default: 01012 if (!(buf = ast_threadstorage_get(&state2str_threadbuf, STATE2STR_BUFSIZE))) 01013 return "Unknown"; 01014 snprintf(buf, STATE2STR_BUFSIZE, "Unknown (%d)", state); 01015 return buf; 01016 } 01017 }
int ast_str2cause | ( | const char * | name | ) |
Convert the string form of a cause code to a number.
name | string form of the cause |
Definition at line 972 of file channel.c.
References ARRAY_LEN, and causes.
Referenced by pbx_builtin_hangup().
00973 { 00974 int x; 00975 00976 for (x = 0; x < ARRAY_LEN(causes); x++) 00977 if (!strncasecmp(causes[x].name, name, strlen(causes[x].name))) 00978 return causes[x].cause; 00979 00980 return -1; 00981 }
int ast_tonepair | ( | struct ast_channel * | chan, | |
int | freq1, | |||
int | freq2, | |||
int | duration, | |||
int | vol | |||
) |
Play a tone pair for a given amount of time
Definition at line 7708 of file channel.c.
References ast_frfree, ast_read(), ast_tonepair_start(), ast_waitfor(), f, and ast_channel::generatordata.
Referenced by zapateller_exec().
07709 { 07710 int res; 07711 07712 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol))) 07713 return res; 07714 07715 /* Give us some wiggle room */ 07716 while (chan->generatordata && ast_waitfor(chan, 100) >= 0) { 07717 struct ast_frame *f = ast_read(chan); 07718 if (f) 07719 ast_frfree(f); 07720 else 07721 return -1; 07722 } 07723 return 0; 07724 }
int ast_tonepair_start | ( | struct ast_channel * | chan, | |
int | freq1, | |||
int | freq2, | |||
int | duration, | |||
int | vol | |||
) |
Start a tone going
Definition at line 7690 of file channel.c.
References ast_activate_generator(), tonepair_def::duration, tonepair_def::freq1, tonepair_def::freq2, tonepair, and tonepair_def::vol.
Referenced by ast_tonepair(), pbx_builtin_waitexten(), play_dialtone(), play_tone_pair(), rpt_tele_thread(), and sendnoise().
07691 { 07692 struct tonepair_def d = { 0, }; 07693 07694 d.freq1 = freq1; 07695 d.freq2 = freq2; 07696 d.duration = duration; 07697 d.vol = (vol < 1) ? 8192 : vol; /* force invalid to 8192 */ 07698 if (ast_activate_generator(chan, &tonepair, &d)) 07699 return -1; 07700 return 0; 07701 }
void ast_tonepair_stop | ( | struct ast_channel * | chan | ) |
Stop a tone from playing
Definition at line 7703 of file channel.c.
References ast_deactivate_generator().
Referenced by sendnoise().
07704 { 07705 ast_deactivate_generator(chan); 07706 }
int ast_transfer | ( | struct ast_channel * | chan, | |
char * | dest | |||
) |
Transfer a channel (if supported).
Called by:
Definition at line 5637 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_CONTROL_TRANSFER, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, ast_frfree, ast_read(), ast_test_flag, AST_TRANSFER_SUCCESS, ast_waitfor(), chanlist::chan, ast_channel::tech, and ast_channel_tech::transfer.
Referenced by transfer_exec().
05638 { 05639 int res = -1; 05640 05641 /* Stop if we're a zombie or need a soft hangup */ 05642 ast_channel_lock(chan); 05643 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) { 05644 if (chan->tech->transfer) { 05645 res = chan->tech->transfer(chan, dest); 05646 if (!res) 05647 res = 1; 05648 } else 05649 res = 0; 05650 } 05651 ast_channel_unlock(chan); 05652 05653 if (res <= 0) { 05654 return res; 05655 } 05656 05657 for (;;) { 05658 struct ast_frame *fr; 05659 05660 res = ast_waitfor(chan, -1); 05661 05662 if (res < 0 || !(fr = ast_read(chan))) { 05663 res = -1; 05664 break; 05665 } 05666 05667 if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_TRANSFER) { 05668 enum ast_control_transfer *message = fr->data.ptr; 05669 05670 if (*message == AST_TRANSFER_SUCCESS) { 05671 res = 1; 05672 } else { 05673 res = -1; 05674 } 05675 05676 ast_frfree(fr); 05677 break; 05678 } 05679 05680 ast_frfree(fr); 05681 } 05682 05683 return res; 05684 }
char* ast_transfercapability2str | ( | int | transfercapability | ) | const |
Gives the string form of a given transfer capability.
transfercapability | transfer capability to get the name of |
Definition at line 1020 of file channel.c.
References AST_TRANS_CAP_3_1K_AUDIO, AST_TRANS_CAP_DIGITAL, AST_TRANS_CAP_DIGITAL_W_TONES, AST_TRANS_CAP_RESTRICTED_DIGITAL, AST_TRANS_CAP_SPEECH, and AST_TRANS_CAP_VIDEO.
Referenced by ast_channel_data_add_structure(), cb_events(), misdn_call(), oh323_call(), sig_pri_call(), sig_pri_new_ast_channel(), and sig_ss7_new_ast_channel().
01021 { 01022 switch (transfercapability) { 01023 case AST_TRANS_CAP_SPEECH: 01024 return "SPEECH"; 01025 case AST_TRANS_CAP_DIGITAL: 01026 return "DIGITAL"; 01027 case AST_TRANS_CAP_RESTRICTED_DIGITAL: 01028 return "RESTRICTED_DIGITAL"; 01029 case AST_TRANS_CAP_3_1K_AUDIO: 01030 return "3K1AUDIO"; 01031 case AST_TRANS_CAP_DIGITAL_W_TONES: 01032 return "DIGITAL_W_TONES"; 01033 case AST_TRANS_CAP_VIDEO: 01034 return "VIDEO"; 01035 default: 01036 return "UNKNOWN"; 01037 } 01038 }
int ast_waitfor | ( | struct ast_channel * | chan, | |
int | ms | |||
) |
Wait for input on a channel.
chan | channel to wait on | |
ms | length of time to wait on the channel |
< | 0 on failure | |
0 | if nothing ever arrived | |
the | # of ms remaining otherwise |
Definition at line 3463 of file channel.c.
References ast_waitfor_nandfds().
Referenced by __adsi_transmit_messages(), __analog_ss_thread(), __ast_answer(), __ast_play_and_record(), __ast_request_and_dial(), adsi_careful_send(), agent_ack_sleep(), analog_ss_thread(), ast_dtmf_stream(), ast_recvtext(), ast_safe_sleep_conditional(), ast_tonepair(), ast_transfer(), async_wait(), background_detect_exec(), channel_spy(), conf_flush(), dictate_exec(), disa_exec(), disable_t38(), do_idle_thread(), do_waiting(), echo_exec(), handle_recordfile(), handle_speechrecognize(), ices_exec(), isAnsweringMachine(), jack_exec(), launch_asyncagi(), measurenoise(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), receivefax_t38_init(), recordthread(), send_tone_burst(), send_waveform_to_channel(), sendfax_t38_init(), sendurl_exec(), speech_background(), transmit_audio(), transmit_t38(), wait_for_hangup(), waitforring_exec(), and waitstream_core().
03464 { 03465 int oldms = ms; /* -1 if no timeout */ 03466 03467 ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms); 03468 if ((ms < 0) && (oldms < 0)) 03469 ms = 0; 03470 return ms; 03471 }
struct ast_channel* ast_waitfor_n | ( | struct ast_channel ** | chan, | |
int | n, | |||
int * | ms | |||
) |
Waits for input on a group of channels Wait for input on an array of channels for a given # of milliseconds.
chan | an array of pointers to channels | |
n | number of channels that are to be waited upon | |
ms | time "ms" is modified in-place, if applicable |
Definition at line 3458 of file channel.c.
References ast_waitfor_nandfds().
Referenced by ast_udptl_bridge(), autoservice_run(), dahdi_bridge(), dial_exec_full(), feature_request_and_dial(), generic_thread_loop(), misdn_bridge(), monitor_dial(), remote_bridge_loop(), rpt(), wait_for_answer(), and wait_for_winner().
03459 { 03460 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms); 03461 }
int ast_waitfor_n_fd | ( | int * | fds, | |
int | n, | |||
int * | ms, | |||
int * | exception | |||
) |
Waits for input on an fd.
Definition at line 3099 of file channel.c.
References ast_waitfor_nandfds().
Referenced by dundi_lookup_internal(), dundi_precache_internal(), and softmix_bridge_thread().
03100 { 03101 int winner = -1; 03102 ast_waitfor_nandfds(NULL, 0, fds, n, exception, &winner, ms); 03103 return winner; 03104 }
struct ast_channel* ast_waitfor_nandfds | ( | struct ast_channel ** | chan, | |
int | n, | |||
int * | fds, | |||
int | nfds, | |||
int * | exception, | |||
int * | outfd, | |||
int * | ms | |||
) |
Waits for activity on a group of channels.
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 |
Definition at line 3111 of file channel.c.
References ast_channel::_softhangup, ast_add_fd(), ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, ast_log(), AST_MAX_FDS, ast_poll, ast_set_flag, AST_SOFTHANGUP_TIMEOUT, ast_tvcmp(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), chanlist::chan, CHECK_BLOCKING, errno, and LOG_WARNING.
Referenced by ast_waitfor(), ast_waitfor_n(), ast_waitfor_n_fd(), ast_waitfordigit_full(), conf_run(), eivr_comm(), find_cache(), generic_fax_exec(), multiplexed_thread_function(), run_agi(), and waitstream_core().
03114 { 03115 struct timeval start = { 0 , 0 }; 03116 struct pollfd *pfds = NULL; 03117 int res; 03118 long rms; 03119 int x, y, max; 03120 int sz; 03121 struct timeval now = { 0, 0 }; 03122 struct timeval whentohangup = { 0, 0 }, diff; 03123 struct ast_channel *winner = NULL; 03124 struct fdmap { 03125 int chan; 03126 int fdno; 03127 } *fdmap = NULL; 03128 03129 if ((sz = n * AST_MAX_FDS + nfds)) { 03130 pfds = alloca(sizeof(*pfds) * sz); 03131 fdmap = alloca(sizeof(*fdmap) * sz); 03132 } 03133 03134 if (outfd) 03135 *outfd = -99999; 03136 if (exception) 03137 *exception = 0; 03138 03139 /* Perform any pending masquerades */ 03140 for (x = 0; x < n; x++) { 03141 if (c[x]->masq && ast_do_masquerade(c[x])) { 03142 ast_log(LOG_WARNING, "Masquerade failed\n"); 03143 *ms = -1; 03144 return NULL; 03145 } 03146 03147 ast_channel_lock(c[x]); 03148 if (!ast_tvzero(c[x]->whentohangup)) { 03149 if (ast_tvzero(whentohangup)) 03150 now = ast_tvnow(); 03151 diff = ast_tvsub(c[x]->whentohangup, now); 03152 if (diff.tv_sec < 0 || ast_tvzero(diff)) { 03153 /* Should already be hungup */ 03154 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 03155 ast_channel_unlock(c[x]); 03156 return c[x]; 03157 } 03158 if (ast_tvzero(whentohangup) || ast_tvcmp(diff, whentohangup) < 0) 03159 whentohangup = diff; 03160 } 03161 ast_channel_unlock(c[x]); 03162 } 03163 /* Wait full interval */ 03164 rms = *ms; 03165 /* INT_MAX, not LONG_MAX, because it matters on 64-bit */ 03166 if (!ast_tvzero(whentohangup) && whentohangup.tv_sec < INT_MAX / 1000) { 03167 rms = whentohangup.tv_sec * 1000 + whentohangup.tv_usec / 1000; /* timeout in milliseconds */ 03168 if (*ms >= 0 && *ms < rms) { /* original *ms still smaller */ 03169 rms = *ms; 03170 } 03171 } else if (!ast_tvzero(whentohangup) && rms < 0) { 03172 /* Tiny corner case... call would need to last >24 days */ 03173 rms = INT_MAX; 03174 } 03175 /* 03176 * Build the pollfd array, putting the channels' fds first, 03177 * followed by individual fds. Order is important because 03178 * individual fd's must have priority over channel fds. 03179 */ 03180 max = 0; 03181 for (x = 0; x < n; x++) { 03182 for (y = 0; y < AST_MAX_FDS; y++) { 03183 fdmap[max].fdno = y; /* fd y is linked to this pfds */ 03184 fdmap[max].chan = x; /* channel x is linked to this pfds */ 03185 max += ast_add_fd(&pfds[max], c[x]->fds[y]); 03186 } 03187 CHECK_BLOCKING(c[x]); 03188 } 03189 /* Add the individual fds */ 03190 for (x = 0; x < nfds; x++) { 03191 fdmap[max].chan = -1; 03192 max += ast_add_fd(&pfds[max], fds[x]); 03193 } 03194 03195 if (*ms > 0) 03196 start = ast_tvnow(); 03197 03198 if (sizeof(int) == 4) { /* XXX fix timeout > 600000 on linux x86-32 */ 03199 do { 03200 int kbrms = rms; 03201 if (kbrms > 600000) 03202 kbrms = 600000; 03203 res = ast_poll(pfds, max, kbrms); 03204 if (!res) 03205 rms -= kbrms; 03206 } while (!res && (rms > 0)); 03207 } else { 03208 res = ast_poll(pfds, max, rms); 03209 } 03210 for (x = 0; x < n; x++) 03211 ast_clear_flag(c[x], AST_FLAG_BLOCKING); 03212 if (res < 0) { /* Simulate a timeout if we were interrupted */ 03213 if (errno != EINTR) 03214 *ms = -1; 03215 return NULL; 03216 } 03217 if (!ast_tvzero(whentohangup)) { /* if we have a timeout, check who expired */ 03218 now = ast_tvnow(); 03219 for (x = 0; x < n; x++) { 03220 if (!ast_tvzero(c[x]->whentohangup) && ast_tvcmp(c[x]->whentohangup, now) <= 0) { 03221 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 03222 if (winner == NULL) 03223 winner = c[x]; 03224 } 03225 } 03226 } 03227 if (res == 0) { /* no fd ready, reset timeout and done */ 03228 *ms = 0; /* XXX use 0 since we may not have an exact timeout. */ 03229 return winner; 03230 } 03231 /* 03232 * Then check if any channel or fd has a pending event. 03233 * Remember to check channels first and fds last, as they 03234 * must have priority on setting 'winner' 03235 */ 03236 for (x = 0; x < max; x++) { 03237 res = pfds[x].revents; 03238 if (res == 0) 03239 continue; 03240 if (fdmap[x].chan >= 0) { /* this is a channel */ 03241 winner = c[fdmap[x].chan]; /* override previous winners */ 03242 if (res & POLLPRI) 03243 ast_set_flag(winner, AST_FLAG_EXCEPTION); 03244 else 03245 ast_clear_flag(winner, AST_FLAG_EXCEPTION); 03246 winner->fdno = fdmap[x].fdno; 03247 } else { /* this is an fd */ 03248 if (outfd) 03249 *outfd = pfds[x].fd; 03250 if (exception) 03251 *exception = (res & POLLPRI) ? -1 : 0; 03252 winner = NULL; 03253 } 03254 } 03255 if (*ms > 0) { 03256 *ms -= ast_tvdiff_ms(ast_tvnow(), start); 03257 if (*ms < 0) 03258 *ms = 0; 03259 } 03260 return winner; 03261 }
int ast_waitfordigit | ( | struct ast_channel * | c, | |
int | ms | |||
) |
Waits for a digit.
c | channel to wait for a digit on | |
ms | how many milliseconds to wait |
Definition at line 3474 of file channel.c.
References ast_waitfordigit_full().
Referenced by __analog_ss_thread(), _while_exec(), advanced_options(), analog_my_getsigstr(), analog_ss_thread(), ast_adsi_get_cpeid(), ast_adsi_get_cpeinfo(), ast_adsi_print(), ast_adsi_read_encoded_dtmf(), ast_adsi_transmit_message_full(), ast_app_dtget(), ast_control_streamfile(), ast_record_review(), bridge_channel_feature(), builtin_atxfer(), collect_digits(), common_exec(), cpeid_exec(), dialout(), directory_exec(), forward_message(), get_folder(), ivr_dispatch(), mgcp_ss(), my_getsigstr(), pbx_builtin_waitexten(), play_record_review(), pri_ss_thread(), read_exec(), read_newoption(), readexten_exec(), retrydial_exec(), select_item_menu(), select_item_pause(), select_item_seq(), sendnoise(), testclient_exec(), testserver_exec(), vm_execmain(), vm_forwardoptions(), vm_instructions_en(), vm_options(), vm_tempgreeting(), and wait_a_bit().
03475 { 03476 return ast_waitfordigit_full(c, ms, -1, -1); 03477 }
int ast_waitfordigit_full | ( | struct ast_channel * | c, | |
int | ms, | |||
int | audiofd, | |||
int | ctrlfd | |||
) |
Wait for a digit Same as ast_waitfordigit() with audio fd for outputting read audio and ctrlfd to monitor for reading.
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 |
Definition at line 3512 of file channel.c.
References ast_check_hangup(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UPDATE_RTP_PEER, AST_FLAG_END_DTMF_ONLY, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_frfree, ast_log(), ast_read(), ast_set_flag, ast_test_flag, ast_waitfor_nandfds(), errno, f, and LOG_WARNING.
Referenced by ast_readstring_full(), ast_waitfordigit(), handle_getoption(), and handle_waitfordigit().
03513 { 03514 /* Stop if we're a zombie or need a soft hangup */ 03515 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 03516 return -1; 03517 03518 /* Only look for the end of DTMF, don't bother with the beginning and don't emulate things */ 03519 ast_set_flag(c, AST_FLAG_END_DTMF_ONLY); 03520 03521 /* Wait for a digit, no more than ms milliseconds total. */ 03522 03523 while (ms) { 03524 struct ast_channel *rchan; 03525 int outfd=-1; 03526 03527 errno = 0; 03528 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 03529 03530 if (!rchan && outfd < 0 && ms) { 03531 if (errno == 0 || errno == EINTR) 03532 continue; 03533 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 03534 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03535 return -1; 03536 } else if (outfd > -1) { 03537 /* The FD we were watching has something waiting */ 03538 ast_log(LOG_WARNING, "The FD we were waiting for has something waiting. Waitfordigit returning numeric 1\n"); 03539 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03540 return 1; 03541 } else if (rchan) { 03542 int res; 03543 struct ast_frame *f = ast_read(c); 03544 if (!f) 03545 return -1; 03546 03547 switch (f->frametype) { 03548 case AST_FRAME_DTMF_BEGIN: 03549 break; 03550 case AST_FRAME_DTMF_END: 03551 res = f->subclass.integer; 03552 ast_frfree(f); 03553 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03554 return res; 03555 case AST_FRAME_CONTROL: 03556 switch (f->subclass.integer) { 03557 case AST_CONTROL_HANGUP: 03558 ast_frfree(f); 03559 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03560 return -1; 03561 case AST_CONTROL_RINGING: 03562 case AST_CONTROL_ANSWER: 03563 case AST_CONTROL_SRCUPDATE: 03564 case AST_CONTROL_SRCCHANGE: 03565 case AST_CONTROL_CONNECTED_LINE: 03566 case AST_CONTROL_REDIRECTING: 03567 case AST_CONTROL_UPDATE_RTP_PEER: 03568 case -1: 03569 /* Unimportant */ 03570 break; 03571 default: 03572 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass.integer); 03573 break; 03574 } 03575 break; 03576 case AST_FRAME_VOICE: 03577 /* Write audio if appropriate */ 03578 if (audiofd > -1) { 03579 if (write(audiofd, f->data.ptr, f->datalen) < 0) { 03580 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 03581 } 03582 } 03583 default: 03584 /* Ignore */ 03585 break; 03586 } 03587 ast_frfree(f); 03588 } 03589 } 03590 03591 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03592 03593 return 0; /* Time is up */ 03594 }
int ast_write | ( | struct ast_channel * | chan, | |
struct ast_frame * | frame | |||
) |
Write a frame to a channel This function writes the given frame to the indicated channel.
chan | destination channel of the frame | |
frame | frame that will be written |
Definition at line 4767 of file channel.c.
References ast_channel::_softhangup, apply_plc(), ast_audiohook_detach_list(), AST_AUDIOHOOK_DIRECTION_WRITE, ast_audiohook_write_list(), ast_audiohook_write_list_empty(), ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_CONTROL_UNHOLD, ast_deactivate_generator(), ast_debug, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_WRITE_INT, AST_FLAG_ZOMBIE, AST_FORMAT_AUDIO_MASK, ast_format_rate(), AST_FORMAT_SLINEAR, AST_FORMAT_T140, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_frame_dump(), AST_FRAME_HTML, AST_FRAME_IAX, AST_FRAME_MODEM, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_framehook_list_write_event(), ast_frfree, ast_frisolate(), ast_getformatname(), ast_getformatname_multiple(), AST_LIST_NEXT, ast_log(), AST_MONITOR_RUNNING, ast_opt_generic_plc, ast_seekstream(), ast_senddigit_begin(), ast_senddigit_end(), ast_set_write_format(), AST_SOFTHANGUP_DEV, ast_test_flag, ast_translate(), ast_writestream(), ast_channel::audiohooks, calc_monitor_jump(), chanlist::chan, CHECK_BLOCKING, ast_frame_subclass::codec, ast_frame::data, ast_frame::datalen, DEBUGCHAN_FLAG, f, ast_filestream::fmt, ast_format::format, ast_channel::fout, FRAMECOUNT_INC, ast_channel::framehooks, ast_frame::frametype, ast_channel::generatordata, ast_channel_tech::indicate, ast_channel::insmpl, ast_frame_subclass::integer, ast_frame::len, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::name, ast_channel::nativeformats, chanlist::next, ast_channel::outsmpl, ast_frame::ptr, ast_channel::rawwriteformat, ast_channel_monitor::read_stream, ast_frame::samples, SEEK_FORCECUR, send_dtmf_event(), ast_channel_tech::send_html, ast_channel_tech::send_text, ast_frame::src, ast_channel_monitor::state, ast_frame::subclass, ast_channel::tech, ast_channel_tech::write, ast_channel_monitor::write_stream, ast_channel_tech::write_text, ast_channel_tech::write_video, ast_channel::writeformat, and ast_channel::writetrans.
Referenced by adsi_careful_send(), agent_write(), ast_bridge_call(), ast_prod(), ast_readaudio_callback(), ast_readvideo_callback(), ast_udptl_bridge(), ast_write_video(), conf_queue_dtmf(), conf_run(), dahdi_bridge(), dictate_exec(), echo_exec(), fax_generator_generate(), feature_request_and_dial(), function_ilink(), gen_generate(), generic_fax_exec(), handle_jack_audio(), handle_link_data(), jb_get_and_deliver(), linear_generator(), milliwatt_generate(), misdn_bridge(), moh_files_generator(), moh_generate(), mp3_exec(), multiplexed_bridge_write(), NBScat_exec(), remote_bridge_loop(), rpt(), send_link_dtmf(), send_link_keyquery(), send_tone_burst(), send_usb_txt(), send_waveform_to_channel(), silence_generator_generate(), simple_bridge_write(), softmix_bridge_poke(), softmix_bridge_write(), spy_generate(), and t38_tx_packet_handler().
04768 { 04769 int res = -1; 04770 struct ast_frame *f = NULL; 04771 int count = 0; 04772 04773 /*Deadlock avoidance*/ 04774 while(ast_channel_trylock(chan)) { 04775 /*cannot goto done since the channel is not locked*/ 04776 if(count++ > 10) { 04777 ast_debug(1, "Deadlock avoided for write to channel '%s'\n", chan->name); 04778 return 0; 04779 } 04780 usleep(1); 04781 } 04782 /* Stop if we're a zombie or need a soft hangup */ 04783 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) 04784 goto done; 04785 04786 /* Handle any pending masquerades */ 04787 if (chan->masq) { 04788 ast_channel_unlock(chan); 04789 if (ast_do_masquerade(chan)) { 04790 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 04791 return res; /* no need to goto done: chan is already unlocked for masq */ 04792 } 04793 ast_channel_lock(chan); 04794 } 04795 if (chan->masqr) { 04796 res = 0; /* XXX explain, why 0 ? */ 04797 goto done; 04798 } 04799 04800 /* Perform the framehook write event here. After the frame enters the framehook list 04801 * there is no telling what will happen, how awesome is that!!! */ 04802 if (!(fr = ast_framehook_list_write_event(chan->framehooks, fr))) { 04803 res = 0; 04804 goto done; 04805 } 04806 04807 if (chan->generatordata && (!fr->src || strcasecmp(fr->src, "ast_prod"))) { 04808 if (ast_test_flag(chan, AST_FLAG_WRITE_INT)) { 04809 ast_deactivate_generator(chan); 04810 } else { 04811 if (fr->frametype == AST_FRAME_DTMF_END) { 04812 /* There is a generator running while we're in the middle of a digit. 04813 * It's probably inband DTMF, so go ahead and pass it so it can 04814 * stop the generator */ 04815 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04816 ast_channel_unlock(chan); 04817 res = ast_senddigit_end(chan, fr->subclass.integer, fr->len); 04818 ast_channel_lock(chan); 04819 CHECK_BLOCKING(chan); 04820 } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_UNHOLD) { 04821 /* This is a side case where Echo is basically being called and the person put themselves on hold and took themselves off hold */ 04822 res = (chan->tech->indicate == NULL) ? 0 : 04823 chan->tech->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen); 04824 } 04825 res = 0; /* XXX explain, why 0 ? */ 04826 goto done; 04827 } 04828 } 04829 /* High bit prints debugging */ 04830 if (chan->fout & DEBUGCHAN_FLAG) 04831 ast_frame_dump(chan->name, fr, ">>"); 04832 CHECK_BLOCKING(chan); 04833 switch (fr->frametype) { 04834 case AST_FRAME_CONTROL: 04835 res = (chan->tech->indicate == NULL) ? 0 : 04836 chan->tech->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen); 04837 break; 04838 case AST_FRAME_DTMF_BEGIN: 04839 if (chan->audiohooks) { 04840 struct ast_frame *old_frame = fr; 04841 fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr); 04842 if (old_frame != fr) 04843 f = fr; 04844 } 04845 send_dtmf_event(chan, "Sent", fr->subclass.integer, "Yes", "No"); 04846 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04847 ast_channel_unlock(chan); 04848 res = ast_senddigit_begin(chan, fr->subclass.integer); 04849 ast_channel_lock(chan); 04850 CHECK_BLOCKING(chan); 04851 break; 04852 case AST_FRAME_DTMF_END: 04853 if (chan->audiohooks) { 04854 struct ast_frame *new_frame = fr; 04855 04856 new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr); 04857 if (new_frame != fr) { 04858 ast_frfree(new_frame); 04859 } 04860 } 04861 send_dtmf_event(chan, "Sent", fr->subclass.integer, "No", "Yes"); 04862 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04863 ast_channel_unlock(chan); 04864 res = ast_senddigit_end(chan, fr->subclass.integer, fr->len); 04865 ast_channel_lock(chan); 04866 CHECK_BLOCKING(chan); 04867 break; 04868 case AST_FRAME_TEXT: 04869 if (fr->subclass.integer == AST_FORMAT_T140) { 04870 res = (chan->tech->write_text == NULL) ? 0 : 04871 chan->tech->write_text(chan, fr); 04872 } else { 04873 res = (chan->tech->send_text == NULL) ? 0 : 04874 chan->tech->send_text(chan, (char *) fr->data.ptr); 04875 } 04876 break; 04877 case AST_FRAME_HTML: 04878 res = (chan->tech->send_html == NULL) ? 0 : 04879 chan->tech->send_html(chan, fr->subclass.integer, (char *) fr->data.ptr, fr->datalen); 04880 break; 04881 case AST_FRAME_VIDEO: 04882 /* XXX Handle translation of video codecs one day XXX */ 04883 res = (chan->tech->write_video == NULL) ? 0 : 04884 chan->tech->write_video(chan, fr); 04885 break; 04886 case AST_FRAME_MODEM: 04887 res = (chan->tech->write == NULL) ? 0 : 04888 chan->tech->write(chan, fr); 04889 break; 04890 case AST_FRAME_VOICE: 04891 if (chan->tech->write == NULL) 04892 break; /*! \todo XXX should return 0 maybe ? */ 04893 04894 if (ast_opt_generic_plc && fr->subclass.codec == AST_FORMAT_SLINEAR) { 04895 apply_plc(chan, fr); 04896 } 04897 04898 /* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */ 04899 if (fr->subclass.codec == chan->rawwriteformat) { 04900 f = fr; 04901 } else { 04902 /* XXX Something is not right we are not compatible with this frame bad things can happen 04903 * problems range from no/one-way audio to unexplained line hangups as a last resort try adjust the format 04904 * ideally we do not want to do this and this indicates a deeper problem for now we log these events to 04905 * eliminate user impact and help identify the problem areas 04906 * JIRA issues related to this :- 04907 * ASTERISK-14384, ASTERISK-17502, ASTERISK-17541, ASTERISK-18063, ASTERISK-18325, ASTERISK-18422*/ 04908 if ((!(fr->subclass.codec & chan->nativeformats)) && (chan->writeformat != fr->subclass.codec)) { 04909 char nf[512]; 04910 ast_log(LOG_WARNING, "Codec mismatch on channel %s setting write format to %s from %s native formats %s\n", 04911 chan->name, ast_getformatname(fr->subclass.codec), ast_getformatname(chan->writeformat), 04912 ast_getformatname_multiple(nf, sizeof(nf), chan->nativeformats & AST_FORMAT_AUDIO_MASK)); 04913 ast_set_write_format(chan, fr->subclass.codec); 04914 } 04915 04916 f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr; 04917 } 04918 04919 if (!f) { 04920 res = 0; 04921 break; 04922 } 04923 04924 if (chan->audiohooks) { 04925 struct ast_frame *prev = NULL, *new_frame, *cur, *dup; 04926 int freeoldlist = 0; 04927 04928 if (f != fr) { 04929 freeoldlist = 1; 04930 } 04931 04932 /* Since ast_audiohook_write may return a new frame, and the cur frame is 04933 * an item in a list of frames, create a new list adding each cur frame back to it 04934 * regardless if the cur frame changes or not. */ 04935 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 04936 new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, cur); 04937 04938 /* if this frame is different than cur, preserve the end of the list, 04939 * free the old frames, and set cur to be the new frame */ 04940 if (new_frame != cur) { 04941 04942 /* doing an ast_frisolate here seems silly, but we are not guaranteed the new_frame 04943 * isn't part of local storage, meaning if ast_audiohook_write is called multiple 04944 * times it may override the previous frame we got from it unless we dup it */ 04945 if ((dup = ast_frisolate(new_frame))) { 04946 AST_LIST_NEXT(dup, frame_list) = AST_LIST_NEXT(cur, frame_list); 04947 if (freeoldlist) { 04948 AST_LIST_NEXT(cur, frame_list) = NULL; 04949 ast_frfree(cur); 04950 } 04951 if (new_frame != dup) { 04952 ast_frfree(new_frame); 04953 } 04954 cur = dup; 04955 } 04956 } 04957 04958 /* now, regardless if cur is new or not, add it to the new list, 04959 * if the new list has not started, cur will become the first item. */ 04960 if (prev) { 04961 AST_LIST_NEXT(prev, frame_list) = cur; 04962 } else { 04963 f = cur; /* set f to be the beginning of our new list */ 04964 } 04965 prev = cur; 04966 } 04967 } 04968 04969 /* If Monitor is running on this channel, then we have to write frames out there too */ 04970 /* the translator on chan->writetrans may have returned multiple frames 04971 from the single frame we passed in; if so, feed each one of them to the 04972 monitor */ 04973 if (chan->monitor && chan->monitor->write_stream) { 04974 struct ast_frame *cur; 04975 04976 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 04977 /* XXX must explain this code */ 04978 #ifndef MONITOR_CONSTANT_DELAY 04979 int jump = chan->insmpl - chan->outsmpl - 4 * cur->samples; 04980 if (jump >= 0) { 04981 jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format)); 04982 if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1) 04983 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 04984 chan->outsmpl += (chan->insmpl - chan->outsmpl) + cur->samples; 04985 } else { 04986 chan->outsmpl += cur->samples; 04987 } 04988 #else 04989 int jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format)); 04990 if (jump - MONITOR_DELAY >= 0) { 04991 if (ast_seekstream(chan->monitor->write_stream, jump - cur->samples, SEEK_FORCECUR) == -1) 04992 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 04993 chan->outsmpl += chan->insmpl - chan->outsmpl; 04994 } else { 04995 chan->outsmpl += cur->samples; 04996 } 04997 #endif 04998 if (chan->monitor->state == AST_MONITOR_RUNNING) { 04999 if (ast_writestream(chan->monitor->write_stream, cur) < 0) 05000 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n"); 05001 } 05002 } 05003 } 05004 05005 /* the translator on chan->writetrans may have returned multiple frames 05006 from the single frame we passed in; if so, feed each one of them to the 05007 channel, freeing each one after it has been written */ 05008 if ((f != fr) && AST_LIST_NEXT(f, frame_list)) { 05009 struct ast_frame *cur, *next; 05010 unsigned int skip = 0; 05011 05012 for (cur = f, next = AST_LIST_NEXT(cur, frame_list); 05013 cur; 05014 cur = next, next = cur ? AST_LIST_NEXT(cur, frame_list) : NULL) { 05015 if (!skip) { 05016 if ((res = chan->tech->write(chan, cur)) < 0) { 05017 chan->_softhangup |= AST_SOFTHANGUP_DEV; 05018 skip = 1; 05019 } else if (next) { 05020 /* don't do this for the last frame in the list, 05021 as the code outside the loop will do it once 05022 */ 05023 chan->fout = FRAMECOUNT_INC(chan->fout); 05024 } 05025 } 05026 ast_frfree(cur); 05027 } 05028 05029 /* reset f so the code below doesn't attempt to free it */ 05030 f = NULL; 05031 } else { 05032 res = chan->tech->write(chan, f); 05033 } 05034 break; 05035 case AST_FRAME_NULL: 05036 case AST_FRAME_IAX: 05037 /* Ignore these */ 05038 res = 0; 05039 break; 05040 default: 05041 /* At this point, fr is the incoming frame and f is NULL. Channels do 05042 * not expect to get NULL as a frame pointer and will segfault. Hence, 05043 * we output the original frame passed in. */ 05044 res = chan->tech->write(chan, fr); 05045 break; 05046 } 05047 05048 if (f && f != fr) 05049 ast_frfree(f); 05050 ast_clear_flag(chan, AST_FLAG_BLOCKING); 05051 05052 /* Consider a write failure to force a soft hangup */ 05053 if (res < 0) { 05054 chan->_softhangup |= AST_SOFTHANGUP_DEV; 05055 } else { 05056 chan->fout = FRAMECOUNT_INC(chan->fout); 05057 } 05058 done: 05059 if (chan->audiohooks && ast_audiohook_write_list_empty(chan->audiohooks)) { 05060 /* The list gets recreated if audiohooks are added again later */ 05061 ast_audiohook_detach_list(chan->audiohooks); 05062 chan->audiohooks = NULL; 05063 } 05064 ast_channel_unlock(chan); 05065 return res; 05066 }
int ast_write_text | ( | struct ast_channel * | chan, | |
struct ast_frame * | frame | |||
) |
Write text frame to a channel This function writes the given frame to the indicated channel.
chan | destination channel of the frame | |
frame | frame that will be written |
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.
chan | destination channel of the frame | |
frame | frame that will be written |
Definition at line 4652 of file channel.c.
References ast_write(), chanlist::chan, ast_channel::tech, and ast_channel_tech::write_video.
04653 { 04654 int res; 04655 if (!chan->tech->write_video) 04656 return 0; 04657 res = ast_write(chan, fr); 04658 if (!res) 04659 res = 1; 04660 return res; 04661 }
const char* channelreloadreason2txt | ( | enum channelreloadreason | reason | ) |
Convert enum channelreloadreason to text string for manager event.
\ brief Convert channel reloadreason (ENUM) to text string for manager event
Definition at line 8076 of file channel.c.
References CHANNEL_CLI_RELOAD, CHANNEL_MODULE_LOAD, and CHANNEL_MODULE_RELOAD.
08077 { 08078 switch (reason) { 08079 case CHANNEL_MODULE_LOAD: 08080 return "LOAD (Channel module load)"; 08081 08082 case CHANNEL_MODULE_RELOAD: 08083 return "RELOAD (Channel module reload)"; 08084 08085 case CHANNEL_CLI_RELOAD: 08086 return "CLIRELOAD (Channel module reload by CLI command)"; 08087 08088 default: 08089 return "MANAGERRELOAD (Channel module reload by manager)"; 08090 } 08091 };
struct ast_channel_tech ast_kill_tech |
Kill the channel channel driver technology descriptor.
The purpose of this channel technology is to encourage the channel to hangup as quickly as possible.
Definition at line 653 of file channel.c.
Referenced by ast_do_masquerade().
unsigned long global_fin |
The current value of the debug flags is stored in the two variables global_fin and global_fout (declared in main/channel.c)
Definition at line 97 of file channel.c.
Referenced by handle_core_set_debug_channel().
unsigned long global_fout |