#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,) |
#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) } |
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. | |
int | ast_channel_cmpwhentohangup (struct ast_channel *chan, time_t offset) |
Compare a offset with the settings of when to hang a channel up. | |
int | ast_channel_cmpwhentohangup_tv (struct ast_channel *chan, struct timeval offset) |
Compare a offset with the settings of when to hang a channel up. | |
int | ast_channel_connected_line_macro (struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *connected_info, int caller, int frame) |
Run a connected line interception macro and update a channel's connected line information. | |
int | ast_channel_data_add_structure (struct ast_data *tree, struct ast_channel *chan, int add_bridged) |
Insert into an astdata tree, the channel structure. | |
int | ast_channel_data_cmp_structure (const struct ast_data_search *tree, struct ast_channel *chan, const char *structure_name) |
Compare to channel structures using the data api. | |
int | ast_channel_datastore_add (struct ast_channel *chan, struct ast_datastore *datastore) |
Add a datastore to a channel. | |
ast_datastore *attribute_malloc | ast_channel_datastore_alloc (const struct ast_datastore_info *info, const char *uid) |
Create a channel data store object. | |
ast_datastore * | ast_channel_datastore_find (struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid) |
Find a datastore on a channel. | |
int | ast_channel_datastore_free (struct ast_datastore *datastore) |
Free a channel data store object. | |
int | ast_channel_datastore_inherit (struct ast_channel *from, struct ast_channel *to) |
Inherit datastores from a parent to a child. | |
int | ast_channel_datastore_remove (struct ast_channel *chan, struct ast_datastore *datastore) |
Remove a datastore from a channel. | |
int | ast_channel_defer_dtmf (struct ast_channel *chan) |
Defers DTMF so that you only read things like hangups and audio. | |
int | ast_channel_early_bridge (struct ast_channel *c0, struct ast_channel *c1) |
Bridge two channels together (early). | |
int | ast_channel_get_cc_agent_type (struct ast_channel *chan, char *agent_type, size_t size) |
Find the appropriate CC agent type to use given a channel. | |
ast_cc_config_params * | ast_channel_get_cc_config_params (struct ast_channel *chan) |
Get the CCSS parameters from a channel. | |
int | ast_channel_get_device_name (struct ast_channel *chan, char *device_name, size_t name_buffer_length) |
Get a device name given its channel structure. | |
static enum ast_t38_state | ast_channel_get_t38_state (struct ast_channel *chan) |
Retrieves the current T38 state of a channel. | |
void | ast_channel_inherit_variables (const struct ast_channel *parent, struct ast_channel *child) |
Inherits channel variable from parent to child channel. | |
int | ast_channel_make_compatible (struct ast_channel *c0, struct ast_channel *c1) |
Makes two channel formats compatible. | |
int | ast_channel_masquerade (struct ast_channel *original, struct ast_channel *clone) |
Weird function made for call transfers. | |
int | ast_channel_queryoption (struct ast_channel *channel, int option, void *data, int *datalen, int block) |
Checks the value of an option. | |
void | ast_channel_queue_connected_line_update (struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update) |
Queue a connected line update frame on a channel. | |
void | ast_channel_queue_redirecting_update (struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update) |
Queue a redirecting update frame on a channel. | |
const char * | ast_channel_reason2str (int reason) |
return an english explanation of the code returned thru __ast_request_and_dial's 'outstate' argument | |
int | ast_channel_redirecting_macro (struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *redirecting_info, int is_caller, int is_frame) |
Run a redirecting interception macro and update a channel's redirecting information. | |
int | ast_channel_register (const struct ast_channel_tech *tech) |
Register a channel technology (a new channel driver) Called by a channel module to register the kind of channels it supports. | |
ast_channel * | ast_channel_release (struct ast_channel *chan) |
Unlink and release reference to a channel. | |
int | ast_channel_sendhtml (struct ast_channel *channel, int subclass, const char *data, int datalen) |
Sends HTML on given channel Send HTML or URL on link. | |
int | ast_channel_sendurl (struct ast_channel *channel, const char *url) |
Sends a URL on a given link Send URL on link. | |
void | ast_channel_set_caller (struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update) |
Set the caller id information in the Asterisk channel. | |
void | ast_channel_set_caller_event (struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update) |
Set the caller id information in the Asterisk channel and generate an AMI event if the caller id name or number changed. | |
void | ast_channel_set_connected_line (struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update) |
Set the connected line information in the Asterisk channel. | |
void | ast_channel_set_fd (struct ast_channel *chan, int which, int fd) |
void | ast_channel_set_linkgroup (struct ast_channel *chan, struct ast_channel *peer) |
propagate the linked id between chan and peer | |
void | ast_channel_set_redirecting (struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update) |
Set the redirecting id information in the Asterisk channel. | |
int | ast_channel_setoption (struct ast_channel *channel, int option, void *data, int datalen, int block) |
Sets an option on a channel. | |
void | ast_channel_setwhentohangup (struct ast_channel *chan, time_t offset) |
Set when to hang a channel up. | |
void | ast_channel_setwhentohangup_tv (struct ast_channel *chan, struct timeval offset) |
Set when to hang a channel up. | |
ast_silence_generator * | ast_channel_start_silence_generator (struct ast_channel *chan) |
Starts a silence generator on the given channel. | |
void | ast_channel_stop_silence_generator (struct ast_channel *chan, struct ast_silence_generator *state) |
Stops a previously-started silence generator on the given channel. | |
int | ast_channel_supports_html (struct ast_channel *channel) |
Checks for HTML support on a channel. | |
int | ast_channel_transfer_masquerade (struct ast_channel *target_chan, const struct ast_party_connected_line *target_id, int target_held, struct ast_channel *transferee_chan, const struct ast_party_connected_line *transferee_id, int transferee_held) |
Setup a masquerade to transfer a call. | |
void | ast_channel_undefer_dtmf (struct ast_channel *chan) |
Unset defer DTMF flag on channel. | |
void | ast_channel_unregister (const struct ast_channel_tech *tech) |
Unregister a channel technology. | |
void | ast_channel_update_connected_line (struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update) |
Indicate that the connected line information has changed. | |
void | ast_channel_update_redirecting (struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update) |
Indicate that the redirecting id has changed. | |
ast_variable * | ast_channeltype_list (void) |
return an ast_variable list of channeltypes | |
int | ast_check_hangup (struct ast_channel *chan) |
Check to see if a channel is needing hang up. | |
int | ast_check_hangup_locked (struct ast_channel *chan) |
int | ast_connected_line_build_data (unsigned char *data, size_t datalen, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update) |
Build the connected line information data frame. | |
void | ast_connected_line_copy_from_caller (struct ast_party_connected_line *dest, const struct ast_party_caller *src) |
Copy the caller information to the connected line information. | |
void | ast_connected_line_copy_to_caller (struct ast_party_caller *dest, const struct ast_party_connected_line *src) |
Copy the connected line information to the caller information. | |
int | ast_connected_line_parse_data (const unsigned char *data, size_t datalen, struct ast_party_connected_line *connected) |
Parse connected line indication frame data. | |
void | ast_deactivate_generator (struct ast_channel *chan) |
int | ast_do_masquerade (struct ast_channel *chan) |
Start masquerading a channel. | |
ast_channel * | ast_dummy_channel_alloc (void) |
Create a fake channel structure. | |
static int | ast_fdisset (struct pollfd *pfds, int fd, int maximum, int *start) |
Helper function for migrating select to poll. | |
ast_channel_tech * | ast_get_channel_tech (const char *name) |
Get a channel technology structure by name. | |
ast_group_t | ast_get_group (const char *s) |
int | ast_hangup (struct ast_channel *chan) |
Hang up a channel. | |
int | ast_indicate (struct ast_channel *chan, int condition) |
Indicates condition of channel. | |
int | ast_indicate_data (struct ast_channel *chan, int condition, const void *data, size_t datalen) |
Indicates condition of channel, with payload. | |
int | ast_internal_timing_enabled (struct ast_channel *chan) |
Check if the channel can run in internal timing mode. | |
int | ast_is_deferrable_frame (const struct ast_frame *frame) |
Should we keep this frame for later? | |
void | ast_party_caller_copy (struct ast_party_caller *dest, const struct ast_party_caller *src) |
Copy the source caller information to the destination caller. | |
void | ast_party_caller_free (struct ast_party_caller *doomed) |
Destroy the caller party contents. | |
void | ast_party_caller_init (struct ast_party_caller *init) |
Initialize the given caller structure. | |
void | ast_party_caller_set (struct ast_party_caller *dest, const struct ast_party_caller *src, const struct ast_set_party_caller *update) |
Set the caller information based on another caller source. | |
void | ast_party_caller_set_init (struct ast_party_caller *init, const struct ast_party_caller *guide) |
Initialize the given caller structure using the given guide for a set update operation. | |
void | ast_party_connected_line_collect_caller (struct ast_party_connected_line *connected, struct ast_party_caller *caller) |
Collect the caller party information into a connected line structure. | |
void | ast_party_connected_line_copy (struct ast_party_connected_line *dest, const struct ast_party_connected_line *src) |
Copy the source connected line information to the destination connected line. | |
void | ast_party_connected_line_free (struct ast_party_connected_line *doomed) |
Destroy the connected line information contents. | |
void | ast_party_connected_line_init (struct ast_party_connected_line *init) |
Initialize the given connected line structure. | |
void | ast_party_connected_line_set (struct ast_party_connected_line *dest, const struct ast_party_connected_line *src, const struct ast_set_party_connected_line *update) |
Set the connected line information based on another connected line source. | |
void | ast_party_connected_line_set_init (struct ast_party_connected_line *init, const struct ast_party_connected_line *guide) |
Initialize the given connected line structure using the given guide for a set update operation. | |
void | ast_party_dialed_copy (struct ast_party_dialed *dest, const struct ast_party_dialed *src) |
Copy the source dialed party information to the destination dialed party. | |
void | ast_party_dialed_free (struct ast_party_dialed *doomed) |
Destroy the dialed party contents. | |
void | ast_party_dialed_init (struct ast_party_dialed *init) |
Initialize the given dialed structure. | |
void | ast_party_dialed_set (struct ast_party_dialed *dest, const struct ast_party_dialed *src) |
Set the dialed information based on another dialed source. | |
void | ast_party_dialed_set_init (struct ast_party_dialed *init, const struct ast_party_dialed *guide) |
Initialize the given dialed structure using the given guide for a set update operation. | |
void | ast_party_id_copy (struct ast_party_id *dest, const struct ast_party_id *src) |
Copy the source party id information to the destination party id. | |
void | ast_party_id_free (struct ast_party_id *doomed) |
Destroy the party id contents. | |
void | ast_party_id_init (struct ast_party_id *init) |
Initialize the given party id structure. | |
int | ast_party_id_presentation (const struct ast_party_id *id) |
Determine the overall presentation value for the given party. | |
void | ast_party_id_set (struct ast_party_id *dest, const struct ast_party_id *src, const struct ast_set_party_id *update) |
Set the source party id information into the destination party id. | |
void | ast_party_id_set_init (struct ast_party_id *init, const struct ast_party_id *guide) |
Initialize the given party id structure using the given guide for a set update operation. | |
void | ast_party_name_copy (struct ast_party_name *dest, const struct ast_party_name *src) |
Copy the source party name information to the destination party name. | |
void | ast_party_name_free (struct ast_party_name *doomed) |
Destroy the party name contents. | |
void | ast_party_name_init (struct ast_party_name *init) |
Initialize the given name structure. | |
void | ast_party_name_set (struct ast_party_name *dest, const struct ast_party_name *src) |
Set the source party name information into the destination party name. | |
void | ast_party_name_set_init (struct ast_party_name *init, const struct ast_party_name *guide) |
Initialize the given party name structure using the given guide for a set update operation. | |
void | ast_party_number_copy (struct ast_party_number *dest, const struct ast_party_number *src) |
Copy the source party number information to the destination party number. | |
void | ast_party_number_free (struct ast_party_number *doomed) |
Destroy the party number contents. | |
void | ast_party_number_init (struct ast_party_number *init) |
Initialize the given number structure. | |
void | ast_party_number_set (struct ast_party_number *dest, const struct ast_party_number *src) |
Set the source party number information into the destination party number. | |
void | ast_party_number_set_init (struct ast_party_number *init, const struct ast_party_number *guide) |
Initialize the given party number structure using the given guide for a set update operation. | |
void | ast_party_redirecting_copy (struct ast_party_redirecting *dest, const struct ast_party_redirecting *src) |
Copy the source redirecting information to the destination redirecting. | |
void | ast_party_redirecting_free (struct ast_party_redirecting *doomed) |
Destroy the redirecting information contents. | |
void | ast_party_redirecting_init (struct ast_party_redirecting *init) |
Initialize the given redirecting structure. | |
void | ast_party_redirecting_set (struct ast_party_redirecting *dest, const struct ast_party_redirecting *src, const struct ast_set_party_redirecting *update) |
Set the redirecting information based on another redirecting source. | |
void | ast_party_redirecting_set_init (struct ast_party_redirecting *init, const struct ast_party_redirecting *guide) |
Initialize the given redirecting id structure using the given guide for a set update operation. | |
void | ast_party_subaddress_copy (struct ast_party_subaddress *dest, const struct ast_party_subaddress *src) |
Copy the source party subaddress information to the destination party subaddress. | |
void | ast_party_subaddress_free (struct ast_party_subaddress *doomed) |
Destroy the party subaddress contents. | |
void | ast_party_subaddress_init (struct ast_party_subaddress *init) |
Initialize the given subaddress structure. | |
void | ast_party_subaddress_set (struct ast_party_subaddress *dest, const struct ast_party_subaddress *src) |
Set the source party subaddress information into the destination party subaddress. | |
void | ast_party_subaddress_set_init (struct ast_party_subaddress *init, const struct ast_party_subaddress *guide) |
Initialize the given party subaddress structure using the given guide for a set update operation. | |
void | ast_poll_channel_add (struct ast_channel *chan0, struct ast_channel *chan1) |
void | ast_poll_channel_del (struct ast_channel *chan0, struct ast_channel *chan1) |
char * | ast_print_group (char *buf, int buflen, ast_group_t group) |
print call- and pickup groups into buffer | |
int | ast_prod (struct ast_channel *chan) |
Send empty audio to prime a channel driver. | |
int | ast_queue_control (struct ast_channel *chan, enum ast_control_frame_type control) |
Queue a control frame with payload. | |
int | ast_queue_control_data (struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen) |
Queue a control frame with payload. | |
int | ast_queue_frame (struct ast_channel *chan, struct ast_frame *f) |
Queue one or more frames to a channel's frame queue. | |
int | ast_queue_frame_head (struct ast_channel *chan, struct ast_frame *f) |
Queue one or more frames to the head of a channel's frame queue. | |
int | ast_queue_hangup (struct ast_channel *chan) |
Queue a hangup frame. | |
int | ast_queue_hangup_with_cause (struct ast_channel *chan, int cause) |
Queue a hangup frame with hangupcause set. | |
int | ast_raw_answer (struct ast_channel *chan, int cdr_answer) |
Answer a channel. | |
ast_frame * | ast_read (struct ast_channel *chan) |
Reads a frame. | |
ast_frame * | ast_read_noaudio (struct ast_channel *chan) |
Reads a frame, returning AST_FRAME_NULL frame if audio. | |
int | ast_readstring (struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders) |
Reads multiple digits. | |
int | ast_readstring_full (struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders, int audiofd, int ctrlfd) |
int | ast_recvchar (struct ast_channel *chan, int timeout) |
Receives a text character from a channel. | |
char * | ast_recvtext (struct ast_channel *chan, int timeout) |
Receives a text string from a channel Read a string of text from a channel. | |
int | ast_redirecting_build_data (unsigned char *data, size_t datalen, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update) |
Build the redirecting id data frame. | |
int | ast_redirecting_parse_data (const unsigned char *data, size_t datalen, struct ast_party_redirecting *redirecting) |
Parse redirecting indication frame data. | |
ast_channel * | ast_request (const char *type, format_t format, const struct ast_channel *requestor, void *data, int *status) |
Requests a channel. | |
ast_channel * | ast_request_and_dial (const char *type, format_t format, const struct ast_channel *requestor, void *data, int timeout, int *reason, const char *cid_num, const char *cid_name) |
Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it. | |
int | ast_safe_sleep (struct ast_channel *chan, int ms) |
Wait for a specified amount of time, looking for hangups. | |
int | ast_safe_sleep_conditional (struct ast_channel *chan, int ms, int(*cond)(void *), void *data) |
Wait for a specified amount of time, looking for hangups and a condition argument. | |
int | ast_senddigit (struct ast_channel *chan, char digit, unsigned int duration) |
Send a DTMF digit to a channel. | |
int | ast_senddigit_begin (struct ast_channel *chan, char digit) |
Send a DTMF digit to a channel. | |
int | ast_senddigit_end (struct ast_channel *chan, char digit, unsigned int duration) |
Send a DTMF digit to a channel. | |
int | ast_sendtext (struct ast_channel *chan, const char *text) |
Sends text to a channel. | |
void | ast_set_callerid (struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani) |
Set caller ID number, name and ANI and generate AMI event. | |
void | ast_set_hangupsource (struct ast_channel *chan, const char *source, int force) |
Set the source of the hangup in this channel and it's bridge. | |
int | ast_set_read_format (struct ast_channel *chan, format_t format) |
Sets read format on channel chan Set read format for channel to whichever component of "format" is best. | |
void | ast_set_variables (struct ast_channel *chan, struct ast_variable *vars) |
adds a list of channel variables to a channel | |
int | ast_set_write_format (struct ast_channel *chan, format_t format) |
Sets write format on channel chan Set write format for channel to whichever component of "format" is best. | |
int | ast_settimeout (struct ast_channel *c, unsigned int rate, int(*func)(const void *data), void *data) |
Enable or disable timer ticks for a channel. | |
int | ast_shutting_down (void) |
Returns non-zero if Asterisk is being shut down. | |
int | ast_softhangup (struct ast_channel *chan, int reason) |
Softly hangup up a channel. | |
int | ast_softhangup_nolock (struct ast_channel *chan, int reason) |
Softly hangup up a channel (no channel lock). | |
const char * | ast_state2str (enum ast_channel_state) |
Gives the string form of a given channel state. | |
int | ast_str2cause (const char *name) attribute_pure |
Convert the string form of a cause code to a number. | |
int | ast_tonepair (struct ast_channel *chan, int freq1, int freq2, int duration, int vol) |
int | ast_tonepair_start (struct ast_channel *chan, int freq1, int freq2, int duration, int vol) |
void | ast_tonepair_stop (struct ast_channel *chan) |
int | ast_transfer (struct ast_channel *chan, char *dest) |
Transfer a channel (if supported). | |
char * | ast_transfercapability2str (int transfercapability) attribute_const |
Gives the string form of a given transfer capability. | |
int | ast_waitfor (struct ast_channel *chan, int ms) |
Wait for input on a channel. | |
ast_channel * | ast_waitfor_n (struct ast_channel **chan, int n, int *ms) |
Waits for input on a group of channels Wait for input on an array of channels for a given # of milliseconds. | |
int | ast_waitfor_n_fd (int *fds, int n, int *ms, int *exception) |
Waits for input on an fd. | |
ast_channel * | ast_waitfor_nandfds (struct ast_channel **chan, int n, int *fds, int nfds, int *exception, int *outfd, int *ms) |
Waits for activity on a group of channels. | |
int | ast_waitfordigit (struct ast_channel *c, int ms) |
Waits for a digit. | |
int | ast_waitfordigit_full (struct ast_channel *c, int ms, int audiofd, int ctrlfd) |
Wait for a digit Same as ast_waitfordigit() with audio fd for outputting read audio and ctrlfd to monitor for reading. | |
int | ast_write (struct ast_channel *chan, struct ast_frame *frame) |
Write a frame to a channel This function writes the given frame to the indicated channel. | |
int | ast_write_text (struct ast_channel *chan, struct ast_frame *frame) |
Write text frame to a channel This function writes the given frame to the indicated channel. | |
int | ast_write_video (struct ast_channel *chan, struct ast_frame *frame) |
Write video frame to a channel This function writes the given frame to the indicated channel. | |
const char * | channelreloadreason2txt (enum channelreloadreason reason) |
Convert enum channelreloadreason to text string for manager event. | |
Variables | |
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 1841 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 1843 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__)
Definition at line 1106 of file channel.h.
Referenced by __oh323_new(), action_bridge(), agent_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_pbx_outgoing_exten(), bridge_exec(), bridge_request(), builtin_atxfer(), check_goto_on_transfer(), console_new(), dahdi_new(), do_notify(), gtalk_new(), iax_park(), jingle_new(), local_new(), masq_park_call(), mgcp_new(), misdn_new(), multicast_rtp_request(), nbs_new(), oss_new(), phone_new(), sip_new(), sip_park(), skinny_new(), unistim_new(), and usbradio_new().
#define ast_channel_lock | ( | chan | ) | ao2_lock(chan) |
Definition at line 2369 of file channel.h.
Referenced by __ast_answer(), __ast_channel_masquerade(), __ast_queue_frame(), __ast_read(), __oh323_destroy(), __sip_destroy(), _macro_exec(), _while_exec(), acf_cc_read(), acf_cc_write(), action_add_agi_cmd(), action_coreshowchannels(), action_hangup(), action_redirect(), action_sendtext(), action_status(), action_timeout(), add_features_datastores(), add_to_agi(), agent_hangup(), agent_indicate(), 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_cmp_cb(), ast_channel_connected_line_macro(), ast_channel_destructor(), ast_channel_redirecting_macro(), ast_channel_set_caller(), ast_channel_set_caller_event(), ast_channel_set_connected_line(), ast_channel_set_redirecting(), ast_check_hangup_locked(), ast_complete_channels(), ast_deactivate_generator(), ast_dial_join(), ast_do_masquerade(), 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_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(), calendar_event_read(), calendar_query_exec(), calendar_query_result_exec(), callerid_read(), callerid_write(), cb_events(), cc_build_payload(), cc_interfaces_datastore_init(), channel_set_debug(), channel_spy(), common_exec(), conf_run(), conf_start_moh(), confbridge_exec(), connectedline_read(), connectedline_write(), crement_function_read(), dahdi_bridge(), dahdi_handle_dtmf(), data_channels_provider_handler(), dial_exec_full(), dialog_unlink_all(), disable_jack_hook(), do_forward(), dundi_query_read(), dundi_result_read(), enable_jack_hook(), end_bridge_callback(), enum_query_read(), enum_result_read(), feature_interpret(), feature_request_and_dial(), find_by_mark(), find_by_part(), find_calling_channel(), find_details(), find_or_create_details(), find_transaction(), frame_trace_helper(), func_channel_read(), func_channel_write_real(), func_channels_read(), func_header_read(), func_inheritance_write(), func_mute_write(), function_agent(), function_sipchaninfo_read(), generator_force(), generic_fax_exec(), get_agi_cmd(), get_cid_name(), handle_chanlist(), handle_cli_mixmonitor(), handle_invite_replaces(), handle_request_bye(), handle_request_invite(), handle_showchan(), handle_softhangup(), import_ch(), import_helper(), init_jack_data(), jack_hook_callback(), leave_voicemail(), linkedid_match(), listfilter(), local_ast_moh_stop(), local_call(), local_hangup(), local_read(), local_setoption(), login_exec(), lua_get_state(), manage_parkinglot(), manager_mutestream(), manager_park(), 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(), park_exec_full(), park_space_reserve(), pbx_builtin_background(), pbx_builtin_getvar_helper(), pbx_builtin_gotoiftime(), pbx_builtin_pushvar_helper(), pbx_builtin_serialize_variables(), pbx_builtin_setvar_helper(), peek_read(), pickup_by_exten(), pickup_by_mark(), pickup_by_name_cb(), pickup_by_part(), pickup_do(), pitchshift_helper(), process_sdp(), queue_exec(), receivefax_exec(), redirecting_read(), redirecting_write(), release_transaction(), report_fax_status(), retrydial_exec(), ring_entry(), 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_read(), sip_removeheader(), smdi_msg_read(), smdi_msg_retrieve_read(), softhangup_exec(), speech_background(), speex_read(), speex_write(), srv_datastore_setup(), srv_query_read(), srv_result_read(), start_monitor_action(), state_notify_build_xml(), stop_mixmonitor_exec(), transmit_invite(), try_calling(), update_bridge_vars(), and wait_for_answer().
#define ast_channel_lock_both | ( | chan1, | |||
chan2 | ) |
Lock two channels.
Definition at line 2376 of file channel.h.
Referenced by ast_pickup_call(), and do_bridge_masquerade().
#define AST_CHANNEL_NAME 80 |
Max length of an ast_channel name
Definition at line 137 of file channel.h.
Referenced by 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(), dial_exec_full(), fast_originate(), page_exec(), park_call_full(), sig_pri_call(), 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 2394 of file channel.h.
Referenced by ast_autochan_new_channel(), ast_autochan_setup(), ast_cel_report_event(), handle_getvariablefull(), handle_incoming(), handle_invite_replaces(), handle_request_refer(), and local_attended_transfer().
#define ast_channel_trylock | ( | chan | ) | ao2_trylock(chan) |
Definition at line 2371 of file channel.h.
Referenced by __ast_channel_masquerade(), __oh323_rtp_create(), __sip_autodestruct(), agent_indicate(), agent_logoff(), agent_read(), analog_lock_sub_owner(), ast_call_forward(), ast_do_masquerade(), ast_queue_hangup(), ast_queue_hangup_with_cause(), ast_rtp_instance_bridge(), ast_rtp_instance_early_bridge(), ast_rtp_instance_early_bridge_make_compatible(), ast_udptl_bridge(), ast_write(), auto_congest(), bridge_queue_hangup(), bridge_write(), check_bridge(), check_rtp_timeout(), cleanup_connection(), dahdi_bridge(), dahdi_handle_event(), dahdi_lock_sub_owner(), dahdi_queue_frame(), dahdi_softhangup_all(), dial_exec_full(), do_forward(), get_sip_pvt_byid_locked(), grab_owner(), handle_request_bye(), handle_request_do(), handle_request_refer(), hangup_connection(), iax2_destroy(), iax2_lock_owner(), local_call(), local_hangup(), local_queryoption(), local_queue_frame(), local_setoption(), manager_park(), 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(), ring_entry(), scheduler_process_request_queue(), setup_rtp_connection(), sig_pri_lock_owner(), sig_ss7_lock_owner(), sip_hangup(), sip_park(), sip_reinvite_retry(), and update_state().
#define ast_channel_unlock | ( | chan | ) | ao2_unlock(chan) |
Definition at line 2370 of file channel.h.
Referenced by __analog_handle_event(), __ast_answer(), __ast_channel_masquerade(), __ast_queue_frame(), __ast_read(), __oh323_destroy(), __oh323_rtp_create(), __sip_autodestruct(), __sip_destroy(), _macro_exec(), _while_exec(), acf_cc_read(), acf_cc_write(), action_add_agi_cmd(), action_coreshowchannels(), action_hangup(), action_redirect(), action_sendtext(), action_timeout(), add_features_datastores(), add_to_agi(), agent_hangup(), agent_indicate(), agent_logoff(), agent_read(), alsa_call(), analog_attempt_transfer(), analog_hangup(), 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_cmp_cb(), ast_channel_connected_line_macro(), ast_channel_destructor(), ast_channel_redirecting_macro(), ast_channel_set_caller(), ast_channel_set_caller_event(), ast_channel_set_connected_line(), ast_channel_set_redirecting(), ast_check_hangup_locked(), ast_complete_channels(), ast_deactivate_generator(), ast_dial_join(), ast_do_masquerade(), 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_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_exec(), bridge_play_sounds(), bridge_queue_hangup(), bridge_write(), builtin_atxfer(), builtin_automixmonitor(), calendar_event_read(), calendar_query_exec(), calendar_query_result_exec(), callerid_read(), callerid_write(), cb_events(), cc_build_payload(), cc_interfaces_datastore_init(), channel_set_debug(), channel_spy(), check_bridge(), check_rtp_timeout(), cleanup_connection(), common_exec(), conf_run(), conf_start_moh(), confbridge_exec(), connectedline_read(), connectedline_write(), console_answer(), console_hangup(), console_sendtext(), crement_function_read(), dahdi_bridge(), dahdi_handle_dtmf(), dahdi_handle_event(), dahdi_queue_frame(), dahdi_softhangup_all(), data_channels_provider_handler(), dial_exec_full(), 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(), fast_originate(), feature_interpret(), feature_request_and_dial(), find_by_mark(), find_by_part(), find_calling_channel(), find_details(), find_or_create_details(), find_transaction(), frame_trace_helper(), func_channel_read(), func_channel_write_real(), func_channels_read(), func_header_read(), func_inheritance_write(), func_mute_write(), function_agent(), function_sipchaninfo_read(), generator_force(), generic_fax_exec(), get_agi_cmd(), get_cid_name(), handle_chanlist(), handle_cli_agi_add_cmd(), handle_cli_mixmonitor(), handle_incoming(), handle_invite_replaces(), handle_request_bye(), handle_request_do(), handle_request_invite(), handle_request_refer(), handle_showchan(), handle_softhangup(), hangup_connection(), iax2_destroy(), iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), import_ch(), import_helper(), init_jack_data(), jack_hook_callback(), leave_voicemail(), linkedid_match(), listfilter(), local_ast_moh_stop(), local_attended_transfer(), local_bridge_loop(), local_call(), local_hangup(), local_queryoption(), local_queue_frame(), local_read(), local_setoption(), login_exec(), lua_get_state(), manage_parkinglot(), manager_mutestream(), manager_park(), 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(), park_exec_full(), park_space_reserve(), pbx_builtin_background(), pbx_builtin_getvar_helper(), pbx_builtin_gotoiftime(), pbx_builtin_pushvar_helper(), pbx_builtin_serialize_variables(), pbx_builtin_setvar_helper(), peek_read(), pickup_by_channel(), pickup_by_exten(), pickup_by_mark(), pickup_by_name_cb(), pickup_by_part(), pickup_do(), pitchshift_helper(), pri_fixup_principle(), pri_queue_frame(), proc_session_timer(), process_sdp(), queue_exec(), receive_digit(), receivefax_exec(), redirecting_read(), redirecting_write(), release_chan(), release_chan_early(), release_transaction(), remote_bridge_loop(), remote_hold(), report_fax_status(), retrans_pkt(), retrydial_exec(), ring_entry(), run_agi(), schedule_delivery(), 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_handle_hold(), sig_pri_handle_subcmds(), sig_ss7_queue_frame(), sip_addheader(), sip_dtmfmode(), sip_hangup(), sip_new(), sip_park(), sip_read(), sip_reinvite_retry(), sip_removeheader(), 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(), start_monitor_action(), state_notify_build_xml(), stop_mixmonitor_exec(), transmit_invite(), try_calling(), update_bridge_vars(), update_state(), 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 2405 of file channel.h.
Referenced by __ast_channel_alloc_ap(), action_add_agi_cmd(), action_aocmessage(), action_atxfer(), action_bridge(), action_coreshowchannels(), action_getvar(), action_hangup(), action_redirect(), action_sendtext(), action_setvar(), action_timeout(), ast_async_goto_by_name(), ast_autochan_destroy(), ast_autochan_new_channel(), ast_bridge_call(), ast_cel_check_retire_linkedid(), ast_cel_report_event(), ast_channel_release(), ast_complete_channels(), ast_dummy_channel_alloc(), ast_parse_device_state(), ast_pickup_call(), ast_var_channel_bridge(), ast_var_channel_types_table(), ast_var_channels_table(), asyncgoto_exec(), bridge_exec(), change_monitor_action(), common_exec(), data_channels_provider_handler(), 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_refer(), handle_set_chanvar(), handle_show_chanvar(), handle_showchan(), handle_softhangup(), import_helper(), local_attended_transfer(), manager_mute_mixmonitor(), manager_mutestream(), manager_optimize_away(), manager_park(), manager_play_dtmf(), park_call_full(), pbx_builtin_importvar(), pickup_by_channel(), pickup_by_exten(), pickup_by_mark(), pickup_by_part(), senddtmf_exec(), shared_read(), shared_write(), softhangup_exec(), start_monitor_action(), state_notify_build_xml(), and stop_monitor_action().
#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(), cleanup_stale_contexts(), common_exec(), conf_run(), config_parse_variables(), dial_transfer(), do_magic_pickup(), gtalk_load_config(), handle_gosub(), handle_request_invite(), 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_device_state_changed(), ast_devstate_changed(), ast_ivr_menu_run_internal(), begin_dial_channel(), build_device(), cc_extension_monitor_init(), conf_run(), destroy_station(), dial_exec_full(), dial_transfer(), disa_exec(), do_forward(), 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(), load_module(), log_exec(), manager_show_dialplan_helper(), mgcp_ss(), phone_check_exception(), pri_dchannel(), pri_ss_thread(), realtime_common(), realtime_switch_common(), search_directory_sub(), show_dialplan_helper(), sig_pri_party_number_convert(), skinny_extensionstate_cb(), skinny_ss(), speech_background(), state_notify_build_xml(), try_calling(), vm_authenticate(), and vmauthenticate().
#define AST_MAX_FDS 10 |
Definition at line 158 of file channel.h.
Referenced by ast_channel_destructor(), ast_do_masquerade(), ast_poll_channel_add(), ast_poll_channel_del(), and ast_waitfor_nandfds().
#define AST_TIMING_FD (AST_MAX_FDS-2) |
used for timingfd
Definition at line 164 of file channel.h.
Referenced by __ast_channel_alloc_ap(), __ast_read(), agent_read(), and ast_do_masquerade().
#define CHECK_BLOCKING | ( | c | ) |
Definition at line 2330 of file channel.h.
Referenced by ast_sendtext(), ast_waitfor_nandfds(), ast_write(), dahdi_read(), and phone_read().
#define DATASTORE_INHERIT_FOREVER INT_MAX |
Definition at line 156 of file channel.h.
Referenced by _macro_exec(), acf_iaxvar_write(), add_features_datastores(), ast_channel_datastore_inherit(), ast_iax2_new(), ast_setup_cc_recall_datastore(), authenticate_reply(), calendar_query_exec(), cc_interfaces_datastore_init(), dial_exec_full(), do_notify(), and socket_process().
#define DEBUGCHAN_FLAG 0x80000000 |
The high bit of the frame count is used as a debug marker, so increments of the counters must be done with care. Please use c->fin = FRAMECOUNT_INC(c->fin) and the same for c->fout.
Definition at line 639 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 867 of file channel.h.
00867 { 00868 /*! 00869 * \brief Channels have this property if they can accept input with jitter; 00870 * i.e. most VoIP channels 00871 */ 00872 AST_CHAN_TP_WANTSJITTER = (1 << 0), 00873 /*! 00874 * \brief Channels have this property if they can create jitter; 00875 * i.e. most VoIP channels 00876 */ 00877 AST_CHAN_TP_CREATESJITTER = (1 << 1), 00878 };
anonymous enum |
ast_channel flags
Definition at line 881 of file channel.h.
00881 { 00882 /*! Queue incoming DTMF, to be released when this flag is turned off */ 00883 AST_FLAG_DEFER_DTMF = (1 << 1), 00884 /*! write should be interrupt generator */ 00885 AST_FLAG_WRITE_INT = (1 << 2), 00886 /*! a thread is blocking on this channel */ 00887 AST_FLAG_BLOCKING = (1 << 3), 00888 /*! This is a zombie channel */ 00889 AST_FLAG_ZOMBIE = (1 << 4), 00890 /*! There is an exception pending */ 00891 AST_FLAG_EXCEPTION = (1 << 5), 00892 /*! Listening to moh XXX anthm promises me this will disappear XXX */ 00893 AST_FLAG_MOH = (1 << 6), 00894 /*! This channel is spying on another channel */ 00895 AST_FLAG_SPYING = (1 << 7), 00896 /*! This channel is in a native bridge */ 00897 AST_FLAG_NBRIDGE = (1 << 8), 00898 /*! the channel is in an auto-incrementing dialplan processor, 00899 * so when ->priority is set, it will get incremented before 00900 * finding the next priority to run */ 00901 AST_FLAG_IN_AUTOLOOP = (1 << 9), 00902 /*! This is an outgoing call */ 00903 AST_FLAG_OUTGOING = (1 << 10), 00904 /*! A DTMF_BEGIN frame has been read from this channel, but not yet an END */ 00905 AST_FLAG_IN_DTMF = (1 << 12), 00906 /*! A DTMF_END was received when not IN_DTMF, so the length of the digit is 00907 * currently being emulated */ 00908 AST_FLAG_EMULATE_DTMF = (1 << 13), 00909 /*! This is set to tell the channel not to generate DTMF begin frames, and 00910 * to instead only generate END frames. */ 00911 AST_FLAG_END_DTMF_ONLY = (1 << 14), 00912 /*! Flag to show channels that this call is hangup due to the fact that the call 00913 was indeed answered, but in another channel */ 00914 AST_FLAG_ANSWERED_ELSEWHERE = (1 << 15), 00915 /*! This flag indicates that on a masquerade, an active stream should not 00916 * be carried over */ 00917 AST_FLAG_MASQ_NOSTREAM = (1 << 16), 00918 /*! This flag indicates that the hangup exten was run when the bridge terminated, 00919 * a message aimed at preventing a subsequent hangup exten being run at the pbx_run 00920 * level */ 00921 AST_FLAG_BRIDGE_HANGUP_RUN = (1 << 17), 00922 /*! This flag indicates that the hangup exten should NOT be run when the 00923 * bridge terminates, this will allow the hangup in the pbx loop to be run instead. 00924 * */ 00925 AST_FLAG_BRIDGE_HANGUP_DONT = (1 << 18), 00926 /*! Disable certain workarounds. This reintroduces certain bugs, but allows 00927 * some non-traditional dialplans (like AGI) to continue to function. 00928 */ 00929 AST_FLAG_DISABLE_WORKAROUNDS = (1 << 20), 00930 };
anonymous enum |
ast_bridge_config flags
Definition at line 933 of file channel.h.
00933 { 00934 AST_FEATURE_PLAY_WARNING = (1 << 0), 00935 AST_FEATURE_REDIRECT = (1 << 1), 00936 AST_FEATURE_DISCONNECT = (1 << 2), 00937 AST_FEATURE_ATXFER = (1 << 3), 00938 AST_FEATURE_AUTOMON = (1 << 4), 00939 AST_FEATURE_PARKCALL = (1 << 5), 00940 AST_FEATURE_AUTOMIXMON = (1 << 6), 00941 AST_FEATURE_NO_H_EXTEN = (1 << 7), 00942 AST_FEATURE_WARNING_ACTIVE = (1 << 8), 00943 };
anonymous enum |
Definition at line 981 of file channel.h.
00981 { 00982 /*! 00983 * Soft hangup requested by device or other internal reason. 00984 * Actual hangup needed. 00985 */ 00986 AST_SOFTHANGUP_DEV = (1 << 0), 00987 /*! 00988 * Used to break the normal frame flow so an async goto can be 00989 * done instead of actually hanging up. 00990 */ 00991 AST_SOFTHANGUP_ASYNCGOTO = (1 << 1), 00992 /*! 00993 * Soft hangup requested by system shutdown. Actual hangup 00994 * needed. 00995 */ 00996 AST_SOFTHANGUP_SHUTDOWN = (1 << 2), 00997 /*! 00998 * Used to break the normal frame flow after a timeout so an 00999 * implicit async goto can be done to the 'T' exten if it exists 01000 * instead of actually hanging up. If the exten does not exist 01001 * then actually hangup. 01002 */ 01003 AST_SOFTHANGUP_TIMEOUT = (1 << 3), 01004 /*! 01005 * Soft hangup requested by application/channel-driver being 01006 * unloaded. Actual hangup needed. 01007 */ 01008 AST_SOFTHANGUP_APPUNLOAD = (1 << 4), 01009 /*! 01010 * Soft hangup requested by non-associated party. Actual hangup 01011 * needed. 01012 */ 01013 AST_SOFTHANGUP_EXPLICIT = (1 << 5), 01014 /*! 01015 * Used to break a bridge so the channel can be spied upon 01016 * instead of actually hanging up. 01017 */ 01018 AST_SOFTHANGUP_UNBRIDGE = (1 << 6), 01019 };
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 650 of file channel.h.
00650 { 00651 AST_ADSI_UNKNOWN, 00652 AST_ADSI_AVAILABLE, 00653 AST_ADSI_UNAVAILABLE, 00654 AST_ADSI_OFFHOOKONLY, 00655 };
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 660 of file channel.h.
00660 { 00661 T38_STATE_UNAVAILABLE, /*!< T38 is unavailable on this channel or disabled by configuration */ 00662 T38_STATE_UNKNOWN, /*!< The channel supports T38 but the current status is unknown */ 00663 T38_STATE_NEGOTIATING, /*!< T38 is being negotiated */ 00664 T38_STATE_REJECTED, /*!< Remote side has rejected our offer */ 00665 T38_STATE_NEGOTIATED, /*!< T38 established */ 00666 };
enum channelreloadreason |
Channel reload reasons for manager events at load or reload of configuration.
Definition at line 1023 of file channel.h.
01023 { 01024 CHANNEL_MODULE_LOAD, 01025 CHANNEL_MODULE_RELOAD, 01026 CHANNEL_CLI_RELOAD, 01027 CHANNEL_MANAGER_RELOAD, 01028 };
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 2825 of file channel.c.
References ast_channel::_state, ast_channel_lock, ast_channel_unlock, AST_CONTROL_HANGUP, ast_debug, AST_FRAME_CNG, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_HTML, AST_FRAME_IAX, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_frisolate(), AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_HEAD_NOLOCK, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_HEAD, ast_log(), ast_queue_frame_head(), ast_raw_answer(), ast_read(), AST_STATE_RING, AST_STATE_RINGING, ast_waitfor(), chanlist::chan, errno, frames, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, MAX, ast_channel::name, and ast_frame::subclass.
Referenced by ast_answer(), dial_exec_full(), pbx_builtin_answer(), and pbx_builtin_incomplete().
02826 { 02827 int res = 0; 02828 enum ast_channel_state old_state; 02829 02830 old_state = chan->_state; 02831 if ((res = ast_raw_answer(chan, cdr_answer))) { 02832 return res; 02833 } 02834 02835 switch (old_state) { 02836 case AST_STATE_RINGING: 02837 case AST_STATE_RING: 02838 /* wait for media to start flowing, but don't wait any longer 02839 * than 'delay' or 500 milliseconds, whichever is longer 02840 */ 02841 do { 02842 AST_LIST_HEAD_NOLOCK(, ast_frame) frames; 02843 struct ast_frame *cur, *new; 02844 int ms = MAX(delay, 500); 02845 unsigned int done = 0; 02846 02847 AST_LIST_HEAD_INIT_NOLOCK(&frames); 02848 02849 for (;;) { 02850 ms = ast_waitfor(chan, ms); 02851 if (ms < 0) { 02852 ast_log(LOG_WARNING, "Error condition occurred when polling channel %s for a voice frame: %s\n", chan->name, strerror(errno)); 02853 res = -1; 02854 break; 02855 } 02856 if (ms == 0) { 02857 ast_debug(2, "Didn't receive a media frame from %s within %d ms of answering. Continuing anyway\n", chan->name, MAX(delay, 500)); 02858 break; 02859 } 02860 cur = ast_read(chan); 02861 if (!cur || ((cur->frametype == AST_FRAME_CONTROL) && 02862 (cur->subclass.integer == AST_CONTROL_HANGUP))) { 02863 if (cur) { 02864 ast_frfree(cur); 02865 } 02866 res = -1; 02867 ast_debug(2, "Hangup of channel %s detected in answer routine\n", chan->name); 02868 break; 02869 } 02870 02871 if ((new = ast_frisolate(cur)) != cur) { 02872 ast_frfree(cur); 02873 } 02874 02875 AST_LIST_INSERT_HEAD(&frames, new, frame_list); 02876 02877 /* if a specific delay period was requested, continue 02878 * until that delay has passed. don't stop just because 02879 * incoming media has arrived. 02880 */ 02881 if (delay) { 02882 continue; 02883 } 02884 02885 switch (new->frametype) { 02886 /* all of these frametypes qualify as 'media' */ 02887 case AST_FRAME_VOICE: 02888 case AST_FRAME_VIDEO: 02889 case AST_FRAME_TEXT: 02890 case AST_FRAME_DTMF_BEGIN: 02891 case AST_FRAME_DTMF_END: 02892 case AST_FRAME_IMAGE: 02893 case AST_FRAME_HTML: 02894 case AST_FRAME_MODEM: 02895 done = 1; 02896 break; 02897 case AST_FRAME_CONTROL: 02898 case AST_FRAME_IAX: 02899 case AST_FRAME_NULL: 02900 case AST_FRAME_CNG: 02901 break; 02902 } 02903 02904 if (done) { 02905 break; 02906 } 02907 } 02908 02909 if (res == 0) { 02910 ast_channel_lock(chan); 02911 while ((cur = AST_LIST_REMOVE_HEAD(&frames, frame_list))) { 02912 ast_queue_frame_head(chan, cur); 02913 ast_frfree(cur); 02914 } 02915 ast_channel_unlock(chan); 02916 } 02917 } while (0); 02918 break; 02919 default: 02920 break; 02921 } 02922 02923 return res; 02924 }
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 |
Definition at line 1295 of file channel.c.
References __ast_channel_alloc_ap().
01301 { 01302 va_list ap1, ap2; 01303 struct ast_channel *result; 01304 01305 va_start(ap1, name_fmt); 01306 va_start(ap2, name_fmt); 01307 result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context, 01308 linkedid, amaflag, file, line, function, name_fmt, ap1, ap2); 01309 va_end(ap1); 01310 va_end(ap2); 01311 01312 return result; 01313 }
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 5151 of file channel.c.
References ast_channel::_state, outgoing_helper::account, ast_call(), ast_call_forward(), AST_CAUSE_NO_ANSWER, ast_cdr_alloc(), ast_cdr_answer(), ast_cdr_busy(), ast_cdr_disposition(), ast_cdr_end(), ast_cdr_failed(), AST_CDR_FLAG_ORIGINATED, ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_setapp(), ast_cdr_start(), ast_cdr_update(), ast_channel_datastore_inherit(), ast_channel_inherit_variables(), ast_channel_set_connected_line(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CC, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_copy_string(), AST_FRAME_CONTROL, ast_frfree, ast_hangup(), ast_log(), ast_party_connected_line_set_init(), AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, ast_read(), ast_request(), ast_set_callerid(), ast_set_flag, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_waitfor(), ast_channel::call_forward, cause, ast_channel::cdr, chanlist::chan, outgoing_helper::cid_name, outgoing_helper::cid_num, 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().
05152 { 05153 int dummy_outstate; 05154 int cause = 0; 05155 struct ast_channel *chan; 05156 int res = 0; 05157 int last_subclass = 0; 05158 struct ast_party_connected_line connected; 05159 05160 if (outstate) 05161 *outstate = 0; 05162 else 05163 outstate = &dummy_outstate; /* make outstate always a valid pointer */ 05164 05165 chan = ast_request(type, format, requestor, data, &cause); 05166 if (!chan) { 05167 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data); 05168 handle_cause(cause, outstate); 05169 return NULL; 05170 } 05171 05172 if (oh) { 05173 if (oh->vars) 05174 ast_set_variables(chan, oh->vars); 05175 /* XXX why is this necessary, for the parent_channel perhaps ? */ 05176 if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) 05177 ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num); 05178 if (oh->parent_channel) { 05179 ast_channel_inherit_variables(oh->parent_channel, chan); 05180 ast_channel_datastore_inherit(oh->parent_channel, chan); 05181 } 05182 if (oh->account) 05183 ast_cdr_setaccount(chan, oh->account); 05184 } 05185 05186 ast_set_callerid(chan, cid_num, cid_name, cid_num); 05187 ast_set_flag(chan->cdr, AST_CDR_FLAG_ORIGINATED); 05188 ast_party_connected_line_set_init(&connected, &chan->connected); 05189 if (cid_num) { 05190 connected.id.number.valid = 1; 05191 connected.id.number.str = (char *) cid_num; 05192 connected.id.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 05193 } 05194 if (cid_name) { 05195 connected.id.name.valid = 1; 05196 connected.id.name.str = (char *) cid_name; 05197 connected.id.name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 05198 } 05199 ast_channel_set_connected_line(chan, &connected, NULL); 05200 05201 if (ast_call(chan, data, 0)) { /* ast_call failed... */ 05202 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data); 05203 } else { 05204 res = 1; /* mark success in case chan->_state is already AST_STATE_UP */ 05205 while (timeout && chan->_state != AST_STATE_UP) { 05206 struct ast_frame *f; 05207 res = ast_waitfor(chan, timeout); 05208 if (res == 0) { /* timeout, treat it like ringing */ 05209 *outstate = AST_CONTROL_RINGING; 05210 break; 05211 } 05212 if (res < 0) /* error or done */ 05213 break; 05214 if (timeout > -1) 05215 timeout = res; 05216 if (!ast_strlen_zero(chan->call_forward)) { 05217 if (!(chan = ast_call_forward(NULL, chan, NULL, format, oh, outstate))) { 05218 return NULL; 05219 } 05220 continue; 05221 } 05222 05223 f = ast_read(chan); 05224 if (!f) { 05225 *outstate = AST_CONTROL_HANGUP; 05226 res = 0; 05227 break; 05228 } 05229 if (f->frametype == AST_FRAME_CONTROL) { 05230 switch (f->subclass.integer) { 05231 case AST_CONTROL_RINGING: /* record but keep going */ 05232 *outstate = f->subclass.integer; 05233 break; 05234 05235 case AST_CONTROL_BUSY: 05236 ast_cdr_busy(chan->cdr); 05237 *outstate = f->subclass.integer; 05238 timeout = 0; 05239 break; 05240 05241 case AST_CONTROL_CONGESTION: 05242 ast_cdr_failed(chan->cdr); 05243 *outstate = f->subclass.integer; 05244 timeout = 0; 05245 break; 05246 05247 case AST_CONTROL_ANSWER: 05248 ast_cdr_answer(chan->cdr); 05249 *outstate = f->subclass.integer; 05250 timeout = 0; /* trick to force exit from the while() */ 05251 break; 05252 05253 /* Ignore these */ 05254 case AST_CONTROL_PROGRESS: 05255 case AST_CONTROL_PROCEEDING: 05256 case AST_CONTROL_HOLD: 05257 case AST_CONTROL_UNHOLD: 05258 case AST_CONTROL_VIDUPDATE: 05259 case AST_CONTROL_SRCUPDATE: 05260 case AST_CONTROL_SRCCHANGE: 05261 case AST_CONTROL_CONNECTED_LINE: 05262 case AST_CONTROL_REDIRECTING: 05263 case AST_CONTROL_CC: 05264 case -1: /* Ignore -- just stopping indications */ 05265 break; 05266 05267 default: 05268 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass.integer); 05269 } 05270 last_subclass = f->subclass.integer; 05271 } 05272 ast_frfree(f); 05273 } 05274 } 05275 05276 /* Final fixups */ 05277 if (oh) { 05278 if (!ast_strlen_zero(oh->context)) 05279 ast_copy_string(chan->context, oh->context, sizeof(chan->context)); 05280 if (!ast_strlen_zero(oh->exten)) 05281 ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten)); 05282 if (oh->priority) 05283 chan->priority = oh->priority; 05284 } 05285 if (chan->_state == AST_STATE_UP) 05286 *outstate = AST_CONTROL_ANSWER; 05287 05288 if (res <= 0) { 05289 if ( AST_CONTROL_RINGING == last_subclass ) 05290 chan->hangupcause = AST_CAUSE_NO_ANSWER; 05291 if (!chan->cdr && (chan->cdr = ast_cdr_alloc())) 05292 ast_cdr_init(chan->cdr, chan); 05293 if (chan->cdr) { 05294 char tmp[256]; 05295 snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data); 05296 ast_cdr_setapp(chan->cdr,"Dial",tmp); 05297 ast_cdr_update(chan); 05298 ast_cdr_start(chan->cdr); 05299 ast_cdr_end(chan->cdr); 05300 /* If the cause wasn't handled properly */ 05301 if (ast_cdr_disposition(chan->cdr,chan->hangupcause)) 05302 ast_cdr_failed(chan->cdr); 05303 } 05304 ast_hangup(chan); 05305 chan = NULL; 05306 } 05307 return chan; 05308 }
int ast_activate_generator | ( | struct ast_channel * | chan, | |
struct ast_generator * | gen, | |||
void * | params | |||
) |
Activate a given generator
Definition at line 2976 of file channel.c.
References ast_generator::alloc, ast_channel_lock, ast_channel_unlock, ast_prod(), ast_settimeout(), chanlist::chan, gen, ast_channel::generator, generator_force(), ast_channel::generatordata, and ast_generator::release.
Referenced by ast_channel_start_silence_generator(), ast_linear_stream(), ast_playtones_start(), ast_tonepair_start(), channel_spy(), eivr_comm(), old_milliwatt_exec(), and transmit_audio().
02977 { 02978 int res = 0; 02979 02980 ast_channel_lock(chan); 02981 if (chan->generatordata) { 02982 if (chan->generator && chan->generator->release) 02983 chan->generator->release(chan, chan->generatordata); 02984 chan->generatordata = NULL; 02985 } 02986 if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) { 02987 res = -1; 02988 } 02989 if (!res) { 02990 ast_settimeout(chan, 50, generator_force, chan); 02991 chan->generator = gen; 02992 } 02993 ast_channel_unlock(chan); 02994 02995 ast_prod(chan); 02996 02997 return res; 02998 }
int ast_active_channels | ( | void | ) |
returns number of active/allocated channels
Definition at line 783 of file channel.c.
References ao2_container_count(), and channels.
Referenced by action_corestatus(), ast_var_channels(), ast_var_channels_table(), handle_chanlist(), handle_show_settings(), and quit_handler().
00784 { 00785 return channels ? ao2_container_count(channels) : 0; 00786 }
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 2293 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 2926 of file channel.c.
References __ast_answer(), and chanlist::chan.
Referenced by action_bridge(), agi_exec_full(), alarmreceiver_exec(), answer_trunk_chan(), app_exec(), ast_control_streamfile(), ast_pickup_call(), auth_exec(), background_detect_exec(), bridge_exec(), common_exec(), conf_exec(), count_exec(), dahdiras_exec(), dial_exec_full(), dictate_exec(), directory_exec(), disa_exec(), eivr_comm(), handle_answer(), ices_exec(), login_exec(), minivm_accmess_exec(), minivm_greet_exec(), minivm_record_exec(), old_milliwatt_exec(), park_call_exec(), park_exec_full(), parkcall_helper(), pbx_builtin_background(), pickup_do(), playback_exec(), privacy_exec(), read_exec(), readexten_exec(), receivefax_exec(), rpt_exec(), sayunixtime_exec(), send_waveform_to_channel(), sendfax_exec(), setup_privacy_args(), skel_exec(), sla_station_exec(), speech_background(), testclient_exec(), testserver_exec(), transmit(), vm_exec(), vm_execmain(), waitfor_exec(), and zapateller_exec().
02927 { 02928 return __ast_answer(chan, 0, 1); 02929 }
int ast_autoservice_ignore | ( | struct ast_channel * | chan, | |
enum ast_frame_type | ftype | |||
) |
Ignore certain frame types.
0 | success | |
-1 | channel is not in autoservice |
Definition at line 302 of file autoservice.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, asent::chan, asent::ignore_frame_types, and asent::list.
Referenced by builtin_automixmonitor(), builtin_blindtransfer(), feature_exec_app(), and play_message_in_bridged_call().
00303 { 00304 struct asent *as; 00305 int res = -1; 00306 00307 AST_LIST_LOCK(&aslist); 00308 AST_LIST_TRAVERSE(&aslist, as, list) { 00309 if (as->chan == chan) { 00310 res = 0; 00311 as->ignore_frame_types |= (1 << ftype); 00312 break; 00313 } 00314 } 00315 AST_LIST_UNLOCK(&aslist); 00316 return res; 00317 }
int ast_autoservice_start | ( | struct ast_channel * | chan | ) |
Automatically service a channel for us...
0 | success | |
-1 | failure, or the channel is already being autoserviced |
Definition at line 174 of file autoservice.c.
References as_cond, ast_calloc, ast_channel_lock, ast_channel_unlock, ast_cond_signal, AST_FLAG_END_DTMF_ONLY, AST_LIST_EMPTY, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_pthread_create_background, AST_PTHREADT_NULL, ast_set_flag, ast_test_flag, asthread, autoservice_run(), asent::chan, free, asent::list, LOG_WARNING, and asent::use_count.
Referenced by _macro_exec(), acf_curl_helper(), acf_jabberreceive_read(), acf_odbc_read(), acf_odbc_write(), ast_app_run_macro(), ast_dtmf_stream(), ast_get_enum(), ast_get_srv(), ast_get_txt(), bridge_playfile(), builtin_atxfer(), builtin_automixmonitor(), builtin_blindtransfer(), conf_play(), confbridge_exec(), dial_exec_full(), 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_in_bridged_call(), post_join_marked(), realtimefield_read(), senddtmf_exec(), shell_helper(), sla_station_exec(), smdi_msg_retrieve_read(), srv_datastore_setup(), system_exec_helper(), and trylock_read().
00175 { 00176 int res = 0; 00177 struct asent *as; 00178 00179 AST_LIST_LOCK(&aslist); 00180 AST_LIST_TRAVERSE(&aslist, as, list) { 00181 if (as->chan == chan) { 00182 as->use_count++; 00183 break; 00184 } 00185 } 00186 AST_LIST_UNLOCK(&aslist); 00187 00188 if (as) { 00189 /* Entry exists, autoservice is already handling this channel */ 00190 return 0; 00191 } 00192 00193 if (!(as = ast_calloc(1, sizeof(*as)))) 00194 return -1; 00195 00196 /* New entry created */ 00197 as->chan = chan; 00198 as->use_count = 1; 00199 00200 ast_channel_lock(chan); 00201 as->orig_end_dtmf_flag = ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY) ? 1 : 0; 00202 if (!as->orig_end_dtmf_flag) 00203 ast_set_flag(chan, AST_FLAG_END_DTMF_ONLY); 00204 ast_channel_unlock(chan); 00205 00206 AST_LIST_LOCK(&aslist); 00207 00208 if (AST_LIST_EMPTY(&aslist) && asthread != AST_PTHREADT_NULL) { 00209 ast_cond_signal(&as_cond); 00210 } 00211 00212 AST_LIST_INSERT_HEAD(&aslist, as, list); 00213 00214 if (asthread == AST_PTHREADT_NULL) { /* need start the thread */ 00215 if (ast_pthread_create_background(&asthread, NULL, autoservice_run, NULL)) { 00216 ast_log(LOG_WARNING, "Unable to create autoservice thread :(\n"); 00217 /* There will only be a single member in the list at this point, 00218 the one we just added. */ 00219 AST_LIST_REMOVE(&aslist, as, list); 00220 free(as); 00221 asthread = AST_PTHREADT_NULL; 00222 res = -1; 00223 } else { 00224 pthread_kill(asthread, SIGURG); 00225 } 00226 } 00227 00228 AST_LIST_UNLOCK(&aslist); 00229 00230 return res; 00231 }
int ast_autoservice_stop | ( | struct ast_channel * | chan | ) |
Stop servicing a channel for us...
chan |
0 | success | |
-1 | error, or the channel has been hungup |
Definition at line 233 of file autoservice.c.
References ast_channel::_softhangup, as_chan_list_state, ast_channel_lock, ast_channel_unlock, ast_clear_flag, AST_FLAG_END_DTMF_ONLY, ast_frfree, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, AST_PTHREADT_NULL, ast_queue_frame_head(), asthread, asent::chan, asent::deferred_frames, f, free, asent::ignore_frame_types, asent::list, asent::orig_end_dtmf_flag, and asent::use_count.
Referenced by _macro_exec(), acf_curl_helper(), acf_jabberreceive_read(), acf_odbc_read(), acf_odbc_write(), array(), ast_app_run_macro(), ast_dtmf_stream(), ast_get_srv(), ast_get_txt(), ast_hangup(), bridge_playfile(), builtin_atxfer(), builtin_automixmonitor(), conf_play(), confbridge_exec(), dial_exec_full(), 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_in_bridged_call(), post_join_marked(), realtimefield_read(), senddtmf_exec(), shell_helper(), sla_station_exec(), smdi_msg_retrieve_read(), srv_datastore_setup(), system_exec_helper(), and trylock_read().
00234 { 00235 int res = -1; 00236 struct asent *as, *removed = NULL; 00237 struct ast_frame *f; 00238 int chan_list_state; 00239 00240 AST_LIST_LOCK(&aslist); 00241 00242 /* Save the autoservice channel list state. We _must_ verify that the channel 00243 * list has been rebuilt before we return. Because, after we return, the channel 00244 * could get destroyed and we don't want our poor autoservice thread to step on 00245 * it after its gone! */ 00246 chan_list_state = as_chan_list_state; 00247 00248 /* Find the entry, but do not free it because it still can be in the 00249 autoservice thread array */ 00250 AST_LIST_TRAVERSE_SAFE_BEGIN(&aslist, as, list) { 00251 if (as->chan == chan) { 00252 as->use_count--; 00253 if (as->use_count < 1) { 00254 AST_LIST_REMOVE_CURRENT(list); 00255 removed = as; 00256 } 00257 break; 00258 } 00259 } 00260 AST_LIST_TRAVERSE_SAFE_END; 00261 00262 if (removed && asthread != AST_PTHREADT_NULL) { 00263 pthread_kill(asthread, SIGURG); 00264 } 00265 00266 AST_LIST_UNLOCK(&aslist); 00267 00268 if (!removed) { 00269 return 0; 00270 } 00271 00272 /* Wait while autoservice thread rebuilds its list. */ 00273 while (chan_list_state == as_chan_list_state) { 00274 usleep(1000); 00275 } 00276 00277 /* Now autoservice thread should have no references to our entry 00278 and we can safely destroy it */ 00279 00280 if (!chan->_softhangup) { 00281 res = 0; 00282 } 00283 00284 if (!as->orig_end_dtmf_flag) { 00285 ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY); 00286 } 00287 00288 ast_channel_lock(chan); 00289 while ((f = AST_LIST_REMOVE_HEAD(&as->deferred_frames, frame_list))) { 00290 if (!((1 << f->frametype) & as->ignore_frame_types)) { 00291 ast_queue_frame_head(chan, f); 00292 } 00293 ast_frfree(f); 00294 } 00295 ast_channel_unlock(chan); 00296 00297 free(as); 00298 00299 return res; 00300 }
void ast_begin_shutdown | ( | int | hangup | ) |
Initiate system shutdown -- prevents new channels from being allocated.
hangup | If "hangup" is non-zero, all existing channels will receive soft hangups |
Definition at line 773 of file channel.c.
References ao2_callback, ast_channel_softhangup_cb(), channels, OBJ_MULTIPLE, and OBJ_NODATA.
Referenced by quit_handler().
00774 { 00775 shutting_down = 1; 00776 00777 if (hangup) { 00778 ao2_callback(channels, OBJ_NODATA | OBJ_MULTIPLE, ast_channel_softhangup_cb, NULL); 00779 } 00780 }
Pick the best audio codec.
Pick the best codec Choose the best codec... Uhhh... Yah.
Okay, ulaw is used by all telephony equipment, so start with it
Unless of course, you're a silly European, so then prefer ALAW
G.722 is better then all below, but not as common as the above... so give ulaw and alaw priority
Okay, well, signed linear is easy to translate into other stuff
G.726 is standard ADPCM, in RFC3551 packing order
G.726 is standard ADPCM, in AAL2 packing order
ADPCM has great sound quality and is still pretty easy to translate
Okay, we're down to vocoders now, so pick GSM because it's small and easier to translate and sounds pretty good
iLBC is not too bad
Speex is free, but computationally more expensive than GSM
Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough to use it
G.729a is faster than 723 and slightly less expensive
Down to G.723.1 which is proprietary but at least designed for voice
Definition at line 992 of file channel.c.
References ARRAY_LEN, AST_FORMAT_ADPCM, AST_FORMAT_ALAW, AST_FORMAT_AUDIO_MASK, AST_FORMAT_G719, AST_FORMAT_G722, AST_FORMAT_G723_1, AST_FORMAT_G726, AST_FORMAT_G726_AAL2, AST_FORMAT_G729A, AST_FORMAT_GSM, AST_FORMAT_ILBC, AST_FORMAT_LPC10, AST_FORMAT_SIREN14, AST_FORMAT_SIREN7, AST_FORMAT_SLINEAR, AST_FORMAT_SLINEAR16, AST_FORMAT_SPEEX, AST_FORMAT_SPEEX16, AST_FORMAT_TESTLAW, AST_FORMAT_ULAW, ast_getformatname_multiple(), ast_log(), LOG_WARNING, and prefs.
Referenced by __oh323_new(), agent_call(), ast_codec_choose(), ast_iax2_new(), ast_speech_new(), bridge_make_compatible(), builtin_atxfer(), echo_exec(), findmeexec(), gtalk_new(), handle_open_receive_channel_ack_message(), iax2_request(), jingle_new(), local_new(), login_exec(), mgcp_new(), multicast_rtp_request(), set_format(), sip_new(), skinny_new(), skinny_set_rtp_peer(), socket_process(), start_rtp(), transmit_connect(), and unistim_new().
00993 { 00994 /* This just our opinion, expressed in code. We are asked to choose 00995 the best codec to use, given no information */ 00996 int x; 00997 static const format_t prefs[] = 00998 { 00999 /*! Okay, ulaw is used by all telephony equipment, so start with it */ 01000 AST_FORMAT_ULAW, 01001 /*! Unless of course, you're a silly European, so then prefer ALAW */ 01002 AST_FORMAT_ALAW, 01003 AST_FORMAT_G719, 01004 AST_FORMAT_SIREN14, 01005 AST_FORMAT_SIREN7, 01006 AST_FORMAT_TESTLAW, 01007 /*! G.722 is better then all below, but not as common as the above... so give ulaw and alaw priority */ 01008 AST_FORMAT_G722, 01009 /*! Okay, well, signed linear is easy to translate into other stuff */ 01010 AST_FORMAT_SLINEAR16, 01011 AST_FORMAT_SLINEAR, 01012 /*! G.726 is standard ADPCM, in RFC3551 packing order */ 01013 AST_FORMAT_G726, 01014 /*! G.726 is standard ADPCM, in AAL2 packing order */ 01015 AST_FORMAT_G726_AAL2, 01016 /*! ADPCM has great sound quality and is still pretty easy to translate */ 01017 AST_FORMAT_ADPCM, 01018 /*! Okay, we're down to vocoders now, so pick GSM because it's small and easier to 01019 translate and sounds pretty good */ 01020 AST_FORMAT_GSM, 01021 /*! iLBC is not too bad */ 01022 AST_FORMAT_ILBC, 01023 /*! Speex is free, but computationally more expensive than GSM */ 01024 AST_FORMAT_SPEEX16, 01025 AST_FORMAT_SPEEX, 01026 /*! Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough 01027 to use it */ 01028 AST_FORMAT_LPC10, 01029 /*! G.729a is faster than 723 and slightly less expensive */ 01030 AST_FORMAT_G729A, 01031 /*! Down to G.723.1 which is proprietary but at least designed for voice */ 01032 AST_FORMAT_G723_1, 01033 }; 01034 char buf[512]; 01035 01036 /* Strip out video */ 01037 fmts &= AST_FORMAT_AUDIO_MASK; 01038 01039 /* Find the first preferred codec in the format given */ 01040 for (x = 0; x < ARRAY_LEN(prefs); x++) { 01041 if (fmts & prefs[x]) 01042 return prefs[x]; 01043 } 01044 01045 ast_log(LOG_WARNING, "Don't know any of %s formats\n", ast_getformatname_multiple(buf, sizeof(buf), fmts)); 01046 01047 return 0; 01048 }
struct ast_channel* ast_bridged_channel | ( | struct ast_channel * | chan | ) |
Find bridged channel.
chan | Current channel |
Definition at line 6674 of file channel.c.
References ast_channel::_bridge, ast_channel_tech::bridged_channel, chanlist::chan, and ast_channel::tech.
Referenced by __analog_handle_event(), __analog_ss_thread(), __ast_channel_masquerade(), __ast_read(), __dahdi_exception(), _skinny_show_lines(), action_agents(), action_coreshowchannels(), agents_data_provider_get(), agents_show(), agents_show_online(), analog_attempt_transfer(), analog_exception(), analog_hangup(), analog_ss_thread(), ast_bridge_call(), ast_cel_report_event(), ast_channel_data_add_structure(), ast_channel_set_linkgroup(), ast_do_masquerade(), ast_rtp_instance_set_stats_vars(), ast_set_hangupsource(), ast_var_channel_bridge(), ast_var_channels_table(), attempt_transfer(), cb_events(), channel_spy(), check_bridge(), common_exec(), console_transfer(), create_jb(), dahdi_handle_event(), dahdi_hangup(), export_aoc_vars(), func_channel_read(), get_refer_info(), handle_chanlist(), handle_hd_hf(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_refer(), handle_showchan(), handle_soft_key_event_message(), handle_stimulus_message(), key_call(), key_dial_page(), local_attended_transfer(), local_queryoption(), mgcp_hangup(), mgcp_ss(), misdn_attempt_transfer(), mixmonitor_thread(), my_get_sigpvt_bridged_channel(), park_call_full(), schedule_delivery(), sig_pri_attempt_transfer(), sig_pri_handle_hold(), sip_hangup(), sip_set_rtp_peer(), skinny_transfer(), socket_process(), start_spying(), startmon(), TransferCallStep1(), and unistim_hangup().
06675 { 06676 struct ast_channel *bridged; 06677 bridged = chan->_bridge; 06678 if (bridged && bridged->tech->bridged_channel) 06679 bridged = bridged->tech->bridged_channel(chan, bridged); 06680 return bridged; 06681 }
int ast_call | ( | struct ast_channel * | chan, | |
char * | addr, | |||
int | timeout | |||
) |
Make a call.
chan | which channel to make the call on | |
addr | destination of the call | |
timeout | time to wait on for connect |
Definition at line 5421 of file channel.c.
References AST_CDR_FLAG_DIALED, ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, ast_set_flag, ast_test_flag, ast_channel_tech::call, ast_channel::cdr, chanlist::chan, and ast_channel::tech.
Referenced by __ast_request_and_dial(), ast_call_forward(), attempt_reconnect(), begin_dial_channel(), connect_link(), dial_exec_full(), dial_transfer(), do_forward(), do_idle_thread(), feature_request_and_dial(), findmeexec(), play_sound_file(), ring_entry(), and rpt().
05422 { 05423 /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 05424 If the remote end does not answer within the timeout, then do NOT hang up, but 05425 return anyway. */ 05426 int res = -1; 05427 /* Stop if we're a zombie or need a soft hangup */ 05428 ast_channel_lock(chan); 05429 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) { 05430 if (chan->cdr) { 05431 ast_set_flag(chan->cdr, AST_CDR_FLAG_DIALED); 05432 } 05433 if (chan->tech->call) 05434 res = chan->tech->call(chan, addr, timeout); 05435 ast_set_flag(chan, AST_FLAG_OUTGOING); 05436 } 05437 ast_channel_unlock(chan); 05438 return res; 05439 }
struct ast_channel* ast_call_forward | ( | struct ast_channel * | caller, | |
struct ast_channel * | orig, | |||
int * | timeout, | |||
format_t | format, | |||
struct outgoing_helper * | oh, | |||
int * | outstate | |||
) |
Forwards a call to a new channel specified by the original channel's call_forward str. If possible, the new forwarded channel is created and returned while the original one is terminated.
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 5070 of file channel.c.
References outgoing_helper::account, accountcode, ast_channel::accountcode, ast_call(), AST_CDR_FLAG_ORIGINATED, ast_cdr_setaccount(), ast_channel_datastore_inherit(), ast_channel_inherit_variables(), ast_channel_lock, ast_channel_set_redirecting(), ast_channel_trylock, ast_channel_unlock, ast_channel_update_redirecting(), ast_copy_flags, ast_copy_string(), ast_hangup(), ast_log(), ast_party_caller_copy(), ast_party_connected_line_copy(), ast_request(), ast_set_callerid(), ast_set_variables(), ast_string_field_set, ast_strlen_zero(), ast_channel::call_forward, ast_channel::caller, cause, ast_channel::cdr, CHANNEL_DEADLOCK_AVOIDANCE, outgoing_helper::cid_name, outgoing_helper::cid_num, ast_channel::connected, ast_channel::context, handle_cause(), LOG_NOTICE, outgoing_helper::parent_channel, pbx_builtin_getvar_helper(), ast_channel::redirecting, S_OR, type, and outgoing_helper::vars.
Referenced by __ast_request_and_dial(), and feature_request_and_dial().
05071 { 05072 char tmpchan[256]; 05073 struct ast_channel *new = NULL; 05074 struct ast_party_redirecting *apr = &orig->redirecting; 05075 char *data, *type; 05076 int cause = 0; 05077 int res; 05078 05079 /* gather data and request the new forward channel */ 05080 ast_copy_string(tmpchan, orig->call_forward, sizeof(tmpchan)); 05081 if ((data = strchr(tmpchan, '/'))) { 05082 *data++ = '\0'; 05083 type = tmpchan; 05084 } else { 05085 const char *forward_context; 05086 ast_channel_lock(orig); 05087 forward_context = pbx_builtin_getvar_helper(orig, "FORWARD_CONTEXT"); 05088 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", orig->call_forward, S_OR(forward_context, orig->context)); 05089 ast_channel_unlock(orig); 05090 data = tmpchan; 05091 type = "Local"; 05092 } 05093 if (!(new = ast_request(type, format, orig, data, &cause))) { 05094 ast_log(LOG_NOTICE, "Unable to create channel for call forward to '%s/%s' (cause = %d)\n", type, data, cause); 05095 handle_cause(cause, outstate); 05096 ast_hangup(orig); 05097 return NULL; 05098 } 05099 05100 ast_channel_set_redirecting(new, apr, NULL); 05101 05102 /* Copy/inherit important information into new channel */ 05103 if (oh) { 05104 if (oh->vars) { 05105 ast_set_variables(new, oh->vars); 05106 } 05107 if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) { 05108 ast_set_callerid(new, oh->cid_num, oh->cid_name, oh->cid_num); 05109 } 05110 if (oh->parent_channel) { 05111 ast_channel_update_redirecting(oh->parent_channel, apr, NULL); 05112 ast_channel_inherit_variables(oh->parent_channel, new); 05113 ast_channel_datastore_inherit(oh->parent_channel, new); 05114 } 05115 if (oh->account) { 05116 ast_cdr_setaccount(new, oh->account); 05117 } 05118 } else if (caller) { /* no outgoing helper so use caller if avaliable */ 05119 ast_channel_update_redirecting(caller, apr, NULL); 05120 ast_channel_inherit_variables(caller, new); 05121 ast_channel_datastore_inherit(caller, new); 05122 } 05123 05124 ast_channel_lock(orig); 05125 while (ast_channel_trylock(new)) { 05126 CHANNEL_DEADLOCK_AVOIDANCE(orig); 05127 } 05128 ast_copy_flags(new->cdr, orig->cdr, AST_CDR_FLAG_ORIGINATED); 05129 ast_string_field_set(new, accountcode, orig->accountcode); 05130 ast_party_caller_copy(&new->caller, &orig->caller); 05131 ast_party_connected_line_copy(&new->connected, &orig->connected); 05132 ast_channel_unlock(new); 05133 ast_channel_unlock(orig); 05134 05135 /* call new channel */ 05136 res = ast_call(new, data, 0); 05137 if (timeout) { 05138 *timeout = res; 05139 } 05140 if (res) { 05141 ast_log(LOG_NOTICE, "Unable to call forward to channel %s/%s\n", type, (char *)data); 05142 ast_hangup(orig); 05143 ast_hangup(new); 05144 return NULL; 05145 } 05146 ast_hangup(orig); 05147 05148 return new; 05149 }
void ast_cancel_shutdown | ( | void | ) |
Cancel a shutdown in progress.
Cancels an existing shutdown and returns to normal operation
Definition at line 789 of file channel.c.
Referenced by handle_abort_shutdown().
00790 { 00791 shutting_down = 0; 00792 }
const char* ast_cause2str | ( | int | state | ) |
Gives the string form of a given cause code.
state | cause to get the description of |
Definition at line 910 of file channel.c.
References ARRAY_LEN, and causes.
Referenced by __transmit_response(), ast_channel_data_add_structure(), ast_do_masquerade(), ast_hangup(), dial_exec_full(), findmeexec(), sip_hangup(), and transmit_request_with_auth().
00911 { 00912 int x; 00913 00914 for (x = 0; x < ARRAY_LEN(causes); x++) { 00915 if (causes[x].cause == cause) 00916 return causes[x].desc; 00917 } 00918 00919 return "Unknown"; 00920 }
void ast_change_name | ( | struct ast_channel * | chan, | |
const char * | newname | |||
) |
Change channel name.
chan | the channel to change the name of | |
newname | the name to change to |
Definition at line 5856 of file channel.c.
References __ast_change_name_nolink(), ao2_link, ao2_unlink, ast_channel_lock, ast_channel_unlock, chanlist::chan, and channels.
Referenced by update_name().
05857 { 05858 /* We must re-link, as the hash value will change here. */ 05859 ao2_unlink(channels, chan); 05860 ast_channel_lock(chan); 05861 __ast_change_name_nolink(chan, newname); 05862 ast_channel_unlock(chan); 05863 ao2_link(channels, chan); 05864 }
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 7017 of file channel.c.
References ast_channel::_bridge, ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_RETRY, ast_channel_make_compatible(), ast_check_hangup(), ast_check_hangup_locked(), ast_clear_flag, AST_CONTROL_SRCUPDATE, ast_debug, AST_FEATURE_PLAY_WARNING, AST_FEATURE_WARNING_ACTIVE, AST_FLAG_END_DTMF_ONLY, AST_FLAG_NBRIDGE, AST_FLAG_ZOMBIE, ast_generic_bridge(), ast_indicate(), ast_log(), ast_manager_event_multichan, ast_samp2tv(), ast_set_flag, ast_set_owners_and_peers(), AST_SOFTHANGUP_UNBRIDGE, ast_test_flag, ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), ast_verb, ast_channel::audiohooks, ast_channel_tech::bridge, bridge_play_sounds(), bridge_playfile(), ast_channel::caller, config, EVENT_FLAG_CALL, ast_channel::generator, ast_party_caller::id, LOG_WARNING, manager_bridge_event(), ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::name, ast_channel::nativeformats, ast_party_id::number, ast_channel::readformat, S_COR, ast_channel_tech::send_digit_begin, ast_party_number::str, ast_channel::tech, ast_channel::uniqueid, update_bridge_vars(), ast_party_number::valid, and ast_channel::writeformat.
Referenced by ast_bridge_call().
07019 { 07020 struct ast_channel *chans[2] = { c0, c1 }; 07021 enum ast_bridge_result res = AST_BRIDGE_COMPLETE; 07022 format_t o0nativeformats; 07023 format_t o1nativeformats; 07024 long time_left_ms=0; 07025 char caller_warning = 0; 07026 char callee_warning = 0; 07027 07028 if (c0->_bridge) { 07029 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 07030 c0->name, c0->_bridge->name); 07031 return -1; 07032 } 07033 if (c1->_bridge) { 07034 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 07035 c1->name, c1->_bridge->name); 07036 return -1; 07037 } 07038 07039 /* Stop if we're a zombie or need a soft hangup */ 07040 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 07041 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) 07042 return -1; 07043 07044 *fo = NULL; 07045 07046 if (ast_tvzero(config->start_time)) { 07047 config->start_time = ast_tvnow(); 07048 if (config->start_sound) { 07049 if (caller_warning) { 07050 bridge_playfile(c0, c1, config->start_sound, config->timelimit / 1000); 07051 } 07052 if (callee_warning) { 07053 bridge_playfile(c1, c0, config->start_sound, config->timelimit / 1000); 07054 } 07055 } 07056 } 07057 07058 /* Keep track of bridge */ 07059 c0->_bridge = c1; 07060 c1->_bridge = c0; 07061 07062 ast_set_owners_and_peers(c0, c1); 07063 07064 o0nativeformats = c0->nativeformats; 07065 o1nativeformats = c1->nativeformats; 07066 07067 if (config->feature_timer && !ast_tvzero(config->nexteventts)) { 07068 config->nexteventts = ast_tvadd(config->feature_start_time, ast_samp2tv(config->feature_timer, 1000)); 07069 } else if (config->timelimit) { 07070 time_left_ms = config->timelimit - ast_tvdiff_ms(ast_tvnow(), config->start_time); 07071 caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING); 07072 callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING); 07073 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 07074 if ((caller_warning || callee_warning) && config->play_warning) { 07075 long next_warn = config->play_warning; 07076 if (time_left_ms < config->play_warning) { 07077 /* At least one warning was played, which means we are returning after feature */ 07078 long warns_passed = (config->play_warning - time_left_ms) / config->warning_freq; 07079 /* It is 'warns_passed * warning_freq' NOT '(warns_passed + 1) * warning_freq', 07080 because nexteventts will be updated once again in the 'if (!to)' block */ 07081 next_warn = config->play_warning - warns_passed * config->warning_freq; 07082 } 07083 config->nexteventts = ast_tvsub(config->nexteventts, ast_samp2tv(next_warn, 1000)); 07084 } 07085 } else { 07086 config->nexteventts.tv_sec = 0; 07087 config->nexteventts.tv_usec = 0; 07088 } 07089 07090 if (!c0->tech->send_digit_begin) 07091 ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY); 07092 if (!c1->tech->send_digit_begin) 07093 ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY); 07094 manager_bridge_event(1, 1, c0, c1); 07095 07096 /* Before we enter in and bridge these two together tell them both the source of audio has changed */ 07097 ast_indicate(c0, AST_CONTROL_SRCUPDATE); 07098 ast_indicate(c1, AST_CONTROL_SRCUPDATE); 07099 07100 for (/* ever */;;) { 07101 struct timeval now = { 0, }; 07102 int to; 07103 07104 to = -1; 07105 07106 if (!ast_tvzero(config->nexteventts)) { 07107 now = ast_tvnow(); 07108 to = ast_tvdiff_ms(config->nexteventts, now); 07109 if (to <= 0) { 07110 if (!config->timelimit) { 07111 res = AST_BRIDGE_COMPLETE; 07112 break; 07113 } 07114 to = 0; 07115 } 07116 } 07117 07118 if (config->timelimit) { 07119 time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time); 07120 if (time_left_ms < to) 07121 to = time_left_ms; 07122 07123 if (time_left_ms <= 0) { 07124 if (caller_warning && config->end_sound) 07125 bridge_playfile(c0, c1, config->end_sound, 0); 07126 if (callee_warning && config->end_sound) 07127 bridge_playfile(c1, c0, config->end_sound, 0); 07128 *fo = NULL; 07129 res = 0; 07130 break; 07131 } 07132 07133 if (!to) { 07134 if (time_left_ms >= 5000 && config->warning_sound && config->play_warning && ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) { 07135 int t = (time_left_ms + 500) / 1000; /* round to nearest second */ 07136 if (caller_warning) 07137 bridge_playfile(c0, c1, config->warning_sound, t); 07138 if (callee_warning) 07139 bridge_playfile(c1, c0, config->warning_sound, t); 07140 } 07141 07142 if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000))) { 07143 config->nexteventts = ast_tvadd(config->nexteventts, ast_samp2tv(config->warning_freq, 1000)); 07144 } else { 07145 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 07146 } 07147 } 07148 ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE); 07149 } 07150 07151 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */ 07152 if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) { 07153 c0->_softhangup &= ~AST_SOFTHANGUP_UNBRIDGE; 07154 } 07155 if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) { 07156 c1->_softhangup &= ~AST_SOFTHANGUP_UNBRIDGE; 07157 } 07158 c0->_bridge = c1; 07159 c1->_bridge = c0; 07160 ast_debug(1, "Unbridge signal received. Ending native bridge.\n"); 07161 continue; 07162 } 07163 07164 /* Stop if we're a zombie or need a soft hangup */ 07165 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 07166 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) { 07167 *fo = NULL; 07168 res = 0; 07169 ast_debug(1, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n", 07170 c0->name, c1->name, 07171 ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No", 07172 ast_check_hangup(c0) ? "Yes" : "No", 07173 ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No", 07174 ast_check_hangup(c1) ? "Yes" : "No"); 07175 break; 07176 } 07177 07178 update_bridge_vars(c0, c1); 07179 07180 bridge_play_sounds(c0, c1); 07181 07182 if (c0->tech->bridge && 07183 /* if < 1 ms remains use generic bridging for accurate timing */ 07184 (!config->timelimit || to > 1000 || to == 0) && 07185 (c0->tech->bridge == c1->tech->bridge) && 07186 !c0->monitor && !c1->monitor && 07187 !c0->audiohooks && !c1->audiohooks && 07188 !c0->masq && !c0->masqr && !c1->masq && !c1->masqr) { 07189 int timeoutms = to - 1000 > 0 ? to - 1000 : to; 07190 /* Looks like they share a bridge method and nothing else is in the way */ 07191 ast_set_flag(c0, AST_FLAG_NBRIDGE); 07192 ast_set_flag(c1, AST_FLAG_NBRIDGE); 07193 if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, timeoutms)) == AST_BRIDGE_COMPLETE) { 07194 ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans, 07195 "Channel1: %s\r\n" 07196 "Channel2: %s\r\n" 07197 "Uniqueid1: %s\r\n" 07198 "Uniqueid2: %s\r\n" 07199 "CallerID1: %s\r\n" 07200 "CallerID2: %s\r\n", 07201 c0->name, c1->name, 07202 c0->uniqueid, c1->uniqueid, 07203 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"), 07204 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>")); 07205 07206 ast_debug(1, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name); 07207 07208 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 07209 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 07210 07211 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */ 07212 continue; 07213 } 07214 07215 c0->_bridge = NULL; 07216 c1->_bridge = NULL; 07217 return res; 07218 } else { 07219 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 07220 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 07221 } 07222 switch (res) { 07223 case AST_BRIDGE_RETRY: 07224 if (config->play_warning) { 07225 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE); 07226 } 07227 continue; 07228 default: 07229 ast_verb(3, "Native bridging %s and %s ended\n", c0->name, c1->name); 07230 /* fallthrough */ 07231 case AST_BRIDGE_FAILED_NOWARN: 07232 break; 07233 } 07234 } 07235 07236 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) || 07237 (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) && 07238 !(c0->generator || c1->generator)) { 07239 if (ast_channel_make_compatible(c0, c1)) { 07240 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name); 07241 manager_bridge_event(0, 1, c0, c1); 07242 return AST_BRIDGE_FAILED; 07243 } 07244 o0nativeformats = c0->nativeformats; 07245 o1nativeformats = c1->nativeformats; 07246 } 07247 07248 update_bridge_vars(c0, c1); 07249 07250 res = ast_generic_bridge(c0, c1, config, fo, rc); 07251 if (res != AST_BRIDGE_RETRY) { 07252 break; 07253 } else if (config->feature_timer) { 07254 /* feature timer expired but has not been updated, sending to ast_bridge_call to do so */ 07255 break; 07256 } 07257 } 07258 07259 ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY); 07260 ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY); 07261 07262 /* Now that we have broken the bridge the source will change yet again */ 07263 ast_indicate(c0, AST_CONTROL_SRCUPDATE); 07264 ast_indicate(c1, AST_CONTROL_SRCUPDATE); 07265 07266 c0->_bridge = NULL; 07267 c1->_bridge = NULL; 07268 07269 ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans, 07270 "Channel1: %s\r\n" 07271 "Channel2: %s\r\n" 07272 "Uniqueid1: %s\r\n" 07273 "Uniqueid2: %s\r\n" 07274 "CallerID1: %s\r\n" 07275 "CallerID2: %s\r\n", 07276 c0->name, c1->name, 07277 c0->uniqueid, c1->uniqueid, 07278 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"), 07279 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>")); 07280 ast_debug(1, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name); 07281 07282 return res; 07283 }
struct ast_channel* ast_channel_callback | ( | ao2_callback_data_fn * | cb_fn, | |
void * | arg, | |||
void * | data, | |||
int | ao2_flags | |||
) |
Call a function with every active channel.
This function executes a callback one time for each active channel on the system. The channel is provided as an argument to the function.
Definition at line 1544 of file channel.c.
References ao2_callback_data, and channels.
Referenced by ast_cel_check_retire_linkedid(), ast_pickup_call(), handle_core_set_debug_channel(), my_ast_get_channel_by_name_locked(), pickup_by_mark(), pickup_by_part(), and state_notify_build_xml().
01546 { 01547 return ao2_callback_data(channels, ao2_flags, cb_fn, arg, data); 01548 }
int ast_channel_cc_params_init | ( | struct ast_channel * | chan, | |
const struct ast_cc_config_params * | base_params | |||
) |
Set up datastore with CCSS parameters for a channel.
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 9162 of file channel.c.
References ast_cc_config_params_destroy(), ast_cc_config_params_init, ast_cc_copy_config_params(), ast_channel_datastore_add(), ast_datastore_alloc, cc_channel_datastore_info, and ast_datastore::data.
Referenced by ast_channel_get_cc_config_params(), dahdi_new(), local_call(), local_request(), and sip_new().
09164 { 09165 struct ast_cc_config_params *cc_params; 09166 struct ast_datastore *cc_datastore; 09167 09168 if (!(cc_params = ast_cc_config_params_init())) { 09169 return -1; 09170 } 09171 09172 if (!(cc_datastore = ast_datastore_alloc(&cc_channel_datastore_info, NULL))) { 09173 ast_cc_config_params_destroy(cc_params); 09174 return -1; 09175 } 09176 09177 if (base_params) { 09178 ast_cc_copy_config_params(cc_params, base_params); 09179 } 09180 cc_datastore->data = cc_params; 09181 ast_channel_datastore_add(chan, cc_datastore); 09182 return 0; 09183 }
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 830 of file channel.c.
References ast_channel_cmpwhentohangup_tv(), and chanlist::chan.
00831 { 00832 struct timeval when = { offset, }; 00833 return ast_channel_cmpwhentohangup_tv(chan, when); 00834 }
int ast_channel_cmpwhentohangup_tv | ( | struct ast_channel * | chan, | |
struct timeval | offset | |||
) |
Compare a offset with the settings of when to hang a channel up.
chan | channel on which to check for hangup | |
offset | offset in seconds and microseconds from current time |
Definition at line 815 of file channel.c.
References ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), chanlist::chan, and ast_channel::whentohangup.
Referenced by ast_channel_cmpwhentohangup().
00816 { 00817 struct timeval whentohangup; 00818 00819 if (ast_tvzero(chan->whentohangup)) 00820 return ast_tvzero(offset) ? 0 : -1; 00821 00822 if (ast_tvzero(offset)) 00823 return 1; 00824 00825 whentohangup = ast_tvadd(offset, ast_tvnow()); 00826 00827 return ast_tvdiff_ms(whentohangup, chan->whentohangup); 00828 }
int ast_channel_connected_line_macro | ( | struct ast_channel * | autoservice_chan, | |
struct ast_channel * | macro_chan, | |||
const void * | connected_info, | |||
int | caller, | |||
int | frame | |||
) |
Run a connected line interception macro and update a channel's connected line information.
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 9060 of file channel.c.
References ast_app_run_macro(), ast_channel_lock, ast_channel_unlock, ast_channel_update_connected_line(), ast_connected_line_parse_data(), ast_party_connected_line_copy(), ast_strdupa, ast_strlen_zero(), ast_channel::connected, connected, ast_frame::data, ast_frame::datalen, pbx_builtin_getvar_helper(), ast_frame::ptr, and S_OR.
Referenced by __ast_read(), ast_bridge_call(), ast_pickup_call(), atxfer_fail_cleanup(), builtin_atxfer(), builtin_blindtransfer(), feature_request_and_dial(), handle_frame(), pickup_do(), remote_bridge_loop(), and wait_for_answer().
09061 { 09062 const char *macro; 09063 const char *macro_args; 09064 int retval; 09065 09066 ast_channel_lock(macro_chan); 09067 macro = pbx_builtin_getvar_helper(macro_chan, is_caller 09068 ? "CONNECTED_LINE_CALLER_SEND_MACRO" : "CONNECTED_LINE_CALLEE_SEND_MACRO"); 09069 macro = ast_strdupa(S_OR(macro, "")); 09070 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller 09071 ? "CONNECTED_LINE_CALLER_SEND_MACRO_ARGS" : "CONNECTED_LINE_CALLEE_SEND_MACRO_ARGS"); 09072 macro_args = ast_strdupa(S_OR(macro_args, "")); 09073 09074 if (ast_strlen_zero(macro)) { 09075 ast_channel_unlock(macro_chan); 09076 return -1; 09077 } 09078 09079 if (is_frame) { 09080 const struct ast_frame *frame = connected_info; 09081 09082 ast_connected_line_parse_data(frame->data.ptr, frame->datalen, ¯o_chan->connected); 09083 } else { 09084 const struct ast_party_connected_line *connected = connected_info; 09085 09086 ast_party_connected_line_copy(¯o_chan->connected, connected); 09087 } 09088 ast_channel_unlock(macro_chan); 09089 09090 if (!(retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args))) { 09091 ast_channel_lock(macro_chan); 09092 ast_channel_update_connected_line(macro_chan, ¯o_chan->connected, NULL); 09093 ast_channel_unlock(macro_chan); 09094 } 09095 09096 return retval; 09097 }
int ast_channel_data_add_structure | ( | struct ast_data * | tree, | |
struct ast_channel * | chan, | |||
int | add_bridged | |||
) |
Insert into an astdata tree, the channel structure.
[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 343 of file channel.c.
References ast_channel::_softhangup, ast_channel::_state, ast_channel::amaflags, ast_bridged_channel(), ast_cause2str(), ast_cdr_data_add_structure(), ast_cdr_flags2str(), ast_channel_data_add_structure(), ast_data_add_bool(), ast_data_add_codecs(), ast_data_add_int(), ast_data_add_node(), ast_data_add_str(), ast_data_add_structure, ast_data_add_uint(), AST_SOFTHANGUP_APPUNLOAD, AST_SOFTHANGUP_ASYNCGOTO, AST_SOFTHANGUP_DEV, AST_SOFTHANGUP_EXPLICIT, AST_SOFTHANGUP_SHUTDOWN, AST_SOFTHANGUP_TIMEOUT, AST_SOFTHANGUP_UNBRIDGE, ast_state2str(), ast_tone_zone_data_add_structure(), ast_transfercapability2str(), ast_channel::cdr, chanlist::chan, channel_data_add_flags(), ast_channel::hangupcause, ast_channel::nativeformats, ast_channel::oldwriteformat, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::transfercapability, ast_channel::whentohangup, ast_channel::writeformat, and ast_channel::zone.
Referenced by agents_data_provider_get(), ast_channel_data_add_structure(), data_channels_provider_handler(), queues_data_provider_get_helper(), and user_add_provider_cb().
00345 { 00346 struct ast_channel *bc; 00347 struct ast_data *data_bridged; 00348 struct ast_data *data_cdr; 00349 struct ast_data *data_flags; 00350 struct ast_data *data_zones; 00351 struct ast_data *enum_node; 00352 struct ast_data *data_softhangup; 00353 #if 0 /* XXX AstData: ast_callerid no longer exists. (Equivalent code not readily apparent.) */ 00354 struct ast_data *data_callerid; 00355 char value_str[100]; 00356 #endif 00357 00358 if (!tree) { 00359 return -1; 00360 } 00361 00362 ast_data_add_structure(ast_channel, tree, chan); 00363 00364 if (add_bridged) { 00365 bc = ast_bridged_channel(chan); 00366 if (bc) { 00367 data_bridged = ast_data_add_node(tree, "bridged"); 00368 if (!data_bridged) { 00369 return -1; 00370 } 00371 ast_channel_data_add_structure(data_bridged, bc, 0); 00372 } 00373 } 00374 00375 ast_data_add_codecs(tree, "oldwriteformat", chan->oldwriteformat); 00376 ast_data_add_codecs(tree, "nativeformats", chan->nativeformats); 00377 ast_data_add_codecs(tree, "readformat", chan->readformat); 00378 ast_data_add_codecs(tree, "writeformat", chan->writeformat); 00379 ast_data_add_codecs(tree, "rawreadformat", chan->rawreadformat); 00380 ast_data_add_codecs(tree, "rawwriteformat", chan->rawwriteformat); 00381 00382 /* state */ 00383 enum_node = ast_data_add_node(tree, "state"); 00384 if (!enum_node) { 00385 return -1; 00386 } 00387 ast_data_add_str(enum_node, "text", ast_state2str(chan->_state)); 00388 ast_data_add_int(enum_node, "value", chan->_state); 00389 00390 /* hangupcause */ 00391 enum_node = ast_data_add_node(tree, "hangupcause"); 00392 if (!enum_node) { 00393 return -1; 00394 } 00395 ast_data_add_str(enum_node, "text", ast_cause2str(chan->hangupcause)); 00396 ast_data_add_int(enum_node, "value", chan->hangupcause); 00397 00398 /* amaflags */ 00399 enum_node = ast_data_add_node(tree, "amaflags"); 00400 if (!enum_node) { 00401 return -1; 00402 } 00403 ast_data_add_str(enum_node, "text", ast_cdr_flags2str(chan->amaflags)); 00404 ast_data_add_int(enum_node, "value", chan->amaflags); 00405 00406 /* transfercapability */ 00407 enum_node = ast_data_add_node(tree, "transfercapability"); 00408 if (!enum_node) { 00409 return -1; 00410 } 00411 ast_data_add_str(enum_node, "text", ast_transfercapability2str(chan->transfercapability)); 00412 ast_data_add_int(enum_node, "value", chan->transfercapability); 00413 00414 /* _softphangup */ 00415 data_softhangup = ast_data_add_node(tree, "softhangup"); 00416 if (!data_softhangup) { 00417 return -1; 00418 } 00419 ast_data_add_bool(data_softhangup, "dev", chan->_softhangup & AST_SOFTHANGUP_DEV); 00420 ast_data_add_bool(data_softhangup, "asyncgoto", chan->_softhangup & AST_SOFTHANGUP_ASYNCGOTO); 00421 ast_data_add_bool(data_softhangup, "shutdown", chan->_softhangup & AST_SOFTHANGUP_SHUTDOWN); 00422 ast_data_add_bool(data_softhangup, "timeout", chan->_softhangup & AST_SOFTHANGUP_TIMEOUT); 00423 ast_data_add_bool(data_softhangup, "appunload", chan->_softhangup & AST_SOFTHANGUP_APPUNLOAD); 00424 ast_data_add_bool(data_softhangup, "explicit", chan->_softhangup & AST_SOFTHANGUP_EXPLICIT); 00425 ast_data_add_bool(data_softhangup, "unbridge", chan->_softhangup & AST_SOFTHANGUP_UNBRIDGE); 00426 00427 /* channel flags */ 00428 data_flags = ast_data_add_node(tree, "flags"); 00429 if (!data_flags) { 00430 return -1; 00431 } 00432 channel_data_add_flags(data_flags, chan); 00433 00434 ast_data_add_uint(tree, "timetohangup", chan->whentohangup.tv_sec); 00435 00436 #if 0 /* XXX AstData: ast_callerid no longer exists. (Equivalent code not readily apparent.) */ 00437 /* callerid */ 00438 data_callerid = ast_data_add_node(tree, "callerid"); 00439 if (!data_callerid) { 00440 return -1; 00441 } 00442 ast_data_add_structure(ast_callerid, data_callerid, &(chan->cid)); 00443 /* insert the callerid ton */ 00444 enum_node = ast_data_add_node(data_callerid, "cid_ton"); 00445 if (!enum_node) { 00446 return -1; 00447 } 00448 ast_data_add_int(enum_node, "value", chan->cid.cid_ton); 00449 snprintf(value_str, sizeof(value_str), "TON: %s/Plan: %s", 00450 party_number_ton2str(chan->cid.cid_ton), 00451 party_number_plan2str(chan->cid.cid_ton)); 00452 ast_data_add_str(enum_node, "text", value_str); 00453 #endif 00454 00455 /* tone zone */ 00456 if (chan->zone) { 00457 data_zones = ast_data_add_node(tree, "zone"); 00458 if (!data_zones) { 00459 return -1; 00460 } 00461 ast_tone_zone_data_add_structure(data_zones, chan->zone); 00462 } 00463 00464 /* insert cdr */ 00465 data_cdr = ast_data_add_node(tree, "cdr"); 00466 if (!data_cdr) { 00467 return -1; 00468 } 00469 00470 ast_cdr_data_add_structure(data_cdr, chan->cdr, 1); 00471 00472 return 0; 00473 }
int ast_channel_data_cmp_structure | ( | const struct ast_data_search * | tree, | |
struct ast_channel * | chan, | |||
const char * | structure_name | |||
) |
Compare to channel structures using the data api.
[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 475 of file channel.c.
References ast_data_search_cmp_structure, and chanlist::chan.
00477 { 00478 return ast_data_search_cmp_structure(tree, ast_channel, chan, structure_name); 00479 }
int ast_channel_datastore_add | ( | struct ast_channel * | chan, | |
struct ast_datastore * | datastore | |||
) |
Add a datastore to a channel.
0 | success | |
non-zero | failure |
Definition at line 2484 of file channel.c.
References AST_LIST_INSERT_HEAD, chanlist::chan, ast_channel::datastores, and ast_datastore::entry.
Referenced by __ast_channel_masquerade(), _macro_exec(), acf_curlopt_write(), acf_iaxvar_write(), add_features_datastores(), add_to_agi(), apply_plc(), ast_channel_cc_params_init(), ast_iax2_new(), ast_setup_cc_recall_datastore(), audiohook_volume_get(), authenticate_reply(), calendar_query_exec(), cc_interfaces_datastore_init(), dial_exec_full(), do_notify(), dundi_query_read(), enable_jack_hook(), enum_query_read(), find_or_create_details(), find_transaction(), frame_trace_helper(), func_channel_write_real(), get_lock(), gosub_exec(), lua_get_state(), mute_add_audiohook(), pbx_builtin_raise_exception(), pitchshift_helper(), setup_inheritance_datastore(), setup_mixmonitor_ds(), setup_transfer_datastore(), shared_write(), smdi_msg_retrieve_read(), socket_process(), speech_create(), speex_write(), srv_datastore_setup(), and volume_write().
02485 { 02486 int res = 0; 02487 02488 AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry); 02489 02490 return res; 02491 }
struct ast_datastore* attribute_malloc ast_channel_datastore_alloc | ( | const struct ast_datastore_info * | info, | |
const char * | uid | |||
) |
Create a channel data store object.
Definition at line 2457 of file channel.c.
References ast_datastore_alloc, and ast_datastore::info.
02458 { 02459 return ast_datastore_alloc(info, uid); 02460 }
struct ast_datastore* ast_channel_datastore_find | ( | struct ast_channel * | chan, | |
const struct ast_datastore_info * | info, | |||
const char * | uid | |||
) |
Find a datastore on a channel.
The datastore returned from this function must not be used if the reference to the channel is released.
pointer | to the datastore if found | |
NULL | if not found |
Definition at line 2498 of file channel.c.
References AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, chanlist::chan, ast_channel::datastores, ast_datastore::entry, ast_datastore::info, and ast_datastore::uid.
Referenced by _macro_exec(), acf_curl_helper(), acf_curlopt_helper(), acf_curlopt_write(), acf_exception_read(), acf_fetch(), acf_iaxvar_read(), acf_iaxvar_write(), add_agi_cmd(), add_features_datastores(), add_to_agi(), apply_plc(), ast_cc_agent_set_interfaces_chanvar(), ast_cc_call_init(), ast_cc_completed(), ast_cc_extension_monitor_add_dialstring(), ast_cc_get_current_core_id(), ast_cc_is_recall(), ast_cc_offer(), ast_channel_get_cc_config_params(), ast_do_masquerade(), ast_handle_cc_control_frame(), ast_ignore_cc(), ast_odbc_retrieve_transaction_obj(), ast_set_cc_interfaces_chanvar(), attended_transfer_occurred(), audiohook_volume_callback(), audiohook_volume_get(), builtin_atxfer(), calendar_event_read(), calendar_query_exec(), calendar_query_result_exec(), cc_build_payload(), dial_exec_full(), disable_jack_hook(), dundi_result_read(), enable_jack_hook(), enum_result_read(), exec_odbcfinish(), find_details(), find_speech(), find_transaction(), frame_trace_helper(), func_channel_read(), func_channel_write_real(), func_inheritance_write(), func_mute_write(), get_agi_cmd(), get_lock(), gosub_exec(), handle_gosub(), iax2_call(), jack_hook_callback(), local_read(), local_write(), lock_fixup(), lua_get_state(), manage_parkinglot(), manager_mutestream(), mark_transaction_active(), mute_callback(), park_exec_full(), pbx_builtin_raise_exception(), pitchshift_cb(), pitchshift_helper(), pop_exec(), queue_transfer_fixup(), release_transaction(), return_exec(), set_security_requirements(), shared_read(), shared_write(), smdi_msg_read(), speech_background(), speech_destroy(), speex_callback(), speex_read(), speex_write(), srv_query_read(), srv_result_read(), stop_mixmonitor_exec(), try_calling(), unlock_read(), volume_callback(), and volume_write().
02499 { 02500 struct ast_datastore *datastore = NULL; 02501 02502 if (info == NULL) 02503 return NULL; 02504 02505 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore, entry) { 02506 if (datastore->info != info) { 02507 continue; 02508 } 02509 02510 if (uid == NULL) { 02511 /* matched by type only */ 02512 break; 02513 } 02514 02515 if ((datastore->uid != NULL) && !strcasecmp(uid, datastore->uid)) { 02516 /* Matched by type AND uid */ 02517 break; 02518 } 02519 } 02520 AST_LIST_TRAVERSE_SAFE_END; 02521 02522 return datastore; 02523 }
int ast_channel_datastore_free | ( | struct ast_datastore * | datastore | ) |
Free a channel data store object.
Definition at line 2462 of file channel.c.
References ast_datastore_free().
02463 { 02464 return ast_datastore_free(datastore); 02465 }
int ast_channel_datastore_inherit | ( | struct ast_channel * | from, | |
struct ast_channel * | to | |||
) |
Inherit datastores from a parent to a child.
Definition at line 2467 of file channel.c.
References ast_datastore_alloc, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_datastore::data, DATASTORE_INHERIT_FOREVER, ast_channel::datastores, ast_datastore_info::duplicate, ast_datastore::entry, ast_datastore::info, ast_datastore::inheritance, and ast_datastore::uid.
Referenced by __ast_request_and_dial(), ast_call_forward(), begin_dial_channel(), dial_exec_full(), do_forward(), findmeexec(), local_call(), and ring_entry().
02468 { 02469 struct ast_datastore *datastore = NULL, *datastore2; 02470 02471 AST_LIST_TRAVERSE(&from->datastores, datastore, entry) { 02472 if (datastore->inheritance > 0) { 02473 datastore2 = ast_datastore_alloc(datastore->info, datastore->uid); 02474 if (datastore2) { 02475 datastore2->data = datastore->info->duplicate ? datastore->info->duplicate(datastore->data) : NULL; 02476 datastore2->inheritance = datastore->inheritance == DATASTORE_INHERIT_FOREVER ? DATASTORE_INHERIT_FOREVER : datastore->inheritance - 1; 02477 AST_LIST_INSERT_TAIL(&to->datastores, datastore2, entry); 02478 } 02479 } 02480 } 02481 return 0; 02482 }
int ast_channel_datastore_remove | ( | struct ast_channel * | chan, | |
struct ast_datastore * | datastore | |||
) |
Remove a datastore from a channel.
0 | success | |
non-zero | failure |
Definition at line 2493 of file channel.c.
References AST_LIST_REMOVE, chanlist::chan, ast_channel::datastores, and ast_datastore::entry.
Referenced by acf_fetch(), adjust_frame_for_plc(), ast_do_masquerade(), dial_exec_full(), disable_jack_hook(), exec_odbcfinish(), frame_trace_helper(), lua_get_state(), queue_transfer_fixup(), speech_background(), speech_destroy(), speex_write(), srv_query_read(), and stop_mixmonitor_exec().
02494 { 02495 return AST_LIST_REMOVE(&chan->datastores, datastore, entry) ? 0 : -1; 02496 }
int ast_channel_defer_dtmf | ( | struct ast_channel * | chan | ) |
Defers DTMF so that you only read things like hangups and audio.
Definition at line 1526 of file channel.c.
References AST_FLAG_DEFER_DTMF, ast_set_flag, ast_test_flag, and chanlist::chan.
Referenced by find_cache().
01527 { 01528 int pre = 0; 01529 01530 if (chan) { 01531 pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF); 01532 ast_set_flag(chan, AST_FLAG_DEFER_DTMF); 01533 } 01534 return pre; 01535 }
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 6917 of file channel.c.
References ast_channel_tech::early_bridge, and ast_channel::tech.
Referenced by dial_exec_full().
06918 { 06919 /* Make sure we can early bridge, if not error out */ 06920 if (!c0->tech->early_bridge || (c1 && (!c1->tech->early_bridge || c0->tech->early_bridge != c1->tech->early_bridge))) 06921 return -1; 06922 06923 return c0->tech->early_bridge(c0, c1); 06924 }
struct ast_channel* ast_channel_get_by_exten | ( | const char * | exten, | |
const char * | context | |||
) |
Find a channel by extension and context.
a | channel that is at the specified extension and context | |
NULL | if no channel was found |
Definition at line 1723 of file channel.c.
References ast_channel_get_full().
01724 { 01725 return ast_channel_get_full(NULL, 0, exten, context); 01726 }
struct ast_channel* ast_channel_get_by_name | ( | const char * | name | ) |
Find a channel by name.
a | channel with the name specified by the argument | |
NULL | if no channel was found |
Definition at line 1713 of file channel.c.
References ast_channel_get_full().
Referenced by action_add_agi_cmd(), action_aocmessage(), action_atxfer(), action_getvar(), action_hangup(), action_redirect(), action_sendtext(), action_setvar(), action_status(), action_timeout(), ast_async_goto_by_name(), ast_bridge_call(), asyncgoto_exec(), change_monitor_action(), do_pause_or_unpause(), func_mchan_read(), func_mchan_write(), handle_channelstatus(), handle_cli_agi_add_cmd(), handle_core_set_debug_channel(), handle_getvariablefull(), handle_hangup(), handle_redirect(), handle_set_chanvar(), handle_show_chanvar(), handle_showchan(), handle_softhangup(), import_helper(), manager_mute_mixmonitor(), manager_mutestream(), manager_optimize_away(), manager_park(), manager_play_dtmf(), park_call_full(), pbx_builtin_importvar(), senddtmf_exec(), shared_read(), shared_write(), start_monitor_action(), and stop_monitor_action().
01714 { 01715 return ast_channel_get_full(name, 0, NULL, NULL); 01716 }
struct ast_channel* ast_channel_get_by_name_prefix | ( | const char * | name, | |
size_t | name_len | |||
) |
Find a channel by a name prefix.
a | channel with the name prefix specified by the arguments | |
NULL | if no channel was found |
Definition at line 1718 of file channel.c.
References ast_channel_get_full().
Referenced by action_aocmessage(), action_bridge(), ast_parse_device_state(), bridge_exec(), cc_generic_agent_stop_ringing(), common_exec(), handle_cli_mixmonitor(), shared_read(), and shared_write().
01719 { 01720 return ast_channel_get_full(name, name_len, NULL, NULL); 01721 }
int ast_channel_get_cc_agent_type | ( | struct ast_channel * | chan, | |
char * | agent_type, | |||
size_t | size | |||
) |
Find the appropriate CC agent type to use given a channel.
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 9224 of file channel.c.
References ast_channel_queryoption(), ast_copy_string(), AST_OPTION_CC_AGENT_TYPE, and ast_channel::name.
Referenced by find_agent_callbacks().
09225 { 09226 int len = size; 09227 char *slash; 09228 09229 if (!ast_channel_queryoption(chan, AST_OPTION_CC_AGENT_TYPE, agent_type, &len, 0)) { 09230 return 0; 09231 } 09232 09233 ast_copy_string(agent_type, chan->name, size); 09234 if ((slash = strchr(agent_type, '/'))) { 09235 *slash = '\0'; 09236 } 09237 return 0; 09238 }
struct ast_cc_config_params* ast_channel_get_cc_config_params | ( | struct ast_channel * | chan | ) |
Get the CCSS parameters from a channel.
chan | Channel to retrieve parameters from |
NULL | Failure | |
non-NULL | The parameters desired |
Definition at line 9185 of file channel.c.
References ast_assert, ast_channel_cc_params_init(), ast_channel_datastore_find(), cc_channel_datastore_info, and ast_datastore::data.
Referenced by acf_cc_read(), acf_cc_write(), analog_call(), ast_cc_call_failed(), ast_cc_call_init(), ast_queue_cc_frame(), cc_agent_init(), cc_core_init_instance(), find_agent_callbacks(), local_call(), local_request(), and sig_pri_cc_generic_check().
09186 { 09187 struct ast_datastore *cc_datastore; 09188 09189 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) { 09190 /* If we can't find the datastore, it almost definitely means that the channel type being 09191 * used has not had its driver modified to parse CC config parameters. The best action 09192 * to take here is to create the parameters on the spot with the defaults set. 09193 */ 09194 if (ast_channel_cc_params_init(chan, NULL)) { 09195 return NULL; 09196 } 09197 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) { 09198 /* Should be impossible */ 09199 return NULL; 09200 } 09201 } 09202 09203 ast_assert(cc_datastore->data != NULL); 09204 return cc_datastore->data; 09205 }
int ast_channel_get_device_name | ( | struct ast_channel * | chan, | |
char * | device_name, | |||
size_t | name_buffer_length | |||
) |
Get a device name given its channel structure.
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 9207 of file channel.c.
References ast_channel_queryoption(), ast_copy_string(), AST_OPTION_DEVICE_NAME, and ast_channel::name.
Referenced by ast_cc_call_failed(), ast_cc_is_recall(), ast_queue_cc_frame(), cc_core_init_instance(), cccancel_exec(), ccreq_exec(), dial_exec_full(), sig_pri_call(), sig_pri_cc_generic_check(), sip_call(), and sip_handle_cc().
09208 { 09209 int len = name_buffer_length; 09210 char *dash; 09211 if (!ast_channel_queryoption(chan, AST_OPTION_DEVICE_NAME, device_name, &len, 0)) { 09212 return 0; 09213 } 09214 09215 /* Dang. Do it the old-fashioned way */ 09216 ast_copy_string(device_name, chan->name, name_buffer_length); 09217 if ((dash = strrchr(device_name, '-'))) { 09218 *dash = '\0'; 09219 } 09220 09221 return 0; 09222 }
static 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 2320 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().
02321 { 02322 enum ast_t38_state state = T38_STATE_UNAVAILABLE; 02323 int datalen = sizeof(state); 02324 02325 ast_channel_queryoption(chan, AST_OPTION_T38_STATE, &state, &datalen, 0); 02326 02327 return state; 02328 }
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 5866 of file channel.c.
References ast_debug, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_var_assign(), ast_var_full_name(), ast_var_name(), ast_var_value(), ast_var_t::entries, and ast_channel::varshead.
Referenced by __ast_request_and_dial(), ast_call_forward(), begin_dial_channel(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), and ring_entry().
05867 { 05868 struct ast_var_t *current, *newvar; 05869 const char *varname; 05870 05871 AST_LIST_TRAVERSE(&parent->varshead, current, entries) { 05872 int vartype = 0; 05873 05874 varname = ast_var_full_name(current); 05875 if (!varname) 05876 continue; 05877 05878 if (varname[0] == '_') { 05879 vartype = 1; 05880 if (varname[1] == '_') 05881 vartype = 2; 05882 } 05883 05884 switch (vartype) { 05885 case 1: 05886 newvar = ast_var_assign(&varname[1], ast_var_value(current)); 05887 if (newvar) { 05888 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 05889 ast_debug(1, "Copying soft-transferable variable %s.\n", ast_var_name(newvar)); 05890 } 05891 break; 05892 case 2: 05893 newvar = ast_var_assign(varname, ast_var_value(current)); 05894 if (newvar) { 05895 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 05896 ast_debug(1, "Copying hard-transferable variable %s.\n", ast_var_name(newvar)); 05897 } 05898 break; 05899 default: 05900 ast_debug(1, "Not copying variable %s.\n", ast_var_name(current)); 05901 break; 05902 } 05903 } 05904 }
struct ast_channel_iterator* ast_channel_iterator_all_new | ( | void | ) |
Create a new channel iterator.
After creating an iterator using this function, the ast_channel_iterator_next() function can be used to iterate through all channels that exist.
NULL | on failure | |
a | new channel iterator |
Definition at line 1611 of file channel.c.
References ao2_iterator_init(), ast_calloc, channels, and ast_channel_iterator::simple_iterator.
Referenced by action_coreshowchannels(), action_status(), ast_complete_channels(), ast_var_channel_bridge(), ast_var_channel_types_table(), ast_var_channels_table(), common_exec(), data_channels_provider_handler(), func_channels_read(), handle_chanlist(), and handle_softhangup().
01612 { 01613 struct ast_channel_iterator *i; 01614 01615 if (!(i = ast_calloc(1, sizeof(*i)))) { 01616 return NULL; 01617 } 01618 01619 i->simple_iterator = ao2_iterator_init(channels, 0); 01620 i->active_iterator = &i->simple_iterator; 01621 01622 return i; 01623 }
struct ast_channel_iterator* ast_channel_iterator_by_exten_new | ( | const char * | exten, | |
const char * | context | |||
) |
Create a new channel iterator based on extension.
NULL | on failure | |
a | new channel iterator based on the specified parameters |
Definition at line 1601 of file channel.c.
References channel_iterator_search().
Referenced by common_exec(), and pickup_by_exten().
01602 { 01603 return channel_iterator_search(NULL, 0, exten, context); 01604 }
struct ast_channel_iterator* ast_channel_iterator_by_name_new | ( | const char * | name, | |
size_t | name_len | |||
) |
Create a new channel iterator based on name.
NULL | on failure | |
a | new channel iterator based on the specified parameters |
Definition at line 1606 of file channel.c.
References channel_iterator_search().
Referenced by ast_complete_channels(), common_exec(), and softhangup_exec().
01607 { 01608 return channel_iterator_search(name, name_len, NULL, NULL); 01609 }
struct ast_channel_iterator* ast_channel_iterator_destroy | ( | struct ast_channel_iterator * | i | ) |
Destroy a channel iterator.
Definition at line 1559 of file channel.c.
References ast_channel_iterator::active_iterator, ao2_iterator_destroy(), and ast_free.
Referenced by action_coreshowchannels(), ast_complete_channels(), ast_var_channel_bridge(), ast_var_channel_types_table(), ast_var_channels_table(), common_exec(), data_channels_provider_handler(), func_channels_read(), handle_chanlist(), handle_softhangup(), pickup_by_exten(), and softhangup_exec().
01560 { 01561 ao2_iterator_destroy(i->active_iterator); 01562 ast_free(i); 01563 01564 return NULL; 01565 }
struct ast_channel* ast_channel_iterator_next | ( | struct ast_channel_iterator * | i | ) |
Get the next channel for a channel iterator.
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 1625 of file channel.c.
References ast_channel_iterator::active_iterator, and ao2_iterator_next.
Referenced by action_coreshowchannels(), action_status(), ast_complete_channels(), ast_var_channel_bridge(), ast_var_channel_types_table(), ast_var_channels_table(), data_channels_provider_handler(), func_channels_read(), handle_chanlist(), handle_softhangup(), next_channel(), pickup_by_exten(), and softhangup_exec().
01626 { 01627 return ao2_iterator_next(i->active_iterator); 01628 }
int ast_channel_make_compatible | ( | struct ast_channel * | c0, | |
struct ast_channel * | c1 | |||
) |
Makes two channel formats compatible.
c0 | first channel to make compatible | |
c1 | other channel to make compatible |
Definition at line 5630 of file channel.c.
References ast_channel_make_compatible_helper(), and chanlist::chan.
Referenced by action_bridge(), app_exec(), ast_channel_bridge(), bridge_exec(), check_compat(), dial_exec_full(), do_forward(), multiplexed_bridge_join(), park_exec_full(), simple_bridge_join(), and wait_for_answer().
05631 { 05632 /* Some callers do not check return code, and we must try to set all call legs correctly */ 05633 int rc = 0; 05634 05635 /* Set up translation from the chan to the peer */ 05636 rc = ast_channel_make_compatible_helper(chan, peer); 05637 05638 if (rc < 0) 05639 return rc; 05640 05641 /* Set up translation from the peer to the chan */ 05642 rc = ast_channel_make_compatible_helper(peer, chan); 05643 05644 return rc; 05645 }
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 5737 of file channel.c.
References __ast_channel_masquerade().
Referenced by ast_async_goto(), ast_pickup_call(), attempt_transfer(), builtin_atxfer(), check_availability(), check_bridge(), check_goto_on_transfer(), do_bridge_masquerade(), handle_invite_replaces(), iax_park(), masq_park_call(), pickup_do(), sip_park(), and skinny_transfer().
05738 { 05739 return __ast_channel_masquerade(original, clone, NULL); 05740 }
int ast_channel_queryoption | ( | struct ast_channel * | channel, | |
int | option, | |||
void * | data, | |||
int * | datalen, | |||
int | block | |||
) |
Checks the value of an option.
Query the value of an option Works similarly to setoption except only reads the options.
Definition at line 7299 of file channel.c.
References ast_log(), chanlist::chan, errno, LOG_ERROR, ast_channel_tech::queryoption, and ast_channel::tech.
Referenced by ast_channel_get_cc_agent_type(), ast_channel_get_device_name(), ast_channel_get_t38_state(), local_queryoption(), rcvfax_exec(), and sndfax_exec().
07300 { 07301 if (!chan->tech->queryoption) { 07302 errno = ENOSYS; 07303 return -1; 07304 } 07305 07306 if (block) 07307 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 07308 07309 return chan->tech->queryoption(chan, option, data, datalen); 07310 }
void ast_channel_queue_connected_line_update | ( | struct ast_channel * | chan, | |
const struct ast_party_connected_line * | connected, | |||
const struct ast_set_party_connected_line * | update | |||
) |
Queue a connected line update frame on a channel.
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 8540 of file channel.c.
References ast_connected_line_build_data(), AST_CONTROL_CONNECTED_LINE, ast_queue_control_data(), connected, and update().
Referenced by ast_pickup_call(), handle_request_invite(), handle_request_update(), handle_response_invite(), local_attended_transfer(), masquerade_colp_transfer(), misdn_queue_connected_line_update(), pickup_do(), and sig_pri_handle_subcmds().
08541 { 08542 unsigned char data[1024]; /* This should be large enough */ 08543 size_t datalen; 08544 08545 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update); 08546 if (datalen == (size_t) -1) { 08547 return; 08548 } 08549 08550 ast_queue_control_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen); 08551 }
void ast_channel_queue_redirecting_update | ( | struct ast_channel * | chan, | |
const struct ast_party_redirecting * | redirecting, | |||
const struct ast_set_party_redirecting * | update | |||
) |
Queue a redirecting update frame on a channel.
chan | Asterisk channel to indicate redirecting id information | |
redirecting | Redirecting id information | |
update | What redirecting information to update. NULL if all. |
Definition at line 9047 of file channel.c.
References AST_CONTROL_REDIRECTING, ast_queue_control_data(), ast_redirecting_build_data(), and update().
Referenced by cb_events(), handle_response_invite(), misdn_facility_ie_handler(), and sig_pri_handle_subcmds().
09048 { 09049 unsigned char data[1024]; /* This should be large enough */ 09050 size_t datalen; 09051 09052 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update); 09053 if (datalen == (size_t) -1) { 09054 return; 09055 } 09056 09057 ast_queue_control_data(chan, AST_CONTROL_REDIRECTING, data, datalen); 09058 }
const char* ast_channel_reason2str | ( | int | reason | ) |
return an english explanation of the code returned thru __ast_request_and_dial's 'outstate' argument
reason | The integer argument, usually taken from AST_CONTROL_ macros |
Definition at line 5034 of file channel.c.
References AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_RING, and AST_CONTROL_RINGING.
Referenced by attempt_thread().
05035 { 05036 switch (reason) /* the following appear to be the only ones actually returned by request_and_dial */ 05037 { 05038 case 0: 05039 return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)"; 05040 case AST_CONTROL_HANGUP: 05041 return "Hangup"; 05042 case AST_CONTROL_RING: 05043 return "Local Ring"; 05044 case AST_CONTROL_RINGING: 05045 return "Remote end Ringing"; 05046 case AST_CONTROL_ANSWER: 05047 return "Remote end has Answered"; 05048 case AST_CONTROL_BUSY: 05049 return "Remote end is Busy"; 05050 case AST_CONTROL_CONGESTION: 05051 return "Congestion (circuits busy)"; 05052 default: 05053 return "Unknown Reason!!"; 05054 } 05055 }
int ast_channel_redirecting_macro | ( | struct ast_channel * | autoservice_chan, | |
struct ast_channel * | macro_chan, | |||
const void * | redirecting_info, | |||
int | is_caller, | |||
int | is_frame | |||
) |
Run a redirecting interception macro and update a channel's redirecting information.
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 9099 of file channel.c.
References ast_app_run_macro(), ast_channel_lock, ast_channel_unlock, ast_channel_update_redirecting(), ast_party_redirecting_copy(), ast_redirecting_parse_data(), ast_strdupa, ast_strlen_zero(), ast_frame::data, ast_frame::datalen, pbx_builtin_getvar_helper(), ast_frame::ptr, ast_channel::redirecting, and S_OR.
Referenced by ast_bridge_call(), do_forward(), feature_request_and_dial(), handle_frame(), and remote_bridge_loop().
09100 { 09101 const char *macro; 09102 const char *macro_args; 09103 int retval; 09104 09105 ast_channel_lock(macro_chan); 09106 macro = pbx_builtin_getvar_helper(macro_chan, is_caller 09107 ? "REDIRECTING_CALLER_SEND_MACRO" : "REDIRECTING_CALLEE_SEND_MACRO"); 09108 macro = ast_strdupa(S_OR(macro, "")); 09109 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller 09110 ? "REDIRECTING_CALLER_SEND_MACRO_ARGS" : "REDIRECTING_CALLEE_SEND_MACRO_ARGS"); 09111 macro_args = ast_strdupa(S_OR(macro_args, "")); 09112 09113 if (ast_strlen_zero(macro)) { 09114 ast_channel_unlock(macro_chan); 09115 return -1; 09116 } 09117 09118 if (is_frame) { 09119 const struct ast_frame *frame = redirecting_info; 09120 09121 ast_redirecting_parse_data(frame->data.ptr, frame->datalen, ¯o_chan->redirecting); 09122 } else { 09123 const struct ast_party_redirecting *redirecting = redirecting_info; 09124 09125 ast_party_redirecting_copy(¯o_chan->redirecting, redirecting); 09126 } 09127 ast_channel_unlock(macro_chan); 09128 09129 retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args); 09130 if (!retval) { 09131 ast_channel_lock(macro_chan); 09132 ast_channel_update_redirecting(macro_chan, ¯o_chan->redirecting, NULL); 09133 ast_channel_unlock(macro_chan); 09134 } 09135 09136 return retval; 09137 }
int ast_channel_register | ( | const struct ast_channel_tech * | tech | ) |
Register a channel technology (a new channel driver) Called by a channel module to register the kind of channels it supports.
tech | Structure defining channel technology or "type" |
Definition at line 837 of file channel.c.
References ast_calloc, ast_debug, ast_log(), AST_RWLIST_INSERT_HEAD, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, chanlist::chan, chanlist::list, LOG_WARNING, chanlist::tech, ast_channel::tech, and ast_channel_tech::type.
Referenced by load_module(), and unload_module().
00838 { 00839 struct chanlist *chan; 00840 00841 AST_RWLIST_WRLOCK(&backends); 00842 00843 AST_RWLIST_TRAVERSE(&backends, chan, list) { 00844 if (!strcasecmp(tech->type, chan->tech->type)) { 00845 ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type); 00846 AST_RWLIST_UNLOCK(&backends); 00847 return -1; 00848 } 00849 } 00850 00851 if (!(chan = ast_calloc(1, sizeof(*chan)))) { 00852 AST_RWLIST_UNLOCK(&backends); 00853 return -1; 00854 } 00855 chan->tech = tech; 00856 AST_RWLIST_INSERT_HEAD(&backends, chan, list); 00857 00858 ast_debug(1, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description); 00859 00860 ast_verb(2, "Registered channel type '%s' (%s)\n", chan->tech->type, chan->tech->description); 00861 00862 AST_RWLIST_UNLOCK(&backends); 00863 00864 return 0; 00865 }
struct ast_channel* ast_channel_release | ( | struct ast_channel * | chan | ) |
Unlink and release reference to a channel.
This function will unlink the channel from the global channels container if it is still there and also release the current reference to the channel.
Definition at line 1827 of file channel.c.
References ao2_unlink, ast_channel_unref, chanlist::chan, and channels.
Referenced by acf_odbc_read(), acf_odbc_write(), action_getvar(), agent_cleanup(), agent_new(), ast_add_extension2_lockopt(), ast_cel_fabricate_channel_from_event(), ast_do_masquerade(), ast_hangup(), ast_iax2_new(), ast_pbx_outgoing_cdr_failed(), ast_request(), ast_str_substitute_variables_full(), bridge_request(), custom_log(), do_notify(), gtalk_newcall(), local_new(), local_request(), make_email_file(), manager_log(), pbx_substitute_variables_helper_full(), rotate_file(), sendmail(), sendpage(), syslog_log(), and write_cdr().
01828 { 01829 /* Safe, even if already unlinked. */ 01830 ao2_unlink(channels, chan); 01831 return ast_channel_unref(chan); 01832 }
int ast_channel_sendhtml | ( | struct ast_channel * | channel, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) |
Sends HTML on given channel Send HTML or URL on link.
Definition at line 5567 of file channel.c.
References chanlist::chan, ast_channel_tech::send_html, and ast_channel::tech.
Referenced by agent_sendhtml(), and ast_channel_sendurl().
05568 { 05569 if (chan->tech->send_html) 05570 return chan->tech->send_html(chan, subclass, data, datalen); 05571 return -1; 05572 }
int ast_channel_sendurl | ( | struct ast_channel * | channel, | |
const char * | url | |||
) |
Sends a URL on a given link Send URL on link.
Definition at line 5574 of file channel.c.
References ast_channel_sendhtml(), AST_HTML_URL, and chanlist::chan.
Referenced by dial_exec_full(), and sendurl_exec().
05575 { 05576 return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1); 05577 }
void ast_channel_set_caller | ( | struct ast_channel * | chan, | |
const struct ast_party_caller * | caller, | |||
const struct ast_set_party_caller * | update | |||
) |
Set the caller id information in the Asterisk channel.
chan | Asterisk channel to set caller id information | |
caller | Caller id information | |
update | What caller information to update. NULL if all. |
Definition at line 6600 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_party_caller_set(), ast_channel::caller, chanlist::chan, and update().
06601 { 06602 if (&chan->caller == caller) { 06603 /* Don't set to self */ 06604 return; 06605 } 06606 06607 ast_channel_lock(chan); 06608 ast_party_caller_set(&chan->caller, caller, update); 06609 ast_channel_unlock(chan); 06610 }
void ast_channel_set_caller_event | ( | struct ast_channel * | chan, | |
const struct ast_party_caller * | caller, | |||
const struct ast_set_party_caller * | update | |||
) |
Set the caller id information in the Asterisk channel and generate an AMI event if the caller id name or number changed.
chan | Asterisk channel to set caller id information | |
caller | Caller id information | |
update | What caller information to update. NULL if all. |
Definition at line 6612 of file channel.c.
References ast_cdr_setcid(), ast_channel_lock, ast_channel_unlock, ast_party_caller_set(), ast_channel::caller, ast_channel::cdr, chanlist::chan, ast_party_caller::id, ast_party_id::name, ast_party_id::number, report_new_callerid(), S_COR, ast_party_number::str, ast_party_name::str, update(), ast_party_number::valid, and ast_party_name::valid.
Referenced by callerid_write(), dial_exec_full(), misdn_update_caller_id(), ring_entry(), and sig_pri_handle_subcmds().
06613 { 06614 struct ast_party_caller pre_set; 06615 06616 if (&chan->caller == caller) { 06617 /* Don't set to self */ 06618 return; 06619 } 06620 06621 ast_channel_lock(chan); 06622 pre_set = chan->caller; 06623 ast_party_caller_set(&chan->caller, caller, update); 06624 if (S_COR(pre_set.id.number.valid, pre_set.id.number.str, NULL) 06625 != S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL) 06626 || S_COR(pre_set.id.name.valid, pre_set.id.name.str, NULL) 06627 != S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL)) { 06628 /* The caller id name or number changed. */ 06629 report_new_callerid(chan); 06630 } 06631 if (chan->cdr) { 06632 ast_cdr_setcid(chan->cdr, chan); 06633 } 06634 ast_channel_unlock(chan); 06635 }
void ast_channel_set_connected_line | ( | struct ast_channel * | chan, | |
const struct ast_party_connected_line * | connected, | |||
const struct ast_set_party_connected_line * | update | |||
) |
Set the connected line information in the Asterisk channel.
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 7900 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().
07901 { 07902 if (&chan->connected == connected) { 07903 /* Don't set to self */ 07904 return; 07905 } 07906 07907 ast_channel_lock(chan); 07908 ast_party_connected_line_set(&chan->connected, connected, update); 07909 ast_channel_unlock(chan); 07910 }
void ast_channel_set_fd | ( | struct ast_channel * | chan, | |
int | which, | |||
int | fd | |||
) |
Set the file descriptor on the channel
Definition at line 2526 of file channel.c.
References ast_calloc, chanlist::chan, ast_channel::data, ast_channel::fds, and free.
Referenced by __ast_channel_alloc_ap(), __oh323_new(), __oh323_rtp_create(), __oh323_update_info(), alsa_new(), ast_deactivate_generator(), ast_do_masquerade(), dahdi_new(), gtalk_new(), jingle_new(), mgcp_new(), misdn_new(), my_swap_subchannels(), nbs_new(), oss_new(), phone_new(), setformat(), sip_new(), skinny_new(), start_rtp(), and swap_subs().
02527 { 02528 #ifdef HAVE_EPOLL 02529 struct epoll_event ev; 02530 struct ast_epoll_data *aed = NULL; 02531 02532 if (chan->fds[which] > -1) { 02533 epoll_ctl(chan->epfd, EPOLL_CTL_DEL, chan->fds[which], &ev); 02534 aed = chan->epfd_data[which]; 02535 } 02536 02537 /* If this new fd is valid, add it to the epoll */ 02538 if (fd > -1) { 02539 if (!aed && (!(aed = ast_calloc(1, sizeof(*aed))))) 02540 return; 02541 02542 chan->epfd_data[which] = aed; 02543 aed->chan = chan; 02544 aed->which = which; 02545 02546 ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP; 02547 ev.data.ptr = aed; 02548 epoll_ctl(chan->epfd, EPOLL_CTL_ADD, fd, &ev); 02549 } else if (aed) { 02550 /* We don't have to keep around this epoll data structure now */ 02551 free(aed); 02552 chan->epfd_data[which] = NULL; 02553 } 02554 #endif 02555 chan->fds[which] = fd; 02556 return; 02557 }
void ast_channel_set_linkgroup | ( | struct ast_channel * | chan, | |
struct ast_channel * | peer | |||
) |
propagate the linked id between chan and peer
Definition at line 6010 of file channel.c.
References ast_channel::_bridge, ast_bridged_channel(), ast_channel_change_linkedid(), ast_strdupa, chanlist::chan, ast_channel::linkedid, oldest_linkedid(), and ast_channel::uniqueid.
Referenced by ast_bridge_call(), and ast_do_masquerade().
06011 { 06012 const char* linkedid=NULL; 06013 struct ast_channel *bridged; 06014 06015 linkedid = oldest_linkedid(chan->linkedid, peer->linkedid); 06016 linkedid = oldest_linkedid(linkedid, chan->uniqueid); 06017 linkedid = oldest_linkedid(linkedid, peer->uniqueid); 06018 if (chan->_bridge) { 06019 bridged = ast_bridged_channel(chan); 06020 if (bridged != peer) { 06021 linkedid = oldest_linkedid(linkedid, bridged->linkedid); 06022 linkedid = oldest_linkedid(linkedid, bridged->uniqueid); 06023 } 06024 } 06025 if (peer->_bridge) { 06026 bridged = ast_bridged_channel(peer); 06027 if (bridged != chan) { 06028 linkedid = oldest_linkedid(linkedid, bridged->linkedid); 06029 linkedid = oldest_linkedid(linkedid, bridged->uniqueid); 06030 } 06031 } 06032 06033 /* just in case setting a stringfield to itself causes problems */ 06034 linkedid = ast_strdupa(linkedid); 06035 06036 ast_channel_change_linkedid(chan, linkedid); 06037 ast_channel_change_linkedid(peer, linkedid); 06038 if (chan->_bridge) { 06039 bridged = ast_bridged_channel(chan); 06040 if (bridged != peer) { 06041 ast_channel_change_linkedid(bridged, linkedid); 06042 } 06043 } 06044 if (peer->_bridge) { 06045 bridged = ast_bridged_channel(peer); 06046 if (bridged != chan) { 06047 ast_channel_change_linkedid(bridged, linkedid); 06048 } 06049 } 06050 }
void ast_channel_set_redirecting | ( | struct ast_channel * | chan, | |
const struct ast_party_redirecting * | redirecting, | |||
const struct ast_set_party_redirecting * | update | |||
) |
Set the redirecting id information in the Asterisk channel.
chan | Asterisk channel to set redirecting id information | |
redirecting | Redirecting id information | |
update | What redirecting information to update. NULL if all. |
Definition at line 8553 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_party_redirecting_set(), ast_channel::redirecting, and update().
Referenced by ast_call_forward(), ast_indicate_data(), do_forward(), handle_request_invite(), handle_response(), misdn_copy_redirecting_to_ast(), redirecting_write(), and sig_pri_handle_subcmds().
08554 { 08555 if (&chan->redirecting == redirecting) { 08556 /* Don't set to self */ 08557 return; 08558 } 08559 08560 ast_channel_lock(chan); 08561 ast_party_redirecting_set(&chan->redirecting, redirecting, update); 08562 ast_channel_unlock(chan); 08563 }
int ast_channel_setoption | ( | struct ast_channel * | channel, | |
int | option, | |||
void * | data, | |||
int | datalen, | |||
int | block | |||
) |
Sets an option on a channel.
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 7286 of file channel.c.
References ast_log(), chanlist::chan, errno, LOG_ERROR, ast_channel_tech::setoption, and ast_channel::tech.
Referenced by analog_hangup(), ast_bridge_call(), ast_channel_make_compatible_helper(), common_exec(), conf_run(), dahdi_hangup(), dial_exec_full(), func_channel_write(), func_channel_write_real(), handle_tddmode(), play_record_review(), rcvfax_exec(), reset_volumes(), rpt(), rpt_exec(), set_format(), set_listen_volume(), set_security_requirements(), set_talk_volume(), sndfax_exec(), and vm_forwardoptions().
07287 { 07288 if (!chan->tech->setoption) { 07289 errno = ENOSYS; 07290 return -1; 07291 } 07292 07293 if (block) 07294 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 07295 07296 return chan->tech->setoption(chan, option, data, datalen); 07297 }
void ast_channel_setwhentohangup | ( | struct ast_channel * | chan, | |
time_t | offset | |||
) |
Set when to hang a channel up.
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 808 of file channel.c.
References ast_channel_setwhentohangup_tv(), and chanlist::chan.
00809 { 00810 struct timeval when = { offset, }; 00811 ast_channel_setwhentohangup_tv(chan, when); 00812 }
void ast_channel_setwhentohangup_tv | ( | struct ast_channel * | chan, | |
struct timeval | offset | |||
) |
Set when to hang a channel up.
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 801 of file channel.c.
References ast_null_frame, ast_queue_frame(), ast_tvadd(), ast_tvnow(), ast_tvzero(), chanlist::chan, and ast_channel::whentohangup.
Referenced by action_timeout(), ast_channel_setwhentohangup(), handle_autohangup(), and timeout_write().
00802 { 00803 chan->whentohangup = ast_tvzero(offset) ? offset : ast_tvadd(offset, ast_tvnow()); 00804 ast_queue_frame(chan, &ast_null_frame); 00805 return; 00806 }
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 7774 of file channel.c.
References ast_activate_generator(), ast_calloc, ast_debug, AST_FORMAT_SLINEAR, ast_free, ast_log(), ast_set_write_format(), LOG_ERROR, ast_channel::name, ast_silence_generator::old_write_format, silence_generator, state, and ast_channel::writeformat.
Referenced by __ast_play_and_record(), ast_dtmf_stream(), ast_readstring_full(), ast_safe_sleep_conditional(), channel_spy(), TransferCallStep1(), waitfor_exec(), and waitforring_exec().
07775 { 07776 struct ast_silence_generator *state; 07777 07778 if (!(state = ast_calloc(1, sizeof(*state)))) { 07779 return NULL; 07780 } 07781 07782 state->old_write_format = chan->writeformat; 07783 07784 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) { 07785 ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n"); 07786 ast_free(state); 07787 return NULL; 07788 } 07789 07790 ast_activate_generator(chan, &silence_generator, state); 07791 07792 ast_debug(1, "Started silence generator on '%s'\n", chan->name); 07793 07794 return state; 07795 }
void ast_channel_stop_silence_generator | ( | struct ast_channel * | chan, | |
struct ast_silence_generator * | state | |||
) |
Stops a previously-started silence generator on the given channel.
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 7797 of file channel.c.
References ast_deactivate_generator(), ast_debug, ast_free, ast_log(), ast_set_write_format(), LOG_ERROR, ast_channel::name, and state.
Referenced by ast_dtmf_stream(), ast_readstring_full(), ast_safe_sleep_conditional(), channel_spy(), HandleCallOutgoing(), key_dial_page(), unistim_hangup(), waitfor_exec(), and waitforring_exec().
07798 { 07799 if (!state) 07800 return; 07801 07802 ast_deactivate_generator(chan); 07803 07804 ast_debug(1, "Stopped silence generator on '%s'\n", chan->name); 07805 07806 if (ast_set_write_format(chan, state->old_write_format) < 0) 07807 ast_log(LOG_ERROR, "Could not return write format to its original state\n"); 07808 07809 ast_free(state); 07810 }
int ast_channel_supports_html | ( | struct ast_channel * | channel | ) |
Checks for HTML support on a channel.
Definition at line 5562 of file channel.c.
References chanlist::chan, ast_channel_tech::send_html, and ast_channel::tech.
Referenced by dial_exec_full(), and sendurl_exec().
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 5811 of file channel.c.
References __ast_channel_masquerade(), ast_calloc, ast_datastore_alloc, ast_datastore_free(), ast_datastore::data, party_connected_line_copy_transfer(), xfer_masquerade_ds::target_id, xfer_masquerade_ds::transferee_id, and xfer_ds_info.
Referenced by analog_attempt_transfer(), misdn_attempt_transfer(), and sig_pri_attempt_transfer().
05818 { 05819 struct ast_datastore *xfer_ds; 05820 struct xfer_masquerade_ds *xfer_colp; 05821 int res; 05822 05823 xfer_ds = ast_datastore_alloc(&xfer_ds_info, NULL); 05824 if (!xfer_ds) { 05825 return -1; 05826 } 05827 05828 xfer_colp = ast_calloc(1, sizeof(*xfer_colp)); 05829 if (!xfer_colp) { 05830 ast_datastore_free(xfer_ds); 05831 return -1; 05832 } 05833 party_connected_line_copy_transfer(&xfer_colp->target_id, target_id); 05834 xfer_colp->target_held = target_held; 05835 party_connected_line_copy_transfer(&xfer_colp->transferee_id, transferee_id); 05836 xfer_colp->transferee_held = transferee_held; 05837 xfer_ds->data = xfer_colp; 05838 05839 res = __ast_channel_masquerade(target_chan, transferee_chan, xfer_ds); 05840 if (res) { 05841 ast_datastore_free(xfer_ds); 05842 } 05843 return res; 05844 }
void ast_channel_undefer_dtmf | ( | struct ast_channel * | chan | ) |
Unset defer DTMF flag on channel.
Undo defer. ast_read will return any DTMF characters that were queued
Definition at line 1538 of file channel.c.
References ast_clear_flag, AST_FLAG_DEFER_DTMF, and chanlist::chan.
Referenced by find_cache(), and rpt_call().
01539 { 01540 if (chan) 01541 ast_clear_flag(chan, AST_FLAG_DEFER_DTMF); 01542 }
void ast_channel_unregister | ( | const struct ast_channel_tech * | tech | ) |
Unregister a channel technology.
tech | Structure defining channel technology or "type" that was previously registered |
Definition at line 868 of file channel.c.
References ast_debug, ast_free, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_END, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, chanlist::chan, chanlist::list, chanlist::tech, ast_channel::tech, and ast_channel_tech::type.
Referenced by __unload_module(), load_module(), and unload_module().
00869 { 00870 struct chanlist *chan; 00871 00872 ast_debug(1, "Unregistering channel type '%s'\n", tech->type); 00873 00874 AST_RWLIST_WRLOCK(&backends); 00875 00876 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) { 00877 if (chan->tech == tech) { 00878 AST_LIST_REMOVE_CURRENT(list); 00879 ast_free(chan); 00880 ast_verb(2, "Unregistered channel type '%s'\n", tech->type); 00881 break; 00882 } 00883 } 00884 AST_LIST_TRAVERSE_SAFE_END; 00885 00886 AST_RWLIST_UNLOCK(&backends); 00887 }
void ast_channel_update_connected_line | ( | struct ast_channel * | chan, | |
const struct ast_party_connected_line * | connected, | |||
const struct ast_set_party_connected_line * | update | |||
) |
Indicate that the connected line information has changed.
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 8527 of file channel.c.
References ast_connected_line_build_data(), AST_CONTROL_CONNECTED_LINE, ast_indicate_data(), connected, and update().
Referenced by ast_channel_connected_line_macro(), ast_pickup_call(), atxfer_fail_cleanup(), builtin_atxfer(), builtin_blindtransfer(), connectedline_write(), pickup_do(), and wait_for_answer().
08528 { 08529 unsigned char data[1024]; /* This should be large enough */ 08530 size_t datalen; 08531 08532 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update); 08533 if (datalen == (size_t) -1) { 08534 return; 08535 } 08536 08537 ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen); 08538 }
void ast_channel_update_redirecting | ( | struct ast_channel * | chan, | |
const struct ast_party_redirecting * | redirecting, | |||
const struct ast_set_party_redirecting * | update | |||
) |
Indicate that the redirecting id has changed.
chan | Asterisk channel to indicate redirecting id information | |
redirecting | Redirecting id information | |
update | What redirecting information to update. NULL if all. |
Definition at line 9034 of file channel.c.
References AST_CONTROL_REDIRECTING, ast_indicate_data(), ast_redirecting_build_data(), and update().
Referenced by ast_call_forward(), ast_channel_redirecting_macro(), do_forward(), and redirecting_write().
09035 { 09036 unsigned char data[1024]; /* This should be large enough */ 09037 size_t datalen; 09038 09039 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update); 09040 if (datalen == (size_t) -1) { 09041 return; 09042 } 09043 09044 ast_indicate_data(chan, AST_CONTROL_REDIRECTING, data, datalen); 09045 }
struct ast_variable* ast_channeltype_list | ( | void | ) |
return an ast_variable list of channeltypes
Definition at line 248 of file channel.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_variable_new(), ast_channel_tech::description, chanlist::list, chanlist::tech, ast_channel_tech::type, and var.
Referenced by ast_var_channel_types(), and ast_var_channel_types_table().
00249 { 00250 struct chanlist *cl; 00251 struct ast_variable *var = NULL, *prev = NULL; 00252 00253 AST_RWLIST_RDLOCK(&backends); 00254 AST_RWLIST_TRAVERSE(&backends, cl, list) { 00255 if (prev) { 00256 if ((prev->next = ast_variable_new(cl->tech->type, cl->tech->description, ""))) 00257 prev = prev->next; 00258 } else { 00259 var = ast_variable_new(cl->tech->type, cl->tech->description, ""); 00260 prev = var; 00261 } 00262 } 00263 AST_RWLIST_UNLOCK(&backends); 00264 00265 return var; 00266 }
int ast_check_hangup | ( | struct ast_channel * | chan | ) |
Check to see if a channel is needing hang up.
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 742 of file channel.c.
References ast_channel::_softhangup, ast_debug, AST_SOFTHANGUP_TIMEOUT, ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), chanlist::chan, and ast_channel::whentohangup.
Referenced by __ast_pbx_run(), __ast_read(), _macro_exec(), agent_indicate(), agi_exec(), agi_handle_command(), announce_thread(), ast_bridge_call(), ast_call(), ast_channel_bridge(), ast_check_hangup_locked(), ast_indicate_data(), ast_raw_answer(), ast_readstring_full(), ast_recvtext(), ast_rtp_instance_bridge(), ast_sendtext(), ast_transfer(), ast_udptl_bridge(), ast_waitfordigit_full(), ast_write(), autoservice_run(), bridge_call_thread(), bridge_exec(), builtin_atxfer(), channel_spy(), check_bridge(), common_exec(), conf_play(), conf_run(), dahdi_sendtext(), dahdi_setoption(), dial_exec_full(), dundi_lookup_internal(), eagi_exec(), eivr_comm(), feature_request_and_dial(), findmeexec(), func_channel_read(), handle_sendimage(), launch_asyncagi(), local_fixup(), lua_check_hangup(), ospfinished_exec(), pbx_builtin_incomplete(), pbx_exec(), read_exec(), readexten_exec(), remote_bridge_loop(), rpt(), and run_ras().
00743 { 00744 if (chan->_softhangup) /* yes if soft hangup flag set */ 00745 return 1; 00746 if (ast_tvzero(chan->whentohangup)) /* no if no hangup scheduled */ 00747 return 0; 00748 if (ast_tvdiff_ms(chan->whentohangup, ast_tvnow()) > 0) /* no if hangup time has not come yet. */ 00749 return 0; 00750 ast_debug(4, "Hangup time has come: %" PRIi64 "\n", ast_tvdiff_ms(chan->whentohangup, ast_tvnow())); 00751 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT; /* record event */ 00752 return 1; 00753 }
int ast_check_hangup_locked | ( | struct ast_channel * | chan | ) |
Definition at line 755 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_check_hangup(), and chanlist::chan.
Referenced by action_redirect(), and ast_channel_bridge().
00756 { 00757 int res; 00758 ast_channel_lock(chan); 00759 res = ast_check_hangup(chan); 00760 ast_channel_unlock(chan); 00761 return res; 00762 }
int ast_connected_line_build_data | ( | unsigned char * | data, | |
size_t | datalen, | |||
const struct ast_party_connected_line * | connected, | |||
const struct ast_set_party_connected_line * | update | |||
) |
Build the connected line information data frame.
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 8267 of file channel.c.
References AST_CONNECTED_LINE_ID_PRESENTATION, AST_CONNECTED_LINE_NAME, AST_CONNECTED_LINE_NAME_CHAR_SET, AST_CONNECTED_LINE_NAME_PRESENTATION, AST_CONNECTED_LINE_NAME_VALID, AST_CONNECTED_LINE_NUMBER, AST_CONNECTED_LINE_NUMBER_PLAN, AST_CONNECTED_LINE_NUMBER_PRESENTATION, AST_CONNECTED_LINE_NUMBER_VALID, AST_CONNECTED_LINE_SOURCE, AST_CONNECTED_LINE_SUBADDRESS, AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN, AST_CONNECTED_LINE_SUBADDRESS_TYPE, AST_CONNECTED_LINE_SUBADDRESS_VALID, AST_CONNECTED_LINE_TAG, AST_CONNECTED_LINE_VERSION, ast_log(), connected, LOG_WARNING, ast_party_id_ies::name, party_id_build_data(), ast_party_name_ies::str, update(), and value.
Referenced by ast_channel_queue_connected_line_update(), ast_channel_update_connected_line(), local_attended_transfer(), local_indicate(), and masquerade_colp_transfer().
08268 { 08269 int32_t value; 08270 size_t pos = 0; 08271 int res; 08272 08273 static const struct ast_party_id_ies ies = { 08274 .name.str = AST_CONNECTED_LINE_NAME, 08275 .name.char_set = AST_CONNECTED_LINE_NAME_CHAR_SET, 08276 .name.presentation = AST_CONNECTED_LINE_NAME_PRESENTATION, 08277 .name.valid = AST_CONNECTED_LINE_NAME_VALID, 08278 08279 .number.str = AST_CONNECTED_LINE_NUMBER, 08280 .number.plan = AST_CONNECTED_LINE_NUMBER_PLAN, 08281 .number.presentation = AST_CONNECTED_LINE_NUMBER_PRESENTATION, 08282 .number.valid = AST_CONNECTED_LINE_NUMBER_VALID, 08283 08284 .subaddress.str = AST_CONNECTED_LINE_SUBADDRESS, 08285 .subaddress.type = AST_CONNECTED_LINE_SUBADDRESS_TYPE, 08286 .subaddress.odd_even_indicator = AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN, 08287 .subaddress.valid = AST_CONNECTED_LINE_SUBADDRESS_VALID, 08288 08289 .tag = AST_CONNECTED_LINE_TAG, 08290 .combined_presentation = AST_CONNECTED_LINE_ID_PRESENTATION, 08291 }; 08292 08293 /* 08294 * The size of integer values must be fixed in case the frame is 08295 * shipped to another machine. 08296 */ 08297 08298 /* Connected line frame version */ 08299 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08300 ast_log(LOG_WARNING, "No space left for connected line frame version\n"); 08301 return -1; 08302 } 08303 data[pos++] = AST_CONNECTED_LINE_VERSION; 08304 data[pos++] = 1; 08305 data[pos++] = 2;/* Version 1 did not have a version ie */ 08306 08307 res = party_id_build_data(data + pos, datalen - pos, &connected->id, 08308 "connected line", &ies, update ? &update->id : NULL); 08309 if (res < 0) { 08310 return -1; 08311 } 08312 pos += res; 08313 08314 /* Connected line source */ 08315 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) { 08316 ast_log(LOG_WARNING, "No space left for connected line source\n"); 08317 return -1; 08318 } 08319 data[pos++] = AST_CONNECTED_LINE_SOURCE; 08320 data[pos++] = sizeof(value); 08321 value = htonl(connected->source); 08322 memcpy(data + pos, &value, sizeof(value)); 08323 pos += sizeof(value); 08324 08325 return pos; 08326 }
void ast_connected_line_copy_from_caller | ( | struct ast_party_connected_line * | dest, | |
const struct ast_party_caller * | src | |||
) |
Copy the caller information to the connected line information.
dest | Destination connected line information | |
src | Source caller information |
Definition at line 7885 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 begin_dial_channel(), builtin_atxfer(), dial_exec_full(), feature_request_and_dial(), local_call(), pickup_do(), ring_entry(), and wait_for_answer().
07886 { 07887 ast_party_id_copy(&dest->id, &src->id); 07888 ast_party_id_copy(&dest->ani, &src->ani); 07889 dest->ani2 = src->ani2; 07890 }
void ast_connected_line_copy_to_caller | ( | struct ast_party_caller * | dest, | |
const struct ast_party_connected_line * | src | |||
) |
Copy the connected line information to the caller information.
dest | Destination caller information | |
src | Source connected line information |
Definition at line 7892 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().
07893 { 07894 ast_party_id_copy(&dest->id, &src->id); 07895 ast_party_id_copy(&dest->ani, &src->ani); 07896 07897 dest->ani2 = src->ani2; 07898 }
int ast_connected_line_parse_data | ( | const unsigned char * | data, | |
size_t | datalen, | |||
struct ast_party_connected_line * | connected | |||
) |
Parse connected line indication frame data.
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 8328 of file channel.c.
References AST_CONNECTED_LINE_ID_PRESENTATION, AST_CONNECTED_LINE_NAME, AST_CONNECTED_LINE_NAME_CHAR_SET, AST_CONNECTED_LINE_NAME_PRESENTATION, AST_CONNECTED_LINE_NAME_VALID, AST_CONNECTED_LINE_NUMBER, AST_CONNECTED_LINE_NUMBER_PLAN, AST_CONNECTED_LINE_NUMBER_PRESENTATION, AST_CONNECTED_LINE_NUMBER_VALID, AST_CONNECTED_LINE_SOURCE, AST_CONNECTED_LINE_SUBADDRESS, AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN, AST_CONNECTED_LINE_SUBADDRESS_TYPE, AST_CONNECTED_LINE_SUBADDRESS_VALID, AST_CONNECTED_LINE_TAG, AST_CONNECTED_LINE_VERSION, ast_free, ast_log(), ast_malloc, AST_PARTY_CHAR_SET_ISO8859_1, ast_party_id_ies::combined_presentation, connected, LOG_DEBUG, LOG_WARNING, and value.
Referenced by __ast_read(), ast_channel_connected_line_macro(), ast_indicate_data(), feature_request_and_dial(), and socket_process().
08329 { 08330 size_t pos; 08331 unsigned char ie_len; 08332 unsigned char ie_id; 08333 int32_t value; 08334 int frame_version = 1; 08335 int combined_presentation = 0; 08336 int got_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */ 08337 08338 for (pos = 0; pos < datalen; pos += ie_len) { 08339 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) { 08340 ast_log(LOG_WARNING, "Invalid connected line update\n"); 08341 return -1; 08342 } 08343 ie_id = data[pos++]; 08344 ie_len = data[pos++]; 08345 if (datalen < pos + ie_len) { 08346 ast_log(LOG_WARNING, "Invalid connected line update\n"); 08347 return -1; 08348 } 08349 08350 switch (ie_id) { 08351 /* Connected line party frame version */ 08352 case AST_CONNECTED_LINE_VERSION: 08353 if (ie_len != 1) { 08354 ast_log(LOG_WARNING, "Invalid connected line frame version (%u)\n", 08355 (unsigned) ie_len); 08356 break; 08357 } 08358 frame_version = data[pos]; 08359 break; 08360 /* Connected line party id name */ 08361 case AST_CONNECTED_LINE_NAME: 08362 ast_free(connected->id.name.str); 08363 connected->id.name.str = ast_malloc(ie_len + 1); 08364 if (connected->id.name.str) { 08365 memcpy(connected->id.name.str, data + pos, ie_len); 08366 connected->id.name.str[ie_len] = 0; 08367 } 08368 break; 08369 case AST_CONNECTED_LINE_NAME_CHAR_SET: 08370 if (ie_len != 1) { 08371 ast_log(LOG_WARNING, "Invalid connected line name char set (%u)\n", 08372 (unsigned) ie_len); 08373 break; 08374 } 08375 connected->id.name.char_set = data[pos]; 08376 break; 08377 case AST_CONNECTED_LINE_NAME_PRESENTATION: 08378 if (ie_len != 1) { 08379 ast_log(LOG_WARNING, "Invalid connected line name presentation (%u)\n", 08380 (unsigned) ie_len); 08381 break; 08382 } 08383 connected->id.name.presentation = data[pos]; 08384 break; 08385 case AST_CONNECTED_LINE_NAME_VALID: 08386 if (ie_len != 1) { 08387 ast_log(LOG_WARNING, "Invalid connected line name valid (%u)\n", 08388 (unsigned) ie_len); 08389 break; 08390 } 08391 connected->id.name.valid = data[pos]; 08392 break; 08393 /* Connected line party id number */ 08394 case AST_CONNECTED_LINE_NUMBER: 08395 ast_free(connected->id.number.str); 08396 connected->id.number.str = ast_malloc(ie_len + 1); 08397 if (connected->id.number.str) { 08398 memcpy(connected->id.number.str, data + pos, ie_len); 08399 connected->id.number.str[ie_len] = 0; 08400 } 08401 break; 08402 case AST_CONNECTED_LINE_NUMBER_PLAN: 08403 if (ie_len != 1) { 08404 ast_log(LOG_WARNING, "Invalid connected line numbering plan (%u)\n", 08405 (unsigned) ie_len); 08406 break; 08407 } 08408 connected->id.number.plan = data[pos]; 08409 break; 08410 case AST_CONNECTED_LINE_NUMBER_PRESENTATION: 08411 if (ie_len != 1) { 08412 ast_log(LOG_WARNING, "Invalid connected line number presentation (%u)\n", 08413 (unsigned) ie_len); 08414 break; 08415 } 08416 connected->id.number.presentation = data[pos]; 08417 break; 08418 case AST_CONNECTED_LINE_NUMBER_VALID: 08419 if (ie_len != 1) { 08420 ast_log(LOG_WARNING, "Invalid connected line number valid (%u)\n", 08421 (unsigned) ie_len); 08422 break; 08423 } 08424 connected->id.number.valid = data[pos]; 08425 break; 08426 /* Connected line party id combined presentation */ 08427 case AST_CONNECTED_LINE_ID_PRESENTATION: 08428 if (ie_len != 1) { 08429 ast_log(LOG_WARNING, "Invalid connected line combined presentation (%u)\n", 08430 (unsigned) ie_len); 08431 break; 08432 } 08433 combined_presentation = data[pos]; 08434 got_combined_presentation = 1; 08435 break; 08436 /* Connected line party id subaddress */ 08437 case AST_CONNECTED_LINE_SUBADDRESS: 08438 ast_free(connected->id.subaddress.str); 08439 connected->id.subaddress.str = ast_malloc(ie_len + 1); 08440 if (connected->id.subaddress.str) { 08441 memcpy(connected->id.subaddress.str, data + pos, ie_len); 08442 connected->id.subaddress.str[ie_len] = 0; 08443 } 08444 break; 08445 case AST_CONNECTED_LINE_SUBADDRESS_TYPE: 08446 if (ie_len != 1) { 08447 ast_log(LOG_WARNING, "Invalid connected line type of subaddress (%u)\n", 08448 (unsigned) ie_len); 08449 break; 08450 } 08451 connected->id.subaddress.type = data[pos]; 08452 break; 08453 case AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN: 08454 if (ie_len != 1) { 08455 ast_log(LOG_WARNING, 08456 "Invalid connected line subaddress odd-even indicator (%u)\n", 08457 (unsigned) ie_len); 08458 break; 08459 } 08460 connected->id.subaddress.odd_even_indicator = data[pos]; 08461 break; 08462 case AST_CONNECTED_LINE_SUBADDRESS_VALID: 08463 if (ie_len != 1) { 08464 ast_log(LOG_WARNING, "Invalid connected line subaddress valid (%u)\n", 08465 (unsigned) ie_len); 08466 break; 08467 } 08468 connected->id.subaddress.valid = data[pos]; 08469 break; 08470 /* Connected line party tag */ 08471 case AST_CONNECTED_LINE_TAG: 08472 ast_free(connected->id.tag); 08473 connected->id.tag = ast_malloc(ie_len + 1); 08474 if (connected->id.tag) { 08475 memcpy(connected->id.tag, data + pos, ie_len); 08476 connected->id.tag[ie_len] = 0; 08477 } 08478 break; 08479 /* Connected line party source */ 08480 case AST_CONNECTED_LINE_SOURCE: 08481 if (ie_len != sizeof(value)) { 08482 ast_log(LOG_WARNING, "Invalid connected line source (%u)\n", 08483 (unsigned) ie_len); 08484 break; 08485 } 08486 memcpy(&value, data + pos, sizeof(value)); 08487 connected->source = ntohl(value); 08488 break; 08489 /* Connected line party unknown element */ 08490 default: 08491 ast_log(LOG_DEBUG, "Unknown connected line element: %u (%u)\n", 08492 (unsigned) ie_id, (unsigned) ie_len); 08493 break; 08494 } 08495 } 08496 08497 switch (frame_version) { 08498 case 1: 08499 /* 08500 * The other end is an earlier version that we need to adjust 08501 * for compatibility. 08502 */ 08503 connected->id.name.valid = 1; 08504 connected->id.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1; 08505 connected->id.number.valid = 1; 08506 if (got_combined_presentation) { 08507 connected->id.name.presentation = combined_presentation; 08508 connected->id.number.presentation = combined_presentation; 08509 } 08510 break; 08511 case 2: 08512 /* The other end is at the same level as we are. */ 08513 break; 08514 default: 08515 /* 08516 * The other end is newer than we are. 08517 * We need to assume that they are compatible with us. 08518 */ 08519 ast_log(LOG_DEBUG, "Connected line frame has newer version: %u\n", 08520 (unsigned) frame_version); 08521 break; 08522 } 08523 08524 return 0; 08525 }
void ast_deactivate_generator | ( | struct ast_channel * | chan | ) |
Deactivate an active generator
Definition at line 2931 of file channel.c.
References ast_channel_lock, ast_channel_set_fd(), ast_channel_unlock, ast_clear_flag, AST_FLAG_WRITE_INT, AST_GENERATOR_FD, ast_settimeout(), chanlist::chan, ast_channel::generator, ast_channel::generatordata, and ast_generator::release.
Referenced by __ast_read(), app_exec(), ast_channel_stop_silence_generator(), ast_openstream_full(), ast_playtones_stop(), ast_quiet_chan(), ast_read_generator_actions(), ast_tonepair_stop(), ast_write(), cb_events(), channel_spy(), dial_exec_full(), generator_force(), local_ast_moh_stop(), old_milliwatt_exec(), transmit_audio(), and wait_for_answer().
02932 { 02933 ast_channel_lock(chan); 02934 if (chan->generatordata) { 02935 if (chan->generator && chan->generator->release) 02936 chan->generator->release(chan, chan->generatordata); 02937 chan->generatordata = NULL; 02938 chan->generator = NULL; 02939 ast_channel_set_fd(chan, AST_GENERATOR_FD, -1); 02940 ast_clear_flag(chan, AST_FLAG_WRITE_INT); 02941 ast_settimeout(chan, 0, NULL, NULL); 02942 } 02943 ast_channel_unlock(chan); 02944 }
int ast_do_masquerade | ( | struct ast_channel * | original | ) |
Start masquerading a channel.
Definition at line 6169 of file channel.c.
References __ast_change_name_nolink(), ast_channel::_bridge, ast_channel::_softhangup, ast_channel::_state, accountcode, ast_channel::adsicpe, ast_channel::alertpipe, ao2_link, ao2_lock, ao2_unlink, ao2_unlock, ast_app_group_update(), ast_autochan_new_channel(), ast_bridged_channel(), ast_cause2str(), AST_CEL_BRIDGE_UPDATE, ast_cel_report_event(), ast_channel_datastore_find(), ast_channel_datastore_remove(), ast_channel_lock, AST_CHANNEL_NAME, ast_channel_release(), ast_channel_set_fd(), ast_channel_set_linkgroup(), ast_channel_trylock, ast_channel_unlock, AST_CONTROL_SRCCHANGE, AST_CONTROL_UNHOLD, ast_copy_string(), ast_datastore_free(), ast_debug, AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, AST_GENERATOR_FD, ast_getformatname(), ast_indicate(), AST_LIST_APPEND_LIST, AST_LIST_FIRST, AST_LIST_HEAD_NOLOCK, AST_LIST_HEAD_SET_NOLOCK, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), ast_manager_event, ast_manager_event_multichan, AST_MAX_FDS, ast_null_frame, ast_queue_frame(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_SOFTHANGUP_DEV, ast_state2str(), ast_string_field_set, ast_test_flag, AST_TIMING_FD, ast_channel::blocker, ast_channel::caller, ast_channel::cdr, ast_datastore_info::chan_fixup, CHANNEL_DEADLOCK_AVOIDANCE, channels, clone_variables(), chanlist::connected, ast_channel::connected, ast_datastore::data, ast_channel::datastores, ast_channel::dialed, ast_datastore::entry, errno, EVENT_FLAG_CALL, ast_channel::fdno, ast_channel::fds, ast_channel_tech::fixup, free_translation(), ast_channel_tech::hangup, ast_datastore::info, language, ast_channel::language, LOG_WARNING, ast_channel::masq, ast_channel::masqr, masquerade_colp_transfer(), ast_channel::monitor, musicclass, ast_channel::name, ast_channel::nativeformats, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::readq, ast_channel::redirecting, report_new_callerid(), S_OR, ast_channel::tech, ast_channel::tech_pvt, ast_channel::timingfd, xfer_masquerade_ds::transferee_held, ast_channel_tech::type, ast_channel::visible_indication, ast_channel::writeformat, and xfer_ds_info.
Referenced by __ast_read(), ast_async_goto(), ast_hangup(), ast_waitfor_nandfds(), ast_write(), builtin_atxfer(), do_bridge_masquerade(), handle_invite_replaces(), iax_park(), local_attended_transfer(), sip_park(), and sip_park_thread().
06170 { 06171 format_t x; 06172 int i; 06173 int res=0; 06174 int origstate; 06175 int visible_indication; 06176 struct ast_frame *current; 06177 const struct ast_channel_tech *t; 06178 void *t_pvt; 06179 union { 06180 struct ast_party_dialed dialed; 06181 struct ast_party_caller caller; 06182 struct ast_party_connected_line connected; 06183 struct ast_party_redirecting redirecting; 06184 } exchange; 06185 struct ast_channel *clonechan, *chans[2]; 06186 struct ast_channel *bridged; 06187 struct ast_cdr *cdr; 06188 struct ast_datastore *xfer_ds; 06189 struct xfer_masquerade_ds *xfer_colp; 06190 format_t rformat = original->readformat; 06191 format_t wformat = original->writeformat; 06192 char newn[AST_CHANNEL_NAME]; 06193 char orig[AST_CHANNEL_NAME]; 06194 char masqn[AST_CHANNEL_NAME]; 06195 char zombn[AST_CHANNEL_NAME]; 06196 06197 /* XXX This operation is a bit odd. We're essentially putting the guts of 06198 * the clone channel into the original channel. Start by killing off the 06199 * original channel's backend. While the features are nice, which is the 06200 * reason we're keeping it, it's still awesomely weird. XXX */ 06201 06202 /* The reasoning for the channels ao2_container lock here is complex. 06203 * 06204 * In order to check for a race condition, the original channel must 06205 * be locked. If it is determined that the masquerade should proceed 06206 * the original channel can absolutely not be unlocked until the end 06207 * of the function. Since after determining the masquerade should 06208 * continue requires the channels to be unlinked from the ao2_container, 06209 * the container lock must be held first to achieve proper locking order. 06210 */ 06211 ao2_lock(channels); 06212 06213 /* lock the original channel to determine if the masquerade is require or not */ 06214 ast_channel_lock(original); 06215 06216 /* This checks to see if the masquerade has already happened or not. There is a 06217 * race condition that exists for this function. Since all pvt and channel locks 06218 * must be let go before calling do_masquerade, it is possible that it could be 06219 * called multiple times for the same channel. This check verifies whether 06220 * or not the masquerade has already been completed by another thread */ 06221 if (!original->masq) { 06222 ast_channel_unlock(original); 06223 ao2_unlock(channels); 06224 return 0; /* masq already completed by another thread, or never needed to be done to begin with */ 06225 } 06226 06227 /* now that we have verified no race condition exists, set the clone channel */ 06228 clonechan = original->masq; 06229 06230 /* since this function already holds the global container lock, unlocking original 06231 * for deadlock avoidance will not result in any sort of masquerade race condition. 06232 * If masq is called by a different thread while this happens, it will be stuck waiting 06233 * until we unlock the container. */ 06234 while (ast_channel_trylock(clonechan)) { 06235 CHANNEL_DEADLOCK_AVOIDANCE(original); 06236 } 06237 06238 /* Get any transfer masquerade connected line exchange data. */ 06239 xfer_ds = ast_channel_datastore_find(original, &xfer_ds_info, NULL); 06240 if (xfer_ds) { 06241 ast_channel_datastore_remove(original, xfer_ds); 06242 xfer_colp = xfer_ds->data; 06243 } else { 06244 xfer_colp = NULL; 06245 } 06246 06247 /* 06248 * Release any hold on the transferee channel before proceeding 06249 * with the masquerade. 06250 */ 06251 if (xfer_colp && xfer_colp->transferee_held) { 06252 ast_indicate(clonechan, AST_CONTROL_UNHOLD); 06253 } 06254 06255 /* clear the masquerade channels */ 06256 original->masq = NULL; 06257 clonechan->masqr = NULL; 06258 06259 /* unlink from channels container as name (which is the hash value) will change */ 06260 ao2_unlink(channels, original); 06261 ao2_unlink(channels, clonechan); 06262 06263 ast_debug(4, "Actually Masquerading %s(%d) into the structure of %s(%d)\n", 06264 clonechan->name, clonechan->_state, original->name, original->_state); 06265 06266 /* 06267 * Stop any visible indiction on the original channel so we can 06268 * transfer it to the clonechan taking the original's place. 06269 */ 06270 visible_indication = original->visible_indication; 06271 ast_indicate(original, -1); 06272 06273 chans[0] = clonechan; 06274 chans[1] = original; 06275 ast_manager_event_multichan(EVENT_FLAG_CALL, "Masquerade", 2, chans, 06276 "Clone: %s\r\n" 06277 "CloneState: %s\r\n" 06278 "Original: %s\r\n" 06279 "OriginalState: %s\r\n", 06280 clonechan->name, ast_state2str(clonechan->_state), original->name, ast_state2str(original->_state)); 06281 06282 /* Having remembered the original read/write formats, we turn off any translation on either 06283 one */ 06284 free_translation(clonechan); 06285 free_translation(original); 06286 06287 /* Save the original name */ 06288 ast_copy_string(orig, original->name, sizeof(orig)); 06289 /* Save the new name */ 06290 ast_copy_string(newn, clonechan->name, sizeof(newn)); 06291 /* Create the masq name */ 06292 snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn); 06293 06294 /* Mangle the name of the clone channel */ 06295 __ast_change_name_nolink(clonechan, masqn); 06296 06297 /* Copy the name from the clone channel */ 06298 __ast_change_name_nolink(original, newn); 06299 06300 /* share linked id's */ 06301 ast_channel_set_linkgroup(original, clonechan); 06302 06303 /* Swap the technologies */ 06304 t = original->tech; 06305 original->tech = clonechan->tech; 06306 clonechan->tech = t; 06307 06308 /* Swap the cdrs */ 06309 cdr = original->cdr; 06310 original->cdr = clonechan->cdr; 06311 clonechan->cdr = cdr; 06312 06313 t_pvt = original->tech_pvt; 06314 original->tech_pvt = clonechan->tech_pvt; 06315 clonechan->tech_pvt = t_pvt; 06316 06317 /* Swap the alertpipes */ 06318 for (i = 0; i < 2; i++) { 06319 x = original->alertpipe[i]; 06320 original->alertpipe[i] = clonechan->alertpipe[i]; 06321 clonechan->alertpipe[i] = x; 06322 } 06323 06324 /* 06325 * Swap the readq's. The end result should be this: 06326 * 06327 * 1) All frames should be on the new (original) channel. 06328 * 2) Any frames that were already on the new channel before this 06329 * masquerade need to be at the end of the readq, after all of the 06330 * frames on the old (clone) channel. 06331 * 3) The alertpipe needs to get poked for every frame that was already 06332 * on the new channel, since we are now using the alert pipe from the 06333 * old (clone) channel. 06334 */ 06335 { 06336 AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq; 06337 AST_LIST_HEAD_SET_NOLOCK(&tmp_readq, NULL); 06338 06339 AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list); 06340 AST_LIST_APPEND_LIST(&original->readq, &clonechan->readq, frame_list); 06341 06342 while ((current = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) { 06343 AST_LIST_INSERT_TAIL(&original->readq, current, frame_list); 06344 if (original->alertpipe[1] > -1) { 06345 int poke = 0; 06346 06347 if (write(original->alertpipe[1], &poke, sizeof(poke)) < 0) { 06348 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 06349 } 06350 } 06351 } 06352 } 06353 06354 /* Swap the raw formats */ 06355 x = original->rawreadformat; 06356 original->rawreadformat = clonechan->rawreadformat; 06357 clonechan->rawreadformat = x; 06358 x = original->rawwriteformat; 06359 original->rawwriteformat = clonechan->rawwriteformat; 06360 clonechan->rawwriteformat = x; 06361 06362 clonechan->_softhangup = AST_SOFTHANGUP_DEV; 06363 06364 /* And of course, so does our current state. Note we need not 06365 call ast_setstate since the event manager doesn't really consider 06366 these separate. We do this early so that the clone has the proper 06367 state of the original channel. */ 06368 origstate = original->_state; 06369 original->_state = clonechan->_state; 06370 clonechan->_state = origstate; 06371 06372 if (clonechan->tech->fixup && clonechan->tech->fixup(original, clonechan)) { 06373 ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clonechan->name); 06374 } 06375 06376 /* Start by disconnecting the original's physical side */ 06377 if (clonechan->tech->hangup && clonechan->tech->hangup(clonechan)) { 06378 ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n"); 06379 res = -1; 06380 goto done; 06381 } 06382 06383 /* Mangle the name of the clone channel */ 06384 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig); /* quick, hide the brains! */ 06385 __ast_change_name_nolink(clonechan, zombn); 06386 06387 /* Update the type. */ 06388 t_pvt = original->monitor; 06389 original->monitor = clonechan->monitor; 06390 clonechan->monitor = t_pvt; 06391 06392 /* Keep the same language. */ 06393 ast_string_field_set(original, language, clonechan->language); 06394 /* Copy the FD's other than the generator fd */ 06395 for (x = 0; x < AST_MAX_FDS; x++) { 06396 if (x != AST_GENERATOR_FD) 06397 ast_channel_set_fd(original, x, clonechan->fds[x]); 06398 } 06399 06400 ast_app_group_update(clonechan, original); 06401 06402 /* Move data stores over */ 06403 if (AST_LIST_FIRST(&clonechan->datastores)) { 06404 struct ast_datastore *ds; 06405 /* We use a safe traversal here because some fixup routines actually 06406 * remove the datastore from the list and free them. 06407 */ 06408 AST_LIST_TRAVERSE_SAFE_BEGIN(&clonechan->datastores, ds, entry) { 06409 if (ds->info->chan_fixup) 06410 ds->info->chan_fixup(ds->data, clonechan, original); 06411 } 06412 AST_LIST_TRAVERSE_SAFE_END; 06413 AST_LIST_APPEND_LIST(&original->datastores, &clonechan->datastores, entry); 06414 } 06415 06416 ast_autochan_new_channel(clonechan, original); 06417 06418 clone_variables(original, clonechan); 06419 /* Presense of ADSI capable CPE follows clone */ 06420 original->adsicpe = clonechan->adsicpe; 06421 /* Bridge remains the same */ 06422 /* CDR fields remain the same */ 06423 /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */ 06424 /* Application and data remain the same */ 06425 /* Clone exception becomes real one, as with fdno */ 06426 ast_set_flag(original, ast_test_flag(clonechan, AST_FLAG_EXCEPTION | AST_FLAG_OUTGOING)); 06427 original->fdno = clonechan->fdno; 06428 /* Schedule context remains the same */ 06429 /* Stream stuff stays the same */ 06430 /* Keep the original state. The fixup code will need to work with it most likely */ 06431 06432 /* 06433 * Just swap the whole structures, nevermind the allocations, 06434 * they'll work themselves out. 06435 */ 06436 exchange.dialed = original->dialed; 06437 original->dialed = clonechan->dialed; 06438 clonechan->dialed = exchange.dialed; 06439 06440 exchange.caller = original->caller; 06441 original->caller = clonechan->caller; 06442 clonechan->caller = exchange.caller; 06443 06444 exchange.connected = original->connected; 06445 original->connected = clonechan->connected; 06446 clonechan->connected = exchange.connected; 06447 06448 exchange.redirecting = original->redirecting; 06449 original->redirecting = clonechan->redirecting; 06450 clonechan->redirecting = exchange.redirecting; 06451 06452 report_new_callerid(original); 06453 06454 /* Restore original timing file descriptor */ 06455 ast_channel_set_fd(original, AST_TIMING_FD, original->timingfd); 06456 06457 /* Our native formats are different now */ 06458 original->nativeformats = clonechan->nativeformats; 06459 06460 /* Context, extension, priority, app data, jump table, remain the same */ 06461 /* pvt switches. pbx stays the same, as does next */ 06462 06463 /* Set the write format */ 06464 ast_set_write_format(original, wformat); 06465 06466 /* Set the read format */ 06467 ast_set_read_format(original, rformat); 06468 06469 /* Copy the music class */ 06470 ast_string_field_set(original, musicclass, clonechan->musicclass); 06471 06472 /* copy over accuntcode and set peeraccount across the bridge */ 06473 ast_string_field_set(original, accountcode, S_OR(clonechan->accountcode, "")); 06474 if (original->_bridge) { 06475 /* XXX - should we try to lock original->_bridge here? */ 06476 ast_string_field_set(original->_bridge, peeraccount, S_OR(clonechan->accountcode, "")); 06477 ast_cel_report_event(original, AST_CEL_BRIDGE_UPDATE, NULL, NULL, NULL); 06478 } 06479 06480 ast_debug(1, "Putting channel %s in %s/%s formats\n", original->name, 06481 ast_getformatname(wformat), ast_getformatname(rformat)); 06482 06483 /* Okay. Last thing is to let the channel driver know about all this mess, so he 06484 can fix up everything as best as possible */ 06485 if (original->tech->fixup) { 06486 if (original->tech->fixup(clonechan, original)) { 06487 ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n", 06488 original->tech->type, original->name); 06489 res = -1; 06490 goto done; 06491 } 06492 } else 06493 ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)! Bad things may happen.\n", 06494 original->tech->type, original->name); 06495 06496 /* 06497 * If an indication is currently playing, maintain it on the channel 06498 * that is taking the place of original 06499 * 06500 * This is needed because the masquerade is swapping out in the internals 06501 * of this channel, and the new channel private data needs to be made 06502 * aware of the current visible indication (RINGING, CONGESTION, etc.) 06503 */ 06504 if (visible_indication) { 06505 ast_indicate(original, visible_indication); 06506 } 06507 06508 /* Now, at this point, the "clone" channel is totally F'd up. We mark it as 06509 a zombie so nothing tries to touch it. If it's already been marked as a 06510 zombie, then free it now (since it already is considered invalid). */ 06511 if (ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) { 06512 ast_debug(1, "Destroying channel clone '%s'\n", clonechan->name); 06513 ast_channel_unlock(clonechan); 06514 ast_manager_event(clonechan, EVENT_FLAG_CALL, "Hangup", 06515 "Channel: %s\r\n" 06516 "Uniqueid: %s\r\n" 06517 "Cause: %d\r\n" 06518 "Cause-txt: %s\r\n", 06519 clonechan->name, 06520 clonechan->uniqueid, 06521 clonechan->hangupcause, 06522 ast_cause2str(clonechan->hangupcause) 06523 ); 06524 clonechan = ast_channel_release(clonechan); 06525 } else { 06526 ast_debug(1, "Released clone lock on '%s'\n", clonechan->name); 06527 ast_set_flag(clonechan, AST_FLAG_ZOMBIE); 06528 ast_queue_frame(clonechan, &ast_null_frame); 06529 } 06530 06531 /* Signal any blocker */ 06532 if (ast_test_flag(original, AST_FLAG_BLOCKING)) 06533 pthread_kill(original->blocker, SIGURG); 06534 ast_debug(1, "Done Masquerading %s (%d)\n", original->name, original->_state); 06535 06536 if ((bridged = ast_bridged_channel(original))) { 06537 ast_channel_lock(bridged); 06538 ast_indicate(bridged, AST_CONTROL_SRCCHANGE); 06539 ast_channel_unlock(bridged); 06540 } 06541 ast_indicate(original, AST_CONTROL_SRCCHANGE); 06542 06543 if (xfer_colp) { 06544 /* 06545 * After the masquerade, the original channel pointer actually 06546 * points to the new transferee channel and the bridged channel 06547 * is still the intended transfer target party. 06548 */ 06549 masquerade_colp_transfer(original, xfer_colp); 06550 } 06551 06552 done: 06553 if (xfer_ds) { 06554 ast_datastore_free(xfer_ds); 06555 } 06556 /* it is possible for the clone channel to disappear during this */ 06557 if (clonechan) { 06558 ast_channel_unlock(original); 06559 ast_channel_unlock(clonechan); 06560 ao2_link(channels, clonechan); 06561 ao2_link(channels, original); 06562 } else { 06563 ast_channel_unlock(original); 06564 ao2_link(channels, original); 06565 } 06566 06567 ao2_unlock(channels); 06568 06569 return res; 06570 }
struct ast_channel* ast_dummy_channel_alloc | ( | void | ) |
Create a fake channel structure.
NULL | failure | |
non-NULL | successfully allocated channel |
Definition at line 1320 of file channel.c.
References __ao2_alloc_debug(), ao2_alloc, ast_channel_unref, ast_dummy_channel_destructor(), AST_LIST_HEAD_INIT_NOLOCK, and ast_string_field_init.
Referenced by acf_odbc_read(), acf_odbc_write(), action_getvar(), ast_add_extension2_lockopt(), ast_cel_fabricate_channel_from_event(), ast_pbx_outgoing_cdr_failed(), ast_str_substitute_variables_full(), custom_log(), make_email_file(), manager_log(), pbx_substitute_variables_helper_full(), rotate_file(), sendmail(), sendpage(), syslog_log(), and write_cdr().
01322 { 01323 struct ast_channel *tmp; 01324 struct varshead *headp; 01325 01326 #if defined(REF_DEBUG) 01327 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel", 01328 file, line, function, 1); 01329 #elif defined(__AST_DEBUG_MALLOC) 01330 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel", 01331 file, line, function, 0); 01332 #else 01333 tmp = ao2_alloc(sizeof(*tmp), ast_dummy_channel_destructor); 01334 #endif 01335 if (!tmp) { 01336 /* Dummy channel structure allocation failure. */ 01337 return NULL; 01338 } 01339 01340 if ((ast_string_field_init(tmp, 128))) { 01341 return ast_channel_unref(tmp); 01342 } 01343 01344 headp = &tmp->varshead; 01345 AST_LIST_HEAD_INIT_NOLOCK(headp); 01346 01347 return tmp; 01348 }
static int ast_fdisset | ( | struct pollfd * | pfds, | |
int | fd, | |||
int | maximum, | |||
int * | start | |||
) | [inline, static] |
Helper function for migrating select to poll.
Definition at line 2301 of file channel.h.
References dummy().
02302 { 02303 int x; 02304 int dummy = 0; 02305 02306 if (fd < 0) 02307 return 0; 02308 if (!start) 02309 start = &dummy; 02310 for (x = *start; x < maximum; x++) 02311 if (pfds[x].fd == fd) { 02312 if (x == *start) 02313 (*start)++; 02314 return pfds[x].revents; 02315 } 02316 return 0; 02317 }
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 890 of file channel.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, chanlist::list, chanlist::tech, and ast_channel_tech::type.
Referenced by __ast_channel_alloc_ap(), _ast_device_state(), ast_cc_callback(), and ast_var_channel_types_table().
00891 { 00892 struct chanlist *chanls; 00893 const struct ast_channel_tech *ret = NULL; 00894 00895 AST_RWLIST_RDLOCK(&backends); 00896 00897 AST_RWLIST_TRAVERSE(&backends, chanls, list) { 00898 if (!strcasecmp(name, chanls->tech->type)) { 00899 ret = chanls->tech; 00900 break; 00901 } 00902 } 00903 00904 AST_RWLIST_UNLOCK(&backends); 00905 00906 return ret; 00907 }
ast_group_t ast_get_group | ( | const char * | s | ) |
Definition at line 7464 of file channel.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), LOG_ERROR, LOG_WARNING, and strsep().
Referenced by _parse(), build_device(), build_peer(), config_parse_variables(), func_channel_write_real(), and read_agent_config().
07465 { 07466 char *piece; 07467 char *c; 07468 int start=0, finish=0, x; 07469 ast_group_t group = 0; 07470 07471 if (ast_strlen_zero(s)) 07472 return 0; 07473 07474 c = ast_strdupa(s); 07475 07476 while ((piece = strsep(&c, ","))) { 07477 if (sscanf(piece, "%30d-%30d", &start, &finish) == 2) { 07478 /* Range */ 07479 } else if (sscanf(piece, "%30d", &start)) { 07480 /* Just one */ 07481 finish = start; 07482 } else { 07483 ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece); 07484 continue; 07485 } 07486 for (x = start; x <= finish; x++) { 07487 if ((x > 63) || (x < 0)) { 07488 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x); 07489 } else 07490 group |= ((ast_group_t) 1 << x); 07491 } 07492 } 07493 return group; 07494 }
int ast_hangup | ( | struct ast_channel * | chan | ) |
Hang up a channel.
chan | channel to hang up |
Definition at line 2658 of file channel.c.
References ao2_unlink, ast_assert, ast_audiohook_detach_list(), ast_autoservice_stop(), ast_cause2str(), ast_cc_offer(), ast_cdr_detach(), ast_cdr_end(), AST_CDR_FLAG_BRIDGED, AST_CDR_FLAG_DIALED, AST_CDR_FLAG_POST_DISABLED, AST_CDR_NULL, AST_CEL_HANGUP, ast_cel_report_event(), ast_channel_lock, ast_channel_release(), ast_channel_unlock, ast_closestream(), ast_debug, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_framehook_list_destroy(), ast_log(), ast_manager_event, ast_set_flag, ast_test_flag, ast_channel::audiohooks, ast_channel::blocker, ast_channel::blockproc, ast_channel::caller, ast_channel::cdr, chanlist::chan, channels, ast_cdr::disposition, EVENT_FLAG_CALL, free_translation(), ast_channel::generator, ast_channel::generatordata, ast_channel_tech::hangup, ast_channel::hangupcause, ast_channel::hangupsource, ast_party_caller::id, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::name, ast_party_id::name, ast_party_id::number, pbx_builtin_getvar_helper(), ast_generator::release, S_COR, S_OR, ast_channel::sched, sched_context_destroy(), ast_party_number::str, ast_party_name::str, ast_channel::stream, ast_channel::tech, ast_channel::uniqueid, ast_party_number::valid, ast_party_name::valid, and ast_channel::vstream.
Referenced by __analog_handle_event(), __analog_ss_thread(), __ast_request_and_dial(), __oh323_new(), action_bridge(), alsa_new(), analog_handle_init_event(), analog_ss_thread(), answer_exec_run(), app_exec(), ast_async_goto(), ast_call_forward(), ast_dial_destroy(), ast_dial_hangup(), ast_iax2_new(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pbx_run_app(), async_wait(), begin_dial_channel(), bridge_call_thread(), bridge_channel_thread(), bridge_exec(), build_conf(), builtin_atxfer(), chanavail_exec(), check_compat(), check_goto_on_transfer(), clear_caller(), conf_run(), connect_link(), console_new(), dahdi_handle_event(), dahdi_new(), destroy_conference_bridge(), dial_exec_full(), dial_transfer(), do_forward(), do_hang(), do_idle_thread(), feature_attended_transfer(), feature_request_and_dial(), findmeexec(), generic_recall(), gtalk_new(), handle_call_forward(), handle_callforward_button(), handle_enbloc_call_message(), handle_frame(), handle_frame_ownerless(), handle_hd_hf(), handle_init_event(), handle_invite_replaces(), handle_offhook_message(), handle_request_invite(), handle_soft_key_event_message(), handle_stimulus_message(), handle_timeout_trip(), handle_transfer_button(), HandleCallOutgoing(), hangup_chan(), hangupcalls(), hanguptree(), iax2_request(), iax_park(), iax_park_thread(), jingle_new(), local_hangup(), manage_parkinglot(), mgcp_new(), mgcp_ss(), monitor_dial(), mwi_thread(), my_distinctive_ring(), my_handle_notify_message(), nbs_new(), oss_new(), park_exec_full(), parkandannounce_exec(), phone_new(), play_sound_file(), pri_dchannel(), pri_ss_thread(), rpt(), rpt_call(), rpt_tele_thread(), sip_new(), sip_park(), sip_park_thread(), skinny_new(), skinny_ss(), ss7_start_call(), unistim_new(), usbradio_new(), and wait_for_winner().
02659 { 02660 int res = 0; 02661 char extra_str[64]; /* used for cel logging below */ 02662 02663 /* Don't actually hang up a channel that will masquerade as someone else, or 02664 if someone is going to masquerade as us */ 02665 ast_channel_lock(chan); 02666 02667 if (chan->audiohooks) { 02668 ast_audiohook_detach_list(chan->audiohooks); 02669 chan->audiohooks = NULL; 02670 } 02671 02672 ast_framehook_list_destroy(chan); 02673 02674 ast_autoservice_stop(chan); 02675 02676 if (chan->masq) { 02677 ast_channel_unlock(chan); 02678 if (ast_do_masquerade(chan)) { 02679 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 02680 } 02681 ast_channel_lock(chan); 02682 } 02683 02684 if (chan->masq) { 02685 ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name); 02686 ast_channel_unlock(chan); 02687 return 0; 02688 } 02689 /* If this channel is one which will be masqueraded into something, 02690 mark it as a zombie already, so we know to free it later */ 02691 if (chan->masqr) { 02692 ast_set_flag(chan, AST_FLAG_ZOMBIE); 02693 ast_channel_unlock(chan); 02694 return 0; 02695 } 02696 ast_channel_unlock(chan); 02697 02698 ao2_unlink(channels, chan); 02699 02700 ast_channel_lock(chan); 02701 free_translation(chan); 02702 /* Close audio stream */ 02703 if (chan->stream) { 02704 ast_closestream(chan->stream); 02705 chan->stream = NULL; 02706 } 02707 /* Close video stream */ 02708 if (chan->vstream) { 02709 ast_closestream(chan->vstream); 02710 chan->vstream = NULL; 02711 } 02712 if (chan->sched) { 02713 sched_context_destroy(chan->sched); 02714 chan->sched = NULL; 02715 } 02716 02717 if (chan->generatordata) /* Clear any tone stuff remaining */ 02718 if (chan->generator && chan->generator->release) 02719 chan->generator->release(chan, chan->generatordata); 02720 chan->generatordata = NULL; 02721 chan->generator = NULL; 02722 02723 snprintf(extra_str, sizeof(extra_str), "%d,%s,%s", chan->hangupcause, chan->hangupsource, S_OR(pbx_builtin_getvar_helper(chan, "DIALSTATUS"), "")); 02724 ast_cel_report_event(chan, AST_CEL_HANGUP, NULL, extra_str, NULL); 02725 02726 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) { 02727 ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd " 02728 "is blocked by thread %ld in procedure %s! Expect a failure\n", 02729 (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc); 02730 ast_assert(ast_test_flag(chan, AST_FLAG_BLOCKING) == 0); 02731 } 02732 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) { 02733 ast_debug(1, "Hanging up channel '%s'\n", chan->name); 02734 if (chan->tech->hangup) 02735 res = chan->tech->hangup(chan); 02736 } else { 02737 ast_debug(1, "Hanging up zombie '%s'\n", chan->name); 02738 } 02739 02740 ast_channel_unlock(chan); 02741 ast_cc_offer(chan); 02742 ast_manager_event(chan, EVENT_FLAG_CALL, "Hangup", 02743 "Channel: %s\r\n" 02744 "Uniqueid: %s\r\n" 02745 "CallerIDNum: %s\r\n" 02746 "CallerIDName: %s\r\n" 02747 "Cause: %d\r\n" 02748 "Cause-txt: %s\r\n", 02749 chan->name, 02750 chan->uniqueid, 02751 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "<unknown>"), 02752 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, "<unknown>"), 02753 chan->hangupcause, 02754 ast_cause2str(chan->hangupcause) 02755 ); 02756 02757 if (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_BRIDGED) && 02758 !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED) && 02759 (chan->cdr->disposition != AST_CDR_NULL || ast_test_flag(chan->cdr, AST_CDR_FLAG_DIALED))) { 02760 ast_channel_lock(chan); 02761 02762 ast_cdr_end(chan->cdr); 02763 ast_cdr_detach(chan->cdr); 02764 chan->cdr = NULL; 02765 ast_channel_unlock(chan); 02766 } 02767 02768 chan = ast_channel_release(chan); 02769 02770 return res; 02771 }
int ast_indicate | ( | struct ast_channel * | chan, | |
int | condition | |||
) |
Indicates condition of channel.
chan | channel to change the indication | |
condition | which condition to indicate on the channel |
Definition at line 4159 of file channel.c.
References ast_indicate_data(), and chanlist::chan.
Referenced by __ast_play_and_record(), agent_new(), alsa_call(), answer_trunk_chan(), ast_bridge_call(), ast_channel_bridge(), ast_do_masquerade(), ast_dtmf_stream(), ast_raw_answer(), attempt_transfer(), builtin_atxfer(), builtin_blindtransfer(), cli_console_answer(), conf_run(), console_call(), dial_exec_full(), do_forward(), feature_request_and_dial(), finishup(), function_remote(), handle_callforward_button(), handle_frame(), handle_recordfile(), handle_request_refer(), local_attended_transfer(), manage_parkinglot(), mgcp_ss(), monitor_dial(), oss_call(), park_call_full(), park_exec_full(), pbx_builtin_busy(), pbx_builtin_congestion(), pbx_builtin_proceeding(), pbx_builtin_progress(), pbx_builtin_ringing(), pbx_builtin_waitexten(), queue_exec(), rna(), rpt(), rpt_exec(), say_periodic_announcement(), say_position(), send_waveform_to_channel(), skinny_ss(), sla_handle_hold_event(), sla_station_exec(), and sla_trunk_exec().
04160 { 04161 return ast_indicate_data(chan, condition, NULL, 0); 04162 }
int ast_indicate_data | ( | struct ast_channel * | chan, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) |
Indicates condition of channel, with payload.
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 4211 of file channel.c.
References ast_channel::_state, _XXX_AST_CONTROL_T38, ast_channel_lock, ast_channel_set_connected_line(), ast_channel_set_redirecting(), ast_channel_unlock, ast_check_hangup(), ast_connected_line_parse_data(), AST_CONTROL_ANSWER, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CC, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_END_OF_Q, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_READ_ACTION, AST_CONTROL_REDIRECTING, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_TRANSFER, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, AST_CONTROL_WINK, ast_debug, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, ast_framehook_list_is_empty(), ast_framehook_list_read_event(), ast_frdup(), ast_frfree, ast_get_indication_tone(), ast_log(), ast_party_connected_line_free(), ast_party_connected_line_set_init(), ast_party_redirecting_free(), ast_party_redirecting_set_init(), ast_playtones_start(), ast_playtones_stop(), ast_redirecting_parse_data(), AST_STATE_UP, ast_test_flag, ast_tone_zone_sound_unref(), chanlist::chan, 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_parkinglot(), park_call_full(), pbx_builtin_waitexten(), receivefax_t38_init(), remote_bridge_loop(), sendfax_t38_init(), set_fax_t38_caps(), transmit_audio(), transmit_t38(), and wait_for_answer().
04213 { 04214 /* By using an enum, we'll get compiler warnings for values not handled 04215 * in switch statements. */ 04216 enum ast_control_frame_type condition = _condition; 04217 struct ast_tone_zone_sound *ts = NULL; 04218 int res; 04219 /* this frame is used by framehooks. if it is set, we must free it at the end of this function */ 04220 struct ast_frame *awesome_frame = NULL; 04221 04222 ast_channel_lock(chan); 04223 04224 /* Don't bother if the channel is about to go away, anyway. */ 04225 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 04226 res = -1; 04227 goto indicate_cleanup; 04228 } 04229 04230 if (!ast_framehook_list_is_empty(chan->framehooks)) { 04231 /* Do framehooks now, do it, go, go now */ 04232 struct ast_frame frame = { 04233 .frametype = AST_FRAME_CONTROL, 04234 .subclass.integer = condition, 04235 .data.ptr = (void *) data, /* this cast from const is only okay because we do the ast_frdup below */ 04236 .datalen = datalen 04237 }; 04238 04239 /* we have now committed to freeing this frame */ 04240 awesome_frame = ast_frdup(&frame); 04241 04242 /* who knows what we will get back! the anticipation is killing me. */ 04243 if (!(awesome_frame = ast_framehook_list_read_event(chan->framehooks, &frame))) { 04244 res = 0; 04245 goto indicate_cleanup; 04246 } 04247 04248 condition = awesome_frame->subclass.integer; 04249 data = awesome_frame->data.ptr; 04250 datalen = awesome_frame->datalen; 04251 } 04252 04253 switch (condition) { 04254 case AST_CONTROL_CONNECTED_LINE: 04255 { 04256 struct ast_party_connected_line connected; 04257 04258 ast_party_connected_line_set_init(&connected, &chan->connected); 04259 res = ast_connected_line_parse_data(data, datalen, &connected); 04260 if (!res) { 04261 ast_channel_set_connected_line(chan, &connected, NULL); 04262 } 04263 ast_party_connected_line_free(&connected); 04264 } 04265 break; 04266 04267 case AST_CONTROL_REDIRECTING: 04268 { 04269 struct ast_party_redirecting redirecting; 04270 04271 ast_party_redirecting_set_init(&redirecting, &chan->redirecting); 04272 res = ast_redirecting_parse_data(data, datalen, &redirecting); 04273 if (!res) { 04274 ast_channel_set_redirecting(chan, &redirecting, NULL); 04275 } 04276 ast_party_redirecting_free(&redirecting); 04277 } 04278 break; 04279 04280 default: 04281 break; 04282 } 04283 04284 if (is_visible_indication(condition)) { 04285 /* A new visible indication is requested. */ 04286 chan->visible_indication = condition; 04287 } else if (condition == AST_CONTROL_UNHOLD || _condition < 0) { 04288 /* Visible indication is cleared/stopped. */ 04289 chan->visible_indication = 0; 04290 } 04291 04292 if (chan->tech->indicate) { 04293 /* See if the channel driver can handle this condition. */ 04294 res = chan->tech->indicate(chan, condition, data, datalen); 04295 } else { 04296 res = -1; 04297 } 04298 04299 if (!res) { 04300 /* The channel driver successfully handled this indication */ 04301 res = 0; 04302 goto indicate_cleanup; 04303 } 04304 04305 /* The channel driver does not support this indication, let's fake 04306 * it by doing our own tone generation if applicable. */ 04307 04308 /*!\note If we compare the enumeration type, which does not have any 04309 * negative constants, the compiler may optimize this code away. 04310 * Therefore, we must perform an integer comparison here. */ 04311 if (_condition < 0) { 04312 /* Stop any tones that are playing */ 04313 ast_playtones_stop(chan); 04314 res = 0; 04315 goto indicate_cleanup; 04316 } 04317 04318 /* Handle conditions that we have tones for. */ 04319 switch (condition) { 04320 case _XXX_AST_CONTROL_T38: 04321 /* deprecated T.38 control frame */ 04322 res = -1; 04323 goto indicate_cleanup; 04324 case AST_CONTROL_T38_PARAMETERS: 04325 /* there is no way to provide 'default' behavior for these 04326 * control frames, so we need to return failure, but there 04327 * is also no value in the log message below being emitted 04328 * since failure to handle these frames is not an 'error' 04329 * so just return right now. in addition, we want to return 04330 * whatever value the channel driver returned, in case it 04331 * has some meaning.*/ 04332 goto indicate_cleanup; 04333 case AST_CONTROL_RINGING: 04334 ts = ast_get_indication_tone(chan->zone, "ring"); 04335 /* It is common practice for channel drivers to return -1 if trying 04336 * to indicate ringing on a channel which is up. The idea is to let the 04337 * core generate the ringing inband. However, we don't want the 04338 * warning message about not being able to handle the specific indication 04339 * to print nor do we want ast_indicate_data to return an "error" for this 04340 * condition 04341 */ 04342 if (chan->_state == AST_STATE_UP) { 04343 res = 0; 04344 } 04345 break; 04346 case AST_CONTROL_BUSY: 04347 ts = ast_get_indication_tone(chan->zone, "busy"); 04348 break; 04349 case AST_CONTROL_CONGESTION: 04350 ts = ast_get_indication_tone(chan->zone, "congestion"); 04351 break; 04352 case AST_CONTROL_PROGRESS: 04353 case AST_CONTROL_PROCEEDING: 04354 case AST_CONTROL_VIDUPDATE: 04355 case AST_CONTROL_SRCUPDATE: 04356 case AST_CONTROL_SRCCHANGE: 04357 case AST_CONTROL_RADIO_KEY: 04358 case AST_CONTROL_RADIO_UNKEY: 04359 case AST_CONTROL_OPTION: 04360 case AST_CONTROL_WINK: 04361 case AST_CONTROL_FLASH: 04362 case AST_CONTROL_OFFHOOK: 04363 case AST_CONTROL_TAKEOFFHOOK: 04364 case AST_CONTROL_ANSWER: 04365 case AST_CONTROL_HANGUP: 04366 case AST_CONTROL_RING: 04367 case AST_CONTROL_HOLD: 04368 case AST_CONTROL_UNHOLD: 04369 case AST_CONTROL_TRANSFER: 04370 case AST_CONTROL_CONNECTED_LINE: 04371 case AST_CONTROL_REDIRECTING: 04372 case AST_CONTROL_CC: 04373 case AST_CONTROL_READ_ACTION: 04374 case AST_CONTROL_AOC: 04375 case AST_CONTROL_END_OF_Q: 04376 /* Nothing left to do for these. */ 04377 res = 0; 04378 break; 04379 } 04380 04381 if (ts) { 04382 /* We have a tone to play, yay. */ 04383 ast_debug(1, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition); 04384 res = ast_playtones_start(chan, 0, ts->data, 1); 04385 ts = ast_tone_zone_sound_unref(ts); 04386 } 04387 04388 if (res) { 04389 /* not handled */ 04390 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name); 04391 } 04392 04393 indicate_cleanup: 04394 ast_channel_unlock(chan); 04395 if (awesome_frame) { 04396 ast_frfree(awesome_frame); 04397 } 04398 04399 return res; 04400 }
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 4144 of file channel.c.
References ast_opt_internal_timing, chanlist::chan, and ast_channel::timingfd.
Referenced by add_sdp(), and ast_read_generator_actions().
04145 { 04146 return (ast_opt_internal_timing && chan->timingfd > -1); 04147 }
int ast_is_deferrable_frame | ( | const struct ast_frame * | frame | ) |
Should we keep this frame for later?
There are functions such as ast_safe_sleep which will service a channel to ensure that it does not have a large backlog of queued frames. When this happens, we want to hold on to specific frame types and just drop others. This function will tell if the frame we just read should be held onto.
frame | The frame we just read |
1 | frame should be kept | |
0 | frame should be dropped |
Definition at line 1728 of file channel.c.
References AST_FRAME_CNG, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_HTML, AST_FRAME_IAX, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, and ast_frame::frametype.
Referenced by ast_safe_sleep_conditional(), autoservice_run(), and feature_request_and_dial().
01729 { 01730 /* Do not add a default entry in this switch statement. Each new 01731 * frame type should be addressed directly as to whether it should 01732 * be queued up or not. 01733 */ 01734 switch (frame->frametype) { 01735 case AST_FRAME_CONTROL: 01736 case AST_FRAME_TEXT: 01737 case AST_FRAME_IMAGE: 01738 case AST_FRAME_HTML: 01739 return 1; 01740 01741 case AST_FRAME_DTMF_END: 01742 case AST_FRAME_DTMF_BEGIN: 01743 case AST_FRAME_VOICE: 01744 case AST_FRAME_VIDEO: 01745 case AST_FRAME_NULL: 01746 case AST_FRAME_IAX: 01747 case AST_FRAME_CNG: 01748 case AST_FRAME_MODEM: 01749 return 0; 01750 } 01751 return 0; 01752 }
void ast_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 2179 of file channel.c.
References ast_party_caller::ani, ast_party_caller::ani2, ast_party_id_copy(), and ast_party_caller::id.
Referenced by ast_call_forward(), and do_forward().
02180 { 02181 if (dest == src) { 02182 /* Don't copy to self */ 02183 return; 02184 } 02185 02186 ast_party_id_copy(&dest->id, &src->id); 02187 ast_party_id_copy(&dest->ani, &src->ani); 02188 dest->ani2 = src->ani2; 02189 }
void ast_party_caller_free | ( | struct ast_party_caller * | doomed | ) |
Destroy the caller party contents.
doomed | The caller party to destroy. |
Definition at line 2205 of file channel.c.
References ast_party_caller::ani, ast_party_id_free(), and ast_party_caller::id.
Referenced by ast_channel_destructor(), ast_dummy_channel_destructor(), callerid_write(), dial_trunk(), and sla_ring_station().
02206 { 02207 ast_party_id_free(&doomed->id); 02208 ast_party_id_free(&doomed->ani); 02209 }
void ast_party_caller_init | ( | struct ast_party_caller * | init | ) |
Initialize the given caller structure.
init | Caller structure to initialize. |
Definition at line 2172 of file channel.c.
References ast_party_caller::ani, ast_party_caller::ani2, ast_party_id_init(), and ast_party_caller::id.
Referenced by __ast_channel_alloc_ap(), dial_trunk(), sig_pri_set_caller_id(), sig_ss7_set_caller_id(), and sla_ring_station().
02173 { 02174 ast_party_id_init(&init->id); 02175 ast_party_id_init(&init->ani); 02176 init->ani2 = 0; 02177 }
void ast_party_caller_set | ( | struct ast_party_caller * | dest, | |
const struct ast_party_caller * | src, | |||
const struct ast_set_party_caller * | update | |||
) |
Set the caller information based on another caller source.
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 2198 of file channel.c.
References ast_party_caller::ani, ast_party_caller::ani2, ast_party_id_set(), ast_party_caller::id, and update().
Referenced by ast_channel_set_caller(), ast_channel_set_caller_event(), and callerid_write().
02199 { 02200 ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL); 02201 ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL); 02202 dest->ani2 = src->ani2; 02203 }
void ast_party_caller_set_init | ( | struct ast_party_caller * | init, | |
const struct ast_party_caller * | guide | |||
) |
Initialize the given caller structure using the given guide for a set update operation.
init | Caller structure to initialize. | |
guide | Source caller to use as a guide in initializing. |
Definition at line 2191 of file channel.c.
References ast_party_caller::ani, ast_party_caller::ani2, ast_party_id_set_init(), and ast_party_caller::id.
Referenced by callerid_write(), dial_exec_full(), misdn_update_caller_id(), ring_entry(), and sig_pri_handle_subcmds().
02192 { 02193 ast_party_id_set_init(&init->id, &guide->id); 02194 ast_party_id_set_init(&init->ani, &guide->ani); 02195 init->ani2 = guide->ani2; 02196 }
void ast_party_connected_line_collect_caller | ( | struct ast_party_connected_line * | connected, | |
struct ast_party_caller * | caller | |||
) |
Collect the caller party information into a connected line structure.
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 2248 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.
Referenced by ast_pickup_call().
02249 { 02250 connected->id = caller->id; 02251 connected->ani = caller->ani; 02252 connected->ani2 = caller->ani2; 02253 connected->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN; 02254 }
void ast_party_connected_line_copy | ( | struct ast_party_connected_line * | dest, | |
const struct ast_party_connected_line * | src | |||
) |
Copy the source connected line information to the destination connected line.
dest | Destination connected line | |
src | Source connected line |
Definition at line 2219 of file channel.c.
References ast_party_connected_line::ani, ast_party_connected_line::ani2, ast_party_id_copy(), ast_party_connected_line::id, and ast_party_connected_line::source.
Referenced by __ast_read(), ast_call_forward(), ast_channel_connected_line_macro(), builtin_atxfer(), dial_exec_full(), do_forward(), local_attended_transfer(), misdn_attempt_transfer(), party_connected_line_copy_transfer(), and pickup_do().
02220 { 02221 if (dest == src) { 02222 /* Don't copy to self */ 02223 return; 02224 } 02225 02226 ast_party_id_copy(&dest->id, &src->id); 02227 ast_party_id_copy(&dest->ani, &src->ani); 02228 dest->ani2 = src->ani2; 02229 dest->source = src->source; 02230 }
void ast_party_connected_line_free | ( | struct ast_party_connected_line * | doomed | ) |
Destroy the connected line information contents.
doomed | The connected line information to destroy. |
Definition at line 2256 of file channel.c.
References ast_party_connected_line::ani, ast_party_id_free(), and ast_party_connected_line::id.
Referenced by __ast_read(), ast_channel_destructor(), ast_dummy_channel_destructor(), ast_indicate_data(), atxfer_fail_cleanup(), builtin_atxfer(), callattempt_free(), chanlist_free(), connectedline_write(), feature_request_and_dial(), local_attended_transfer(), misdn_attempt_transfer(), pickup_do(), sig_pri_handle_subcmds(), socket_process(), wait_for_answer(), and xfer_ds_destroy().
02257 { 02258 ast_party_id_free(&doomed->id); 02259 ast_party_id_free(&doomed->ani); 02260 }
void ast_party_connected_line_init | ( | struct ast_party_connected_line * | init | ) |
Initialize the given connected line structure.
init | Connected line structure to initialize. |
Definition at line 2211 of file channel.c.
References ast_party_connected_line::ani, ast_party_connected_line::ani2, AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN, ast_party_id_init(), ast_party_connected_line::id, and ast_party_connected_line::source.
Referenced by __ast_channel_alloc_ap(), __ast_read(), builtin_atxfer(), handle_request_invite(), handle_request_update(), handle_response_invite(), local_attended_transfer(), misdn_attempt_transfer(), misdn_queue_connected_line_update(), pickup_do(), sig_pri_handle_subcmds(), socket_process(), and wait_for_answer().
02212 { 02213 ast_party_id_init(&init->id); 02214 ast_party_id_init(&init->ani); 02215 init->ani2 = 0; 02216 init->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN; 02217 }
void ast_party_connected_line_set | ( | struct ast_party_connected_line * | dest, | |
const struct ast_party_connected_line * | src, | |||
const struct ast_set_party_connected_line * | update | |||
) |
Set the connected line information based on another connected line source.
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 2240 of file channel.c.
References ast_party_connected_line::ani, ast_party_connected_line::ani2, ast_party_id_set(), ast_party_connected_line::id, ast_party_connected_line::source, and update().
Referenced by ast_channel_set_connected_line().
02241 { 02242 ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL); 02243 ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL); 02244 dest->ani2 = src->ani2; 02245 dest->source = src->source; 02246 }
void ast_party_connected_line_set_init | ( | struct ast_party_connected_line * | init, | |
const struct ast_party_connected_line * | guide | |||
) |
Initialize the given connected line structure using the given guide for a set update operation.
init | Connected line structure to initialize. | |
guide | Source connected line to use as a guide in initializing. |
Definition at line 2232 of file channel.c.
References ast_party_connected_line::ani, ast_party_connected_line::ani2, ast_party_id_set_init(), ast_party_connected_line::id, and ast_party_connected_line::source.
Referenced by __ast_request_and_dial(), ast_indicate_data(), connectedline_write(), dial_exec_full(), and feature_request_and_dial().
02233 { 02234 ast_party_id_set_init(&init->id, &guide->id); 02235 ast_party_id_set_init(&init->ani, &guide->ani); 02236 init->ani2 = guide->ani2; 02237 init->source = guide->source; 02238 }
void ast_party_dialed_copy | ( | struct ast_party_dialed * | dest, | |
const struct ast_party_dialed * | src | |||
) |
Copy the source dialed party information to the destination dialed party.
dest | Destination dialed party | |
src | Source dialed party |
Definition at line 2130 of file channel.c.
References ast_free, ast_party_subaddress_copy(), ast_strdup, ast_party_dialed::number, ast_party_dialed::plan, ast_party_dialed::str, ast_party_dialed::subaddress, and ast_party_dialed::transit_network_select.
Referenced by local_call().
02131 { 02132 if (dest == src) { 02133 /* Don't copy to self */ 02134 return; 02135 } 02136 02137 ast_free(dest->number.str); 02138 dest->number.str = ast_strdup(src->number.str); 02139 dest->number.plan = src->number.plan; 02140 ast_party_subaddress_copy(&dest->subaddress, &src->subaddress); 02141 dest->transit_network_select = src->transit_network_select; 02142 }
void ast_party_dialed_free | ( | struct ast_party_dialed * | doomed | ) |
Destroy the dialed party contents.
doomed | The dialed party to destroy. |
Definition at line 2165 of file channel.c.
References ast_free, ast_party_subaddress_free(), ast_party_dialed::number, ast_party_dialed::str, and ast_party_dialed::subaddress.
Referenced by ast_channel_destructor(), ast_dummy_channel_destructor(), and callerid_write().
02166 { 02167 ast_free(doomed->number.str); 02168 doomed->number.str = NULL; 02169 ast_party_subaddress_free(&doomed->subaddress); 02170 }
void ast_party_dialed_init | ( | struct ast_party_dialed * | init | ) |
Initialize the given dialed structure.
init | Dialed structure to initialize. |
Definition at line 2122 of file channel.c.
References ast_party_subaddress_init(), ast_party_dialed::number, ast_party_dialed::plan, ast_party_dialed::str, ast_party_dialed::subaddress, and ast_party_dialed::transit_network_select.
Referenced by __ast_channel_alloc_ap().
02123 { 02124 init->number.str = NULL; 02125 init->number.plan = 0;/* Unknown */ 02126 ast_party_subaddress_init(&init->subaddress); 02127 init->transit_network_select = 0; 02128 }
void ast_party_dialed_set | ( | struct ast_party_dialed * | dest, | |
const struct ast_party_dialed * | src | |||
) |
Set the dialed information based on another dialed source.
dest | The dialed one wishes to update | |
src | The new dialed values to update the dest |
Definition at line 2152 of file channel.c.
References ast_free, ast_party_subaddress_set(), ast_strdup, ast_party_dialed::number, ast_party_dialed::plan, ast_party_dialed::str, ast_party_dialed::subaddress, and ast_party_dialed::transit_network_select.
Referenced by callerid_write().
02153 { 02154 if (src->number.str && src->number.str != dest->number.str) { 02155 ast_free(dest->number.str); 02156 dest->number.str = ast_strdup(src->number.str); 02157 } 02158 dest->number.plan = src->number.plan; 02159 02160 ast_party_subaddress_set(&dest->subaddress, &src->subaddress); 02161 02162 dest->transit_network_select = src->transit_network_select; 02163 }
void ast_party_dialed_set_init | ( | struct ast_party_dialed * | init, | |
const struct ast_party_dialed * | guide | |||
) |
Initialize the given dialed structure using the given guide for a set update operation.
init | Caller structure to initialize. | |
guide | Source dialed to use as a guide in initializing. |
Definition at line 2144 of file channel.c.
References ast_party_subaddress_set_init(), ast_party_dialed::number, ast_party_dialed::plan, ast_party_dialed::str, ast_party_dialed::subaddress, and ast_party_dialed::transit_network_select.
Referenced by callerid_write().
02145 { 02146 init->number.str = NULL; 02147 init->number.plan = guide->number.plan; 02148 ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress); 02149 init->transit_network_select = guide->transit_network_select; 02150 }
void ast_party_id_copy | ( | struct ast_party_id * | dest, | |
const struct ast_party_id * | src | |||
) |
Copy the source party id information to the destination party id.
dest | Destination party id | |
src | Source party id |
Definition at line 2001 of file channel.c.
References ast_free, ast_party_name_copy(), ast_party_number_copy(), ast_party_subaddress_copy(), ast_strdup, ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, and ast_party_id::tag.
Referenced by ast_connected_line_copy_from_caller(), ast_connected_line_copy_to_caller(), ast_party_caller_copy(), ast_party_connected_line_copy(), and ast_party_redirecting_copy().
02002 { 02003 if (dest == src) { 02004 /* Don't copy to self */ 02005 return; 02006 } 02007 02008 ast_party_name_copy(&dest->name, &src->name); 02009 ast_party_number_copy(&dest->number, &src->number); 02010 ast_party_subaddress_copy(&dest->subaddress, &src->subaddress); 02011 02012 ast_free(dest->tag); 02013 dest->tag = ast_strdup(src->tag); 02014 }
void ast_party_id_free | ( | struct ast_party_id * | doomed | ) |
Destroy the party id contents.
doomed | The party id to destroy. |
Definition at line 2047 of file channel.c.
References ast_free, ast_party_name_free(), ast_party_number_free(), ast_party_subaddress_free(), ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, and ast_party_id::tag.
Referenced by ast_party_caller_free(), ast_party_connected_line_free(), ast_party_redirecting_free(), and do_forward().
02048 { 02049 ast_party_name_free(&doomed->name); 02050 ast_party_number_free(&doomed->number); 02051 ast_party_subaddress_free(&doomed->subaddress); 02052 02053 ast_free(doomed->tag); 02054 doomed->tag = NULL; 02055 }
void ast_party_id_init | ( | struct ast_party_id * | init | ) |
Initialize the given party id structure.
init | Party id structure to initialize. |
Definition at line 1993 of file channel.c.
References ast_party_name_init(), ast_party_number_init(), ast_party_subaddress_init(), ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, and ast_party_id::tag.
Referenced by ast_party_caller_init(), ast_party_connected_line_init(), ast_party_redirecting_init(), and do_forward().
01994 { 01995 ast_party_name_init(&init->name); 01996 ast_party_number_init(&init->number); 01997 ast_party_subaddress_init(&init->subaddress); 01998 init->tag = NULL; 01999 }
int ast_party_id_presentation | ( | const struct ast_party_id * | id | ) |
Determine the overall presentation value for the given party.
id | Party to determine the overall presentation value. |
Definition at line 2057 of file channel.c.
References AST_PRES_ALLOWED, AST_PRES_NUMBER_TYPE, AST_PRES_RESTRICTED, AST_PRES_RESTRICTION, AST_PRES_UNAVAILABLE, AST_PRES_USER_NUMBER_UNSCREENED, and id.
Referenced by add_rpid(), ast_str_retrieve_variable(), ast_var_channels_table(), callerpres_read(), iax2_call(), initreqprep(), my_set_callerid(), oh323_call(), party_id_build_data(), party_id_read(), redirecting_read(), report_new_callerid(), setup_env(), sig_pri_handle_subcmds(), sip_call(), and socket_process().
02058 { 02059 int number_priority; 02060 int number_value; 02061 int number_screening; 02062 int name_priority; 02063 int name_value; 02064 02065 /* Determine name presentation priority. */ 02066 if (!id->name.valid) { 02067 name_value = AST_PRES_UNAVAILABLE; 02068 name_priority = 3; 02069 } else { 02070 name_value = id->name.presentation & AST_PRES_RESTRICTION; 02071 switch (name_value) { 02072 case AST_PRES_RESTRICTED: 02073 name_priority = 0; 02074 break; 02075 case AST_PRES_ALLOWED: 02076 name_priority = 1; 02077 break; 02078 case AST_PRES_UNAVAILABLE: 02079 name_priority = 2; 02080 break; 02081 default: 02082 name_value = AST_PRES_UNAVAILABLE; 02083 name_priority = 3; 02084 break; 02085 } 02086 } 02087 02088 /* Determine number presentation priority. */ 02089 if (!id->number.valid) { 02090 number_screening = AST_PRES_USER_NUMBER_UNSCREENED; 02091 number_value = AST_PRES_UNAVAILABLE; 02092 number_priority = 3; 02093 } else { 02094 number_screening = id->number.presentation & AST_PRES_NUMBER_TYPE; 02095 number_value = id->number.presentation & AST_PRES_RESTRICTION; 02096 switch (number_value) { 02097 case AST_PRES_RESTRICTED: 02098 number_priority = 0; 02099 break; 02100 case AST_PRES_ALLOWED: 02101 number_priority = 1; 02102 break; 02103 case AST_PRES_UNAVAILABLE: 02104 number_priority = 2; 02105 break; 02106 default: 02107 number_screening = AST_PRES_USER_NUMBER_UNSCREENED; 02108 number_value = AST_PRES_UNAVAILABLE; 02109 number_priority = 3; 02110 break; 02111 } 02112 } 02113 02114 /* Select the wining presentation value. */ 02115 if (name_priority < number_priority) { 02116 number_value = name_value; 02117 } 02118 02119 return number_value | number_screening; 02120 }
void ast_party_id_set | ( | struct ast_party_id * | dest, | |
const struct ast_party_id * | src, | |||
const struct ast_set_party_id * | update | |||
) |
Set the source party id information into the destination party id.
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 2024 of file channel.c.
References ast_free, ast_party_name_set(), ast_party_number_set(), ast_party_subaddress_set(), ast_strdup, ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, ast_party_id::tag, and update().
Referenced by ast_party_caller_set(), ast_party_connected_line_set(), and ast_party_redirecting_set().
02025 { 02026 if (dest == src) { 02027 /* Don't set to self */ 02028 return; 02029 } 02030 02031 if (!update || update->name) { 02032 ast_party_name_set(&dest->name, &src->name); 02033 } 02034 if (!update || update->number) { 02035 ast_party_number_set(&dest->number, &src->number); 02036 } 02037 if (!update || update->subaddress) { 02038 ast_party_subaddress_set(&dest->subaddress, &src->subaddress); 02039 } 02040 02041 if (src->tag && src->tag != dest->tag) { 02042 ast_free(dest->tag); 02043 dest->tag = ast_strdup(src->tag); 02044 } 02045 }
void ast_party_id_set_init | ( | struct ast_party_id * | init, | |
const struct ast_party_id * | guide | |||
) |
Initialize the given party id structure using the given guide for a set update operation.
init | Party id structure to initialize. | |
guide | Source party id to use as a guide in initializing. |
Definition at line 2016 of file channel.c.
References ast_party_name_set_init(), ast_party_number_set_init(), ast_party_subaddress_set_init(), ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, and ast_party_id::tag.
Referenced by ast_party_caller_set_init(), ast_party_connected_line_set_init(), and ast_party_redirecting_set_init().
02017 { 02018 ast_party_name_set_init(&init->name, &guide->name); 02019 ast_party_number_set_init(&init->number, &guide->number); 02020 ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress); 02021 init->tag = NULL; 02022 }
void ast_party_name_copy | ( | struct ast_party_name * | dest, | |
const struct ast_party_name * | src | |||
) |
Copy the source party name information to the destination party name.
dest | Destination party name | |
src | Source party name |
Definition at line 1842 of file channel.c.
References ast_free, ast_strdup, ast_party_name::char_set, ast_party_name::presentation, ast_party_name::str, and ast_party_name::valid.
Referenced by ast_party_id_copy().
01843 { 01844 if (dest == src) { 01845 /* Don't copy to self */ 01846 return; 01847 } 01848 01849 ast_free(dest->str); 01850 dest->str = ast_strdup(src->str); 01851 dest->char_set = src->char_set; 01852 dest->presentation = src->presentation; 01853 dest->valid = src->valid; 01854 }
void ast_party_name_free | ( | struct ast_party_name * | doomed | ) |
Destroy the party name contents.
doomed | The party name to destroy. |
Definition at line 1881 of file channel.c.
References ast_free, and ast_party_name::str.
Referenced by __analog_ss_thread(), analog_ss_thread(), ast_party_id_free(), and skinny_newcall().
void ast_party_name_init | ( | struct ast_party_name * | init | ) |
Initialize the given name structure.
init | Name structure to initialize. |
Definition at line 1834 of file channel.c.
References AST_PARTY_CHAR_SET_ISO8859_1, AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, ast_party_name::char_set, ast_party_name::presentation, ast_party_name::str, and ast_party_name::valid.
Referenced by __analog_ss_thread(), analog_ss_thread(), ast_party_id_init(), and skinny_newcall().
01835 { 01836 init->str = NULL; 01837 init->char_set = AST_PARTY_CHAR_SET_ISO8859_1; 01838 init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 01839 init->valid = 0; 01840 }
void ast_party_name_set | ( | struct ast_party_name * | dest, | |
const struct ast_party_name * | src | |||
) |
Set the source party name information into the destination party name.
dest | The name one wishes to update | |
src | The new name values to update the dest |
Definition at line 1864 of file channel.c.
References ast_free, ast_strdup, ast_party_name::char_set, ast_party_name::presentation, ast_party_name::str, and ast_party_name::valid.
Referenced by ast_party_id_set().
01865 { 01866 if (dest == src) { 01867 /* Don't set to self */ 01868 return; 01869 } 01870 01871 if (src->str && src->str != dest->str) { 01872 ast_free(dest->str); 01873 dest->str = ast_strdup(src->str); 01874 } 01875 01876 dest->char_set = src->char_set; 01877 dest->presentation = src->presentation; 01878 dest->valid = src->valid; 01879 }
void ast_party_name_set_init | ( | struct ast_party_name * | init, | |
const struct ast_party_name * | guide | |||
) |
Initialize the given party name structure using the given guide for a set update operation.
init | Party name structure to initialize. | |
guide | Source party name to use as a guide in initializing. |
Definition at line 1856 of file channel.c.
References ast_party_name::char_set, ast_party_name::presentation, ast_party_name::str, and ast_party_name::valid.
Referenced by ast_party_id_set_init().
01857 { 01858 init->str = NULL; 01859 init->char_set = guide->char_set; 01860 init->presentation = guide->presentation; 01861 init->valid = guide->valid; 01862 }
void ast_party_number_copy | ( | struct ast_party_number * | dest, | |
const struct ast_party_number * | src | |||
) |
Copy the source party number information to the destination party number.
dest | Destination party number | |
src | Source party number |
Definition at line 1895 of file channel.c.
References ast_free, ast_strdup, ast_party_number::plan, ast_party_number::presentation, ast_party_number::str, and ast_party_number::valid.
Referenced by ast_party_id_copy().
01896 { 01897 if (dest == src) { 01898 /* Don't copy to self */ 01899 return; 01900 } 01901 01902 ast_free(dest->str); 01903 dest->str = ast_strdup(src->str); 01904 dest->plan = src->plan; 01905 dest->presentation = src->presentation; 01906 dest->valid = src->valid; 01907 }
void ast_party_number_free | ( | struct ast_party_number * | doomed | ) |
Destroy the party number contents.
doomed | The party number to destroy. |
Definition at line 1934 of file channel.c.
References ast_free, and ast_party_number::str.
Referenced by __analog_ss_thread(), analog_ss_thread(), ast_party_id_free(), do_forward(), and skinny_newcall().
void ast_party_number_init | ( | struct ast_party_number * | init | ) |
Initialize the given number structure.
init | Number structure to initialize. |
Definition at line 1887 of file channel.c.
References AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, ast_party_number::plan, ast_party_number::presentation, ast_party_number::str, and ast_party_number::valid.
Referenced by __analog_ss_thread(), analog_ss_thread(), ast_party_id_init(), do_forward(), and skinny_newcall().
01888 { 01889 init->str = NULL; 01890 init->plan = 0;/* Unknown */ 01891 init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 01892 init->valid = 0; 01893 }
void ast_party_number_set | ( | struct ast_party_number * | dest, | |
const struct ast_party_number * | src | |||
) |
Set the source party number information into the destination party number.
dest | The number one wishes to update | |
src | The new number values to update the dest |
Definition at line 1917 of file channel.c.
References ast_free, ast_strdup, ast_party_number::plan, ast_party_number::presentation, ast_party_number::str, and ast_party_number::valid.
Referenced by ast_party_id_set().
01918 { 01919 if (dest == src) { 01920 /* Don't set to self */ 01921 return; 01922 } 01923 01924 if (src->str && src->str != dest->str) { 01925 ast_free(dest->str); 01926 dest->str = ast_strdup(src->str); 01927 } 01928 01929 dest->plan = src->plan; 01930 dest->presentation = src->presentation; 01931 dest->valid = src->valid; 01932 }
void ast_party_number_set_init | ( | struct ast_party_number * | init, | |
const struct ast_party_number * | guide | |||
) |
Initialize the given party number structure using the given guide for a set update operation.
init | Party number structure to initialize. | |
guide | Source party number to use as a guide in initializing. |
Definition at line 1909 of file channel.c.
References ast_party_number::plan, ast_party_number::presentation, ast_party_number::str, and ast_party_number::valid.
Referenced by ast_party_id_set_init().
01910 { 01911 init->str = NULL; 01912 init->plan = guide->plan; 01913 init->presentation = guide->presentation; 01914 init->valid = guide->valid; 01915 }
void ast_party_redirecting_copy | ( | struct ast_party_redirecting * | dest, | |
const struct ast_party_redirecting * | src | |||
) |
Copy the source redirecting information to the destination redirecting.
dest | Destination redirecting | |
src | Source redirecting |
Definition at line 2270 of file channel.c.
References ast_party_id_copy(), ast_party_redirecting::count, ast_party_redirecting::from, ast_party_redirecting::reason, and ast_party_redirecting::to.
Referenced by ast_channel_redirecting_macro(), begin_dial_channel(), dial_exec_full(), do_forward(), local_call(), and ring_entry().
02271 { 02272 if (dest == src) { 02273 /* Don't copy to self */ 02274 return; 02275 } 02276 02277 ast_party_id_copy(&dest->from, &src->from); 02278 ast_party_id_copy(&dest->to, &src->to); 02279 dest->count = src->count; 02280 dest->reason = src->reason; 02281 }
void ast_party_redirecting_free | ( | struct ast_party_redirecting * | doomed | ) |
Destroy the redirecting information contents.
doomed | The redirecting information to destroy. |
Definition at line 2299 of file channel.c.
References ast_party_id_free(), ast_party_redirecting::from, and ast_party_redirecting::to.
Referenced by ast_channel_destructor(), ast_dummy_channel_destructor(), ast_indicate_data(), do_forward(), handle_request_invite(), handle_response(), handle_response_invite(), redirecting_write(), and sig_pri_handle_subcmds().
02300 { 02301 ast_party_id_free(&doomed->from); 02302 ast_party_id_free(&doomed->to); 02303 }
void ast_party_redirecting_init | ( | struct ast_party_redirecting * | init | ) |
Initialize the given redirecting structure.
init | Redirecting structure to initialize. |
Definition at line 2262 of file channel.c.
References ast_party_id_init(), AST_REDIRECTING_REASON_UNKNOWN, ast_party_redirecting::count, ast_party_redirecting::from, ast_party_redirecting::reason, and ast_party_redirecting::to.
Referenced by __ast_channel_alloc_ap(), do_forward(), handle_request_invite(), handle_response(), and handle_response_invite().
02263 { 02264 ast_party_id_init(&init->from); 02265 ast_party_id_init(&init->to); 02266 init->count = 0; 02267 init->reason = AST_REDIRECTING_REASON_UNKNOWN; 02268 }
void ast_party_redirecting_set | ( | struct ast_party_redirecting * | dest, | |
const struct ast_party_redirecting * | src, | |||
const struct ast_set_party_redirecting * | update | |||
) |
Set the redirecting information based on another redirecting source.
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 2291 of file channel.c.
References ast_party_id_set(), ast_party_redirecting::count, ast_party_redirecting::from, ast_party_redirecting::reason, ast_party_redirecting::to, and update().
Referenced by ast_channel_set_redirecting().
02292 { 02293 ast_party_id_set(&dest->from, &src->from, update ? &update->from : NULL); 02294 ast_party_id_set(&dest->to, &src->to, update ? &update->to : NULL); 02295 dest->reason = src->reason; 02296 dest->count = src->count; 02297 }
void ast_party_redirecting_set_init | ( | struct ast_party_redirecting * | init, | |
const struct ast_party_redirecting * | guide | |||
) |
Initialize the given redirecting id structure using the given guide for a set update operation.
init | Redirecting id structure to initialize. | |
guide | Source redirecting id to use as a guide in initializing. |
Definition at line 2283 of file channel.c.
References ast_party_id_set_init(), ast_party_redirecting::count, ast_party_redirecting::from, ast_party_redirecting::reason, and ast_party_redirecting::to.
Referenced by ast_indicate_data(), misdn_copy_redirecting_to_ast(), redirecting_write(), and sig_pri_redirecting_convert().
02284 { 02285 ast_party_id_set_init(&init->from, &guide->from); 02286 ast_party_id_set_init(&init->to, &guide->to); 02287 init->count = guide->count; 02288 init->reason = guide->reason; 02289 }
void ast_party_subaddress_copy | ( | struct ast_party_subaddress * | dest, | |
const struct ast_party_subaddress * | src | |||
) |
Copy the source party subaddress information to the destination party subaddress.
dest | Destination party subaddress | |
src | Source party subaddress |
Definition at line 1948 of file channel.c.
References ast_free, ast_strdup, ast_party_subaddress::odd_even_indicator, ast_party_subaddress::str, ast_party_subaddress::type, and ast_party_subaddress::valid.
Referenced by ast_party_dialed_copy(), and ast_party_id_copy().
01949 { 01950 if (dest == src) { 01951 /* Don't copy to self */ 01952 return; 01953 } 01954 01955 ast_free(dest->str); 01956 dest->str = ast_strdup(src->str); 01957 dest->type = src->type; 01958 dest->odd_even_indicator = src->odd_even_indicator; 01959 dest->valid = src->valid; 01960 }
void ast_party_subaddress_free | ( | struct ast_party_subaddress * | doomed | ) |
Destroy the party subaddress contents.
doomed | The party subaddress to destroy. |
Definition at line 1987 of file channel.c.
References ast_free, and ast_party_subaddress::str.
Referenced by ast_party_dialed_free(), and ast_party_id_free().
void ast_party_subaddress_init | ( | struct ast_party_subaddress * | init | ) |
Initialize the given subaddress structure.
init | Subaddress structure to initialize. |
Definition at line 1940 of file channel.c.
References ast_party_subaddress::odd_even_indicator, ast_party_subaddress::str, ast_party_subaddress::type, and ast_party_subaddress::valid.
Referenced by ast_party_dialed_init(), ast_party_id_init(), sig_pri_call(), and sig_pri_set_subaddress().
01941 { 01942 init->str = NULL; 01943 init->type = 0; 01944 init->odd_even_indicator = 0; 01945 init->valid = 0; 01946 }
void ast_party_subaddress_set | ( | struct ast_party_subaddress * | dest, | |
const struct ast_party_subaddress * | src | |||
) |
Set the source party subaddress information into the destination party subaddress.
dest | The subaddress one wishes to update | |
src | The new subaddress values to update the dest |
Definition at line 1970 of file channel.c.
References ast_free, ast_strdup, ast_party_subaddress::odd_even_indicator, ast_party_subaddress::str, ast_party_subaddress::type, and ast_party_subaddress::valid.
Referenced by ast_party_dialed_set(), ast_party_id_set(), and sig_pri_handle_subcmds().
01971 { 01972 if (dest == src) { 01973 /* Don't set to self */ 01974 return; 01975 } 01976 01977 if (src->str && src->str != dest->str) { 01978 ast_free(dest->str); 01979 dest->str = ast_strdup(src->str); 01980 } 01981 01982 dest->type = src->type; 01983 dest->odd_even_indicator = src->odd_even_indicator; 01984 dest->valid = src->valid; 01985 }
void ast_party_subaddress_set_init | ( | struct ast_party_subaddress * | init, | |
const struct ast_party_subaddress * | guide | |||
) |
Initialize the given party subaddress structure using the given guide for a set update operation.
init | Party subaddress structure to initialize. | |
guide | Source party subaddress to use as a guide in initializing. |
Definition at line 1962 of file channel.c.
References ast_party_subaddress::odd_even_indicator, ast_party_subaddress::str, ast_party_subaddress::type, and ast_party_subaddress::valid.
Referenced by ast_party_dialed_set_init(), and ast_party_id_set_init().
01963 { 01964 init->str = NULL; 01965 init->type = guide->type; 01966 init->odd_even_indicator = guide->odd_even_indicator; 01967 init->valid = guide->valid; 01968 }
void ast_poll_channel_add | ( | struct ast_channel * | chan0, | |
struct ast_channel * | chan1 | |||
) |
Add a channel to an optimized waitfor
Definition at line 2560 of file channel.c.
References AST_MAX_FDS, and ast_channel::fds.
Referenced by ast_generic_bridge(), begin_dial_channel(), feature_request_and_dial(), local_bridge_loop(), remote_bridge_loop(), and wait_for_answer().
02561 { 02562 #ifdef HAVE_EPOLL 02563 struct epoll_event ev; 02564 int i = 0; 02565 02566 if (chan0->epfd == -1) 02567 return; 02568 02569 /* Iterate through the file descriptors on chan1, adding them to chan0 */ 02570 for (i = 0; i < AST_MAX_FDS; i++) { 02571 if (chan1->fds[i] == -1) 02572 continue; 02573 ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP; 02574 ev.data.ptr = chan1->epfd_data[i]; 02575 epoll_ctl(chan0->epfd, EPOLL_CTL_ADD, chan1->fds[i], &ev); 02576 } 02577 02578 #endif 02579 return; 02580 }
void ast_poll_channel_del | ( | struct ast_channel * | chan0, | |
struct ast_channel * | chan1 | |||
) |
Delete a channel from an optimized waitfor
Definition at line 2583 of file channel.c.
References AST_MAX_FDS, and ast_channel::fds.
Referenced by feature_request_and_dial(), and monitor_dial().
02584 { 02585 #ifdef HAVE_EPOLL 02586 struct epoll_event ev; 02587 int i = 0; 02588 02589 if (chan0->epfd == -1) 02590 return; 02591 02592 for (i = 0; i < AST_MAX_FDS; i++) { 02593 if (chan1->fds[i] == -1) 02594 continue; 02595 epoll_ctl(chan0->epfd, EPOLL_CTL_DEL, chan1->fds[i], &ev); 02596 } 02597 02598 #endif 02599 return; 02600 }
char* ast_print_group | ( | char * | buf, | |
int | buflen, | |||
ast_group_t | group | |||
) |
print call- and pickup groups into buffer
Definition at line 7701 of file channel.c.
References first.
Referenced by _sip_show_peer(), _skinny_show_line(), func_channel_read(), function_sippeer(), misdn_cfg_get_config_string(), print_group(), read_config(), and serialize_showchan().
07702 { 07703 unsigned int i; 07704 int first = 1; 07705 char num[3]; 07706 07707 buf[0] = '\0'; 07708 07709 if (!group) /* Return empty string if no group */ 07710 return buf; 07711 07712 for (i = 0; i <= 63; i++) { /* Max group is 63 */ 07713 if (group & ((ast_group_t) 1 << i)) { 07714 if (!first) { 07715 strncat(buf, ", ", buflen - strlen(buf) - 1); 07716 } else { 07717 first = 0; 07718 } 07719 snprintf(num, sizeof(num), "%u", i); 07720 strncat(buf, num, buflen - strlen(buf) - 1); 07721 } 07722 } 07723 return buf; 07724 }
int ast_prod | ( | struct ast_channel * | chan | ) |
Send empty audio to prime a channel driver.
Definition at line 4521 of file channel.c.
References ast_channel::_state, ast_debug, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), AST_STATE_UP, ast_write(), chanlist::chan, ast_frame_subclass::codec, ast_frame::data, LOG_WARNING, ast_channel::name, ast_frame::ptr, ast_channel::rawwriteformat, ast_frame::src, and ast_frame::subclass.
Referenced by ast_activate_generator().
04522 { 04523 struct ast_frame a = { AST_FRAME_VOICE }; 04524 char nothing[128]; 04525 04526 /* Send an empty audio frame to get things moving */ 04527 if (chan->_state != AST_STATE_UP) { 04528 ast_debug(1, "Prodding channel '%s'\n", chan->name); 04529 a.subclass.codec = chan->rawwriteformat; 04530 a.data.ptr = nothing + AST_FRIENDLY_OFFSET; 04531 a.src = "ast_prod"; /* this better match check in ast_write */ 04532 if (ast_write(chan, &a)) 04533 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name); 04534 } 04535 return 0; 04536 }
int ast_queue_control | ( | struct ast_channel * | chan, | |
enum ast_control_frame_type | control | |||
) |
Queue a control frame with payload.
chan | channel to queue frame onto | |
control | type of control frame |
zero | on success | |
non-zero | on failure |
Definition at line 1511 of file channel.c.
References AST_FRAME_CONTROL, ast_queue_frame(), chanlist::chan, and f.
Referenced by __analog_handle_event(), __analog_ss_thread(), __ast_read(), __dahdi_exception(), __oh323_update_info(), analog_call(), analog_exception(), analog_hangup(), analog_ss_thread(), ast_pickup_call(), attempt_transfer(), auto_congest(), cb_events(), cli_console_answer(), cli_console_flash(), console_answer(), console_call(), console_sendtext(), dahdi_handle_event(), dahdi_hangup(), gtalk_is_answered(), gtalk_ringing_ack(), handle_hd_hf(), handle_offhook_message(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), handle_response_refer(), handle_soft_key_event_message(), handle_stimulus_message(), HandleCallIncoming(), jingle_is_answered(), jingle_ringing_ack(), masquerade_colp_transfer(), misdn_facility_ie_handler(), multicast_rtp_call(), nbs_call(), phone_call(), pickup_do(), process_sdp(), receive_digit(), remote_hold(), send_cause2ast(), setup_rtp_connection(), sig_pri_handle_subcmds(), skinny_call(), skinny_transfer(), skinny_unhold(), unistim_call(), and update_state().
01512 { 01513 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control }; 01514 return ast_queue_frame(chan, &f); 01515 }
int ast_queue_control_data | ( | struct ast_channel * | chan, | |
enum ast_control_frame_type | control, | |||
const void * | data, | |||
size_t | datalen | |||
) |
Queue a control frame with payload.
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 1518 of file channel.c.
References AST_FRAME_CONTROL, ast_queue_frame(), chanlist::chan, and f.
Referenced by __analog_handle_event(), analog_hangup(), ast_channel_queue_connected_line_update(), ast_channel_queue_redirecting_update(), change_t38_state(), dahdi_handle_event(), dahdi_hangup(), handle_request_notify(), handle_response_refer(), iax2_queue_control_data(), iax2_transfer(), interpret_t38_parameters(), local_attended_transfer(), masquerade_colp_transfer(), process_sdp(), sip_sipredirect(), and skinny_hold().
01520 { 01521 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control, .data.ptr = (void *) data, .datalen = datalen }; 01522 return ast_queue_frame(chan, &f); 01523 }
int ast_queue_frame | ( | struct ast_channel * | chan, | |
struct ast_frame * | f | |||
) |
Queue one or more frames to a channel's frame queue.
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 1468 of file channel.c.
References __ast_queue_frame(), and chanlist::chan.
Referenced by __ast_channel_masquerade(), __ast_read(), __oh323_rtp_create(), __oh323_update_info(), action_atxfer(), agent_new(), alsa_call(), ast_channel_setwhentohangup_tv(), ast_do_masquerade(), ast_queue_cc_frame(), ast_queue_control(), ast_queue_control_data(), ast_queue_hangup(), ast_queue_hangup_with_cause(), ast_softhangup_nolock(), bridge_write(), cb_events(), cli_console_dial(), cli_console_sendtext(), console_dial(), console_do_answer(), console_flash(), console_sendtext(), dahdi_queue_frame(), dahdi_read(), dictate_exec(), do_immediate_setup(), gtalk_handle_dtmf(), handle_keypad_button_message(), handle_request_info(), handle_request_invite(), handle_response_invite(), iax2_queue_frame(), jingle_handle_dtmf(), keypad_digit(), local_queue_frame(), mgcp_queue_frame(), oh323_simulate_dtmf_end(), oss_call(), pri_queue_frame(), process_sdp(), queue_dtmf_readq(), receive_digit(), receive_message(), rpt_call(), sig_pri_handle_hold(), sig_ss7_queue_frame(), stream_monitor(), unistim_do_senddigit(), unistim_senddigit_end(), usbradio_read(), and wakeup_sub().
01469 { 01470 return __ast_queue_frame(chan, fin, 0, NULL); 01471 }
int ast_queue_frame_head | ( | struct ast_channel * | chan, | |
struct ast_frame * | f | |||
) |
Queue one or more frames to the head of a channel's frame queue.
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 1473 of file channel.c.
References __ast_queue_frame(), and chanlist::chan.
Referenced by __ast_answer(), __ast_read(), ast_autoservice_stop(), ast_safe_sleep_conditional(), and feature_request_and_dial().
01474 { 01475 return __ast_queue_frame(chan, fin, 1, NULL); 01476 }
int ast_queue_hangup | ( | struct ast_channel * | chan | ) |
Queue a hangup frame.
Definition at line 1479 of file channel.c.
References ast_channel::_softhangup, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, ast_queue_frame(), AST_SOFTHANGUP_DEV, chanlist::chan, and f.
Referenced by bridge_queue_hangup(), cleanup_connection(), cli_console_hangup(), close_call(), gtalk_hangup_farend(), gtalk_is_answered(), handle_onhook_message(), handle_request_bye(), handle_request_cancel(), handle_soft_key_event_message(), iax2_destroy(), iax2_queue_hangup(), jingle_hangup_farend(), local_fixup(), local_hangup(), and mgcp_queue_hangup().
01480 { 01481 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP }; 01482 /* Yeah, let's not change a lock-critical value without locking */ 01483 if (!ast_channel_trylock(chan)) { 01484 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01485 ast_channel_unlock(chan); 01486 } 01487 return ast_queue_frame(chan, &f); 01488 }
int ast_queue_hangup_with_cause | ( | struct ast_channel * | chan, | |
int | cause | |||
) |
Queue a hangup frame with hangupcause set.
[in] | chan | channel to queue frame onto |
[in] | cause | the hangup cause |
Definition at line 1491 of file channel.c.
References ast_channel::_softhangup, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, ast_queue_frame(), AST_SOFTHANGUP_DEV, chanlist::chan, f, and ast_channel::hangupcause.
Referenced by __analog_handle_event(), __oh323_update_info(), __sip_autodestruct(), close_call(), close_client(), console_hangup(), dahdi_handle_event(), dahdi_r2_on_call_disconnect(), handle_request_bye(), handle_response(), handle_response_invite(), handle_response_notify(), HandleCallOutgoing(), hangup_chan(), hangup_connection(), misdn_answer(), retrans_pkt(), and TransferCallStep1().
01492 { 01493 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP }; 01494 01495 if (cause >= 0) 01496 f.data.uint32 = cause; 01497 01498 /* Yeah, let's not change a lock-critical value without locking */ 01499 if (!ast_channel_trylock(chan)) { 01500 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01501 if (cause < 0) 01502 f.data.uint32 = chan->hangupcause; 01503 01504 ast_channel_unlock(chan); 01505 } 01506 01507 return ast_queue_frame(chan, &f); 01508 }
int ast_raw_answer | ( | struct ast_channel * | chan, | |
int | cdr_answer | |||
) |
Answer a channel.
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 2773 of file channel.c.
References ast_channel::_state, ast_channel_tech::answer, ast_cdr_answer(), AST_CEL_ANSWER, ast_cel_report_event(), ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, ast_indicate(), ast_setstate(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_test_flag, ast_channel::cdr, chanlist::chan, and ast_channel::tech.
Referenced by __ast_answer(), and ast_bridge_call().
02774 { 02775 int res = 0; 02776 02777 ast_channel_lock(chan); 02778 02779 /* You can't answer an outbound call */ 02780 if (ast_test_flag(chan, AST_FLAG_OUTGOING)) { 02781 ast_channel_unlock(chan); 02782 return 0; 02783 } 02784 02785 /* Stop if we're a zombie or need a soft hangup */ 02786 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 02787 ast_channel_unlock(chan); 02788 return -1; 02789 } 02790 02791 ast_channel_unlock(chan); 02792 02793 switch (chan->_state) { 02794 case AST_STATE_RINGING: 02795 case AST_STATE_RING: 02796 ast_channel_lock(chan); 02797 if (chan->tech->answer) { 02798 res = chan->tech->answer(chan); 02799 } 02800 ast_setstate(chan, AST_STATE_UP); 02801 if (cdr_answer) { 02802 ast_cdr_answer(chan->cdr); 02803 } 02804 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL); 02805 ast_channel_unlock(chan); 02806 break; 02807 case AST_STATE_UP: 02808 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL); 02809 /* Calling ast_cdr_answer when it it has previously been called 02810 * is essentially a no-op, so it is safe. 02811 */ 02812 if (cdr_answer) { 02813 ast_cdr_answer(chan->cdr); 02814 } 02815 break; 02816 default: 02817 break; 02818 } 02819 02820 ast_indicate(chan, -1); 02821 02822 return res; 02823 }
struct ast_frame* ast_read | ( | struct ast_channel * | chan | ) |
Reads a frame.
chan | channel to read a frame from |
Definition at line 4149 of file channel.c.
References __ast_read(), and chanlist::chan.
Referenced by __adsi_transmit_messages(), __analog_ss_thread(), __ast_answer(), __ast_play_and_record(), __ast_request_and_dial(), adsi_careful_send(), agent_ack_sleep(), agent_read(), analog_ss_thread(), ast_bridge_handle_trip(), ast_recvtext(), ast_safe_sleep_conditional(), ast_tonepair(), ast_transfer(), ast_udptl_bridge(), ast_waitfordigit_full(), async_wait(), autoservice_run(), background_detect_exec(), channel_spy(), check_goto_on_transfer(), conf_flush(), conf_run(), dahdi_bridge(), dial_exec_full(), dictate_exec(), disa_exec(), disable_t38(), do_idle_thread(), do_waiting(), echo_exec(), eivr_comm(), feature_request_and_dial(), find_cache(), generic_fax_exec(), handle_recordfile(), handle_speechrecognize(), iax_park_thread(), ices_exec(), isAnsweringMachine(), jack_exec(), launch_asyncagi(), local_bridge_loop(), manage_parkinglot(), masq_park_call(), measurenoise(), misdn_bridge(), monitor_dial(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), receivefax_t38_init(), recordthread(), remote_bridge_loop(), rpt(), run_agi(), send_tone_burst(), send_waveform_to_channel(), sendfax_t38_init(), sendurl_exec(), speech_background(), transmit_audio(), transmit_t38(), wait_for_hangup(), wait_for_winner(), waitforring_exec(), and waitstream_core().
04150 { 04151 return __ast_read(chan, 0); 04152 }
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 4154 of file channel.c.
References __ast_read(), and chanlist::chan.
Referenced by ast_bridge_handle_trip(), and conf_run().
04155 { 04156 return __ast_read(chan, 1); 04157 }
int ast_readstring | ( | struct ast_channel * | c, | |
char * | s, | |||
int | len, | |||
int | timeout, | |||
int | rtimeout, | |||
char * | enders | |||
) |
Reads multiple digits.
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 5497 of file channel.c.
References ast_readstring_full().
Referenced by ast_adsi_begin_download(), ast_adsi_get_cpeinfo(), ast_adsi_load_session(), ast_app_getdata(), dialout(), do_directory(), forward_message(), privacy_exec(), vm_authenticate(), vm_newuser(), and vm_options().
05498 { 05499 return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1); 05500 }
int ast_readstring_full | ( | struct ast_channel * | c, | |
char * | s, | |||
int | len, | |||
int | timeout, | |||
int | rtimeout, | |||
char * | enders, | |||
int | audiofd, | |||
int | ctrlfd | |||
) |
Definition at line 5502 of file channel.c.
References ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_check_hangup(), AST_DIGIT_ANY, AST_FLAG_ZOMBIE, AST_GETDATA_COMPLETE, AST_GETDATA_EMPTY_END_TERMINATED, AST_GETDATA_FAILED, AST_GETDATA_INTERRUPTED, AST_GETDATA_TIMEOUT, ast_opt_transmit_silence, ast_stopstream(), ast_test_flag, ast_waitfordigit_full(), ast_waitstream_full(), and ast_channel::stream.
Referenced by ast_app_getdata_full(), and ast_readstring().
05503 { 05504 int pos = 0; /* index in the buffer where we accumulate digits */ 05505 int to = ftimeout; 05506 05507 struct ast_silence_generator *silgen = NULL; 05508 05509 /* Stop if we're a zombie or need a soft hangup */ 05510 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 05511 return -1; 05512 if (!len) 05513 return -1; 05514 for (;;) { 05515 int d; 05516 if (c->stream) { 05517 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd); 05518 ast_stopstream(c); 05519 if (!silgen && ast_opt_transmit_silence) 05520 silgen = ast_channel_start_silence_generator(c); 05521 usleep(1000); 05522 if (!d) 05523 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 05524 } else { 05525 if (!silgen && ast_opt_transmit_silence) 05526 silgen = ast_channel_start_silence_generator(c); 05527 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 05528 } 05529 if (d < 0) { 05530 ast_channel_stop_silence_generator(c, silgen); 05531 return AST_GETDATA_FAILED; 05532 } 05533 if (d == 0) { 05534 s[pos] = '\0'; 05535 ast_channel_stop_silence_generator(c, silgen); 05536 return AST_GETDATA_TIMEOUT; 05537 } 05538 if (d == 1) { 05539 s[pos] = '\0'; 05540 ast_channel_stop_silence_generator(c, silgen); 05541 return AST_GETDATA_INTERRUPTED; 05542 } 05543 if (strchr(enders, d) && (pos == 0)) { 05544 s[pos] = '\0'; 05545 ast_channel_stop_silence_generator(c, silgen); 05546 return AST_GETDATA_EMPTY_END_TERMINATED; 05547 } 05548 if (!strchr(enders, d)) { 05549 s[pos++] = d; 05550 } 05551 if (strchr(enders, d) || (pos >= len)) { 05552 s[pos] = '\0'; 05553 ast_channel_stop_silence_generator(c, silgen); 05554 return AST_GETDATA_COMPLETE; 05555 } 05556 to = timeout; 05557 } 05558 /* Never reached */ 05559 return 0; 05560 }
int ast_recvchar | ( | struct ast_channel * | chan, | |
int | timeout | |||
) |
Receives a text character from a channel.
chan | channel to act upon | |
timeout | timeout in milliseconds (0 for infinite wait) |
Definition at line 4402 of file channel.c.
References ast_free, ast_recvtext(), and chanlist::chan.
Referenced by handle_recvchar().
04403 { 04404 int c; 04405 char *buf = ast_recvtext(chan, timeout); 04406 if (buf == NULL) 04407 return -1; /* error or timeout */ 04408 c = *(unsigned char *)buf; 04409 ast_free(buf); 04410 return c; 04411 }
char* ast_recvtext | ( | struct ast_channel * | chan, | |
int | timeout | |||
) |
Receives a text string from a channel Read a string of text from a channel.
chan | channel to act upon | |
timeout | timeout in milliseconds (0 for infinite wait) |
Definition at line 4413 of file channel.c.
References ast_check_hangup(), AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_TEXT, ast_frfree, ast_read(), ast_strndup, ast_waitfor(), chanlist::chan, and f.
Referenced by ast_recvchar(), and handle_recvtext().
04414 { 04415 int res, done = 0; 04416 char *buf = NULL; 04417 04418 while (!done) { 04419 struct ast_frame *f; 04420 if (ast_check_hangup(chan)) 04421 break; 04422 res = ast_waitfor(chan, timeout); 04423 if (res <= 0) /* timeout or error */ 04424 break; 04425 timeout = res; /* update timeout */ 04426 f = ast_read(chan); 04427 if (f == NULL) 04428 break; /* no frame */ 04429 if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_HANGUP) 04430 done = 1; /* force a break */ 04431 else if (f->frametype == AST_FRAME_TEXT) { /* what we want */ 04432 buf = ast_strndup((char *) f->data.ptr, f->datalen); /* dup and break */ 04433 done = 1; 04434 } 04435 ast_frfree(f); 04436 } 04437 return buf; 04438 }
int ast_redirecting_build_data | ( | unsigned char * | data, | |
size_t | datalen, | |||
const struct ast_party_redirecting * | redirecting, | |||
const struct ast_set_party_redirecting * | update | |||
) |
Build the redirecting id data frame.
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 8603 of file channel.c.
References ast_log(), AST_REDIRECTING_COUNT, AST_REDIRECTING_FROM_ID_PRESENTATION, AST_REDIRECTING_FROM_NAME, AST_REDIRECTING_FROM_NAME_CHAR_SET, AST_REDIRECTING_FROM_NAME_PRESENTATION, AST_REDIRECTING_FROM_NAME_VALID, AST_REDIRECTING_FROM_NUMBER, AST_REDIRECTING_FROM_NUMBER_PLAN, AST_REDIRECTING_FROM_NUMBER_PRESENTATION, AST_REDIRECTING_FROM_NUMBER_VALID, AST_REDIRECTING_FROM_SUBADDRESS, AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_FROM_SUBADDRESS_TYPE, AST_REDIRECTING_FROM_SUBADDRESS_VALID, AST_REDIRECTING_FROM_TAG, AST_REDIRECTING_TO_ID_PRESENTATION, AST_REDIRECTING_TO_NAME, AST_REDIRECTING_TO_NAME_CHAR_SET, AST_REDIRECTING_TO_NAME_PRESENTATION, AST_REDIRECTING_TO_NAME_VALID, AST_REDIRECTING_TO_NUMBER, AST_REDIRECTING_TO_NUMBER_PLAN, AST_REDIRECTING_TO_NUMBER_PRESENTATION, AST_REDIRECTING_TO_NUMBER_VALID, AST_REDIRECTING_TO_SUBADDRESS, AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_TO_SUBADDRESS_TYPE, AST_REDIRECTING_TO_SUBADDRESS_VALID, AST_REDIRECTING_TO_TAG, AST_REDIRECTING_VERSION, ast_party_redirecting::count, ast_party_redirecting::from, LOG_WARNING, ast_party_id_ies::name, party_id_build_data(), ast_party_redirecting::reason, ast_party_name_ies::str, ast_party_redirecting::to, update(), and value.
Referenced by ast_channel_queue_redirecting_update(), ast_channel_update_redirecting(), and local_indicate().
08604 { 08605 int32_t value; 08606 size_t pos = 0; 08607 int res; 08608 08609 static const struct ast_party_id_ies from_ies = { 08610 .name.str = AST_REDIRECTING_FROM_NAME, 08611 .name.char_set = AST_REDIRECTING_FROM_NAME_CHAR_SET, 08612 .name.presentation = AST_REDIRECTING_FROM_NAME_PRESENTATION, 08613 .name.valid = AST_REDIRECTING_FROM_NAME_VALID, 08614 08615 .number.str = AST_REDIRECTING_FROM_NUMBER, 08616 .number.plan = AST_REDIRECTING_FROM_NUMBER_PLAN, 08617 .number.presentation = AST_REDIRECTING_FROM_NUMBER_PRESENTATION, 08618 .number.valid = AST_REDIRECTING_FROM_NUMBER_VALID, 08619 08620 .subaddress.str = AST_REDIRECTING_FROM_SUBADDRESS, 08621 .subaddress.type = AST_REDIRECTING_FROM_SUBADDRESS_TYPE, 08622 .subaddress.odd_even_indicator = AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN, 08623 .subaddress.valid = AST_REDIRECTING_FROM_SUBADDRESS_VALID, 08624 08625 .tag = AST_REDIRECTING_FROM_TAG, 08626 .combined_presentation = AST_REDIRECTING_FROM_ID_PRESENTATION, 08627 }; 08628 static const struct ast_party_id_ies to_ies = { 08629 .name.str = AST_REDIRECTING_TO_NAME, 08630 .name.char_set = AST_REDIRECTING_TO_NAME_CHAR_SET, 08631 .name.presentation = AST_REDIRECTING_TO_NAME_PRESENTATION, 08632 .name.valid = AST_REDIRECTING_TO_NAME_VALID, 08633 08634 .number.str = AST_REDIRECTING_TO_NUMBER, 08635 .number.plan = AST_REDIRECTING_TO_NUMBER_PLAN, 08636 .number.presentation = AST_REDIRECTING_TO_NUMBER_PRESENTATION, 08637 .number.valid = AST_REDIRECTING_TO_NUMBER_VALID, 08638 08639 .subaddress.str = AST_REDIRECTING_TO_SUBADDRESS, 08640 .subaddress.type = AST_REDIRECTING_TO_SUBADDRESS_TYPE, 08641 .subaddress.odd_even_indicator = AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN, 08642 .subaddress.valid = AST_REDIRECTING_TO_SUBADDRESS_VALID, 08643 08644 .tag = AST_REDIRECTING_TO_TAG, 08645 .combined_presentation = AST_REDIRECTING_TO_ID_PRESENTATION, 08646 }; 08647 08648 /* Redirecting frame version */ 08649 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08650 ast_log(LOG_WARNING, "No space left for redirecting frame version\n"); 08651 return -1; 08652 } 08653 data[pos++] = AST_REDIRECTING_VERSION; 08654 data[pos++] = 1; 08655 data[pos++] = 2;/* Version 1 did not have a version ie */ 08656 08657 res = party_id_build_data(data + pos, datalen - pos, &redirecting->from, 08658 "redirecting-from", &from_ies, update ? &update->from : NULL); 08659 if (res < 0) { 08660 return -1; 08661 } 08662 pos += res; 08663 08664 res = party_id_build_data(data + pos, datalen - pos, &redirecting->to, 08665 "redirecting-to", &to_ies, update ? &update->to : NULL); 08666 if (res < 0) { 08667 return -1; 08668 } 08669 pos += res; 08670 08671 /* Redirecting reason */ 08672 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) { 08673 ast_log(LOG_WARNING, "No space left for redirecting reason\n"); 08674 return -1; 08675 } 08676 data[pos++] = AST_REDIRECTING_REASON; 08677 data[pos++] = sizeof(value); 08678 value = htonl(redirecting->reason); 08679 memcpy(data + pos, &value, sizeof(value)); 08680 pos += sizeof(value); 08681 08682 /* Redirecting count */ 08683 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) { 08684 ast_log(LOG_WARNING, "No space left for redirecting count\n"); 08685 return -1; 08686 } 08687 data[pos++] = AST_REDIRECTING_COUNT; 08688 data[pos++] = sizeof(value); 08689 value = htonl(redirecting->count); 08690 memcpy(data + pos, &value, sizeof(value)); 08691 pos += sizeof(value); 08692 08693 return pos; 08694 }
int ast_redirecting_parse_data | ( | const unsigned char * | data, | |
size_t | datalen, | |||
struct ast_party_redirecting * | redirecting | |||
) |
Parse redirecting indication frame data.
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 8696 of file channel.c.
References ast_free, ast_log(), ast_malloc, AST_PARTY_CHAR_SET_ISO8859_1, AST_REDIRECTING_COUNT, AST_REDIRECTING_FROM_ID_PRESENTATION, AST_REDIRECTING_FROM_NAME, AST_REDIRECTING_FROM_NAME_CHAR_SET, AST_REDIRECTING_FROM_NAME_PRESENTATION, AST_REDIRECTING_FROM_NAME_VALID, AST_REDIRECTING_FROM_NUMBER, AST_REDIRECTING_FROM_NUMBER_PLAN, AST_REDIRECTING_FROM_NUMBER_PRESENTATION, AST_REDIRECTING_FROM_NUMBER_VALID, AST_REDIRECTING_FROM_SUBADDRESS, AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_FROM_SUBADDRESS_TYPE, AST_REDIRECTING_FROM_SUBADDRESS_VALID, AST_REDIRECTING_FROM_TAG, AST_REDIRECTING_TO_ID_PRESENTATION, AST_REDIRECTING_TO_NAME, AST_REDIRECTING_TO_NAME_CHAR_SET, AST_REDIRECTING_TO_NAME_PRESENTATION, AST_REDIRECTING_TO_NAME_VALID, AST_REDIRECTING_TO_NUMBER, AST_REDIRECTING_TO_NUMBER_PLAN, AST_REDIRECTING_TO_NUMBER_PRESENTATION, AST_REDIRECTING_TO_NUMBER_VALID, AST_REDIRECTING_TO_SUBADDRESS, AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_TO_SUBADDRESS_TYPE, AST_REDIRECTING_TO_SUBADDRESS_VALID, AST_REDIRECTING_TO_TAG, AST_REDIRECTING_VERSION, ast_party_name::char_set, ast_party_redirecting::count, ast_party_redirecting::from, LOG_DEBUG, LOG_WARNING, ast_party_id::name, ast_party_id::number, ast_party_subaddress::odd_even_indicator, ast_party_number::plan, ast_party_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().
08697 { 08698 size_t pos; 08699 unsigned char ie_len; 08700 unsigned char ie_id; 08701 int32_t value; 08702 int frame_version = 1; 08703 int from_combined_presentation = 0; 08704 int got_from_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */ 08705 int to_combined_presentation = 0; 08706 int got_to_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */ 08707 08708 for (pos = 0; pos < datalen; pos += ie_len) { 08709 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) { 08710 ast_log(LOG_WARNING, "Invalid redirecting update\n"); 08711 return -1; 08712 } 08713 ie_id = data[pos++]; 08714 ie_len = data[pos++]; 08715 if (datalen < pos + ie_len) { 08716 ast_log(LOG_WARNING, "Invalid redirecting update\n"); 08717 return -1; 08718 } 08719 08720 switch (ie_id) { 08721 /* Redirecting frame version */ 08722 case AST_REDIRECTING_VERSION: 08723 if (ie_len != 1) { 08724 ast_log(LOG_WARNING, "Invalid redirecting frame version (%u)\n", 08725 (unsigned) ie_len); 08726 break; 08727 } 08728 frame_version = data[pos]; 08729 break; 08730 /* Redirecting-from party id name */ 08731 case AST_REDIRECTING_FROM_NAME: 08732 ast_free(redirecting->from.name.str); 08733 redirecting->from.name.str = ast_malloc(ie_len + 1); 08734 if (redirecting->from.name.str) { 08735 memcpy(redirecting->from.name.str, data + pos, ie_len); 08736 redirecting->from.name.str[ie_len] = 0; 08737 } 08738 break; 08739 case AST_REDIRECTING_FROM_NAME_CHAR_SET: 08740 if (ie_len != 1) { 08741 ast_log(LOG_WARNING, "Invalid redirecting-from name char set (%u)\n", 08742 (unsigned) ie_len); 08743 break; 08744 } 08745 redirecting->from.name.char_set = data[pos]; 08746 break; 08747 case AST_REDIRECTING_FROM_NAME_PRESENTATION: 08748 if (ie_len != 1) { 08749 ast_log(LOG_WARNING, "Invalid redirecting-from name presentation (%u)\n", 08750 (unsigned) ie_len); 08751 break; 08752 } 08753 redirecting->from.name.presentation = data[pos]; 08754 break; 08755 case AST_REDIRECTING_FROM_NAME_VALID: 08756 if (ie_len != 1) { 08757 ast_log(LOG_WARNING, "Invalid redirecting-from name valid (%u)\n", 08758 (unsigned) ie_len); 08759 break; 08760 } 08761 redirecting->from.name.valid = data[pos]; 08762 break; 08763 /* Redirecting-from party id number */ 08764 case AST_REDIRECTING_FROM_NUMBER: 08765 ast_free(redirecting->from.number.str); 08766 redirecting->from.number.str = ast_malloc(ie_len + 1); 08767 if (redirecting->from.number.str) { 08768 memcpy(redirecting->from.number.str, data + pos, ie_len); 08769 redirecting->from.number.str[ie_len] = 0; 08770 } 08771 break; 08772 case AST_REDIRECTING_FROM_NUMBER_PLAN: 08773 if (ie_len != 1) { 08774 ast_log(LOG_WARNING, "Invalid redirecting-from numbering plan (%u)\n", 08775 (unsigned) ie_len); 08776 break; 08777 } 08778 redirecting->from.number.plan = data[pos]; 08779 break; 08780 case AST_REDIRECTING_FROM_NUMBER_PRESENTATION: 08781 if (ie_len != 1) { 08782 ast_log(LOG_WARNING, "Invalid redirecting-from number presentation (%u)\n", 08783 (unsigned) ie_len); 08784 break; 08785 } 08786 redirecting->from.number.presentation = data[pos]; 08787 break; 08788 case AST_REDIRECTING_FROM_NUMBER_VALID: 08789 if (ie_len != 1) { 08790 ast_log(LOG_WARNING, "Invalid redirecting-from number valid (%u)\n", 08791 (unsigned) ie_len); 08792 break; 08793 } 08794 redirecting->from.number.valid = data[pos]; 08795 break; 08796 /* Redirecting-from party id combined presentation */ 08797 case AST_REDIRECTING_FROM_ID_PRESENTATION: 08798 if (ie_len != 1) { 08799 ast_log(LOG_WARNING, "Invalid redirecting-from combined presentation (%u)\n", 08800 (unsigned) ie_len); 08801 break; 08802 } 08803 from_combined_presentation = data[pos]; 08804 got_from_combined_presentation = 1; 08805 break; 08806 /* Redirecting-from party id subaddress */ 08807 case AST_REDIRECTING_FROM_SUBADDRESS: 08808 ast_free(redirecting->from.subaddress.str); 08809 redirecting->from.subaddress.str = ast_malloc(ie_len + 1); 08810 if (redirecting->from.subaddress.str) { 08811 memcpy(redirecting->from.subaddress.str, data + pos, ie_len); 08812 redirecting->from.subaddress.str[ie_len] = 0; 08813 } 08814 break; 08815 case AST_REDIRECTING_FROM_SUBADDRESS_TYPE: 08816 if (ie_len != 1) { 08817 ast_log(LOG_WARNING, "Invalid redirecting-from type of subaddress (%u)\n", 08818 (unsigned) ie_len); 08819 break; 08820 } 08821 redirecting->from.subaddress.type = data[pos]; 08822 break; 08823 case AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN: 08824 if (ie_len != 1) { 08825 ast_log(LOG_WARNING, 08826 "Invalid redirecting-from subaddress odd-even indicator (%u)\n", 08827 (unsigned) ie_len); 08828 break; 08829 } 08830 redirecting->from.subaddress.odd_even_indicator = data[pos]; 08831 break; 08832 case AST_REDIRECTING_FROM_SUBADDRESS_VALID: 08833 if (ie_len != 1) { 08834 ast_log(LOG_WARNING, "Invalid redirecting-from subaddress valid (%u)\n", 08835 (unsigned) ie_len); 08836 break; 08837 } 08838 redirecting->from.subaddress.valid = data[pos]; 08839 break; 08840 /* Redirecting-from party id tag */ 08841 case AST_REDIRECTING_FROM_TAG: 08842 ast_free(redirecting->from.tag); 08843 redirecting->from.tag = ast_malloc(ie_len + 1); 08844 if (redirecting->from.tag) { 08845 memcpy(redirecting->from.tag, data + pos, ie_len); 08846 redirecting->from.tag[ie_len] = 0; 08847 } 08848 break; 08849 /* Redirecting-to party id name */ 08850 case AST_REDIRECTING_TO_NAME: 08851 ast_free(redirecting->to.name.str); 08852 redirecting->to.name.str = ast_malloc(ie_len + 1); 08853 if (redirecting->to.name.str) { 08854 memcpy(redirecting->to.name.str, data + pos, ie_len); 08855 redirecting->to.name.str[ie_len] = 0; 08856 } 08857 break; 08858 case AST_REDIRECTING_TO_NAME_CHAR_SET: 08859 if (ie_len != 1) { 08860 ast_log(LOG_WARNING, "Invalid redirecting-to name char set (%u)\n", 08861 (unsigned) ie_len); 08862 break; 08863 } 08864 redirecting->to.name.char_set = data[pos]; 08865 break; 08866 case AST_REDIRECTING_TO_NAME_PRESENTATION: 08867 if (ie_len != 1) { 08868 ast_log(LOG_WARNING, "Invalid redirecting-to name presentation (%u)\n", 08869 (unsigned) ie_len); 08870 break; 08871 } 08872 redirecting->to.name.presentation = data[pos]; 08873 break; 08874 case AST_REDIRECTING_TO_NAME_VALID: 08875 if (ie_len != 1) { 08876 ast_log(LOG_WARNING, "Invalid redirecting-to name valid (%u)\n", 08877 (unsigned) ie_len); 08878 break; 08879 } 08880 redirecting->to.name.valid = data[pos]; 08881 break; 08882 /* Redirecting-to party id number */ 08883 case AST_REDIRECTING_TO_NUMBER: 08884 ast_free(redirecting->to.number.str); 08885 redirecting->to.number.str = ast_malloc(ie_len + 1); 08886 if (redirecting->to.number.str) { 08887 memcpy(redirecting->to.number.str, data + pos, ie_len); 08888 redirecting->to.number.str[ie_len] = 0; 08889 } 08890 break; 08891 case AST_REDIRECTING_TO_NUMBER_PLAN: 08892 if (ie_len != 1) { 08893 ast_log(LOG_WARNING, "Invalid redirecting-to numbering plan (%u)\n", 08894 (unsigned) ie_len); 08895 break; 08896 } 08897 redirecting->to.number.plan = data[pos]; 08898 break; 08899 case AST_REDIRECTING_TO_NUMBER_PRESENTATION: 08900 if (ie_len != 1) { 08901 ast_log(LOG_WARNING, "Invalid redirecting-to number presentation (%u)\n", 08902 (unsigned) ie_len); 08903 break; 08904 } 08905 redirecting->to.number.presentation = data[pos]; 08906 break; 08907 case AST_REDIRECTING_TO_NUMBER_VALID: 08908 if (ie_len != 1) { 08909 ast_log(LOG_WARNING, "Invalid redirecting-to number valid (%u)\n", 08910 (unsigned) ie_len); 08911 break; 08912 } 08913 redirecting->to.number.valid = data[pos]; 08914 break; 08915 /* Redirecting-to party id combined presentation */ 08916 case AST_REDIRECTING_TO_ID_PRESENTATION: 08917 if (ie_len != 1) { 08918 ast_log(LOG_WARNING, "Invalid redirecting-to combined presentation (%u)\n", 08919 (unsigned) ie_len); 08920 break; 08921 } 08922 to_combined_presentation = data[pos]; 08923 got_to_combined_presentation = 1; 08924 break; 08925 /* Redirecting-to party id subaddress */ 08926 case AST_REDIRECTING_TO_SUBADDRESS: 08927 ast_free(redirecting->to.subaddress.str); 08928 redirecting->to.subaddress.str = ast_malloc(ie_len + 1); 08929 if (redirecting->to.subaddress.str) { 08930 memcpy(redirecting->to.subaddress.str, data + pos, ie_len); 08931 redirecting->to.subaddress.str[ie_len] = 0; 08932 } 08933 break; 08934 case AST_REDIRECTING_TO_SUBADDRESS_TYPE: 08935 if (ie_len != 1) { 08936 ast_log(LOG_WARNING, "Invalid redirecting-to type of subaddress (%u)\n", 08937 (unsigned) ie_len); 08938 break; 08939 } 08940 redirecting->to.subaddress.type = data[pos]; 08941 break; 08942 case AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN: 08943 if (ie_len != 1) { 08944 ast_log(LOG_WARNING, 08945 "Invalid redirecting-to subaddress odd-even indicator (%u)\n", 08946 (unsigned) ie_len); 08947 break; 08948 } 08949 redirecting->to.subaddress.odd_even_indicator = data[pos]; 08950 break; 08951 case AST_REDIRECTING_TO_SUBADDRESS_VALID: 08952 if (ie_len != 1) { 08953 ast_log(LOG_WARNING, "Invalid redirecting-to subaddress valid (%u)\n", 08954 (unsigned) ie_len); 08955 break; 08956 } 08957 redirecting->to.subaddress.valid = data[pos]; 08958 break; 08959 /* Redirecting-to party id tag */ 08960 case AST_REDIRECTING_TO_TAG: 08961 ast_free(redirecting->to.tag); 08962 redirecting->to.tag = ast_malloc(ie_len + 1); 08963 if (redirecting->to.tag) { 08964 memcpy(redirecting->to.tag, data + pos, ie_len); 08965 redirecting->to.tag[ie_len] = 0; 08966 } 08967 break; 08968 /* Redirecting reason */ 08969 case AST_REDIRECTING_REASON: 08970 if (ie_len != sizeof(value)) { 08971 ast_log(LOG_WARNING, "Invalid redirecting reason (%u)\n", 08972 (unsigned) ie_len); 08973 break; 08974 } 08975 memcpy(&value, data + pos, sizeof(value)); 08976 redirecting->reason = ntohl(value); 08977 break; 08978 /* Redirecting count */ 08979 case AST_REDIRECTING_COUNT: 08980 if (ie_len != sizeof(value)) { 08981 ast_log(LOG_WARNING, "Invalid redirecting count (%u)\n", 08982 (unsigned) ie_len); 08983 break; 08984 } 08985 memcpy(&value, data + pos, sizeof(value)); 08986 redirecting->count = ntohl(value); 08987 break; 08988 /* Redirecting unknown element */ 08989 default: 08990 ast_log(LOG_DEBUG, "Unknown redirecting element: %u (%u)\n", 08991 (unsigned) ie_id, (unsigned) ie_len); 08992 break; 08993 } 08994 } 08995 08996 switch (frame_version) { 08997 case 1: 08998 /* 08999 * The other end is an earlier version that we need to adjust 09000 * for compatibility. 09001 */ 09002 redirecting->from.name.valid = 1; 09003 redirecting->from.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1; 09004 redirecting->from.number.valid = 1; 09005 if (got_from_combined_presentation) { 09006 redirecting->from.name.presentation = from_combined_presentation; 09007 redirecting->from.number.presentation = from_combined_presentation; 09008 } 09009 09010 redirecting->to.name.valid = 1; 09011 redirecting->to.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1; 09012 redirecting->to.number.valid = 1; 09013 if (got_to_combined_presentation) { 09014 redirecting->to.name.presentation = to_combined_presentation; 09015 redirecting->to.number.presentation = to_combined_presentation; 09016 } 09017 break; 09018 case 2: 09019 /* The other end is at the same level as we are. */ 09020 break; 09021 default: 09022 /* 09023 * The other end is newer than we are. 09024 * We need to assume that they are compatible with us. 09025 */ 09026 ast_log(LOG_DEBUG, "Redirecting frame has newer version: %u\n", 09027 (unsigned) frame_version); 09028 break; 09029 } 09030 09031 return 0; 09032 }
struct ast_channel* ast_request | ( | const char * | type, | |
format_t | format, | |||
const struct ast_channel * | requestor, | |||
void * | data, | |||
int * | status | |||
) |
Requests a channel.
type | type of channel to request | |
format | requested channel format (codec) | |
requestor | channel asking for data | |
data | data to pass to the channel requester | |
status | status |
NULL | failure | |
non-NULL | channel on success |
Definition at line 5355 of file channel.c.
References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_NOSUCHDRIVER, AST_CAUSE_NOTDEFINED, ast_channel_release(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_translator_best_choice(), capabilities, ast_channel_tech::capabilities, chanlist::chan, chanlist::list, LOG_WARNING, ast_channel_tech::requester, set_security_requirements(), ast_channel::tech, and ast_channel_tech::type.
Referenced by __ast_request_and_dial(), ast_call_forward(), attempt_reconnect(), begin_dial_channel(), build_conf(), chanavail_exec(), conf_run(), connect_link(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), play_sound_file(), ring_entry(), rpt(), rpt_call(), rpt_exec(), and rpt_tele_thread().
05356 { 05357 struct chanlist *chan; 05358 struct ast_channel *c; 05359 format_t capabilities; 05360 format_t fmt; 05361 int res; 05362 int foo; 05363 format_t videoformat = format & AST_FORMAT_VIDEO_MASK; 05364 format_t textformat = format & AST_FORMAT_TEXT_MASK; 05365 05366 if (!cause) 05367 cause = &foo; 05368 *cause = AST_CAUSE_NOTDEFINED; 05369 05370 if (AST_RWLIST_RDLOCK(&backends)) { 05371 ast_log(LOG_WARNING, "Unable to lock technology backend list\n"); 05372 return NULL; 05373 } 05374 05375 AST_RWLIST_TRAVERSE(&backends, chan, list) { 05376 if (strcasecmp(type, chan->tech->type)) 05377 continue; 05378 05379 capabilities = chan->tech->capabilities; 05380 fmt = format & AST_FORMAT_AUDIO_MASK; 05381 if (fmt) { 05382 /* We have audio - is it possible to connect the various calls to each other? 05383 (Avoid this check for calls without audio, like text+video calls) 05384 */ 05385 res = ast_translator_best_choice(&fmt, &capabilities); 05386 if (res < 0) { 05387 char tmp1[256], tmp2[256]; 05388 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %s) to %s\n", type, 05389 ast_getformatname_multiple(tmp1, sizeof(tmp1), chan->tech->capabilities), 05390 ast_getformatname_multiple(tmp2, sizeof(tmp2), format)); 05391 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05392 AST_RWLIST_UNLOCK(&backends); 05393 return NULL; 05394 } 05395 } 05396 AST_RWLIST_UNLOCK(&backends); 05397 if (!chan->tech->requester) 05398 return NULL; 05399 05400 if (!(c = chan->tech->requester(type, capabilities | videoformat | textformat, requestor, data, cause))) 05401 return NULL; 05402 05403 if (set_security_requirements(requestor, c)) { 05404 ast_log(LOG_WARNING, "Setting security requirements failed\n"); 05405 c = ast_channel_release(c); 05406 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05407 return NULL; 05408 } 05409 05410 /* no need to generate a Newchannel event here; it is done in the channel_alloc call */ 05411 return c; 05412 } 05413 05414 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type); 05415 *cause = AST_CAUSE_NOSUCHDRIVER; 05416 AST_RWLIST_UNLOCK(&backends); 05417 05418 return NULL; 05419 }
struct ast_channel* ast_request_and_dial | ( | const char * | type, | |
format_t | format, | |||
const struct ast_channel * | requestor, | |||
void * | data, | |||
int | timeout, | |||
int * | reason, | |||
const char * | cid_num, | |||
const char * | cid_name | |||
) |
Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it.
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 5310 of file channel.c.
References __ast_request_and_dial().
Referenced by ast_pbx_outgoing_exten(), and generic_recall().
05311 { 05312 return __ast_request_and_dial(type, format, requestor, data, timeout, outstate, cidnum, cidname, NULL); 05313 }
int ast_safe_sleep | ( | struct ast_channel * | chan, | |
int | ms | |||
) |
Wait for a specified amount of time, looking for hangups.
chan | channel to wait for | |
ms | length of time in milliseconds to sleep |
Definition at line 1822 of file channel.c.
References ast_safe_sleep_conditional(), and chanlist::chan.
Referenced by __analog_ss_thread(), alarmreceiver_exec(), analog_ss_thread(), ast_adsi_transmit_message_full(), ast_dtmf_stream(), ast_senddigit(), builtin_atxfer(), conf_run(), dictate_exec(), flash_exec(), function_ilink(), handle_callforward_button(), login_exec(), mgcp_ss(), milliwatt_exec(), misdn_check_l2l1(), old_milliwatt_exec(), park_call_exec(), parkcall_helper(), pbx_builtin_wait(), play_moh_exec(), play_tone_pair(), playtone(), privacy_exec(), receive_ademco_contact_id(), rpt_call(), rpt_exec(), rpt_tele_thread(), send_morse(), send_tone_telemetry(), skinny_ss(), testclient_exec(), testserver_exec(), wait_for_hangup(), wait_interval(), wait_moh_exec(), waituntil_exec(), and zapateller_exec().
01823 { 01824 return ast_safe_sleep_conditional(chan, ms, NULL, NULL); 01825 }
int ast_safe_sleep_conditional | ( | struct ast_channel * | chan, | |
int | ms, | |||
int(*)(void *) | cond, | |||
void * | data | |||
) |
Wait for a specified amount of time, looking for hangups and a condition argument.
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 1755 of file channel.c.
References ast_channel_lock, ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_channel_unlock, ast_frfree, ast_frisolate(), ast_is_deferrable_frame(), AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_HEAD_NOLOCK, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_HEAD, ast_opt_transmit_silence, ast_queue_frame_head(), ast_read(), ast_waitfor(), chanlist::chan, f, and ast_channel::generatordata.
Referenced by ast_safe_sleep(), and login_exec().
01756 { 01757 struct ast_frame *f; 01758 struct ast_silence_generator *silgen = NULL; 01759 int res = 0; 01760 AST_LIST_HEAD_NOLOCK(, ast_frame) deferred_frames; 01761 01762 AST_LIST_HEAD_INIT_NOLOCK(&deferred_frames); 01763 01764 /* If no other generator is present, start silencegen while waiting */ 01765 if (ast_opt_transmit_silence && !chan->generatordata) { 01766 silgen = ast_channel_start_silence_generator(chan); 01767 } 01768 01769 while (ms > 0) { 01770 struct ast_frame *dup_f = NULL; 01771 if (cond && ((*cond)(data) == 0)) { 01772 break; 01773 } 01774 ms = ast_waitfor(chan, ms); 01775 if (ms < 0) { 01776 res = -1; 01777 break; 01778 } 01779 if (ms > 0) { 01780 f = ast_read(chan); 01781 if (!f) { 01782 res = -1; 01783 break; 01784 } 01785 01786 if (!ast_is_deferrable_frame(f)) { 01787 ast_frfree(f); 01788 continue; 01789 } 01790 01791 if ((dup_f = ast_frisolate(f))) { 01792 if (dup_f != f) { 01793 ast_frfree(f); 01794 } 01795 AST_LIST_INSERT_HEAD(&deferred_frames, dup_f, frame_list); 01796 } 01797 } 01798 } 01799 01800 /* stop silgen if present */ 01801 if (silgen) { 01802 ast_channel_stop_silence_generator(chan, silgen); 01803 } 01804 01805 /* We need to free all the deferred frames, but we only need to 01806 * queue the deferred frames if there was no error and no 01807 * hangup was received 01808 */ 01809 ast_channel_lock(chan); 01810 while ((f = AST_LIST_REMOVE_HEAD(&deferred_frames, frame_list))) { 01811 if (!res) { 01812 ast_queue_frame_head(chan, f); 01813 } 01814 ast_frfree(f); 01815 } 01816 ast_channel_unlock(chan); 01817 01818 return res; 01819 }
int ast_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 4511 of file channel.c.
References AST_DEFAULT_EMULATE_DTMF_DURATION, ast_safe_sleep(), ast_senddigit_begin(), ast_senddigit_end(), chanlist::chan, ast_channel_tech::send_digit_begin, and ast_channel::tech.
Referenced by ast_dtmf_stream(), dial_exec_full(), do_dtmf_phone(), manager_play_dtmf(), and rpt_call().
04512 { 04513 if (chan->tech->send_digit_begin) { 04514 ast_senddigit_begin(chan, digit); 04515 ast_safe_sleep(chan, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION)); 04516 } 04517 04518 return ast_senddigit_end(chan, digit, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION)); 04519 }
int ast_senddigit_begin | ( | struct ast_channel * | chan, | |
char | digit | |||
) |
Send a DTMF digit to a channel.
chan | channel to act upon | |
digit | the DTMF digit to send, encoded in ASCII |
Definition at line 4453 of file channel.c.
References ast_debug, ast_playtones_start(), chanlist::chan, ast_channel::name, ast_channel_tech::send_digit_begin, and ast_channel::tech.
Referenced by agent_digit_begin(), ast_senddigit(), and ast_write().
04454 { 04455 /* Device does not support DTMF tones, lets fake 04456 * it by doing our own generation. */ 04457 static const char * const dtmf_tones[] = { 04458 "941+1336", /* 0 */ 04459 "697+1209", /* 1 */ 04460 "697+1336", /* 2 */ 04461 "697+1477", /* 3 */ 04462 "770+1209", /* 4 */ 04463 "770+1336", /* 5 */ 04464 "770+1477", /* 6 */ 04465 "852+1209", /* 7 */ 04466 "852+1336", /* 8 */ 04467 "852+1477", /* 9 */ 04468 "697+1633", /* A */ 04469 "770+1633", /* B */ 04470 "852+1633", /* C */ 04471 "941+1633", /* D */ 04472 "941+1209", /* * */ 04473 "941+1477" /* # */ 04474 }; 04475 04476 if (!chan->tech->send_digit_begin) 04477 return 0; 04478 04479 if (!chan->tech->send_digit_begin(chan, digit)) 04480 return 0; 04481 04482 if (digit >= '0' && digit <='9') 04483 ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0); 04484 else if (digit >= 'A' && digit <= 'D') 04485 ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0); 04486 else if (digit == '*') 04487 ast_playtones_start(chan, 0, dtmf_tones[14], 0); 04488 else if (digit == '#') 04489 ast_playtones_start(chan, 0, dtmf_tones[15], 0); 04490 else { 04491 /* not handled */ 04492 ast_debug(1, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name); 04493 } 04494 04495 return 0; 04496 }
int ast_senddigit_end | ( | struct ast_channel * | chan, | |
char | digit, | |||
unsigned int | duration | |||
) |
Send a DTMF digit to a channel.
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 4498 of file channel.c.
References ast_playtones_stop(), chanlist::chan, ast_channel::generator, ast_channel_tech::send_digit_end, and ast_channel::tech.
Referenced by agent_digit_end(), ast_senddigit(), and ast_write().
04499 { 04500 int res = -1; 04501 04502 if (chan->tech->send_digit_end) 04503 res = chan->tech->send_digit_end(chan, digit, duration); 04504 04505 if (res && chan->generator) 04506 ast_playtones_stop(chan); 04507 04508 return 0; 04509 }
int ast_sendtext | ( | struct ast_channel * | chan, | |
const char * | text | |||
) |
Sends text to a channel.
chan | channel to act upon | |
text | string of text to send on the channel |
0 | on success | |
-1 | on failure |
Definition at line 4440 of file channel.c.
References ast_check_hangup(), ast_clear_flag, AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_test_flag, chanlist::chan, CHECK_BLOCKING, ast_channel_tech::send_text, and ast_channel::tech.
Referenced by action_sendtext(), agent_sendtext(), handle_sendtext(), send_newkey(), and sendtext_exec().
04441 { 04442 int res = 0; 04443 /* Stop if we're a zombie or need a soft hangup */ 04444 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) 04445 return -1; 04446 CHECK_BLOCKING(chan); 04447 if (chan->tech->send_text) 04448 res = chan->tech->send_text(chan, text); 04449 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04450 return res; 04451 }
void ast_set_callerid | ( | struct ast_channel * | chan, | |
const char * | cid_num, | |||
const char * | cid_name, | |||
const char * | cid_ani | |||
) |
Set caller ID number, name and ANI and generate AMI event.
The channel does not need to be locked before calling this function.
Definition at line 6572 of file channel.c.
References ast_party_caller::ani, ast_cdr_setcid(), ast_channel_lock, ast_channel_unlock, ast_free, ast_strdup, ast_channel::caller, ast_channel::cdr, chanlist::chan, ast_party_caller::id, ast_party_id::name, ast_party_id::number, report_new_callerid(), ast_party_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(), ast_call_forward(), cb_events(), dial_exec_full(), do_forward(), findmeexec(), get_pai(), get_rpid(), handle_setcallerid(), mgcp_ss(), ring_entry(), rpt_exec(), skinny_newcall(), and socket_process().
06573 { 06574 ast_channel_lock(chan); 06575 06576 if (cid_num) { 06577 chan->caller.id.number.valid = 1; 06578 ast_free(chan->caller.id.number.str); 06579 chan->caller.id.number.str = ast_strdup(cid_num); 06580 } 06581 if (cid_name) { 06582 chan->caller.id.name.valid = 1; 06583 ast_free(chan->caller.id.name.str); 06584 chan->caller.id.name.str = ast_strdup(cid_name); 06585 } 06586 if (cid_ani) { 06587 chan->caller.ani.number.valid = 1; 06588 ast_free(chan->caller.ani.number.str); 06589 chan->caller.ani.number.str = ast_strdup(cid_ani); 06590 } 06591 if (chan->cdr) { 06592 ast_cdr_setcid(chan->cdr, chan); 06593 } 06594 06595 report_new_callerid(chan); 06596 06597 ast_channel_unlock(chan); 06598 }
void ast_set_hangupsource | ( | struct ast_channel * | chan, | |
const char * | source, | |||
int | force | |||
) |
Set the source of the hangup in this channel and it's bridge.
chan | channel to set the field on | |
source | a string describing the source of the hangup for this channel | |
force |
Definition at line 2639 of file channel.c.
References ast_bridged_channel(), ast_channel_lock, ast_channel_unlock, ast_string_field_set, ast_strlen_zero(), ast_channel::bridge, chanlist::chan, and ast_channel::hangupsource.
Referenced by __dahdi_exception(), func_channel_write_real(), handle_hangup(), handle_request_bye(), handle_request_cancel(), handle_response_invite(), pbx_builtin_hangup(), and set_hangup_source_and_cause().
02640 { 02641 struct ast_channel *bridge; 02642 02643 ast_channel_lock(chan); 02644 if (force || ast_strlen_zero(chan->hangupsource)) { 02645 ast_string_field_set(chan, hangupsource, source); 02646 } 02647 bridge = ast_bridged_channel(chan); 02648 ast_channel_unlock(chan); 02649 02650 if (bridge && (force || ast_strlen_zero(bridge->hangupsource))) { 02651 ast_channel_lock(bridge); 02652 ast_string_field_set(chan, hangupsource, source); 02653 ast_channel_unlock(bridge); 02654 } 02655 }
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 5022 of file channel.c.
References chanlist::chan, ast_channel::rawreadformat, ast_channel::readformat, ast_channel::readtrans, and set_format().
Referenced by __ast_play_and_record(), __oh323_update_info(), agent_call(), alarmreceiver_exec(), ast_adsi_transmit_message_full(), ast_channel_make_compatible_helper(), ast_do_masquerade(), attempt_reconnect(), background_detect_exec(), bridge_channel_join(), bridge_make_compatible(), build_conf(), conf_run(), connect_link(), dictate_exec(), do_waiting(), eagi_exec(), echo_exec(), generic_fax_exec(), gtalk_rtp_read(), handle_recordfile(), handle_speechrecognize(), ices_exec(), isAnsweringMachine(), jack_exec(), jingle_rtp_read(), login_exec(), measurenoise(), mgcp_rtp_read(), oh323_rtp_read(), old_milliwatt_exec(), process_sdp(), rpt(), rpt_exec(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_process(), speech_background(), transmit_audio(), and unistim_rtp_read().
05023 { 05024 return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat, 05025 &chan->readtrans, 0); 05026 }
void ast_set_variables | ( | struct ast_channel * | chan, | |
struct ast_variable * | vars | |||
) |
adds a list of channel variables to a channel
chan | the channel | |
vars | a linked list of variables |
Definition at line 7726 of file channel.c.
References ast_variable::name, ast_variable::next, pbx_builtin_setvar_helper(), and ast_variable::value.
Referenced by __ast_request_and_dial(), ast_call_forward(), ast_pbx_outgoing_app(), and ast_pbx_outgoing_exten().
07727 { 07728 struct ast_variable *cur; 07729 07730 for (cur = vars; cur; cur = cur->next) 07731 pbx_builtin_setvar_helper(chan, cur->name, cur->value); 07732 }
int ast_set_write_format | ( | struct ast_channel * | chan, | |
format_t | format | |||
) |
Sets write format on channel chan Set write format for channel to whichever component of "format" is best.
chan | channel to change | |
format | new format for writing |
Definition at line 5028 of file channel.c.
References chanlist::chan, ast_channel::rawwriteformat, set_format(), ast_channel::writeformat, and ast_channel::writetrans.
Referenced by __oh323_update_info(), agent_call(), alarmreceiver_exec(), ast_adsi_transmit_message_full(), ast_channel_make_compatible_helper(), ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_do_masquerade(), ast_openstream_full(), ast_stopstream(), attempt_reconnect(), bridge_channel_join(), bridge_make_compatible(), build_conf(), chanspy_exec(), conf_run(), connect_link(), dahdiscan_exec(), echo_exec(), extenspy_exec(), generic_fax_exec(), gtalk_rtp_read(), jack_exec(), jingle_rtp_read(), linear_alloc(), linear_release(), login_exec(), mgcp_rtp_read(), moh_alloc(), moh_files_release(), moh_release(), mp3_exec(), NBScat_exec(), oh323_rtp_read(), old_milliwatt_exec(), playtones_alloc(), playtones_release(), process_sdp(), rpt(), rpt_exec(), send_waveform_to_channel(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_process(), tonepair_alloc(), tonepair_release(), transmit_audio(), and unistim_rtp_read().
05029 { 05030 return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat, 05031 &chan->writetrans, 1); 05032 }
int ast_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 3381 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_debug, ast_timer_get_max_rate(), ast_timer_set_rate(), ast_channel::timer, ast_channel::timingdata, ast_channel::timingfd, and ast_channel::timingfunc.
Referenced by ast_activate_generator(), ast_closestream(), ast_deactivate_generator(), ast_read_generator_actions(), ast_readaudio_callback(), and filestream_destructor().
03382 { 03383 int res; 03384 unsigned int real_rate = rate, max_rate; 03385 03386 ast_channel_lock(c); 03387 03388 if (c->timingfd == -1) { 03389 ast_channel_unlock(c); 03390 return -1; 03391 } 03392 03393 if (!func) { 03394 rate = 0; 03395 data = NULL; 03396 } 03397 03398 if (rate && rate > (max_rate = ast_timer_get_max_rate(c->timer))) { 03399 real_rate = max_rate; 03400 } 03401 03402 ast_debug(1, "Scheduling timer at (%u requested / %u actual) timer ticks per second\n", rate, real_rate); 03403 03404 res = ast_timer_set_rate(c->timer, real_rate); 03405 03406 c->timingfunc = func; 03407 c->timingdata = data; 03408 03409 ast_channel_unlock(c); 03410 03411 return res; 03412 }
int ast_shutting_down | ( | void | ) |
Returns non-zero if Asterisk is being shut down.
Definition at line 795 of file channel.c.
Referenced by handle_request_options().
00796 { 00797 return shutting_down; 00798 }
int ast_softhangup | ( | struct ast_channel * | chan, | |
int | reason | |||
) |
Softly hangup up a channel.
chan | channel to be soft-hung-up | |
reason | an AST_SOFTHANGUP_* reason code |
Definition at line 2616 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_softhangup_nolock(), and chanlist::chan.
Referenced by __analog_handle_event(), __ast_module_user_hangup_all(), __unload_module(), agent_hangup(), agent_logoff(), agent_read(), ast_channel_softhangup_cb(), ast_dial_join(), birdbath(), cc_generic_agent_stop_ringing(), conf_free(), connect_link(), dahdi_handle_event(), flush_telem(), function_ilink(), handle_hangup(), handle_link_data(), handle_softhangup(), login_exec(), manager_park(), mgcp_pktcgate_remove(), read_agent_config(), rpt(), rpt_call(), rpt_do_restart(), rpt_exec(), sla_handle_hold_event(), softhangup_exec(), start_spying(), startmon(), and unload_module().
02617 { 02618 int res; 02619 02620 ast_channel_lock(chan); 02621 res = ast_softhangup_nolock(chan, cause); 02622 ast_channel_unlock(chan); 02623 02624 return res; 02625 }
int ast_softhangup_nolock | ( | struct ast_channel * | chan, | |
int | reason | |||
) |
Softly hangup up a channel (no channel lock).
chan | channel to be soft-hung-up | |
reason | an AST_SOFTHANGUP_* reason code |
Definition at line 2603 of file channel.c.
References ast_channel::_softhangup, ast_debug, AST_FLAG_BLOCKING, ast_null_frame, ast_queue_frame(), ast_test_flag, ast_channel::blocker, chanlist::chan, and ast_channel::name.
Referenced by __analog_handle_event(), action_hangup(), ast_async_goto(), ast_softhangup(), attempt_transfer(), check_pendings(), check_rtp_timeout(), dahdi_softhangup_all(), oh323_indicate(), proc_session_timer(), sig_pri_indicate(), sip_indicate(), and skinny_indicate().
02604 { 02605 ast_debug(1, "Soft-Hanging up channel '%s'\n", chan->name); 02606 /* Inform channel driver that we need to be hung up, if it cares */ 02607 chan->_softhangup |= cause; 02608 ast_queue_frame(chan, &ast_null_frame); 02609 /* Interrupt any poll call or such */ 02610 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) 02611 pthread_kill(chan->blocker, SIGURG); 02612 return 0; 02613 }
const char* ast_state2str | ( | enum ast_channel_state | state | ) |
Gives the string form of a given channel state.
Definition at line 937 of file channel.c.
References AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DIALING_OFFHOOK, AST_STATE_DOWN, AST_STATE_OFFHOOK, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_threadstorage_get(), STATE2STR_BUFSIZE, and state2str_threadbuf.
Referenced by __ast_channel_alloc_ap(), action_coreshowchannels(), agent_hangup(), ast_channel_data_add_structure(), ast_do_masquerade(), ast_setstate(), attempt_transfer(), func_channel_read(), handle_chanlist(), handle_showchan(), local_attended_transfer(), mgcp_new(), serialize_showchan(), sip_hangup(), and update_connectedline().
00938 { 00939 char *buf; 00940 00941 switch (state) { 00942 case AST_STATE_DOWN: 00943 return "Down"; 00944 case AST_STATE_RESERVED: 00945 return "Rsrvd"; 00946 case AST_STATE_OFFHOOK: 00947 return "OffHook"; 00948 case AST_STATE_DIALING: 00949 return "Dialing"; 00950 case AST_STATE_RING: 00951 return "Ring"; 00952 case AST_STATE_RINGING: 00953 return "Ringing"; 00954 case AST_STATE_UP: 00955 return "Up"; 00956 case AST_STATE_BUSY: 00957 return "Busy"; 00958 case AST_STATE_DIALING_OFFHOOK: 00959 return "Dialing Offhook"; 00960 case AST_STATE_PRERING: 00961 return "Pre-ring"; 00962 default: 00963 if (!(buf = ast_threadstorage_get(&state2str_threadbuf, STATE2STR_BUFSIZE))) 00964 return "Unknown"; 00965 snprintf(buf, STATE2STR_BUFSIZE, "Unknown (%d)", state); 00966 return buf; 00967 } 00968 }
int ast_str2cause | ( | const char * | name | ) |
Convert the string form of a cause code to a number.
name | string form of the cause |
Definition at line 923 of file channel.c.
References ARRAY_LEN, and causes.
Referenced by pbx_builtin_hangup().
00924 { 00925 int x; 00926 00927 for (x = 0; x < ARRAY_LEN(causes); x++) 00928 if (!strncasecmp(causes[x].name, name, strlen(causes[x].name))) 00929 return causes[x].cause; 00930 00931 return -1; 00932 }
int ast_tonepair | ( | struct ast_channel * | chan, | |
int | freq1, | |||
int | freq2, | |||
int | duration, | |||
int | vol | |||
) |
Play a tone pair for a given amount of time
Definition at line 7446 of file channel.c.
References ast_frfree, ast_read(), ast_tonepair_start(), ast_waitfor(), f, and ast_channel::generatordata.
Referenced by zapateller_exec().
07447 { 07448 int res; 07449 07450 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol))) 07451 return res; 07452 07453 /* Give us some wiggle room */ 07454 while (chan->generatordata && ast_waitfor(chan, 100) >= 0) { 07455 struct ast_frame *f = ast_read(chan); 07456 if (f) 07457 ast_frfree(f); 07458 else 07459 return -1; 07460 } 07461 return 0; 07462 }
int ast_tonepair_start | ( | struct ast_channel * | chan, | |
int | freq1, | |||
int | freq2, | |||
int | duration, | |||
int | vol | |||
) |
Start a tone going
Definition at line 7428 of file channel.c.
References ast_activate_generator(), tonepair_def::duration, tonepair_def::freq1, tonepair_def::freq2, tonepair, and tonepair_def::vol.
Referenced by ast_tonepair(), pbx_builtin_waitexten(), play_dialtone(), play_tone_pair(), rpt_tele_thread(), and sendnoise().
07429 { 07430 struct tonepair_def d = { 0, }; 07431 07432 d.freq1 = freq1; 07433 d.freq2 = freq2; 07434 d.duration = duration; 07435 d.vol = (vol < 1) ? 8192 : vol; /* force invalid to 8192 */ 07436 if (ast_activate_generator(chan, &tonepair, &d)) 07437 return -1; 07438 return 0; 07439 }
void ast_tonepair_stop | ( | struct ast_channel * | chan | ) |
Stop a tone from playing
Definition at line 7441 of file channel.c.
References ast_deactivate_generator().
Referenced by sendnoise().
07442 { 07443 ast_deactivate_generator(chan); 07444 }
int ast_transfer | ( | struct ast_channel * | chan, | |
char * | dest | |||
) |
Transfer a channel (if supported).
Called by:
Definition at line 5448 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_CONTROL_TRANSFER, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, ast_frfree, ast_read(), ast_test_flag, AST_TRANSFER_SUCCESS, ast_waitfor(), chanlist::chan, ast_channel::tech, and ast_channel_tech::transfer.
Referenced by transfer_exec().
05449 { 05450 int res = -1; 05451 05452 /* Stop if we're a zombie or need a soft hangup */ 05453 ast_channel_lock(chan); 05454 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) { 05455 if (chan->tech->transfer) { 05456 res = chan->tech->transfer(chan, dest); 05457 if (!res) 05458 res = 1; 05459 } else 05460 res = 0; 05461 } 05462 ast_channel_unlock(chan); 05463 05464 if (res <= 0) { 05465 return res; 05466 } 05467 05468 for (;;) { 05469 struct ast_frame *fr; 05470 05471 res = ast_waitfor(chan, -1); 05472 05473 if (res < 0 || !(fr = ast_read(chan))) { 05474 res = -1; 05475 break; 05476 } 05477 05478 if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_TRANSFER) { 05479 enum ast_control_transfer *message = fr->data.ptr; 05480 05481 if (*message == AST_TRANSFER_SUCCESS) { 05482 res = 1; 05483 } else { 05484 res = -1; 05485 } 05486 05487 ast_frfree(fr); 05488 break; 05489 } 05490 05491 ast_frfree(fr); 05492 } 05493 05494 return res; 05495 }
char* ast_transfercapability2str | ( | int | transfercapability | ) | const |
Gives the string form of a given transfer capability.
transfercapability | transfer capability to get the name of |
Definition at line 971 of file channel.c.
References AST_TRANS_CAP_3_1K_AUDIO, AST_TRANS_CAP_DIGITAL, AST_TRANS_CAP_DIGITAL_W_TONES, AST_TRANS_CAP_RESTRICTED_DIGITAL, AST_TRANS_CAP_SPEECH, and AST_TRANS_CAP_VIDEO.
Referenced by ast_channel_data_add_structure(), cb_events(), misdn_call(), oh323_call(), sig_pri_call(), sig_pri_new_ast_channel(), and sig_ss7_new_ast_channel().
00972 { 00973 switch (transfercapability) { 00974 case AST_TRANS_CAP_SPEECH: 00975 return "SPEECH"; 00976 case AST_TRANS_CAP_DIGITAL: 00977 return "DIGITAL"; 00978 case AST_TRANS_CAP_RESTRICTED_DIGITAL: 00979 return "RESTRICTED_DIGITAL"; 00980 case AST_TRANS_CAP_3_1K_AUDIO: 00981 return "3K1AUDIO"; 00982 case AST_TRANS_CAP_DIGITAL_W_TONES: 00983 return "DIGITAL_W_TONES"; 00984 case AST_TRANS_CAP_VIDEO: 00985 return "VIDEO"; 00986 default: 00987 return "UNKNOWN"; 00988 } 00989 }
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 3365 of file channel.c.
References ast_waitfor_nandfds().
Referenced by __adsi_transmit_messages(), __analog_ss_thread(), __ast_answer(), __ast_play_and_record(), __ast_request_and_dial(), adsi_careful_send(), agent_ack_sleep(), analog_ss_thread(), ast_dtmf_stream(), ast_recvtext(), ast_safe_sleep_conditional(), ast_tonepair(), ast_transfer(), async_wait(), background_detect_exec(), channel_spy(), conf_flush(), dictate_exec(), disa_exec(), disable_t38(), do_idle_thread(), do_waiting(), echo_exec(), handle_recordfile(), handle_speechrecognize(), ices_exec(), isAnsweringMachine(), jack_exec(), launch_asyncagi(), measurenoise(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), receivefax_t38_init(), recordthread(), send_tone_burst(), send_waveform_to_channel(), sendfax_t38_init(), sendurl_exec(), speech_background(), transmit_audio(), transmit_t38(), wait_for_hangup(), waitforring_exec(), and waitstream_core().
03366 { 03367 int oldms = ms; /* -1 if no timeout */ 03368 03369 ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms); 03370 if ((ms < 0) && (oldms < 0)) 03371 ms = 0; 03372 return ms; 03373 }
struct ast_channel* ast_waitfor_n | ( | struct ast_channel ** | chan, | |
int | n, | |||
int * | ms | |||
) |
Waits for input on a group of channels Wait for input on an array of channels for a given # of milliseconds.
chan | an array of pointers to channels | |
n | number of channels that are to be waited upon | |
ms | time "ms" is modified in-place, if applicable |
Definition at line 3360 of file channel.c.
References ast_waitfor_nandfds().
Referenced by ast_udptl_bridge(), autoservice_run(), dahdi_bridge(), dial_exec_full(), feature_request_and_dial(), generic_thread_loop(), misdn_bridge(), monitor_dial(), remote_bridge_loop(), rpt(), wait_for_answer(), and wait_for_winner().
03361 { 03362 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms); 03363 }
int ast_waitfor_n_fd | ( | int * | fds, | |
int | n, | |||
int * | ms, | |||
int * | exception | |||
) |
Waits for input on an fd.
Definition at line 3001 of file channel.c.
References ast_waitfor_nandfds().
Referenced by dundi_lookup_internal(), dundi_precache_internal(), and softmix_bridge_thread().
03002 { 03003 int winner = -1; 03004 ast_waitfor_nandfds(NULL, 0, fds, n, exception, &winner, ms); 03005 return winner; 03006 }
struct ast_channel* ast_waitfor_nandfds | ( | struct ast_channel ** | chan, | |
int | n, | |||
int * | fds, | |||
int | nfds, | |||
int * | exception, | |||
int * | outfd, | |||
int * | ms | |||
) |
Waits for activity on a group of channels.
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 3013 of file channel.c.
References ast_channel::_softhangup, ast_add_fd(), ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, ast_log(), AST_MAX_FDS, ast_poll, ast_set_flag, AST_SOFTHANGUP_TIMEOUT, ast_tvcmp(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), chanlist::chan, CHECK_BLOCKING, errno, and LOG_WARNING.
Referenced by ast_waitfor(), ast_waitfor_n(), ast_waitfor_n_fd(), ast_waitfordigit_full(), conf_run(), eivr_comm(), find_cache(), generic_fax_exec(), multiplexed_thread_function(), run_agi(), and waitstream_core().
03016 { 03017 struct timeval start = { 0 , 0 }; 03018 struct pollfd *pfds = NULL; 03019 int res; 03020 long rms; 03021 int x, y, max; 03022 int sz; 03023 struct timeval now = { 0, 0 }; 03024 struct timeval whentohangup = { 0, 0 }, diff; 03025 struct ast_channel *winner = NULL; 03026 struct fdmap { 03027 int chan; 03028 int fdno; 03029 } *fdmap = NULL; 03030 03031 if ((sz = n * AST_MAX_FDS + nfds)) { 03032 pfds = alloca(sizeof(*pfds) * sz); 03033 fdmap = alloca(sizeof(*fdmap) * sz); 03034 } 03035 03036 if (outfd) 03037 *outfd = -99999; 03038 if (exception) 03039 *exception = 0; 03040 03041 /* Perform any pending masquerades */ 03042 for (x = 0; x < n; x++) { 03043 if (c[x]->masq && ast_do_masquerade(c[x])) { 03044 ast_log(LOG_WARNING, "Masquerade failed\n"); 03045 *ms = -1; 03046 return NULL; 03047 } 03048 03049 ast_channel_lock(c[x]); 03050 if (!ast_tvzero(c[x]->whentohangup)) { 03051 if (ast_tvzero(whentohangup)) 03052 now = ast_tvnow(); 03053 diff = ast_tvsub(c[x]->whentohangup, now); 03054 if (diff.tv_sec < 0 || ast_tvzero(diff)) { 03055 /* Should already be hungup */ 03056 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 03057 ast_channel_unlock(c[x]); 03058 return c[x]; 03059 } 03060 if (ast_tvzero(whentohangup) || ast_tvcmp(diff, whentohangup) < 0) 03061 whentohangup = diff; 03062 } 03063 ast_channel_unlock(c[x]); 03064 } 03065 /* Wait full interval */ 03066 rms = *ms; 03067 /* INT_MAX, not LONG_MAX, because it matters on 64-bit */ 03068 if (!ast_tvzero(whentohangup) && whentohangup.tv_sec < INT_MAX / 1000) { 03069 rms = whentohangup.tv_sec * 1000 + whentohangup.tv_usec / 1000; /* timeout in milliseconds */ 03070 if (*ms >= 0 && *ms < rms) { /* original *ms still smaller */ 03071 rms = *ms; 03072 } 03073 } else if (!ast_tvzero(whentohangup) && rms < 0) { 03074 /* Tiny corner case... call would need to last >24 days */ 03075 rms = INT_MAX; 03076 } 03077 /* 03078 * Build the pollfd array, putting the channels' fds first, 03079 * followed by individual fds. Order is important because 03080 * individual fd's must have priority over channel fds. 03081 */ 03082 max = 0; 03083 for (x = 0; x < n; x++) { 03084 for (y = 0; y < AST_MAX_FDS; y++) { 03085 fdmap[max].fdno = y; /* fd y is linked to this pfds */ 03086 fdmap[max].chan = x; /* channel x is linked to this pfds */ 03087 max += ast_add_fd(&pfds[max], c[x]->fds[y]); 03088 } 03089 CHECK_BLOCKING(c[x]); 03090 } 03091 /* Add the individual fds */ 03092 for (x = 0; x < nfds; x++) { 03093 fdmap[max].chan = -1; 03094 max += ast_add_fd(&pfds[max], fds[x]); 03095 } 03096 03097 if (*ms > 0) 03098 start = ast_tvnow(); 03099 03100 if (sizeof(int) == 4) { /* XXX fix timeout > 600000 on linux x86-32 */ 03101 do { 03102 int kbrms = rms; 03103 if (kbrms > 600000) 03104 kbrms = 600000; 03105 res = ast_poll(pfds, max, kbrms); 03106 if (!res) 03107 rms -= kbrms; 03108 } while (!res && (rms > 0)); 03109 } else { 03110 res = ast_poll(pfds, max, rms); 03111 } 03112 for (x = 0; x < n; x++) 03113 ast_clear_flag(c[x], AST_FLAG_BLOCKING); 03114 if (res < 0) { /* Simulate a timeout if we were interrupted */ 03115 if (errno != EINTR) 03116 *ms = -1; 03117 return NULL; 03118 } 03119 if (!ast_tvzero(whentohangup)) { /* if we have a timeout, check who expired */ 03120 now = ast_tvnow(); 03121 for (x = 0; x < n; x++) { 03122 if (!ast_tvzero(c[x]->whentohangup) && ast_tvcmp(c[x]->whentohangup, now) <= 0) { 03123 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 03124 if (winner == NULL) 03125 winner = c[x]; 03126 } 03127 } 03128 } 03129 if (res == 0) { /* no fd ready, reset timeout and done */ 03130 *ms = 0; /* XXX use 0 since we may not have an exact timeout. */ 03131 return winner; 03132 } 03133 /* 03134 * Then check if any channel or fd has a pending event. 03135 * Remember to check channels first and fds last, as they 03136 * must have priority on setting 'winner' 03137 */ 03138 for (x = 0; x < max; x++) { 03139 res = pfds[x].revents; 03140 if (res == 0) 03141 continue; 03142 if (fdmap[x].chan >= 0) { /* this is a channel */ 03143 winner = c[fdmap[x].chan]; /* override previous winners */ 03144 if (res & POLLPRI) 03145 ast_set_flag(winner, AST_FLAG_EXCEPTION); 03146 else 03147 ast_clear_flag(winner, AST_FLAG_EXCEPTION); 03148 winner->fdno = fdmap[x].fdno; 03149 } else { /* this is an fd */ 03150 if (outfd) 03151 *outfd = pfds[x].fd; 03152 if (exception) 03153 *exception = (res & POLLPRI) ? -1 : 0; 03154 winner = NULL; 03155 } 03156 } 03157 if (*ms > 0) { 03158 *ms -= ast_tvdiff_ms(ast_tvnow(), start); 03159 if (*ms < 0) 03160 *ms = 0; 03161 } 03162 return winner; 03163 }
int ast_waitfordigit | ( | struct ast_channel * | c, | |
int | ms | |||
) |
Waits for a digit.
c | channel to wait for a digit on | |
ms | how many milliseconds to wait |
Definition at line 3376 of file channel.c.
References ast_waitfordigit_full().
Referenced by __analog_ss_thread(), _while_exec(), advanced_options(), analog_my_getsigstr(), analog_ss_thread(), ast_adsi_get_cpeid(), ast_adsi_get_cpeinfo(), ast_adsi_print(), ast_adsi_read_encoded_dtmf(), ast_adsi_transmit_message_full(), ast_app_dtget(), ast_control_streamfile(), ast_record_review(), bridge_channel_feature(), builtin_atxfer(), collect_digits(), common_exec(), cpeid_exec(), dialout(), directory_exec(), forward_message(), get_folder(), ivr_dispatch(), mgcp_ss(), my_getsigstr(), pbx_builtin_waitexten(), play_record_review(), pri_ss_thread(), read_exec(), read_newoption(), readexten_exec(), retrydial_exec(), select_item_menu(), select_item_pause(), select_item_seq(), sendnoise(), testclient_exec(), testserver_exec(), vm_execmain(), vm_forwardoptions(), vm_instructions_en(), vm_options(), vm_tempgreeting(), and wait_a_bit().
03377 { 03378 return ast_waitfordigit_full(c, ms, -1, -1); 03379 }
int ast_waitfordigit_full | ( | struct ast_channel * | c, | |
int | ms, | |||
int | audiofd, | |||
int | ctrlfd | |||
) |
Wait for a digit Same as ast_waitfordigit() with audio fd for outputting read audio and ctrlfd to monitor for reading.
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 3414 of file channel.c.
References ast_check_hangup(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_FLAG_END_DTMF_ONLY, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_frfree, ast_log(), ast_read(), ast_set_flag, ast_test_flag, ast_waitfor_nandfds(), errno, f, and LOG_WARNING.
Referenced by ast_readstring_full(), ast_waitfordigit(), handle_getoption(), and handle_waitfordigit().
03415 { 03416 /* Stop if we're a zombie or need a soft hangup */ 03417 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 03418 return -1; 03419 03420 /* Only look for the end of DTMF, don't bother with the beginning and don't emulate things */ 03421 ast_set_flag(c, AST_FLAG_END_DTMF_ONLY); 03422 03423 /* Wait for a digit, no more than ms milliseconds total. */ 03424 03425 while (ms) { 03426 struct ast_channel *rchan; 03427 int outfd=-1; 03428 03429 errno = 0; 03430 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 03431 03432 if (!rchan && outfd < 0 && ms) { 03433 if (errno == 0 || errno == EINTR) 03434 continue; 03435 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 03436 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03437 return -1; 03438 } else if (outfd > -1) { 03439 /* The FD we were watching has something waiting */ 03440 ast_log(LOG_WARNING, "The FD we were waiting for has something waiting. Waitfordigit returning numeric 1\n"); 03441 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03442 return 1; 03443 } else if (rchan) { 03444 int res; 03445 struct ast_frame *f = ast_read(c); 03446 if (!f) 03447 return -1; 03448 03449 switch (f->frametype) { 03450 case AST_FRAME_DTMF_BEGIN: 03451 break; 03452 case AST_FRAME_DTMF_END: 03453 res = f->subclass.integer; 03454 ast_frfree(f); 03455 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03456 return res; 03457 case AST_FRAME_CONTROL: 03458 switch (f->subclass.integer) { 03459 case AST_CONTROL_HANGUP: 03460 ast_frfree(f); 03461 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03462 return -1; 03463 case AST_CONTROL_RINGING: 03464 case AST_CONTROL_ANSWER: 03465 case AST_CONTROL_SRCUPDATE: 03466 case AST_CONTROL_SRCCHANGE: 03467 case AST_CONTROL_CONNECTED_LINE: 03468 case AST_CONTROL_REDIRECTING: 03469 case -1: 03470 /* Unimportant */ 03471 break; 03472 default: 03473 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass.integer); 03474 break; 03475 } 03476 break; 03477 case AST_FRAME_VOICE: 03478 /* Write audio if appropriate */ 03479 if (audiofd > -1) { 03480 if (write(audiofd, f->data.ptr, f->datalen) < 0) { 03481 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 03482 } 03483 } 03484 default: 03485 /* Ignore */ 03486 break; 03487 } 03488 ast_frfree(f); 03489 } 03490 } 03491 03492 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03493 03494 return 0; /* Time is up */ 03495 }
int ast_write | ( | struct ast_channel * | chan, | |
struct ast_frame * | frame | |||
) |
Write a frame to a channel This function writes the given frame to the indicated channel.
chan | destination channel of the frame | |
frame | frame that will be written |
Definition at line 4653 of file channel.c.
References ast_channel::_softhangup, apply_plc(), ast_audiohook_detach_list(), AST_AUDIOHOOK_DIRECTION_WRITE, ast_audiohook_write_list(), ast_audiohook_write_list_empty(), ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_CONTROL_UNHOLD, ast_deactivate_generator(), ast_debug, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_WRITE_INT, AST_FLAG_ZOMBIE, ast_format_rate(), AST_FORMAT_SLINEAR, AST_FORMAT_T140, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_frame_dump(), AST_FRAME_HTML, AST_FRAME_IAX, AST_FRAME_MODEM, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_framehook_list_write_event(), ast_frfree, ast_frisolate(), AST_LIST_NEXT, ast_log(), AST_MONITOR_RUNNING, ast_opt_generic_plc, ast_seekstream(), ast_senddigit_begin(), ast_senddigit_end(), AST_SOFTHANGUP_DEV, ast_test_flag, ast_translate(), ast_writestream(), ast_channel::audiohooks, calc_monitor_jump(), chanlist::chan, CHECK_BLOCKING, ast_frame_subclass::codec, ast_frame::data, ast_frame::datalen, DEBUGCHAN_FLAG, f, ast_filestream::fmt, ast_format::format, ast_channel::fout, FRAMECOUNT_INC, ast_channel::framehooks, ast_frame::frametype, ast_channel::generatordata, ast_channel_tech::indicate, ast_channel::insmpl, ast_frame_subclass::integer, ast_frame::len, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::name, chanlist::next, ast_channel::outsmpl, ast_frame::ptr, ast_channel::rawwriteformat, ast_channel_monitor::read_stream, ast_frame::samples, SEEK_FORCECUR, send_dtmf_event(), ast_channel_tech::send_html, ast_channel_tech::send_text, ast_frame::src, ast_channel_monitor::state, ast_frame::subclass, ast_channel::tech, ast_channel_tech::write, ast_channel_monitor::write_stream, ast_channel_tech::write_text, ast_channel_tech::write_video, and ast_channel::writetrans.
Referenced by adsi_careful_send(), agent_write(), ast_prod(), ast_readaudio_callback(), ast_readvideo_callback(), ast_udptl_bridge(), ast_write_video(), conf_queue_dtmf(), conf_run(), dahdi_bridge(), dictate_exec(), echo_exec(), fax_generator_generate(), feature_request_and_dial(), function_ilink(), gen_generate(), generic_fax_exec(), handle_jack_audio(), handle_link_data(), jb_get_and_deliver(), linear_generator(), milliwatt_generate(), misdn_bridge(), moh_files_generator(), moh_generate(), mp3_exec(), multiplexed_bridge_write(), NBScat_exec(), remote_bridge_loop(), rpt(), send_link_dtmf(), send_link_keyquery(), send_tone_burst(), send_usb_txt(), send_waveform_to_channel(), silence_generator_generate(), simple_bridge_write(), softmix_bridge_poke(), softmix_bridge_write(), spy_generate(), and t38_tx_packet_handler().
04654 { 04655 int res = -1; 04656 struct ast_frame *f = NULL; 04657 int count = 0; 04658 04659 /*Deadlock avoidance*/ 04660 while(ast_channel_trylock(chan)) { 04661 /*cannot goto done since the channel is not locked*/ 04662 if(count++ > 10) { 04663 ast_debug(1, "Deadlock avoided for write to channel '%s'\n", chan->name); 04664 return 0; 04665 } 04666 usleep(1); 04667 } 04668 /* Stop if we're a zombie or need a soft hangup */ 04669 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) 04670 goto done; 04671 04672 /* Handle any pending masquerades */ 04673 if (chan->masq) { 04674 ast_channel_unlock(chan); 04675 if (ast_do_masquerade(chan)) { 04676 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 04677 return res; /* no need to goto done: chan is already unlocked for masq */ 04678 } 04679 ast_channel_lock(chan); 04680 } 04681 if (chan->masqr) { 04682 res = 0; /* XXX explain, why 0 ? */ 04683 goto done; 04684 } 04685 04686 /* Perform the framehook write event here. After the frame enters the framehook list 04687 * there is no telling what will happen, how awesome is that!!! */ 04688 if (!(fr = ast_framehook_list_write_event(chan->framehooks, fr))) { 04689 res = 0; 04690 goto done; 04691 } 04692 04693 if (chan->generatordata && (!fr->src || strcasecmp(fr->src, "ast_prod"))) { 04694 if (ast_test_flag(chan, AST_FLAG_WRITE_INT)) { 04695 ast_deactivate_generator(chan); 04696 } else { 04697 if (fr->frametype == AST_FRAME_DTMF_END) { 04698 /* There is a generator running while we're in the middle of a digit. 04699 * It's probably inband DTMF, so go ahead and pass it so it can 04700 * stop the generator */ 04701 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04702 ast_channel_unlock(chan); 04703 res = ast_senddigit_end(chan, fr->subclass.integer, fr->len); 04704 ast_channel_lock(chan); 04705 CHECK_BLOCKING(chan); 04706 } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_UNHOLD) { 04707 /* This is a side case where Echo is basically being called and the person put themselves on hold and took themselves off hold */ 04708 res = (chan->tech->indicate == NULL) ? 0 : 04709 chan->tech->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen); 04710 } 04711 res = 0; /* XXX explain, why 0 ? */ 04712 goto done; 04713 } 04714 } 04715 /* High bit prints debugging */ 04716 if (chan->fout & DEBUGCHAN_FLAG) 04717 ast_frame_dump(chan->name, fr, ">>"); 04718 CHECK_BLOCKING(chan); 04719 switch (fr->frametype) { 04720 case AST_FRAME_CONTROL: 04721 res = (chan->tech->indicate == NULL) ? 0 : 04722 chan->tech->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen); 04723 break; 04724 case AST_FRAME_DTMF_BEGIN: 04725 if (chan->audiohooks) { 04726 struct ast_frame *old_frame = fr; 04727 fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr); 04728 if (old_frame != fr) 04729 f = fr; 04730 } 04731 send_dtmf_event(chan, "Sent", fr->subclass.integer, "Yes", "No"); 04732 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04733 ast_channel_unlock(chan); 04734 res = ast_senddigit_begin(chan, fr->subclass.integer); 04735 ast_channel_lock(chan); 04736 CHECK_BLOCKING(chan); 04737 break; 04738 case AST_FRAME_DTMF_END: 04739 if (chan->audiohooks) { 04740 struct ast_frame *new_frame = fr; 04741 04742 new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr); 04743 if (new_frame != fr) { 04744 ast_frfree(new_frame); 04745 } 04746 } 04747 send_dtmf_event(chan, "Sent", fr->subclass.integer, "No", "Yes"); 04748 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04749 ast_channel_unlock(chan); 04750 res = ast_senddigit_end(chan, fr->subclass.integer, fr->len); 04751 ast_channel_lock(chan); 04752 CHECK_BLOCKING(chan); 04753 break; 04754 case AST_FRAME_TEXT: 04755 if (fr->subclass.integer == AST_FORMAT_T140) { 04756 res = (chan->tech->write_text == NULL) ? 0 : 04757 chan->tech->write_text(chan, fr); 04758 } else { 04759 res = (chan->tech->send_text == NULL) ? 0 : 04760 chan->tech->send_text(chan, (char *) fr->data.ptr); 04761 } 04762 break; 04763 case AST_FRAME_HTML: 04764 res = (chan->tech->send_html == NULL) ? 0 : 04765 chan->tech->send_html(chan, fr->subclass.integer, (char *) fr->data.ptr, fr->datalen); 04766 break; 04767 case AST_FRAME_VIDEO: 04768 /* XXX Handle translation of video codecs one day XXX */ 04769 res = (chan->tech->write_video == NULL) ? 0 : 04770 chan->tech->write_video(chan, fr); 04771 break; 04772 case AST_FRAME_MODEM: 04773 res = (chan->tech->write == NULL) ? 0 : 04774 chan->tech->write(chan, fr); 04775 break; 04776 case AST_FRAME_VOICE: 04777 if (chan->tech->write == NULL) 04778 break; /*! \todo XXX should return 0 maybe ? */ 04779 04780 if (ast_opt_generic_plc && fr->subclass.codec == AST_FORMAT_SLINEAR) { 04781 apply_plc(chan, fr); 04782 } 04783 04784 /* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */ 04785 if (fr->subclass.codec == chan->rawwriteformat) 04786 f = fr; 04787 else 04788 f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr; 04789 04790 if (!f) { 04791 res = 0; 04792 break; 04793 } 04794 04795 if (chan->audiohooks) { 04796 struct ast_frame *prev = NULL, *new_frame, *cur, *dup; 04797 int freeoldlist = 0; 04798 04799 if (f != fr) { 04800 freeoldlist = 1; 04801 } 04802 04803 /* Since ast_audiohook_write may return a new frame, and the cur frame is 04804 * an item in a list of frames, create a new list adding each cur frame back to it 04805 * regardless if the cur frame changes or not. */ 04806 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 04807 new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, cur); 04808 04809 /* if this frame is different than cur, preserve the end of the list, 04810 * free the old frames, and set cur to be the new frame */ 04811 if (new_frame != cur) { 04812 04813 /* doing an ast_frisolate here seems silly, but we are not guaranteed the new_frame 04814 * isn't part of local storage, meaning if ast_audiohook_write is called multiple 04815 * times it may override the previous frame we got from it unless we dup it */ 04816 if ((dup = ast_frisolate(new_frame))) { 04817 AST_LIST_NEXT(dup, frame_list) = AST_LIST_NEXT(cur, frame_list); 04818 if (freeoldlist) { 04819 AST_LIST_NEXT(cur, frame_list) = NULL; 04820 ast_frfree(cur); 04821 } 04822 if (new_frame != dup) { 04823 ast_frfree(new_frame); 04824 } 04825 cur = dup; 04826 } 04827 } 04828 04829 /* now, regardless if cur is new or not, add it to the new list, 04830 * if the new list has not started, cur will become the first item. */ 04831 if (prev) { 04832 AST_LIST_NEXT(prev, frame_list) = cur; 04833 } else { 04834 f = cur; /* set f to be the beginning of our new list */ 04835 } 04836 prev = cur; 04837 } 04838 } 04839 04840 /* If Monitor is running on this channel, then we have to write frames out there too */ 04841 /* the translator on chan->writetrans may have returned multiple frames 04842 from the single frame we passed in; if so, feed each one of them to the 04843 monitor */ 04844 if (chan->monitor && chan->monitor->write_stream) { 04845 struct ast_frame *cur; 04846 04847 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 04848 /* XXX must explain this code */ 04849 #ifndef MONITOR_CONSTANT_DELAY 04850 int jump = chan->insmpl - chan->outsmpl - 4 * cur->samples; 04851 if (jump >= 0) { 04852 jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format)); 04853 if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1) 04854 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 04855 chan->outsmpl += (chan->insmpl - chan->outsmpl) + cur->samples; 04856 } else { 04857 chan->outsmpl += cur->samples; 04858 } 04859 #else 04860 int jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format)); 04861 if (jump - MONITOR_DELAY >= 0) { 04862 if (ast_seekstream(chan->monitor->write_stream, jump - cur->samples, SEEK_FORCECUR) == -1) 04863 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 04864 chan->outsmpl += chan->insmpl - chan->outsmpl; 04865 } else { 04866 chan->outsmpl += cur->samples; 04867 } 04868 #endif 04869 if (chan->monitor->state == AST_MONITOR_RUNNING) { 04870 if (ast_writestream(chan->monitor->write_stream, cur) < 0) 04871 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n"); 04872 } 04873 } 04874 } 04875 04876 /* the translator on chan->writetrans may have returned multiple frames 04877 from the single frame we passed in; if so, feed each one of them to the 04878 channel, freeing each one after it has been written */ 04879 if ((f != fr) && AST_LIST_NEXT(f, frame_list)) { 04880 struct ast_frame *cur, *next; 04881 unsigned int skip = 0; 04882 04883 for (cur = f, next = AST_LIST_NEXT(cur, frame_list); 04884 cur; 04885 cur = next, next = cur ? AST_LIST_NEXT(cur, frame_list) : NULL) { 04886 if (!skip) { 04887 if ((res = chan->tech->write(chan, cur)) < 0) { 04888 chan->_softhangup |= AST_SOFTHANGUP_DEV; 04889 skip = 1; 04890 } else if (next) { 04891 /* don't do this for the last frame in the list, 04892 as the code outside the loop will do it once 04893 */ 04894 chan->fout = FRAMECOUNT_INC(chan->fout); 04895 } 04896 } 04897 ast_frfree(cur); 04898 } 04899 04900 /* reset f so the code below doesn't attempt to free it */ 04901 f = NULL; 04902 } else { 04903 res = chan->tech->write(chan, f); 04904 } 04905 break; 04906 case AST_FRAME_NULL: 04907 case AST_FRAME_IAX: 04908 /* Ignore these */ 04909 res = 0; 04910 break; 04911 default: 04912 /* At this point, fr is the incoming frame and f is NULL. Channels do 04913 * not expect to get NULL as a frame pointer and will segfault. Hence, 04914 * we output the original frame passed in. */ 04915 res = chan->tech->write(chan, fr); 04916 break; 04917 } 04918 04919 if (f && f != fr) 04920 ast_frfree(f); 04921 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04922 04923 /* Consider a write failure to force a soft hangup */ 04924 if (res < 0) { 04925 chan->_softhangup |= AST_SOFTHANGUP_DEV; 04926 } else { 04927 chan->fout = FRAMECOUNT_INC(chan->fout); 04928 } 04929 done: 04930 if (chan->audiohooks && ast_audiohook_write_list_empty(chan->audiohooks)) { 04931 /* The list gets recreated if audiohooks are added again later */ 04932 ast_audiohook_detach_list(chan->audiohooks); 04933 chan->audiohooks = NULL; 04934 } 04935 ast_channel_unlock(chan); 04936 return res; 04937 }
int ast_write_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 4538 of file channel.c.
References ast_write(), chanlist::chan, ast_channel::tech, and ast_channel_tech::write_video.
04539 { 04540 int res; 04541 if (!chan->tech->write_video) 04542 return 0; 04543 res = ast_write(chan, fr); 04544 if (!res) 04545 res = 1; 04546 return res; 04547 }
const char* channelreloadreason2txt | ( | enum channelreloadreason | reason | ) |
Convert enum channelreloadreason to text string for manager event.
\ brief Convert channel reloadreason (ENUM) to text string for manager event
Definition at line 7814 of file channel.c.
References CHANNEL_CLI_RELOAD, CHANNEL_MODULE_LOAD, and CHANNEL_MODULE_RELOAD.
07815 { 07816 switch (reason) { 07817 case CHANNEL_MODULE_LOAD: 07818 return "LOAD (Channel module load)"; 07819 07820 case CHANNEL_MODULE_RELOAD: 07821 return "RELOAD (Channel module reload)"; 07822 07823 case CHANNEL_CLI_RELOAD: 07824 return "CLIRELOAD (Channel module reload by CLI command)"; 07825 07826 default: 07827 return "MANAGERRELOAD (Channel module reload by manager)"; 07828 } 07829 };
unsigned long global_fin |
The current value of the debug flags is stored in the two variables global_fin and global_fout (declared in main/channel.c)
Definition at line 98 of file channel.c.
Referenced by handle_core_set_debug_channel().
unsigned long global_fout |