#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_undestroyed_channels (void) |
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 1913 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 1915 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 1135 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(), and unistim_new().
#define ast_channel_lock | ( | chan | ) | ao2_lock(chan) |
Definition at line 2446 of file channel.h.
Referenced by __analog_handle_event(), __ast_answer(), __ast_pbx_run(), __ast_queue_frame(), __ast_read(), __ast_request_and_dial(), __dahdi_exception(), __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_datastore(), add_to_agi(), agent_indicate(), agent_lock_owner(), analog_exception(), 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_bridge(), 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(), dahdi_handle_event(), 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(), gosub_exec(), 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(), listfilter(), local_ast_moh_stop(), local_call(), local_hangup(), local_queryoption(), local_queue_frame(), local_read(), local_setoption(), local_write(), 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(), pop_exec(), process_sdp(), queue_exec(), receivefax_exec(), redirecting_read(), redirecting_write(), release_transaction(), report_fax_status(), retrydial_exec(), return_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(), stackpeek_read(), 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 2453 of file channel.h.
Referenced by __ast_channel_masquerade(), __ast_request_and_dial(), ast_bridge_call(), ast_call_forward(), ast_do_masquerade(), call_forward_inherit(), dial_transfer(), do_bridge_masquerade(), do_forward(), 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 2471 of file channel.h.
Referenced by agent_hangup(), agent_lock_owner(), ast_autochan_new_channel(), ast_autochan_setup(), ast_cel_report_event(), ast_do_masquerade(), ast_set_hangupsource(), awesome_locking(), check_bridge(), handle_getvariablefull(), handle_incoming(), handle_invite_replaces(), handle_request_refer(), local_attended_transfer(), local_queryoption(), local_queue_frame(), local_setoption(), set_hangup_source_and_cause(), sip_pickup(), sip_pvt_lock_full(), sip_queue_hangup_cause(), and socket_process().
#define ast_channel_trylock | ( | chan | ) | ao2_trylock(chan) |
Definition at line 2448 of file channel.h.
Referenced by __ast_channel_masquerade(), __oh323_rtp_create(), agent_indicate(), agent_logoff(), agent_read(), analog_lock_sub_owner(), 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(), 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(), sip_hangup(), sip_reinvite_retry(), and update_state().
#define ast_channel_unlock | ( | chan | ) | ao2_unlock(chan) |
Definition at line 2447 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(), __dahdi_exception(), __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_datastore(), add_to_agi(), agent_indicate(), agent_lock_owner(), agent_logoff(), agent_read(), agents_data_provider_get(), agents_show(), agents_show_online(), alsa_call(), analog_attempt_transfer(), analog_exception(), 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(), gosub_exec(), 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(), listfilter(), local_ast_moh_stop(), local_attended_transfer(), local_bridge_loop(), local_call(), local_hangup(), local_queryoption(), local_queue_frame(), local_read(), local_setoption(), local_write(), 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(), pop_exec(), pri_fixup_principle(), pri_queue_frame(), proc_session_timer(), process_sdp(), queue_exec(), receive_digit(), receivefax_exec(), redirecting_read(), redirecting_write(), reinvite_timeout(), release_chan(), release_chan_early(), release_transaction(), remote_bridge_loop(), remote_hold(), report_fax_status(), retrans_pkt(), retrydial_exec(), return_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(), sip_addheader(), sip_dtmfmode(), sip_hangup(), sip_new(), sip_pvt_lock_full(), sip_queue_hangup_cause(), 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(), stackpeek_read(), 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 2482 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_fabricate_channel_from_event(), ast_cel_report_event(), ast_channel_release(), ast_complete_channels(), ast_do_masquerade(), ast_dummy_channel_alloc(), ast_hangup(), ast_parse_device_state(), ast_pbx_outgoing_cdr_failed(), ast_pickup_call(), ast_set_hangupsource(), 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(), reinvite_timeout(), rotate_file(), send_provisional_keepalive_full(), senddtmf_exec(), sendmail(), sendpage(), set_hangup_source_and_cause(), shared_read(), shared_write(), sip_pickup(), sip_pickup_thread(), sip_pvt_lock_full(), sip_queue_hangup_cause(), 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(), ast_do_masquerade(), and ast_settimeout().
#define CHECK_BLOCKING | ( | c | ) |
Definition at line 2407 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_datastore(), 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 648 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 876 of file channel.h.
00876 { 00877 /*! 00878 * \brief Channels have this property if they can accept input with jitter; 00879 * i.e. most VoIP channels 00880 */ 00881 AST_CHAN_TP_WANTSJITTER = (1 << 0), 00882 /*! 00883 * \brief Channels have this property if they can create jitter; 00884 * i.e. most VoIP channels 00885 */ 00886 AST_CHAN_TP_CREATESJITTER = (1 << 1), 00887 };
anonymous enum |
ast_channel flags
Definition at line 890 of file channel.h.
00890 { 00891 /*! Queue incoming DTMF, to be released when this flag is turned off */ 00892 AST_FLAG_DEFER_DTMF = (1 << 1), 00893 /*! write should be interrupt generator */ 00894 AST_FLAG_WRITE_INT = (1 << 2), 00895 /*! a thread is blocking on this channel */ 00896 AST_FLAG_BLOCKING = (1 << 3), 00897 /*! This is a zombie channel */ 00898 AST_FLAG_ZOMBIE = (1 << 4), 00899 /*! There is an exception pending */ 00900 AST_FLAG_EXCEPTION = (1 << 5), 00901 /*! Listening to moh XXX anthm promises me this will disappear XXX */ 00902 AST_FLAG_MOH = (1 << 6), 00903 /*! This channel is spying on another channel */ 00904 AST_FLAG_SPYING = (1 << 7), 00905 /*! This channel is in a native bridge */ 00906 AST_FLAG_NBRIDGE = (1 << 8), 00907 /*! the channel is in an auto-incrementing dialplan processor, 00908 * so when ->priority is set, it will get incremented before 00909 * finding the next priority to run */ 00910 AST_FLAG_IN_AUTOLOOP = (1 << 9), 00911 /*! This is an outgoing call */ 00912 AST_FLAG_OUTGOING = (1 << 10), 00913 /*! A DTMF_BEGIN frame has been read from this channel, but not yet an END */ 00914 AST_FLAG_IN_DTMF = (1 << 12), 00915 /*! A DTMF_END was received when not IN_DTMF, so the length of the digit is 00916 * currently being emulated */ 00917 AST_FLAG_EMULATE_DTMF = (1 << 13), 00918 /*! This is set to tell the channel not to generate DTMF begin frames, and 00919 * to instead only generate END frames. */ 00920 AST_FLAG_END_DTMF_ONLY = (1 << 14), 00921 /*! Flag to show channels that this call is hangup due to the fact that the call 00922 was indeed answered, but in another channel */ 00923 AST_FLAG_ANSWERED_ELSEWHERE = (1 << 15), 00924 /*! This flag indicates that on a masquerade, an active stream should not 00925 * be carried over */ 00926 AST_FLAG_MASQ_NOSTREAM = (1 << 16), 00927 /*! This flag indicates that the hangup exten was run when the bridge terminated, 00928 * a message aimed at preventing a subsequent hangup exten being run at the pbx_run 00929 * level */ 00930 AST_FLAG_BRIDGE_HANGUP_RUN = (1 << 17), 00931 /*! This flag indicates that the hangup exten should NOT be run when the 00932 * bridge terminates, this will allow the hangup in the pbx loop to be run instead. 00933 * */ 00934 AST_FLAG_BRIDGE_HANGUP_DONT = (1 << 18), 00935 /*! Disable certain workarounds. This reintroduces certain bugs, but allows 00936 * some non-traditional dialplans (like AGI) to continue to function. 00937 */ 00938 AST_FLAG_DISABLE_WORKAROUNDS = (1 << 20), 00939 };
anonymous enum |
ast_bridge_config flags
Definition at line 942 of file channel.h.
00942 { 00943 AST_FEATURE_PLAY_WARNING = (1 << 0), 00944 AST_FEATURE_REDIRECT = (1 << 1), 00945 AST_FEATURE_DISCONNECT = (1 << 2), 00946 AST_FEATURE_ATXFER = (1 << 3), 00947 AST_FEATURE_AUTOMON = (1 << 4), 00948 AST_FEATURE_PARKCALL = (1 << 5), 00949 AST_FEATURE_AUTOMIXMON = (1 << 6), 00950 AST_FEATURE_NO_H_EXTEN = (1 << 7), 00951 AST_FEATURE_WARNING_ACTIVE = (1 << 8), 00952 };
anonymous enum |
Definition at line 990 of file channel.h.
00990 { 00991 /*! 00992 * Soft hangup requested by device or other internal reason. 00993 * Actual hangup needed. 00994 */ 00995 AST_SOFTHANGUP_DEV = (1 << 0), 00996 /*! 00997 * Used to break the normal frame flow so an async goto can be 00998 * done instead of actually hanging up. 00999 */ 01000 AST_SOFTHANGUP_ASYNCGOTO = (1 << 1), 01001 /*! 01002 * Soft hangup requested by system shutdown. Actual hangup 01003 * needed. 01004 */ 01005 AST_SOFTHANGUP_SHUTDOWN = (1 << 2), 01006 /*! 01007 * Used to break the normal frame flow after a timeout so an 01008 * implicit async goto can be done to the 'T' exten if it exists 01009 * instead of actually hanging up. If the exten does not exist 01010 * then actually hangup. 01011 */ 01012 AST_SOFTHANGUP_TIMEOUT = (1 << 3), 01013 /*! 01014 * Soft hangup requested by application/channel-driver being 01015 * unloaded. Actual hangup needed. 01016 */ 01017 AST_SOFTHANGUP_APPUNLOAD = (1 << 4), 01018 /*! 01019 * Soft hangup requested by non-associated party. Actual hangup 01020 * needed. 01021 */ 01022 AST_SOFTHANGUP_EXPLICIT = (1 << 5), 01023 /*! 01024 * Used to break a bridge so the channel can be spied upon 01025 * instead of actually hanging up. 01026 */ 01027 AST_SOFTHANGUP_UNBRIDGE = (1 << 6), 01028 01029 01030 /*! 01031 * \brief All softhangup flags. 01032 * 01033 * This can be used as an argument to ast_channel_softhangup_clear 01034 * to clear all softhangup flags from a channel. 01035 */ 01036 AST_SOFTHANGUP_ALL = (0xFFFFFFFF) 01037 };
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 659 of file channel.h.
00659 { 00660 AST_ADSI_UNKNOWN, 00661 AST_ADSI_AVAILABLE, 00662 AST_ADSI_UNAVAILABLE, 00663 AST_ADSI_OFFHOOKONLY, 00664 };
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 669 of file channel.h.
00669 { 00670 T38_STATE_UNAVAILABLE, /*!< T38 is unavailable on this channel or disabled by configuration */ 00671 T38_STATE_UNKNOWN, /*!< The channel supports T38 but the current status is unknown */ 00672 T38_STATE_NEGOTIATING, /*!< T38 is being negotiated */ 00673 T38_STATE_REJECTED, /*!< Remote side has rejected our offer */ 00674 T38_STATE_NEGOTIATED, /*!< T38 established */ 00675 };
enum channelreloadreason |
Channel reload reasons for manager events at load or reload of configuration.
Definition at line 1041 of file channel.h.
01041 { 01042 CHANNEL_MODULE_LOAD, 01043 CHANNEL_MODULE_RELOAD, 01044 CHANNEL_CLI_RELOAD, 01045 CHANNEL_MANAGER_RELOAD, 01046 };
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 2949 of file channel.c.
References ast_channel::_state, ast_channel_lock, ast_channel_unlock, AST_CONTROL_HANGUP, ast_debug, AST_FRAME_CNG, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_HTML, AST_FRAME_IAX, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_frisolate(), AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_HEAD_NOLOCK, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_HEAD, ast_log(), ast_queue_frame_head(), ast_raw_answer(), ast_read(), AST_STATE_RING, AST_STATE_RINGING, ast_waitfor(), chanlist::chan, errno, frames, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, MAX, ast_channel::name, and ast_frame::subclass.
Referenced by ast_answer(), pbx_builtin_answer(), and pbx_builtin_incomplete().
02950 { 02951 int res = 0; 02952 enum ast_channel_state old_state; 02953 02954 old_state = chan->_state; 02955 if ((res = ast_raw_answer(chan, cdr_answer))) { 02956 return res; 02957 } 02958 02959 switch (old_state) { 02960 case AST_STATE_RINGING: 02961 case AST_STATE_RING: 02962 /* wait for media to start flowing, but don't wait any longer 02963 * than 'delay' or 500 milliseconds, whichever is longer 02964 */ 02965 do { 02966 AST_LIST_HEAD_NOLOCK(, ast_frame) frames; 02967 struct ast_frame *cur, *new; 02968 int ms = MAX(delay, 500); 02969 unsigned int done = 0; 02970 02971 AST_LIST_HEAD_INIT_NOLOCK(&frames); 02972 02973 for (;;) { 02974 ms = ast_waitfor(chan, ms); 02975 if (ms < 0) { 02976 ast_log(LOG_WARNING, "Error condition occurred when polling channel %s for a voice frame: %s\n", chan->name, strerror(errno)); 02977 res = -1; 02978 break; 02979 } 02980 if (ms == 0) { 02981 ast_debug(2, "Didn't receive a media frame from %s within %d ms of answering. Continuing anyway\n", chan->name, MAX(delay, 500)); 02982 break; 02983 } 02984 cur = ast_read(chan); 02985 if (!cur || ((cur->frametype == AST_FRAME_CONTROL) && 02986 (cur->subclass.integer == AST_CONTROL_HANGUP))) { 02987 if (cur) { 02988 ast_frfree(cur); 02989 } 02990 res = -1; 02991 ast_debug(2, "Hangup of channel %s detected in answer routine\n", chan->name); 02992 break; 02993 } 02994 02995 if ((new = ast_frisolate(cur)) != cur) { 02996 ast_frfree(cur); 02997 } 02998 02999 AST_LIST_INSERT_HEAD(&frames, new, frame_list); 03000 03001 /* if a specific delay period was requested, continue 03002 * until that delay has passed. don't stop just because 03003 * incoming media has arrived. 03004 */ 03005 if (delay) { 03006 continue; 03007 } 03008 03009 switch (new->frametype) { 03010 /* all of these frametypes qualify as 'media' */ 03011 case AST_FRAME_VOICE: 03012 case AST_FRAME_VIDEO: 03013 case AST_FRAME_TEXT: 03014 case AST_FRAME_DTMF_BEGIN: 03015 case AST_FRAME_DTMF_END: 03016 case AST_FRAME_IMAGE: 03017 case AST_FRAME_HTML: 03018 case AST_FRAME_MODEM: 03019 done = 1; 03020 break; 03021 case AST_FRAME_CONTROL: 03022 case AST_FRAME_IAX: 03023 case AST_FRAME_NULL: 03024 case AST_FRAME_CNG: 03025 break; 03026 } 03027 03028 if (done) { 03029 break; 03030 } 03031 } 03032 03033 if (res == 0) { 03034 ast_channel_lock(chan); 03035 while ((cur = AST_LIST_REMOVE_HEAD(&frames, frame_list))) { 03036 ast_queue_frame_head(chan, cur); 03037 ast_frfree(cur); 03038 } 03039 ast_channel_unlock(chan); 03040 } 03041 } while (0); 03042 break; 03043 default: 03044 break; 03045 } 03046 03047 return res; 03048 }
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 1355 of file channel.c.
References __ast_channel_alloc_ap().
01361 { 01362 va_list ap1, ap2; 01363 struct ast_channel *result; 01364 01365 va_start(ap1, name_fmt); 01366 va_start(ap2, name_fmt); 01367 result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context, 01368 linkedid, amaflag, file, line, function, name_fmt, ap1, ap2); 01369 va_end(ap1); 01370 va_end(ap2); 01371 01372 return result; 01373 }
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 5341 of file channel.c.
References ast_channel::_state, outgoing_helper::account, ast_call(), ast_call_forward(), AST_CAUSE_NO_ANSWER, ast_cdr_alloc(), ast_cdr_answer(), ast_cdr_busy(), ast_cdr_disposition(), ast_cdr_end(), ast_cdr_failed(), AST_CDR_FLAG_ORIGINATED, ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_setapp(), ast_cdr_start(), ast_cdr_update(), ast_channel_datastore_inherit(), ast_channel_inherit_variables(), ast_channel_lock, ast_channel_lock_both, ast_channel_set_connected_line(), ast_channel_unlock, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CC, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_copy_string(), AST_FRAME_CONTROL, ast_frfree, ast_hangup(), ast_log(), ast_party_connected_line_set_init(), AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, ast_read(), ast_request(), ast_set_callerid(), ast_set_flag, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_waitfor(), ast_channel::call_forward, cause, ast_channel::cdr, chanlist::chan, outgoing_helper::cid_name, outgoing_helper::cid_num, 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().
05342 { 05343 int dummy_outstate; 05344 int cause = 0; 05345 struct ast_channel *chan; 05346 int res = 0; 05347 int last_subclass = 0; 05348 struct ast_party_connected_line connected; 05349 05350 if (outstate) 05351 *outstate = 0; 05352 else 05353 outstate = &dummy_outstate; /* make outstate always a valid pointer */ 05354 05355 chan = ast_request(type, format, requestor, data, &cause); 05356 if (!chan) { 05357 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data); 05358 handle_cause(cause, outstate); 05359 return NULL; 05360 } 05361 05362 if (oh) { 05363 if (oh->vars) { 05364 ast_set_variables(chan, oh->vars); 05365 } 05366 if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) { 05367 /* 05368 * Use the oh values instead of the function parameters for the 05369 * outgoing CallerID. 05370 */ 05371 cid_num = oh->cid_num; 05372 cid_name = oh->cid_name; 05373 } 05374 if (oh->parent_channel) { 05375 /* Safely inherit variables and datastores from the parent channel. */ 05376 ast_channel_lock_both(oh->parent_channel, chan); 05377 ast_channel_inherit_variables(oh->parent_channel, chan); 05378 ast_channel_datastore_inherit(oh->parent_channel, chan); 05379 ast_channel_unlock(oh->parent_channel); 05380 ast_channel_unlock(chan); 05381 } 05382 if (oh->account) { 05383 ast_channel_lock(chan); 05384 ast_cdr_setaccount(chan, oh->account); 05385 ast_channel_unlock(chan); 05386 } 05387 } 05388 05389 /* 05390 * I seems strange to set the CallerID on an outgoing call leg 05391 * to whom we are calling, but this function's callers are doing 05392 * various Originate methods. This call leg goes to the local 05393 * user. Once the local user answers, the dialplan needs to be 05394 * able to access the CallerID from the CALLERID function as if 05395 * the local user had placed this call. 05396 */ 05397 ast_set_callerid(chan, cid_num, cid_name, cid_num); 05398 05399 ast_set_flag(chan->cdr, AST_CDR_FLAG_ORIGINATED); 05400 ast_party_connected_line_set_init(&connected, &chan->connected); 05401 if (cid_num) { 05402 connected.id.number.valid = 1; 05403 connected.id.number.str = (char *) cid_num; 05404 connected.id.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 05405 } 05406 if (cid_name) { 05407 connected.id.name.valid = 1; 05408 connected.id.name.str = (char *) cid_name; 05409 connected.id.name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 05410 } 05411 ast_channel_set_connected_line(chan, &connected, NULL); 05412 05413 if (ast_call(chan, data, 0)) { /* ast_call failed... */ 05414 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data); 05415 } else { 05416 res = 1; /* mark success in case chan->_state is already AST_STATE_UP */ 05417 while (timeout && chan->_state != AST_STATE_UP) { 05418 struct ast_frame *f; 05419 res = ast_waitfor(chan, timeout); 05420 if (res == 0) { /* timeout, treat it like ringing */ 05421 *outstate = AST_CONTROL_RINGING; 05422 break; 05423 } 05424 if (res < 0) /* error or done */ 05425 break; 05426 if (timeout > -1) 05427 timeout = res; 05428 if (!ast_strlen_zero(chan->call_forward)) { 05429 if (!(chan = ast_call_forward(NULL, chan, NULL, format, oh, outstate))) { 05430 return NULL; 05431 } 05432 continue; 05433 } 05434 05435 f = ast_read(chan); 05436 if (!f) { 05437 *outstate = AST_CONTROL_HANGUP; 05438 res = 0; 05439 break; 05440 } 05441 if (f->frametype == AST_FRAME_CONTROL) { 05442 switch (f->subclass.integer) { 05443 case AST_CONTROL_RINGING: /* record but keep going */ 05444 *outstate = f->subclass.integer; 05445 break; 05446 05447 case AST_CONTROL_BUSY: 05448 ast_cdr_busy(chan->cdr); 05449 *outstate = f->subclass.integer; 05450 timeout = 0; 05451 break; 05452 05453 case AST_CONTROL_INCOMPLETE: 05454 ast_cdr_failed(chan->cdr); 05455 *outstate = AST_CONTROL_CONGESTION; 05456 timeout = 0; 05457 break; 05458 05459 case AST_CONTROL_CONGESTION: 05460 ast_cdr_failed(chan->cdr); 05461 *outstate = f->subclass.integer; 05462 timeout = 0; 05463 break; 05464 05465 case AST_CONTROL_ANSWER: 05466 ast_cdr_answer(chan->cdr); 05467 *outstate = f->subclass.integer; 05468 timeout = 0; /* trick to force exit from the while() */ 05469 break; 05470 05471 /* Ignore these */ 05472 case AST_CONTROL_PROGRESS: 05473 case AST_CONTROL_PROCEEDING: 05474 case AST_CONTROL_HOLD: 05475 case AST_CONTROL_UNHOLD: 05476 case AST_CONTROL_VIDUPDATE: 05477 case AST_CONTROL_SRCUPDATE: 05478 case AST_CONTROL_SRCCHANGE: 05479 case AST_CONTROL_CONNECTED_LINE: 05480 case AST_CONTROL_REDIRECTING: 05481 case AST_CONTROL_CC: 05482 case -1: /* Ignore -- just stopping indications */ 05483 break; 05484 05485 default: 05486 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass.integer); 05487 } 05488 last_subclass = f->subclass.integer; 05489 } 05490 ast_frfree(f); 05491 } 05492 } 05493 05494 /* Final fixups */ 05495 if (oh) { 05496 if (!ast_strlen_zero(oh->context)) 05497 ast_copy_string(chan->context, oh->context, sizeof(chan->context)); 05498 if (!ast_strlen_zero(oh->exten)) 05499 ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten)); 05500 if (oh->priority) 05501 chan->priority = oh->priority; 05502 } 05503 if (chan->_state == AST_STATE_UP) 05504 *outstate = AST_CONTROL_ANSWER; 05505 05506 if (res <= 0) { 05507 ast_channel_lock(chan); 05508 if (AST_CONTROL_RINGING == last_subclass) { 05509 chan->hangupcause = AST_CAUSE_NO_ANSWER; 05510 } 05511 if (!chan->cdr && (chan->cdr = ast_cdr_alloc())) { 05512 ast_cdr_init(chan->cdr, chan); 05513 } 05514 if (chan->cdr) { 05515 char tmp[256]; 05516 05517 snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data); 05518 ast_cdr_setapp(chan->cdr, "Dial", tmp); 05519 ast_cdr_update(chan); 05520 ast_cdr_start(chan->cdr); 05521 ast_cdr_end(chan->cdr); 05522 /* If the cause wasn't handled properly */ 05523 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) { 05524 ast_cdr_failed(chan->cdr); 05525 } 05526 } 05527 ast_channel_unlock(chan); 05528 ast_hangup(chan); 05529 chan = NULL; 05530 } 05531 return chan; 05532 }
int ast_activate_generator | ( | struct ast_channel * | chan, | |
struct ast_generator * | gen, | |||
void * | params | |||
) |
Activate a given generator
Definition at line 3100 of file channel.c.
References ast_generator::alloc, ast_channel_lock, ast_channel_unlock, ast_prod(), ast_settimeout(), chanlist::chan, gen, ast_channel::generator, generator_force(), ast_channel::generatordata, and ast_generator::release.
Referenced by ast_channel_start_silence_generator(), ast_linear_stream(), ast_playtones_start(), ast_tonepair_start(), channel_spy(), eivr_comm(), old_milliwatt_exec(), and transmit_audio().
03101 { 03102 int res = 0; 03103 03104 ast_channel_lock(chan); 03105 if (chan->generatordata) { 03106 if (chan->generator && chan->generator->release) 03107 chan->generator->release(chan, chan->generatordata); 03108 chan->generatordata = NULL; 03109 } 03110 if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) { 03111 res = -1; 03112 } 03113 if (!res) { 03114 ast_settimeout(chan, 50, generator_force, chan); 03115 chan->generator = gen; 03116 } 03117 ast_channel_unlock(chan); 03118 03119 ast_prod(chan); 03120 03121 return res; 03122 }
int ast_active_channels | ( | void | ) |
returns number of active/allocated channels
Definition at line 837 of file channel.c.
References ao2_container_count(), and channels.
Referenced by action_corestatus(), ast_var_channels(), ast_var_channels_table(), handle_chanlist(), handle_show_settings(), and really_quit().
00838 { 00839 return channels ? ao2_container_count(channels) : 0; 00840 }
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 2370 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 3050 of file channel.c.
References __ast_answer(), and chanlist::chan.
Referenced by action_bridge(), agi_exec_full(), alarmreceiver_exec(), answer_trunk_chan(), app_exec(), ast_control_streamfile(), ast_do_pickup(), ast_pickup_call(), auth_exec(), background_detect_exec(), bridge_exec(), builtin_parkcall(), common_exec(), conf_exec(), count_exec(), dahdiras_exec(), dial_exec_full(), dictate_exec(), directory_exec(), disa_exec(), eivr_comm(), handle_answer(), ices_exec(), login_exec(), minivm_accmess_exec(), minivm_greet_exec(), minivm_record_exec(), old_milliwatt_exec(), park_call_exec(), parked_call_exec(), pbx_builtin_background(), playback_exec(), privacy_exec(), read_exec(), readexten_exec(), receivefax_exec(), sayunixtime_exec(), send_waveform_to_channel(), sendfax_exec(), setup_privacy_args(), skel_exec(), sla_station_exec(), speech_background(), testclient_exec(), testserver_exec(), transmit(), vm_exec(), vm_execmain(), waitfor_exec(), and zapateller_exec().
03051 { 03052 return __ast_answer(chan, 0, 1); 03053 }
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 306 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().
00307 { 00308 struct asent *as; 00309 int res = -1; 00310 00311 AST_LIST_LOCK(&aslist); 00312 AST_LIST_TRAVERSE(&aslist, as, list) { 00313 if (as->chan == chan) { 00314 res = 0; 00315 as->ignore_frame_types |= (1 << ftype); 00316 break; 00317 } 00318 } 00319 AST_LIST_UNLOCK(&aslist); 00320 return res; 00321 }
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 178 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(), realtimefield_read(), senddtmf_exec(), shell_helper(), sla_station_exec(), smdi_msg_retrieve_read(), srv_datastore_setup(), system_exec_helper(), and trylock_read().
00179 { 00180 int res = 0; 00181 struct asent *as; 00182 00183 AST_LIST_LOCK(&aslist); 00184 AST_LIST_TRAVERSE(&aslist, as, list) { 00185 if (as->chan == chan) { 00186 as->use_count++; 00187 break; 00188 } 00189 } 00190 AST_LIST_UNLOCK(&aslist); 00191 00192 if (as) { 00193 /* Entry exists, autoservice is already handling this channel */ 00194 return 0; 00195 } 00196 00197 if (!(as = ast_calloc(1, sizeof(*as)))) 00198 return -1; 00199 00200 /* New entry created */ 00201 as->chan = chan; 00202 as->use_count = 1; 00203 00204 ast_channel_lock(chan); 00205 as->orig_end_dtmf_flag = ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY) ? 1 : 0; 00206 if (!as->orig_end_dtmf_flag) 00207 ast_set_flag(chan, AST_FLAG_END_DTMF_ONLY); 00208 ast_channel_unlock(chan); 00209 00210 AST_LIST_LOCK(&aslist); 00211 00212 if (AST_LIST_EMPTY(&aslist) && asthread != AST_PTHREADT_NULL) { 00213 ast_cond_signal(&as_cond); 00214 } 00215 00216 AST_LIST_INSERT_HEAD(&aslist, as, list); 00217 00218 if (asthread == AST_PTHREADT_NULL) { /* need start the thread */ 00219 if (ast_pthread_create_background(&asthread, NULL, autoservice_run, NULL)) { 00220 ast_log(LOG_WARNING, "Unable to create autoservice thread :(\n"); 00221 /* There will only be a single member in the list at this point, 00222 the one we just added. */ 00223 AST_LIST_REMOVE(&aslist, as, list); 00224 free(as); 00225 asthread = AST_PTHREADT_NULL; 00226 res = -1; 00227 } else { 00228 pthread_kill(asthread, SIGURG); 00229 } 00230 } 00231 00232 AST_LIST_UNLOCK(&aslist); 00233 00234 return res; 00235 }
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 237 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(), realtimefield_read(), senddtmf_exec(), shell_helper(), sla_station_exec(), smdi_msg_retrieve_read(), srv_datastore_setup(), system_exec_helper(), and trylock_read().
00238 { 00239 int res = -1; 00240 struct asent *as, *removed = NULL; 00241 struct ast_frame *f; 00242 int chan_list_state; 00243 00244 AST_LIST_LOCK(&aslist); 00245 00246 /* Save the autoservice channel list state. We _must_ verify that the channel 00247 * list has been rebuilt before we return. Because, after we return, the channel 00248 * could get destroyed and we don't want our poor autoservice thread to step on 00249 * it after its gone! */ 00250 chan_list_state = as_chan_list_state; 00251 00252 /* Find the entry, but do not free it because it still can be in the 00253 autoservice thread array */ 00254 AST_LIST_TRAVERSE_SAFE_BEGIN(&aslist, as, list) { 00255 if (as->chan == chan) { 00256 as->use_count--; 00257 if (as->use_count < 1) { 00258 AST_LIST_REMOVE_CURRENT(list); 00259 removed = as; 00260 } 00261 break; 00262 } 00263 } 00264 AST_LIST_TRAVERSE_SAFE_END; 00265 00266 if (removed && asthread != AST_PTHREADT_NULL) { 00267 pthread_kill(asthread, SIGURG); 00268 } 00269 00270 AST_LIST_UNLOCK(&aslist); 00271 00272 if (!removed) { 00273 return 0; 00274 } 00275 00276 /* Wait while autoservice thread rebuilds its list. */ 00277 while (chan_list_state == as_chan_list_state) { 00278 usleep(1000); 00279 } 00280 00281 /* Now autoservice thread should have no references to our entry 00282 and we can safely destroy it */ 00283 00284 if (!chan->_softhangup) { 00285 res = 0; 00286 } 00287 00288 if (!as->orig_end_dtmf_flag) { 00289 ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY); 00290 } 00291 00292 ast_channel_lock(chan); 00293 while ((f = AST_LIST_REMOVE_HEAD(&as->deferred_frames, frame_list))) { 00294 if (!((1 << f->frametype) & as->ignore_frame_types)) { 00295 ast_queue_frame_head(chan, f); 00296 } 00297 ast_frfree(f); 00298 } 00299 ast_channel_unlock(chan); 00300 00301 free(as); 00302 00303 return res; 00304 }
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 827 of file channel.c.
References ao2_callback, ast_channel_softhangup_cb(), channels, OBJ_MULTIPLE, and OBJ_NODATA.
Referenced by can_safely_quit().
00828 { 00829 shutting_down = 1; 00830 00831 if (hangup) { 00832 ao2_callback(channels, OBJ_NODATA | OBJ_MULTIPLE, ast_channel_softhangup_cb, NULL); 00833 } 00834 }
Pick the best audio codec.
Pick the best codec Choose the best codec... Uhhh... Yah.
Okay, ulaw is used by all telephony equipment, so start with it
Unless of course, you're a silly European, so then prefer ALAW
G.722 is better then all below, but not as common as the above... so give ulaw and alaw priority
Okay, well, signed linear is easy to translate into other stuff
G.726 is standard ADPCM, in RFC3551 packing order
G.726 is standard ADPCM, in AAL2 packing order
ADPCM has great sound quality and is still pretty easy to translate
Okay, we're down to vocoders now, so pick GSM because it's small and easier to translate and sounds pretty good
iLBC is not too bad
Speex is free, but computationally more expensive than GSM
Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough to use it
G.729a is faster than 723 and slightly less expensive
Down to G.723.1 which is proprietary but at least designed for voice
Definition at line 1051 of file channel.c.
References ARRAY_LEN, AST_FORMAT_ADPCM, AST_FORMAT_ALAW, AST_FORMAT_AUDIO_MASK, AST_FORMAT_G719, AST_FORMAT_G722, AST_FORMAT_G723_1, AST_FORMAT_G726, AST_FORMAT_G726_AAL2, AST_FORMAT_G729A, AST_FORMAT_GSM, AST_FORMAT_ILBC, AST_FORMAT_LPC10, AST_FORMAT_SIREN14, AST_FORMAT_SIREN7, AST_FORMAT_SLINEAR, AST_FORMAT_SLINEAR16, AST_FORMAT_SPEEX, AST_FORMAT_SPEEX16, AST_FORMAT_TESTLAW, AST_FORMAT_ULAW, ast_getformatname_multiple(), ast_log(), LOG_WARNING, and prefs.
Referenced by __oh323_new(), agent_call(), ast_codec_choose(), ast_iax2_new(), ast_speech_new(), bridge_make_compatible(), builtin_atxfer(), echo_exec(), findmeexec(), gtalk_new(), handle_open_receive_channel_ack_message(), iax2_request(), jingle_new(), local_new(), login_exec(), mgcp_new(), multicast_rtp_request(), set_format(), sip_new(), skinny_new(), skinny_set_rtp_peer(), socket_process(), start_rtp(), transmit_connect(), and unistim_new().
01052 { 01053 /* This just our opinion, expressed in code. We are asked to choose 01054 the best codec to use, given no information */ 01055 int x; 01056 static const format_t prefs[] = 01057 { 01058 /*! Okay, ulaw is used by all telephony equipment, so start with it */ 01059 AST_FORMAT_ULAW, 01060 /*! Unless of course, you're a silly European, so then prefer ALAW */ 01061 AST_FORMAT_ALAW, 01062 AST_FORMAT_G719, 01063 AST_FORMAT_SIREN14, 01064 AST_FORMAT_SIREN7, 01065 AST_FORMAT_TESTLAW, 01066 /*! G.722 is better then all below, but not as common as the above... so give ulaw and alaw priority */ 01067 AST_FORMAT_G722, 01068 /*! Okay, well, signed linear is easy to translate into other stuff */ 01069 AST_FORMAT_SLINEAR16, 01070 AST_FORMAT_SLINEAR, 01071 /*! G.726 is standard ADPCM, in RFC3551 packing order */ 01072 AST_FORMAT_G726, 01073 /*! G.726 is standard ADPCM, in AAL2 packing order */ 01074 AST_FORMAT_G726_AAL2, 01075 /*! ADPCM has great sound quality and is still pretty easy to translate */ 01076 AST_FORMAT_ADPCM, 01077 /*! Okay, we're down to vocoders now, so pick GSM because it's small and easier to 01078 translate and sounds pretty good */ 01079 AST_FORMAT_GSM, 01080 /*! iLBC is not too bad */ 01081 AST_FORMAT_ILBC, 01082 /*! Speex is free, but computationally more expensive than GSM */ 01083 AST_FORMAT_SPEEX16, 01084 AST_FORMAT_SPEEX, 01085 /*! Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough 01086 to use it */ 01087 AST_FORMAT_LPC10, 01088 /*! G.729a is faster than 723 and slightly less expensive */ 01089 AST_FORMAT_G729A, 01090 /*! Down to G.723.1 which is proprietary but at least designed for voice */ 01091 AST_FORMAT_G723_1, 01092 }; 01093 char buf[512]; 01094 01095 /* Strip out video */ 01096 fmts &= AST_FORMAT_AUDIO_MASK; 01097 01098 /* Find the first preferred codec in the format given */ 01099 for (x = 0; x < ARRAY_LEN(prefs); x++) { 01100 if (fmts & prefs[x]) 01101 return prefs[x]; 01102 } 01103 01104 ast_log(LOG_WARNING, "Don't know any of %s formats\n", ast_getformatname_multiple(buf, sizeof(buf), fmts)); 01105 01106 return 0; 01107 }
struct ast_channel* ast_bridged_channel | ( | struct ast_channel * | chan | ) |
Find bridged channel.
chan | Current channel |
Definition at line 6994 of file channel.c.
References ast_channel::_bridge, ast_channel_tech::bridged_channel, chanlist::chan, and ast_channel::tech.
Referenced by __analog_handle_event(), __analog_ss_thread(), __ast_channel_masquerade(), __ast_read(), __dahdi_exception(), _skinny_show_lines(), action_agents(), action_coreshowchannels(), agents_data_provider_get(), agents_show(), agents_show_online(), analog_attempt_transfer(), analog_exception(), analog_hangup(), analog_ss_thread(), ast_bridge_call(), ast_cel_report_event(), ast_channel_data_add_structure(), ast_channel_set_linkgroup(), ast_do_masquerade(), ast_rtp_instance_set_stats_vars(), ast_set_hangupsource(), ast_var_channel_bridge(), ast_var_channels_table(), attempt_transfer(), cb_events(), channel_spy(), check_bridge(), common_exec(), console_transfer(), create_jb(), dahdi_handle_event(), dahdi_hangup(), export_aoc_vars(), func_channel_read(), get_refer_info(), handle_chanlist(), handle_hd_hf(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_refer(), handle_showchan(), handle_soft_key_event_message(), handle_stimulus_message(), key_call(), key_dial_page(), local_attended_transfer(), local_queryoption(), mgcp_hangup(), mgcp_ss(), misdn_attempt_transfer(), mixmonitor_thread(), my_get_sigpvt_bridged_channel(), park_call_full(), schedule_delivery(), serialize_showchan(), sig_pri_attempt_transfer(), sip_get_rtp_peer(), sip_get_trtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), sip_hangup(), sip_set_rtp_peer(), skinny_transfer(), socket_process(), start_spying(), startmon(), TransferCallStep1(), and unistim_hangup().
06995 { 06996 struct ast_channel *bridged; 06997 bridged = chan->_bridge; 06998 if (bridged && bridged->tech->bridged_channel) 06999 bridged = bridged->tech->bridged_channel(chan, bridged); 07000 return bridged; 07001 }
int ast_call | ( | struct ast_channel * | chan, | |
char * | addr, | |||
int | timeout | |||
) |
Make a call.
chan | which channel to make the call on | |
addr | destination of the call (Should be treated as const char *) | |
timeout | time to wait on for connect |
Definition at line 5645 of file channel.c.
References AST_CDR_FLAG_DIALED, ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, ast_set_flag, ast_test_flag, ast_channel_tech::call, ast_channel::cdr, chanlist::chan, and ast_channel::tech.
Referenced by __ast_request_and_dial(), ast_call_forward(), begin_dial_channel(), dial_exec_full(), dial_transfer(), do_forward(), do_idle_thread(), feature_request_and_dial(), findmeexec(), play_sound_file(), and ring_entry().
05646 { 05647 /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 05648 If the remote end does not answer within the timeout, then do NOT hang up, but 05649 return anyway. */ 05650 int res = -1; 05651 /* Stop if we're a zombie or need a soft hangup */ 05652 ast_channel_lock(chan); 05653 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) { 05654 if (chan->cdr) { 05655 ast_set_flag(chan->cdr, AST_CDR_FLAG_DIALED); 05656 } 05657 if (chan->tech->call) 05658 res = chan->tech->call(chan, addr, timeout); 05659 ast_set_flag(chan, AST_FLAG_OUTGOING); 05660 } 05661 ast_channel_unlock(chan); 05662 return res; 05663 }
struct ast_channel* ast_call_forward | ( | struct ast_channel * | caller, | |
struct ast_channel * | orig, | |||
int * | timeout, | |||
format_t | format, | |||
struct outgoing_helper * | oh, | |||
int * | outstate | |||
) |
Forwards a call to a new channel specified by the original channel's call_forward str. If possible, the new forwarded channel is created and returned while the original one is terminated.
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 5271 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().
05272 { 05273 char tmpchan[256]; 05274 struct ast_channel *new_chan = NULL; 05275 char *data, *type; 05276 int cause = 0; 05277 int res; 05278 05279 /* gather data and request the new forward channel */ 05280 ast_copy_string(tmpchan, orig->call_forward, sizeof(tmpchan)); 05281 if ((data = strchr(tmpchan, '/'))) { 05282 *data++ = '\0'; 05283 type = tmpchan; 05284 } else { 05285 const char *forward_context; 05286 ast_channel_lock(orig); 05287 forward_context = pbx_builtin_getvar_helper(orig, "FORWARD_CONTEXT"); 05288 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", orig->call_forward, S_OR(forward_context, orig->context)); 05289 ast_channel_unlock(orig); 05290 data = tmpchan; 05291 type = "Local"; 05292 } 05293 if (!(new_chan = ast_request(type, format, orig, data, &cause))) { 05294 ast_log(LOG_NOTICE, "Unable to create channel for call forward to '%s/%s' (cause = %d)\n", type, data, cause); 05295 handle_cause(cause, outstate); 05296 ast_hangup(orig); 05297 return NULL; 05298 } 05299 05300 /* Copy/inherit important information into new channel */ 05301 if (oh) { 05302 if (oh->vars) { 05303 ast_set_variables(new_chan, oh->vars); 05304 } 05305 if (oh->parent_channel) { 05306 call_forward_inherit(new_chan, oh->parent_channel, orig); 05307 } 05308 if (oh->account) { 05309 ast_channel_lock(new_chan); 05310 ast_cdr_setaccount(new_chan, oh->account); 05311 ast_channel_unlock(new_chan); 05312 } 05313 } else if (caller) { /* no outgoing helper so use caller if avaliable */ 05314 call_forward_inherit(new_chan, caller, orig); 05315 } 05316 05317 ast_channel_lock_both(orig, new_chan); 05318 ast_copy_flags(new_chan->cdr, orig->cdr, AST_CDR_FLAG_ORIGINATED); 05319 ast_string_field_set(new_chan, accountcode, orig->accountcode); 05320 ast_party_connected_line_copy(&new_chan->connected, &orig->connected); 05321 ast_party_redirecting_copy(&new_chan->redirecting, &orig->redirecting); 05322 ast_channel_unlock(new_chan); 05323 ast_channel_unlock(orig); 05324 05325 /* call new channel */ 05326 res = ast_call(new_chan, data, 0); 05327 if (timeout) { 05328 *timeout = res; 05329 } 05330 if (res) { 05331 ast_log(LOG_NOTICE, "Unable to call forward to channel %s/%s\n", type, (char *)data); 05332 ast_hangup(orig); 05333 ast_hangup(new_chan); 05334 return NULL; 05335 } 05336 ast_hangup(orig); 05337 05338 return new_chan; 05339 }
void ast_cancel_shutdown | ( | void | ) |
Cancel a shutdown in progress.
Cancels an existing shutdown and returns to normal operation
Definition at line 848 of file channel.c.
Referenced by handle_abort_shutdown().
00849 { 00850 shutting_down = 0; 00851 }
const char* ast_cause2str | ( | int | state | ) |
Gives the string form of a given cause code.
state | cause to get the description of |
Definition at line 969 of file channel.c.
References ARRAY_LEN, and causes.
Referenced by __transmit_response(), ast_channel_data_add_structure(), ast_do_masquerade(), ast_hangup(), dial_exec_full(), findmeexec(), sip_hangup(), and transmit_request_with_auth().
00970 { 00971 int x; 00972 00973 for (x = 0; x < ARRAY_LEN(causes); x++) { 00974 if (causes[x].cause == cause) 00975 return causes[x].desc; 00976 } 00977 00978 return "Unknown"; 00979 }
void ast_change_name | ( | struct ast_channel * | chan, | |
const char * | newname | |||
) |
Change channel name.
chan | the channel to change the name of | |
newname | the name to change to |
Definition at line 6113 of file channel.c.
References __ast_change_name_nolink(), ao2_link, ao2_lock, ao2_unlink, ao2_unlock, ast_channel_lock, ast_channel_unlock, chanlist::chan, and channels.
Referenced by update_name().
06114 { 06115 /* We must re-link, as the hash value will change here. */ 06116 ao2_lock(channels); 06117 ast_channel_lock(chan); 06118 ao2_unlink(channels, chan); 06119 __ast_change_name_nolink(chan, newname); 06120 ao2_link(channels, chan); 06121 ast_channel_unlock(chan); 06122 ao2_unlock(channels); 06123 }
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 7337 of file channel.c.
References ast_channel::_bridge, ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_RETRY, ast_channel_clear_softhangup(), ast_channel_make_compatible(), ast_check_hangup(), ast_check_hangup_locked(), ast_clear_flag, AST_CONTROL_SRCUPDATE, ast_debug, AST_FEATURE_PLAY_WARNING, AST_FEATURE_WARNING_ACTIVE, AST_FLAG_END_DTMF_ONLY, AST_FLAG_NBRIDGE, AST_FLAG_ZOMBIE, ast_framehook_list_is_empty(), ast_generic_bridge(), ast_indicate(), ast_log(), ast_manager_event_multichan, ast_samp2tv(), ast_set_flag, ast_set_owners_and_peers(), AST_SOFTHANGUP_UNBRIDGE, ast_test_flag, ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), ast_verb, ast_channel::audiohooks, ast_channel_tech::bridge, bridge_play_sounds(), bridge_playfile(), ast_channel::caller, config, EVENT_FLAG_CALL, ast_channel::framehooks, ast_channel::generator, ast_party_caller::id, LOG_WARNING, manager_bridge_event(), ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::name, ast_channel::nativeformats, ast_party_id::number, ast_channel::readformat, S_COR, ast_channel_tech::send_digit_begin, ast_party_number::str, ast_channel::tech, ast_channel::uniqueid, update_bridge_vars(), ast_party_number::valid, and ast_channel::writeformat.
Referenced by ast_bridge_call().
07339 { 07340 struct ast_channel *chans[2] = { c0, c1 }; 07341 enum ast_bridge_result res = AST_BRIDGE_COMPLETE; 07342 format_t o0nativeformats; 07343 format_t o1nativeformats; 07344 long time_left_ms=0; 07345 char caller_warning = 0; 07346 char callee_warning = 0; 07347 07348 *fo = NULL; 07349 07350 if (c0->_bridge) { 07351 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 07352 c0->name, c0->_bridge->name); 07353 return -1; 07354 } 07355 if (c1->_bridge) { 07356 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 07357 c1->name, c1->_bridge->name); 07358 return -1; 07359 } 07360 07361 /* Stop if we're a zombie or need a soft hangup */ 07362 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 07363 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) 07364 return -1; 07365 07366 caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING); 07367 callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING); 07368 07369 if (ast_tvzero(config->start_time)) { 07370 config->start_time = ast_tvnow(); 07371 if (config->start_sound) { 07372 if (caller_warning) { 07373 bridge_playfile(c0, c1, config->start_sound, config->timelimit / 1000); 07374 } 07375 if (callee_warning) { 07376 bridge_playfile(c1, c0, config->start_sound, config->timelimit / 1000); 07377 } 07378 } 07379 } 07380 07381 /* Keep track of bridge */ 07382 c0->_bridge = c1; 07383 c1->_bridge = c0; 07384 07385 ast_set_owners_and_peers(c0, c1); 07386 07387 o0nativeformats = c0->nativeformats; 07388 o1nativeformats = c1->nativeformats; 07389 07390 if (config->feature_timer && !ast_tvzero(config->nexteventts)) { 07391 config->nexteventts = ast_tvadd(config->feature_start_time, ast_samp2tv(config->feature_timer, 1000)); 07392 } else if (config->timelimit) { 07393 time_left_ms = config->timelimit - ast_tvdiff_ms(ast_tvnow(), config->start_time); 07394 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 07395 if ((caller_warning || callee_warning) && config->play_warning) { 07396 long next_warn = config->play_warning; 07397 if (time_left_ms < config->play_warning && config->warning_freq > 0) { 07398 /* At least one warning was played, which means we are returning after feature */ 07399 long warns_passed = (config->play_warning - time_left_ms) / config->warning_freq; 07400 /* It is 'warns_passed * warning_freq' NOT '(warns_passed + 1) * warning_freq', 07401 because nexteventts will be updated once again in the 'if (!to)' block */ 07402 next_warn = config->play_warning - warns_passed * config->warning_freq; 07403 } 07404 config->nexteventts = ast_tvsub(config->nexteventts, ast_samp2tv(next_warn, 1000)); 07405 } 07406 } else { 07407 config->nexteventts.tv_sec = 0; 07408 config->nexteventts.tv_usec = 0; 07409 } 07410 07411 if (!c0->tech->send_digit_begin) 07412 ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY); 07413 if (!c1->tech->send_digit_begin) 07414 ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY); 07415 manager_bridge_event(1, 1, c0, c1); 07416 07417 /* Before we enter in and bridge these two together tell them both the source of audio has changed */ 07418 ast_indicate(c0, AST_CONTROL_SRCUPDATE); 07419 ast_indicate(c1, AST_CONTROL_SRCUPDATE); 07420 07421 for (/* ever */;;) { 07422 struct timeval now = { 0, }; 07423 int to; 07424 07425 to = -1; 07426 07427 if (!ast_tvzero(config->nexteventts)) { 07428 now = ast_tvnow(); 07429 to = ast_tvdiff_ms(config->nexteventts, now); 07430 if (to <= 0) { 07431 if (!config->timelimit) { 07432 res = AST_BRIDGE_COMPLETE; 07433 break; 07434 } 07435 to = 0; 07436 } 07437 } 07438 07439 if (config->timelimit) { 07440 time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time); 07441 if (time_left_ms < to) 07442 to = time_left_ms; 07443 07444 if (time_left_ms <= 0) { 07445 if (caller_warning && config->end_sound) 07446 bridge_playfile(c0, c1, config->end_sound, 0); 07447 if (callee_warning && config->end_sound) 07448 bridge_playfile(c1, c0, config->end_sound, 0); 07449 *fo = NULL; 07450 res = 0; 07451 break; 07452 } 07453 07454 if (!to) { 07455 if (time_left_ms >= 5000 && config->warning_sound && config->play_warning && ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) { 07456 int t = (time_left_ms + 500) / 1000; /* round to nearest second */ 07457 if (caller_warning) 07458 bridge_playfile(c0, c1, config->warning_sound, t); 07459 if (callee_warning) 07460 bridge_playfile(c1, c0, config->warning_sound, t); 07461 } 07462 07463 if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000))) { 07464 config->nexteventts = ast_tvadd(config->nexteventts, ast_samp2tv(config->warning_freq, 1000)); 07465 } else { 07466 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 07467 } 07468 } 07469 ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE); 07470 } 07471 07472 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */ 07473 if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) { 07474 ast_channel_clear_softhangup(c0, AST_SOFTHANGUP_UNBRIDGE); 07475 } 07476 if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) { 07477 ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE); 07478 } 07479 c0->_bridge = c1; 07480 c1->_bridge = c0; 07481 ast_debug(1, "Unbridge signal received. Ending native bridge.\n"); 07482 continue; 07483 } 07484 07485 /* Stop if we're a zombie or need a soft hangup */ 07486 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 07487 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) { 07488 *fo = NULL; 07489 res = 0; 07490 ast_debug(1, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n", 07491 c0->name, c1->name, 07492 ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No", 07493 ast_check_hangup(c0) ? "Yes" : "No", 07494 ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No", 07495 ast_check_hangup(c1) ? "Yes" : "No"); 07496 break; 07497 } 07498 07499 update_bridge_vars(c0, c1); 07500 07501 bridge_play_sounds(c0, c1); 07502 07503 if (c0->tech->bridge && 07504 /* if < 1 ms remains use generic bridging for accurate timing */ 07505 (!config->timelimit || to > 1000 || to == 0) && 07506 (c0->tech->bridge == c1->tech->bridge) && 07507 !c0->monitor && !c1->monitor && 07508 !c0->audiohooks && !c1->audiohooks && 07509 ast_framehook_list_is_empty(c0->framehooks) && ast_framehook_list_is_empty(c1->framehooks) && 07510 !c0->masq && !c0->masqr && !c1->masq && !c1->masqr) { 07511 int timeoutms = to - 1000 > 0 ? to - 1000 : to; 07512 /* Looks like they share a bridge method and nothing else is in the way */ 07513 ast_set_flag(c0, AST_FLAG_NBRIDGE); 07514 ast_set_flag(c1, AST_FLAG_NBRIDGE); 07515 if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, timeoutms)) == AST_BRIDGE_COMPLETE) { 07516 ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans, 07517 "Channel1: %s\r\n" 07518 "Channel2: %s\r\n" 07519 "Uniqueid1: %s\r\n" 07520 "Uniqueid2: %s\r\n" 07521 "CallerID1: %s\r\n" 07522 "CallerID2: %s\r\n", 07523 c0->name, c1->name, 07524 c0->uniqueid, c1->uniqueid, 07525 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"), 07526 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>")); 07527 07528 ast_debug(1, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name); 07529 07530 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 07531 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 07532 07533 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */ 07534 continue; 07535 } 07536 07537 c0->_bridge = NULL; 07538 c1->_bridge = NULL; 07539 return res; 07540 } else { 07541 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 07542 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 07543 } 07544 switch (res) { 07545 case AST_BRIDGE_RETRY: 07546 if (config->play_warning) { 07547 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE); 07548 } 07549 continue; 07550 default: 07551 ast_verb(3, "Native bridging %s and %s ended\n", c0->name, c1->name); 07552 /* fallthrough */ 07553 case AST_BRIDGE_FAILED_NOWARN: 07554 break; 07555 } 07556 } 07557 07558 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) || 07559 (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) && 07560 !(c0->generator || c1->generator)) { 07561 if (ast_channel_make_compatible(c0, c1)) { 07562 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name); 07563 manager_bridge_event(0, 1, c0, c1); 07564 return AST_BRIDGE_FAILED; 07565 } 07566 o0nativeformats = c0->nativeformats; 07567 o1nativeformats = c1->nativeformats; 07568 } 07569 07570 update_bridge_vars(c0, c1); 07571 07572 res = ast_generic_bridge(c0, c1, config, fo, rc); 07573 if (res != AST_BRIDGE_RETRY) { 07574 break; 07575 } else if (config->feature_timer) { 07576 /* feature timer expired but has not been updated, sending to ast_bridge_call to do so */ 07577 break; 07578 } 07579 } 07580 07581 ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY); 07582 ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY); 07583 07584 /* Now that we have broken the bridge the source will change yet again */ 07585 ast_indicate(c0, AST_CONTROL_SRCUPDATE); 07586 ast_indicate(c1, AST_CONTROL_SRCUPDATE); 07587 07588 c0->_bridge = NULL; 07589 c1->_bridge = NULL; 07590 07591 ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans, 07592 "Channel1: %s\r\n" 07593 "Channel2: %s\r\n" 07594 "Uniqueid1: %s\r\n" 07595 "Uniqueid2: %s\r\n" 07596 "CallerID1: %s\r\n" 07597 "CallerID2: %s\r\n", 07598 c0->name, c1->name, 07599 c0->uniqueid, c1->uniqueid, 07600 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"), 07601 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>")); 07602 ast_debug(1, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name); 07603 07604 return res; 07605 }
struct ast_channel* ast_channel_callback | ( | ao2_callback_data_fn * | cb_fn, | |
void * | arg, | |||
void * | data, | |||
int | ao2_flags | |||
) |
Call a function with every active channel.
This function executes a callback one time for each active channel on the system. The channel is provided as an argument to the function.
Definition at line 1606 of file channel.c.
References ao2_callback_data, and channels.
Referenced by ast_pickup_call(), handle_core_set_debug_channel(), my_ast_get_channel_by_name_locked(), pickup_by_group(), pickup_by_mark(), pickup_by_part(), and state_notify_build_xml().
01608 { 01609 return ao2_callback_data(channels, ao2_flags, cb_fn, arg, data); 01610 }
int ast_channel_cc_params_init | ( | struct ast_channel * | chan, | |
const struct ast_cc_config_params * | base_params | |||
) |
Set up datastore with CCSS parameters for a channel.
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 9509 of file channel.c.
References ast_cc_config_params_destroy(), ast_cc_config_params_init, ast_cc_copy_config_params(), ast_channel_datastore_add(), ast_datastore_alloc, cc_channel_datastore_info, and ast_datastore::data.
Referenced by ast_channel_get_cc_config_params(), dahdi_new(), local_call(), local_request(), and sip_new().
09511 { 09512 struct ast_cc_config_params *cc_params; 09513 struct ast_datastore *cc_datastore; 09514 09515 if (!(cc_params = ast_cc_config_params_init())) { 09516 return -1; 09517 } 09518 09519 if (!(cc_datastore = ast_datastore_alloc(&cc_channel_datastore_info, NULL))) { 09520 ast_cc_config_params_destroy(cc_params); 09521 return -1; 09522 } 09523 09524 if (base_params) { 09525 ast_cc_copy_config_params(cc_params, base_params); 09526 } 09527 cc_datastore->data = cc_params; 09528 ast_channel_datastore_add(chan, cc_datastore); 09529 return 0; 09530 }
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 2674 of file channel.c.
References ast_channel::_softhangup, ast_channel_lock, ast_channel_unlock, AST_CONTROL_END_OF_Q, AST_FRAME_CONTROL, ast_frfree, AST_LIST_LAST, AST_LIST_REMOVE, chanlist::chan, ast_frame::frametype, ast_frame_subclass::integer, ast_channel::readq, and ast_frame::subclass.
Referenced by __ast_pbx_run(), ast_channel_bridge(), check_goto_on_transfer(), and collect_digits().
02675 { 02676 ast_channel_lock(chan); 02677 02678 chan->_softhangup &= ~flag; 02679 02680 if (!chan->_softhangup) { 02681 struct ast_frame *fr; 02682 02683 /* If we have completely cleared the softhangup flag, 02684 * then we need to fully abort the hangup process. This requires 02685 * pulling the END_OF_Q frame out of the channel frame queue if it 02686 * still happens to be there. */ 02687 02688 fr = AST_LIST_LAST(&chan->readq); 02689 if (fr && fr->frametype == AST_FRAME_CONTROL && 02690 fr->subclass.integer == AST_CONTROL_END_OF_Q) { 02691 AST_LIST_REMOVE(&chan->readq, fr, frame_list); 02692 ast_frfree(fr); 02693 } 02694 } 02695 02696 ast_channel_unlock(chan); 02697 }
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 889 of file channel.c.
References ast_channel_cmpwhentohangup_tv(), and chanlist::chan.
00890 { 00891 struct timeval when = { offset, }; 00892 return ast_channel_cmpwhentohangup_tv(chan, when); 00893 }
int ast_channel_cmpwhentohangup_tv | ( | struct ast_channel * | chan, | |
struct timeval | offset | |||
) |
Compare a offset with the settings of when to hang a channel up.
chan | channel on which to check for hangup | |
offset | offset in seconds and microseconds from current time |
Definition at line 874 of file channel.c.
References ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), chanlist::chan, and ast_channel::whentohangup.
Referenced by ast_channel_cmpwhentohangup().
00875 { 00876 struct timeval whentohangup; 00877 00878 if (ast_tvzero(chan->whentohangup)) 00879 return ast_tvzero(offset) ? 0 : -1; 00880 00881 if (ast_tvzero(offset)) 00882 return 1; 00883 00884 whentohangup = ast_tvadd(offset, ast_tvnow()); 00885 00886 return ast_tvdiff_ms(whentohangup, chan->whentohangup); 00887 }
int ast_channel_connected_line_macro | ( | struct ast_channel * | autoservice_chan, | |
struct ast_channel * | macro_chan, | |||
const void * | connected_info, | |||
int | caller, | |||
int | frame | |||
) |
Run a connected line interception macro and update a channel's connected line information.
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 9396 of file channel.c.
References ast_app_run_macro(), ast_channel_lock, ast_channel_unlock, ast_channel_update_connected_line(), ast_connected_line_parse_data(), ast_party_connected_line_copy(), ast_party_connected_line_free(), ast_party_connected_line_init(), ast_strdupa, ast_strlen_zero(), 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().
09397 { 09398 const char *macro; 09399 const char *macro_args; 09400 int retval; 09401 09402 ast_channel_lock(macro_chan); 09403 macro = pbx_builtin_getvar_helper(macro_chan, is_caller 09404 ? "CONNECTED_LINE_CALLER_SEND_MACRO" : "CONNECTED_LINE_CALLEE_SEND_MACRO"); 09405 macro = ast_strdupa(S_OR(macro, "")); 09406 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller 09407 ? "CONNECTED_LINE_CALLER_SEND_MACRO_ARGS" : "CONNECTED_LINE_CALLEE_SEND_MACRO_ARGS"); 09408 macro_args = ast_strdupa(S_OR(macro_args, "")); 09409 09410 if (ast_strlen_zero(macro)) { 09411 ast_channel_unlock(macro_chan); 09412 return -1; 09413 } 09414 09415 if (is_frame) { 09416 const struct ast_frame *frame = connected_info; 09417 09418 ast_connected_line_parse_data(frame->data.ptr, frame->datalen, ¯o_chan->connected); 09419 } else { 09420 const struct ast_party_connected_line *connected = connected_info; 09421 09422 ast_party_connected_line_copy(¯o_chan->connected, connected); 09423 } 09424 ast_channel_unlock(macro_chan); 09425 09426 retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args); 09427 if (!retval) { 09428 struct ast_party_connected_line saved_connected; 09429 09430 ast_party_connected_line_init(&saved_connected); 09431 ast_channel_lock(macro_chan); 09432 ast_party_connected_line_copy(&saved_connected, ¯o_chan->connected); 09433 ast_channel_unlock(macro_chan); 09434 ast_channel_update_connected_line(macro_chan, &saved_connected, NULL); 09435 ast_party_connected_line_free(&saved_connected); 09436 } 09437 09438 return retval; 09439 }
int ast_channel_data_add_structure | ( | struct ast_data * | tree, | |
struct ast_channel * | chan, | |||
int | add_bridged | |||
) |
Insert into an astdata tree, the channel structure.
[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 347 of file channel.c.
References ast_channel::_softhangup, ast_channel::_state, ast_channel::amaflags, ast_bridged_channel(), ast_cause2str(), ast_cdr_data_add_structure(), ast_cdr_flags2str(), ast_channel_data_add_structure(), ast_data_add_bool(), ast_data_add_codecs(), ast_data_add_int(), ast_data_add_node(), ast_data_add_str(), ast_data_add_structure, ast_data_add_uint(), AST_SOFTHANGUP_APPUNLOAD, AST_SOFTHANGUP_ASYNCGOTO, AST_SOFTHANGUP_DEV, AST_SOFTHANGUP_EXPLICIT, AST_SOFTHANGUP_SHUTDOWN, AST_SOFTHANGUP_TIMEOUT, AST_SOFTHANGUP_UNBRIDGE, ast_state2str(), ast_tone_zone_data_add_structure(), ast_transfercapability2str(), ast_channel::cdr, chanlist::chan, channel_data_add_flags(), ast_channel::hangupcause, ast_channel::nativeformats, ast_channel::oldwriteformat, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::transfercapability, ast_channel::whentohangup, ast_channel::writeformat, and ast_channel::zone.
Referenced by agents_data_provider_get(), ast_channel_data_add_structure(), data_channels_provider_handler(), queues_data_provider_get_helper(), and user_add_provider_cb().
00349 { 00350 struct ast_channel *bc; 00351 struct ast_data *data_bridged; 00352 struct ast_data *data_cdr; 00353 struct ast_data *data_flags; 00354 struct ast_data *data_zones; 00355 struct ast_data *enum_node; 00356 struct ast_data *data_softhangup; 00357 #if 0 /* XXX AstData: ast_callerid no longer exists. (Equivalent code not readily apparent.) */ 00358 struct ast_data *data_callerid; 00359 char value_str[100]; 00360 #endif 00361 00362 if (!tree) { 00363 return -1; 00364 } 00365 00366 ast_data_add_structure(ast_channel, tree, chan); 00367 00368 if (add_bridged) { 00369 bc = ast_bridged_channel(chan); 00370 if (bc) { 00371 data_bridged = ast_data_add_node(tree, "bridged"); 00372 if (!data_bridged) { 00373 return -1; 00374 } 00375 ast_channel_data_add_structure(data_bridged, bc, 0); 00376 } 00377 } 00378 00379 ast_data_add_codecs(tree, "oldwriteformat", chan->oldwriteformat); 00380 ast_data_add_codecs(tree, "nativeformats", chan->nativeformats); 00381 ast_data_add_codecs(tree, "readformat", chan->readformat); 00382 ast_data_add_codecs(tree, "writeformat", chan->writeformat); 00383 ast_data_add_codecs(tree, "rawreadformat", chan->rawreadformat); 00384 ast_data_add_codecs(tree, "rawwriteformat", chan->rawwriteformat); 00385 00386 /* state */ 00387 enum_node = ast_data_add_node(tree, "state"); 00388 if (!enum_node) { 00389 return -1; 00390 } 00391 ast_data_add_str(enum_node, "text", ast_state2str(chan->_state)); 00392 ast_data_add_int(enum_node, "value", chan->_state); 00393 00394 /* hangupcause */ 00395 enum_node = ast_data_add_node(tree, "hangupcause"); 00396 if (!enum_node) { 00397 return -1; 00398 } 00399 ast_data_add_str(enum_node, "text", ast_cause2str(chan->hangupcause)); 00400 ast_data_add_int(enum_node, "value", chan->hangupcause); 00401 00402 /* amaflags */ 00403 enum_node = ast_data_add_node(tree, "amaflags"); 00404 if (!enum_node) { 00405 return -1; 00406 } 00407 ast_data_add_str(enum_node, "text", ast_cdr_flags2str(chan->amaflags)); 00408 ast_data_add_int(enum_node, "value", chan->amaflags); 00409 00410 /* transfercapability */ 00411 enum_node = ast_data_add_node(tree, "transfercapability"); 00412 if (!enum_node) { 00413 return -1; 00414 } 00415 ast_data_add_str(enum_node, "text", ast_transfercapability2str(chan->transfercapability)); 00416 ast_data_add_int(enum_node, "value", chan->transfercapability); 00417 00418 /* _softphangup */ 00419 data_softhangup = ast_data_add_node(tree, "softhangup"); 00420 if (!data_softhangup) { 00421 return -1; 00422 } 00423 ast_data_add_bool(data_softhangup, "dev", chan->_softhangup & AST_SOFTHANGUP_DEV); 00424 ast_data_add_bool(data_softhangup, "asyncgoto", chan->_softhangup & AST_SOFTHANGUP_ASYNCGOTO); 00425 ast_data_add_bool(data_softhangup, "shutdown", chan->_softhangup & AST_SOFTHANGUP_SHUTDOWN); 00426 ast_data_add_bool(data_softhangup, "timeout", chan->_softhangup & AST_SOFTHANGUP_TIMEOUT); 00427 ast_data_add_bool(data_softhangup, "appunload", chan->_softhangup & AST_SOFTHANGUP_APPUNLOAD); 00428 ast_data_add_bool(data_softhangup, "explicit", chan->_softhangup & AST_SOFTHANGUP_EXPLICIT); 00429 ast_data_add_bool(data_softhangup, "unbridge", chan->_softhangup & AST_SOFTHANGUP_UNBRIDGE); 00430 00431 /* channel flags */ 00432 data_flags = ast_data_add_node(tree, "flags"); 00433 if (!data_flags) { 00434 return -1; 00435 } 00436 channel_data_add_flags(data_flags, chan); 00437 00438 ast_data_add_uint(tree, "timetohangup", chan->whentohangup.tv_sec); 00439 00440 #if 0 /* XXX AstData: ast_callerid no longer exists. (Equivalent code not readily apparent.) */ 00441 /* callerid */ 00442 data_callerid = ast_data_add_node(tree, "callerid"); 00443 if (!data_callerid) { 00444 return -1; 00445 } 00446 ast_data_add_structure(ast_callerid, data_callerid, &(chan->cid)); 00447 /* insert the callerid ton */ 00448 enum_node = ast_data_add_node(data_callerid, "cid_ton"); 00449 if (!enum_node) { 00450 return -1; 00451 } 00452 ast_data_add_int(enum_node, "value", chan->cid.cid_ton); 00453 snprintf(value_str, sizeof(value_str), "TON: %s/Plan: %s", 00454 party_number_ton2str(chan->cid.cid_ton), 00455 party_number_plan2str(chan->cid.cid_ton)); 00456 ast_data_add_str(enum_node, "text", value_str); 00457 #endif 00458 00459 /* tone zone */ 00460 if (chan->zone) { 00461 data_zones = ast_data_add_node(tree, "zone"); 00462 if (!data_zones) { 00463 return -1; 00464 } 00465 ast_tone_zone_data_add_structure(data_zones, chan->zone); 00466 } 00467 00468 /* insert cdr */ 00469 data_cdr = ast_data_add_node(tree, "cdr"); 00470 if (!data_cdr) { 00471 return -1; 00472 } 00473 00474 ast_cdr_data_add_structure(data_cdr, chan->cdr, 1); 00475 00476 return 0; 00477 }
int ast_channel_data_cmp_structure | ( | const struct ast_data_search * | tree, | |
struct ast_channel * | chan, | |||
const char * | structure_name | |||
) |
Compare to channel structures using the data api.
[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 479 of file channel.c.
References ast_data_search_cmp_structure, and chanlist::chan.
00481 { 00482 return ast_data_search_cmp_structure(tree, ast_channel, chan, structure_name); 00483 }
int ast_channel_datastore_add | ( | struct ast_channel * | chan, | |
struct ast_datastore * | datastore | |||
) |
Add a datastore to a channel.
0 | success | |
non-zero | failure |
Definition at line 2557 of file channel.c.
References AST_LIST_INSERT_HEAD, chanlist::chan, ast_channel::datastores, and ast_datastore::entry.
Referenced by __ast_channel_masquerade(), _macro_exec(), acf_curlopt_write(), acf_iaxvar_write(), add_features_datastore(), add_to_agi(), apply_plc(), ast_cel_fabricate_channel_from_event(), ast_channel_cc_params_init(), ast_do_pickup(), ast_iax2_new(), ast_setup_cc_recall_datastore(), audiohook_volume_get(), authenticate_reply(), calendar_query_exec(), cc_interfaces_datastore_init(), dial_exec_full(), do_notify(), dundi_query_read(), enable_jack_hook(), enum_query_read(), find_or_create_details(), find_transaction(), frame_trace_helper(), func_channel_write_real(), get_lock(), gosub_exec(), lua_get_state(), mute_add_audiohook(), pitchshift_helper(), raise_exception(), set_chan_app_data(), setup_inheritance_datastore(), setup_mixmonitor_ds(), setup_transfer_datastore(), shared_write(), smdi_msg_retrieve_read(), socket_process(), speech_create(), speex_write(), srv_datastore_setup(), and volume_write().
02558 { 02559 int res = 0; 02560 02561 AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry); 02562 02563 return res; 02564 }
struct ast_datastore* attribute_malloc ast_channel_datastore_alloc | ( | const struct ast_datastore_info * | info, | |
const char * | uid | |||
) |
Create a channel data store object.
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 |
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_datastore(), 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(), stackpeek_read(), stop_mixmonitor_exec(), try_calling(), unlock_read(), volume_callback(), and volume_write().
int ast_channel_datastore_free | ( | struct ast_datastore * | datastore | ) |
Free a channel data store object.
Definition at line 2535 of file channel.c.
References ast_datastore_free().
02536 { 02537 return ast_datastore_free(datastore); 02538 }
int ast_channel_datastore_inherit | ( | struct ast_channel * | from, | |
struct ast_channel * | to | |||
) |
Inherit datastores from a parent to a child.
Definition at line 2540 of file channel.c.
References ast_datastore_alloc, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_datastore::data, DATASTORE_INHERIT_FOREVER, ast_channel::datastores, ast_datastore_info::duplicate, ast_datastore::entry, ast_datastore::info, ast_datastore::inheritance, and ast_datastore::uid.
Referenced by __ast_request_and_dial(), begin_dial_channel(), call_forward_inherit(), dial_exec_full(), dial_transfer(), do_forward(), findmeexec(), local_call(), and ring_entry().
02541 { 02542 struct ast_datastore *datastore = NULL, *datastore2; 02543 02544 AST_LIST_TRAVERSE(&from->datastores, datastore, entry) { 02545 if (datastore->inheritance > 0) { 02546 datastore2 = ast_datastore_alloc(datastore->info, datastore->uid); 02547 if (datastore2) { 02548 datastore2->data = datastore->info->duplicate ? datastore->info->duplicate(datastore->data) : NULL; 02549 datastore2->inheritance = datastore->inheritance == DATASTORE_INHERIT_FOREVER ? DATASTORE_INHERIT_FOREVER : datastore->inheritance - 1; 02550 AST_LIST_INSERT_TAIL(&to->datastores, datastore2, entry); 02551 } 02552 } 02553 } 02554 return 0; 02555 }
int ast_channel_datastore_remove | ( | struct ast_channel * | chan, | |
struct ast_datastore * | datastore | |||
) |
Remove a datastore from a channel.
0 | success | |
non-zero | failure |
Definition at line 2566 of file channel.c.
References AST_LIST_REMOVE, chanlist::chan, ast_channel::datastores, and ast_datastore::entry.
Referenced by acf_fetch(), adjust_frame_for_plc(), ast_do_masquerade(), ast_do_pickup(), clear_dialed_interfaces(), dial_exec_full(), disable_jack_hook(), exec_odbcfinish(), frame_trace_helper(), lua_get_state(), queue_transfer_fixup(), speech_background(), speech_destroy(), speex_write(), srv_query_read(), and stop_mixmonitor_exec().
02567 { 02568 return AST_LIST_REMOVE(&chan->datastores, datastore, entry) ? 0 : -1; 02569 }
int ast_channel_defer_dtmf | ( | struct ast_channel * | chan | ) |
Defers DTMF so that you only read things like hangups and audio.
Definition at line 1588 of file channel.c.
References AST_FLAG_DEFER_DTMF, ast_set_flag, ast_test_flag, and chanlist::chan.
Referenced by find_cache().
01589 { 01590 int pre = 0; 01591 01592 if (chan) { 01593 pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF); 01594 ast_set_flag(chan, AST_FLAG_DEFER_DTMF); 01595 } 01596 return pre; 01597 }
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 7237 of file channel.c.
References ast_channel_tech::early_bridge, and ast_channel::tech.
Referenced by dial_exec_full().
07238 { 07239 /* Make sure we can early bridge, if not error out */ 07240 if (!c0->tech->early_bridge || (c1 && (!c1->tech->early_bridge || c0->tech->early_bridge != c1->tech->early_bridge))) 07241 return -1; 07242 07243 return c0->tech->early_bridge(c0, c1); 07244 }
struct ast_channel* ast_channel_get_by_exten | ( | const char * | exten, | |
const char * | context | |||
) |
Find a channel by extension and context.
a | channel that is at the specified extension and context | |
NULL | if no channel was found |
Definition at line 1785 of file channel.c.
References ast_channel_get_full().
01786 { 01787 return ast_channel_get_full(NULL, 0, exten, context); 01788 }
struct ast_channel* ast_channel_get_by_name | ( | const char * | name | ) |
Find a channel by name.
a | channel with the name specified by the argument | |
NULL | if no channel was found |
Definition at line 1775 of file channel.c.
References ast_channel_get_full().
Referenced by action_add_agi_cmd(), action_aocmessage(), action_atxfer(), action_getvar(), action_hangup(), action_redirect(), action_sendtext(), action_setvar(), action_status(), action_timeout(), ast_async_goto_by_name(), ast_bridge_call(), asyncgoto_exec(), change_monitor_action(), do_pause_or_unpause(), func_mchan_read(), func_mchan_write(), handle_channelstatus(), handle_cli_agi_add_cmd(), handle_core_set_debug_channel(), handle_getvariablefull(), handle_hangup(), handle_redirect(), handle_set_chanvar(), handle_show_chanvar(), handle_showchan(), handle_softhangup(), import_helper(), manager_mute_mixmonitor(), manager_mutestream(), manager_optimize_away(), manager_park(), manager_play_dtmf(), park_call_full(), pbx_builtin_importvar(), senddtmf_exec(), shared_read(), shared_write(), start_monitor_action(), and stop_monitor_action().
01776 { 01777 return ast_channel_get_full(name, 0, NULL, NULL); 01778 }
struct ast_channel* ast_channel_get_by_name_prefix | ( | const char * | name, | |
size_t | name_len | |||
) |
Find a channel by a name prefix.
a | channel with the name prefix specified by the arguments | |
NULL | if no channel was found |
Definition at line 1780 of file channel.c.
References ast_channel_get_full().
Referenced by action_aocmessage(), action_bridge(), ast_parse_device_state(), bridge_exec(), cc_generic_agent_stop_ringing(), common_exec(), handle_cli_mixmonitor(), shared_read(), and shared_write().
01781 { 01782 return ast_channel_get_full(name, name_len, NULL, NULL); 01783 }
int ast_channel_get_cc_agent_type | ( | struct ast_channel * | chan, | |
char * | agent_type, | |||
size_t | size | |||
) |
Find the appropriate CC agent type to use given a channel.
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 9571 of file channel.c.
References ast_channel_queryoption(), ast_copy_string(), AST_OPTION_CC_AGENT_TYPE, and ast_channel::name.
Referenced by find_agent_callbacks().
09572 { 09573 int len = size; 09574 char *slash; 09575 09576 if (!ast_channel_queryoption(chan, AST_OPTION_CC_AGENT_TYPE, agent_type, &len, 0)) { 09577 return 0; 09578 } 09579 09580 ast_copy_string(agent_type, chan->name, size); 09581 if ((slash = strchr(agent_type, '/'))) { 09582 *slash = '\0'; 09583 } 09584 return 0; 09585 }
struct ast_cc_config_params* ast_channel_get_cc_config_params | ( | struct ast_channel * | chan | ) |
Get the CCSS parameters from a channel.
chan | Channel to retrieve parameters from |
NULL | Failure | |
non-NULL | The parameters desired |
Definition at line 9532 of file channel.c.
References ast_assert, ast_channel_cc_params_init(), ast_channel_datastore_find(), cc_channel_datastore_info, and ast_datastore::data.
Referenced by acf_cc_read(), acf_cc_write(), analog_call(), ast_cc_call_failed(), ast_cc_call_init(), ast_queue_cc_frame(), cc_agent_init(), cc_core_init_instance(), find_agent_callbacks(), local_call(), local_request(), sig_pri_cc_available(), and sig_pri_cc_generic_check().
09533 { 09534 struct ast_datastore *cc_datastore; 09535 09536 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) { 09537 /* If we can't find the datastore, it almost definitely means that the channel type being 09538 * used has not had its driver modified to parse CC config parameters. The best action 09539 * to take here is to create the parameters on the spot with the defaults set. 09540 */ 09541 if (ast_channel_cc_params_init(chan, NULL)) { 09542 return NULL; 09543 } 09544 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) { 09545 /* Should be impossible */ 09546 return NULL; 09547 } 09548 } 09549 09550 ast_assert(cc_datastore->data != NULL); 09551 return cc_datastore->data; 09552 }
int ast_channel_get_device_name | ( | struct ast_channel * | chan, | |
char * | device_name, | |||
size_t | name_buffer_length | |||
) |
Get a device name given its channel structure.
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 9554 of file channel.c.
References ast_channel_queryoption(), ast_copy_string(), AST_OPTION_DEVICE_NAME, and ast_channel::name.
Referenced by ast_cc_call_failed(), ast_cc_is_recall(), ast_queue_cc_frame(), cc_core_init_instance(), cccancel_exec(), ccreq_exec(), dial_exec_full(), sig_pri_call(), sig_pri_cc_available(), sig_pri_cc_generic_check(), sip_call(), and sip_handle_cc().
09555 { 09556 int len = name_buffer_length; 09557 char *dash; 09558 if (!ast_channel_queryoption(chan, AST_OPTION_DEVICE_NAME, device_name, &len, 0)) { 09559 return 0; 09560 } 09561 09562 /* Dang. Do it the old-fashioned way */ 09563 ast_copy_string(device_name, chan->name, name_buffer_length); 09564 if ((dash = strrchr(device_name, '-'))) { 09565 *dash = '\0'; 09566 } 09567 09568 return 0; 09569 }
static 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 2397 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().
02398 { 02399 enum ast_t38_state state = T38_STATE_UNAVAILABLE; 02400 int datalen = sizeof(state); 02401 02402 ast_channel_queryoption(chan, AST_OPTION_T38_STATE, &state, &datalen, 0); 02403 02404 return state; 02405 }
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 6125 of file channel.c.
References ast_debug, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_var_assign(), ast_var_full_name(), ast_var_name(), ast_var_value(), ast_var_t::entries, and ast_channel::varshead.
Referenced by __ast_request_and_dial(), begin_dial_channel(), call_forward_inherit(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), and ring_entry().
06126 { 06127 struct ast_var_t *current, *newvar; 06128 const char *varname; 06129 06130 AST_LIST_TRAVERSE(&parent->varshead, current, entries) { 06131 int vartype = 0; 06132 06133 varname = ast_var_full_name(current); 06134 if (!varname) 06135 continue; 06136 06137 if (varname[0] == '_') { 06138 vartype = 1; 06139 if (varname[1] == '_') 06140 vartype = 2; 06141 } 06142 06143 switch (vartype) { 06144 case 1: 06145 newvar = ast_var_assign(&varname[1], ast_var_value(current)); 06146 if (newvar) { 06147 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 06148 ast_debug(1, "Copying soft-transferable variable %s.\n", ast_var_name(newvar)); 06149 } 06150 break; 06151 case 2: 06152 newvar = ast_var_assign(varname, ast_var_value(current)); 06153 if (newvar) { 06154 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 06155 ast_debug(1, "Copying hard-transferable variable %s.\n", ast_var_name(newvar)); 06156 } 06157 break; 06158 default: 06159 ast_debug(1, "Not copying variable %s.\n", ast_var_name(current)); 06160 break; 06161 } 06162 } 06163 }
struct ast_channel_iterator* ast_channel_iterator_all_new | ( | void | ) |
Create a new channel iterator.
After creating an iterator using this function, the ast_channel_iterator_next() function can be used to iterate through all channels that exist.
NULL | on failure | |
a | new channel iterator |
Definition at line 1673 of file channel.c.
References ao2_iterator_init(), ast_calloc, channels, and ast_channel_iterator::simple_iterator.
Referenced by action_coreshowchannels(), action_status(), ast_complete_channels(), ast_var_channel_bridge(), ast_var_channel_types_table(), ast_var_channels_table(), common_exec(), data_channels_provider_handler(), func_channels_read(), handle_chanlist(), and handle_softhangup().
01674 { 01675 struct ast_channel_iterator *i; 01676 01677 if (!(i = ast_calloc(1, sizeof(*i)))) { 01678 return NULL; 01679 } 01680 01681 i->simple_iterator = ao2_iterator_init(channels, 0); 01682 i->active_iterator = &i->simple_iterator; 01683 01684 return i; 01685 }
struct ast_channel_iterator* ast_channel_iterator_by_exten_new | ( | const char * | exten, | |
const char * | context | |||
) |
Create a new channel iterator based on extension.
NULL | on failure | |
a | new channel iterator based on the specified parameters |
Definition at line 1663 of file channel.c.
References channel_iterator_search().
Referenced by common_exec(), and pickup_by_exten().
01664 { 01665 return channel_iterator_search(NULL, 0, exten, context); 01666 }
struct ast_channel_iterator* ast_channel_iterator_by_name_new | ( | const char * | name, | |
size_t | name_len | |||
) |
Create a new channel iterator based on name.
NULL | on failure | |
a | new channel iterator based on the specified parameters |
Definition at line 1668 of file channel.c.
References channel_iterator_search().
Referenced by ast_complete_channels(), common_exec(), and softhangup_exec().
01669 { 01670 return channel_iterator_search(name, name_len, NULL, NULL); 01671 }
struct ast_channel_iterator* ast_channel_iterator_destroy | ( | struct ast_channel_iterator * | i | ) |
Destroy a channel iterator.
Definition at line 1621 of file channel.c.
References ast_channel_iterator::active_iterator, ao2_iterator_destroy(), and ast_free.
Referenced by action_coreshowchannels(), ast_complete_channels(), ast_var_channel_bridge(), ast_var_channel_types_table(), ast_var_channels_table(), common_exec(), data_channels_provider_handler(), func_channels_read(), handle_chanlist(), handle_softhangup(), pickup_by_exten(), and softhangup_exec().
01622 { 01623 ao2_iterator_destroy(i->active_iterator); 01624 ast_free(i); 01625 01626 return NULL; 01627 }
struct ast_channel* ast_channel_iterator_next | ( | struct ast_channel_iterator * | i | ) |
Get the next channel for a channel iterator.
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 1687 of file channel.c.
References ast_channel_iterator::active_iterator, and ao2_iterator_next.
Referenced by action_coreshowchannels(), action_status(), ast_complete_channels(), ast_var_channel_bridge(), ast_var_channel_types_table(), ast_var_channels_table(), data_channels_provider_handler(), func_channels_read(), handle_chanlist(), handle_softhangup(), next_channel(), pickup_by_exten(), and softhangup_exec().
01688 { 01689 return ao2_iterator_next(i->active_iterator); 01690 }
int ast_channel_make_compatible | ( | struct ast_channel * | c0, | |
struct ast_channel * | c1 | |||
) |
Makes two channel formats compatible.
c0 | first channel to make compatible | |
c1 | other channel to make compatible |
Definition at line 5854 of file channel.c.
References ast_channel_make_compatible_helper(), and chanlist::chan.
Referenced by action_bridge(), app_exec(), ast_channel_bridge(), bridge_exec(), check_compat(), dial_exec_full(), do_forward(), multiplexed_bridge_join(), parked_call_exec(), simple_bridge_join(), and wait_for_answer().
05855 { 05856 /* Some callers do not check return code, and we must try to set all call legs correctly */ 05857 int rc = 0; 05858 05859 /* Set up translation from the chan to the peer */ 05860 rc = ast_channel_make_compatible_helper(chan, peer); 05861 05862 if (rc < 0) 05863 return rc; 05864 05865 /* Set up translation from the peer to the chan */ 05866 rc = ast_channel_make_compatible_helper(peer, chan); 05867 05868 return rc; 05869 }
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 5994 of file channel.c.
References __ast_channel_masquerade().
Referenced by ast_async_goto(), ast_do_pickup(), attempt_transfer(), builtin_atxfer(), check_availability(), check_bridge(), check_goto_on_transfer(), do_bridge_masquerade(), handle_invite_replaces(), iax_park(), masq_park_call(), sip_park(), and skinny_transfer().
05995 { 05996 return __ast_channel_masquerade(original, clone, NULL); 05997 }
int ast_channel_queryoption | ( | struct ast_channel * | channel, | |
int | option, | |||
void * | data, | |||
int * | datalen, | |||
int | block | |||
) |
Checks the value of an option.
Query the value of an option Works similarly to setoption except only reads the options.
Definition at line 7628 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_log(), chanlist::chan, errno, LOG_ERROR, ast_channel_tech::queryoption, and ast_channel::tech.
Referenced by ast_channel_get_cc_agent_type(), ast_channel_get_device_name(), ast_channel_get_t38_state(), local_queryoption(), rcvfax_exec(), and sndfax_exec().
07629 { 07630 int res; 07631 07632 ast_channel_lock(chan); 07633 if (!chan->tech->queryoption) { 07634 errno = ENOSYS; 07635 ast_channel_unlock(chan); 07636 return -1; 07637 } 07638 07639 if (block) 07640 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 07641 07642 res = chan->tech->queryoption(chan, option, data, datalen); 07643 ast_channel_unlock(chan); 07644 07645 return res; 07646 }
void ast_channel_queue_connected_line_update | ( | struct ast_channel * | chan, | |
const struct ast_party_connected_line * | connected, | |||
const struct ast_set_party_connected_line * | update | |||
) |
Queue a connected line update frame on a channel.
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 8876 of file channel.c.
References ast_connected_line_build_data(), AST_CONTROL_CONNECTED_LINE, ast_queue_control_data(), connected, and update().
Referenced by ast_do_pickup(), handle_request_invite(), handle_request_update(), handle_response_invite(), local_attended_transfer(), masquerade_colp_transfer(), misdn_queue_connected_line_update(), sig_pri_handle_subcmds(), and sip_call().
08877 { 08878 unsigned char data[1024]; /* This should be large enough */ 08879 size_t datalen; 08880 08881 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update); 08882 if (datalen == (size_t) -1) { 08883 return; 08884 } 08885 08886 ast_queue_control_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen); 08887 }
void ast_channel_queue_redirecting_update | ( | struct ast_channel * | chan, | |
const struct ast_party_redirecting * | redirecting, | |||
const struct ast_set_party_redirecting * | update | |||
) |
Queue a redirecting update frame on a channel.
chan | Asterisk channel to indicate redirecting id information | |
redirecting | Redirecting id information | |
update | What redirecting information to update. NULL if all. |
Definition at line 9383 of file channel.c.
References AST_CONTROL_REDIRECTING, ast_queue_control_data(), ast_redirecting_build_data(), and update().
Referenced by cb_events(), handle_response_invite(), misdn_facility_ie_handler(), and sig_pri_handle_subcmds().
09384 { 09385 unsigned char data[1024]; /* This should be large enough */ 09386 size_t datalen; 09387 09388 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update); 09389 if (datalen == (size_t) -1) { 09390 return; 09391 } 09392 09393 ast_queue_control_data(chan, AST_CONTROL_REDIRECTING, data, datalen); 09394 }
const char* ast_channel_reason2str | ( | int | reason | ) |
return an english explanation of the code returned thru __ast_request_and_dial's 'outstate' argument
reason | The integer argument, usually taken from AST_CONTROL_ macros |
Definition at line 5198 of file channel.c.
References AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_RING, and AST_CONTROL_RINGING.
Referenced by attempt_thread().
05199 { 05200 switch (reason) /* the following appear to be the only ones actually returned by request_and_dial */ 05201 { 05202 case 0: 05203 return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)"; 05204 case AST_CONTROL_HANGUP: 05205 return "Hangup"; 05206 case AST_CONTROL_RING: 05207 return "Local Ring"; 05208 case AST_CONTROL_RINGING: 05209 return "Remote end Ringing"; 05210 case AST_CONTROL_ANSWER: 05211 return "Remote end has Answered"; 05212 case AST_CONTROL_BUSY: 05213 return "Remote end is Busy"; 05214 case AST_CONTROL_CONGESTION: 05215 return "Congestion (circuits busy)"; 05216 default: 05217 return "Unknown Reason!!"; 05218 } 05219 }
int ast_channel_redirecting_macro | ( | struct ast_channel * | autoservice_chan, | |
struct ast_channel * | macro_chan, | |||
const void * | redirecting_info, | |||
int | is_caller, | |||
int | is_frame | |||
) |
Run a redirecting interception macro and update a channel's redirecting information.
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 9441 of file channel.c.
References ast_app_run_macro(), ast_channel_lock, ast_channel_unlock, ast_channel_update_redirecting(), ast_party_redirecting_copy(), ast_party_redirecting_free(), ast_party_redirecting_init(), ast_redirecting_parse_data(), ast_strdupa, ast_strlen_zero(), ast_frame::data, ast_frame::datalen, pbx_builtin_getvar_helper(), ast_frame::ptr, ast_channel::redirecting, and S_OR.
Referenced by ast_bridge_call(), call_forward_inherit(), do_forward(), feature_request_and_dial(), handle_frame(), and remote_bridge_loop().
09442 { 09443 const char *macro; 09444 const char *macro_args; 09445 int retval; 09446 09447 ast_channel_lock(macro_chan); 09448 macro = pbx_builtin_getvar_helper(macro_chan, is_caller 09449 ? "REDIRECTING_CALLER_SEND_MACRO" : "REDIRECTING_CALLEE_SEND_MACRO"); 09450 macro = ast_strdupa(S_OR(macro, "")); 09451 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller 09452 ? "REDIRECTING_CALLER_SEND_MACRO_ARGS" : "REDIRECTING_CALLEE_SEND_MACRO_ARGS"); 09453 macro_args = ast_strdupa(S_OR(macro_args, "")); 09454 09455 if (ast_strlen_zero(macro)) { 09456 ast_channel_unlock(macro_chan); 09457 return -1; 09458 } 09459 09460 if (is_frame) { 09461 const struct ast_frame *frame = redirecting_info; 09462 09463 ast_redirecting_parse_data(frame->data.ptr, frame->datalen, ¯o_chan->redirecting); 09464 } else { 09465 const struct ast_party_redirecting *redirecting = redirecting_info; 09466 09467 ast_party_redirecting_copy(¯o_chan->redirecting, redirecting); 09468 } 09469 ast_channel_unlock(macro_chan); 09470 09471 retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args); 09472 if (!retval) { 09473 struct ast_party_redirecting saved_redirecting; 09474 09475 ast_party_redirecting_init(&saved_redirecting); 09476 ast_channel_lock(macro_chan); 09477 ast_party_redirecting_copy(&saved_redirecting, ¯o_chan->redirecting); 09478 ast_channel_unlock(macro_chan); 09479 ast_channel_update_redirecting(macro_chan, &saved_redirecting, NULL); 09480 ast_party_redirecting_free(&saved_redirecting); 09481 } 09482 09483 return retval; 09484 }
int ast_channel_register | ( | const struct ast_channel_tech * | tech | ) |
Register a channel technology (a new channel driver) Called by a channel module to register the kind of channels it supports.
tech | Structure defining channel technology or "type" |
Definition at line 896 of file channel.c.
References ast_calloc, ast_debug, ast_log(), AST_RWLIST_INSERT_HEAD, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, chanlist::chan, chanlist::list, LOG_WARNING, chanlist::tech, ast_channel::tech, and ast_channel_tech::type.
Referenced by load_module(), and unload_module().
00897 { 00898 struct chanlist *chan; 00899 00900 AST_RWLIST_WRLOCK(&backends); 00901 00902 AST_RWLIST_TRAVERSE(&backends, chan, list) { 00903 if (!strcasecmp(tech->type, chan->tech->type)) { 00904 ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type); 00905 AST_RWLIST_UNLOCK(&backends); 00906 return -1; 00907 } 00908 } 00909 00910 if (!(chan = ast_calloc(1, sizeof(*chan)))) { 00911 AST_RWLIST_UNLOCK(&backends); 00912 return -1; 00913 } 00914 chan->tech = tech; 00915 AST_RWLIST_INSERT_HEAD(&backends, chan, list); 00916 00917 ast_debug(1, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description); 00918 00919 ast_verb(2, "Registered channel type '%s' (%s)\n", chan->tech->type, chan->tech->description); 00920 00921 AST_RWLIST_UNLOCK(&backends); 00922 00923 return 0; 00924 }
struct ast_channel* ast_channel_release | ( | struct ast_channel * | chan | ) |
Unlink and release reference to a channel.
This function will unlink the channel from the global channels container if it is still there and also release the current reference to the channel.
Definition at line 1889 of file channel.c.
References ao2_unlink, ast_channel_unref, chanlist::chan, and channels.
Referenced by agent_cleanup(), ast_iax2_new(), ast_request(), bridge_request(), do_notify(), gtalk_newcall(), local_new(), and local_request().
01890 { 01891 /* Safe, even if already unlinked. */ 01892 ao2_unlink(channels, chan); 01893 return ast_channel_unref(chan); 01894 }
int ast_channel_sendhtml | ( | struct ast_channel * | channel, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) |
Sends HTML on given channel Send HTML or URL on link.
Definition at line 5791 of file channel.c.
References chanlist::chan, ast_channel_tech::send_html, and ast_channel::tech.
Referenced by agent_sendhtml(), and ast_channel_sendurl().
05792 { 05793 if (chan->tech->send_html) 05794 return chan->tech->send_html(chan, subclass, data, datalen); 05795 return -1; 05796 }
int ast_channel_sendurl | ( | struct ast_channel * | channel, | |
const char * | url | |||
) |
Sends a URL on a given link Send URL on link.
Definition at line 5798 of file channel.c.
References ast_channel_sendhtml(), AST_HTML_URL, and chanlist::chan.
Referenced by dial_exec_full(), and sendurl_exec().
05799 { 05800 return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1); 05801 }
void ast_channel_set_caller | ( | struct ast_channel * | chan, | |
const struct ast_party_caller * | caller, | |||
const struct ast_set_party_caller * | update | |||
) |
Set the caller id information in the Asterisk channel.
chan | Asterisk channel to set caller id information | |
caller | Caller id information | |
update | What caller information to update. NULL if all. |
Definition at line 6913 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_party_caller_set(), ast_channel::caller, chanlist::chan, and update().
06914 { 06915 if (&chan->caller == caller) { 06916 /* Don't set to self */ 06917 return; 06918 } 06919 06920 ast_channel_lock(chan); 06921 ast_party_caller_set(&chan->caller, caller, update); 06922 ast_channel_unlock(chan); 06923 }
void ast_channel_set_caller_event | ( | struct ast_channel * | chan, | |
const struct ast_party_caller * | caller, | |||
const struct ast_set_party_caller * | update | |||
) |
Set the caller id information in the Asterisk channel and generate an AMI event if the caller id name or number changed.
chan | Asterisk channel to set caller id information | |
caller | Caller id information | |
update | What caller information to update. NULL if all. |
Definition at line 6925 of file channel.c.
References ast_cdr_setcid(), ast_channel_lock, ast_channel_unlock, ast_party_caller_set(), ast_channel::caller, ast_channel::cdr, chanlist::chan, ast_party_caller::id, ast_party_id::name, ast_party_id::number, report_new_callerid(), S_COR, ast_party_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().
06926 { 06927 const char *pre_set_number; 06928 const char *pre_set_name; 06929 06930 if (&chan->caller == caller) { 06931 /* Don't set to self */ 06932 return; 06933 } 06934 06935 ast_channel_lock(chan); 06936 pre_set_number = 06937 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL); 06938 pre_set_name = S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL); 06939 ast_party_caller_set(&chan->caller, caller, update); 06940 if (S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL) 06941 != pre_set_number 06942 || S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL) 06943 != pre_set_name) { 06944 /* The caller id name or number changed. */ 06945 report_new_callerid(chan); 06946 } 06947 if (chan->cdr) { 06948 ast_cdr_setcid(chan->cdr, chan); 06949 } 06950 ast_channel_unlock(chan); 06951 }
void ast_channel_set_connected_line | ( | struct ast_channel * | chan, | |
const struct ast_party_connected_line * | connected, | |||
const struct ast_set_party_connected_line * | update | |||
) |
Set the connected line information in the Asterisk channel.
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 8236 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().
08237 { 08238 if (&chan->connected == connected) { 08239 /* Don't set to self */ 08240 return; 08241 } 08242 08243 ast_channel_lock(chan); 08244 ast_party_connected_line_set(&chan->connected, connected, update); 08245 ast_channel_unlock(chan); 08246 }
void ast_channel_set_fd | ( | struct ast_channel * | chan, | |
int | which, | |||
int | fd | |||
) |
Set the file descriptor on the channel
Definition at line 2598 of file channel.c.
References ast_calloc, chanlist::chan, ast_channel::data, ast_channel::fds, and free.
Referenced by __ast_channel_alloc_ap(), __oh323_new(), __oh323_rtp_create(), __oh323_update_info(), alsa_new(), ast_deactivate_generator(), ast_do_masquerade(), dahdi_new(), gtalk_new(), initialize_udptl(), jingle_new(), mgcp_new(), misdn_new(), my_swap_subchannels(), nbs_new(), oss_new(), phone_new(), process_sdp(), setformat(), sip_new(), sip_set_rtp_peer(), skinny_new(), start_rtp(), and swap_subs().
02599 { 02600 #ifdef HAVE_EPOLL 02601 struct epoll_event ev; 02602 struct ast_epoll_data *aed = NULL; 02603 02604 if (chan->fds[which] > -1) { 02605 epoll_ctl(chan->epfd, EPOLL_CTL_DEL, chan->fds[which], &ev); 02606 aed = chan->epfd_data[which]; 02607 } 02608 02609 /* If this new fd is valid, add it to the epoll */ 02610 if (fd > -1) { 02611 if (!aed && (!(aed = ast_calloc(1, sizeof(*aed))))) 02612 return; 02613 02614 chan->epfd_data[which] = aed; 02615 aed->chan = chan; 02616 aed->which = which; 02617 02618 ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP; 02619 ev.data.ptr = aed; 02620 epoll_ctl(chan->epfd, EPOLL_CTL_ADD, fd, &ev); 02621 } else if (aed) { 02622 /* We don't have to keep around this epoll data structure now */ 02623 free(aed); 02624 chan->epfd_data[which] = NULL; 02625 } 02626 #endif 02627 chan->fds[which] = fd; 02628 return; 02629 }
void ast_channel_set_linkgroup | ( | struct ast_channel * | chan, | |
struct ast_channel * | peer | |||
) |
propagate the linked id between chan and peer
Definition at line 6270 of file channel.c.
References ast_channel::_bridge, ast_bridged_channel(), ast_channel_change_linkedid(), ast_strdupa, chanlist::chan, ast_channel::linkedid, oldest_linkedid(), and ast_channel::uniqueid.
Referenced by ast_bridge_call(), and ast_do_masquerade().
06271 { 06272 const char* linkedid=NULL; 06273 struct ast_channel *bridged; 06274 06275 linkedid = oldest_linkedid(chan->linkedid, peer->linkedid); 06276 linkedid = oldest_linkedid(linkedid, chan->uniqueid); 06277 linkedid = oldest_linkedid(linkedid, peer->uniqueid); 06278 if (chan->_bridge) { 06279 bridged = ast_bridged_channel(chan); 06280 if (bridged != peer) { 06281 linkedid = oldest_linkedid(linkedid, bridged->linkedid); 06282 linkedid = oldest_linkedid(linkedid, bridged->uniqueid); 06283 } 06284 } 06285 if (peer->_bridge) { 06286 bridged = ast_bridged_channel(peer); 06287 if (bridged != chan) { 06288 linkedid = oldest_linkedid(linkedid, bridged->linkedid); 06289 linkedid = oldest_linkedid(linkedid, bridged->uniqueid); 06290 } 06291 } 06292 06293 /* just in case setting a stringfield to itself causes problems */ 06294 linkedid = ast_strdupa(linkedid); 06295 06296 ast_channel_change_linkedid(chan, linkedid); 06297 ast_channel_change_linkedid(peer, linkedid); 06298 if (chan->_bridge) { 06299 bridged = ast_bridged_channel(chan); 06300 if (bridged != peer) { 06301 ast_channel_change_linkedid(bridged, linkedid); 06302 } 06303 } 06304 if (peer->_bridge) { 06305 bridged = ast_bridged_channel(peer); 06306 if (bridged != chan) { 06307 ast_channel_change_linkedid(bridged, linkedid); 06308 } 06309 } 06310 }
void ast_channel_set_redirecting | ( | struct ast_channel * | chan, | |
const struct ast_party_redirecting * | redirecting, | |||
const struct ast_set_party_redirecting * | update | |||
) |
Set the redirecting id information in the Asterisk channel.
chan | Asterisk channel to set redirecting id information | |
redirecting | Redirecting id information | |
update | What redirecting information to update. NULL if all. |
Definition at line 8889 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_party_redirecting_set(), ast_channel::redirecting, and update().
Referenced by ast_indicate_data(), handle_request_invite(), handle_response(), misdn_copy_redirecting_to_ast(), redirecting_write(), and sig_pri_handle_subcmds().
08890 { 08891 if (&chan->redirecting == redirecting) { 08892 /* Don't set to self */ 08893 return; 08894 } 08895 08896 ast_channel_lock(chan); 08897 ast_party_redirecting_set(&chan->redirecting, redirecting, update); 08898 ast_channel_unlock(chan); 08899 }
int ast_channel_setoption | ( | struct ast_channel * | channel, | |
int | option, | |||
void * | data, | |||
int | datalen, | |||
int | block | |||
) |
Sets an option on a channel.
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 7608 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_log(), chanlist::chan, errno, LOG_ERROR, ast_channel_tech::setoption, and ast_channel::tech.
Referenced by analog_hangup(), ast_bridge_call(), ast_channel_make_compatible_helper(), common_exec(), conf_run(), dahdi_hangup(), dial_exec_full(), func_channel_write(), func_channel_write_real(), handle_tddmode(), play_record_review(), rcvfax_exec(), reset_volumes(), set_format(), set_listen_volume(), set_security_requirements(), set_talk_volume(), sndfax_exec(), and vm_forwardoptions().
07609 { 07610 int res; 07611 07612 ast_channel_lock(chan); 07613 if (!chan->tech->setoption) { 07614 errno = ENOSYS; 07615 ast_channel_unlock(chan); 07616 return -1; 07617 } 07618 07619 if (block) 07620 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 07621 07622 res = chan->tech->setoption(chan, option, data, datalen); 07623 ast_channel_unlock(chan); 07624 07625 return res; 07626 }
void ast_channel_setwhentohangup | ( | struct ast_channel * | chan, | |
time_t | offset | |||
) |
Set when to hang a channel up.
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 867 of file channel.c.
References ast_channel_setwhentohangup_tv(), and chanlist::chan.
00868 { 00869 struct timeval when = { offset, }; 00870 ast_channel_setwhentohangup_tv(chan, when); 00871 }
void ast_channel_setwhentohangup_tv | ( | struct ast_channel * | chan, | |
struct timeval | offset | |||
) |
Set when to hang a channel up.
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 860 of file channel.c.
References ast_null_frame, ast_queue_frame(), ast_tvadd(), ast_tvnow(), ast_tvzero(), chanlist::chan, and ast_channel::whentohangup.
Referenced by action_timeout(), ast_channel_setwhentohangup(), handle_autohangup(), sig_pri_send_aoce_termination_request(), and timeout_write().
00861 { 00862 chan->whentohangup = ast_tvzero(offset) ? offset : ast_tvadd(offset, ast_tvnow()); 00863 ast_queue_frame(chan, &ast_null_frame); 00864 return; 00865 }
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 8110 of file channel.c.
References ast_activate_generator(), ast_calloc, ast_debug, AST_FORMAT_SLINEAR, ast_free, ast_log(), ast_set_write_format(), LOG_ERROR, ast_channel::name, ast_silence_generator::old_write_format, silence_generator, state, and ast_channel::writeformat.
Referenced by __ast_play_and_record(), ast_bridge_call(), ast_dtmf_stream(), ast_readstring_full(), ast_safe_sleep_conditional(), channel_spy(), TransferCallStep1(), waitfor_exec(), and waitforring_exec().
08111 { 08112 struct ast_silence_generator *state; 08113 08114 if (!(state = ast_calloc(1, sizeof(*state)))) { 08115 return NULL; 08116 } 08117 08118 state->old_write_format = chan->writeformat; 08119 08120 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) { 08121 ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n"); 08122 ast_free(state); 08123 return NULL; 08124 } 08125 08126 ast_activate_generator(chan, &silence_generator, state); 08127 08128 ast_debug(1, "Started silence generator on '%s'\n", chan->name); 08129 08130 return state; 08131 }
void ast_channel_stop_silence_generator | ( | struct ast_channel * | chan, | |
struct ast_silence_generator * | state | |||
) |
Stops a previously-started silence generator on the given channel.
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 8133 of file channel.c.
References ast_deactivate_generator(), ast_debug, ast_free, ast_log(), ast_set_write_format(), LOG_ERROR, ast_channel::name, and state.
Referenced by ast_bridge_call(), ast_dtmf_stream(), ast_readstring_full(), ast_safe_sleep_conditional(), channel_spy(), HandleCallOutgoing(), key_dial_page(), unistim_hangup(), waitfor_exec(), and waitforring_exec().
08134 { 08135 if (!state) 08136 return; 08137 08138 ast_deactivate_generator(chan); 08139 08140 ast_debug(1, "Stopped silence generator on '%s'\n", chan->name); 08141 08142 if (ast_set_write_format(chan, state->old_write_format) < 0) 08143 ast_log(LOG_ERROR, "Could not return write format to its original state\n"); 08144 08145 ast_free(state); 08146 }
int ast_channel_supports_html | ( | struct ast_channel * | channel | ) |
Checks for HTML support on a channel.
Definition at line 5786 of file channel.c.
References chanlist::chan, ast_channel_tech::send_html, and ast_channel::tech.
Referenced by dial_exec_full(), and sendurl_exec().
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 6068 of file channel.c.
References __ast_channel_masquerade(), ast_calloc, ast_datastore_alloc, ast_datastore_free(), ast_datastore::data, party_connected_line_copy_transfer(), xfer_masquerade_ds::target_id, xfer_masquerade_ds::transferee_id, and xfer_ds_info.
Referenced by analog_attempt_transfer(), misdn_attempt_transfer(), and sig_pri_attempt_transfer().
06075 { 06076 struct ast_datastore *xfer_ds; 06077 struct xfer_masquerade_ds *xfer_colp; 06078 int res; 06079 06080 xfer_ds = ast_datastore_alloc(&xfer_ds_info, NULL); 06081 if (!xfer_ds) { 06082 return -1; 06083 } 06084 06085 xfer_colp = ast_calloc(1, sizeof(*xfer_colp)); 06086 if (!xfer_colp) { 06087 ast_datastore_free(xfer_ds); 06088 return -1; 06089 } 06090 party_connected_line_copy_transfer(&xfer_colp->target_id, target_id); 06091 xfer_colp->target_held = target_held; 06092 party_connected_line_copy_transfer(&xfer_colp->transferee_id, transferee_id); 06093 xfer_colp->transferee_held = transferee_held; 06094 xfer_ds->data = xfer_colp; 06095 06096 res = __ast_channel_masquerade(target_chan, transferee_chan, xfer_ds); 06097 if (res) { 06098 ast_datastore_free(xfer_ds); 06099 } 06100 return res; 06101 }
void ast_channel_undefer_dtmf | ( | struct ast_channel * | chan | ) |
Unset defer DTMF flag on channel.
Undo defer. ast_read will return any DTMF characters that were queued
Definition at line 1600 of file channel.c.
References ast_clear_flag, AST_FLAG_DEFER_DTMF, and chanlist::chan.
Referenced by find_cache().
01601 { 01602 if (chan) 01603 ast_clear_flag(chan, AST_FLAG_DEFER_DTMF); 01604 }
void ast_channel_unregister | ( | const struct ast_channel_tech * | tech | ) |
Unregister a channel technology.
tech | Structure defining channel technology or "type" that was previously registered |
Definition at line 927 of file channel.c.
References ast_debug, ast_free, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_END, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, chanlist::chan, chanlist::list, chanlist::tech, ast_channel::tech, and ast_channel_tech::type.
Referenced by __unload_module(), load_module(), and unload_module().
00928 { 00929 struct chanlist *chan; 00930 00931 ast_debug(1, "Unregistering channel type '%s'\n", tech->type); 00932 00933 AST_RWLIST_WRLOCK(&backends); 00934 00935 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) { 00936 if (chan->tech == tech) { 00937 AST_LIST_REMOVE_CURRENT(list); 00938 ast_free(chan); 00939 ast_verb(2, "Unregistered channel type '%s'\n", tech->type); 00940 break; 00941 } 00942 } 00943 AST_LIST_TRAVERSE_SAFE_END; 00944 00945 AST_RWLIST_UNLOCK(&backends); 00946 }
void ast_channel_update_connected_line | ( | struct ast_channel * | chan, | |
const struct ast_party_connected_line * | connected, | |||
const struct ast_set_party_connected_line * | update | |||
) |
Indicate that the connected line information has changed.
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 8863 of file channel.c.
References ast_connected_line_build_data(), AST_CONTROL_CONNECTED_LINE, ast_indicate_data(), connected, and update().
Referenced by app_exec(), ast_channel_connected_line_macro(), ast_do_pickup(), atxfer_fail_cleanup(), builtin_atxfer(), connectedline_write(), parked_call_exec(), and wait_for_answer().
08864 { 08865 unsigned char data[1024]; /* This should be large enough */ 08866 size_t datalen; 08867 08868 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update); 08869 if (datalen == (size_t) -1) { 08870 return; 08871 } 08872 08873 ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen); 08874 }
void ast_channel_update_redirecting | ( | struct ast_channel * | chan, | |
const struct ast_party_redirecting * | redirecting, | |||
const struct ast_set_party_redirecting * | update | |||
) |
Indicate that the redirecting id has changed.
chan | Asterisk channel to indicate redirecting id information | |
redirecting | Redirecting id information | |
update | What redirecting information to update. NULL if all. |
Definition at line 9370 of file channel.c.
References AST_CONTROL_REDIRECTING, ast_indicate_data(), ast_redirecting_build_data(), and update().
Referenced by ast_channel_redirecting_macro(), call_forward_inherit(), do_forward(), and redirecting_write().
09371 { 09372 unsigned char data[1024]; /* This should be large enough */ 09373 size_t datalen; 09374 09375 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update); 09376 if (datalen == (size_t) -1) { 09377 return; 09378 } 09379 09380 ast_indicate_data(chan, AST_CONTROL_REDIRECTING, data, datalen); 09381 }
struct ast_variable* ast_channeltype_list | ( | void | ) |
return an ast_variable list of channeltypes
Definition at line 252 of file channel.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_variable_new(), ast_channel_tech::description, chanlist::list, chanlist::tech, ast_channel_tech::type, and var.
Referenced by ast_var_channel_types(), and ast_var_channel_types_table().
00253 { 00254 struct chanlist *cl; 00255 struct ast_variable *var = NULL, *prev = NULL; 00256 00257 AST_RWLIST_RDLOCK(&backends); 00258 AST_RWLIST_TRAVERSE(&backends, cl, list) { 00259 if (prev) { 00260 if ((prev->next = ast_variable_new(cl->tech->type, cl->tech->description, ""))) 00261 prev = prev->next; 00262 } else { 00263 var = ast_variable_new(cl->tech->type, cl->tech->description, ""); 00264 prev = var; 00265 } 00266 } 00267 AST_RWLIST_UNLOCK(&backends); 00268 00269 return var; 00270 }
int ast_check_hangup | ( | struct ast_channel * | chan | ) |
Check to see if a channel is needing hang up.
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 796 of file channel.c.
References ast_channel::_softhangup, ast_debug, AST_SOFTHANGUP_TIMEOUT, ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), chanlist::chan, and ast_channel::whentohangup.
Referenced by __ast_pbx_run(), __ast_read(), _macro_exec(), agent_indicate(), agi_exec(), agi_handle_command(), announce_thread(), ast_bridge_call(), ast_call(), ast_channel_bridge(), ast_check_hangup_locked(), ast_indicate_data(), ast_raw_answer(), ast_readstring_full(), ast_recvtext(), ast_rtp_instance_bridge(), ast_sendtext(), ast_transfer(), ast_udptl_bridge(), ast_waitfordigit_full(), ast_write(), autoservice_run(), bridge_call_thread(), bridge_exec(), builtin_atxfer(), call_forward_inherit(), channel_spy(), check_bridge(), common_exec(), conf_play(), conf_run(), dahdi_sendtext(), dahdi_setoption(), dial_exec_full(), dundi_lookup_internal(), eagi_exec(), eivr_comm(), feature_request_and_dial(), findmeexec(), func_channel_read(), handle_sendimage(), launch_asyncagi(), local_fixup(), lua_check_hangup(), ospfinished_exec(), pbx_builtin_incomplete(), pbx_builtin_waitexten(), pbx_exec(), read_exec(), readexten_exec(), remote_bridge_loop(), run_agi(), and run_ras().
00797 { 00798 if (chan->_softhangup) /* yes if soft hangup flag set */ 00799 return 1; 00800 if (ast_tvzero(chan->whentohangup)) /* no if no hangup scheduled */ 00801 return 0; 00802 if (ast_tvdiff_ms(chan->whentohangup, ast_tvnow()) > 0) /* no if hangup time has not come yet. */ 00803 return 0; 00804 ast_debug(4, "Hangup time has come: %" PRIi64 "\n", ast_tvdiff_ms(chan->whentohangup, ast_tvnow())); 00805 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT; /* record event */ 00806 return 1; 00807 }
int ast_check_hangup_locked | ( | struct ast_channel * | chan | ) |
Definition at line 809 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_check_hangup(), and chanlist::chan.
Referenced by action_redirect(), and ast_channel_bridge().
00810 { 00811 int res; 00812 ast_channel_lock(chan); 00813 res = ast_check_hangup(chan); 00814 ast_channel_unlock(chan); 00815 return res; 00816 }
int ast_connected_line_build_data | ( | unsigned char * | data, | |
size_t | datalen, | |||
const struct ast_party_connected_line * | connected, | |||
const struct ast_set_party_connected_line * | update | |||
) |
Build the connected line information data frame.
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 8603 of file channel.c.
References AST_CONNECTED_LINE_ID_PRESENTATION, AST_CONNECTED_LINE_NAME, AST_CONNECTED_LINE_NAME_CHAR_SET, AST_CONNECTED_LINE_NAME_PRESENTATION, AST_CONNECTED_LINE_NAME_VALID, AST_CONNECTED_LINE_NUMBER, AST_CONNECTED_LINE_NUMBER_PLAN, AST_CONNECTED_LINE_NUMBER_PRESENTATION, AST_CONNECTED_LINE_NUMBER_VALID, AST_CONNECTED_LINE_SOURCE, AST_CONNECTED_LINE_SUBADDRESS, AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN, AST_CONNECTED_LINE_SUBADDRESS_TYPE, AST_CONNECTED_LINE_SUBADDRESS_VALID, AST_CONNECTED_LINE_TAG, AST_CONNECTED_LINE_VERSION, ast_log(), connected, LOG_WARNING, ast_party_id_ies::name, party_id_build_data(), ast_party_name_ies::str, update(), and value.
Referenced by ast_channel_queue_connected_line_update(), ast_channel_update_connected_line(), local_attended_transfer(), local_indicate(), and masquerade_colp_transfer().
08604 { 08605 int32_t value; 08606 size_t pos = 0; 08607 int res; 08608 08609 static const struct ast_party_id_ies ies = { 08610 .name.str = AST_CONNECTED_LINE_NAME, 08611 .name.char_set = AST_CONNECTED_LINE_NAME_CHAR_SET, 08612 .name.presentation = AST_CONNECTED_LINE_NAME_PRESENTATION, 08613 .name.valid = AST_CONNECTED_LINE_NAME_VALID, 08614 08615 .number.str = AST_CONNECTED_LINE_NUMBER, 08616 .number.plan = AST_CONNECTED_LINE_NUMBER_PLAN, 08617 .number.presentation = AST_CONNECTED_LINE_NUMBER_PRESENTATION, 08618 .number.valid = AST_CONNECTED_LINE_NUMBER_VALID, 08619 08620 .subaddress.str = AST_CONNECTED_LINE_SUBADDRESS, 08621 .subaddress.type = AST_CONNECTED_LINE_SUBADDRESS_TYPE, 08622 .subaddress.odd_even_indicator = AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN, 08623 .subaddress.valid = AST_CONNECTED_LINE_SUBADDRESS_VALID, 08624 08625 .tag = AST_CONNECTED_LINE_TAG, 08626 .combined_presentation = AST_CONNECTED_LINE_ID_PRESENTATION, 08627 }; 08628 08629 /* 08630 * The size of integer values must be fixed in case the frame is 08631 * shipped to another machine. 08632 */ 08633 08634 /* Connected line frame version */ 08635 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08636 ast_log(LOG_WARNING, "No space left for connected line frame version\n"); 08637 return -1; 08638 } 08639 data[pos++] = AST_CONNECTED_LINE_VERSION; 08640 data[pos++] = 1; 08641 data[pos++] = 2;/* Version 1 did not have a version ie */ 08642 08643 res = party_id_build_data(data + pos, datalen - pos, &connected->id, 08644 "connected line", &ies, update ? &update->id : NULL); 08645 if (res < 0) { 08646 return -1; 08647 } 08648 pos += res; 08649 08650 /* Connected line source */ 08651 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) { 08652 ast_log(LOG_WARNING, "No space left for connected line source\n"); 08653 return -1; 08654 } 08655 data[pos++] = AST_CONNECTED_LINE_SOURCE; 08656 data[pos++] = sizeof(value); 08657 value = htonl(connected->source); 08658 memcpy(data + pos, &value, sizeof(value)); 08659 pos += sizeof(value); 08660 08661 return pos; 08662 }
void ast_connected_line_copy_from_caller | ( | struct ast_party_connected_line * | dest, | |
const struct ast_party_caller * | src | |||
) |
Copy the caller information to the connected line information.
dest | Destination connected line information | |
src | Source caller information |
Definition at line 8221 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().
08222 { 08223 ast_party_id_copy(&dest->id, &src->id); 08224 ast_party_id_copy(&dest->ani, &src->ani); 08225 dest->ani2 = src->ani2; 08226 }
void ast_connected_line_copy_to_caller | ( | struct ast_party_caller * | dest, | |
const struct ast_party_connected_line * | src | |||
) |
Copy the connected line information to the caller information.
dest | Destination caller information | |
src | Source connected line information |
Definition at line 8228 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().
08229 { 08230 ast_party_id_copy(&dest->id, &src->id); 08231 ast_party_id_copy(&dest->ani, &src->ani); 08232 08233 dest->ani2 = src->ani2; 08234 }
int ast_connected_line_parse_data | ( | const unsigned char * | data, | |
size_t | datalen, | |||
struct ast_party_connected_line * | connected | |||
) |
Parse connected line indication frame data.
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 8664 of file channel.c.
References AST_CONNECTED_LINE_ID_PRESENTATION, AST_CONNECTED_LINE_NAME, AST_CONNECTED_LINE_NAME_CHAR_SET, AST_CONNECTED_LINE_NAME_PRESENTATION, AST_CONNECTED_LINE_NAME_VALID, AST_CONNECTED_LINE_NUMBER, AST_CONNECTED_LINE_NUMBER_PLAN, AST_CONNECTED_LINE_NUMBER_PRESENTATION, AST_CONNECTED_LINE_NUMBER_VALID, AST_CONNECTED_LINE_SOURCE, AST_CONNECTED_LINE_SUBADDRESS, AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN, AST_CONNECTED_LINE_SUBADDRESS_TYPE, AST_CONNECTED_LINE_SUBADDRESS_VALID, AST_CONNECTED_LINE_TAG, AST_CONNECTED_LINE_VERSION, ast_free, ast_log(), ast_malloc, AST_PARTY_CHAR_SET_ISO8859_1, ast_party_id_ies::combined_presentation, connected, LOG_DEBUG, LOG_WARNING, and value.
Referenced by __ast_read(), ast_channel_connected_line_macro(), ast_indicate_data(), feature_request_and_dial(), socket_process(), and wait_for_winner().
08665 { 08666 size_t pos; 08667 unsigned char ie_len; 08668 unsigned char ie_id; 08669 int32_t value; 08670 int frame_version = 1; 08671 int combined_presentation = 0; 08672 int got_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */ 08673 08674 for (pos = 0; pos < datalen; pos += ie_len) { 08675 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) { 08676 ast_log(LOG_WARNING, "Invalid connected line update\n"); 08677 return -1; 08678 } 08679 ie_id = data[pos++]; 08680 ie_len = data[pos++]; 08681 if (datalen < pos + ie_len) { 08682 ast_log(LOG_WARNING, "Invalid connected line update\n"); 08683 return -1; 08684 } 08685 08686 switch (ie_id) { 08687 /* Connected line party frame version */ 08688 case AST_CONNECTED_LINE_VERSION: 08689 if (ie_len != 1) { 08690 ast_log(LOG_WARNING, "Invalid connected line frame version (%u)\n", 08691 (unsigned) ie_len); 08692 break; 08693 } 08694 frame_version = data[pos]; 08695 break; 08696 /* Connected line party id name */ 08697 case AST_CONNECTED_LINE_NAME: 08698 ast_free(connected->id.name.str); 08699 connected->id.name.str = ast_malloc(ie_len + 1); 08700 if (connected->id.name.str) { 08701 memcpy(connected->id.name.str, data + pos, ie_len); 08702 connected->id.name.str[ie_len] = 0; 08703 } 08704 break; 08705 case AST_CONNECTED_LINE_NAME_CHAR_SET: 08706 if (ie_len != 1) { 08707 ast_log(LOG_WARNING, "Invalid connected line name char set (%u)\n", 08708 (unsigned) ie_len); 08709 break; 08710 } 08711 connected->id.name.char_set = data[pos]; 08712 break; 08713 case AST_CONNECTED_LINE_NAME_PRESENTATION: 08714 if (ie_len != 1) { 08715 ast_log(LOG_WARNING, "Invalid connected line name presentation (%u)\n", 08716 (unsigned) ie_len); 08717 break; 08718 } 08719 connected->id.name.presentation = data[pos]; 08720 break; 08721 case AST_CONNECTED_LINE_NAME_VALID: 08722 if (ie_len != 1) { 08723 ast_log(LOG_WARNING, "Invalid connected line name valid (%u)\n", 08724 (unsigned) ie_len); 08725 break; 08726 } 08727 connected->id.name.valid = data[pos]; 08728 break; 08729 /* Connected line party id number */ 08730 case AST_CONNECTED_LINE_NUMBER: 08731 ast_free(connected->id.number.str); 08732 connected->id.number.str = ast_malloc(ie_len + 1); 08733 if (connected->id.number.str) { 08734 memcpy(connected->id.number.str, data + pos, ie_len); 08735 connected->id.number.str[ie_len] = 0; 08736 } 08737 break; 08738 case AST_CONNECTED_LINE_NUMBER_PLAN: 08739 if (ie_len != 1) { 08740 ast_log(LOG_WARNING, "Invalid connected line numbering plan (%u)\n", 08741 (unsigned) ie_len); 08742 break; 08743 } 08744 connected->id.number.plan = data[pos]; 08745 break; 08746 case AST_CONNECTED_LINE_NUMBER_PRESENTATION: 08747 if (ie_len != 1) { 08748 ast_log(LOG_WARNING, "Invalid connected line number presentation (%u)\n", 08749 (unsigned) ie_len); 08750 break; 08751 } 08752 connected->id.number.presentation = data[pos]; 08753 break; 08754 case AST_CONNECTED_LINE_NUMBER_VALID: 08755 if (ie_len != 1) { 08756 ast_log(LOG_WARNING, "Invalid connected line number valid (%u)\n", 08757 (unsigned) ie_len); 08758 break; 08759 } 08760 connected->id.number.valid = data[pos]; 08761 break; 08762 /* Connected line party id combined presentation */ 08763 case AST_CONNECTED_LINE_ID_PRESENTATION: 08764 if (ie_len != 1) { 08765 ast_log(LOG_WARNING, "Invalid connected line combined presentation (%u)\n", 08766 (unsigned) ie_len); 08767 break; 08768 } 08769 combined_presentation = data[pos]; 08770 got_combined_presentation = 1; 08771 break; 08772 /* Connected line party id subaddress */ 08773 case AST_CONNECTED_LINE_SUBADDRESS: 08774 ast_free(connected->id.subaddress.str); 08775 connected->id.subaddress.str = ast_malloc(ie_len + 1); 08776 if (connected->id.subaddress.str) { 08777 memcpy(connected->id.subaddress.str, data + pos, ie_len); 08778 connected->id.subaddress.str[ie_len] = 0; 08779 } 08780 break; 08781 case AST_CONNECTED_LINE_SUBADDRESS_TYPE: 08782 if (ie_len != 1) { 08783 ast_log(LOG_WARNING, "Invalid connected line type of subaddress (%u)\n", 08784 (unsigned) ie_len); 08785 break; 08786 } 08787 connected->id.subaddress.type = data[pos]; 08788 break; 08789 case AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN: 08790 if (ie_len != 1) { 08791 ast_log(LOG_WARNING, 08792 "Invalid connected line subaddress odd-even indicator (%u)\n", 08793 (unsigned) ie_len); 08794 break; 08795 } 08796 connected->id.subaddress.odd_even_indicator = data[pos]; 08797 break; 08798 case AST_CONNECTED_LINE_SUBADDRESS_VALID: 08799 if (ie_len != 1) { 08800 ast_log(LOG_WARNING, "Invalid connected line subaddress valid (%u)\n", 08801 (unsigned) ie_len); 08802 break; 08803 } 08804 connected->id.subaddress.valid = data[pos]; 08805 break; 08806 /* Connected line party tag */ 08807 case AST_CONNECTED_LINE_TAG: 08808 ast_free(connected->id.tag); 08809 connected->id.tag = ast_malloc(ie_len + 1); 08810 if (connected->id.tag) { 08811 memcpy(connected->id.tag, data + pos, ie_len); 08812 connected->id.tag[ie_len] = 0; 08813 } 08814 break; 08815 /* Connected line party source */ 08816 case AST_CONNECTED_LINE_SOURCE: 08817 if (ie_len != sizeof(value)) { 08818 ast_log(LOG_WARNING, "Invalid connected line source (%u)\n", 08819 (unsigned) ie_len); 08820 break; 08821 } 08822 memcpy(&value, data + pos, sizeof(value)); 08823 connected->source = ntohl(value); 08824 break; 08825 /* Connected line party unknown element */ 08826 default: 08827 ast_log(LOG_DEBUG, "Unknown connected line element: %u (%u)\n", 08828 (unsigned) ie_id, (unsigned) ie_len); 08829 break; 08830 } 08831 } 08832 08833 switch (frame_version) { 08834 case 1: 08835 /* 08836 * The other end is an earlier version that we need to adjust 08837 * for compatibility. 08838 */ 08839 connected->id.name.valid = 1; 08840 connected->id.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1; 08841 connected->id.number.valid = 1; 08842 if (got_combined_presentation) { 08843 connected->id.name.presentation = combined_presentation; 08844 connected->id.number.presentation = combined_presentation; 08845 } 08846 break; 08847 case 2: 08848 /* The other end is at the same level as we are. */ 08849 break; 08850 default: 08851 /* 08852 * The other end is newer than we are. 08853 * We need to assume that they are compatible with us. 08854 */ 08855 ast_log(LOG_DEBUG, "Connected line frame has newer version: %u\n", 08856 (unsigned) frame_version); 08857 break; 08858 } 08859 08860 return 0; 08861 }
void ast_deactivate_generator | ( | struct ast_channel * | chan | ) |
Deactivate an active generator
Definition at line 3055 of file channel.c.
References ast_channel_lock, ast_channel_set_fd(), ast_channel_unlock, ast_clear_flag, AST_FLAG_WRITE_INT, AST_GENERATOR_FD, ast_settimeout(), chanlist::chan, ast_channel::generator, ast_channel::generatordata, and ast_generator::release.
Referenced by __ast_read(), app_exec(), ast_channel_stop_silence_generator(), ast_openstream_full(), ast_playtones_stop(), ast_quiet_chan(), ast_read_generator_actions(), ast_tonepair_stop(), ast_write(), cb_events(), channel_spy(), dial_exec_full(), generator_force(), local_ast_moh_stop(), old_milliwatt_exec(), transmit_audio(), and wait_for_answer().
03056 { 03057 ast_channel_lock(chan); 03058 if (chan->generatordata) { 03059 if (chan->generator && chan->generator->release) 03060 chan->generator->release(chan, chan->generatordata); 03061 chan->generatordata = NULL; 03062 chan->generator = NULL; 03063 ast_channel_set_fd(chan, AST_GENERATOR_FD, -1); 03064 ast_clear_flag(chan, AST_FLAG_WRITE_INT); 03065 ast_settimeout(chan, 0, NULL, NULL); 03066 } 03067 ast_channel_unlock(chan); 03068 }
int ast_do_masquerade | ( | struct ast_channel * | original | ) |
Start masquerading a channel.
< TRUE if the clonechan was a zombie before the masquerade.
Definition at line 6429 of file channel.c.
References __ast_change_name_nolink(), ast_channel::_bridge, ast_channel::_softhangup, ast_channel::_state, accountcode, ast_channel::adsicpe, ast_channel::alertpipe, ao2_link, ao2_lock, ao2_unlink, ao2_unlock, ast_app_group_update(), ast_autochan_new_channel(), ast_bridged_channel(), ast_cause2str(), AST_CEL_BRIDGE_UPDATE, ast_cel_report_event(), ast_channel_datastore_find(), ast_channel_datastore_remove(), ast_channel_lock, ast_channel_lock_both, AST_CHANNEL_NAME, ast_channel_ref, ast_channel_set_fd(), ast_channel_set_linkgroup(), ast_channel_unlock, ast_channel_unref, AST_CONTROL_SRCCHANGE, AST_CONTROL_UNHOLD, ast_copy_string(), ast_datastore_free(), ast_debug, AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, AST_GENERATOR_FD, ast_getformatname(), ast_indicate(), ast_kill_tech, AST_LIST_APPEND_LIST, AST_LIST_FIRST, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_HEAD_NOLOCK, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), ast_manager_event, ast_manager_event_multichan, AST_MAX_FDS, ast_null_frame, ast_queue_frame(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_SOFTHANGUP_DEV, ast_state2str(), ast_string_field_set, ast_test_flag, AST_TIMING_FD, ast_channel::blocker, ast_channel::caller, ast_channel::cdr, ast_datastore_info::chan_fixup, channels, clone_variables(), 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_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_bridge(), check_goto_on_transfer(), do_bridge_masquerade(), handle_invite_replaces(), iax_park(), local_attended_transfer(), masq_park_call(), and sip_park().
06430 { 06431 int x; 06432 int i; 06433 int origstate; 06434 int visible_indication; 06435 int clone_was_zombie = 0;/*!< TRUE if the clonechan was a zombie before the masquerade. */ 06436 struct ast_frame *current; 06437 const struct ast_channel_tech *t; 06438 void *t_pvt; 06439 union { 06440 struct ast_party_dialed dialed; 06441 struct ast_party_caller caller; 06442 struct ast_party_connected_line connected; 06443 struct ast_party_redirecting redirecting; 06444 } exchange; 06445 struct ast_channel *clonechan, *chans[2]; 06446 struct ast_channel *bridged; 06447 struct ast_cdr *cdr; 06448 struct ast_datastore *xfer_ds; 06449 struct xfer_masquerade_ds *xfer_colp; 06450 format_t rformat; 06451 format_t wformat; 06452 format_t tmp_format; 06453 char newn[AST_CHANNEL_NAME]; 06454 char orig[AST_CHANNEL_NAME]; 06455 char masqn[AST_CHANNEL_NAME]; 06456 char zombn[AST_CHANNEL_NAME]; 06457 06458 /* XXX This operation is a bit odd. We're essentially putting the guts of 06459 * the clone channel into the original channel. Start by killing off the 06460 * original channel's backend. While the features are nice, which is the 06461 * reason we're keeping it, it's still awesomely weird. XXX */ 06462 06463 /* 06464 * The reasoning for the channels ao2_container lock here is 06465 * complex. 06466 * 06467 * There is a race condition that exists for this function. 06468 * Since all pvt and channel locks must be let go before calling 06469 * ast_do_masquerade, it is possible that it could be called 06470 * multiple times for the same channel. In order to prevent the 06471 * race condition with competing threads to do the masquerade 06472 * and new masquerade attempts, the channels container must be 06473 * locked for the entire masquerade. The original and clonechan 06474 * need to be unlocked earlier to avoid potential deadlocks with 06475 * the chan_local deadlock avoidance method. 06476 * 06477 * The container lock blocks competing masquerade attempts from 06478 * starting as well as being necessary for proper locking order 06479 * because the channels must to be unlinked to change their 06480 * names. 06481 * 06482 * The original and clonechan locks must be held while the 06483 * channel contents are shuffled around for the masquerade. 06484 * 06485 * The masq and masqr pointers need to be left alone until the 06486 * masquerade has restabilized the channels to prevent another 06487 * masquerade request until the AST_FLAG_ZOMBIE can be set on 06488 * the clonechan. 06489 */ 06490 ao2_lock(channels); 06491 06492 /* 06493 * Lock the original channel to determine if the masquerade is 06494 * still required. 06495 */ 06496 ast_channel_lock(original); 06497 06498 clonechan = original->masq; 06499 if (!clonechan) { 06500 /* 06501 * The masq is already completed by another thread or never 06502 * needed to be done to begin with. 06503 */ 06504 ast_channel_unlock(original); 06505 ao2_unlock(channels); 06506 return 0; 06507 } 06508 06509 /* Bump the refs to ensure that they won't dissapear on us. */ 06510 ast_channel_ref(original); 06511 ast_channel_ref(clonechan); 06512 06513 /* unlink from channels container as name (which is the hash value) will change */ 06514 ao2_unlink(channels, original); 06515 ao2_unlink(channels, clonechan); 06516 06517 /* Get any transfer masquerade connected line exchange data. */ 06518 xfer_ds = ast_channel_datastore_find(original, &xfer_ds_info, NULL); 06519 if (xfer_ds) { 06520 ast_channel_datastore_remove(original, xfer_ds); 06521 xfer_colp = xfer_ds->data; 06522 } else { 06523 xfer_colp = NULL; 06524 } 06525 06526 /* 06527 * Stop any visible indication on the original channel so we can 06528 * transfer it to the clonechan taking the original's place. 06529 */ 06530 visible_indication = original->visible_indication; 06531 ast_channel_unlock(original); 06532 ast_indicate(original, -1); 06533 06534 /* 06535 * Release any hold on the transferee channel before going any 06536 * further with the masquerade. 06537 */ 06538 if (xfer_colp && xfer_colp->transferee_held) { 06539 ast_indicate(clonechan, AST_CONTROL_UNHOLD); 06540 } 06541 06542 /* Start the masquerade channel contents rearangement. */ 06543 ast_channel_lock_both(original, clonechan); 06544 06545 ast_debug(4, "Actually Masquerading %s(%d) into the structure of %s(%d)\n", 06546 clonechan->name, clonechan->_state, original->name, original->_state); 06547 06548 chans[0] = clonechan; 06549 chans[1] = original; 06550 ast_manager_event_multichan(EVENT_FLAG_CALL, "Masquerade", 2, chans, 06551 "Clone: %s\r\n" 06552 "CloneState: %s\r\n" 06553 "Original: %s\r\n" 06554 "OriginalState: %s\r\n", 06555 clonechan->name, ast_state2str(clonechan->_state), original->name, ast_state2str(original->_state)); 06556 06557 /* 06558 * Remember the original read/write formats. We turn off any 06559 * translation on either one 06560 */ 06561 rformat = original->readformat; 06562 wformat = original->writeformat; 06563 free_translation(clonechan); 06564 free_translation(original); 06565 06566 /* Save the original name */ 06567 ast_copy_string(orig, original->name, sizeof(orig)); 06568 /* Save the new name */ 06569 ast_copy_string(newn, clonechan->name, sizeof(newn)); 06570 /* Create the masq name */ 06571 snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn); 06572 06573 /* Mangle the name of the clone channel */ 06574 __ast_change_name_nolink(clonechan, masqn); 06575 06576 /* Copy the name from the clone channel */ 06577 __ast_change_name_nolink(original, newn); 06578 06579 /* share linked id's */ 06580 ast_channel_set_linkgroup(original, clonechan); 06581 06582 /* Swap the technologies */ 06583 t = original->tech; 06584 original->tech = clonechan->tech; 06585 clonechan->tech = t; 06586 06587 t_pvt = original->tech_pvt; 06588 original->tech_pvt = clonechan->tech_pvt; 06589 clonechan->tech_pvt = t_pvt; 06590 06591 /* Swap the cdrs */ 06592 cdr = original->cdr; 06593 original->cdr = clonechan->cdr; 06594 clonechan->cdr = cdr; 06595 06596 /* Swap the alertpipes */ 06597 for (i = 0; i < 2; i++) { 06598 x = original->alertpipe[i]; 06599 original->alertpipe[i] = clonechan->alertpipe[i]; 06600 clonechan->alertpipe[i] = x; 06601 } 06602 06603 /* 06604 * Swap the readq's. The end result should be this: 06605 * 06606 * 1) All frames should be on the new (original) channel. 06607 * 2) Any frames that were already on the new channel before this 06608 * masquerade need to be at the end of the readq, after all of the 06609 * frames on the old (clone) channel. 06610 * 3) The alertpipe needs to get poked for every frame that was already 06611 * on the new channel, since we are now using the alert pipe from the 06612 * old (clone) channel. 06613 */ 06614 { 06615 AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq; 06616 06617 AST_LIST_HEAD_INIT_NOLOCK(&tmp_readq); 06618 AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list); 06619 AST_LIST_APPEND_LIST(&original->readq, &clonechan->readq, frame_list); 06620 06621 while ((current = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) { 06622 AST_LIST_INSERT_TAIL(&original->readq, current, frame_list); 06623 if (original->alertpipe[1] > -1) { 06624 int poke = 0; 06625 06626 if (write(original->alertpipe[1], &poke, sizeof(poke)) < 0) { 06627 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 06628 } 06629 } 06630 } 06631 } 06632 06633 /* Swap the raw formats */ 06634 tmp_format = original->rawreadformat; 06635 original->rawreadformat = clonechan->rawreadformat; 06636 clonechan->rawreadformat = tmp_format; 06637 06638 tmp_format = original->rawwriteformat; 06639 original->rawwriteformat = clonechan->rawwriteformat; 06640 clonechan->rawwriteformat = tmp_format; 06641 06642 clonechan->_softhangup = AST_SOFTHANGUP_DEV; 06643 06644 /* And of course, so does our current state. Note we need not 06645 call ast_setstate since the event manager doesn't really consider 06646 these separate. We do this early so that the clone has the proper 06647 state of the original channel. */ 06648 origstate = original->_state; 06649 original->_state = clonechan->_state; 06650 clonechan->_state = origstate; 06651 06652 /* Mangle the name of the clone channel */ 06653 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig); /* quick, hide the brains! */ 06654 __ast_change_name_nolink(clonechan, zombn); 06655 06656 /* Update the type. */ 06657 t_pvt = original->monitor; 06658 original->monitor = clonechan->monitor; 06659 clonechan->monitor = t_pvt; 06660 06661 /* Keep the same language. */ 06662 ast_string_field_set(original, language, clonechan->language); 06663 /* Copy the FD's other than the generator fd */ 06664 for (x = 0; x < AST_MAX_FDS; x++) { 06665 if (x != AST_GENERATOR_FD) 06666 ast_channel_set_fd(original, x, clonechan->fds[x]); 06667 } 06668 06669 ast_app_group_update(clonechan, original); 06670 06671 /* Move data stores over */ 06672 if (AST_LIST_FIRST(&clonechan->datastores)) { 06673 struct ast_datastore *ds; 06674 /* We use a safe traversal here because some fixup routines actually 06675 * remove the datastore from the list and free them. 06676 */ 06677 AST_LIST_TRAVERSE_SAFE_BEGIN(&clonechan->datastores, ds, entry) { 06678 if (ds->info->chan_fixup) 06679 ds->info->chan_fixup(ds->data, clonechan, original); 06680 } 06681 AST_LIST_TRAVERSE_SAFE_END; 06682 AST_LIST_APPEND_LIST(&original->datastores, &clonechan->datastores, entry); 06683 } 06684 06685 ast_autochan_new_channel(clonechan, original); 06686 06687 clone_variables(original, clonechan); 06688 /* Presense of ADSI capable CPE follows clone */ 06689 original->adsicpe = clonechan->adsicpe; 06690 /* Bridge remains the same */ 06691 /* CDR fields remain the same */ 06692 /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */ 06693 /* Application and data remain the same */ 06694 /* Clone exception becomes real one, as with fdno */ 06695 ast_set_flag(original, ast_test_flag(clonechan, AST_FLAG_EXCEPTION | AST_FLAG_OUTGOING)); 06696 original->fdno = clonechan->fdno; 06697 /* Schedule context remains the same */ 06698 /* Stream stuff stays the same */ 06699 /* Keep the original state. The fixup code will need to work with it most likely */ 06700 06701 /* 06702 * Just swap the whole structures, nevermind the allocations, 06703 * they'll work themselves out. 06704 */ 06705 exchange.dialed = original->dialed; 06706 original->dialed = clonechan->dialed; 06707 clonechan->dialed = exchange.dialed; 06708 06709 exchange.caller = original->caller; 06710 original->caller = clonechan->caller; 06711 clonechan->caller = exchange.caller; 06712 06713 exchange.connected = original->connected; 06714 original->connected = clonechan->connected; 06715 clonechan->connected = exchange.connected; 06716 06717 exchange.redirecting = original->redirecting; 06718 original->redirecting = clonechan->redirecting; 06719 clonechan->redirecting = exchange.redirecting; 06720 06721 report_new_callerid(original); 06722 06723 /* Restore original timing file descriptor */ 06724 ast_channel_set_fd(original, AST_TIMING_FD, original->timingfd); 06725 06726 /* Our native formats are different now */ 06727 original->nativeformats = clonechan->nativeformats; 06728 06729 /* Context, extension, priority, app data, jump table, remain the same */ 06730 /* pvt switches. pbx stays the same, as does next */ 06731 06732 /* Set the write format */ 06733 ast_set_write_format(original, wformat); 06734 06735 /* Set the read format */ 06736 ast_set_read_format(original, rformat); 06737 06738 /* Copy the music class */ 06739 ast_string_field_set(original, musicclass, clonechan->musicclass); 06740 06741 /* copy over accuntcode and set peeraccount across the bridge */ 06742 ast_string_field_set(original, accountcode, S_OR(clonechan->accountcode, "")); 06743 if (original->_bridge) { 06744 /* XXX - should we try to lock original->_bridge here? */ 06745 ast_string_field_set(original->_bridge, peeraccount, S_OR(clonechan->accountcode, "")); 06746 ast_cel_report_event(original, AST_CEL_BRIDGE_UPDATE, NULL, NULL, NULL); 06747 } 06748 06749 ast_debug(1, "Putting channel %s in %s/%s formats\n", original->name, 06750 ast_getformatname(wformat), ast_getformatname(rformat)); 06751 06752 /* Fixup the original clonechan's physical side */ 06753 if (original->tech->fixup && original->tech->fixup(clonechan, original)) { 06754 ast_log(LOG_WARNING, "Channel type '%s' could not fixup channel %s, strange things may happen. (clonechan)\n", 06755 original->tech->type, original->name); 06756 } 06757 06758 /* Fixup the original original's physical side */ 06759 if (clonechan->tech->fixup && clonechan->tech->fixup(original, clonechan)) { 06760 ast_log(LOG_WARNING, "Channel type '%s' could not fixup channel %s, strange things may happen. (original)\n", 06761 clonechan->tech->type, clonechan->name); 06762 } 06763 06764 /* 06765 * Now, at this point, the "clone" channel is totally F'd up. 06766 * We mark it as a zombie so nothing tries to touch it. If it's 06767 * already been marked as a zombie, then we must free it (since 06768 * it already is considered invalid). 06769 * 06770 * This must be done before we unlock clonechan to prevent 06771 * setting up another masquerade on the clonechan. 06772 */ 06773 if (ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) { 06774 clone_was_zombie = 1; 06775 } else { 06776 ast_set_flag(clonechan, AST_FLAG_ZOMBIE); 06777 ast_queue_frame(clonechan, &ast_null_frame); 06778 } 06779 06780 /* clear the masquerade channels */ 06781 original->masq = NULL; 06782 clonechan->masqr = NULL; 06783 06784 /* 06785 * When we unlock original here, it can be immediately setup to 06786 * masquerade again or hungup. The new masquerade or hangup 06787 * will not actually happen until we release the channels 06788 * container lock. 06789 */ 06790 ast_channel_unlock(original); 06791 06792 /* Disconnect the original original's physical side */ 06793 if (clonechan->tech->hangup && clonechan->tech->hangup(clonechan)) { 06794 ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n"); 06795 } else { 06796 /* 06797 * We just hung up the original original's physical side of the 06798 * channel. Set the new zombie to use the kill channel driver 06799 * for safety. 06800 */ 06801 clonechan->tech = &ast_kill_tech; 06802 } 06803 06804 ast_channel_unlock(clonechan); 06805 06806 /* 06807 * If an indication is currently playing, maintain it on the 06808 * channel that is taking the place of original. 06809 * 06810 * This is needed because the masquerade is swapping out the 06811 * internals of the channel, and the new channel private data 06812 * needs to be made aware of the current visible indication 06813 * (RINGING, CONGESTION, etc.) 06814 */ 06815 if (visible_indication) { 06816 ast_indicate(original, visible_indication); 06817 } 06818 06819 ast_channel_lock(original); 06820 06821 /* Signal any blocker */ 06822 if (ast_test_flag(original, AST_FLAG_BLOCKING)) { 06823 pthread_kill(original->blocker, SIGURG); 06824 } 06825 06826 ast_debug(1, "Done Masquerading %s (%d)\n", original->name, original->_state); 06827 06828 if ((bridged = ast_bridged_channel(original))) { 06829 ast_channel_ref(bridged); 06830 ast_channel_unlock(original); 06831 ast_indicate(bridged, AST_CONTROL_SRCCHANGE); 06832 ast_channel_unref(bridged); 06833 } else { 06834 ast_channel_unlock(original); 06835 } 06836 ast_indicate(original, AST_CONTROL_SRCCHANGE); 06837 06838 if (xfer_colp) { 06839 /* 06840 * After the masquerade, the original channel pointer actually 06841 * points to the new transferee channel and the bridged channel 06842 * is still the intended transfer target party. 06843 */ 06844 masquerade_colp_transfer(original, xfer_colp); 06845 } 06846 06847 if (xfer_ds) { 06848 ast_datastore_free(xfer_ds); 06849 } 06850 06851 if (clone_was_zombie) { 06852 ast_channel_lock(clonechan); 06853 ast_debug(1, "Destroying channel clone '%s'\n", clonechan->name); 06854 ast_manager_event(clonechan, EVENT_FLAG_CALL, "Hangup", 06855 "Channel: %s\r\n" 06856 "Uniqueid: %s\r\n" 06857 "Cause: %d\r\n" 06858 "Cause-txt: %s\r\n", 06859 clonechan->name, 06860 clonechan->uniqueid, 06861 clonechan->hangupcause, 06862 ast_cause2str(clonechan->hangupcause) 06863 ); 06864 ast_channel_unlock(clonechan); 06865 06866 /* 06867 * Drop the system reference to destroy the channel since it is 06868 * already unlinked. 06869 */ 06870 ast_channel_unref(clonechan); 06871 } else { 06872 ao2_link(channels, clonechan); 06873 } 06874 06875 ao2_link(channels, original); 06876 ao2_unlock(channels); 06877 06878 /* Release our held safety references. */ 06879 ast_channel_unref(original); 06880 ast_channel_unref(clonechan); 06881 06882 return 0; 06883 }
struct ast_channel* ast_dummy_channel_alloc | ( | void | ) |
Create a fake channel structure.
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 1380 of file channel.c.
References __ao2_alloc_debug(), ao2_alloc, ast_channel_unref, ast_dummy_channel_destructor(), AST_LIST_HEAD_INIT_NOLOCK, and ast_string_field_init.
Referenced by acf_odbc_read(), acf_odbc_write(), action_getvar(), ast_add_extension2_lockopt(), ast_cel_fabricate_channel_from_event(), ast_pbx_outgoing_cdr_failed(), ast_str_substitute_variables_full(), custom_log(), make_email_file(), manager_log(), pbx_substitute_variables_helper_full(), rotate_file(), sendmail(), sendpage(), syslog_log(), and write_cdr().
01382 { 01383 struct ast_channel *tmp; 01384 struct varshead *headp; 01385 01386 #if defined(REF_DEBUG) 01387 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel", 01388 file, line, function, 1); 01389 #elif defined(__AST_DEBUG_MALLOC) 01390 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel", 01391 file, line, function, 0); 01392 #else 01393 tmp = ao2_alloc(sizeof(*tmp), ast_dummy_channel_destructor); 01394 #endif 01395 if (!tmp) { 01396 /* Dummy channel structure allocation failure. */ 01397 return NULL; 01398 } 01399 01400 if ((ast_string_field_init(tmp, 128))) { 01401 return ast_channel_unref(tmp); 01402 } 01403 01404 headp = &tmp->varshead; 01405 AST_LIST_HEAD_INIT_NOLOCK(headp); 01406 01407 return tmp; 01408 }
static int ast_fdisset | ( | struct pollfd * | pfds, | |
int | fd, | |||
int | maximum, | |||
int * | start | |||
) | [inline, static] |
Helper function for migrating select to poll.
Definition at line 2378 of file channel.h.
References dummy().
02379 { 02380 int x; 02381 int dummy = 0; 02382 02383 if (fd < 0) 02384 return 0; 02385 if (!start) 02386 start = &dummy; 02387 for (x = *start; x < maximum; x++) 02388 if (pfds[x].fd == fd) { 02389 if (x == *start) 02390 (*start)++; 02391 return pfds[x].revents; 02392 } 02393 return 0; 02394 }
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 949 of file channel.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, chanlist::list, chanlist::tech, and ast_channel_tech::type.
Referenced by __ast_channel_alloc_ap(), _ast_device_state(), ast_cc_callback(), and ast_var_channel_types_table().
00950 { 00951 struct chanlist *chanls; 00952 const struct ast_channel_tech *ret = NULL; 00953 00954 AST_RWLIST_RDLOCK(&backends); 00955 00956 AST_RWLIST_TRAVERSE(&backends, chanls, list) { 00957 if (!strcasecmp(name, chanls->tech->type)) { 00958 ret = chanls->tech; 00959 break; 00960 } 00961 } 00962 00963 AST_RWLIST_UNLOCK(&backends); 00964 00965 return ret; 00966 }
ast_group_t ast_get_group | ( | const char * | s | ) |
Definition at line 7800 of file channel.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), LOG_ERROR, LOG_WARNING, and strsep().
Referenced by _parse(), build_device(), build_peer(), config_parse_variables(), func_channel_write_real(), and read_agent_config().
07801 { 07802 char *piece; 07803 char *c; 07804 int start=0, finish=0, x; 07805 ast_group_t group = 0; 07806 07807 if (ast_strlen_zero(s)) 07808 return 0; 07809 07810 c = ast_strdupa(s); 07811 07812 while ((piece = strsep(&c, ","))) { 07813 if (sscanf(piece, "%30d-%30d", &start, &finish) == 2) { 07814 /* Range */ 07815 } else if (sscanf(piece, "%30d", &start)) { 07816 /* Just one */ 07817 finish = start; 07818 } else { 07819 ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece); 07820 continue; 07821 } 07822 for (x = start; x <= finish; x++) { 07823 if ((x > 63) || (x < 0)) { 07824 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x); 07825 } else 07826 group |= ((ast_group_t) 1 << x); 07827 } 07828 } 07829 return group; 07830 }
int ast_hangup | ( | struct ast_channel * | chan | ) |
Hang up a channel.
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 2771 of file channel.c.
References ao2_unlink, ast_assert, ast_autoservice_stop(), ast_cause2str(), ast_cc_offer(), ast_cdr_detach(), ast_cdr_end(), AST_CDR_FLAG_BRIDGED, AST_CDR_FLAG_DIALED, AST_CDR_FLAG_POST_DISABLED, AST_CDR_NULL, AST_CEL_HANGUP, ast_cel_report_event(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_closestream(), ast_debug, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_log(), ast_manager_event, ast_set_flag, ast_test_flag, ast_channel::blocker, ast_channel::blockproc, ast_channel::caller, ast_channel::cdr, chanlist::chan, channels, ast_channel::connected, destroy_hooks(), ast_cdr::disposition, EVENT_FLAG_CALL, free_translation(), ast_channel::generator, ast_channel::generatordata, ast_channel_tech::hangup, ast_channel::hangupcause, ast_channel::hangupsource, ast_party_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_call_thread_launch(), bridge_channel_thread(), bridge_exec(), build_conf(), builtin_atxfer(), chanavail_exec(), check_availability(), check_compat(), check_goto_on_transfer(), clear_caller(), conf_run(), console_new(), dahdi_handle_event(), dahdi_new(), destroy_conference_bridge(), dial_exec_full(), dial_transfer(), do_forward(), do_hang(), do_idle_thread(), feature_attended_transfer(), feature_request_and_dial(), findmeexec(), generic_recall(), gtalk_new(), handle_call_forward(), handle_callforward_button(), handle_enbloc_call_message(), handle_frame(), handle_frame_ownerless(), handle_hd_hf(), handle_init_event(), handle_invite_replaces(), handle_offhook_message(), handle_request_invite(), handle_soft_key_event_message(), handle_stimulus_message(), handle_timeout_trip(), handle_transfer_button(), HandleCallOutgoing(), hangup_chan(), hangupcalls(), hanguptree(), iax2_request(), iax_park(), iax_park_thread(), jingle_new(), local_hangup(), manage_parked_call(), masq_park_call(), mgcp_new(), mgcp_ss(), monitor_dial(), mwi_thread(), my_distinctive_ring(), my_handle_notify_message(), nbs_new(), oss_new(), parkandannounce_exec(), parked_call_exec(), phone_new(), play_sound_file(), pri_dchannel(), pri_ss_thread(), sip_park(), sip_park_thread(), sip_pickup_thread(), skinny_new(), skinny_ss(), unistim_new(), and wait_for_winner().
02772 { 02773 char extra_str[64]; /* used for cel logging below */ 02774 int was_zombie; 02775 02776 ast_autoservice_stop(chan); 02777 02778 ast_channel_lock(chan); 02779 02780 /* 02781 * Do the masquerade if someone is setup to masquerade into us. 02782 * 02783 * NOTE: We must hold the channel lock after testing for a 02784 * pending masquerade and setting the channel as a zombie to 02785 * prevent __ast_channel_masquerade() from setting up a 02786 * masquerade with a dead channel. 02787 */ 02788 while (chan->masq) { 02789 ast_channel_unlock(chan); 02790 ast_do_masquerade(chan); 02791 ast_channel_lock(chan); 02792 } 02793 02794 if (chan->masqr) { 02795 /* 02796 * This channel is one which will be masqueraded into something. 02797 * Mark it as a zombie already so ast_do_masquerade() will know 02798 * to free it later. 02799 */ 02800 ast_set_flag(chan, AST_FLAG_ZOMBIE); 02801 destroy_hooks(chan); 02802 ast_channel_unlock(chan); 02803 return 0; 02804 } 02805 02806 /* Mark as a zombie so a masquerade cannot be setup on this channel. */ 02807 if (!(was_zombie = ast_test_flag(chan, AST_FLAG_ZOMBIE))) { 02808 ast_set_flag(chan, AST_FLAG_ZOMBIE); 02809 } 02810 02811 ast_channel_unlock(chan); 02812 ao2_unlink(channels, chan); 02813 ast_channel_lock(chan); 02814 02815 destroy_hooks(chan); 02816 02817 free_translation(chan); 02818 /* Close audio stream */ 02819 if (chan->stream) { 02820 ast_closestream(chan->stream); 02821 chan->stream = NULL; 02822 } 02823 /* Close video stream */ 02824 if (chan->vstream) { 02825 ast_closestream(chan->vstream); 02826 chan->vstream = NULL; 02827 } 02828 if (chan->sched) { 02829 sched_context_destroy(chan->sched); 02830 chan->sched = NULL; 02831 } 02832 02833 if (chan->generatordata) { /* Clear any tone stuff remaining */ 02834 if (chan->generator && chan->generator->release) { 02835 chan->generator->release(chan, chan->generatordata); 02836 } 02837 } 02838 chan->generatordata = NULL; 02839 chan->generator = NULL; 02840 02841 snprintf(extra_str, sizeof(extra_str), "%d,%s,%s", chan->hangupcause, chan->hangupsource, S_OR(pbx_builtin_getvar_helper(chan, "DIALSTATUS"), "")); 02842 ast_cel_report_event(chan, AST_CEL_HANGUP, NULL, extra_str, NULL); 02843 02844 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) { 02845 ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd " 02846 "is blocked by thread %ld in procedure %s! Expect a failure\n", 02847 (long) pthread_self(), chan->name, (long)chan->blocker, chan->blockproc); 02848 ast_assert(ast_test_flag(chan, AST_FLAG_BLOCKING) == 0); 02849 } 02850 if (!was_zombie) { 02851 ast_debug(1, "Hanging up channel '%s'\n", chan->name); 02852 02853 if (chan->tech->hangup) { 02854 chan->tech->hangup(chan); 02855 } 02856 } else { 02857 ast_debug(1, "Hanging up zombie '%s'\n", chan->name); 02858 } 02859 02860 ast_channel_unlock(chan); 02861 02862 ast_cc_offer(chan); 02863 ast_manager_event(chan, EVENT_FLAG_CALL, "Hangup", 02864 "Channel: %s\r\n" 02865 "Uniqueid: %s\r\n" 02866 "CallerIDNum: %s\r\n" 02867 "CallerIDName: %s\r\n" 02868 "ConnectedLineNum: %s\r\n" 02869 "ConnectedLineName: %s\r\n" 02870 "Cause: %d\r\n" 02871 "Cause-txt: %s\r\n", 02872 chan->name, 02873 chan->uniqueid, 02874 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "<unknown>"), 02875 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, "<unknown>"), 02876 S_COR(chan->connected.id.number.valid, chan->connected.id.number.str, "<unknown>"), 02877 S_COR(chan->connected.id.name.valid, chan->connected.id.name.str, "<unknown>"), 02878 chan->hangupcause, 02879 ast_cause2str(chan->hangupcause) 02880 ); 02881 02882 if (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_BRIDGED) && 02883 !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED) && 02884 (chan->cdr->disposition != AST_CDR_NULL || ast_test_flag(chan->cdr, AST_CDR_FLAG_DIALED))) { 02885 ast_channel_lock(chan); 02886 ast_cdr_end(chan->cdr); 02887 ast_cdr_detach(chan->cdr); 02888 chan->cdr = NULL; 02889 ast_channel_unlock(chan); 02890 } 02891 02892 ast_channel_unref(chan); 02893 02894 return 0; 02895 }
int ast_indicate | ( | struct ast_channel * | chan, | |
int | condition | |||
) |
Indicates condition of channel.
Indicate a condition such as AST_CONTROL_BUSY, AST_CONTROL_RINGING, or AST_CONTROL_CONGESTION on a channel
chan | channel to change the indication | |
condition | which condition to indicate on the channel |
Definition at line 4296 of file channel.c.
References ast_indicate_data(), and chanlist::chan.
Referenced by __ast_play_and_record(), agent_request(), alsa_call(), answer_trunk_chan(), ast_bridge_call(), ast_channel_bridge(), ast_do_masquerade(), ast_dtmf_stream(), ast_raw_answer(), attempt_transfer(), builtin_atxfer(), builtin_blindtransfer(), cli_console_answer(), conf_run(), console_call(), dial_exec_full(), do_forward(), feature_request_and_dial(), finishup(), handle_callforward_button(), handle_frame(), handle_recordfile(), handle_request_refer(), local_attended_transfer(), manage_parked_call(), mgcp_ss(), monitor_dial(), oss_call(), park_call_full(), parked_call_exec(), pbx_builtin_busy(), pbx_builtin_congestion(), pbx_builtin_incomplete(), pbx_builtin_proceeding(), pbx_builtin_progress(), pbx_builtin_ringing(), pbx_builtin_waitexten(), queue_exec(), rna(), say_periodic_announcement(), say_position(), send_waveform_to_channel(), skinny_ss(), sla_handle_hold_event(), sla_station_exec(), and sla_trunk_exec().
04297 { 04298 return ast_indicate_data(chan, condition, NULL, 0); 04299 }
int ast_indicate_data | ( | struct ast_channel * | chan, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) |
Indicates condition of channel, with payload.
Indicate a condition such as AST_CONTROL_HOLD with payload being music on hold class
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 4350 of file channel.c.
References ast_channel::_state, _XXX_AST_CONTROL_T38, ast_channel_lock, ast_channel_set_connected_line(), ast_channel_set_redirecting(), ast_channel_unlock, ast_check_hangup(), ast_connected_line_parse_data(), AST_CONTROL_ANSWER, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CC, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_END_OF_Q, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_READ_ACTION, AST_CONTROL_REDIRECTING, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_TRANSFER, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_CONTROL_VIDUPDATE, AST_CONTROL_WINK, ast_debug, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, ast_framehook_list_is_empty(), ast_framehook_list_write_event(), ast_frdup(), ast_frfree, ast_get_indication_tone(), ast_log(), ast_party_connected_line_free(), ast_party_connected_line_set_init(), ast_party_redirecting_free(), ast_party_redirecting_set_init(), ast_playtones_start(), ast_playtones_stop(), ast_redirecting_parse_data(), AST_STATE_UP, ast_test_flag, ast_tone_zone_sound_unref(), chanlist::chan, 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().
04352 { 04353 /* By using an enum, we'll get compiler warnings for values not handled 04354 * in switch statements. */ 04355 enum ast_control_frame_type condition = _condition; 04356 struct ast_tone_zone_sound *ts = NULL; 04357 int res; 04358 /* this frame is used by framehooks. if it is set, we must free it at the end of this function */ 04359 struct ast_frame *awesome_frame = NULL; 04360 04361 ast_channel_lock(chan); 04362 04363 /* Don't bother if the channel is about to go away, anyway. */ 04364 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 04365 res = -1; 04366 goto indicate_cleanup; 04367 } 04368 04369 if (!ast_framehook_list_is_empty(chan->framehooks)) { 04370 /* Do framehooks now, do it, go, go now */ 04371 struct ast_frame frame = { 04372 .frametype = AST_FRAME_CONTROL, 04373 .subclass.integer = condition, 04374 .data.ptr = (void *) data, /* this cast from const is only okay because we do the ast_frdup below */ 04375 .datalen = datalen 04376 }; 04377 04378 /* we have now committed to freeing this frame */ 04379 awesome_frame = ast_frdup(&frame); 04380 04381 /* who knows what we will get back! the anticipation is killing me. */ 04382 if (!(awesome_frame = ast_framehook_list_write_event(chan->framehooks, awesome_frame)) 04383 || awesome_frame->frametype != AST_FRAME_CONTROL) { 04384 04385 res = 0; 04386 goto indicate_cleanup; 04387 } 04388 04389 condition = awesome_frame->subclass.integer; 04390 data = awesome_frame->data.ptr; 04391 datalen = awesome_frame->datalen; 04392 } 04393 04394 switch (condition) { 04395 case AST_CONTROL_CONNECTED_LINE: 04396 { 04397 struct ast_party_connected_line connected; 04398 04399 ast_party_connected_line_set_init(&connected, &chan->connected); 04400 res = ast_connected_line_parse_data(data, datalen, &connected); 04401 if (!res) { 04402 ast_channel_set_connected_line(chan, &connected, NULL); 04403 } 04404 ast_party_connected_line_free(&connected); 04405 } 04406 break; 04407 04408 case AST_CONTROL_REDIRECTING: 04409 { 04410 struct ast_party_redirecting redirecting; 04411 04412 ast_party_redirecting_set_init(&redirecting, &chan->redirecting); 04413 res = ast_redirecting_parse_data(data, datalen, &redirecting); 04414 if (!res) { 04415 ast_channel_set_redirecting(chan, &redirecting, NULL); 04416 } 04417 ast_party_redirecting_free(&redirecting); 04418 } 04419 break; 04420 04421 default: 04422 break; 04423 } 04424 04425 if (is_visible_indication(condition)) { 04426 /* A new visible indication is requested. */ 04427 chan->visible_indication = condition; 04428 } else if (condition == AST_CONTROL_UNHOLD || _condition < 0) { 04429 /* Visible indication is cleared/stopped. */ 04430 chan->visible_indication = 0; 04431 } 04432 04433 if (chan->tech->indicate) { 04434 /* See if the channel driver can handle this condition. */ 04435 res = chan->tech->indicate(chan, condition, data, datalen); 04436 } else { 04437 res = -1; 04438 } 04439 04440 if (!res) { 04441 /* The channel driver successfully handled this indication */ 04442 res = 0; 04443 goto indicate_cleanup; 04444 } 04445 04446 /* The channel driver does not support this indication, let's fake 04447 * it by doing our own tone generation if applicable. */ 04448 04449 /*!\note If we compare the enumeration type, which does not have any 04450 * negative constants, the compiler may optimize this code away. 04451 * Therefore, we must perform an integer comparison here. */ 04452 if (_condition < 0) { 04453 /* Stop any tones that are playing */ 04454 ast_playtones_stop(chan); 04455 res = 0; 04456 goto indicate_cleanup; 04457 } 04458 04459 /* Handle conditions that we have tones for. */ 04460 switch (condition) { 04461 case _XXX_AST_CONTROL_T38: 04462 /* deprecated T.38 control frame */ 04463 res = -1; 04464 goto indicate_cleanup; 04465 case AST_CONTROL_T38_PARAMETERS: 04466 /* there is no way to provide 'default' behavior for these 04467 * control frames, so we need to return failure, but there 04468 * is also no value in the log message below being emitted 04469 * since failure to handle these frames is not an 'error' 04470 * so just return right now. in addition, we want to return 04471 * whatever value the channel driver returned, in case it 04472 * has some meaning.*/ 04473 goto indicate_cleanup; 04474 case AST_CONTROL_RINGING: 04475 ts = ast_get_indication_tone(chan->zone, "ring"); 04476 /* It is common practice for channel drivers to return -1 if trying 04477 * to indicate ringing on a channel which is up. The idea is to let the 04478 * core generate the ringing inband. However, we don't want the 04479 * warning message about not being able to handle the specific indication 04480 * to print nor do we want ast_indicate_data to return an "error" for this 04481 * condition 04482 */ 04483 if (chan->_state == AST_STATE_UP) { 04484 res = 0; 04485 } 04486 break; 04487 case AST_CONTROL_BUSY: 04488 ts = ast_get_indication_tone(chan->zone, "busy"); 04489 break; 04490 case AST_CONTROL_INCOMPLETE: 04491 case AST_CONTROL_CONGESTION: 04492 ts = ast_get_indication_tone(chan->zone, "congestion"); 04493 break; 04494 case AST_CONTROL_PROGRESS: 04495 case AST_CONTROL_PROCEEDING: 04496 case AST_CONTROL_VIDUPDATE: 04497 case AST_CONTROL_SRCUPDATE: 04498 case AST_CONTROL_SRCCHANGE: 04499 case AST_CONTROL_RADIO_KEY: 04500 case AST_CONTROL_RADIO_UNKEY: 04501 case AST_CONTROL_OPTION: 04502 case AST_CONTROL_WINK: 04503 case AST_CONTROL_FLASH: 04504 case AST_CONTROL_OFFHOOK: 04505 case AST_CONTROL_TAKEOFFHOOK: 04506 case AST_CONTROL_ANSWER: 04507 case AST_CONTROL_HANGUP: 04508 case AST_CONTROL_RING: 04509 case AST_CONTROL_HOLD: 04510 case AST_CONTROL_UNHOLD: 04511 case AST_CONTROL_TRANSFER: 04512 case AST_CONTROL_CONNECTED_LINE: 04513 case AST_CONTROL_REDIRECTING: 04514 case AST_CONTROL_CC: 04515 case AST_CONTROL_READ_ACTION: 04516 case AST_CONTROL_AOC: 04517 case AST_CONTROL_END_OF_Q: 04518 case AST_CONTROL_UPDATE_RTP_PEER: 04519 /* Nothing left to do for these. */ 04520 res = 0; 04521 break; 04522 } 04523 04524 if (ts) { 04525 /* We have a tone to play, yay. */ 04526 ast_debug(1, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition); 04527 res = ast_playtones_start(chan, 0, ts->data, 1); 04528 ts = ast_tone_zone_sound_unref(ts); 04529 } 04530 04531 if (res) { 04532 /* not handled */ 04533 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name); 04534 } 04535 04536 indicate_cleanup: 04537 ast_channel_unlock(chan); 04538 if (awesome_frame) { 04539 ast_frfree(awesome_frame); 04540 } 04541 04542 return res; 04543 }
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 4281 of file channel.c.
References ast_opt_internal_timing, chanlist::chan, and ast_channel::timingfd.
Referenced by add_sdp(), and ast_read_generator_actions().
04282 { 04283 return (ast_opt_internal_timing && chan->timingfd > -1); 04284 }
int ast_is_deferrable_frame | ( | const struct ast_frame * | frame | ) |
Should we keep this frame for later?
There are functions such as ast_safe_sleep which will service a channel to ensure that it does not have a large backlog of queued frames. When this happens, we want to hold on to specific frame types and just drop others. This function will tell if the frame we just read should be held onto.
frame | The frame we just read |
1 | frame should be kept | |
0 | frame should be dropped |
Definition at line 1790 of file channel.c.
References AST_FRAME_CNG, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_HTML, AST_FRAME_IAX, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, and ast_frame::frametype.
Referenced by ast_safe_sleep_conditional(), autoservice_run(), and feature_request_and_dial().
01791 { 01792 /* Do not add a default entry in this switch statement. Each new 01793 * frame type should be addressed directly as to whether it should 01794 * be queued up or not. 01795 */ 01796 switch (frame->frametype) { 01797 case AST_FRAME_CONTROL: 01798 case AST_FRAME_TEXT: 01799 case AST_FRAME_IMAGE: 01800 case AST_FRAME_HTML: 01801 return 1; 01802 01803 case AST_FRAME_DTMF_END: 01804 case AST_FRAME_DTMF_BEGIN: 01805 case AST_FRAME_VOICE: 01806 case AST_FRAME_VIDEO: 01807 case AST_FRAME_NULL: 01808 case AST_FRAME_IAX: 01809 case AST_FRAME_CNG: 01810 case AST_FRAME_MODEM: 01811 return 0; 01812 } 01813 return 0; 01814 }
void ast_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 2244 of file channel.c.
References ast_party_caller::ani, ast_party_caller::ani2, ast_party_id_copy(), and ast_party_caller::id.
02245 { 02246 if (dest == src) { 02247 /* Don't copy to self */ 02248 return; 02249 } 02250 02251 ast_party_id_copy(&dest->id, &src->id); 02252 ast_party_id_copy(&dest->ani, &src->ani); 02253 dest->ani2 = src->ani2; 02254 }
void ast_party_caller_free | ( | struct ast_party_caller * | doomed | ) |
Destroy the caller party contents.
doomed | The caller party to destroy. |
Definition at line 2270 of file channel.c.
References ast_party_caller::ani, ast_party_id_free(), and ast_party_caller::id.
Referenced by ast_channel_destructor(), ast_dummy_channel_destructor(), callerid_write(), dial_trunk(), and sla_ring_station().
02271 { 02272 ast_party_id_free(&doomed->id); 02273 ast_party_id_free(&doomed->ani); 02274 }
void ast_party_caller_init | ( | struct ast_party_caller * | init | ) |
Initialize the given caller structure.
init | Caller structure to initialize. |
Definition at line 2237 of file channel.c.
References ast_party_caller::ani, ast_party_caller::ani2, ast_party_id_init(), and ast_party_caller::id.
Referenced by __ast_channel_alloc_ap(), dial_trunk(), sig_pri_set_caller_id(), and sla_ring_station().
02238 { 02239 ast_party_id_init(&init->id); 02240 ast_party_id_init(&init->ani); 02241 init->ani2 = 0; 02242 }
void ast_party_caller_set | ( | struct ast_party_caller * | dest, | |
const struct ast_party_caller * | src, | |||
const struct ast_set_party_caller * | update | |||
) |
Set the caller information based on another caller source.
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 2263 of file channel.c.
References ast_party_caller::ani, ast_party_caller::ani2, ast_party_id_set(), ast_party_caller::id, and update().
Referenced by ast_channel_set_caller(), ast_channel_set_caller_event(), and callerid_write().
02264 { 02265 ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL); 02266 ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL); 02267 dest->ani2 = src->ani2; 02268 }
void ast_party_caller_set_init | ( | struct ast_party_caller * | init, | |
const struct ast_party_caller * | guide | |||
) |
Initialize the given caller structure using the given guide for a set update operation.
init | Caller structure to initialize. | |
guide | Source caller to use as a guide in initializing. |
Definition at line 2256 of file channel.c.
References ast_party_caller::ani, ast_party_caller::ani2, ast_party_id_set_init(), and ast_party_caller::id.
Referenced by callerid_write(), dial_exec_full(), do_forward(), misdn_update_caller_id(), ring_entry(), and sig_pri_handle_subcmds().
02257 { 02258 ast_party_id_set_init(&init->id, &guide->id); 02259 ast_party_id_set_init(&init->ani, &guide->ani); 02260 init->ani2 = guide->ani2; 02261 }
void ast_party_connected_line_collect_caller | ( | struct ast_party_connected_line * | connected, | |
struct ast_party_caller * | caller | |||
) |
Collect the caller party information into a connected line structure.
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 2313 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.
02314 { 02315 connected->id = caller->id; 02316 connected->ani = caller->ani; 02317 connected->ani2 = caller->ani2; 02318 connected->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN; 02319 }
void ast_party_connected_line_copy | ( | struct ast_party_connected_line * | dest, | |
const struct ast_party_connected_line * | src | |||
) |
Copy the source connected line information to the destination connected line.
dest | Destination connected line | |
src | Source connected line |
Definition at line 2284 of file channel.c.
References ast_party_connected_line::ani, ast_party_connected_line::ani2, ast_party_id_copy(), ast_party_connected_line::id, and ast_party_connected_line::source.
Referenced by __ast_read(), ast_call_forward(), ast_channel_connected_line_macro(), ast_do_pickup(), builtin_atxfer(), dial_exec_full(), do_forward(), local_attended_transfer(), misdn_attempt_transfer(), and party_connected_line_copy_transfer().
02285 { 02286 if (dest == src) { 02287 /* Don't copy to self */ 02288 return; 02289 } 02290 02291 ast_party_id_copy(&dest->id, &src->id); 02292 ast_party_id_copy(&dest->ani, &src->ani); 02293 dest->ani2 = src->ani2; 02294 dest->source = src->source; 02295 }
void ast_party_connected_line_free | ( | struct ast_party_connected_line * | doomed | ) |
Destroy the connected line information contents.
doomed | The connected line information to destroy. |
Definition at line 2321 of file channel.c.
References ast_party_connected_line::ani, ast_party_id_free(), and ast_party_connected_line::id.
Referenced by __ast_read(), app_exec(), ast_channel_connected_line_macro(), ast_channel_destructor(), ast_do_pickup(), ast_dummy_channel_destructor(), ast_indicate_data(), atxfer_fail_cleanup(), builtin_atxfer(), callattempt_free(), chanlist_free(), connectedline_write(), destroy_calling_tree(), feature_request_and_dial(), local_attended_transfer(), misdn_attempt_transfer(), parked_call_exec(), sig_pri_handle_subcmds(), socket_process(), wait_for_answer(), wait_for_winner(), and xfer_ds_destroy().
02322 { 02323 ast_party_id_free(&doomed->id); 02324 ast_party_id_free(&doomed->ani); 02325 }
void ast_party_connected_line_init | ( | struct ast_party_connected_line * | init | ) |
Initialize the given connected line structure.
init | Connected line structure to initialize. |
Definition at line 2276 of file channel.c.
References ast_party_connected_line::ani, ast_party_connected_line::ani2, AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN, ast_party_id_init(), ast_party_connected_line::id, and ast_party_connected_line::source.
Referenced by __ast_channel_alloc_ap(), __ast_read(), ast_channel_connected_line_macro(), ast_do_pickup(), builtin_atxfer(), do_forward(), handle_request_invite(), handle_request_update(), handle_response_invite(), local_attended_transfer(), misdn_attempt_transfer(), misdn_queue_connected_line_update(), parked_call_exec(), sig_pri_handle_subcmds(), sip_call(), socket_process(), and wait_for_answer().
02277 { 02278 ast_party_id_init(&init->id); 02279 ast_party_id_init(&init->ani); 02280 init->ani2 = 0; 02281 init->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN; 02282 }
void ast_party_connected_line_set | ( | struct ast_party_connected_line * | dest, | |
const struct ast_party_connected_line * | src, | |||
const struct ast_set_party_connected_line * | update | |||
) |
Set the connected line information based on another connected line source.
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 2305 of file channel.c.
References ast_party_connected_line::ani, ast_party_connected_line::ani2, ast_party_id_set(), ast_party_connected_line::id, ast_party_connected_line::source, and update().
Referenced by ast_channel_set_connected_line(), and wait_for_winner().
02306 { 02307 ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL); 02308 ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL); 02309 dest->ani2 = src->ani2; 02310 dest->source = src->source; 02311 }
void ast_party_connected_line_set_init | ( | struct ast_party_connected_line * | init, | |
const struct ast_party_connected_line * | guide | |||
) |
Initialize the given connected line structure using the given guide for a set update operation.
init | Connected line structure to initialize. | |
guide | Source connected line to use as a guide in initializing. |
Definition at line 2297 of file channel.c.
References ast_party_connected_line::ani, ast_party_connected_line::ani2, ast_party_id_set_init(), ast_party_connected_line::id, and ast_party_connected_line::source.
Referenced by __ast_request_and_dial(), ast_indicate_data(), connectedline_write(), dial_exec_full(), feature_request_and_dial(), and wait_for_winner().
02298 { 02299 ast_party_id_set_init(&init->id, &guide->id); 02300 ast_party_id_set_init(&init->ani, &guide->ani); 02301 init->ani2 = guide->ani2; 02302 init->source = guide->source; 02303 }
void ast_party_dialed_copy | ( | struct ast_party_dialed * | dest, | |
const struct ast_party_dialed * | src | |||
) |
Copy the source dialed party information to the destination dialed party.
dest | Destination dialed party | |
src | Source dialed party |
Definition at line 2195 of file channel.c.
References ast_free, ast_party_subaddress_copy(), ast_strdup, ast_party_dialed::number, ast_party_dialed::plan, ast_party_dialed::str, ast_party_dialed::subaddress, and ast_party_dialed::transit_network_select.
Referenced by local_call().
02196 { 02197 if (dest == src) { 02198 /* Don't copy to self */ 02199 return; 02200 } 02201 02202 ast_free(dest->number.str); 02203 dest->number.str = ast_strdup(src->number.str); 02204 dest->number.plan = src->number.plan; 02205 ast_party_subaddress_copy(&dest->subaddress, &src->subaddress); 02206 dest->transit_network_select = src->transit_network_select; 02207 }
void ast_party_dialed_free | ( | struct ast_party_dialed * | doomed | ) |
Destroy the dialed party contents.
doomed | The dialed party to destroy. |
Definition at line 2230 of file channel.c.
References ast_free, ast_party_subaddress_free(), ast_party_dialed::number, ast_party_dialed::str, and ast_party_dialed::subaddress.
Referenced by ast_channel_destructor(), ast_dummy_channel_destructor(), and callerid_write().
02231 { 02232 ast_free(doomed->number.str); 02233 doomed->number.str = NULL; 02234 ast_party_subaddress_free(&doomed->subaddress); 02235 }
void ast_party_dialed_init | ( | struct ast_party_dialed * | init | ) |
Initialize the given dialed structure.
init | Dialed structure to initialize. |
Definition at line 2187 of file channel.c.
References ast_party_subaddress_init(), ast_party_dialed::number, ast_party_dialed::plan, ast_party_dialed::str, ast_party_dialed::subaddress, and ast_party_dialed::transit_network_select.
Referenced by __ast_channel_alloc_ap().
02188 { 02189 init->number.str = NULL; 02190 init->number.plan = 0;/* Unknown */ 02191 ast_party_subaddress_init(&init->subaddress); 02192 init->transit_network_select = 0; 02193 }
void ast_party_dialed_set | ( | struct ast_party_dialed * | dest, | |
const struct ast_party_dialed * | src | |||
) |
Set the dialed information based on another dialed source.
dest | The dialed one wishes to update | |
src | The new dialed values to update the dest |
Definition at line 2217 of file channel.c.
References ast_free, ast_party_subaddress_set(), ast_strdup, ast_party_dialed::number, ast_party_dialed::plan, ast_party_dialed::str, ast_party_dialed::subaddress, and ast_party_dialed::transit_network_select.
Referenced by callerid_write().
02218 { 02219 if (src->number.str && src->number.str != dest->number.str) { 02220 ast_free(dest->number.str); 02221 dest->number.str = ast_strdup(src->number.str); 02222 } 02223 dest->number.plan = src->number.plan; 02224 02225 ast_party_subaddress_set(&dest->subaddress, &src->subaddress); 02226 02227 dest->transit_network_select = src->transit_network_select; 02228 }
void ast_party_dialed_set_init | ( | struct ast_party_dialed * | init, | |
const struct ast_party_dialed * | guide | |||
) |
Initialize the given dialed structure using the given guide for a set update operation.
init | Caller structure to initialize. | |
guide | Source dialed to use as a guide in initializing. |
Definition at line 2209 of file channel.c.
References ast_party_subaddress_set_init(), ast_party_dialed::number, ast_party_dialed::plan, ast_party_dialed::str, ast_party_dialed::subaddress, and ast_party_dialed::transit_network_select.
Referenced by callerid_write().
02210 { 02211 init->number.str = NULL; 02212 init->number.plan = guide->number.plan; 02213 ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress); 02214 init->transit_network_select = guide->transit_network_select; 02215 }
void ast_party_id_copy | ( | struct ast_party_id * | dest, | |
const struct ast_party_id * | src | |||
) |
Copy the source party id information to the destination party id.
dest | Destination party id | |
src | Source party id |
Definition at line 2063 of file channel.c.
References ast_free, ast_party_name_copy(), ast_party_number_copy(), ast_party_subaddress_copy(), ast_strdup, ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, and ast_party_id::tag.
Referenced by ast_connected_line_copy_from_caller(), ast_connected_line_copy_to_caller(), ast_party_caller_copy(), ast_party_connected_line_copy(), ast_party_redirecting_copy(), and parkandannounce_exec().
02064 { 02065 if (dest == src) { 02066 /* Don't copy to self */ 02067 return; 02068 } 02069 02070 ast_party_name_copy(&dest->name, &src->name); 02071 ast_party_number_copy(&dest->number, &src->number); 02072 ast_party_subaddress_copy(&dest->subaddress, &src->subaddress); 02073 02074 ast_free(dest->tag); 02075 dest->tag = ast_strdup(src->tag); 02076 }
void ast_party_id_free | ( | struct ast_party_id * | doomed | ) |
Destroy the party id contents.
doomed | The party id to destroy. |
Definition at line 2109 of file channel.c.
References ast_free, ast_party_name_free(), ast_party_number_free(), ast_party_subaddress_free(), ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, and ast_party_id::tag.
Referenced by ast_party_caller_free(), ast_party_connected_line_free(), ast_party_redirecting_free(), parkandannounce_exec(), and sig_pri_mcid_event().
02110 { 02111 ast_party_name_free(&doomed->name); 02112 ast_party_number_free(&doomed->number); 02113 ast_party_subaddress_free(&doomed->subaddress); 02114 02115 ast_free(doomed->tag); 02116 doomed->tag = NULL; 02117 }
void ast_party_id_init | ( | struct ast_party_id * | init | ) |
Initialize the given party id structure.
init | Party id structure to initialize. |
Definition at line 2055 of file channel.c.
References ast_party_name_init(), ast_party_number_init(), ast_party_subaddress_init(), ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, and ast_party_id::tag.
Referenced by ast_party_caller_init(), ast_party_connected_line_init(), ast_party_redirecting_init(), dial_exec_full(), parkandannounce_exec(), and sig_pri_mcid_event().
02056 { 02057 ast_party_name_init(&init->name); 02058 ast_party_number_init(&init->number); 02059 ast_party_subaddress_init(&init->subaddress); 02060 init->tag = NULL; 02061 }
int ast_party_id_presentation | ( | const struct ast_party_id * | id | ) |
Determine the overall presentation value for the given party.
id | Party to determine the overall presentation value. |
Definition at line 2119 of file channel.c.
References AST_PRES_ALLOWED, AST_PRES_NUMBER_NOT_AVAILABLE, AST_PRES_NUMBER_TYPE, AST_PRES_RESTRICTED, AST_PRES_RESTRICTION, AST_PRES_UNAVAILABLE, AST_PRES_USER_NUMBER_UNSCREENED, and id.
Referenced by add_rpid(), ast_str_retrieve_variable(), ast_var_channels_table(), callerpres_read(), iax2_call(), initreqprep(), my_set_callerid(), oh323_call(), party_id_build_data(), party_id_read(), redirecting_read(), report_new_callerid(), setup_env(), sig_pri_event_party_id(), sig_pri_handle_subcmds(), sip_call(), and socket_process().
02120 { 02121 int number_priority; 02122 int number_value; 02123 int number_screening; 02124 int name_priority; 02125 int name_value; 02126 02127 /* Determine name presentation priority. */ 02128 if (!id->name.valid) { 02129 name_value = AST_PRES_UNAVAILABLE; 02130 name_priority = 3; 02131 } else { 02132 name_value = id->name.presentation & AST_PRES_RESTRICTION; 02133 switch (name_value) { 02134 case AST_PRES_RESTRICTED: 02135 name_priority = 0; 02136 break; 02137 case AST_PRES_ALLOWED: 02138 name_priority = 1; 02139 break; 02140 case AST_PRES_UNAVAILABLE: 02141 name_priority = 2; 02142 break; 02143 default: 02144 name_value = AST_PRES_UNAVAILABLE; 02145 name_priority = 3; 02146 break; 02147 } 02148 } 02149 02150 /* Determine number presentation priority. */ 02151 if (!id->number.valid) { 02152 number_screening = AST_PRES_USER_NUMBER_UNSCREENED; 02153 number_value = AST_PRES_UNAVAILABLE; 02154 number_priority = 3; 02155 } else { 02156 number_screening = id->number.presentation & AST_PRES_NUMBER_TYPE; 02157 number_value = id->number.presentation & AST_PRES_RESTRICTION; 02158 switch (number_value) { 02159 case AST_PRES_RESTRICTED: 02160 number_priority = 0; 02161 break; 02162 case AST_PRES_ALLOWED: 02163 number_priority = 1; 02164 break; 02165 case AST_PRES_UNAVAILABLE: 02166 number_priority = 2; 02167 break; 02168 default: 02169 number_screening = AST_PRES_USER_NUMBER_UNSCREENED; 02170 number_value = AST_PRES_UNAVAILABLE; 02171 number_priority = 3; 02172 break; 02173 } 02174 } 02175 02176 /* Select the wining presentation value. */ 02177 if (name_priority < number_priority) { 02178 number_value = name_value; 02179 } 02180 if (number_value == AST_PRES_UNAVAILABLE) { 02181 return AST_PRES_NUMBER_NOT_AVAILABLE; 02182 } 02183 02184 return number_value | number_screening; 02185 }
void ast_party_id_set | ( | struct ast_party_id * | dest, | |
const struct ast_party_id * | src, | |||
const struct ast_set_party_id * | update | |||
) |
Set the source party id information into the destination party id.
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 2086 of file channel.c.
References ast_free, ast_party_name_set(), ast_party_number_set(), ast_party_subaddress_set(), ast_strdup, ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, ast_party_id::tag, and update().
Referenced by ast_party_caller_set(), ast_party_connected_line_set(), and ast_party_redirecting_set().
02087 { 02088 if (dest == src) { 02089 /* Don't set to self */ 02090 return; 02091 } 02092 02093 if (!update || update->name) { 02094 ast_party_name_set(&dest->name, &src->name); 02095 } 02096 if (!update || update->number) { 02097 ast_party_number_set(&dest->number, &src->number); 02098 } 02099 if (!update || update->subaddress) { 02100 ast_party_subaddress_set(&dest->subaddress, &src->subaddress); 02101 } 02102 02103 if (src->tag && src->tag != dest->tag) { 02104 ast_free(dest->tag); 02105 dest->tag = ast_strdup(src->tag); 02106 } 02107 }
void ast_party_id_set_init | ( | struct ast_party_id * | init, | |
const struct ast_party_id * | guide | |||
) |
Initialize the given party id structure using the given guide for a set update operation.
init | Party id structure to initialize. | |
guide | Source party id to use as a guide in initializing. |
Definition at line 2078 of file channel.c.
References ast_party_name_set_init(), ast_party_number_set_init(), ast_party_subaddress_set_init(), ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, and ast_party_id::tag.
Referenced by ast_party_caller_set_init(), ast_party_connected_line_set_init(), ast_party_redirecting_set_init(), and dial_exec_full().
02079 { 02080 ast_party_name_set_init(&init->name, &guide->name); 02081 ast_party_number_set_init(&init->number, &guide->number); 02082 ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress); 02083 init->tag = NULL; 02084 }
void ast_party_name_copy | ( | struct ast_party_name * | dest, | |
const struct ast_party_name * | src | |||
) |
Copy the source party name information to the destination party name.
dest | Destination party name | |
src | Source party name |
Definition at line 1904 of file channel.c.
References ast_free, ast_strdup, ast_party_name::char_set, ast_party_name::presentation, ast_party_name::str, and ast_party_name::valid.
Referenced by ast_party_id_copy().
01905 { 01906 if (dest == src) { 01907 /* Don't copy to self */ 01908 return; 01909 } 01910 01911 ast_free(dest->str); 01912 dest->str = ast_strdup(src->str); 01913 dest->char_set = src->char_set; 01914 dest->presentation = src->presentation; 01915 dest->valid = src->valid; 01916 }
void ast_party_name_free | ( | struct ast_party_name * | doomed | ) |
Destroy the party name contents.
doomed | The party name to destroy. |
Definition at line 1943 of file channel.c.
References ast_free, and ast_party_name::str.
Referenced by __analog_ss_thread(), analog_ss_thread(), ast_party_id_free(), and skinny_newcall().
void ast_party_name_init | ( | struct ast_party_name * | init | ) |
Initialize the given name structure.
init | Name structure to initialize. |
Definition at line 1896 of file channel.c.
References AST_PARTY_CHAR_SET_ISO8859_1, AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, ast_party_name::char_set, ast_party_name::presentation, ast_party_name::str, and ast_party_name::valid.
Referenced by __analog_ss_thread(), analog_ss_thread(), ast_party_id_init(), and skinny_newcall().
01897 { 01898 init->str = NULL; 01899 init->char_set = AST_PARTY_CHAR_SET_ISO8859_1; 01900 init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 01901 init->valid = 0; 01902 }
void ast_party_name_set | ( | struct ast_party_name * | dest, | |
const struct ast_party_name * | src | |||
) |
Set the source party name information into the destination party name.
dest | The name one wishes to update | |
src | The new name values to update the dest |
Definition at line 1926 of file channel.c.
References ast_free, ast_strdup, ast_party_name::char_set, ast_party_name::presentation, ast_party_name::str, and ast_party_name::valid.
Referenced by ast_party_id_set().
01927 { 01928 if (dest == src) { 01929 /* Don't set to self */ 01930 return; 01931 } 01932 01933 if (src->str && src->str != dest->str) { 01934 ast_free(dest->str); 01935 dest->str = ast_strdup(src->str); 01936 } 01937 01938 dest->char_set = src->char_set; 01939 dest->presentation = src->presentation; 01940 dest->valid = src->valid; 01941 }
void ast_party_name_set_init | ( | struct ast_party_name * | init, | |
const struct ast_party_name * | guide | |||
) |
Initialize the given party name structure using the given guide for a set update operation.
init | Party name structure to initialize. | |
guide | Source party name to use as a guide in initializing. |
Definition at line 1918 of file channel.c.
References ast_party_name::char_set, ast_party_name::presentation, ast_party_name::str, and ast_party_name::valid.
Referenced by ast_party_id_set_init().
01919 { 01920 init->str = NULL; 01921 init->char_set = guide->char_set; 01922 init->presentation = guide->presentation; 01923 init->valid = guide->valid; 01924 }
void ast_party_number_copy | ( | struct ast_party_number * | dest, | |
const struct ast_party_number * | src | |||
) |
Copy the source party number information to the destination party number.
dest | Destination party number | |
src | Source party number |
Definition at line 1957 of file channel.c.
References ast_free, ast_strdup, ast_party_number::plan, ast_party_number::presentation, ast_party_number::str, and ast_party_number::valid.
Referenced by ast_party_id_copy().
01958 { 01959 if (dest == src) { 01960 /* Don't copy to self */ 01961 return; 01962 } 01963 01964 ast_free(dest->str); 01965 dest->str = ast_strdup(src->str); 01966 dest->plan = src->plan; 01967 dest->presentation = src->presentation; 01968 dest->valid = src->valid; 01969 }
void ast_party_number_free | ( | struct ast_party_number * | doomed | ) |
Destroy the party number contents.
doomed | The party number to destroy. |
Definition at line 1996 of file channel.c.
References ast_free, and ast_party_number::str.
Referenced by __analog_ss_thread(), analog_ss_thread(), ast_party_id_free(), do_forward(), and skinny_newcall().
void ast_party_number_init | ( | struct ast_party_number * | init | ) |
Initialize the given number structure.
init | Number structure to initialize. |
Definition at line 1949 of file channel.c.
References AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, ast_party_number::plan, ast_party_number::presentation, ast_party_number::str, and ast_party_number::valid.
Referenced by __analog_ss_thread(), analog_ss_thread(), ast_party_id_init(), do_forward(), and skinny_newcall().
01950 { 01951 init->str = NULL; 01952 init->plan = 0;/* Unknown */ 01953 init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 01954 init->valid = 0; 01955 }
void ast_party_number_set | ( | struct ast_party_number * | dest, | |
const struct ast_party_number * | src | |||
) |
Set the source party number information into the destination party number.
dest | The number one wishes to update | |
src | The new number values to update the dest |
Definition at line 1979 of file channel.c.
References ast_free, ast_strdup, ast_party_number::plan, ast_party_number::presentation, ast_party_number::str, and ast_party_number::valid.
Referenced by ast_party_id_set().
01980 { 01981 if (dest == src) { 01982 /* Don't set to self */ 01983 return; 01984 } 01985 01986 if (src->str && src->str != dest->str) { 01987 ast_free(dest->str); 01988 dest->str = ast_strdup(src->str); 01989 } 01990 01991 dest->plan = src->plan; 01992 dest->presentation = src->presentation; 01993 dest->valid = src->valid; 01994 }
void ast_party_number_set_init | ( | struct ast_party_number * | init, | |
const struct ast_party_number * | guide | |||
) |
Initialize the given party number structure using the given guide for a set update operation.
init | Party number structure to initialize. | |
guide | Source party number to use as a guide in initializing. |
Definition at line 1971 of file channel.c.
References ast_party_number::plan, ast_party_number::presentation, ast_party_number::str, and ast_party_number::valid.
Referenced by ast_party_id_set_init().
01972 { 01973 init->str = NULL; 01974 init->plan = guide->plan; 01975 init->presentation = guide->presentation; 01976 init->valid = guide->valid; 01977 }
void ast_party_redirecting_copy | ( | struct ast_party_redirecting * | dest, | |
const struct ast_party_redirecting * | src | |||
) |
Copy the source redirecting information to the destination redirecting.
dest | Destination redirecting | |
src | Source redirecting |
Definition at line 2335 of file channel.c.
References ast_party_id_copy(), ast_party_redirecting::count, ast_party_redirecting::from, ast_party_redirecting::reason, and ast_party_redirecting::to.
Referenced by ast_call_forward(), ast_channel_redirecting_macro(), begin_dial_channel(), call_forward_inherit(), dial_exec_full(), do_forward(), local_call(), and ring_entry().
02336 { 02337 if (dest == src) { 02338 /* Don't copy to self */ 02339 return; 02340 } 02341 02342 ast_party_id_copy(&dest->from, &src->from); 02343 ast_party_id_copy(&dest->to, &src->to); 02344 dest->count = src->count; 02345 dest->reason = src->reason; 02346 }
void ast_party_redirecting_free | ( | struct ast_party_redirecting * | doomed | ) |
Destroy the redirecting information contents.
doomed | The redirecting information to destroy. |
Definition at line 2364 of file channel.c.
References ast_party_id_free(), ast_party_redirecting::from, and ast_party_redirecting::to.
Referenced by ast_channel_destructor(), ast_channel_redirecting_macro(), ast_dummy_channel_destructor(), ast_indicate_data(), call_forward_inherit(), do_forward(), handle_request_invite(), handle_response(), handle_response_invite(), redirecting_write(), and sig_pri_handle_subcmds().
02365 { 02366 ast_party_id_free(&doomed->from); 02367 ast_party_id_free(&doomed->to); 02368 }
void ast_party_redirecting_init | ( | struct ast_party_redirecting * | init | ) |
Initialize the given redirecting structure.
init | Redirecting structure to initialize. |
Definition at line 2327 of file channel.c.
References ast_party_id_init(), AST_REDIRECTING_REASON_UNKNOWN, ast_party_redirecting::count, ast_party_redirecting::from, ast_party_redirecting::reason, and ast_party_redirecting::to.
Referenced by __ast_channel_alloc_ap(), ast_channel_redirecting_macro(), call_forward_inherit(), do_forward(), handle_request_invite(), handle_response(), and handle_response_invite().
02328 { 02329 ast_party_id_init(&init->from); 02330 ast_party_id_init(&init->to); 02331 init->count = 0; 02332 init->reason = AST_REDIRECTING_REASON_UNKNOWN; 02333 }
void ast_party_redirecting_set | ( | struct ast_party_redirecting * | dest, | |
const struct ast_party_redirecting * | src, | |||
const struct ast_set_party_redirecting * | update | |||
) |
Set the redirecting information based on another redirecting source.
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 2356 of file channel.c.
References ast_party_id_set(), ast_party_redirecting::count, ast_party_redirecting::from, ast_party_redirecting::reason, ast_party_redirecting::to, and update().
Referenced by ast_channel_set_redirecting().
02357 { 02358 ast_party_id_set(&dest->from, &src->from, update ? &update->from : NULL); 02359 ast_party_id_set(&dest->to, &src->to, update ? &update->to : NULL); 02360 dest->reason = src->reason; 02361 dest->count = src->count; 02362 }
void ast_party_redirecting_set_init | ( | struct ast_party_redirecting * | init, | |
const struct ast_party_redirecting * | guide | |||
) |
Initialize the given redirecting id structure using the given guide for a set update operation.
init | Redirecting id structure to initialize. | |
guide | Source redirecting id to use as a guide in initializing. |
Definition at line 2348 of file channel.c.
References ast_party_id_set_init(), ast_party_redirecting::count, ast_party_redirecting::from, ast_party_redirecting::reason, and ast_party_redirecting::to.
Referenced by ast_indicate_data(), misdn_copy_redirecting_to_ast(), redirecting_write(), and sig_pri_redirecting_convert().
02349 { 02350 ast_party_id_set_init(&init->from, &guide->from); 02351 ast_party_id_set_init(&init->to, &guide->to); 02352 init->count = guide->count; 02353 init->reason = guide->reason; 02354 }
void ast_party_subaddress_copy | ( | struct ast_party_subaddress * | dest, | |
const struct ast_party_subaddress * | src | |||
) |
Copy the source party subaddress information to the destination party subaddress.
dest | Destination party subaddress | |
src | Source party subaddress |
Definition at line 2010 of file channel.c.
References ast_free, ast_strdup, ast_party_subaddress::odd_even_indicator, ast_party_subaddress::str, ast_party_subaddress::type, and ast_party_subaddress::valid.
Referenced by ast_party_dialed_copy(), and ast_party_id_copy().
02011 { 02012 if (dest == src) { 02013 /* Don't copy to self */ 02014 return; 02015 } 02016 02017 ast_free(dest->str); 02018 dest->str = ast_strdup(src->str); 02019 dest->type = src->type; 02020 dest->odd_even_indicator = src->odd_even_indicator; 02021 dest->valid = src->valid; 02022 }
void ast_party_subaddress_free | ( | struct ast_party_subaddress * | doomed | ) |
Destroy the party subaddress contents.
doomed | The party subaddress to destroy. |
Definition at line 2049 of file channel.c.
References ast_free, and ast_party_subaddress::str.
Referenced by ast_party_dialed_free(), and ast_party_id_free().
void ast_party_subaddress_init | ( | struct ast_party_subaddress * | init | ) |
Initialize the given subaddress structure.
init | Subaddress structure to initialize. |
Definition at line 2002 of file channel.c.
References ast_party_subaddress::odd_even_indicator, ast_party_subaddress::str, ast_party_subaddress::type, and ast_party_subaddress::valid.
Referenced by ast_party_dialed_init(), ast_party_id_init(), sig_pri_call(), and sig_pri_set_subaddress().
02003 { 02004 init->str = NULL; 02005 init->type = 0; 02006 init->odd_even_indicator = 0; 02007 init->valid = 0; 02008 }
void ast_party_subaddress_set | ( | struct ast_party_subaddress * | dest, | |
const struct ast_party_subaddress * | src | |||
) |
Set the source party subaddress information into the destination party subaddress.
dest | The subaddress one wishes to update | |
src | The new subaddress values to update the dest |
Definition at line 2032 of file channel.c.
References ast_free, ast_strdup, ast_party_subaddress::odd_even_indicator, ast_party_subaddress::str, ast_party_subaddress::type, and ast_party_subaddress::valid.
Referenced by ast_party_dialed_set(), ast_party_id_set(), and sig_pri_handle_subcmds().
02033 { 02034 if (dest == src) { 02035 /* Don't set to self */ 02036 return; 02037 } 02038 02039 if (src->str && src->str != dest->str) { 02040 ast_free(dest->str); 02041 dest->str = ast_strdup(src->str); 02042 } 02043 02044 dest->type = src->type; 02045 dest->odd_even_indicator = src->odd_even_indicator; 02046 dest->valid = src->valid; 02047 }
void ast_party_subaddress_set_init | ( | struct ast_party_subaddress * | init, | |
const struct ast_party_subaddress * | guide | |||
) |
Initialize the given party subaddress structure using the given guide for a set update operation.
init | Party subaddress structure to initialize. | |
guide | Source party subaddress to use as a guide in initializing. |
Definition at line 2024 of file channel.c.
References ast_party_subaddress::odd_even_indicator, ast_party_subaddress::str, ast_party_subaddress::type, and ast_party_subaddress::valid.
Referenced by ast_party_dialed_set_init(), and ast_party_id_set_init().
02025 { 02026 init->str = NULL; 02027 init->type = guide->type; 02028 init->odd_even_indicator = guide->odd_even_indicator; 02029 init->valid = guide->valid; 02030 }
void ast_poll_channel_add | ( | struct ast_channel * | chan0, | |
struct ast_channel * | chan1 | |||
) |
Add a channel to an optimized waitfor
Definition at line 2632 of file channel.c.
References AST_MAX_FDS, and ast_channel::fds.
Referenced by ast_generic_bridge(), begin_dial_channel(), feature_request_and_dial(), local_bridge_loop(), remote_bridge_loop(), and wait_for_answer().
02633 { 02634 #ifdef HAVE_EPOLL 02635 struct epoll_event ev; 02636 int i = 0; 02637 02638 if (chan0->epfd == -1) 02639 return; 02640 02641 /* Iterate through the file descriptors on chan1, adding them to chan0 */ 02642 for (i = 0; i < AST_MAX_FDS; i++) { 02643 if (chan1->fds[i] == -1) 02644 continue; 02645 ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP; 02646 ev.data.ptr = chan1->epfd_data[i]; 02647 epoll_ctl(chan0->epfd, EPOLL_CTL_ADD, chan1->fds[i], &ev); 02648 } 02649 02650 #endif 02651 return; 02652 }
void ast_poll_channel_del | ( | struct ast_channel * | chan0, | |
struct ast_channel * | chan1 | |||
) |
Delete a channel from an optimized waitfor
Definition at line 2655 of file channel.c.
References AST_MAX_FDS, and ast_channel::fds.
Referenced by feature_request_and_dial(), and monitor_dial().
02656 { 02657 #ifdef HAVE_EPOLL 02658 struct epoll_event ev; 02659 int i = 0; 02660 02661 if (chan0->epfd == -1) 02662 return; 02663 02664 for (i = 0; i < AST_MAX_FDS; i++) { 02665 if (chan1->fds[i] == -1) 02666 continue; 02667 epoll_ctl(chan0->epfd, EPOLL_CTL_DEL, chan1->fds[i], &ev); 02668 } 02669 02670 #endif 02671 return; 02672 }
char* ast_print_group | ( | char * | buf, | |
int | buflen, | |||
ast_group_t | group | |||
) |
print call- and pickup groups into buffer
Definition at line 8037 of file channel.c.
References first.
Referenced by _sip_show_peer(), _skinny_show_line(), func_channel_read(), function_sippeer(), misdn_cfg_get_config_string(), print_group(), read_config(), and serialize_showchan().
08038 { 08039 unsigned int i; 08040 int first = 1; 08041 char num[3]; 08042 08043 buf[0] = '\0'; 08044 08045 if (!group) /* Return empty string if no group */ 08046 return buf; 08047 08048 for (i = 0; i <= 63; i++) { /* Max group is 63 */ 08049 if (group & ((ast_group_t) 1 << i)) { 08050 if (!first) { 08051 strncat(buf, ", ", buflen - strlen(buf) - 1); 08052 } else { 08053 first = 0; 08054 } 08055 snprintf(num, sizeof(num), "%u", i); 08056 strncat(buf, num, buflen - strlen(buf) - 1); 08057 } 08058 } 08059 return buf; 08060 }
int ast_prod | ( | struct ast_channel * | chan | ) |
Send empty audio to prime a channel driver.
Definition at line 4669 of file channel.c.
References ast_channel::_state, ast_debug, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), AST_STATE_UP, ast_write(), chanlist::chan, ast_frame_subclass::codec, ast_frame::data, LOG_WARNING, ast_channel::name, ast_frame::ptr, ast_channel::rawwriteformat, ast_frame::src, and ast_frame::subclass.
Referenced by ast_activate_generator().
04670 { 04671 struct ast_frame a = { AST_FRAME_VOICE }; 04672 char nothing[128]; 04673 04674 /* Send an empty audio frame to get things moving */ 04675 if (chan->_state != AST_STATE_UP) { 04676 ast_debug(1, "Prodding channel '%s'\n", chan->name); 04677 a.subclass.codec = chan->rawwriteformat; 04678 a.data.ptr = nothing + AST_FRIENDLY_OFFSET; 04679 a.src = "ast_prod"; /* this better match check in ast_write */ 04680 if (ast_write(chan, &a)) 04681 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name); 04682 } 04683 return 0; 04684 }
int ast_queue_control | ( | struct ast_channel * | chan, | |
enum ast_control_frame_type | control | |||
) |
Queue a control frame with payload.
chan | channel to queue frame onto | |
control | type of control frame |
zero | on success | |
non-zero | on failure |
Definition at line 1573 of file channel.c.
References AST_FRAME_CONTROL, ast_queue_frame(), chanlist::chan, and f.
Referenced by __analog_handle_event(), __analog_ss_thread(), __ast_read(), __dahdi_exception(), __oh323_update_info(), analog_call(), analog_exception(), analog_hangup(), analog_ss_thread(), ast_do_pickup(), attempt_transfer(), auto_congest(), cb_events(), cli_console_answer(), cli_console_flash(), console_answer(), console_call(), console_sendtext(), dahdi_handle_event(), dahdi_hangup(), gtalk_is_answered(), gtalk_ringing_ack(), handle_hd_hf(), handle_offhook_message(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), handle_response_refer(), handle_soft_key_event_message(), handle_stimulus_message(), HandleCallIncoming(), jingle_is_answered(), jingle_ringing_ack(), masquerade_colp_transfer(), misdn_facility_ie_handler(), multicast_rtp_call(), nbs_call(), phone_call(), process_sdp(), receive_digit(), remote_hold(), send_cause2ast(), setup_rtp_connection(), skinny_call(), skinny_transfer(), skinny_unhold(), unistim_call(), and update_state().
01574 { 01575 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control }; 01576 return ast_queue_frame(chan, &f); 01577 }
int ast_queue_control_data | ( | struct ast_channel * | chan, | |
enum ast_control_frame_type | control, | |||
const void * | data, | |||
size_t | datalen | |||
) |
Queue a control frame with payload.
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 1580 of file channel.c.
References AST_FRAME_CONTROL, ast_queue_frame(), chanlist::chan, and f.
Referenced by __analog_handle_event(), analog_hangup(), ast_channel_queue_connected_line_update(), ast_channel_queue_redirecting_update(), change_t38_state(), dahdi_handle_event(), dahdi_hangup(), handle_request_notify(), handle_response_refer(), iax2_queue_control_data(), iax2_transfer(), interpret_t38_parameters(), local_attended_transfer(), masquerade_colp_transfer(), process_sdp(), sig_pri_aoc_d_from_pri(), sig_pri_aoc_e_from_pri(), sig_pri_aoc_s_from_pri(), sig_pri_send_aoce_termination_request(), sip_sipredirect(), and skinny_hold().
01582 { 01583 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control, .data.ptr = (void *) data, .datalen = datalen }; 01584 return ast_queue_frame(chan, &f); 01585 }
int ast_queue_frame | ( | struct ast_channel * | chan, | |
struct ast_frame * | f | |||
) |
Queue one or more frames to a channel's frame queue.
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 1530 of file channel.c.
References __ast_queue_frame(), and chanlist::chan.
Referenced by __ast_channel_masquerade(), __ast_read(), __oh323_rtp_create(), __oh323_update_info(), action_atxfer(), agent_request(), alsa_call(), ast_channel_setwhentohangup_tv(), ast_do_masquerade(), ast_queue_cc_frame(), ast_queue_control(), ast_queue_control_data(), ast_queue_hangup(), ast_queue_hangup_with_cause(), ast_softhangup_nolock(), bridge_write(), cb_events(), cli_console_dial(), cli_console_sendtext(), console_dial(), console_do_answer(), console_flash(), console_sendtext(), dahdi_queue_frame(), dahdi_read(), dictate_exec(), do_immediate_setup(), gtalk_handle_dtmf(), handle_keypad_button_message(), handle_request_info(), handle_request_invite(), handle_response_invite(), iax2_queue_frame(), jingle_handle_dtmf(), keypad_digit(), local_queue_frame(), mgcp_queue_frame(), oh323_simulate_dtmf_end(), oss_call(), pri_queue_frame(), process_sdp(), queue_dtmf_readq(), receive_digit(), receive_message(), sig_pri_dial_complete(), sig_pri_handle_hold(), sig_pri_handle_subcmds(), stream_monitor(), unistim_do_senddigit(), unistim_senddigit_end(), and wakeup_sub().
01531 { 01532 return __ast_queue_frame(chan, fin, 0, NULL); 01533 }
int ast_queue_frame_head | ( | struct ast_channel * | chan, | |
struct ast_frame * | f | |||
) |
Queue one or more frames to the head of a channel's frame queue.
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 1535 of file channel.c.
References __ast_queue_frame(), and chanlist::chan.
Referenced by __ast_answer(), __ast_read(), ast_autoservice_stop(), ast_safe_sleep_conditional(), and feature_request_and_dial().
01536 { 01537 return __ast_queue_frame(chan, fin, 1, NULL); 01538 }
int ast_queue_hangup | ( | struct ast_channel * | chan | ) |
Queue a hangup frame.
Definition at line 1541 of file channel.c.
References ast_channel::_softhangup, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, ast_queue_frame(), AST_SOFTHANGUP_DEV, chanlist::chan, and f.
Referenced by bridge_queue_hangup(), cleanup_connection(), cli_console_hangup(), close_call(), gtalk_hangup_farend(), gtalk_is_answered(), handle_onhook_message(), handle_request_bye(), handle_soft_key_event_message(), iax2_destroy(), iax2_queue_hangup(), jingle_hangup_farend(), local_fixup(), local_hangup(), mgcp_queue_hangup(), and sip_queue_hangup_cause().
01542 { 01543 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP }; 01544 /* Yeah, let's not change a lock-critical value without locking */ 01545 if (!ast_channel_trylock(chan)) { 01546 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01547 ast_channel_unlock(chan); 01548 } 01549 return ast_queue_frame(chan, &f); 01550 }
int ast_queue_hangup_with_cause | ( | struct ast_channel * | chan, | |
int | cause | |||
) |
Queue a hangup frame with hangupcause set.
[in] | chan | channel to queue frame onto |
[in] | cause | the hangup cause |
Definition at line 1553 of file channel.c.
References ast_channel::_softhangup, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, ast_queue_frame(), AST_SOFTHANGUP_DEV, chanlist::chan, f, and ast_channel::hangupcause.
Referenced by __analog_handle_event(), __oh323_update_info(), __sip_autodestruct(), close_call(), close_client(), console_hangup(), dahdi_handle_event(), dahdi_r2_on_call_disconnect(), handle_request_bye(), handle_response(), handle_response_invite(), HandleCallOutgoing(), hangup_chan(), hangup_connection(), misdn_answer(), retrans_pkt(), sip_queue_hangup_cause(), and TransferCallStep1().
01554 { 01555 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP }; 01556 01557 if (cause >= 0) 01558 f.data.uint32 = cause; 01559 01560 /* Yeah, let's not change a lock-critical value without locking */ 01561 if (!ast_channel_trylock(chan)) { 01562 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01563 if (cause < 0) 01564 f.data.uint32 = chan->hangupcause; 01565 01566 ast_channel_unlock(chan); 01567 } 01568 01569 return ast_queue_frame(chan, &f); 01570 }
int ast_raw_answer | ( | struct ast_channel * | chan, | |
int | cdr_answer | |||
) |
Answer a channel.
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 2897 of file channel.c.
References ast_channel::_state, ast_channel_tech::answer, ast_cdr_answer(), AST_CEL_ANSWER, ast_cel_report_event(), ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, ast_indicate(), ast_setstate(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_test_flag, ast_channel::cdr, chanlist::chan, and ast_channel::tech.
Referenced by __ast_answer(), and ast_bridge_call().
02898 { 02899 int res = 0; 02900 02901 ast_channel_lock(chan); 02902 02903 /* You can't answer an outbound call */ 02904 if (ast_test_flag(chan, AST_FLAG_OUTGOING)) { 02905 ast_channel_unlock(chan); 02906 return 0; 02907 } 02908 02909 /* Stop if we're a zombie or need a soft hangup */ 02910 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 02911 ast_channel_unlock(chan); 02912 return -1; 02913 } 02914 02915 ast_channel_unlock(chan); 02916 02917 switch (chan->_state) { 02918 case AST_STATE_RINGING: 02919 case AST_STATE_RING: 02920 ast_channel_lock(chan); 02921 if (chan->tech->answer) { 02922 res = chan->tech->answer(chan); 02923 } 02924 ast_setstate(chan, AST_STATE_UP); 02925 if (cdr_answer) { 02926 ast_cdr_answer(chan->cdr); 02927 } 02928 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL); 02929 ast_channel_unlock(chan); 02930 break; 02931 case AST_STATE_UP: 02932 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL); 02933 /* Calling ast_cdr_answer when it it has previously been called 02934 * is essentially a no-op, so it is safe. 02935 */ 02936 if (cdr_answer) { 02937 ast_cdr_answer(chan->cdr); 02938 } 02939 break; 02940 default: 02941 break; 02942 } 02943 02944 ast_indicate(chan, -1); 02945 02946 return res; 02947 }
struct ast_frame* ast_read | ( | struct ast_channel * | chan | ) |
Reads a frame.
chan | channel to read a frame from |
Definition at line 4286 of file channel.c.
References __ast_read(), and chanlist::chan.
Referenced by __adsi_transmit_messages(), __analog_ss_thread(), __ast_answer(), __ast_play_and_record(), __ast_request_and_dial(), adsi_careful_send(), agent_ack_sleep(), agent_read(), analog_ss_thread(), ast_bridge_handle_trip(), ast_recvtext(), ast_safe_sleep_conditional(), ast_tonepair(), ast_transfer(), ast_udptl_bridge(), ast_waitfordigit_full(), async_agi_read_frame(), async_wait(), autoservice_run(), background_detect_exec(), channel_spy(), conf_flush(), conf_run(), dahdi_bridge(), dial_exec_full(), dictate_exec(), disa_exec(), disable_t38(), do_idle_thread(), do_waiting(), echo_exec(), eivr_comm(), feature_request_and_dial(), find_cache(), generic_fax_exec(), handle_recordfile(), handle_speechrecognize(), ices_exec(), isAnsweringMachine(), jack_exec(), local_bridge_loop(), manage_parked_call(), measurenoise(), misdn_bridge(), monitor_dial(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), receivefax_t38_init(), recordthread(), remote_bridge_loop(), run_agi(), send_tone_burst(), send_waveform_to_channel(), sendfax_t38_init(), sendurl_exec(), speech_background(), transmit_audio(), transmit_t38(), wait_for_hangup(), wait_for_winner(), waitforring_exec(), and waitstream_core().
04287 { 04288 return __ast_read(chan, 0); 04289 }
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 4291 of file channel.c.
References __ast_read(), and chanlist::chan.
Referenced by ast_bridge_handle_trip(), and conf_run().
04292 { 04293 return __ast_read(chan, 1); 04294 }
int ast_readstring | ( | struct ast_channel * | c, | |
char * | s, | |||
int | len, | |||
int | timeout, | |||
int | rtimeout, | |||
char * | enders | |||
) |
Reads multiple digits.
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 5721 of file channel.c.
References ast_readstring_full().
Referenced by adsi_begin_download(), adsi_get_cpeinfo(), adsi_load_session(), ast_app_getdata(), dialout(), do_directory(), forward_message(), privacy_exec(), vm_authenticate(), vm_newuser(), and vm_options().
05722 { 05723 return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1); 05724 }
int ast_readstring_full | ( | struct ast_channel * | c, | |
char * | s, | |||
int | len, | |||
int | timeout, | |||
int | rtimeout, | |||
char * | enders, | |||
int | audiofd, | |||
int | ctrlfd | |||
) |
Definition at line 5726 of file channel.c.
References ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_check_hangup(), AST_DIGIT_ANY, AST_FLAG_ZOMBIE, AST_GETDATA_COMPLETE, AST_GETDATA_EMPTY_END_TERMINATED, AST_GETDATA_FAILED, AST_GETDATA_INTERRUPTED, AST_GETDATA_TIMEOUT, ast_opt_transmit_silence, ast_stopstream(), ast_test_flag, ast_waitfordigit_full(), ast_waitstream_full(), and ast_channel::stream.
Referenced by ast_app_getdata_full(), and ast_readstring().
05727 { 05728 int pos = 0; /* index in the buffer where we accumulate digits */ 05729 int to = ftimeout; 05730 05731 struct ast_silence_generator *silgen = NULL; 05732 05733 /* Stop if we're a zombie or need a soft hangup */ 05734 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 05735 return -1; 05736 if (!len) 05737 return -1; 05738 for (;;) { 05739 int d; 05740 if (c->stream) { 05741 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd); 05742 ast_stopstream(c); 05743 if (!silgen && ast_opt_transmit_silence) 05744 silgen = ast_channel_start_silence_generator(c); 05745 usleep(1000); 05746 if (!d) 05747 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 05748 } else { 05749 if (!silgen && ast_opt_transmit_silence) 05750 silgen = ast_channel_start_silence_generator(c); 05751 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 05752 } 05753 if (d < 0) { 05754 ast_channel_stop_silence_generator(c, silgen); 05755 return AST_GETDATA_FAILED; 05756 } 05757 if (d == 0) { 05758 s[pos] = '\0'; 05759 ast_channel_stop_silence_generator(c, silgen); 05760 return AST_GETDATA_TIMEOUT; 05761 } 05762 if (d == 1) { 05763 s[pos] = '\0'; 05764 ast_channel_stop_silence_generator(c, silgen); 05765 return AST_GETDATA_INTERRUPTED; 05766 } 05767 if (strchr(enders, d) && (pos == 0)) { 05768 s[pos] = '\0'; 05769 ast_channel_stop_silence_generator(c, silgen); 05770 return AST_GETDATA_EMPTY_END_TERMINATED; 05771 } 05772 if (!strchr(enders, d)) { 05773 s[pos++] = d; 05774 } 05775 if (strchr(enders, d) || (pos >= len)) { 05776 s[pos] = '\0'; 05777 ast_channel_stop_silence_generator(c, silgen); 05778 return AST_GETDATA_COMPLETE; 05779 } 05780 to = timeout; 05781 } 05782 /* Never reached */ 05783 return 0; 05784 }
int ast_recvchar | ( | struct ast_channel * | chan, | |
int | timeout | |||
) |
Receives a text character from a channel.
chan | channel to act upon | |
timeout | timeout in milliseconds (0 for infinite wait) |
Definition at line 4545 of file channel.c.
References ast_free, ast_recvtext(), and chanlist::chan.
Referenced by handle_recvchar().
04546 { 04547 int c; 04548 char *buf = ast_recvtext(chan, timeout); 04549 if (buf == NULL) 04550 return -1; /* error or timeout */ 04551 c = *(unsigned char *)buf; 04552 ast_free(buf); 04553 return c; 04554 }
char* ast_recvtext | ( | struct ast_channel * | chan, | |
int | timeout | |||
) |
Receives a text string from a channel Read a string of text from a channel.
chan | channel to act upon | |
timeout | timeout in milliseconds (0 for infinite wait) |
Definition at line 4556 of file channel.c.
References ast_check_hangup(), AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_TEXT, ast_frfree, ast_read(), ast_strndup, ast_waitfor(), chanlist::chan, and f.
Referenced by ast_recvchar(), and handle_recvtext().
04557 { 04558 int res, done = 0; 04559 char *buf = NULL; 04560 04561 while (!done) { 04562 struct ast_frame *f; 04563 if (ast_check_hangup(chan)) 04564 break; 04565 res = ast_waitfor(chan, timeout); 04566 if (res <= 0) /* timeout or error */ 04567 break; 04568 timeout = res; /* update timeout */ 04569 f = ast_read(chan); 04570 if (f == NULL) 04571 break; /* no frame */ 04572 if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_HANGUP) 04573 done = 1; /* force a break */ 04574 else if (f->frametype == AST_FRAME_TEXT) { /* what we want */ 04575 buf = ast_strndup((char *) f->data.ptr, f->datalen); /* dup and break */ 04576 done = 1; 04577 } 04578 ast_frfree(f); 04579 } 04580 return buf; 04581 }
int ast_redirecting_build_data | ( | unsigned char * | data, | |
size_t | datalen, | |||
const struct ast_party_redirecting * | redirecting, | |||
const struct ast_set_party_redirecting * | update | |||
) |
Build the redirecting id data frame.
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 8939 of file channel.c.
References ast_log(), AST_REDIRECTING_COUNT, AST_REDIRECTING_FROM_ID_PRESENTATION, AST_REDIRECTING_FROM_NAME, AST_REDIRECTING_FROM_NAME_CHAR_SET, AST_REDIRECTING_FROM_NAME_PRESENTATION, AST_REDIRECTING_FROM_NAME_VALID, AST_REDIRECTING_FROM_NUMBER, AST_REDIRECTING_FROM_NUMBER_PLAN, AST_REDIRECTING_FROM_NUMBER_PRESENTATION, AST_REDIRECTING_FROM_NUMBER_VALID, AST_REDIRECTING_FROM_SUBADDRESS, AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_FROM_SUBADDRESS_TYPE, AST_REDIRECTING_FROM_SUBADDRESS_VALID, AST_REDIRECTING_FROM_TAG, AST_REDIRECTING_TO_ID_PRESENTATION, AST_REDIRECTING_TO_NAME, AST_REDIRECTING_TO_NAME_CHAR_SET, AST_REDIRECTING_TO_NAME_PRESENTATION, AST_REDIRECTING_TO_NAME_VALID, AST_REDIRECTING_TO_NUMBER, AST_REDIRECTING_TO_NUMBER_PLAN, AST_REDIRECTING_TO_NUMBER_PRESENTATION, AST_REDIRECTING_TO_NUMBER_VALID, AST_REDIRECTING_TO_SUBADDRESS, AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_TO_SUBADDRESS_TYPE, AST_REDIRECTING_TO_SUBADDRESS_VALID, AST_REDIRECTING_TO_TAG, AST_REDIRECTING_VERSION, ast_party_redirecting::count, ast_party_redirecting::from, LOG_WARNING, ast_party_id_ies::name, party_id_build_data(), ast_party_redirecting::reason, ast_party_name_ies::str, ast_party_redirecting::to, update(), and value.
Referenced by ast_channel_queue_redirecting_update(), ast_channel_update_redirecting(), and local_indicate().
08940 { 08941 int32_t value; 08942 size_t pos = 0; 08943 int res; 08944 08945 static const struct ast_party_id_ies from_ies = { 08946 .name.str = AST_REDIRECTING_FROM_NAME, 08947 .name.char_set = AST_REDIRECTING_FROM_NAME_CHAR_SET, 08948 .name.presentation = AST_REDIRECTING_FROM_NAME_PRESENTATION, 08949 .name.valid = AST_REDIRECTING_FROM_NAME_VALID, 08950 08951 .number.str = AST_REDIRECTING_FROM_NUMBER, 08952 .number.plan = AST_REDIRECTING_FROM_NUMBER_PLAN, 08953 .number.presentation = AST_REDIRECTING_FROM_NUMBER_PRESENTATION, 08954 .number.valid = AST_REDIRECTING_FROM_NUMBER_VALID, 08955 08956 .subaddress.str = AST_REDIRECTING_FROM_SUBADDRESS, 08957 .subaddress.type = AST_REDIRECTING_FROM_SUBADDRESS_TYPE, 08958 .subaddress.odd_even_indicator = AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN, 08959 .subaddress.valid = AST_REDIRECTING_FROM_SUBADDRESS_VALID, 08960 08961 .tag = AST_REDIRECTING_FROM_TAG, 08962 .combined_presentation = AST_REDIRECTING_FROM_ID_PRESENTATION, 08963 }; 08964 static const struct ast_party_id_ies to_ies = { 08965 .name.str = AST_REDIRECTING_TO_NAME, 08966 .name.char_set = AST_REDIRECTING_TO_NAME_CHAR_SET, 08967 .name.presentation = AST_REDIRECTING_TO_NAME_PRESENTATION, 08968 .name.valid = AST_REDIRECTING_TO_NAME_VALID, 08969 08970 .number.str = AST_REDIRECTING_TO_NUMBER, 08971 .number.plan = AST_REDIRECTING_TO_NUMBER_PLAN, 08972 .number.presentation = AST_REDIRECTING_TO_NUMBER_PRESENTATION, 08973 .number.valid = AST_REDIRECTING_TO_NUMBER_VALID, 08974 08975 .subaddress.str = AST_REDIRECTING_TO_SUBADDRESS, 08976 .subaddress.type = AST_REDIRECTING_TO_SUBADDRESS_TYPE, 08977 .subaddress.odd_even_indicator = AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN, 08978 .subaddress.valid = AST_REDIRECTING_TO_SUBADDRESS_VALID, 08979 08980 .tag = AST_REDIRECTING_TO_TAG, 08981 .combined_presentation = AST_REDIRECTING_TO_ID_PRESENTATION, 08982 }; 08983 08984 /* Redirecting frame version */ 08985 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08986 ast_log(LOG_WARNING, "No space left for redirecting frame version\n"); 08987 return -1; 08988 } 08989 data[pos++] = AST_REDIRECTING_VERSION; 08990 data[pos++] = 1; 08991 data[pos++] = 2;/* Version 1 did not have a version ie */ 08992 08993 res = party_id_build_data(data + pos, datalen - pos, &redirecting->from, 08994 "redirecting-from", &from_ies, update ? &update->from : NULL); 08995 if (res < 0) { 08996 return -1; 08997 } 08998 pos += res; 08999 09000 res = party_id_build_data(data + pos, datalen - pos, &redirecting->to, 09001 "redirecting-to", &to_ies, update ? &update->to : NULL); 09002 if (res < 0) { 09003 return -1; 09004 } 09005 pos += res; 09006 09007 /* Redirecting reason */ 09008 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) { 09009 ast_log(LOG_WARNING, "No space left for redirecting reason\n"); 09010 return -1; 09011 } 09012 data[pos++] = AST_REDIRECTING_REASON; 09013 data[pos++] = sizeof(value); 09014 value = htonl(redirecting->reason); 09015 memcpy(data + pos, &value, sizeof(value)); 09016 pos += sizeof(value); 09017 09018 /* Redirecting count */ 09019 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) { 09020 ast_log(LOG_WARNING, "No space left for redirecting count\n"); 09021 return -1; 09022 } 09023 data[pos++] = AST_REDIRECTING_COUNT; 09024 data[pos++] = sizeof(value); 09025 value = htonl(redirecting->count); 09026 memcpy(data + pos, &value, sizeof(value)); 09027 pos += sizeof(value); 09028 09029 return pos; 09030 }
int ast_redirecting_parse_data | ( | const unsigned char * | data, | |
size_t | datalen, | |||
struct ast_party_redirecting * | redirecting | |||
) |
Parse redirecting indication frame data.
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 9032 of file channel.c.
References ast_free, ast_log(), ast_malloc, AST_PARTY_CHAR_SET_ISO8859_1, AST_REDIRECTING_COUNT, AST_REDIRECTING_FROM_ID_PRESENTATION, AST_REDIRECTING_FROM_NAME, AST_REDIRECTING_FROM_NAME_CHAR_SET, AST_REDIRECTING_FROM_NAME_PRESENTATION, AST_REDIRECTING_FROM_NAME_VALID, AST_REDIRECTING_FROM_NUMBER, AST_REDIRECTING_FROM_NUMBER_PLAN, AST_REDIRECTING_FROM_NUMBER_PRESENTATION, AST_REDIRECTING_FROM_NUMBER_VALID, AST_REDIRECTING_FROM_SUBADDRESS, AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_FROM_SUBADDRESS_TYPE, AST_REDIRECTING_FROM_SUBADDRESS_VALID, AST_REDIRECTING_FROM_TAG, AST_REDIRECTING_TO_ID_PRESENTATION, AST_REDIRECTING_TO_NAME, AST_REDIRECTING_TO_NAME_CHAR_SET, AST_REDIRECTING_TO_NAME_PRESENTATION, AST_REDIRECTING_TO_NAME_VALID, AST_REDIRECTING_TO_NUMBER, AST_REDIRECTING_TO_NUMBER_PLAN, AST_REDIRECTING_TO_NUMBER_PRESENTATION, AST_REDIRECTING_TO_NUMBER_VALID, AST_REDIRECTING_TO_SUBADDRESS, AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_TO_SUBADDRESS_TYPE, AST_REDIRECTING_TO_SUBADDRESS_VALID, AST_REDIRECTING_TO_TAG, AST_REDIRECTING_VERSION, ast_party_name::char_set, ast_party_redirecting::count, ast_party_redirecting::from, LOG_DEBUG, LOG_WARNING, ast_party_id::name, ast_party_id::number, ast_party_subaddress::odd_even_indicator, ast_party_number::plan, ast_party_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().
09033 { 09034 size_t pos; 09035 unsigned char ie_len; 09036 unsigned char ie_id; 09037 int32_t value; 09038 int frame_version = 1; 09039 int from_combined_presentation = 0; 09040 int got_from_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */ 09041 int to_combined_presentation = 0; 09042 int got_to_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */ 09043 09044 for (pos = 0; pos < datalen; pos += ie_len) { 09045 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) { 09046 ast_log(LOG_WARNING, "Invalid redirecting update\n"); 09047 return -1; 09048 } 09049 ie_id = data[pos++]; 09050 ie_len = data[pos++]; 09051 if (datalen < pos + ie_len) { 09052 ast_log(LOG_WARNING, "Invalid redirecting update\n"); 09053 return -1; 09054 } 09055 09056 switch (ie_id) { 09057 /* Redirecting frame version */ 09058 case AST_REDIRECTING_VERSION: 09059 if (ie_len != 1) { 09060 ast_log(LOG_WARNING, "Invalid redirecting frame version (%u)\n", 09061 (unsigned) ie_len); 09062 break; 09063 } 09064 frame_version = data[pos]; 09065 break; 09066 /* Redirecting-from party id name */ 09067 case AST_REDIRECTING_FROM_NAME: 09068 ast_free(redirecting->from.name.str); 09069 redirecting->from.name.str = ast_malloc(ie_len + 1); 09070 if (redirecting->from.name.str) { 09071 memcpy(redirecting->from.name.str, data + pos, ie_len); 09072 redirecting->from.name.str[ie_len] = 0; 09073 } 09074 break; 09075 case AST_REDIRECTING_FROM_NAME_CHAR_SET: 09076 if (ie_len != 1) { 09077 ast_log(LOG_WARNING, "Invalid redirecting-from name char set (%u)\n", 09078 (unsigned) ie_len); 09079 break; 09080 } 09081 redirecting->from.name.char_set = data[pos]; 09082 break; 09083 case AST_REDIRECTING_FROM_NAME_PRESENTATION: 09084 if (ie_len != 1) { 09085 ast_log(LOG_WARNING, "Invalid redirecting-from name presentation (%u)\n", 09086 (unsigned) ie_len); 09087 break; 09088 } 09089 redirecting->from.name.presentation = data[pos]; 09090 break; 09091 case AST_REDIRECTING_FROM_NAME_VALID: 09092 if (ie_len != 1) { 09093 ast_log(LOG_WARNING, "Invalid redirecting-from name valid (%u)\n", 09094 (unsigned) ie_len); 09095 break; 09096 } 09097 redirecting->from.name.valid = data[pos]; 09098 break; 09099 /* Redirecting-from party id number */ 09100 case AST_REDIRECTING_FROM_NUMBER: 09101 ast_free(redirecting->from.number.str); 09102 redirecting->from.number.str = ast_malloc(ie_len + 1); 09103 if (redirecting->from.number.str) { 09104 memcpy(redirecting->from.number.str, data + pos, ie_len); 09105 redirecting->from.number.str[ie_len] = 0; 09106 } 09107 break; 09108 case AST_REDIRECTING_FROM_NUMBER_PLAN: 09109 if (ie_len != 1) { 09110 ast_log(LOG_WARNING, "Invalid redirecting-from numbering plan (%u)\n", 09111 (unsigned) ie_len); 09112 break; 09113 } 09114 redirecting->from.number.plan = data[pos]; 09115 break; 09116 case AST_REDIRECTING_FROM_NUMBER_PRESENTATION: 09117 if (ie_len != 1) { 09118 ast_log(LOG_WARNING, "Invalid redirecting-from number presentation (%u)\n", 09119 (unsigned) ie_len); 09120 break; 09121 } 09122 redirecting->from.number.presentation = data[pos]; 09123 break; 09124 case AST_REDIRECTING_FROM_NUMBER_VALID: 09125 if (ie_len != 1) { 09126 ast_log(LOG_WARNING, "Invalid redirecting-from number valid (%u)\n", 09127 (unsigned) ie_len); 09128 break; 09129 } 09130 redirecting->from.number.valid = data[pos]; 09131 break; 09132 /* Redirecting-from party id combined presentation */ 09133 case AST_REDIRECTING_FROM_ID_PRESENTATION: 09134 if (ie_len != 1) { 09135 ast_log(LOG_WARNING, "Invalid redirecting-from combined presentation (%u)\n", 09136 (unsigned) ie_len); 09137 break; 09138 } 09139 from_combined_presentation = data[pos]; 09140 got_from_combined_presentation = 1; 09141 break; 09142 /* Redirecting-from party id subaddress */ 09143 case AST_REDIRECTING_FROM_SUBADDRESS: 09144 ast_free(redirecting->from.subaddress.str); 09145 redirecting->from.subaddress.str = ast_malloc(ie_len + 1); 09146 if (redirecting->from.subaddress.str) { 09147 memcpy(redirecting->from.subaddress.str, data + pos, ie_len); 09148 redirecting->from.subaddress.str[ie_len] = 0; 09149 } 09150 break; 09151 case AST_REDIRECTING_FROM_SUBADDRESS_TYPE: 09152 if (ie_len != 1) { 09153 ast_log(LOG_WARNING, "Invalid redirecting-from type of subaddress (%u)\n", 09154 (unsigned) ie_len); 09155 break; 09156 } 09157 redirecting->from.subaddress.type = data[pos]; 09158 break; 09159 case AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN: 09160 if (ie_len != 1) { 09161 ast_log(LOG_WARNING, 09162 "Invalid redirecting-from subaddress odd-even indicator (%u)\n", 09163 (unsigned) ie_len); 09164 break; 09165 } 09166 redirecting->from.subaddress.odd_even_indicator = data[pos]; 09167 break; 09168 case AST_REDIRECTING_FROM_SUBADDRESS_VALID: 09169 if (ie_len != 1) { 09170 ast_log(LOG_WARNING, "Invalid redirecting-from subaddress valid (%u)\n", 09171 (unsigned) ie_len); 09172 break; 09173 } 09174 redirecting->from.subaddress.valid = data[pos]; 09175 break; 09176 /* Redirecting-from party id tag */ 09177 case AST_REDIRECTING_FROM_TAG: 09178 ast_free(redirecting->from.tag); 09179 redirecting->from.tag = ast_malloc(ie_len + 1); 09180 if (redirecting->from.tag) { 09181 memcpy(redirecting->from.tag, data + pos, ie_len); 09182 redirecting->from.tag[ie_len] = 0; 09183 } 09184 break; 09185 /* Redirecting-to party id name */ 09186 case AST_REDIRECTING_TO_NAME: 09187 ast_free(redirecting->to.name.str); 09188 redirecting->to.name.str = ast_malloc(ie_len + 1); 09189 if (redirecting->to.name.str) { 09190 memcpy(redirecting->to.name.str, data + pos, ie_len); 09191 redirecting->to.name.str[ie_len] = 0; 09192 } 09193 break; 09194 case AST_REDIRECTING_TO_NAME_CHAR_SET: 09195 if (ie_len != 1) { 09196 ast_log(LOG_WARNING, "Invalid redirecting-to name char set (%u)\n", 09197 (unsigned) ie_len); 09198 break; 09199 } 09200 redirecting->to.name.char_set = data[pos]; 09201 break; 09202 case AST_REDIRECTING_TO_NAME_PRESENTATION: 09203 if (ie_len != 1) { 09204 ast_log(LOG_WARNING, "Invalid redirecting-to name presentation (%u)\n", 09205 (unsigned) ie_len); 09206 break; 09207 } 09208 redirecting->to.name.presentation = data[pos]; 09209 break; 09210 case AST_REDIRECTING_TO_NAME_VALID: 09211 if (ie_len != 1) { 09212 ast_log(LOG_WARNING, "Invalid redirecting-to name valid (%u)\n", 09213 (unsigned) ie_len); 09214 break; 09215 } 09216 redirecting->to.name.valid = data[pos]; 09217 break; 09218 /* Redirecting-to party id number */ 09219 case AST_REDIRECTING_TO_NUMBER: 09220 ast_free(redirecting->to.number.str); 09221 redirecting->to.number.str = ast_malloc(ie_len + 1); 09222 if (redirecting->to.number.str) { 09223 memcpy(redirecting->to.number.str, data + pos, ie_len); 09224 redirecting->to.number.str[ie_len] = 0; 09225 } 09226 break; 09227 case AST_REDIRECTING_TO_NUMBER_PLAN: 09228 if (ie_len != 1) { 09229 ast_log(LOG_WARNING, "Invalid redirecting-to numbering plan (%u)\n", 09230 (unsigned) ie_len); 09231 break; 09232 } 09233 redirecting->to.number.plan = data[pos]; 09234 break; 09235 case AST_REDIRECTING_TO_NUMBER_PRESENTATION: 09236 if (ie_len != 1) { 09237 ast_log(LOG_WARNING, "Invalid redirecting-to number presentation (%u)\n", 09238 (unsigned) ie_len); 09239 break; 09240 } 09241 redirecting->to.number.presentation = data[pos]; 09242 break; 09243 case AST_REDIRECTING_TO_NUMBER_VALID: 09244 if (ie_len != 1) { 09245 ast_log(LOG_WARNING, "Invalid redirecting-to number valid (%u)\n", 09246 (unsigned) ie_len); 09247 break; 09248 } 09249 redirecting->to.number.valid = data[pos]; 09250 break; 09251 /* Redirecting-to party id combined presentation */ 09252 case AST_REDIRECTING_TO_ID_PRESENTATION: 09253 if (ie_len != 1) { 09254 ast_log(LOG_WARNING, "Invalid redirecting-to combined presentation (%u)\n", 09255 (unsigned) ie_len); 09256 break; 09257 } 09258 to_combined_presentation = data[pos]; 09259 got_to_combined_presentation = 1; 09260 break; 09261 /* Redirecting-to party id subaddress */ 09262 case AST_REDIRECTING_TO_SUBADDRESS: 09263 ast_free(redirecting->to.subaddress.str); 09264 redirecting->to.subaddress.str = ast_malloc(ie_len + 1); 09265 if (redirecting->to.subaddress.str) { 09266 memcpy(redirecting->to.subaddress.str, data + pos, ie_len); 09267 redirecting->to.subaddress.str[ie_len] = 0; 09268 } 09269 break; 09270 case AST_REDIRECTING_TO_SUBADDRESS_TYPE: 09271 if (ie_len != 1) { 09272 ast_log(LOG_WARNING, "Invalid redirecting-to type of subaddress (%u)\n", 09273 (unsigned) ie_len); 09274 break; 09275 } 09276 redirecting->to.subaddress.type = data[pos]; 09277 break; 09278 case AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN: 09279 if (ie_len != 1) { 09280 ast_log(LOG_WARNING, 09281 "Invalid redirecting-to subaddress odd-even indicator (%u)\n", 09282 (unsigned) ie_len); 09283 break; 09284 } 09285 redirecting->to.subaddress.odd_even_indicator = data[pos]; 09286 break; 09287 case AST_REDIRECTING_TO_SUBADDRESS_VALID: 09288 if (ie_len != 1) { 09289 ast_log(LOG_WARNING, "Invalid redirecting-to subaddress valid (%u)\n", 09290 (unsigned) ie_len); 09291 break; 09292 } 09293 redirecting->to.subaddress.valid = data[pos]; 09294 break; 09295 /* Redirecting-to party id tag */ 09296 case AST_REDIRECTING_TO_TAG: 09297 ast_free(redirecting->to.tag); 09298 redirecting->to.tag = ast_malloc(ie_len + 1); 09299 if (redirecting->to.tag) { 09300 memcpy(redirecting->to.tag, data + pos, ie_len); 09301 redirecting->to.tag[ie_len] = 0; 09302 } 09303 break; 09304 /* Redirecting reason */ 09305 case AST_REDIRECTING_REASON: 09306 if (ie_len != sizeof(value)) { 09307 ast_log(LOG_WARNING, "Invalid redirecting reason (%u)\n", 09308 (unsigned) ie_len); 09309 break; 09310 } 09311 memcpy(&value, data + pos, sizeof(value)); 09312 redirecting->reason = ntohl(value); 09313 break; 09314 /* Redirecting count */ 09315 case AST_REDIRECTING_COUNT: 09316 if (ie_len != sizeof(value)) { 09317 ast_log(LOG_WARNING, "Invalid redirecting count (%u)\n", 09318 (unsigned) ie_len); 09319 break; 09320 } 09321 memcpy(&value, data + pos, sizeof(value)); 09322 redirecting->count = ntohl(value); 09323 break; 09324 /* Redirecting unknown element */ 09325 default: 09326 ast_log(LOG_DEBUG, "Unknown redirecting element: %u (%u)\n", 09327 (unsigned) ie_id, (unsigned) ie_len); 09328 break; 09329 } 09330 } 09331 09332 switch (frame_version) { 09333 case 1: 09334 /* 09335 * The other end is an earlier version that we need to adjust 09336 * for compatibility. 09337 */ 09338 redirecting->from.name.valid = 1; 09339 redirecting->from.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1; 09340 redirecting->from.number.valid = 1; 09341 if (got_from_combined_presentation) { 09342 redirecting->from.name.presentation = from_combined_presentation; 09343 redirecting->from.number.presentation = from_combined_presentation; 09344 } 09345 09346 redirecting->to.name.valid = 1; 09347 redirecting->to.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1; 09348 redirecting->to.number.valid = 1; 09349 if (got_to_combined_presentation) { 09350 redirecting->to.name.presentation = to_combined_presentation; 09351 redirecting->to.number.presentation = to_combined_presentation; 09352 } 09353 break; 09354 case 2: 09355 /* The other end is at the same level as we are. */ 09356 break; 09357 default: 09358 /* 09359 * The other end is newer than we are. 09360 * We need to assume that they are compatible with us. 09361 */ 09362 ast_log(LOG_DEBUG, "Redirecting frame has newer version: %u\n", 09363 (unsigned) frame_version); 09364 break; 09365 } 09366 09367 return 0; 09368 }
struct ast_channel* ast_request | ( | const char * | type, | |
format_t | format, | |||
const struct ast_channel * | requestor, | |||
void * | data, | |||
int * | status | |||
) |
Requests a channel.
type | type of channel to request | |
format | requested channel format (codec) | |
requestor | channel asking for data | |
data | data to pass to the channel requester (Should be treated as const char *) | |
status | status |
NULL | failure | |
non-NULL | channel on success |
Definition at line 5579 of file channel.c.
References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_NOSUCHDRIVER, AST_CAUSE_NOTDEFINED, ast_channel_release(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_translator_best_choice(), 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(), begin_dial_channel(), build_conf(), chanavail_exec(), conf_run(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), play_sound_file(), and ring_entry().
05580 { 05581 struct chanlist *chan; 05582 struct ast_channel *c; 05583 format_t capabilities; 05584 format_t fmt; 05585 int res; 05586 int foo; 05587 format_t videoformat = format & AST_FORMAT_VIDEO_MASK; 05588 format_t textformat = format & AST_FORMAT_TEXT_MASK; 05589 05590 if (!cause) 05591 cause = &foo; 05592 *cause = AST_CAUSE_NOTDEFINED; 05593 05594 if (AST_RWLIST_RDLOCK(&backends)) { 05595 ast_log(LOG_WARNING, "Unable to lock technology backend list\n"); 05596 return NULL; 05597 } 05598 05599 AST_RWLIST_TRAVERSE(&backends, chan, list) { 05600 if (strcasecmp(type, chan->tech->type)) 05601 continue; 05602 05603 capabilities = chan->tech->capabilities; 05604 fmt = format & AST_FORMAT_AUDIO_MASK; 05605 if (fmt) { 05606 /* We have audio - is it possible to connect the various calls to each other? 05607 (Avoid this check for calls without audio, like text+video calls) 05608 */ 05609 res = ast_translator_best_choice(&fmt, &capabilities); 05610 if (res < 0) { 05611 char tmp1[256], tmp2[256]; 05612 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %s) to %s\n", type, 05613 ast_getformatname_multiple(tmp1, sizeof(tmp1), chan->tech->capabilities), 05614 ast_getformatname_multiple(tmp2, sizeof(tmp2), format)); 05615 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05616 AST_RWLIST_UNLOCK(&backends); 05617 return NULL; 05618 } 05619 } 05620 AST_RWLIST_UNLOCK(&backends); 05621 if (!chan->tech->requester) 05622 return NULL; 05623 05624 if (!(c = chan->tech->requester(type, capabilities | videoformat | textformat, requestor, data, cause))) 05625 return NULL; 05626 05627 if (set_security_requirements(requestor, c)) { 05628 ast_log(LOG_WARNING, "Setting security requirements failed\n"); 05629 c = ast_channel_release(c); 05630 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05631 return NULL; 05632 } 05633 05634 /* no need to generate a Newchannel event here; it is done in the channel_alloc call */ 05635 return c; 05636 } 05637 05638 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type); 05639 *cause = AST_CAUSE_NOSUCHDRIVER; 05640 AST_RWLIST_UNLOCK(&backends); 05641 05642 return NULL; 05643 }
struct ast_channel* ast_request_and_dial | ( | const char * | type, | |
format_t | format, | |||
const struct ast_channel * | requestor, | |||
void * | data, | |||
int | timeout, | |||
int * | reason, | |||
const char * | cid_num, | |||
const char * | cid_name | |||
) |
Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it.
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 5534 of file channel.c.
References __ast_request_and_dial().
Referenced by ast_pbx_outgoing_exten(), and generic_recall().
05535 { 05536 return __ast_request_and_dial(type, format, requestor, data, timeout, outstate, cidnum, cidname, NULL); 05537 }
int ast_safe_sleep | ( | struct ast_channel * | chan, | |
int | ms | |||
) |
Wait for a specified amount of time, looking for hangups.
chan | channel to wait for | |
ms | length of time in milliseconds to sleep |
Definition at line 1884 of file channel.c.
References ast_safe_sleep_conditional(), and chanlist::chan.
Referenced by __analog_ss_thread(), adsi_transmit_message_full(), alarmreceiver_exec(), analog_ss_thread(), ast_dtmf_stream(), ast_senddigit(), builtin_atxfer(), builtin_parkcall(), conf_run(), dahdi_send_callrerouting_facility_exec(), dictate_exec(), flash_exec(), handle_callforward_button(), login_exec(), mgcp_ss(), milliwatt_exec(), misdn_check_l2l1(), old_milliwatt_exec(), park_call_exec(), pbx_builtin_wait(), play_moh_exec(), playtone(), privacy_exec(), receive_ademco_contact_id(), skinny_ss(), testclient_exec(), testserver_exec(), wait_for_hangup(), wait_moh_exec(), waituntil_exec(), and zapateller_exec().
01885 { 01886 return ast_safe_sleep_conditional(chan, ms, NULL, NULL); 01887 }
int ast_safe_sleep_conditional | ( | struct ast_channel * | chan, | |
int | ms, | |||
int(*)(void *) | cond, | |||
void * | data | |||
) |
Wait for a specified amount of time, looking for hangups and a condition argument.
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 1817 of file channel.c.
References ast_channel_lock, ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_channel_unlock, ast_frfree, ast_frisolate(), ast_is_deferrable_frame(), AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_HEAD_NOLOCK, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_HEAD, ast_opt_transmit_silence, ast_queue_frame_head(), ast_read(), ast_waitfor(), chanlist::chan, f, and ast_channel::generatordata.
Referenced by ast_safe_sleep(), and login_exec().
01818 { 01819 struct ast_frame *f; 01820 struct ast_silence_generator *silgen = NULL; 01821 int res = 0; 01822 AST_LIST_HEAD_NOLOCK(, ast_frame) deferred_frames; 01823 01824 AST_LIST_HEAD_INIT_NOLOCK(&deferred_frames); 01825 01826 /* If no other generator is present, start silencegen while waiting */ 01827 if (ast_opt_transmit_silence && !chan->generatordata) { 01828 silgen = ast_channel_start_silence_generator(chan); 01829 } 01830 01831 while (ms > 0) { 01832 struct ast_frame *dup_f = NULL; 01833 if (cond && ((*cond)(data) == 0)) { 01834 break; 01835 } 01836 ms = ast_waitfor(chan, ms); 01837 if (ms < 0) { 01838 res = -1; 01839 break; 01840 } 01841 if (ms > 0) { 01842 f = ast_read(chan); 01843 if (!f) { 01844 res = -1; 01845 break; 01846 } 01847 01848 if (!ast_is_deferrable_frame(f)) { 01849 ast_frfree(f); 01850 continue; 01851 } 01852 01853 if ((dup_f = ast_frisolate(f))) { 01854 if (dup_f != f) { 01855 ast_frfree(f); 01856 } 01857 AST_LIST_INSERT_HEAD(&deferred_frames, dup_f, frame_list); 01858 } 01859 } 01860 } 01861 01862 /* stop silgen if present */ 01863 if (silgen) { 01864 ast_channel_stop_silence_generator(chan, silgen); 01865 } 01866 01867 /* We need to free all the deferred frames, but we only need to 01868 * queue the deferred frames if there was no error and no 01869 * hangup was received 01870 */ 01871 ast_channel_lock(chan); 01872 while ((f = AST_LIST_REMOVE_HEAD(&deferred_frames, frame_list))) { 01873 if (!res) { 01874 ast_queue_frame_head(chan, f); 01875 } 01876 ast_frfree(f); 01877 } 01878 ast_channel_unlock(chan); 01879 01880 return res; 01881 }
int ast_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 4659 of file channel.c.
References AST_DEFAULT_EMULATE_DTMF_DURATION, ast_safe_sleep(), ast_senddigit_begin(), ast_senddigit_end(), chanlist::chan, ast_channel_tech::send_digit_begin, and ast_channel::tech.
Referenced by ast_dtmf_stream(), dial_exec_full(), and manager_play_dtmf().
04660 { 04661 if (chan->tech->send_digit_begin) { 04662 ast_senddigit_begin(chan, digit); 04663 ast_safe_sleep(chan, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION)); 04664 } 04665 04666 return ast_senddigit_end(chan, digit, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION)); 04667 }
int ast_senddigit_begin | ( | struct ast_channel * | chan, | |
char | digit | |||
) |
Send a DTMF digit to a channel.
chan | channel to act upon | |
digit | the DTMF digit to send, encoded in ASCII |
Definition at line 4601 of file channel.c.
References ast_debug, ast_playtones_start(), chanlist::chan, ast_channel::name, ast_channel_tech::send_digit_begin, and ast_channel::tech.
Referenced by agent_digit_begin(), ast_senddigit(), and ast_write().
04602 { 04603 /* Device does not support DTMF tones, lets fake 04604 * it by doing our own generation. */ 04605 static const char * const dtmf_tones[] = { 04606 "941+1336", /* 0 */ 04607 "697+1209", /* 1 */ 04608 "697+1336", /* 2 */ 04609 "697+1477", /* 3 */ 04610 "770+1209", /* 4 */ 04611 "770+1336", /* 5 */ 04612 "770+1477", /* 6 */ 04613 "852+1209", /* 7 */ 04614 "852+1336", /* 8 */ 04615 "852+1477", /* 9 */ 04616 "697+1633", /* A */ 04617 "770+1633", /* B */ 04618 "852+1633", /* C */ 04619 "941+1633", /* D */ 04620 "941+1209", /* * */ 04621 "941+1477" /* # */ 04622 }; 04623 04624 if (!chan->tech->send_digit_begin) 04625 return 0; 04626 04627 if (!chan->tech->send_digit_begin(chan, digit)) 04628 return 0; 04629 04630 if (digit >= '0' && digit <='9') 04631 ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0); 04632 else if (digit >= 'A' && digit <= 'D') 04633 ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0); 04634 else if (digit == '*') 04635 ast_playtones_start(chan, 0, dtmf_tones[14], 0); 04636 else if (digit == '#') 04637 ast_playtones_start(chan, 0, dtmf_tones[15], 0); 04638 else { 04639 /* not handled */ 04640 ast_debug(1, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name); 04641 } 04642 04643 return 0; 04644 }
int ast_senddigit_end | ( | struct ast_channel * | chan, | |
char | digit, | |||
unsigned int | duration | |||
) |
Send a DTMF digit to a channel.
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 4646 of file channel.c.
References ast_playtones_stop(), chanlist::chan, ast_channel::generator, ast_channel_tech::send_digit_end, and ast_channel::tech.
Referenced by agent_digit_end(), ast_senddigit(), and ast_write().
04647 { 04648 int res = -1; 04649 04650 if (chan->tech->send_digit_end) 04651 res = chan->tech->send_digit_end(chan, digit, duration); 04652 04653 if (res && chan->generator) 04654 ast_playtones_stop(chan); 04655 04656 return 0; 04657 }
int ast_sendtext | ( | struct ast_channel * | chan, | |
const char * | text | |||
) |
Sends text to a channel.
chan | channel to act upon | |
text | string of text to send on the channel |
0 | on success | |
-1 | on failure |
Definition at line 4583 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_test_flag, chanlist::chan, CHECK_BLOCKING, ast_channel_tech::send_text, and ast_channel::tech.
Referenced by action_sendtext(), agent_sendtext(), handle_sendtext(), and sendtext_exec().
04584 { 04585 int res = 0; 04586 04587 ast_channel_lock(chan); 04588 /* Stop if we're a zombie or need a soft hangup */ 04589 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 04590 ast_channel_unlock(chan); 04591 return -1; 04592 } 04593 CHECK_BLOCKING(chan); 04594 if (chan->tech->send_text) 04595 res = chan->tech->send_text(chan, text); 04596 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04597 ast_channel_unlock(chan); 04598 return res; 04599 }
void ast_set_callerid | ( | struct ast_channel * | chan, | |
const char * | cid_num, | |||
const char * | cid_name, | |||
const char * | cid_ani | |||
) |
Set caller ID number, name and ANI and generate AMI event.
The channel does not need to be locked before calling this function.
Definition at line 6885 of file channel.c.
References ast_party_caller::ani, ast_cdr_setcid(), ast_channel_lock, ast_channel_unlock, ast_free, ast_strdup, ast_channel::caller, ast_channel::cdr, chanlist::chan, ast_party_caller::id, ast_party_id::name, ast_party_id::number, report_new_callerid(), ast_party_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(), skinny_newcall(), and socket_process().
06886 { 06887 ast_channel_lock(chan); 06888 06889 if (cid_num) { 06890 chan->caller.id.number.valid = 1; 06891 ast_free(chan->caller.id.number.str); 06892 chan->caller.id.number.str = ast_strdup(cid_num); 06893 } 06894 if (cid_name) { 06895 chan->caller.id.name.valid = 1; 06896 ast_free(chan->caller.id.name.str); 06897 chan->caller.id.name.str = ast_strdup(cid_name); 06898 } 06899 if (cid_ani) { 06900 chan->caller.ani.number.valid = 1; 06901 ast_free(chan->caller.ani.number.str); 06902 chan->caller.ani.number.str = ast_strdup(cid_ani); 06903 } 06904 if (chan->cdr) { 06905 ast_cdr_setcid(chan->cdr, chan); 06906 } 06907 06908 report_new_callerid(chan); 06909 06910 ast_channel_unlock(chan); 06911 }
void ast_set_hangupsource | ( | struct ast_channel * | chan, | |
const char * | source, | |||
int | force | |||
) |
Set the source of the hangup in this channel and it's bridge.
chan | channel to set the field on | |
source | a string describing the source of the hangup for this channel | |
force |
Definition at line 2736 of file channel.c.
References ast_bridged_channel(), ast_channel_lock, ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_string_field_set, ast_strlen_zero(), ast_channel::bridge, chanlist::chan, and ast_channel::hangupsource.
Referenced by __dahdi_exception(), analog_exception(), func_channel_write_real(), handle_hangup(), pbx_builtin_hangup(), set_hangup_source_and_cause(), and sip_queue_hangup_cause().
02737 { 02738 struct ast_channel *bridge; 02739 02740 ast_channel_lock(chan); 02741 if (force || ast_strlen_zero(chan->hangupsource)) { 02742 ast_string_field_set(chan, hangupsource, source); 02743 } 02744 bridge = ast_bridged_channel(chan); 02745 if (bridge) { 02746 ast_channel_ref(bridge); 02747 } 02748 ast_channel_unlock(chan); 02749 02750 if (bridge) { 02751 ast_channel_lock(bridge); 02752 if (force || ast_strlen_zero(bridge->hangupsource)) { 02753 ast_string_field_set(bridge, hangupsource, source); 02754 } 02755 ast_channel_unlock(bridge); 02756 ast_channel_unref(bridge); 02757 } 02758 }
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 5186 of file channel.c.
References chanlist::chan, ast_channel::rawreadformat, ast_channel::readformat, ast_channel::readtrans, and set_format().
Referenced by __ast_play_and_record(), __oh323_update_info(), adsi_transmit_message_full(), agent_call(), alarmreceiver_exec(), ast_channel_make_compatible_helper(), ast_do_masquerade(), background_detect_exec(), bridge_channel_join(), bridge_make_compatible(), build_conf(), conf_run(), dictate_exec(), do_waiting(), eagi_exec(), echo_exec(), generic_fax_exec(), gtalk_rtp_read(), handle_recordfile(), handle_speechrecognize(), ices_exec(), isAnsweringMachine(), jack_exec(), jingle_rtp_read(), login_exec(), measurenoise(), mgcp_rtp_read(), oh323_rtp_read(), old_milliwatt_exec(), process_sdp(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_process(), speech_background(), transmit_audio(), and unistim_rtp_read().
05187 { 05188 return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat, 05189 &chan->readtrans, 0); 05190 }
void ast_set_variables | ( | struct ast_channel * | chan, | |
struct ast_variable * | vars | |||
) |
adds a list of channel variables to a channel
chan | the channel | |
vars | a linked list of variables |
Definition at line 8062 of file channel.c.
References ast_variable::name, ast_variable::next, pbx_builtin_setvar_helper(), and ast_variable::value.
Referenced by __ast_request_and_dial(), ast_call_forward(), ast_pbx_outgoing_app(), and ast_pbx_outgoing_exten().
08063 { 08064 struct ast_variable *cur; 08065 08066 for (cur = vars; cur; cur = cur->next) 08067 pbx_builtin_setvar_helper(chan, cur->name, cur->value); 08068 }
int ast_set_write_format | ( | struct ast_channel * | chan, | |
format_t | format | |||
) |
Sets write format on channel chan Set write format for channel to whichever component of "format" is best.
chan | channel to change | |
format | new format for writing |
Definition at line 5192 of file channel.c.
References chanlist::chan, ast_channel::rawwriteformat, set_format(), ast_channel::writeformat, and ast_channel::writetrans.
Referenced by __oh323_update_info(), adsi_transmit_message_full(), agent_call(), alarmreceiver_exec(), ast_channel_make_compatible_helper(), ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_do_masquerade(), ast_openstream_full(), ast_stopstream(), ast_write(), bridge_channel_join(), bridge_make_compatible(), build_conf(), chanspy_exec(), conf_run(), dahdiscan_exec(), echo_exec(), extenspy_exec(), generic_fax_exec(), gtalk_rtp_read(), jack_exec(), jingle_rtp_read(), linear_alloc(), linear_release(), login_exec(), mgcp_rtp_read(), moh_alloc(), moh_files_release(), moh_release(), mp3_exec(), NBScat_exec(), oh323_rtp_read(), old_milliwatt_exec(), playtones_alloc(), playtones_release(), process_sdp(), send_waveform_to_channel(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_process(), tonepair_alloc(), tonepair_release(), transmit_audio(), and unistim_rtp_read().
05193 { 05194 return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat, 05195 &chan->writetrans, 1); 05196 }
int ast_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 3502 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_debug, ast_timer_get_max_rate(), ast_timer_set_rate(), AST_TIMING_FD, ast_channel::fdno, ast_channel::timer, ast_channel::timingdata, ast_channel::timingfd, and ast_channel::timingfunc.
Referenced by ast_activate_generator(), ast_deactivate_generator(), ast_read_generator_actions(), ast_readaudio_callback(), and filestream_close().
03503 { 03504 int res; 03505 unsigned int real_rate = rate, max_rate; 03506 03507 ast_channel_lock(c); 03508 03509 if (c->timingfd == -1) { 03510 ast_channel_unlock(c); 03511 return -1; 03512 } 03513 03514 if (!func) { 03515 rate = 0; 03516 data = NULL; 03517 } 03518 03519 if (rate && rate > (max_rate = ast_timer_get_max_rate(c->timer))) { 03520 real_rate = max_rate; 03521 } 03522 03523 ast_debug(1, "Scheduling timer at (%u requested / %u actual) timer ticks per second\n", rate, real_rate); 03524 03525 res = ast_timer_set_rate(c->timer, real_rate); 03526 03527 c->timingfunc = func; 03528 c->timingdata = data; 03529 03530 if (func == NULL && rate == 0 && c->fdno == AST_TIMING_FD) { 03531 /* Clearing the timing func and setting the rate to 0 03532 * means that we don't want to be reading from the timingfd 03533 * any more. Setting c->fdno to -1 means we won't have any 03534 * errant reads from the timingfd, meaning we won't potentially 03535 * miss any important frames. 03536 */ 03537 c->fdno = -1; 03538 } 03539 03540 ast_channel_unlock(c); 03541 03542 return res; 03543 }
int ast_shutting_down | ( | void | ) |
Returns non-zero if Asterisk is being shut down.
Definition at line 854 of file channel.c.
Referenced by handle_request_options().
00855 { 00856 return shutting_down; 00857 }
int ast_softhangup | ( | struct ast_channel * | chan, | |
int | reason | |||
) |
Softly hangup up a channel.
chan | channel to be soft-hung-up | |
reason | an AST_SOFTHANGUP_* reason code |
Definition at line 2713 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_softhangup_nolock(), and chanlist::chan.
Referenced by __analog_handle_event(), __ast_module_user_hangup_all(), __unload_module(), agent_hangup(), agent_logoff(), agent_read(), ast_bridge_call(), ast_channel_softhangup_cb(), ast_dial_join(), cc_generic_agent_stop_ringing(), conf_free(), dahdi_handle_event(), handle_hangup(), handle_softhangup(), login_exec(), manager_park(), mgcp_pktcgate_remove(), read_agent_config(), sla_handle_hold_event(), softhangup_exec(), start_spying(), startmon(), and unload_module().
02714 { 02715 int res; 02716 02717 ast_channel_lock(chan); 02718 res = ast_softhangup_nolock(chan, cause); 02719 ast_channel_unlock(chan); 02720 02721 return res; 02722 }
int ast_softhangup_nolock | ( | struct ast_channel * | chan, | |
int | reason | |||
) |
Softly hangup up a channel (no channel lock).
chan | channel to be soft-hung-up | |
reason | an AST_SOFTHANGUP_* reason code |
Definition at line 2700 of file channel.c.
References ast_channel::_softhangup, ast_debug, AST_FLAG_BLOCKING, ast_null_frame, ast_queue_frame(), ast_test_flag, ast_channel::blocker, chanlist::chan, and ast_channel::name.
Referenced by __analog_handle_event(), action_hangup(), ast_async_goto(), ast_softhangup(), attempt_transfer(), check_pendings(), check_rtp_timeout(), dahdi_softhangup_all(), oh323_indicate(), proc_session_timer(), sig_pri_indicate(), sig_pri_send_aoce_termination_request(), sip_indicate(), and skinny_indicate().
02701 { 02702 ast_debug(1, "Soft-Hanging up channel '%s'\n", chan->name); 02703 /* Inform channel driver that we need to be hung up, if it cares */ 02704 chan->_softhangup |= cause; 02705 ast_queue_frame(chan, &ast_null_frame); 02706 /* Interrupt any poll call or such */ 02707 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) 02708 pthread_kill(chan->blocker, SIGURG); 02709 return 0; 02710 }
const char* ast_state2str | ( | enum ast_channel_state | state | ) |
Gives the string form of a given channel state.
Definition at line 996 of file channel.c.
References AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DIALING_OFFHOOK, AST_STATE_DOWN, AST_STATE_OFFHOOK, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_threadstorage_get(), STATE2STR_BUFSIZE, and state2str_threadbuf.
Referenced by __ast_channel_alloc_ap(), action_coreshowchannels(), agent_hangup(), ast_channel_data_add_structure(), ast_do_masquerade(), ast_setstate(), attempt_transfer(), func_channel_read(), handle_chanlist(), handle_showchan(), local_attended_transfer(), mgcp_new(), serialize_showchan(), sip_hangup(), and update_connectedline().
00997 { 00998 char *buf; 00999 01000 switch (state) { 01001 case AST_STATE_DOWN: 01002 return "Down"; 01003 case AST_STATE_RESERVED: 01004 return "Rsrvd"; 01005 case AST_STATE_OFFHOOK: 01006 return "OffHook"; 01007 case AST_STATE_DIALING: 01008 return "Dialing"; 01009 case AST_STATE_RING: 01010 return "Ring"; 01011 case AST_STATE_RINGING: 01012 return "Ringing"; 01013 case AST_STATE_UP: 01014 return "Up"; 01015 case AST_STATE_BUSY: 01016 return "Busy"; 01017 case AST_STATE_DIALING_OFFHOOK: 01018 return "Dialing Offhook"; 01019 case AST_STATE_PRERING: 01020 return "Pre-ring"; 01021 default: 01022 if (!(buf = ast_threadstorage_get(&state2str_threadbuf, STATE2STR_BUFSIZE))) 01023 return "Unknown"; 01024 snprintf(buf, STATE2STR_BUFSIZE, "Unknown (%d)", state); 01025 return buf; 01026 } 01027 }
int ast_str2cause | ( | const char * | name | ) |
Convert the string form of a cause code to a number.
name | string form of the cause |
Definition at line 982 of file channel.c.
References ARRAY_LEN, and causes.
Referenced by pbx_builtin_hangup().
00983 { 00984 int x; 00985 00986 for (x = 0; x < ARRAY_LEN(causes); x++) 00987 if (!strncasecmp(causes[x].name, name, strlen(causes[x].name))) 00988 return causes[x].cause; 00989 00990 return -1; 00991 }
int ast_tonepair | ( | struct ast_channel * | chan, | |
int | freq1, | |||
int | freq2, | |||
int | duration, | |||
int | vol | |||
) |
Play a tone pair for a given amount of time
Definition at line 7782 of file channel.c.
References ast_frfree, ast_read(), ast_tonepair_start(), ast_waitfor(), f, and ast_channel::generatordata.
Referenced by zapateller_exec().
07783 { 07784 int res; 07785 07786 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol))) 07787 return res; 07788 07789 /* Give us some wiggle room */ 07790 while (chan->generatordata && ast_waitfor(chan, 100) >= 0) { 07791 struct ast_frame *f = ast_read(chan); 07792 if (f) 07793 ast_frfree(f); 07794 else 07795 return -1; 07796 } 07797 return 0; 07798 }
int ast_tonepair_start | ( | struct ast_channel * | chan, | |
int | freq1, | |||
int | freq2, | |||
int | duration, | |||
int | vol | |||
) |
Start a tone going
Definition at line 7764 of file channel.c.
References ast_activate_generator(), tonepair_def::duration, tonepair_def::freq1, tonepair_def::freq2, tonepair, and tonepair_def::vol.
Referenced by ast_tonepair(), pbx_builtin_waitexten(), play_dialtone(), and sendnoise().
07765 { 07766 struct tonepair_def d = { 0, }; 07767 07768 d.freq1 = freq1; 07769 d.freq2 = freq2; 07770 d.duration = duration; 07771 d.vol = (vol < 1) ? 8192 : vol; /* force invalid to 8192 */ 07772 if (ast_activate_generator(chan, &tonepair, &d)) 07773 return -1; 07774 return 0; 07775 }
void ast_tonepair_stop | ( | struct ast_channel * | chan | ) |
Stop a tone from playing
Definition at line 7777 of file channel.c.
References ast_deactivate_generator().
Referenced by sendnoise().
07778 { 07779 ast_deactivate_generator(chan); 07780 }
int ast_transfer | ( | struct ast_channel * | chan, | |
char * | dest | |||
) |
Transfer a channel (if supported).
Called by:
Definition at line 5672 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_CONTROL_TRANSFER, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, ast_frfree, ast_read(), ast_test_flag, AST_TRANSFER_SUCCESS, ast_waitfor(), chanlist::chan, ast_channel::tech, and ast_channel_tech::transfer.
Referenced by transfer_exec().
05673 { 05674 int res = -1; 05675 05676 /* Stop if we're a zombie or need a soft hangup */ 05677 ast_channel_lock(chan); 05678 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) { 05679 if (chan->tech->transfer) { 05680 res = chan->tech->transfer(chan, dest); 05681 if (!res) 05682 res = 1; 05683 } else 05684 res = 0; 05685 } 05686 ast_channel_unlock(chan); 05687 05688 if (res <= 0) { 05689 return res; 05690 } 05691 05692 for (;;) { 05693 struct ast_frame *fr; 05694 05695 res = ast_waitfor(chan, -1); 05696 05697 if (res < 0 || !(fr = ast_read(chan))) { 05698 res = -1; 05699 break; 05700 } 05701 05702 if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_TRANSFER) { 05703 enum ast_control_transfer *message = fr->data.ptr; 05704 05705 if (*message == AST_TRANSFER_SUCCESS) { 05706 res = 1; 05707 } else { 05708 res = -1; 05709 } 05710 05711 ast_frfree(fr); 05712 break; 05713 } 05714 05715 ast_frfree(fr); 05716 } 05717 05718 return res; 05719 }
char* ast_transfercapability2str | ( | int | transfercapability | ) | const |
Gives the string form of a given transfer capability.
transfercapability | transfer capability to get the name of |
Definition at line 1030 of file channel.c.
References AST_TRANS_CAP_3_1K_AUDIO, AST_TRANS_CAP_DIGITAL, AST_TRANS_CAP_DIGITAL_W_TONES, AST_TRANS_CAP_RESTRICTED_DIGITAL, AST_TRANS_CAP_SPEECH, and AST_TRANS_CAP_VIDEO.
Referenced by ast_channel_data_add_structure(), cb_events(), misdn_call(), oh323_call(), sig_pri_call(), and sig_pri_new_ast_channel().
01031 { 01032 switch (transfercapability) { 01033 case AST_TRANS_CAP_SPEECH: 01034 return "SPEECH"; 01035 case AST_TRANS_CAP_DIGITAL: 01036 return "DIGITAL"; 01037 case AST_TRANS_CAP_RESTRICTED_DIGITAL: 01038 return "RESTRICTED_DIGITAL"; 01039 case AST_TRANS_CAP_3_1K_AUDIO: 01040 return "3K1AUDIO"; 01041 case AST_TRANS_CAP_DIGITAL_W_TONES: 01042 return "DIGITAL_W_TONES"; 01043 case AST_TRANS_CAP_VIDEO: 01044 return "VIDEO"; 01045 default: 01046 return "UNKNOWN"; 01047 } 01048 }
int ast_undestroyed_channels | ( | void | ) |
Definition at line 842 of file channel.c.
References ast_atomic_fetchadd_int().
Referenced by can_safely_quit().
00843 { 00844 return ast_atomic_fetchadd_int(&chancount, 0); 00845 }
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 3486 of file channel.c.
References ast_waitfor_nandfds().
Referenced by __adsi_transmit_messages(), __analog_ss_thread(), __ast_answer(), __ast_play_and_record(), __ast_request_and_dial(), adsi_careful_send(), agent_ack_sleep(), analog_ss_thread(), ast_dtmf_stream(), ast_recvtext(), ast_safe_sleep_conditional(), ast_tonepair(), ast_transfer(), async_wait(), background_detect_exec(), channel_spy(), conf_flush(), dictate_exec(), disa_exec(), disable_t38(), do_idle_thread(), do_waiting(), echo_exec(), handle_recordfile(), handle_speechrecognize(), ices_exec(), isAnsweringMachine(), jack_exec(), launch_asyncagi(), measurenoise(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), receivefax_t38_init(), recordthread(), send_tone_burst(), send_waveform_to_channel(), sendfax_t38_init(), sendurl_exec(), speech_background(), transmit_audio(), transmit_t38(), wait_for_hangup(), waitforring_exec(), and waitstream_core().
03487 { 03488 int oldms = ms; /* -1 if no timeout */ 03489 03490 ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms); 03491 if ((ms < 0) && (oldms < 0)) 03492 ms = 0; 03493 return ms; 03494 }
struct ast_channel* ast_waitfor_n | ( | struct ast_channel ** | chan, | |
int | n, | |||
int * | ms | |||
) |
Waits for input on a group of channels Wait for input on an array of channels for a given # of milliseconds.
chan | an array of pointers to channels | |
n | number of channels that are to be waited upon | |
ms | time "ms" is modified in-place, if applicable |
Definition at line 3481 of file channel.c.
References ast_waitfor_nandfds().
Referenced by ast_udptl_bridge(), autoservice_run(), dahdi_bridge(), dial_exec_full(), feature_request_and_dial(), generic_thread_loop(), misdn_bridge(), monitor_dial(), remote_bridge_loop(), wait_for_answer(), and wait_for_winner().
03482 { 03483 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms); 03484 }
int ast_waitfor_n_fd | ( | int * | fds, | |
int | n, | |||
int * | ms, | |||
int * | exception | |||
) |
Waits for input on an fd.
Definition at line 3125 of file channel.c.
References ast_waitfor_nandfds().
Referenced by dundi_lookup_internal(), dundi_precache_internal(), and softmix_bridge_thread().
03126 { 03127 int winner = -1; 03128 ast_waitfor_nandfds(NULL, 0, fds, n, exception, &winner, ms); 03129 return winner; 03130 }
struct ast_channel* ast_waitfor_nandfds | ( | struct ast_channel ** | chan, | |
int | n, | |||
int * | fds, | |||
int | nfds, | |||
int * | exception, | |||
int * | outfd, | |||
int * | ms | |||
) |
Waits for activity on a group of channels.
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 3137 of file channel.c.
References ast_channel::_softhangup, ast_add_fd(), ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, AST_MAX_FDS, ast_poll, ast_set_flag, AST_SOFTHANGUP_TIMEOUT, ast_tvcmp(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), chanlist::chan, CHECK_BLOCKING, and errno.
Referenced by ast_waitfor(), ast_waitfor_n(), ast_waitfor_n_fd(), ast_waitfordigit_full(), conf_run(), eivr_comm(), find_cache(), generic_fax_exec(), multiplexed_thread_function(), run_agi(), and waitstream_core().
03140 { 03141 struct timeval start = { 0 , 0 }; 03142 struct pollfd *pfds = NULL; 03143 int res; 03144 long rms; 03145 int x, y, max; 03146 int sz; 03147 struct timeval now = { 0, 0 }; 03148 struct timeval whentohangup = { 0, 0 }, diff; 03149 struct ast_channel *winner = NULL; 03150 struct fdmap { 03151 int chan; 03152 int fdno; 03153 } *fdmap = NULL; 03154 03155 if (outfd) 03156 *outfd = -99999; 03157 if (exception) 03158 *exception = 0; 03159 03160 if ((sz = n * AST_MAX_FDS + nfds)) { 03161 pfds = alloca(sizeof(*pfds) * sz); 03162 fdmap = alloca(sizeof(*fdmap) * sz); 03163 } else { 03164 /* nothing to allocate and no FDs to check */ 03165 return NULL; 03166 } 03167 03168 /* Perform any pending masquerades */ 03169 for (x = 0; x < n; x++) { 03170 while (c[x]->masq) { 03171 ast_do_masquerade(c[x]); 03172 } 03173 03174 ast_channel_lock(c[x]); 03175 if (!ast_tvzero(c[x]->whentohangup)) { 03176 if (ast_tvzero(whentohangup)) 03177 now = ast_tvnow(); 03178 diff = ast_tvsub(c[x]->whentohangup, now); 03179 if (diff.tv_sec < 0 || ast_tvzero(diff)) { 03180 /* Should already be hungup */ 03181 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 03182 ast_channel_unlock(c[x]); 03183 return c[x]; 03184 } 03185 if (ast_tvzero(whentohangup) || ast_tvcmp(diff, whentohangup) < 0) 03186 whentohangup = diff; 03187 } 03188 ast_channel_unlock(c[x]); 03189 } 03190 /* Wait full interval */ 03191 rms = *ms; 03192 /* INT_MAX, not LONG_MAX, because it matters on 64-bit */ 03193 if (!ast_tvzero(whentohangup) && whentohangup.tv_sec < INT_MAX / 1000) { 03194 rms = whentohangup.tv_sec * 1000 + whentohangup.tv_usec / 1000; /* timeout in milliseconds */ 03195 if (*ms >= 0 && *ms < rms) { /* original *ms still smaller */ 03196 rms = *ms; 03197 } 03198 } else if (!ast_tvzero(whentohangup) && rms < 0) { 03199 /* Tiny corner case... call would need to last >24 days */ 03200 rms = INT_MAX; 03201 } 03202 /* 03203 * Build the pollfd array, putting the channels' fds first, 03204 * followed by individual fds. Order is important because 03205 * individual fd's must have priority over channel fds. 03206 */ 03207 max = 0; 03208 for (x = 0; x < n; x++) { 03209 for (y = 0; y < AST_MAX_FDS; y++) { 03210 fdmap[max].fdno = y; /* fd y is linked to this pfds */ 03211 fdmap[max].chan = x; /* channel x is linked to this pfds */ 03212 max += ast_add_fd(&pfds[max], c[x]->fds[y]); 03213 } 03214 CHECK_BLOCKING(c[x]); 03215 } 03216 /* Add the individual fds */ 03217 for (x = 0; x < nfds; x++) { 03218 fdmap[max].chan = -1; 03219 max += ast_add_fd(&pfds[max], fds[x]); 03220 } 03221 03222 if (*ms > 0) 03223 start = ast_tvnow(); 03224 03225 if (sizeof(int) == 4) { /* XXX fix timeout > 600000 on linux x86-32 */ 03226 do { 03227 int kbrms = rms; 03228 if (kbrms > 600000) 03229 kbrms = 600000; 03230 res = ast_poll(pfds, max, kbrms); 03231 if (!res) 03232 rms -= kbrms; 03233 } while (!res && (rms > 0)); 03234 } else { 03235 res = ast_poll(pfds, max, rms); 03236 } 03237 for (x = 0; x < n; x++) 03238 ast_clear_flag(c[x], AST_FLAG_BLOCKING); 03239 if (res < 0) { /* Simulate a timeout if we were interrupted */ 03240 if (errno != EINTR) 03241 *ms = -1; 03242 return NULL; 03243 } 03244 if (!ast_tvzero(whentohangup)) { /* if we have a timeout, check who expired */ 03245 now = ast_tvnow(); 03246 for (x = 0; x < n; x++) { 03247 if (!ast_tvzero(c[x]->whentohangup) && ast_tvcmp(c[x]->whentohangup, now) <= 0) { 03248 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 03249 if (winner == NULL) 03250 winner = c[x]; 03251 } 03252 } 03253 } 03254 if (res == 0) { /* no fd ready, reset timeout and done */ 03255 *ms = 0; /* XXX use 0 since we may not have an exact timeout. */ 03256 return winner; 03257 } 03258 /* 03259 * Then check if any channel or fd has a pending event. 03260 * Remember to check channels first and fds last, as they 03261 * must have priority on setting 'winner' 03262 */ 03263 for (x = 0; x < max; x++) { 03264 res = pfds[x].revents; 03265 if (res == 0) 03266 continue; 03267 if (fdmap[x].chan >= 0) { /* this is a channel */ 03268 winner = c[fdmap[x].chan]; /* override previous winners */ 03269 if (res & POLLPRI) 03270 ast_set_flag(winner, AST_FLAG_EXCEPTION); 03271 else 03272 ast_clear_flag(winner, AST_FLAG_EXCEPTION); 03273 winner->fdno = fdmap[x].fdno; 03274 } else { /* this is an fd */ 03275 if (outfd) 03276 *outfd = pfds[x].fd; 03277 if (exception) 03278 *exception = (res & POLLPRI) ? -1 : 0; 03279 winner = NULL; 03280 } 03281 } 03282 if (*ms > 0) { 03283 *ms -= ast_tvdiff_ms(ast_tvnow(), start); 03284 if (*ms < 0) 03285 *ms = 0; 03286 } 03287 return winner; 03288 }
int ast_waitfordigit | ( | struct ast_channel * | c, | |
int | ms | |||
) |
Waits for a digit.
c | channel to wait for a digit on | |
ms | how many milliseconds to wait |
Definition at line 3497 of file channel.c.
References ast_waitfordigit_full().
Referenced by __analog_ss_thread(), _while_exec(), adsi_get_cpeid(), adsi_get_cpeinfo(), adsi_print(), adsi_read_encoded_dtmf(), adsi_transmit_message_full(), advanced_options(), analog_my_getsigstr(), analog_ss_thread(), ast_app_dtget(), ast_control_streamfile(), ast_record_review(), bridge_channel_feature(), builtin_atxfer(), collect_digits(), common_exec(), cpeid_exec(), dialout(), directory_exec(), forward_message(), get_folder(), ivr_dispatch(), mgcp_ss(), my_getsigstr(), pbx_builtin_waitexten(), play_record_review(), pri_ss_thread(), read_exec(), read_newoption(), readexten_exec(), retrydial_exec(), select_item_menu(), select_item_pause(), select_item_seq(), sendnoise(), testclient_exec(), testserver_exec(), vm_execmain(), vm_forwardoptions(), vm_instructions_en(), vm_options(), vm_tempgreeting(), and wait_a_bit().
03498 { 03499 return ast_waitfordigit_full(c, ms, -1, -1); 03500 }
int ast_waitfordigit_full | ( | struct ast_channel * | c, | |
int | ms, | |||
int | audiofd, | |||
int | ctrlfd | |||
) |
Wait for a digit Same as ast_waitfordigit() with audio fd for outputting read audio and ctrlfd to monitor for reading.
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 3545 of file channel.c.
References ast_check_hangup(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_FLAG_END_DTMF_ONLY, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_frfree, ast_log(), ast_read(), ast_set_flag, ast_test_flag, ast_waitfor_nandfds(), errno, f, and LOG_WARNING.
Referenced by ast_readstring_full(), ast_waitfordigit(), handle_getoption(), and handle_waitfordigit().
03546 { 03547 /* Stop if we're a zombie or need a soft hangup */ 03548 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 03549 return -1; 03550 03551 /* Only look for the end of DTMF, don't bother with the beginning and don't emulate things */ 03552 ast_set_flag(c, AST_FLAG_END_DTMF_ONLY); 03553 03554 /* Wait for a digit, no more than ms milliseconds total. */ 03555 03556 while (ms) { 03557 struct ast_channel *rchan; 03558 int outfd=-1; 03559 03560 errno = 0; 03561 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 03562 03563 if (!rchan && outfd < 0 && ms) { 03564 if (errno == 0 || errno == EINTR) 03565 continue; 03566 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 03567 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03568 return -1; 03569 } else if (outfd > -1) { 03570 /* The FD we were watching has something waiting */ 03571 ast_log(LOG_WARNING, "The FD we were waiting for has something waiting. Waitfordigit returning numeric 1\n"); 03572 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03573 return 1; 03574 } else if (rchan) { 03575 int res; 03576 struct ast_frame *f = ast_read(c); 03577 if (!f) 03578 return -1; 03579 03580 switch (f->frametype) { 03581 case AST_FRAME_DTMF_BEGIN: 03582 break; 03583 case AST_FRAME_DTMF_END: 03584 res = f->subclass.integer; 03585 ast_frfree(f); 03586 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03587 return res; 03588 case AST_FRAME_CONTROL: 03589 switch (f->subclass.integer) { 03590 case AST_CONTROL_HANGUP: 03591 ast_frfree(f); 03592 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03593 return -1; 03594 case AST_CONTROL_RINGING: 03595 case AST_CONTROL_ANSWER: 03596 case AST_CONTROL_SRCUPDATE: 03597 case AST_CONTROL_SRCCHANGE: 03598 case AST_CONTROL_CONNECTED_LINE: 03599 case AST_CONTROL_REDIRECTING: 03600 case AST_CONTROL_UPDATE_RTP_PEER: 03601 case AST_CONTROL_HOLD: 03602 case AST_CONTROL_UNHOLD: 03603 case -1: 03604 /* Unimportant */ 03605 break; 03606 default: 03607 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass.integer); 03608 break; 03609 } 03610 break; 03611 case AST_FRAME_VOICE: 03612 /* Write audio if appropriate */ 03613 if (audiofd > -1) { 03614 if (write(audiofd, f->data.ptr, f->datalen) < 0) { 03615 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 03616 } 03617 } 03618 default: 03619 /* Ignore */ 03620 break; 03621 } 03622 ast_frfree(f); 03623 } 03624 } 03625 03626 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03627 03628 return 0; /* Time is up */ 03629 }
int ast_write | ( | struct ast_channel * | chan, | |
struct ast_frame * | frame | |||
) |
Write a frame to a channel This function writes the given frame to the indicated channel.
chan | destination channel of the frame | |
frame | frame that will be written |
Definition at line 4801 of file channel.c.
References ast_channel::_softhangup, apply_plc(), ast_audiohook_detach_list(), AST_AUDIOHOOK_DIRECTION_WRITE, ast_audiohook_write_list(), ast_audiohook_write_list_empty(), ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_CONTROL_UNHOLD, ast_deactivate_generator(), ast_debug, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_WRITE_INT, AST_FLAG_ZOMBIE, AST_FORMAT_AUDIO_MASK, ast_format_rate(), AST_FORMAT_SLINEAR, AST_FORMAT_T140, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_frame_dump(), AST_FRAME_HTML, AST_FRAME_IAX, AST_FRAME_MODEM, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_framehook_list_write_event(), ast_frfree, ast_frisolate(), ast_getformatname(), ast_getformatname_multiple(), AST_LIST_NEXT, ast_log(), AST_MONITOR_RUNNING, ast_opt_generic_plc, ast_seekstream(), ast_senddigit_begin(), ast_senddigit_end(), ast_set_write_format(), AST_SOFTHANGUP_DEV, ast_test_flag, ast_translate(), ast_writestream(), ast_channel::audiohooks, calc_monitor_jump(), chanlist::chan, CHECK_BLOCKING, ast_frame_subclass::codec, ast_frame::data, ast_frame::datalen, DEBUGCHAN_FLAG, f, ast_filestream::fmt, ast_format::format, ast_channel::fout, FRAMECOUNT_INC, ast_channel::framehooks, ast_frame::frametype, ast_channel::generatordata, ast_channel_tech::indicate, ast_channel::insmpl, ast_frame_subclass::integer, ast_frame::len, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::name, ast_channel::nativeformats, chanlist::next, ast_channel::outsmpl, ast_frame::ptr, ast_channel::rawwriteformat, ast_channel_monitor::read_stream, ast_frame::samples, SEEK_FORCECUR, send_dtmf_event(), ast_channel_tech::send_html, ast_channel_tech::send_text, ast_frame::src, ast_channel_monitor::state, ast_frame::subclass, ast_channel::tech, ast_channel_tech::write, ast_channel_monitor::write_stream, ast_channel_tech::write_text, ast_channel_tech::write_video, ast_channel::writeformat, and ast_channel::writetrans.
Referenced by adsi_careful_send(), agent_write(), ast_bridge_call(), ast_prod(), ast_readaudio_callback(), ast_readvideo_callback(), ast_udptl_bridge(), ast_write_video(), conf_queue_dtmf(), conf_run(), dahdi_bridge(), dictate_exec(), echo_exec(), fax_generator_generate(), feature_request_and_dial(), gen_generate(), generic_fax_exec(), handle_jack_audio(), jb_get_and_deliver(), linear_generator(), milliwatt_generate(), misdn_bridge(), moh_files_generator(), moh_generate(), mp3_exec(), multiplexed_bridge_write(), NBScat_exec(), remote_bridge_loop(), send_tone_burst(), send_waveform_to_channel(), silence_generator_generate(), simple_bridge_write(), softmix_bridge_poke(), softmix_bridge_write(), spy_generate(), and t38_tx_packet_handler().
04802 { 04803 int res = -1; 04804 struct ast_frame *f = NULL; 04805 int count = 0; 04806 04807 /*Deadlock avoidance*/ 04808 while(ast_channel_trylock(chan)) { 04809 /*cannot goto done since the channel is not locked*/ 04810 if(count++ > 10) { 04811 ast_debug(1, "Deadlock avoided for write to channel '%s'\n", chan->name); 04812 return 0; 04813 } 04814 usleep(1); 04815 } 04816 /* Stop if we're a zombie or need a soft hangup */ 04817 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) 04818 goto done; 04819 04820 /* Handle any pending masquerades */ 04821 while (chan->masq) { 04822 ast_channel_unlock(chan); 04823 ast_do_masquerade(chan); 04824 ast_channel_lock(chan); 04825 } 04826 if (chan->masqr) { 04827 res = 0; /* XXX explain, why 0 ? */ 04828 goto done; 04829 } 04830 04831 /* Perform the framehook write event here. After the frame enters the framehook list 04832 * there is no telling what will happen, how awesome is that!!! */ 04833 if (!(fr = ast_framehook_list_write_event(chan->framehooks, fr))) { 04834 res = 0; 04835 goto done; 04836 } 04837 04838 if (chan->generatordata && (!fr->src || strcasecmp(fr->src, "ast_prod"))) { 04839 if (ast_test_flag(chan, AST_FLAG_WRITE_INT)) { 04840 ast_deactivate_generator(chan); 04841 } else { 04842 if (fr->frametype == AST_FRAME_DTMF_END) { 04843 /* There is a generator running while we're in the middle of a digit. 04844 * It's probably inband DTMF, so go ahead and pass it so it can 04845 * stop the generator */ 04846 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04847 ast_channel_unlock(chan); 04848 res = ast_senddigit_end(chan, fr->subclass.integer, fr->len); 04849 ast_channel_lock(chan); 04850 CHECK_BLOCKING(chan); 04851 } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_UNHOLD) { 04852 /* This is a side case where Echo is basically being called and the person put themselves on hold and took themselves off hold */ 04853 res = (chan->tech->indicate == NULL) ? 0 : 04854 chan->tech->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen); 04855 } 04856 res = 0; /* XXX explain, why 0 ? */ 04857 goto done; 04858 } 04859 } 04860 /* High bit prints debugging */ 04861 if (chan->fout & DEBUGCHAN_FLAG) 04862 ast_frame_dump(chan->name, fr, ">>"); 04863 CHECK_BLOCKING(chan); 04864 switch (fr->frametype) { 04865 case AST_FRAME_CONTROL: 04866 res = (chan->tech->indicate == NULL) ? 0 : 04867 chan->tech->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen); 04868 break; 04869 case AST_FRAME_DTMF_BEGIN: 04870 if (chan->audiohooks) { 04871 struct ast_frame *old_frame = fr; 04872 fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr); 04873 if (old_frame != fr) 04874 f = fr; 04875 } 04876 send_dtmf_event(chan, "Sent", fr->subclass.integer, "Yes", "No"); 04877 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04878 ast_channel_unlock(chan); 04879 res = ast_senddigit_begin(chan, fr->subclass.integer); 04880 ast_channel_lock(chan); 04881 CHECK_BLOCKING(chan); 04882 break; 04883 case AST_FRAME_DTMF_END: 04884 if (chan->audiohooks) { 04885 struct ast_frame *new_frame = fr; 04886 04887 new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr); 04888 if (new_frame != fr) { 04889 ast_frfree(new_frame); 04890 } 04891 } 04892 send_dtmf_event(chan, "Sent", fr->subclass.integer, "No", "Yes"); 04893 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04894 ast_channel_unlock(chan); 04895 res = ast_senddigit_end(chan, fr->subclass.integer, fr->len); 04896 ast_channel_lock(chan); 04897 CHECK_BLOCKING(chan); 04898 break; 04899 case AST_FRAME_TEXT: 04900 if (fr->subclass.integer == AST_FORMAT_T140) { 04901 res = (chan->tech->write_text == NULL) ? 0 : 04902 chan->tech->write_text(chan, fr); 04903 } else { 04904 res = (chan->tech->send_text == NULL) ? 0 : 04905 chan->tech->send_text(chan, (char *) fr->data.ptr); 04906 } 04907 break; 04908 case AST_FRAME_HTML: 04909 res = (chan->tech->send_html == NULL) ? 0 : 04910 chan->tech->send_html(chan, fr->subclass.integer, (char *) fr->data.ptr, fr->datalen); 04911 break; 04912 case AST_FRAME_VIDEO: 04913 /* XXX Handle translation of video codecs one day XXX */ 04914 res = (chan->tech->write_video == NULL) ? 0 : 04915 chan->tech->write_video(chan, fr); 04916 break; 04917 case AST_FRAME_MODEM: 04918 res = (chan->tech->write == NULL) ? 0 : 04919 chan->tech->write(chan, fr); 04920 break; 04921 case AST_FRAME_VOICE: 04922 if (chan->tech->write == NULL) 04923 break; /*! \todo XXX should return 0 maybe ? */ 04924 04925 if (ast_opt_generic_plc && fr->subclass.codec == AST_FORMAT_SLINEAR) { 04926 apply_plc(chan, fr); 04927 } 04928 04929 /* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */ 04930 if (fr->subclass.codec == chan->rawwriteformat) { 04931 f = fr; 04932 } else { 04933 if ((!(fr->subclass.codec & chan->nativeformats)) && (chan->writeformat != fr->subclass.codec)) { 04934 char nf[512]; 04935 04936 /* 04937 * XXX Something is not right. We are not compatible with this 04938 * frame. Bad things can happen. Problems range from no audio, 04939 * one-way audio, to unexplained line hangups. As a last resort 04940 * try to adjust the format. Ideally, we do not want to do this 04941 * because it indicates a deeper problem. For now, we log these 04942 * events to reduce user impact and help identify the problem 04943 * areas. 04944 */ 04945 ast_log(LOG_WARNING, "Codec mismatch on channel %s setting write format to %s from %s native formats %s\n", 04946 chan->name, ast_getformatname(fr->subclass.codec), ast_getformatname(chan->writeformat), 04947 ast_getformatname_multiple(nf, sizeof(nf), chan->nativeformats & AST_FORMAT_AUDIO_MASK)); 04948 ast_set_write_format(chan, fr->subclass.codec); 04949 } 04950 04951 f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr; 04952 } 04953 04954 if (!f) { 04955 res = 0; 04956 break; 04957 } 04958 04959 if (chan->audiohooks) { 04960 struct ast_frame *prev = NULL, *new_frame, *cur, *dup; 04961 int freeoldlist = 0; 04962 04963 if (f != fr) { 04964 freeoldlist = 1; 04965 } 04966 04967 /* Since ast_audiohook_write may return a new frame, and the cur frame is 04968 * an item in a list of frames, create a new list adding each cur frame back to it 04969 * regardless if the cur frame changes or not. */ 04970 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 04971 new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, cur); 04972 04973 /* if this frame is different than cur, preserve the end of the list, 04974 * free the old frames, and set cur to be the new frame */ 04975 if (new_frame != cur) { 04976 04977 /* doing an ast_frisolate here seems silly, but we are not guaranteed the new_frame 04978 * isn't part of local storage, meaning if ast_audiohook_write is called multiple 04979 * times it may override the previous frame we got from it unless we dup it */ 04980 if ((dup = ast_frisolate(new_frame))) { 04981 AST_LIST_NEXT(dup, frame_list) = AST_LIST_NEXT(cur, frame_list); 04982 if (freeoldlist) { 04983 AST_LIST_NEXT(cur, frame_list) = NULL; 04984 ast_frfree(cur); 04985 } 04986 if (new_frame != dup) { 04987 ast_frfree(new_frame); 04988 } 04989 cur = dup; 04990 } 04991 } 04992 04993 /* now, regardless if cur is new or not, add it to the new list, 04994 * if the new list has not started, cur will become the first item. */ 04995 if (prev) { 04996 AST_LIST_NEXT(prev, frame_list) = cur; 04997 } else { 04998 f = cur; /* set f to be the beginning of our new list */ 04999 } 05000 prev = cur; 05001 } 05002 } 05003 05004 /* If Monitor is running on this channel, then we have to write frames out there too */ 05005 /* the translator on chan->writetrans may have returned multiple frames 05006 from the single frame we passed in; if so, feed each one of them to the 05007 monitor */ 05008 if (chan->monitor && chan->monitor->write_stream) { 05009 struct ast_frame *cur; 05010 05011 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 05012 /* XXX must explain this code */ 05013 #ifndef MONITOR_CONSTANT_DELAY 05014 int jump = chan->insmpl - chan->outsmpl - 4 * cur->samples; 05015 if (jump >= 0) { 05016 jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format)); 05017 if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1) 05018 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 05019 chan->outsmpl += (chan->insmpl - chan->outsmpl) + cur->samples; 05020 } else { 05021 chan->outsmpl += cur->samples; 05022 } 05023 #else 05024 int jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format)); 05025 if (jump - MONITOR_DELAY >= 0) { 05026 if (ast_seekstream(chan->monitor->write_stream, jump - cur->samples, SEEK_FORCECUR) == -1) 05027 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 05028 chan->outsmpl += chan->insmpl - chan->outsmpl; 05029 } else { 05030 chan->outsmpl += cur->samples; 05031 } 05032 #endif 05033 if (chan->monitor->state == AST_MONITOR_RUNNING) { 05034 if (ast_writestream(chan->monitor->write_stream, cur) < 0) 05035 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n"); 05036 } 05037 } 05038 } 05039 05040 /* the translator on chan->writetrans may have returned multiple frames 05041 from the single frame we passed in; if so, feed each one of them to the 05042 channel, freeing each one after it has been written */ 05043 if ((f != fr) && AST_LIST_NEXT(f, frame_list)) { 05044 struct ast_frame *cur, *next; 05045 unsigned int skip = 0; 05046 05047 for (cur = f, next = AST_LIST_NEXT(cur, frame_list); 05048 cur; 05049 cur = next, next = cur ? AST_LIST_NEXT(cur, frame_list) : NULL) { 05050 if (!skip) { 05051 if ((res = chan->tech->write(chan, cur)) < 0) { 05052 chan->_softhangup |= AST_SOFTHANGUP_DEV; 05053 skip = 1; 05054 } else if (next) { 05055 /* don't do this for the last frame in the list, 05056 as the code outside the loop will do it once 05057 */ 05058 chan->fout = FRAMECOUNT_INC(chan->fout); 05059 } 05060 } 05061 ast_frfree(cur); 05062 } 05063 05064 /* reset f so the code below doesn't attempt to free it */ 05065 f = NULL; 05066 } else { 05067 res = chan->tech->write(chan, f); 05068 } 05069 break; 05070 case AST_FRAME_NULL: 05071 case AST_FRAME_IAX: 05072 /* Ignore these */ 05073 res = 0; 05074 break; 05075 default: 05076 /* At this point, fr is the incoming frame and f is NULL. Channels do 05077 * not expect to get NULL as a frame pointer and will segfault. Hence, 05078 * we output the original frame passed in. */ 05079 res = chan->tech->write(chan, fr); 05080 break; 05081 } 05082 05083 if (f && f != fr) 05084 ast_frfree(f); 05085 ast_clear_flag(chan, AST_FLAG_BLOCKING); 05086 05087 /* Consider a write failure to force a soft hangup */ 05088 if (res < 0) { 05089 chan->_softhangup |= AST_SOFTHANGUP_DEV; 05090 } else { 05091 chan->fout = FRAMECOUNT_INC(chan->fout); 05092 } 05093 done: 05094 if (chan->audiohooks && ast_audiohook_write_list_empty(chan->audiohooks)) { 05095 /* The list gets recreated if audiohooks are added again later */ 05096 ast_audiohook_detach_list(chan->audiohooks); 05097 chan->audiohooks = NULL; 05098 } 05099 ast_channel_unlock(chan); 05100 return res; 05101 }
int ast_write_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 4686 of file channel.c.
References ast_write(), chanlist::chan, ast_channel::tech, and ast_channel_tech::write_video.
04687 { 04688 int res; 04689 if (!chan->tech->write_video) 04690 return 0; 04691 res = ast_write(chan, fr); 04692 if (!res) 04693 res = 1; 04694 return res; 04695 }
const char* channelreloadreason2txt | ( | enum channelreloadreason | reason | ) |
Convert enum channelreloadreason to text string for manager event.
\ brief Convert channel reloadreason (ENUM) to text string for manager event
Definition at line 8150 of file channel.c.
References CHANNEL_CLI_RELOAD, CHANNEL_MODULE_LOAD, and CHANNEL_MODULE_RELOAD.
08151 { 08152 switch (reason) { 08153 case CHANNEL_MODULE_LOAD: 08154 return "LOAD (Channel module load)"; 08155 08156 case CHANNEL_MODULE_RELOAD: 08157 return "RELOAD (Channel module reload)"; 08158 08159 case CHANNEL_CLI_RELOAD: 08160 return "CLIRELOAD (Channel module reload by CLI command)"; 08161 08162 default: 08163 return "MANAGERRELOAD (Channel module reload by manager)"; 08164 } 08165 };
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 658 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 102 of file channel.c.
Referenced by handle_core_set_debug_channel().
unsigned long global_fout |