General Asterisk PBX channel definitions. More...
#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_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 |
Defines | |
#define | AST_AGENT_FD (AST_MAX_FDS-3) |
#define | AST_ALERT_FD (AST_MAX_FDS-1) |
#define | AST_BRIDGE_DTMF_CHANNEL_0 (1 << 0) |
Report DTMF on channel 0. | |
#define | AST_BRIDGE_DTMF_CHANNEL_1 (1 << 1) |
Report DTMF on channel 1. | |
#define | AST_BRIDGE_IGNORE_SIGS (1 << 4) |
Ignore all signal frames except NULL. | |
#define | AST_BRIDGE_REC_CHANNEL_0 (1 << 2) |
Return all voice frames on channel 0. | |
#define | AST_BRIDGE_REC_CHANNEL_1 (1 << 3) |
Return all voice frames on channel 1. | |
#define | AST_CHAN_WRITE_INFO_T_VERSION 1 |
ast_chan_write_info_t version. Must be incremented if structure is changed | |
#define | ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, linkedid, amaflag,...) |
Create a channel structure. | |
#define | ast_channel_lock(chan) ao2_lock(chan) |
#define | ast_channel_lock_both(chan1, chan2) |
Lock two channels. | |
#define | AST_CHANNEL_NAME 80 |
#define | ast_channel_ref(c) ({ ao2_ref(c, +1); (c); }) |
Increase channel reference count. | |
#define | ast_channel_trylock(chan) ao2_trylock(chan) |
#define | ast_channel_unlock(chan) ao2_unlock(chan) |
#define | ast_channel_unref(c) ({ ao2_ref(c, -1); (struct ast_channel *) (NULL); }) |
Decrease channel reference count. | |
#define | ast_dummy_channel_alloc() __ast_dummy_channel_alloc(__FILE__, __LINE__, __PRETTY_FUNCTION__) |
Create a fake channel structure. | |
#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_FLAG_DISABLE_DEVSTATE_CACHE = (1 << 21), AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT = (1 << 22), AST_FLAG_TIMINGDATA_IS_AO2_OBJ = (1 << 23) } |
ast_channel flags More... | |
enum | { AST_FEATURE_PLAY_WARNING = (1 << 0), AST_FEATURE_REDIRECT = (1 << 1), AST_FEATURE_DISCONNECT = (1 << 2), AST_FEATURE_ATXFER = (1 << 3), AST_FEATURE_AUTOMON = (1 << 4), AST_FEATURE_PARKCALL = (1 << 5), AST_FEATURE_AUTOMIXMON = (1 << 6), AST_FEATURE_NO_H_EXTEN = (1 << 7), AST_FEATURE_WARNING_ACTIVE = (1 << 8) } |
ast_bridge_config flags More... | |
enum | { AST_SOFTHANGUP_DEV = (1 << 0), AST_SOFTHANGUP_ASYNCGOTO = (1 << 1), AST_SOFTHANGUP_SHUTDOWN = (1 << 2), AST_SOFTHANGUP_TIMEOUT = (1 << 3), AST_SOFTHANGUP_APPUNLOAD = (1 << 4), AST_SOFTHANGUP_EXPLICIT = (1 << 5), AST_SOFTHANGUP_UNBRIDGE = (1 << 6), AST_SOFTHANGUP_ALL = (0xFFFFFFFF) } |
enum | ast_bridge_result { AST_BRIDGE_COMPLETE = 0, AST_BRIDGE_FAILED = -1, AST_BRIDGE_FAILED_NOWARN = -2, AST_BRIDGE_RETRY = -3 } |
enum | ast_channel_adsicpe { AST_ADSI_UNKNOWN, AST_ADSI_AVAILABLE, AST_ADSI_UNAVAILABLE, AST_ADSI_OFFHOOKONLY } |
enum | AST_PARTY_CHAR_SET { AST_PARTY_CHAR_SET_UNKNOWN = 0, AST_PARTY_CHAR_SET_ISO8859_1 = 1, AST_PARTY_CHAR_SET_WITHDRAWN = 2, AST_PARTY_CHAR_SET_ISO8859_2 = 3, AST_PARTY_CHAR_SET_ISO8859_3 = 4, AST_PARTY_CHAR_SET_ISO8859_4 = 5, AST_PARTY_CHAR_SET_ISO8859_5 = 6, AST_PARTY_CHAR_SET_ISO8859_7 = 7, AST_PARTY_CHAR_SET_ISO10646_BMPSTRING = 8, AST_PARTY_CHAR_SET_ISO10646_UTF_8STRING = 9 } |
enum | ast_t38_state { T38_STATE_UNAVAILABLE, T38_STATE_UNKNOWN, T38_STATE_NEGOTIATING, T38_STATE_REJECTED, T38_STATE_NEGOTIATED } |
Possible T38 states on channels. More... | |
enum | channelreloadreason { CHANNEL_MODULE_LOAD, CHANNEL_MODULE_RELOAD, CHANNEL_CLI_RELOAD, CHANNEL_MANAGER_RELOAD } |
Channel reload reasons for manager events at load or reload of configuration. More... | |
Functions | |
int | __ast_answer (struct ast_channel *chan, unsigned int delay, int cdr_answer) |
Answer a channel, with a selectable delay before returning. | |
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. | |
struct ast_channel * | __ast_dummy_channel_alloc (const char *file, int line, const char *function) |
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. | |
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. | |
struct 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. | |
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. | |
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. | |
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. | |
int | ast_channel_cc_params_init (struct ast_channel *chan, const struct ast_cc_config_params *base_params) |
Set up datastore with CCSS parameters for a channel. | |
void | ast_channel_clear_softhangup (struct ast_channel *chan, int flag) |
Clear a set of softhangup flags from a channel. | |
int | ast_channel_cmpwhentohangup (struct ast_channel *chan, time_t offset) |
Compare a offset with the settings of when to hang a channel up. | |
int | ast_channel_cmpwhentohangup_tv (struct ast_channel *chan, struct timeval offset) |
Compare a offset with the settings of when to hang a channel up. | |
int | ast_channel_connected_line_macro (struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *connected_info, int caller, int frame) |
Run a connected line interception macro and update a channel's connected line information. | |
int | ast_channel_data_add_structure (struct ast_data *tree, struct ast_channel *chan, int add_bridged) |
Insert into an astdata tree, the channel structure. | |
int | ast_channel_data_cmp_structure (const struct ast_data_search *tree, struct ast_channel *chan, const char *structure_name) |
Compare to channel structures using the data api. | |
int | ast_channel_datastore_add (struct ast_channel *chan, struct ast_datastore *datastore) |
Add a datastore to a channel. | |
struct ast_datastore *attribute_malloc | ast_channel_datastore_alloc (const struct ast_datastore_info *info, const char *uid) |
Create a channel data store object. | |
struct ast_datastore * | ast_channel_datastore_find (struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid) |
Find a datastore on a channel. | |
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. | |
struct 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. | |
struct 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. | |
struct 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. | |
struct 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. | |
static int | ast_fdisset (struct pollfd *pfds, int fd, int maximum, int *start) |
Helper function for migrating select to poll. | |
struct 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. | |
struct ast_frame * | ast_read (struct ast_channel *chan) |
Reads a frame. | |
struct 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. | |
struct ast_channel * | ast_request (const char *type, format_t format, const struct ast_channel *requestor, void *data, int *status) |
Requests a channel. | |
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. | |
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_settimeout_full (struct ast_channel *c, unsigned int rate, int(*func)(const void *data), void *data, unsigned int is_ao2_obj) |
int | ast_shutting_down (void) |
Returns non-zero if Asterisk is being shut down. | |
int | ast_softhangup (struct ast_channel *chan, int reason) |
Softly hangup up a channel. | |
int | ast_softhangup_nolock (struct ast_channel *chan, int reason) |
Softly hangup up a channel (no channel lock). | |
const char * | ast_state2str (enum ast_channel_state) |
Gives the string form of a given channel state. | |
int | ast_str2cause (const char *name) attribute_pure |
Convert the string form of a cause code to a number. | |
int | ast_tonepair (struct ast_channel *chan, int freq1, int freq2, int duration, int vol) |
int | ast_tonepair_start (struct ast_channel *chan, int freq1, int freq2, int duration, int vol) |
void | ast_tonepair_stop (struct ast_channel *chan) |
int | ast_transfer (struct ast_channel *chan, char *dest) |
Transfer a channel (if supported). | |
char * | ast_transfercapability2str (int transfercapability) attribute_const |
Gives the string form of a given transfer capability. | |
int | ast_undestroyed_channels (void) |
int | ast_waitfor (struct ast_channel *chan, int ms) |
Wait for input on a channel. | |
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. | |
int | ast_waitfor_n_fd (int *fds, int n, int *ms, int *exception) |
Waits for input on an fd. | |
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. | |
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. | |
struct ast_channel * | ast_channel_get_by_exten (const char *exten, const char *context) |
Find a channel by extension and context. | |
struct ast_channel * | ast_channel_get_by_name (const char *name) |
Find a channel by name. | |
struct ast_channel * | ast_channel_get_by_name_prefix (const char *name, size_t name_len) |
Find a channel by a name prefix. | |
struct ast_channel_iterator * | ast_channel_iterator_all_new (void) |
Create a new channel iterator. | |
struct ast_channel_iterator * | ast_channel_iterator_by_exten_new (const char *exten, const char *context) |
Create a new channel iterator based on extension. | |
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. | |
struct ast_channel_iterator * | ast_channel_iterator_destroy (struct ast_channel_iterator *i) |
Destroy a channel iterator. | |
struct ast_channel * | ast_channel_iterator_next (struct ast_channel_iterator *i) |
Get the next channel for a channel iterator. | |
Variables | |
struct ast_channel_tech | ast_kill_tech |
unsigned long | global_fin |
unsigned long | global_fout |
General Asterisk PBX channel definitions.
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 1932 of file channel.h.
Referenced by ast_generic_bridge(), ast_rtp_instance_bridge(), dahdi_bridge(), iax2_bridge(), local_bridge_loop(), misdn_bridge(), remote_bridge_loop(), and set_config_flags().
#define AST_BRIDGE_DTMF_CHANNEL_1 (1 << 1) |
Report DTMF on channel 1.
Definition at line 1934 of file channel.h.
Referenced by ast_generic_bridge(), ast_rtp_instance_bridge(), dahdi_bridge(), iax2_bridge(), local_bridge_loop(), misdn_bridge(), remote_bridge_loop(), and set_config_flags().
#define AST_BRIDGE_IGNORE_SIGS (1 << 4) |
Ignore all signal frames except NULL.
Definition at line 1940 of file channel.h.
Referenced by ast_generic_bridge(), iax2_bridge(), local_bridge_loop(), and remote_bridge_loop().
#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, | |||||
... | ) |
__ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, linkedid, amaflag, \ __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
Create a channel structure.
NULL | failure | |
non-NULL | successfully allocated channel |
Definition at line 1154 of file channel.h.
Referenced by __oh323_new(), action_bridge(), agent_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_pbx_outgoing_exten(), bridge_exec(), bridge_request(), builtin_atxfer(), check_goto_on_transfer(), console_new(), dahdi_new(), do_notify(), gtalk_new(), iax_park(), jingle_new(), local_new(), masq_park_call(), mgcp_new(), misdn_new(), multicast_rtp_request(), nbs_new(), oss_new(), phone_new(), sip_new(), sip_park(), skinny_new(), and unistim_new().
#define ast_channel_lock | ( | chan | ) | ao2_lock(chan) |
Definition at line 2466 of file channel.h.
Referenced by __analog_handle_event(), __ast_answer(), __ast_pbx_run(), __ast_queue_frame(), __ast_read(), __ast_request_and_dial(), __dahdi_exception(), __oh323_destroy(), __sip_destroy(), _macro_exec(), _while_exec(), acf_cc_read(), acf_cc_write(), acf_fetch(), acf_odbc_read(), action_add_agi_cmd(), action_coreshowchannels(), action_hangup(), action_redirect(), action_status(), action_timeout(), add_features_datastore(), add_to_agi(), agent_indicate(), agent_lock_owner(), analog_exception(), app_exec(), ast_activate_generator(), ast_async_goto(), ast_audiohook_attach(), ast_audiohook_detach_source(), ast_audiohook_remove(), ast_audiohook_set_mute(), ast_autochan_destroy(), ast_autochan_setup(), ast_autoservice_start(), ast_autoservice_stop(), ast_bridge_call(), ast_bridge_end_dtmf(), ast_bridge_timelimit(), ast_call(), ast_call_forward(), ast_cc_agent_set_interfaces_chanvar(), ast_cc_call_init(), ast_cc_completed(), ast_cc_extension_monitor_add_dialstring(), ast_cc_get_current_core_id(), ast_cc_is_recall(), ast_cc_offer(), ast_cel_report_event(), ast_change_name(), ast_channel_clear_softhangup(), ast_channel_cmp_cb(), ast_channel_connected_line_macro(), ast_channel_destructor(), ast_channel_queryoption(), ast_channel_redirecting_macro(), ast_channel_set_caller(), ast_channel_set_caller_event(), ast_channel_set_connected_line(), ast_channel_set_redirecting(), ast_channel_setoption(), ast_check_hangup_locked(), ast_complete_channels(), ast_deactivate_generator(), ast_dial_join(), ast_do_masquerade(), ast_do_pickup(), ast_eivr_getvariable(), ast_explicit_goto(), ast_handle_cc_control_frame(), ast_hangup(), ast_ignore_cc(), ast_indicate_data(), ast_odbc_retrieve_transaction_obj(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_raw_answer(), ast_read_generator_actions(), ast_rtp_instance_bridge(), ast_rtp_instance_early_bridge(), ast_rtp_instance_early_bridge_make_compatible(), ast_rtp_instance_make_compatible(), ast_safe_sleep_conditional(), ast_senddigit_begin(), ast_senddigit_end(), ast_sendtext(), ast_set_callerid(), ast_set_cc_interfaces_chanvar(), ast_set_hangupsource(), ast_settimeout_full(), 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(), auth_exec(), awesome_locking(), bridge_play_sounds(), builtin_atxfer(), builtin_automixmonitor(), builtin_blindtransfer(), calendar_event_read(), calendar_query_exec(), calendar_query_result_exec(), call_forward_inherit(), callerid_read(), callerid_write(), cb_events(), cc_build_payload(), cc_interfaces_datastore_init(), cdr_read(), cdr_write(), channel_set_debug(), channel_spy(), check_bridge(), check_goto_on_transfer(), clear_caller(), clear_dialed_interfaces(), common_exec(), conf_run(), conf_start_moh(), confbridge_exec(), connectedline_read(), connectedline_write(), create_dynamic_parkinglot(), crement_function_read(), dahdi_bridge(), dahdi_handle_dtmf(), dahdi_handle_event(), data_channels_provider_handler(), deactivate_silence_generator(), dial_exec_full(), disable_jack_hook(), do_forward(), do_notify(), dundi_query_read(), dundi_result_read(), enable_jack_hook(), end_bridge_callback(), enum_query_read(), enum_result_read(), exec_odbcfinish(), expand_gosub_args(), feature_check(), feature_interpret(), feature_request_and_dial(), find_by_mark(), find_by_part(), find_calling_channel(), find_channel_by_group(), find_conf_realtime(), find_details(), find_or_create_details(), find_speech(), find_transaction(), findmeexec(), frame_trace_helper(), func_channel_read(), func_channel_write_real(), func_channels_read(), func_header_read(), func_inheritance_write(), func_mute_write(), function_agent(), function_sipchaninfo_read(), generator_force(), generic_fax_exec(), get_agi_cmd(), get_cid_name(), gosub_exec(), gosub_run(), handle_chanlist(), handle_cli_agi_add_cmd(), handle_cli_mixmonitor(), handle_gosub(), handle_invite_replaces(), handle_request_bye(), handle_request_refer(), handle_showchan(), handle_softhangup(), import_ch(), import_helper(), init_jack_data(), jack_hook_callback(), leave_voicemail(), listfilter(), local_ast_moh_stop(), local_call(), local_hangup(), local_queryoption(), local_queue_frame(), local_read(), local_setoption(), local_write(), login_exec(), lua_get_state(), manage_parked_call(), manager_mutestream(), mark_transaction_active(), meetme_menu_admin_extended(), minivm_delete_exec(), minivm_notify_exec(), misdn_answer(), misdn_attempt_transfer(), misdn_update_caller_id(), moh_files_generator(), morsecode_exec(), mute_callback(), my_handle_dtmf(), notify_new_message(), park_call_full(), parkandannounce_exec(), parked_call_exec(), pbx_builtin_background(), pbx_builtin_getvar_helper(), pbx_builtin_gotoiftime(), pbx_builtin_pushvar_helper(), pbx_builtin_serialize_variables(), pbx_builtin_setamaflags(), pbx_builtin_setvar_helper(), peek_read(), pickup_by_exten(), pickup_by_name_cb(), pitchshift_helper(), pop_exec(), process_sdp(), queue_exec(), receivefax_exec(), redirecting_read(), redirecting_write(), release_transaction(), remote_bridge_loop(), report_fax_status(), retrydial_exec(), return_exec(), run_agi(), sendfax_exec(), sendtext_exec(), set_ext_pri(), set_format(), set_security_requirements(), setup_inheritance_datastore(), setup_mixmonitor_ds(), setup_transfer_datastore(), shared_read(), shared_write(), sip_addheader(), sip_dtmfmode(), sip_new(), sip_pvt_lock_full(), sip_read(), sip_removeheader(), sip_set_rtp_peer(), sip_set_udptl_peer(), smdi_msg_read(), smdi_msg_retrieve_read(), softhangup_exec(), speech_background(), speech_create(), speech_datastore_destroy(), speex_read(), speex_write(), srv_datastore_setup(), srv_query_read(), srv_result_read(), stackpeek_read(), start_monitor_action(), start_monitor_exec(), state_notify_build_xml(), stop_mixmonitor_exec(), transmit_invite(), try_calling(), update_bridge_vars(), volume_write(), and wait_for_answer().
#define ast_channel_lock_both | ( | chan1, | |||
chan2 | ) |
Lock two channels.
Definition at line 2473 of file channel.h.
Referenced by __ast_channel_masquerade(), __ast_request_and_dial(), ast_bridge_call(), ast_call_forward(), ast_channel_bridge(), ast_do_masquerade(), ast_generic_bridge(), call_forward_inherit(), dial_transfer(), do_bridge_masquerade(), do_forward(), findmeexec(), ring_entry(), and wait_for_answer().
#define AST_CHANNEL_NAME 80 |
Max length of an ast_channel name
Definition at line 137 of file channel.h.
Referenced by ast_bridge_call(), ast_cc_call_failed(), ast_cc_is_recall(), ast_channel_destructor(), ast_do_masquerade(), ast_parse_device_state(), ast_queue_cc_frame(), ast_setstate(), cc_core_init_instance(), cc_unique_append(), cccancel_exec(), ccreq_exec(), common_exec(), create_jb(), dahdi_cc_callback(), dahdi_new(), dial_exec_full(), fast_originate(), page_exec(), park_call_full(), sip_call(), sip_handle_cc(), softhangup_exec(), and wait_for_answer().
#define ast_channel_ref | ( | c | ) | ({ ao2_ref(c, +1); (c); }) |
Increase channel reference count.
c | the channel |
c | always |
Definition at line 2491 of file channel.h.
Referenced by agent_hangup(), agent_lock_owner(), ast_autochan_new_channel(), ast_autochan_setup(), ast_cel_report_event(), ast_do_masquerade(), ast_set_hangupsource(), awesome_locking(), check_bridge(), handle_getvariablefull(), handle_incoming(), handle_invite_replaces(), handle_request_refer(), local_attended_transfer(), local_queryoption(), local_queue_frame(), local_setoption(), set_hangup_source_and_cause(), sip_pickup(), sip_pvt_lock_full(), sip_queue_hangup_cause(), and socket_process().
#define ast_channel_trylock | ( | chan | ) | ao2_trylock(chan) |
Definition at line 2468 of file channel.h.
Referenced by __ast_channel_masquerade(), __oh323_rtp_create(), agent_logoff(), agent_read(), analog_lock_sub_owner(), ast_queue_hangup(), ast_queue_hangup_with_cause(), ast_rtp_instance_bridge(), ast_rtp_instance_early_bridge(), ast_rtp_instance_early_bridge_make_compatible(), ast_udptl_bridge(), ast_write(), auto_congest(), awesome_locking(), bridge_queue_hangup(), bridge_write(), check_bridge(), check_rtp_timeout(), cleanup_connection(), dahdi_bridge(), dahdi_handle_event(), dahdi_lock_sub_owner(), dahdi_queue_frame(), dahdi_softhangup_all(), dial_exec_full(), get_sip_pvt_byid_locked(), grab_owner(), handle_request_bye(), hangup_connection(), iax2_destroy(), iax2_lock_owner(), mgcp_queue_frame(), mgcp_queue_hangup(), misdn_attempt_transfer(), oh323_rtp_read(), oh323_simulate_dtmf_end(), proc_session_timer(), receive_digit(), release_chan(), release_chan_early(), remote_hold(), retrans_pkt(), setup_rtp_connection(), sip_hangup(), sip_reinvite_retry(), and update_state().
#define ast_channel_unlock | ( | chan | ) | ao2_unlock(chan) |
Definition at line 2467 of file channel.h.
Referenced by __analog_handle_event(), __ast_answer(), __ast_channel_masquerade(), __ast_pbx_run(), __ast_queue_frame(), __ast_read(), __ast_request_and_dial(), __dahdi_exception(), __oh323_destroy(), __oh323_rtp_create(), __sip_autodestruct(), __sip_destroy(), _macro_exec(), _while_exec(), acf_cc_read(), acf_cc_write(), acf_fetch(), acf_odbc_read(), action_add_agi_cmd(), action_agents(), action_coreshowchannels(), action_hangup(), action_redirect(), action_status(), action_timeout(), add_features_datastore(), add_to_agi(), agent_indicate(), agent_lock_owner(), agent_logoff(), agent_read(), agents_data_provider_get(), agents_show(), agents_show_online(), alsa_call(), analog_attempt_transfer(), analog_exception(), analog_hangup(), app_exec(), ast_activate_generator(), ast_async_goto(), ast_audiohook_attach(), ast_audiohook_detach_source(), ast_audiohook_remove(), ast_audiohook_set_mute(), ast_autochan_destroy(), ast_autochan_setup(), ast_autoservice_start(), ast_autoservice_stop(), ast_bridge_call(), ast_bridge_end_dtmf(), 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_bridge(), ast_channel_clear_softhangup(), ast_channel_cmp_cb(), ast_channel_connected_line_macro(), ast_channel_destructor(), ast_channel_queryoption(), ast_channel_redirecting_macro(), ast_channel_set_caller(), ast_channel_set_caller_event(), ast_channel_set_connected_line(), ast_channel_set_redirecting(), ast_channel_setoption(), ast_check_hangup_locked(), ast_complete_channels(), ast_deactivate_generator(), ast_dial_join(), ast_do_masquerade(), ast_do_pickup(), ast_eivr_getvariable(), ast_explicit_goto(), ast_generic_bridge(), 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_senddigit_begin(), ast_senddigit_end(), ast_sendtext(), ast_set_callerid(), ast_set_cc_interfaces_chanvar(), ast_set_hangupsource(), ast_settimeout_full(), 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(), auth_exec(), auto_congest(), awesome_locking(), bridge_play_sounds(), bridge_queue_hangup(), bridge_write(), builtin_atxfer(), builtin_automixmonitor(), builtin_blindtransfer(), calendar_event_read(), calendar_query_exec(), calendar_query_result_exec(), call_forward_inherit(), callerid_read(), callerid_write(), cb_events(), cc_build_payload(), cc_interfaces_datastore_init(), cdr_read(), cdr_write(), channel_set_debug(), channel_spy(), check_bridge(), check_goto_on_transfer(), check_rtp_timeout(), cleanup_connection(), clear_caller(), clear_dialed_interfaces(), common_exec(), conf_run(), conf_start_moh(), confbridge_exec(), connectedline_read(), connectedline_write(), console_answer(), console_hangup(), console_sendtext(), create_dynamic_parkinglot(), crement_function_read(), dahdi_bridge(), dahdi_handle_dtmf(), dahdi_handle_event(), dahdi_queue_frame(), dahdi_softhangup_all(), data_channels_provider_handler(), deactivate_silence_generator(), dial_exec_full(), dial_transfer(), dialog_unlink_all(), disable_jack_hook(), do_bridge_masquerade(), do_forward(), do_notify(), dundi_query_read(), dundi_result_read(), enable_jack_hook(), end_bridge_callback(), enum_query_read(), enum_result_read(), exec_odbcfinish(), expand_gosub_args(), fast_originate(), feature_check(), feature_interpret(), feature_request_and_dial(), find_by_mark(), find_by_part(), find_calling_channel(), find_channel_by_group(), find_conf_realtime(), find_details(), find_or_create_details(), find_speech(), find_transaction(), findmeexec(), frame_trace_helper(), func_channel_read(), func_channel_write_real(), func_channels_read(), func_header_read(), func_inheritance_write(), func_mute_write(), function_agent(), function_sipchaninfo_read(), generator_force(), generic_fax_exec(), get_agi_cmd(), get_cid_name(), gosub_exec(), gosub_run(), handle_chanlist(), handle_cli_agi_add_cmd(), handle_cli_mixmonitor(), handle_gosub(), handle_incoming(), handle_invite_replaces(), handle_request_bye(), handle_request_do(), handle_request_invite(), handle_request_refer(), handle_showchan(), handle_softhangup(), hangup_connection(), iax2_destroy(), iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), import_ch(), import_helper(), init_jack_data(), jack_hook_callback(), leave_voicemail(), listfilter(), local_ast_moh_stop(), local_attended_transfer(), local_bridge_loop(), local_call(), local_hangup(), local_queryoption(), local_queue_frame(), local_read(), local_setoption(), local_write(), login_exec(), lua_get_state(), manage_parked_call(), manager_mutestream(), mark_transaction_active(), meetme_menu_admin_extended(), mgcp_pktcgate_remove(), mgcp_queue_frame(), mgcp_queue_hangup(), minivm_delete_exec(), minivm_notify_exec(), misdn_answer(), misdn_attempt_transfer(), misdn_update_caller_id(), moh_files_generator(), morsecode_exec(), mute_callback(), my_handle_dtmf(), notify_new_message(), oh323_rtp_read(), oh323_simulate_dtmf_end(), park_call_full(), parkandannounce_exec(), parked_call_exec(), pbx_builtin_background(), pbx_builtin_getvar_helper(), pbx_builtin_gotoiftime(), pbx_builtin_pushvar_helper(), pbx_builtin_serialize_variables(), pbx_builtin_setamaflags(), pbx_builtin_setvar_helper(), peek_read(), pickup_by_channel(), pickup_by_exten(), pickup_by_group(), pickup_by_mark(), pickup_by_name_cb(), pickup_by_part(), pitchshift_helper(), pop_exec(), proc_session_timer(), process_sdp(), queue_exec(), receive_digit(), receivefax_exec(), redirecting_read(), redirecting_write(), reinvite_timeout(), release_chan(), release_chan_early(), release_transaction(), remote_bridge_loop(), remote_hold(), report_fax_status(), retrans_pkt(), retrydial_exec(), return_exec(), ring_entry(), run_agi(), schedule_delivery(), send_provisional_keepalive_full(), sendfax_exec(), sendtext_exec(), set_ext_pri(), set_format(), set_hangup_source_and_cause(), set_security_requirements(), setup_inheritance_datastore(), setup_mixmonitor_ds(), setup_rtp_connection(), setup_transfer_datastore(), shared_read(), shared_write(), sip_addheader(), sip_dtmfmode(), sip_hangup(), sip_new(), sip_pvt_lock_full(), sip_queue_hangup_cause(), sip_read(), sip_reinvite_retry(), sip_removeheader(), sip_request_call(), sip_set_rtp_peer(), sip_set_udptl_peer(), smdi_msg_read(), smdi_msg_retrieve_read(), socket_process(), softhangup_exec(), speech_background(), speech_create(), speech_datastore_destroy(), speex_read(), speex_write(), srv_datastore_setup(), srv_query_read(), srv_result_read(), stackpeek_read(), start_monitor_action(), start_monitor_exec(), state_notify_build_xml(), stop_mixmonitor_exec(), transmit_invite(), try_calling(), update_bridge_vars(), update_state(), volume_write(), wait_for_answer(), and wakeup_sub().
#define ast_channel_unref | ( | c | ) | ({ ao2_ref(c, -1); (struct ast_channel *) (NULL); }) |
Decrease channel reference count.
c | the channel |
NULL | always |
Definition at line 2502 of file channel.h.
Referenced by __ast_channel_alloc_ap(), __ast_dummy_channel_alloc(), __sip_autodestruct(), acf_odbc_read(), acf_odbc_write(), action_add_agi_cmd(), action_agents(), action_aocmessage(), action_atxfer(), action_bridge(), action_coreshowchannels(), action_getvar(), action_hangup(), action_redirect(), action_sendtext(), action_setvar(), action_status(), action_timeout(), agent_hangup(), agent_lock_owner(), agent_logoff(), agent_read(), agents_data_provider_get(), agents_show(), agents_show_online(), ast_add_extension2_lockopt(), ast_async_goto_by_name(), ast_autochan_destroy(), ast_autochan_new_channel(), ast_bridge_call(), ast_cel_fabricate_channel_from_event(), ast_cel_report_event(), ast_channel_release(), ast_complete_channels(), ast_do_masquerade(), ast_hangup(), ast_parse_device_state(), ast_pbx_outgoing_cdr_failed(), ast_pickup_call(), ast_set_hangupsource(), ast_str_substitute_variables_full(), ast_var_channel_bridge(), ast_var_channel_types_table(), ast_var_channels_table(), asyncgoto_exec(), awesome_locking(), bridge_exec(), change_monitor_action(), check_bridge(), cli_odbc_read(), cli_odbc_write(), common_exec(), custom_log(), data_channels_provider_handler(), dialog_unlink_all(), do_pause_or_unpause(), func_channels_read(), func_mchan_read(), func_mchan_write(), handle_chanlist(), handle_channelstatus(), handle_cli_agi_add_cmd(), handle_cli_mixmonitor(), handle_core_set_debug_channel(), handle_getvariablefull(), handle_hangup(), handle_incoming(), handle_invite_replaces(), handle_redirect(), handle_request_do(), handle_request_refer(), handle_set_chanvar(), handle_show_chanvar(), handle_showchan(), handle_softhangup(), import_helper(), local_attended_transfer(), local_call(), local_hangup(), local_queryoption(), local_queue_frame(), local_setoption(), make_email_file(), manager_log(), manager_mute_mixmonitor(), manager_mutestream(), manager_optimize_away(), manager_park(), manager_play_dtmf(), next_channel(), park_call_full(), pbx_builtin_importvar(), pbx_substitute_variables_helper_full(), pickup_by_channel(), pickup_by_exten(), pickup_by_group(), pickup_by_mark(), pickup_by_part(), reinvite_timeout(), rotate_file(), send_provisional_keepalive_full(), senddtmf_exec(), sendmail(), sendpage(), set_hangup_source_and_cause(), shared_read(), shared_write(), sip_pickup(), sip_pickup_thread(), sip_pvt_lock_full(), sip_queue_hangup_cause(), socket_process(), softhangup_exec(), start_monitor_action(), state_notify_build_xml(), stop_monitor_action(), syslog_log(), and write_cdr().
#define ast_dummy_channel_alloc | ( | ) | __ast_dummy_channel_alloc(__FILE__, __LINE__, __PRETTY_FUNCTION__) |
Create a fake channel structure.
NULL | failure | |
non-NULL | successfully allocated channel |
Definition at line 1175 of file channel.h.
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(), cli_odbc_read(), cli_odbc_write(), custom_log(), make_email_file(), manager_log(), pbx_substitute_variables_helper_full(), rotate_file(), sendmail(), sendpage(), syslog_log(), and write_cdr().
#define AST_GENERATOR_FD (AST_MAX_FDS-4) |
used by generator
Definition at line 166 of file channel.h.
Referenced by __ast_read(), ast_do_masquerade(), and deactivate_generator_nolock().
#define AST_MAX_CONTEXT 80 |
Max length of a context
Definition at line 136 of file channel.h.
Referenced by _macro_exec(), aji_publish_mwi(), ast_bridge_call(), cleanup_stale_contexts(), common_exec(), conf_run(), config_parse_variables(), dial_transfer(), do_magic_pickup(), gtalk_load_config(), handle_request_invite(), handle_statechange(), park_call_full(), parkinglot_activate(), reload_config(), and try_calling().
#define AST_MAX_EXTENSION 80 |
Max length of an extension
Definition at line 135 of file channel.h.
Referenced by __analog_ss_thread(), __ast_context_destroy(), add_extensions(), advanced_options(), aji_publish_mwi(), analog_ss_thread(), ast_bridge_call(), ast_device_state_changed(), ast_devstate_changed(), ast_ivr_menu_run_internal(), AST_LIST_HEAD_NOLOCK(), begin_dial_channel(), build_device(), cc_extension_monitor_init(), conf_run(), destroy_space(), dial_exec_full(), dial_transfer(), disa_exec(), do_magic_pickup(), dundi_lookup_local(), feature_attended_transfer(), feature_blind_transfer(), find_conf_realtime(), forward_message(), function_enum(), get_destination(), handle_request_invite(), handle_statechange(), load_module(), log_exec(), manage_parked_call(), manager_show_dialplan_helper(), mgcp_ss(), park_add_hints(), park_call_exec(), park_call_full(), phone_check_exception(), process_dahdi(), realtime_common(), realtime_switch_common(), show_dialplan_helper(), skinny_extensionstate_cb(), skinny_ss(), sla_build_station(), sla_station_destructor(), speech_background(), state_notify_build_xml(), try_calling(), vm_authenticate(), and vmauthenticate().
#define AST_MAX_FDS 10 |
Definition at line 158 of file channel.h.
Referenced by ast_channel_destructor(), ast_do_masquerade(), ast_poll_channel_add(), ast_poll_channel_del(), and ast_waitfor_nandfds().
#define AST_TIMING_FD (AST_MAX_FDS-2) |
used for timingfd
Definition at line 164 of file channel.h.
Referenced by __ast_channel_alloc_ap(), __ast_read(), agent_read(), ast_do_masquerade(), and ast_settimeout_full().
#define CHECK_BLOCKING | ( | c | ) |
Definition at line 2427 of file channel.h.
Referenced by ast_sendtext(), ast_waitfor_nandfds(), ast_write(), dahdi_read(), and phone_read().
#define DATASTORE_INHERIT_FOREVER INT_MAX |
Definition at line 156 of file channel.h.
Referenced by _macro_exec(), acf_iaxvar_write(), add_features_datastore(), ast_channel_datastore_inherit(), ast_iax2_new(), ast_setup_cc_recall_datastore(), authenticate_reply(), calendar_query_exec(), cc_interfaces_datastore_init(), dial_exec_full(), do_notify(), socket_process(), and try_calling().
#define DEBUGCHAN_FLAG 0x80000000 |
The high bit of the frame count is used as a debug marker, so increments of the counters must be done with care. Please use c->fin = FRAMECOUNT_INC(c->fin) and the same for c->fout.
Definition at line 648 of file channel.h.
Referenced by __ast_read(), ast_write(), channel_set_debug(), handle_core_set_debug_channel(), handle_showchan(), and serialize_showchan().
#define FRAMECOUNT_INC | ( | x | ) | ( ((x) & DEBUGCHAN_FLAG) | (((x)+1) & ~DEBUGCHAN_FLAG) ) |
Definition at line 651 of file channel.h.
Referenced by __ast_read(), and ast_write().
#define MAX_LANGUAGE 40 |
Max length of the language setting
Definition at line 138 of file channel.h.
Referenced by ast_readconfig().
#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 878 of file channel.h.
00878 { 00879 /*! 00880 * \brief Channels have this property if they can accept input with jitter; 00881 * i.e. most VoIP channels 00882 */ 00883 AST_CHAN_TP_WANTSJITTER = (1 << 0), 00884 /*! 00885 * \brief Channels have this property if they can create jitter; 00886 * i.e. most VoIP channels 00887 */ 00888 AST_CHAN_TP_CREATESJITTER = (1 << 1), 00889 };
anonymous enum |
ast_channel flags
AST_FLAG_DEFER_DTMF |
Queue incoming DTMF, to be released when this flag is turned off |
AST_FLAG_WRITE_INT |
write should be interrupt generator |
AST_FLAG_BLOCKING |
a thread is blocking on this channel |
AST_FLAG_ZOMBIE |
This is a zombie channel |
AST_FLAG_EXCEPTION |
There is an exception pending |
AST_FLAG_MOH |
Listening to moh XXX anthm promises me this will disappear XXX |
AST_FLAG_SPYING |
This channel is spying on another channel |
AST_FLAG_NBRIDGE |
This channel is in a native bridge |
AST_FLAG_IN_AUTOLOOP |
the channel is in an auto-incrementing dialplan processor, so when ->priority is set, it will get incremented before finding the next priority to run |
AST_FLAG_OUTGOING |
This is an outgoing call |
AST_FLAG_IN_DTMF |
A DTMF_BEGIN frame has been read from this channel, but not yet an END |
AST_FLAG_EMULATE_DTMF |
A DTMF_END was received when not IN_DTMF, so the length of the digit is currently being emulated |
AST_FLAG_END_DTMF_ONLY |
This is set to tell the channel not to generate DTMF begin frames, and to instead only generate END frames. |
AST_FLAG_ANSWERED_ELSEWHERE |
Flag to show channels that this call is hangup due to the fact that the call was indeed answered, but in another channel |
AST_FLAG_MASQ_NOSTREAM |
This flag indicates that on a masquerade, an active stream should not be carried over |
AST_FLAG_BRIDGE_HANGUP_RUN |
This flag indicates that the hangup exten was run when the bridge terminated, a message aimed at preventing a subsequent hangup exten being run at the pbx_run level |
AST_FLAG_BRIDGE_HANGUP_DONT |
This flag indicates that the hangup exten should NOT be run when the bridge terminates, this will allow the hangup in the pbx loop to be run instead. |
AST_FLAG_DISABLE_WORKAROUNDS |
Disable certain workarounds. This reintroduces certain bugs, but allows some non-traditional dialplans (like AGI) to continue to function. |
AST_FLAG_DISABLE_DEVSTATE_CACHE |
Disable device state event caching. This allows channel drivers to selectively prevent device state events from being cached by certain channels such as anonymous calls which have no persistent represenatation that can be tracked. |
AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT |
This flag indicates that a dual channel redirect is in progress. The bridge needs to wait until the flag is cleared to continue. |
AST_FLAG_TIMINGDATA_IS_AO2_OBJ |
The data on chan->timingdata is an astobj2 object. |
Definition at line 892 of file channel.h.
00892 { 00893 /*! Queue incoming DTMF, to be released when this flag is turned off */ 00894 AST_FLAG_DEFER_DTMF = (1 << 1), 00895 /*! write should be interrupt generator */ 00896 AST_FLAG_WRITE_INT = (1 << 2), 00897 /*! a thread is blocking on this channel */ 00898 AST_FLAG_BLOCKING = (1 << 3), 00899 /*! This is a zombie channel */ 00900 AST_FLAG_ZOMBIE = (1 << 4), 00901 /*! There is an exception pending */ 00902 AST_FLAG_EXCEPTION = (1 << 5), 00903 /*! Listening to moh XXX anthm promises me this will disappear XXX */ 00904 AST_FLAG_MOH = (1 << 6), 00905 /*! This channel is spying on another channel */ 00906 AST_FLAG_SPYING = (1 << 7), 00907 /*! This channel is in a native bridge */ 00908 AST_FLAG_NBRIDGE = (1 << 8), 00909 /*! the channel is in an auto-incrementing dialplan processor, 00910 * so when ->priority is set, it will get incremented before 00911 * finding the next priority to run */ 00912 AST_FLAG_IN_AUTOLOOP = (1 << 9), 00913 /*! This is an outgoing call */ 00914 AST_FLAG_OUTGOING = (1 << 10), 00915 /*! A DTMF_BEGIN frame has been read from this channel, but not yet an END */ 00916 AST_FLAG_IN_DTMF = (1 << 12), 00917 /*! A DTMF_END was received when not IN_DTMF, so the length of the digit is 00918 * currently being emulated */ 00919 AST_FLAG_EMULATE_DTMF = (1 << 13), 00920 /*! This is set to tell the channel not to generate DTMF begin frames, and 00921 * to instead only generate END frames. */ 00922 AST_FLAG_END_DTMF_ONLY = (1 << 14), 00923 /*! Flag to show channels that this call is hangup due to the fact that the call 00924 was indeed answered, but in another channel */ 00925 AST_FLAG_ANSWERED_ELSEWHERE = (1 << 15), 00926 /*! This flag indicates that on a masquerade, an active stream should not 00927 * be carried over */ 00928 AST_FLAG_MASQ_NOSTREAM = (1 << 16), 00929 /*! This flag indicates that the hangup exten was run when the bridge terminated, 00930 * a message aimed at preventing a subsequent hangup exten being run at the pbx_run 00931 * level */ 00932 AST_FLAG_BRIDGE_HANGUP_RUN = (1 << 17), 00933 /*! This flag indicates that the hangup exten should NOT be run when the 00934 * bridge terminates, this will allow the hangup in the pbx loop to be run instead. 00935 * */ 00936 AST_FLAG_BRIDGE_HANGUP_DONT = (1 << 18), 00937 /*! Disable certain workarounds. This reintroduces certain bugs, but allows 00938 * some non-traditional dialplans (like AGI) to continue to function. 00939 */ 00940 AST_FLAG_DISABLE_WORKAROUNDS = (1 << 20), 00941 /*! 00942 * Disable device state event caching. This allows channel 00943 * drivers to selectively prevent device state events from being 00944 * cached by certain channels such as anonymous calls which have 00945 * no persistent represenatation that can be tracked. 00946 */ 00947 AST_FLAG_DISABLE_DEVSTATE_CACHE = (1 << 21), 00948 /*! 00949 * This flag indicates that a dual channel redirect is in 00950 * progress. The bridge needs to wait until the flag is cleared 00951 * to continue. 00952 */ 00953 AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT = (1 << 22), 00954 /*! 00955 * The data on chan->timingdata is an astobj2 object. 00956 */ 00957 AST_FLAG_TIMINGDATA_IS_AO2_OBJ = (1 << 23), 00958 };
anonymous enum |
ast_bridge_config flags
Definition at line 961 of file channel.h.
00961 { 00962 AST_FEATURE_PLAY_WARNING = (1 << 0), 00963 AST_FEATURE_REDIRECT = (1 << 1), 00964 AST_FEATURE_DISCONNECT = (1 << 2), 00965 AST_FEATURE_ATXFER = (1 << 3), 00966 AST_FEATURE_AUTOMON = (1 << 4), 00967 AST_FEATURE_PARKCALL = (1 << 5), 00968 AST_FEATURE_AUTOMIXMON = (1 << 6), 00969 AST_FEATURE_NO_H_EXTEN = (1 << 7), 00970 AST_FEATURE_WARNING_ACTIVE = (1 << 8), 00971 };
anonymous enum |
Definition at line 1009 of file channel.h.
01009 { 01010 /*! 01011 * Soft hangup requested by device or other internal reason. 01012 * Actual hangup needed. 01013 */ 01014 AST_SOFTHANGUP_DEV = (1 << 0), 01015 /*! 01016 * Used to break the normal frame flow so an async goto can be 01017 * done instead of actually hanging up. 01018 */ 01019 AST_SOFTHANGUP_ASYNCGOTO = (1 << 1), 01020 /*! 01021 * Soft hangup requested by system shutdown. Actual hangup 01022 * needed. 01023 */ 01024 AST_SOFTHANGUP_SHUTDOWN = (1 << 2), 01025 /*! 01026 * Used to break the normal frame flow after a timeout so an 01027 * implicit async goto can be done to the 'T' exten if it exists 01028 * instead of actually hanging up. If the exten does not exist 01029 * then actually hangup. 01030 */ 01031 AST_SOFTHANGUP_TIMEOUT = (1 << 3), 01032 /*! 01033 * Soft hangup requested by application/channel-driver being 01034 * unloaded. Actual hangup needed. 01035 */ 01036 AST_SOFTHANGUP_APPUNLOAD = (1 << 4), 01037 /*! 01038 * Soft hangup requested by non-associated party. Actual hangup 01039 * needed. 01040 */ 01041 AST_SOFTHANGUP_EXPLICIT = (1 << 5), 01042 /*! 01043 * Used to break a bridge so the channel can be spied upon 01044 * instead of actually hanging up. 01045 */ 01046 AST_SOFTHANGUP_UNBRIDGE = (1 << 6), 01047 01048 01049 /*! 01050 * \brief All softhangup flags. 01051 * 01052 * This can be used as an argument to ast_channel_softhangup_clear 01053 * to clear all softhangup flags from a channel. 01054 */ 01055 AST_SOFTHANGUP_ALL = (0xFFFFFFFF) 01056 };
enum ast_bridge_result |
Definition at line 168 of file channel.h.
00168 { 00169 AST_BRIDGE_COMPLETE = 0, 00170 AST_BRIDGE_FAILED = -1, 00171 AST_BRIDGE_FAILED_NOWARN = -2, 00172 AST_BRIDGE_RETRY = -3, 00173 };
enum ast_channel_adsicpe |
Definition at line 659 of file channel.h.
00659 { 00660 AST_ADSI_UNKNOWN, 00661 AST_ADSI_AVAILABLE, 00662 AST_ADSI_UNAVAILABLE, 00663 AST_ADSI_OFFHOOKONLY, 00664 };
enum AST_PARTY_CHAR_SET |
Party name character set enumeration values (values from Q.SIG)
Definition at line 192 of file channel.h.
00192 { 00193 AST_PARTY_CHAR_SET_UNKNOWN = 0, 00194 AST_PARTY_CHAR_SET_ISO8859_1 = 1, 00195 AST_PARTY_CHAR_SET_WITHDRAWN = 2,/* ITU withdrew this enum value. */ 00196 AST_PARTY_CHAR_SET_ISO8859_2 = 3, 00197 AST_PARTY_CHAR_SET_ISO8859_3 = 4, 00198 AST_PARTY_CHAR_SET_ISO8859_4 = 5, 00199 AST_PARTY_CHAR_SET_ISO8859_5 = 6, 00200 AST_PARTY_CHAR_SET_ISO8859_7 = 7, 00201 AST_PARTY_CHAR_SET_ISO10646_BMPSTRING = 8, 00202 AST_PARTY_CHAR_SET_ISO10646_UTF_8STRING = 9, 00203 };
enum ast_t38_state |
Possible T38 states on channels.
Definition at line 669 of file channel.h.
00669 { 00670 T38_STATE_UNAVAILABLE, /*!< T38 is unavailable on this channel or disabled by configuration */ 00671 T38_STATE_UNKNOWN, /*!< The channel supports T38 but the current status is unknown */ 00672 T38_STATE_NEGOTIATING, /*!< T38 is being negotiated */ 00673 T38_STATE_REJECTED, /*!< Remote side has rejected our offer */ 00674 T38_STATE_NEGOTIATED, /*!< T38 established */ 00675 };
enum channelreloadreason |
Channel reload reasons for manager events at load or reload of configuration.
Definition at line 1060 of file channel.h.
01060 { 01061 CHANNEL_MODULE_LOAD, 01062 CHANNEL_MODULE_RELOAD, 01063 CHANNEL_CLI_RELOAD, 01064 CHANNEL_MANAGER_RELOAD, 01065 };
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 answers a channel and handles all necessary call setup functions.
0 | on success | |
non-zero | on failure |
Definition at line 2982 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_remaining_ms(), AST_STATE_RING, AST_STATE_RINGING, ast_tvnow(), ast_waitfor(), errno, frames, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, MAX, and ast_frame::subclass.
Referenced by ast_answer(), pbx_builtin_answer(), and pbx_builtin_incomplete().
02983 { 02984 int res = 0; 02985 enum ast_channel_state old_state; 02986 02987 old_state = chan->_state; 02988 if ((res = ast_raw_answer(chan, cdr_answer))) { 02989 return res; 02990 } 02991 02992 switch (old_state) { 02993 case AST_STATE_RINGING: 02994 case AST_STATE_RING: 02995 /* wait for media to start flowing, but don't wait any longer 02996 * than 'delay' or 500 milliseconds, whichever is longer 02997 */ 02998 do { 02999 AST_LIST_HEAD_NOLOCK(, ast_frame) frames; 03000 struct ast_frame *cur, *new; 03001 int timeout_ms = MAX(delay, 500); 03002 unsigned int done = 0; 03003 struct timeval start; 03004 03005 AST_LIST_HEAD_INIT_NOLOCK(&frames); 03006 03007 start = ast_tvnow(); 03008 for (;;) { 03009 int ms = ast_remaining_ms(start, timeout_ms); 03010 ms = ast_waitfor(chan, ms); 03011 if (ms < 0) { 03012 ast_log(LOG_WARNING, "Error condition occurred when polling channel %s for a voice frame: %s\n", chan->name, strerror(errno)); 03013 res = -1; 03014 break; 03015 } 03016 if (ms == 0) { 03017 ast_debug(2, "Didn't receive a media frame from %s within %u ms of answering. Continuing anyway\n", chan->name, MAX(delay, 500)); 03018 break; 03019 } 03020 cur = ast_read(chan); 03021 if (!cur || ((cur->frametype == AST_FRAME_CONTROL) && 03022 (cur->subclass.integer == AST_CONTROL_HANGUP))) { 03023 if (cur) { 03024 ast_frfree(cur); 03025 } 03026 res = -1; 03027 ast_debug(2, "Hangup of channel %s detected in answer routine\n", chan->name); 03028 break; 03029 } 03030 03031 if ((new = ast_frisolate(cur)) != cur) { 03032 ast_frfree(cur); 03033 } 03034 03035 AST_LIST_INSERT_HEAD(&frames, new, frame_list); 03036 03037 /* if a specific delay period was requested, continue 03038 * until that delay has passed. don't stop just because 03039 * incoming media has arrived. 03040 */ 03041 if (delay) { 03042 continue; 03043 } 03044 03045 switch (new->frametype) { 03046 /* all of these frametypes qualify as 'media' */ 03047 case AST_FRAME_VOICE: 03048 case AST_FRAME_VIDEO: 03049 case AST_FRAME_TEXT: 03050 case AST_FRAME_DTMF_BEGIN: 03051 case AST_FRAME_DTMF_END: 03052 case AST_FRAME_IMAGE: 03053 case AST_FRAME_HTML: 03054 case AST_FRAME_MODEM: 03055 done = 1; 03056 break; 03057 case AST_FRAME_CONTROL: 03058 case AST_FRAME_IAX: 03059 case AST_FRAME_NULL: 03060 case AST_FRAME_CNG: 03061 break; 03062 } 03063 03064 if (done) { 03065 break; 03066 } 03067 } 03068 03069 if (res == 0) { 03070 ast_channel_lock(chan); 03071 while ((cur = AST_LIST_REMOVE_HEAD(&frames, frame_list))) { 03072 ast_queue_frame_head(chan, cur); 03073 ast_frfree(cur); 03074 } 03075 ast_channel_unlock(chan); 03076 } 03077 } while (0); 03078 break; 03079 default: 03080 break; 03081 } 03082 03083 return res; 03084 }
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, | |||
... | ||||
) | [read] |
Create a channel structure.
NULL | failure | |
non-NULL | successfully allocated channel |
Definition at line 1366 of file channel.c.
References __ast_channel_alloc_ap().
01372 { 01373 va_list ap1, ap2; 01374 struct ast_channel *result; 01375 01376 va_start(ap1, name_fmt); 01377 va_start(ap2, name_fmt); 01378 result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context, 01379 linkedid, amaflag, file, line, function, name_fmt, ap1, ap2); 01380 va_end(ap1); 01381 va_end(ap2); 01382 01383 return result; 01384 }
struct ast_channel* __ast_dummy_channel_alloc | ( | const char * | file, | |
int | line, | |||
const char * | function | |||
) | [read] |
Definition at line 1389 of file channel.c.
References __ao2_alloc_debug(), ast_channel::alertpipe, ao2_alloc, ARRAY_LEN, ast_channel_unref, ast_dummy_channel_destructor(), AST_LIST_HEAD_INIT_NOLOCK, ast_string_field_init, ast_channel::fds, ast_channel::timingfd, and ast_channel::varshead.
01393 { 01394 struct ast_channel *tmp; 01395 struct varshead *headp; 01396 int x; 01397 01398 #if defined(REF_DEBUG) 01399 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel", 01400 file, line, function, 1); 01401 #elif defined(__AST_DEBUG_MALLOC) 01402 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel", 01403 file, line, function, 0); 01404 #else 01405 tmp = ao2_alloc(sizeof(*tmp), ast_dummy_channel_destructor); 01406 #endif 01407 if (!tmp) { 01408 /* Dummy channel structure allocation failure. */ 01409 return NULL; 01410 } 01411 01412 if ((ast_string_field_init(tmp, 128))) { 01413 return ast_channel_unref(tmp); 01414 } 01415 01416 /* 01417 * Init file descriptors to unopened state just in case 01418 * autoservice is called on the channel or something tries to 01419 * read a frame from it. 01420 */ 01421 tmp->timingfd = -1; 01422 for (x = 0; x < ARRAY_LEN(tmp->alertpipe); ++x) { 01423 tmp->alertpipe[x] = -1; 01424 } 01425 for (x = 0; x < ARRAY_LEN(tmp->fds); ++x) { 01426 tmp->fds[x] = -1; 01427 } 01428 #ifdef HAVE_EPOLL 01429 tmp->epfd = -1; 01430 #endif 01431 01432 headp = &tmp->varshead; 01433 AST_LIST_HEAD_INIT_NOLOCK(headp); 01434 01435 return tmp; 01436 }
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 | |||
) | [read] |
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 5456 of file channel.c.
References ast_channel::_state, outgoing_helper::account, ast_call(), ast_call_forward(), AST_CAUSE_NO_ANSWER, ast_cdr_alloc(), ast_cdr_answer(), ast_cdr_busy(), ast_cdr_disposition(), ast_cdr_end(), ast_cdr_failed(), AST_CDR_FLAG_ORIGINATED, ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_setapp(), ast_cdr_start(), ast_cdr_update(), ast_channel_datastore_inherit(), ast_channel_inherit_variables(), ast_channel_lock, ast_channel_lock_both, ast_channel_set_connected_line(), ast_channel_unlock, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CC, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_copy_string(), AST_FRAME_CONTROL, ast_frfree, ast_hangup(), ast_log(), ast_party_connected_line_set_init(), AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, ast_read(), ast_remaining_ms(), ast_request(), ast_set_callerid(), ast_set_flag, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_tvnow(), ast_waitfor(), ast_channel::cdr, outgoing_helper::cid_name, outgoing_helper::cid_num, ast_channel::connected, ast_channel::context, outgoing_helper::context, ast_channel::exten, outgoing_helper::exten, ast_frame::frametype, handle_cause(), ast_channel::hangupcause, ast_party_connected_line::id, ast_frame_subclass::integer, LOG_NOTICE, ast_party_id::name, ast_party_id::number, outgoing_helper::parent_channel, ast_party_name::presentation, ast_party_number::presentation, ast_channel::priority, outgoing_helper::priority, ast_party_name::str, ast_party_number::str, ast_frame::subclass, ast_party_name::valid, ast_party_number::valid, and outgoing_helper::vars.
Referenced by ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_request_and_dial(), and parkandannounce_exec().
05457 { 05458 int dummy_outstate; 05459 int cause = 0; 05460 struct ast_channel *chan; 05461 int res = 0; 05462 int last_subclass = 0; 05463 struct ast_party_connected_line connected; 05464 05465 if (outstate) 05466 *outstate = 0; 05467 else 05468 outstate = &dummy_outstate; /* make outstate always a valid pointer */ 05469 05470 chan = ast_request(type, format, requestor, data, &cause); 05471 if (!chan) { 05472 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data); 05473 handle_cause(cause, outstate); 05474 return NULL; 05475 } 05476 05477 if (oh) { 05478 if (oh->vars) { 05479 ast_set_variables(chan, oh->vars); 05480 } 05481 if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) { 05482 /* 05483 * Use the oh values instead of the function parameters for the 05484 * outgoing CallerID. 05485 */ 05486 cid_num = oh->cid_num; 05487 cid_name = oh->cid_name; 05488 } 05489 if (oh->parent_channel) { 05490 /* Safely inherit variables and datastores from the parent channel. */ 05491 ast_channel_lock_both(oh->parent_channel, chan); 05492 ast_channel_inherit_variables(oh->parent_channel, chan); 05493 ast_channel_datastore_inherit(oh->parent_channel, chan); 05494 ast_channel_unlock(oh->parent_channel); 05495 ast_channel_unlock(chan); 05496 } 05497 if (oh->account) { 05498 ast_channel_lock(chan); 05499 ast_cdr_setaccount(chan, oh->account); 05500 ast_channel_unlock(chan); 05501 } 05502 } 05503 05504 /* 05505 * I seems strange to set the CallerID on an outgoing call leg 05506 * to whom we are calling, but this function's callers are doing 05507 * various Originate methods. This call leg goes to the local 05508 * user. Once the local user answers, the dialplan needs to be 05509 * able to access the CallerID from the CALLERID function as if 05510 * the local user had placed this call. 05511 */ 05512 ast_set_callerid(chan, cid_num, cid_name, cid_num); 05513 05514 ast_set_flag(chan->cdr, AST_CDR_FLAG_ORIGINATED); 05515 ast_party_connected_line_set_init(&connected, &chan->connected); 05516 if (cid_num) { 05517 connected.id.number.valid = 1; 05518 connected.id.number.str = (char *) cid_num; 05519 connected.id.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 05520 } 05521 if (cid_name) { 05522 connected.id.name.valid = 1; 05523 connected.id.name.str = (char *) cid_name; 05524 connected.id.name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 05525 } 05526 ast_channel_set_connected_line(chan, &connected, NULL); 05527 05528 if (ast_call(chan, data, 0)) { /* ast_call failed... */ 05529 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data); 05530 } else { 05531 struct timeval start = ast_tvnow(); 05532 res = 1; /* mark success in case chan->_state is already AST_STATE_UP */ 05533 while (timeout && chan->_state != AST_STATE_UP) { 05534 struct ast_frame *f; 05535 int ms = ast_remaining_ms(start, timeout); 05536 05537 res = ast_waitfor(chan, ms); 05538 if (res == 0) { /* timeout, treat it like ringing */ 05539 *outstate = AST_CONTROL_RINGING; 05540 break; 05541 } 05542 if (res < 0) /* error or done */ 05543 break; 05544 if (!ast_strlen_zero(chan->call_forward)) { 05545 if (!(chan = ast_call_forward(NULL, chan, NULL, format, oh, outstate))) { 05546 return NULL; 05547 } 05548 continue; 05549 } 05550 05551 f = ast_read(chan); 05552 if (!f) { 05553 *outstate = AST_CONTROL_HANGUP; 05554 res = 0; 05555 break; 05556 } 05557 if (f->frametype == AST_FRAME_CONTROL) { 05558 switch (f->subclass.integer) { 05559 case AST_CONTROL_RINGING: /* record but keep going */ 05560 *outstate = f->subclass.integer; 05561 break; 05562 05563 case AST_CONTROL_BUSY: 05564 ast_cdr_busy(chan->cdr); 05565 *outstate = f->subclass.integer; 05566 timeout = 0; 05567 break; 05568 05569 case AST_CONTROL_INCOMPLETE: 05570 ast_cdr_failed(chan->cdr); 05571 *outstate = AST_CONTROL_CONGESTION; 05572 timeout = 0; 05573 break; 05574 05575 case AST_CONTROL_CONGESTION: 05576 ast_cdr_failed(chan->cdr); 05577 *outstate = f->subclass.integer; 05578 timeout = 0; 05579 break; 05580 05581 case AST_CONTROL_ANSWER: 05582 ast_cdr_answer(chan->cdr); 05583 *outstate = f->subclass.integer; 05584 timeout = 0; /* trick to force exit from the while() */ 05585 break; 05586 05587 /* Ignore these */ 05588 case AST_CONTROL_PROGRESS: 05589 case AST_CONTROL_PROCEEDING: 05590 case AST_CONTROL_HOLD: 05591 case AST_CONTROL_UNHOLD: 05592 case AST_CONTROL_VIDUPDATE: 05593 case AST_CONTROL_SRCUPDATE: 05594 case AST_CONTROL_SRCCHANGE: 05595 case AST_CONTROL_CONNECTED_LINE: 05596 case AST_CONTROL_REDIRECTING: 05597 case AST_CONTROL_CC: 05598 case -1: /* Ignore -- just stopping indications */ 05599 break; 05600 05601 default: 05602 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass.integer); 05603 } 05604 last_subclass = f->subclass.integer; 05605 } 05606 ast_frfree(f); 05607 } 05608 } 05609 05610 /* Final fixups */ 05611 if (oh) { 05612 if (!ast_strlen_zero(oh->context)) 05613 ast_copy_string(chan->context, oh->context, sizeof(chan->context)); 05614 if (!ast_strlen_zero(oh->exten)) 05615 ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten)); 05616 if (oh->priority) 05617 chan->priority = oh->priority; 05618 } 05619 if (chan->_state == AST_STATE_UP) 05620 *outstate = AST_CONTROL_ANSWER; 05621 05622 if (res <= 0) { 05623 ast_channel_lock(chan); 05624 if (AST_CONTROL_RINGING == last_subclass) { 05625 chan->hangupcause = AST_CAUSE_NO_ANSWER; 05626 } 05627 if (!chan->cdr && (chan->cdr = ast_cdr_alloc())) { 05628 ast_cdr_init(chan->cdr, chan); 05629 } 05630 if (chan->cdr) { 05631 char tmp[256]; 05632 05633 snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data); 05634 ast_cdr_setapp(chan->cdr, "Dial", tmp); 05635 ast_cdr_update(chan); 05636 ast_cdr_start(chan->cdr); 05637 ast_cdr_end(chan->cdr); 05638 /* If the cause wasn't handled properly */ 05639 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) { 05640 ast_cdr_failed(chan->cdr); 05641 } 05642 } 05643 ast_channel_unlock(chan); 05644 ast_hangup(chan); 05645 chan = NULL; 05646 } 05647 return chan; 05648 }
int ast_activate_generator | ( | struct ast_channel * | chan, | |
struct ast_generator * | gen, | |||
void * | params | |||
) |
Activate a given generator
Definition at line 3148 of file channel.c.
References ast_generator::alloc, ast_channel_lock, ast_channel_unlock, ast_prod(), ast_settimeout(), ast_channel::generator, generator_force(), ast_channel::generatordata, and ast_generator::release.
Referenced by app_exec(), ast_channel_start_silence_generator(), ast_linear_stream(), ast_playtones_start(), ast_tonepair_start(), channel_spy(), eivr_comm(), local_ast_moh_start(), old_milliwatt_exec(), and transmit_audio().
03149 { 03150 int res = 0; 03151 03152 ast_channel_lock(chan); 03153 if (chan->generatordata) { 03154 struct ast_generator *generator_old = chan->generator; 03155 03156 if (generator_old && generator_old->release) { 03157 generator_old->release(chan, chan->generatordata); 03158 } 03159 chan->generatordata = NULL; 03160 } 03161 if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) { 03162 res = -1; 03163 } 03164 if (!res) { 03165 ast_settimeout(chan, 50, generator_force, chan); 03166 chan->generator = gen; 03167 } 03168 ast_channel_unlock(chan); 03169 03170 ast_prod(chan); 03171 03172 return res; 03173 }
int ast_active_channels | ( | void | ) |
returns number of active/allocated channels
Definition at line 848 of file channel.c.
References ao2_container_count(), and channels.
Referenced by action_corestatus(), ast_var_channels(), ast_var_channels_table(), dahdi_restart(), handle_chanlist(), handle_show_settings(), and really_quit().
00849 { 00850 return channels ? ao2_container_count(channels) : 0; 00851 }
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 2390 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 answers a channel and handles all necessary call setup functions.
0 | on success | |
non-zero | on failure |
Definition at line 3086 of file channel.c.
References __ast_answer().
Referenced by action_bridge(), agi_exec_full(), alarmreceiver_exec(), answer_trunk_chan(), app_exec(), ast_control_streamfile(), ast_do_pickup(), ast_pickup_call(), auth_exec(), background_detect_exec(), bridge_exec(), builtin_parkcall(), common_exec(), conf_exec(), count_exec(), dahdiras_exec(), dial_exec_full(), dictate_exec(), directory_exec(), disa_exec(), eivr_comm(), handle_answer(), ices_exec(), login_exec(), minivm_accmess_exec(), minivm_greet_exec(), minivm_record_exec(), old_milliwatt_exec(), park_call_exec(), parked_call_exec(), pbx_builtin_background(), playback_exec(), privacy_exec(), read_exec(), readexten_exec(), receivefax_exec(), record_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().
03087 { 03088 return __ast_answer(chan, 0, 1); 03089 }
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 307 of file autoservice.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, asent::chan, asent::ignore_frame_types, and asent::list.
Referenced by builtin_automixmonitor(), feature_exec_app(), and play_message_on_chan().
00308 { 00309 struct asent *as; 00310 int res = -1; 00311 00312 AST_LIST_LOCK(&aslist); 00313 AST_LIST_TRAVERSE(&aslist, as, list) { 00314 if (as->chan == chan) { 00315 res = 0; 00316 as->ignore_frame_types |= (1 << ftype); 00317 break; 00318 } 00319 } 00320 AST_LIST_UNLOCK(&aslist); 00321 return res; 00322 }
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 179 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, 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(), ast_app_exec_macro(), ast_app_exec_sub(), ast_dtmf_stream(), ast_get_enum(), ast_get_srv(), ast_get_txt(), ast_masq_park_call_exten(), ast_park_call_exten(), bridge_playfile(), builtin_atxfer(), builtin_automixmonitor(), builtin_blindtransfer(), conf_play(), confbridge_exec(), dial_exec_full(), exec(), feature_exec_app(), feature_request_and_dial(), function_realtime_read(), function_realtime_readdestroy(), function_realtime_store(), function_realtime_write(), leave_conference_bridge(), lock_read(), lua_autoservice_start(), lua_get_variable_value(), lua_pbx_exec(), lua_set_variable(), lua_set_variable_value(), originate_exec(), osplookup_exec(), pbx_find_extension(), play_message_on_chan(), realtimefield_read(), shell_helper(), sla_station_exec(), smdi_msg_retrieve_read(), srv_datastore_setup(), system_exec_helper(), try_calling(), and trylock_read().
00180 { 00181 int res = 0; 00182 struct asent *as; 00183 00184 AST_LIST_LOCK(&aslist); 00185 AST_LIST_TRAVERSE(&aslist, as, list) { 00186 if (as->chan == chan) { 00187 as->use_count++; 00188 break; 00189 } 00190 } 00191 AST_LIST_UNLOCK(&aslist); 00192 00193 if (as) { 00194 /* Entry exists, autoservice is already handling this channel */ 00195 return 0; 00196 } 00197 00198 if (!(as = ast_calloc(1, sizeof(*as)))) 00199 return -1; 00200 00201 /* New entry created */ 00202 as->chan = chan; 00203 as->use_count = 1; 00204 00205 ast_channel_lock(chan); 00206 as->orig_end_dtmf_flag = ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY) ? 1 : 0; 00207 if (!as->orig_end_dtmf_flag) 00208 ast_set_flag(chan, AST_FLAG_END_DTMF_ONLY); 00209 ast_channel_unlock(chan); 00210 00211 AST_LIST_LOCK(&aslist); 00212 00213 if (AST_LIST_EMPTY(&aslist) && asthread != AST_PTHREADT_NULL) { 00214 ast_cond_signal(&as_cond); 00215 } 00216 00217 AST_LIST_INSERT_HEAD(&aslist, as, list); 00218 00219 if (asthread == AST_PTHREADT_NULL) { /* need start the thread */ 00220 if (ast_pthread_create_background(&asthread, NULL, autoservice_run, NULL)) { 00221 ast_log(LOG_WARNING, "Unable to create autoservice thread :(\n"); 00222 /* There will only be a single member in the list at this point, 00223 the one we just added. */ 00224 AST_LIST_REMOVE(&aslist, as, list); 00225 free(as); 00226 asthread = AST_PTHREADT_NULL; 00227 res = -1; 00228 } else { 00229 pthread_kill(asthread, SIGURG); 00230 } 00231 } 00232 00233 AST_LIST_UNLOCK(&aslist); 00234 00235 return res; 00236 }
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 238 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, ast_frame::frametype, 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_exec_macro(), ast_app_exec_sub(), ast_dtmf_stream(), ast_get_enum(), ast_get_srv(), ast_get_txt(), ast_hangup(), ast_masq_park_call_exten(), ast_park_call_exten(), bridge_playfile(), builtin_atxfer(), builtin_automixmonitor(), conf_play(), confbridge_exec(), dial_exec_full(), exec(), feature_exec_app(), feature_request_and_dial(), finishup(), function_realtime_read(), function_realtime_readdestroy(), function_realtime_store(), function_realtime_write(), leave_conference_bridge(), lock_read(), lua_autoservice_stop(), lua_get_variable_value(), lua_pbx_exec(), lua_set_variable(), lua_set_variable_value(), originate_exec(), osplookup_exec(), pbx_find_extension(), play_message_on_chan(), realtimefield_read(), shell_helper(), sla_station_exec(), smdi_msg_retrieve_read(), srv_datastore_setup(), system_exec_helper(), try_calling(), and trylock_read().
00239 { 00240 int res = -1; 00241 struct asent *as, *removed = NULL; 00242 struct ast_frame *f; 00243 int chan_list_state; 00244 00245 AST_LIST_LOCK(&aslist); 00246 00247 /* Save the autoservice channel list state. We _must_ verify that the channel 00248 * list has been rebuilt before we return. Because, after we return, the channel 00249 * could get destroyed and we don't want our poor autoservice thread to step on 00250 * it after its gone! */ 00251 chan_list_state = as_chan_list_state; 00252 00253 /* Find the entry, but do not free it because it still can be in the 00254 autoservice thread array */ 00255 AST_LIST_TRAVERSE_SAFE_BEGIN(&aslist, as, list) { 00256 if (as->chan == chan) { 00257 as->use_count--; 00258 if (as->use_count < 1) { 00259 AST_LIST_REMOVE_CURRENT(list); 00260 removed = as; 00261 } 00262 break; 00263 } 00264 } 00265 AST_LIST_TRAVERSE_SAFE_END; 00266 00267 if (removed && asthread != AST_PTHREADT_NULL) { 00268 pthread_kill(asthread, SIGURG); 00269 } 00270 00271 AST_LIST_UNLOCK(&aslist); 00272 00273 if (!removed) { 00274 return 0; 00275 } 00276 00277 /* Wait while autoservice thread rebuilds its list. */ 00278 while (chan_list_state == as_chan_list_state) { 00279 usleep(1000); 00280 } 00281 00282 /* Now autoservice thread should have no references to our entry 00283 and we can safely destroy it */ 00284 00285 if (!chan->_softhangup) { 00286 res = 0; 00287 } 00288 00289 if (!as->orig_end_dtmf_flag) { 00290 ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY); 00291 } 00292 00293 ast_channel_lock(chan); 00294 while ((f = AST_LIST_REMOVE_HEAD(&as->deferred_frames, frame_list))) { 00295 if (!((1 << f->frametype) & as->ignore_frame_types)) { 00296 ast_queue_frame_head(chan, f); 00297 } 00298 ast_frfree(f); 00299 } 00300 ast_channel_unlock(chan); 00301 00302 free(as); 00303 00304 return res; 00305 }
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 838 of file channel.c.
References ao2_callback, ast_channel_softhangup_cb(), channels, OBJ_MULTIPLE, and OBJ_NODATA.
Referenced by can_safely_quit().
00839 { 00840 shutting_down = 1; 00841 00842 if (hangup) { 00843 ao2_callback(channels, OBJ_NODATA | OBJ_MULTIPLE, ast_channel_softhangup_cb, NULL); 00844 } 00845 }
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 1062 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().
01063 { 01064 /* This just our opinion, expressed in code. We are asked to choose 01065 the best codec to use, given no information */ 01066 int x; 01067 static const format_t prefs[] = 01068 { 01069 /*! Okay, ulaw is used by all telephony equipment, so start with it */ 01070 AST_FORMAT_ULAW, 01071 /*! Unless of course, you're a silly European, so then prefer ALAW */ 01072 AST_FORMAT_ALAW, 01073 AST_FORMAT_G719, 01074 AST_FORMAT_SIREN14, 01075 AST_FORMAT_SIREN7, 01076 AST_FORMAT_TESTLAW, 01077 /*! G.722 is better then all below, but not as common as the above... so give ulaw and alaw priority */ 01078 AST_FORMAT_G722, 01079 /*! Okay, well, signed linear is easy to translate into other stuff */ 01080 AST_FORMAT_SLINEAR16, 01081 AST_FORMAT_SLINEAR, 01082 /*! G.726 is standard ADPCM, in RFC3551 packing order */ 01083 AST_FORMAT_G726, 01084 /*! G.726 is standard ADPCM, in AAL2 packing order */ 01085 AST_FORMAT_G726_AAL2, 01086 /*! ADPCM has great sound quality and is still pretty easy to translate */ 01087 AST_FORMAT_ADPCM, 01088 /*! Okay, we're down to vocoders now, so pick GSM because it's small and easier to 01089 translate and sounds pretty good */ 01090 AST_FORMAT_GSM, 01091 /*! iLBC is not too bad */ 01092 AST_FORMAT_ILBC, 01093 /*! Speex is free, but computationally more expensive than GSM */ 01094 AST_FORMAT_SPEEX16, 01095 AST_FORMAT_SPEEX, 01096 /*! Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough 01097 to use it */ 01098 AST_FORMAT_LPC10, 01099 /*! G.729a is faster than 723 and slightly less expensive */ 01100 AST_FORMAT_G729A, 01101 /*! Down to G.723.1 which is proprietary but at least designed for voice */ 01102 AST_FORMAT_G723_1, 01103 }; 01104 char buf[512]; 01105 01106 /* Strip out video */ 01107 fmts &= AST_FORMAT_AUDIO_MASK; 01108 01109 /* Find the first preferred codec in the format given */ 01110 for (x = 0; x < ARRAY_LEN(prefs); x++) { 01111 if (fmts & prefs[x]) 01112 return prefs[x]; 01113 } 01114 01115 ast_log(LOG_WARNING, "Don't know any of %s formats\n", ast_getformatname_multiple(buf, sizeof(buf), fmts)); 01116 01117 return 0; 01118 }
struct ast_channel* ast_bridged_channel | ( | struct ast_channel * | chan | ) | [read] |
Find bridged channel.
chan | Current channel |
Definition at line 7160 of file channel.c.
References ast_channel::_bridge, ast_channel_tech::bridged_channel, and ast_channel::tech.
Referenced by __analog_handle_event(), __analog_ss_thread(), __ast_channel_masquerade(), __ast_read(), __dahdi_exception(), _skinny_show_lines(), action_agents(), action_coreshowchannels(), agents_data_provider_get(), agents_show(), agents_show_online(), analog_attempt_transfer(), analog_exception(), analog_hangup(), analog_ss_thread(), ast_bridge_call(), ast_cel_report_event(), ast_channel_data_add_structure(), ast_channel_set_linkgroup(), ast_do_masquerade(), ast_rtp_instance_set_stats_vars(), ast_set_hangupsource(), ast_var_channel_bridge(), ast_var_channels_table(), attempt_transfer(), cb_events(), channel_spy(), check_bridge(), common_exec(), console_transfer(), create_jb(), dahdi_handle_event(), dahdi_hangup(), export_aoc_vars(), func_channel_read(), get_refer_info(), handle_chanlist(), handle_hd_hf(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_refer(), handle_showchan(), handle_soft_key_event_message(), handle_stimulus_message(), key_call(), key_dial_page(), local_attended_transfer(), local_queryoption(), mgcp_hangup(), mgcp_ss(), misdn_attempt_transfer(), mixmonitor_thread(), my_get_sigpvt_bridged_channel(), park_call_full(), schedule_delivery(), serialize_showchan(), sip_get_rtp_peer(), sip_get_trtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), sip_hangup(), sip_set_rtp_peer(), skinny_transfer(), socket_process(), start_spying(), startmon(), TransferCallStep1(), and unistim_hangup().
07161 { 07162 struct ast_channel *bridged; 07163 bridged = chan->_bridge; 07164 if (bridged && bridged->tech->bridged_channel) 07165 bridged = bridged->tech->bridged_channel(chan, bridged); 07166 return bridged; 07167 }
int ast_call | ( | struct ast_channel * | chan, | |
char * | addr, | |||
int | timeout | |||
) |
Make a call.
chan | which channel to make the call on | |
addr | destination of the call (Should be treated as const char *) | |
timeout | time to wait on for connect |
Place a call, take no longer than timeout ms.
Definition at line 5761 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, and ast_channel::tech.
Referenced by __ast_request_and_dial(), ast_call_forward(), begin_dial_channel(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), play_sound_file(), ring_entry(), and wait_for_answer().
05762 { 05763 /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 05764 If the remote end does not answer within the timeout, then do NOT hang up, but 05765 return anyway. */ 05766 int res = -1; 05767 /* Stop if we're a zombie or need a soft hangup */ 05768 ast_channel_lock(chan); 05769 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) { 05770 if (chan->cdr) { 05771 ast_set_flag(chan->cdr, AST_CDR_FLAG_DIALED); 05772 } 05773 if (chan->tech->call) 05774 res = chan->tech->call(chan, addr, timeout); 05775 ast_set_flag(chan, AST_FLAG_OUTGOING); 05776 } 05777 ast_channel_unlock(chan); 05778 return res; 05779 }
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 | |||
) | [read] |
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 5386 of file channel.c.
References outgoing_helper::account, accountcode, ast_call(), AST_CDR_FLAG_ORIGINATED, ast_cdr_setaccount(), ast_channel_lock, ast_channel_lock_both, ast_channel_unlock, ast_copy_flags, ast_copy_string(), ast_hangup(), ast_log(), ast_party_connected_line_copy(), ast_party_redirecting_copy(), ast_request(), ast_set_variables(), ast_string_field_set, call_forward_inherit(), ast_channel::cdr, ast_channel::connected, ast_channel::context, handle_cause(), LOG_NOTICE, outgoing_helper::parent_channel, pbx_builtin_getvar_helper(), ast_channel::redirecting, S_OR, type, and outgoing_helper::vars.
Referenced by __ast_request_and_dial(), and feature_request_and_dial().
05387 { 05388 char tmpchan[256]; 05389 struct ast_channel *new_chan = NULL; 05390 char *data, *type; 05391 int cause = 0; 05392 int res; 05393 05394 /* gather data and request the new forward channel */ 05395 ast_copy_string(tmpchan, orig->call_forward, sizeof(tmpchan)); 05396 if ((data = strchr(tmpchan, '/'))) { 05397 *data++ = '\0'; 05398 type = tmpchan; 05399 } else { 05400 const char *forward_context; 05401 ast_channel_lock(orig); 05402 forward_context = pbx_builtin_getvar_helper(orig, "FORWARD_CONTEXT"); 05403 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", orig->call_forward, S_OR(forward_context, orig->context)); 05404 ast_channel_unlock(orig); 05405 data = tmpchan; 05406 type = "Local"; 05407 } 05408 if (!(new_chan = ast_request(type, format, orig, data, &cause))) { 05409 ast_log(LOG_NOTICE, "Unable to create channel for call forward to '%s/%s' (cause = %d)\n", type, data, cause); 05410 handle_cause(cause, outstate); 05411 ast_hangup(orig); 05412 return NULL; 05413 } 05414 05415 /* Copy/inherit important information into new channel */ 05416 if (oh) { 05417 if (oh->vars) { 05418 ast_set_variables(new_chan, oh->vars); 05419 } 05420 if (oh->parent_channel) { 05421 call_forward_inherit(new_chan, oh->parent_channel, orig); 05422 } 05423 if (oh->account) { 05424 ast_channel_lock(new_chan); 05425 ast_cdr_setaccount(new_chan, oh->account); 05426 ast_channel_unlock(new_chan); 05427 } 05428 } else if (caller) { /* no outgoing helper so use caller if available */ 05429 call_forward_inherit(new_chan, caller, orig); 05430 } 05431 05432 ast_channel_lock_both(orig, new_chan); 05433 ast_copy_flags(new_chan->cdr, orig->cdr, AST_CDR_FLAG_ORIGINATED); 05434 ast_string_field_set(new_chan, accountcode, orig->accountcode); 05435 ast_party_connected_line_copy(&new_chan->connected, &orig->connected); 05436 ast_party_redirecting_copy(&new_chan->redirecting, &orig->redirecting); 05437 ast_channel_unlock(new_chan); 05438 ast_channel_unlock(orig); 05439 05440 /* call new channel */ 05441 res = ast_call(new_chan, data, 0); 05442 if (timeout) { 05443 *timeout = res; 05444 } 05445 if (res) { 05446 ast_log(LOG_NOTICE, "Unable to call forward to channel %s/%s\n", type, (char *)data); 05447 ast_hangup(orig); 05448 ast_hangup(new_chan); 05449 return NULL; 05450 } 05451 ast_hangup(orig); 05452 05453 return new_chan; 05454 }
void ast_cancel_shutdown | ( | void | ) |
Cancel a shutdown in progress.
Cancels an existing shutdown and returns to normal operation
Definition at line 859 of file channel.c.
Referenced by handle_abort_shutdown().
00860 { 00861 shutting_down = 0; 00862 }
const char* ast_cause2str | ( | int | cause | ) |
Gives the string form of a given cause code.
state | cause to get the description of |
Definition at line 980 of file channel.c.
References ARRAY_LEN, causes, and causes_map::desc.
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().
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 6229 of file channel.c.
References __ast_change_name_nolink(), ao2_link, ao2_lock, ao2_unlink, ao2_unlock, ast_channel_lock, ast_channel_unlock, and channels.
Referenced by update_name().
06230 { 06231 /* We must re-link, as the hash value will change here. */ 06232 ao2_lock(channels); 06233 ast_channel_lock(chan); 06234 ao2_unlink(channels, chan); 06235 __ast_change_name_nolink(chan, newname); 06236 ao2_link(channels, chan); 06237 ast_channel_unlock(chan); 06238 ao2_unlock(channels); 06239 }
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(?) |
Bridge two channels (c0 and c1) together. If an important frame occurs, we return that frame in *rf (remember, it could be NULL) and which channel (0 or 1) in rc
Definition at line 7506 of file channel.c.
References ast_channel::_bridge, ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_RETRY, ast_channel_clear_softhangup(), ast_channel_lock_both, ast_channel_make_compatible(), ast_channel_unlock, ast_check_hangup(), ast_check_hangup_locked(), ast_clear_flag, AST_CONTROL_SRCUPDATE, ast_debug, AST_FEATURE_PLAY_WARNING, AST_FEATURE_WARNING_ACTIVE, AST_FLAG_END_DTMF_ONLY, AST_FLAG_NBRIDGE, AST_FLAG_ZOMBIE, ast_framehook_list_is_empty(), ast_generic_bridge(), ast_indicate(), ast_log(), ast_manager_event_multichan, ast_samp2tv(), ast_set_flag, ast_set_owners_and_peers(), AST_SOFTHANGUP_UNBRIDGE, ast_test_flag, ast_test_suite_event_notify, 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, ast_bridge_config::end_sound, EVENT_FLAG_CALL, ast_bridge_config::feature_start_time, ast_bridge_config::feature_timer, ast_bridge_config::features_callee, ast_bridge_config::features_caller, ast_bridge_config::flags, ast_channel::framehooks, ast_channel::generator, ast_party_caller::id, LOG_WARNING, manager_bridge_event(), ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::nativeformats, ast_bridge_config::nexteventts, ast_party_id::number, ast_bridge_config::play_warning, ast_channel::readformat, S_COR, ast_channel_tech::send_digit_begin, ast_bridge_config::start_sound, ast_bridge_config::start_time, ast_party_number::str, ast_channel::tech, ast_bridge_config::timelimit, update_bridge_vars(), ast_party_number::valid, ast_bridge_config::warning_freq, ast_bridge_config::warning_sound, and ast_channel::writeformat.
Referenced by ast_bridge_call().
07508 { 07509 struct ast_channel *chans[2] = { c0, c1 }; 07510 enum ast_bridge_result res = AST_BRIDGE_COMPLETE; 07511 format_t o0nativeformats; 07512 format_t o1nativeformats; 07513 long time_left_ms=0; 07514 char caller_warning = 0; 07515 char callee_warning = 0; 07516 07517 *fo = NULL; 07518 07519 if (c0->_bridge) { 07520 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 07521 c0->name, c0->_bridge->name); 07522 return -1; 07523 } 07524 if (c1->_bridge) { 07525 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 07526 c1->name, c1->_bridge->name); 07527 return -1; 07528 } 07529 07530 /* Stop if we're a zombie or need a soft hangup */ 07531 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 07532 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) 07533 return -1; 07534 07535 caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING); 07536 callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING); 07537 07538 if (ast_tvzero(config->start_time)) { 07539 config->start_time = ast_tvnow(); 07540 if (config->start_sound) { 07541 if (caller_warning) { 07542 bridge_playfile(c0, c1, config->start_sound, config->timelimit / 1000); 07543 } 07544 if (callee_warning) { 07545 bridge_playfile(c1, c0, config->start_sound, config->timelimit / 1000); 07546 } 07547 } 07548 } 07549 07550 /* Keep track of bridge */ 07551 ast_channel_lock_both(c0, c1); 07552 c0->_bridge = c1; 07553 c1->_bridge = c0; 07554 ast_channel_unlock(c0); 07555 ast_channel_unlock(c1); 07556 07557 ast_set_owners_and_peers(c0, c1); 07558 07559 o0nativeformats = c0->nativeformats; 07560 o1nativeformats = c1->nativeformats; 07561 07562 if (config->feature_timer && !ast_tvzero(config->nexteventts)) { 07563 config->nexteventts = ast_tvadd(config->feature_start_time, ast_samp2tv(config->feature_timer, 1000)); 07564 } else if (config->timelimit) { 07565 time_left_ms = config->timelimit - ast_tvdiff_ms(ast_tvnow(), config->start_time); 07566 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 07567 if ((caller_warning || callee_warning) && config->play_warning) { 07568 long next_warn = config->play_warning; 07569 if (time_left_ms < config->play_warning && config->warning_freq > 0) { 07570 /* At least one warning was played, which means we are returning after feature */ 07571 long warns_passed = (config->play_warning - time_left_ms) / config->warning_freq; 07572 /* It is 'warns_passed * warning_freq' NOT '(warns_passed + 1) * warning_freq', 07573 because nexteventts will be updated once again in the 'if (!to)' block */ 07574 next_warn = config->play_warning - warns_passed * config->warning_freq; 07575 } 07576 config->nexteventts = ast_tvsub(config->nexteventts, ast_samp2tv(next_warn, 1000)); 07577 } 07578 } else { 07579 config->nexteventts.tv_sec = 0; 07580 config->nexteventts.tv_usec = 0; 07581 } 07582 07583 if (!c0->tech->send_digit_begin) 07584 ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY); 07585 if (!c1->tech->send_digit_begin) 07586 ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY); 07587 manager_bridge_event(1, 1, c0, c1); 07588 07589 /* Before we enter in and bridge these two together tell them both the source of audio has changed */ 07590 ast_indicate(c0, AST_CONTROL_SRCUPDATE); 07591 ast_indicate(c1, AST_CONTROL_SRCUPDATE); 07592 07593 for (/* ever */;;) { 07594 struct timeval now = { 0, }; 07595 int to; 07596 07597 to = -1; 07598 07599 if (!ast_tvzero(config->nexteventts)) { 07600 now = ast_tvnow(); 07601 to = ast_tvdiff_ms(config->nexteventts, now); 07602 if (to <= 0) { 07603 if (!config->timelimit) { 07604 res = AST_BRIDGE_COMPLETE; 07605 break; 07606 } 07607 to = 0; 07608 } 07609 } 07610 07611 if (config->timelimit) { 07612 time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time); 07613 if (time_left_ms < 0) { 07614 time_left_ms = 0; 07615 } 07616 07617 if (time_left_ms < to) { 07618 to = time_left_ms; 07619 } 07620 07621 if (time_left_ms <= 0) { 07622 if (caller_warning && config->end_sound) 07623 bridge_playfile(c0, c1, config->end_sound, 0); 07624 if (callee_warning && config->end_sound) 07625 bridge_playfile(c1, c0, config->end_sound, 0); 07626 *fo = NULL; 07627 res = AST_BRIDGE_COMPLETE; 07628 ast_test_suite_event_notify("BRIDGE_TIMELIMIT", "Channel1: %s\r\nChannel2: %s", c0->name, c1->name); 07629 break; 07630 } 07631 07632 if (!to) { 07633 if (time_left_ms >= 5000 && config->warning_sound && config->play_warning && ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) { 07634 int t = (time_left_ms + 500) / 1000; /* round to nearest second */ 07635 if (caller_warning) 07636 bridge_playfile(c0, c1, config->warning_sound, t); 07637 if (callee_warning) 07638 bridge_playfile(c1, c0, config->warning_sound, t); 07639 } 07640 07641 if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000))) { 07642 config->nexteventts = ast_tvadd(config->nexteventts, ast_samp2tv(config->warning_freq, 1000)); 07643 } else { 07644 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 07645 } 07646 } 07647 ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE); 07648 } 07649 07650 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */ 07651 if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) { 07652 ast_channel_clear_softhangup(c0, AST_SOFTHANGUP_UNBRIDGE); 07653 } 07654 if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) { 07655 ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE); 07656 } 07657 ast_channel_lock_both(c0, c1); 07658 c0->_bridge = c1; 07659 c1->_bridge = c0; 07660 ast_channel_unlock(c0); 07661 ast_channel_unlock(c1); 07662 ast_debug(1, "Unbridge signal received. Ending native bridge.\n"); 07663 continue; 07664 } 07665 07666 /* Stop if we're a zombie or need a soft hangup */ 07667 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 07668 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) { 07669 *fo = NULL; 07670 res = AST_BRIDGE_COMPLETE; 07671 ast_debug(1, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n", 07672 c0->name, c1->name, 07673 ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No", 07674 ast_check_hangup(c0) ? "Yes" : "No", 07675 ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No", 07676 ast_check_hangup(c1) ? "Yes" : "No"); 07677 break; 07678 } 07679 07680 update_bridge_vars(c0, c1); 07681 07682 bridge_play_sounds(c0, c1); 07683 07684 if (c0->tech->bridge && 07685 /* if < 1 ms remains use generic bridging for accurate timing */ 07686 (!config->timelimit || to > 1000 || to == -1) && 07687 (c0->tech->bridge == c1->tech->bridge) && 07688 !c0->monitor && !c1->monitor && 07689 !c0->audiohooks && !c1->audiohooks && 07690 ast_framehook_list_is_empty(c0->framehooks) && ast_framehook_list_is_empty(c1->framehooks) && 07691 !c0->masq && !c0->masqr && !c1->masq && !c1->masqr) { 07692 int timeoutms = to - 1000 > 0 ? to - 1000 : to; 07693 /* Looks like they share a bridge method and nothing else is in the way */ 07694 ast_set_flag(c0, AST_FLAG_NBRIDGE); 07695 ast_set_flag(c1, AST_FLAG_NBRIDGE); 07696 if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, timeoutms)) == AST_BRIDGE_COMPLETE) { 07697 ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans, 07698 "Channel1: %s\r\n" 07699 "Channel2: %s\r\n" 07700 "Uniqueid1: %s\r\n" 07701 "Uniqueid2: %s\r\n" 07702 "CallerID1: %s\r\n" 07703 "CallerID2: %s\r\n", 07704 c0->name, c1->name, 07705 c0->uniqueid, c1->uniqueid, 07706 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"), 07707 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>")); 07708 07709 ast_debug(1, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name); 07710 07711 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 07712 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 07713 07714 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */ 07715 continue; 07716 } 07717 07718 ast_channel_lock_both(c0, c1); 07719 c0->_bridge = NULL; 07720 c1->_bridge = NULL; 07721 ast_channel_unlock(c0); 07722 ast_channel_unlock(c1); 07723 return res; 07724 } else { 07725 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 07726 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 07727 } 07728 switch (res) { 07729 case AST_BRIDGE_RETRY: 07730 if (config->play_warning) { 07731 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE); 07732 } 07733 continue; 07734 default: 07735 ast_verb(3, "Native bridging %s and %s ended\n", c0->name, c1->name); 07736 /* fallthrough */ 07737 case AST_BRIDGE_FAILED_NOWARN: 07738 break; 07739 } 07740 } 07741 07742 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) || 07743 (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) && 07744 !(c0->generator || c1->generator)) { 07745 if (ast_channel_make_compatible(c0, c1)) { 07746 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name); 07747 manager_bridge_event(0, 1, c0, c1); 07748 return AST_BRIDGE_FAILED; 07749 } 07750 o0nativeformats = c0->nativeformats; 07751 o1nativeformats = c1->nativeformats; 07752 } 07753 07754 update_bridge_vars(c0, c1); 07755 07756 res = ast_generic_bridge(c0, c1, config, fo, rc); 07757 if (res != AST_BRIDGE_RETRY) { 07758 break; 07759 } else if (config->feature_timer) { 07760 /* feature timer expired but has not been updated, sending to ast_bridge_call to do so */ 07761 break; 07762 } 07763 } 07764 07765 ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY); 07766 ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY); 07767 07768 /* Now that we have broken the bridge the source will change yet again */ 07769 ast_indicate(c0, AST_CONTROL_SRCUPDATE); 07770 ast_indicate(c1, AST_CONTROL_SRCUPDATE); 07771 07772 ast_channel_lock_both(c0, c1); 07773 c0->_bridge = NULL; 07774 c1->_bridge = NULL; 07775 ast_channel_unlock(c0); 07776 ast_channel_unlock(c1); 07777 07778 ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans, 07779 "Channel1: %s\r\n" 07780 "Channel2: %s\r\n" 07781 "Uniqueid1: %s\r\n" 07782 "Uniqueid2: %s\r\n" 07783 "CallerID1: %s\r\n" 07784 "CallerID2: %s\r\n", 07785 c0->name, c1->name, 07786 c0->uniqueid, c1->uniqueid, 07787 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"), 07788 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>")); 07789 ast_debug(1, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name); 07790 07791 return res; 07792 }
struct ast_channel* ast_channel_callback | ( | ao2_callback_data_fn * | cb_fn, | |
void * | arg, | |||
void * | data, | |||
int | ao2_flags | |||
) | [read] |
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 1634 of file channel.c.
References ao2_callback_data, and channels.
Referenced by ast_pickup_call(), handle_core_set_debug_channel(), my_ast_get_channel_by_name_locked(), pickup_by_group(), pickup_by_mark(), pickup_by_part(), and state_notify_build_xml().
01636 { 01637 return ao2_callback_data(channels, ao2_flags, cb_fn, arg, data); 01638 }
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.
This function makes use of datastore operations on the channel, so it is important to lock the channel before calling this function.
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 9731 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, and ast_datastore::data.
Referenced by ast_channel_get_cc_config_params(), dahdi_new(), local_call(), local_request(), and sip_new().
09733 { 09734 struct ast_cc_config_params *cc_params; 09735 struct ast_datastore *cc_datastore; 09736 09737 if (!(cc_params = ast_cc_config_params_init())) { 09738 return -1; 09739 } 09740 09741 if (!(cc_datastore = ast_datastore_alloc(&cc_channel_datastore_info, NULL))) { 09742 ast_cc_config_params_destroy(cc_params); 09743 return -1; 09744 } 09745 09746 if (base_params) { 09747 ast_cc_copy_config_params(cc_params, base_params); 09748 } 09749 cc_datastore->data = cc_params; 09750 ast_channel_datastore_add(chan, cc_datastore); 09751 return 0; 09752 }
void ast_channel_clear_softhangup | ( | struct ast_channel * | chan, | |
int | flag | |||
) |
Clear a set of softhangup flags from a channel.
Never clear a softhangup flag from a channel directly. Instead, use this function. This ensures that all aspects of the softhangup process are aborted.
chan | the channel to clear the flag on | |
flag | the flag or flags to clear |
Definition at line 2707 of file channel.c.
References ast_channel::_softhangup, ast_channel_lock, ast_channel_unlock, AST_CONTROL_END_OF_Q, AST_FRAME_CONTROL, ast_frfree, AST_LIST_LAST, AST_LIST_REMOVE, ast_frame::frametype, ast_frame_subclass::integer, and ast_frame::subclass.
Referenced by __ast_pbx_run(), ast_channel_bridge(), ast_generic_bridge(), check_goto_on_transfer(), and collect_digits().
02708 { 02709 ast_channel_lock(chan); 02710 02711 chan->_softhangup &= ~flag; 02712 02713 if (!chan->_softhangup) { 02714 struct ast_frame *fr; 02715 02716 /* If we have completely cleared the softhangup flag, 02717 * then we need to fully abort the hangup process. This requires 02718 * pulling the END_OF_Q frame out of the channel frame queue if it 02719 * still happens to be there. */ 02720 02721 fr = AST_LIST_LAST(&chan->readq); 02722 if (fr && fr->frametype == AST_FRAME_CONTROL && 02723 fr->subclass.integer == AST_CONTROL_END_OF_Q) { 02724 AST_LIST_REMOVE(&chan->readq, fr, frame_list); 02725 ast_frfree(fr); 02726 } 02727 } 02728 02729 ast_channel_unlock(chan); 02730 }
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 |
This function compares a offset from current time with the absolute time out on a channel (when to hang up). If the absolute time out on a channel is earlier than current time plus the offset, it returns 1, if the two time values are equal, it return 0, otherwise, it return -1.
Definition at line 900 of file channel.c.
References ast_channel_cmpwhentohangup_tv().
00901 { 00902 struct timeval when = { offset, }; 00903 return ast_channel_cmpwhentohangup_tv(chan, when); 00904 }
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 885 of file channel.c.
References ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), and ast_channel::whentohangup.
Referenced by ast_channel_cmpwhentohangup().
00886 { 00887 struct timeval whentohangup; 00888 00889 if (ast_tvzero(chan->whentohangup)) 00890 return ast_tvzero(offset) ? 0 : -1; 00891 00892 if (ast_tvzero(offset)) 00893 return 1; 00894 00895 whentohangup = ast_tvadd(offset, ast_tvnow()); 00896 00897 return ast_tvdiff_ms(whentohangup, chan->whentohangup); 00898 }
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 |
Have multiple return codes based on the MACRO_RESULT
Make constants so that caller and frame can be more expressive than just '1' and '0'
Definition at line 9618 of file channel.c.
References ast_app_run_macro(), ast_channel_lock, ast_channel_unlock, ast_channel_update_connected_line(), ast_connected_line_parse_data(), ast_party_connected_line_copy(), ast_party_connected_line_free(), ast_party_connected_line_init(), ast_strdupa, ast_strlen_zero(), chanlist::connected, ast_channel::connected, ast_frame::data, ast_frame::datalen, pbx_builtin_getvar_helper(), ast_frame::ptr, and S_OR.
Referenced by __ast_read(), app_exec(), ast_bridge_call(), ast_do_pickup(), ast_generic_bridge(), atxfer_fail_cleanup(), builtin_atxfer(), feature_request_and_dial(), handle_frame(), local_bridge_loop(), parked_call_exec(), remote_bridge_loop(), and wait_for_answer().
09619 { 09620 const char *macro; 09621 const char *macro_args; 09622 int retval; 09623 09624 ast_channel_lock(macro_chan); 09625 macro = pbx_builtin_getvar_helper(macro_chan, is_caller 09626 ? "CONNECTED_LINE_CALLER_SEND_MACRO" : "CONNECTED_LINE_CALLEE_SEND_MACRO"); 09627 macro = ast_strdupa(S_OR(macro, "")); 09628 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller 09629 ? "CONNECTED_LINE_CALLER_SEND_MACRO_ARGS" : "CONNECTED_LINE_CALLEE_SEND_MACRO_ARGS"); 09630 macro_args = ast_strdupa(S_OR(macro_args, "")); 09631 09632 if (ast_strlen_zero(macro)) { 09633 ast_channel_unlock(macro_chan); 09634 return -1; 09635 } 09636 09637 if (is_frame) { 09638 const struct ast_frame *frame = connected_info; 09639 09640 ast_connected_line_parse_data(frame->data.ptr, frame->datalen, ¯o_chan->connected); 09641 } else { 09642 const struct ast_party_connected_line *connected = connected_info; 09643 09644 ast_party_connected_line_copy(¯o_chan->connected, connected); 09645 } 09646 ast_channel_unlock(macro_chan); 09647 09648 retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args); 09649 if (!retval) { 09650 struct ast_party_connected_line saved_connected; 09651 09652 ast_party_connected_line_init(&saved_connected); 09653 ast_channel_lock(macro_chan); 09654 ast_party_connected_line_copy(&saved_connected, ¯o_chan->connected); 09655 ast_channel_unlock(macro_chan); 09656 ast_channel_update_connected_line(macro_chan, &saved_connected, NULL); 09657 ast_party_connected_line_free(&saved_connected); 09658 } 09659 09660 return retval; 09661 }
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 357 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, 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().
00359 { 00360 struct ast_channel *bc; 00361 struct ast_data *data_bridged; 00362 struct ast_data *data_cdr; 00363 struct ast_data *data_flags; 00364 struct ast_data *data_zones; 00365 struct ast_data *enum_node; 00366 struct ast_data *data_softhangup; 00367 #if 0 /* XXX AstData: ast_callerid no longer exists. (Equivalent code not readily apparent.) */ 00368 struct ast_data *data_callerid; 00369 char value_str[100]; 00370 #endif 00371 00372 if (!tree) { 00373 return -1; 00374 } 00375 00376 ast_data_add_structure(ast_channel, tree, chan); 00377 00378 if (add_bridged) { 00379 bc = ast_bridged_channel(chan); 00380 if (bc) { 00381 data_bridged = ast_data_add_node(tree, "bridged"); 00382 if (!data_bridged) { 00383 return -1; 00384 } 00385 ast_channel_data_add_structure(data_bridged, bc, 0); 00386 } 00387 } 00388 00389 ast_data_add_codecs(tree, "oldwriteformat", chan->oldwriteformat); 00390 ast_data_add_codecs(tree, "nativeformats", chan->nativeformats); 00391 ast_data_add_codecs(tree, "readformat", chan->readformat); 00392 ast_data_add_codecs(tree, "writeformat", chan->writeformat); 00393 ast_data_add_codecs(tree, "rawreadformat", chan->rawreadformat); 00394 ast_data_add_codecs(tree, "rawwriteformat", chan->rawwriteformat); 00395 00396 /* state */ 00397 enum_node = ast_data_add_node(tree, "state"); 00398 if (!enum_node) { 00399 return -1; 00400 } 00401 ast_data_add_str(enum_node, "text", ast_state2str(chan->_state)); 00402 ast_data_add_int(enum_node, "value", chan->_state); 00403 00404 /* hangupcause */ 00405 enum_node = ast_data_add_node(tree, "hangupcause"); 00406 if (!enum_node) { 00407 return -1; 00408 } 00409 ast_data_add_str(enum_node, "text", ast_cause2str(chan->hangupcause)); 00410 ast_data_add_int(enum_node, "value", chan->hangupcause); 00411 00412 /* amaflags */ 00413 enum_node = ast_data_add_node(tree, "amaflags"); 00414 if (!enum_node) { 00415 return -1; 00416 } 00417 ast_data_add_str(enum_node, "text", ast_cdr_flags2str(chan->amaflags)); 00418 ast_data_add_int(enum_node, "value", chan->amaflags); 00419 00420 /* transfercapability */ 00421 enum_node = ast_data_add_node(tree, "transfercapability"); 00422 if (!enum_node) { 00423 return -1; 00424 } 00425 ast_data_add_str(enum_node, "text", ast_transfercapability2str(chan->transfercapability)); 00426 ast_data_add_int(enum_node, "value", chan->transfercapability); 00427 00428 /* _softphangup */ 00429 data_softhangup = ast_data_add_node(tree, "softhangup"); 00430 if (!data_softhangup) { 00431 return -1; 00432 } 00433 ast_data_add_bool(data_softhangup, "dev", chan->_softhangup & AST_SOFTHANGUP_DEV); 00434 ast_data_add_bool(data_softhangup, "asyncgoto", chan->_softhangup & AST_SOFTHANGUP_ASYNCGOTO); 00435 ast_data_add_bool(data_softhangup, "shutdown", chan->_softhangup & AST_SOFTHANGUP_SHUTDOWN); 00436 ast_data_add_bool(data_softhangup, "timeout", chan->_softhangup & AST_SOFTHANGUP_TIMEOUT); 00437 ast_data_add_bool(data_softhangup, "appunload", chan->_softhangup & AST_SOFTHANGUP_APPUNLOAD); 00438 ast_data_add_bool(data_softhangup, "explicit", chan->_softhangup & AST_SOFTHANGUP_EXPLICIT); 00439 ast_data_add_bool(data_softhangup, "unbridge", chan->_softhangup & AST_SOFTHANGUP_UNBRIDGE); 00440 00441 /* channel flags */ 00442 data_flags = ast_data_add_node(tree, "flags"); 00443 if (!data_flags) { 00444 return -1; 00445 } 00446 channel_data_add_flags(data_flags, chan); 00447 00448 ast_data_add_uint(tree, "timetohangup", chan->whentohangup.tv_sec); 00449 00450 #if 0 /* XXX AstData: ast_callerid no longer exists. (Equivalent code not readily apparent.) */ 00451 /* callerid */ 00452 data_callerid = ast_data_add_node(tree, "callerid"); 00453 if (!data_callerid) { 00454 return -1; 00455 } 00456 ast_data_add_structure(ast_callerid, data_callerid, &(chan->cid)); 00457 /* insert the callerid ton */ 00458 enum_node = ast_data_add_node(data_callerid, "cid_ton"); 00459 if (!enum_node) { 00460 return -1; 00461 } 00462 ast_data_add_int(enum_node, "value", chan->cid.cid_ton); 00463 snprintf(value_str, sizeof(value_str), "TON: %s/Plan: %s", 00464 party_number_ton2str(chan->cid.cid_ton), 00465 party_number_plan2str(chan->cid.cid_ton)); 00466 ast_data_add_str(enum_node, "text", value_str); 00467 #endif 00468 00469 /* tone zone */ 00470 if (chan->zone) { 00471 data_zones = ast_data_add_node(tree, "zone"); 00472 if (!data_zones) { 00473 return -1; 00474 } 00475 ast_tone_zone_data_add_structure(data_zones, chan->zone); 00476 } 00477 00478 /* insert cdr */ 00479 data_cdr = ast_data_add_node(tree, "cdr"); 00480 if (!data_cdr) { 00481 return -1; 00482 } 00483 00484 ast_cdr_data_add_structure(data_cdr, chan->cdr, 1); 00485 00486 return 0; 00487 }
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 489 of file channel.c.
References ast_data_search_cmp_structure.
00491 { 00492 return ast_data_search_cmp_structure(tree, ast_channel, chan, structure_name); 00493 }
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 2590 of file channel.c.
References AST_LIST_INSERT_HEAD.
Referenced by __ast_channel_masquerade(), _macro_exec(), acf_curlopt_write(), acf_iaxvar_write(), acf_odbc_read(), add_features_datastore(), add_to_agi(), apply_plc(), ast_cel_fabricate_channel_from_event(), ast_channel_cc_params_init(), ast_do_pickup(), ast_iax2_new(), ast_setup_cc_recall_datastore(), audiohook_volume_get(), authenticate_reply(), calendar_query_exec(), cc_interfaces_datastore_init(), dial_exec_full(), do_notify(), dundi_query_read(), enable_jack_hook(), enum_query_read(), find_or_create_details(), find_transaction(), frame_trace_helper(), func_channel_write_real(), get_lock(), gosub_exec(), lua_get_state(), mute_add_audiohook(), pitchshift_helper(), raise_exception(), set_chan_app_data(), setup_inheritance_datastore(), setup_mixmonitor_ds(), setup_transfer_datastore(), shared_write(), smdi_msg_retrieve_read(), socket_process(), speech_create(), speex_write(), srv_datastore_setup(), try_calling(), and volume_write().
02591 { 02592 int res = 0; 02593 02594 AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry); 02595 02596 return res; 02597 }
struct ast_datastore* attribute_malloc ast_channel_datastore_alloc | ( | const struct ast_datastore_info * | info, | |
const char * | uid | |||
) | [read] |
Create a channel data store object.
Definition at line 2563 of file channel.c.
References ast_datastore_alloc.
02564 { 02565 return ast_datastore_alloc(info, uid); 02566 }
struct ast_datastore* ast_channel_datastore_find | ( | struct ast_channel * | chan, | |
const struct ast_datastore_info * | info, | |||
const char * | uid | |||
) | [read] |
Find a datastore on a channel.
pointer | to the datastore if found | |
NULL | if not found |
Definition at line 2604 of file channel.c.
References AST_LIST_TRAVERSE, 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(), acf_odbc_read(), add_agi_cmd(), add_features_datastore(), add_to_agi(), apply_plc(), ast_can_pickup(), ast_cc_agent_set_interfaces_chanvar(), ast_cc_call_init(), ast_cc_completed(), ast_cc_extension_monitor_add_dialstring(), ast_cc_get_current_core_id(), ast_cc_is_recall(), ast_cc_offer(), ast_channel_get_cc_config_params(), ast_do_masquerade(), ast_handle_cc_control_frame(), ast_ignore_cc(), ast_odbc_retrieve_transaction_obj(), ast_set_cc_interfaces_chanvar(), attended_transfer_occurred(), audiohook_volume_callback(), audiohook_volume_get(), balance_stack(), builtin_atxfer(), calendar_event_read(), calendar_query_exec(), calendar_query_result_exec(), cc_build_payload(), clear_dialed_interfaces(), dial_exec_full(), disable_jack_hook(), dundi_result_read(), enable_jack_hook(), enum_result_read(), exec_odbcfinish(), find_details(), find_speech(), find_transaction(), frame_trace_helper(), func_channel_read(), func_channel_write_real(), func_inheritance_write(), func_mute_write(), get_agi_cmd(), get_lock(), gosub_exec(), gosub_run(), handle_gosub(), iax2_call(), jack_hook_callback(), local_read(), local_write(), lock_fixup(), lua_get_state(), manage_parked_call(), manager_mutestream(), mark_transaction_active(), mute_callback(), parked_call_exec(), pitchshift_cb(), pitchshift_helper(), pop_exec(), queue_transfer_fixup(), raise_exception(), release_transaction(), return_exec(), set_security_requirements(), shared_read(), shared_write(), smdi_msg_read(), speech_datastore_destroy(), speex_callback(), speex_read(), speex_write(), srv_query_read(), srv_result_read(), stackpeek_read(), stop_mixmonitor_exec(), try_calling(), unlock_read(), volume_callback(), and volume_write().
02605 { 02606 struct ast_datastore *datastore = NULL; 02607 02608 if (info == NULL) 02609 return NULL; 02610 02611 AST_LIST_TRAVERSE(&chan->datastores, datastore, entry) { 02612 if (datastore->info != info) { 02613 continue; 02614 } 02615 02616 if (uid == NULL) { 02617 /* matched by type only */ 02618 break; 02619 } 02620 02621 if ((datastore->uid != NULL) && !strcasecmp(uid, datastore->uid)) { 02622 /* Matched by type AND uid */ 02623 break; 02624 } 02625 } 02626 02627 return datastore; 02628 }
int ast_channel_datastore_free | ( | struct ast_datastore * | datastore | ) |
Free a channel data store object.
Definition at line 2568 of file channel.c.
References ast_datastore_free().
02569 { 02570 return ast_datastore_free(datastore); 02571 }
int ast_channel_datastore_inherit | ( | struct ast_channel * | from, | |
struct ast_channel * | to | |||
) |
Inherit datastores from a parent to a child.
Definition at line 2573 of file channel.c.
References ast_datastore_alloc, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_datastore::data, DATASTORE_INHERIT_FOREVER, ast_datastore_info::duplicate, ast_datastore::info, ast_datastore::inheritance, and ast_datastore::uid.
Referenced by __ast_request_and_dial(), begin_dial_channel(), call_forward_inherit(), dial_exec_full(), dial_transfer(), do_forward(), findmeexec(), local_call(), ring_entry(), and wait_for_answer().
02574 { 02575 struct ast_datastore *datastore = NULL, *datastore2; 02576 02577 AST_LIST_TRAVERSE(&from->datastores, datastore, entry) { 02578 if (datastore->inheritance > 0) { 02579 datastore2 = ast_datastore_alloc(datastore->info, datastore->uid); 02580 if (datastore2) { 02581 datastore2->data = datastore->info->duplicate ? datastore->info->duplicate(datastore->data) : NULL; 02582 datastore2->inheritance = datastore->inheritance == DATASTORE_INHERIT_FOREVER ? DATASTORE_INHERIT_FOREVER : datastore->inheritance - 1; 02583 AST_LIST_INSERT_TAIL(&to->datastores, datastore2, entry); 02584 } 02585 } 02586 } 02587 return 0; 02588 }
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 2599 of file channel.c.
References AST_LIST_REMOVE.
Referenced by acf_fetch(), acf_odbc_read(), adjust_frame_for_plc(), ast_do_masquerade(), ast_do_pickup(), clear_dialed_interfaces(), dial_exec_full(), disable_jack_hook(), exec_odbcfinish(), frame_trace_helper(), lua_get_state(), queue_transfer_fixup(), speech_datastore_destroy(), speex_write(), srv_query_read(), stop_mixmonitor_exec(), and try_calling().
02600 { 02601 return AST_LIST_REMOVE(&chan->datastores, datastore, entry) ? 0 : -1; 02602 }
int ast_channel_defer_dtmf | ( | struct ast_channel * | chan | ) |
Defers DTMF so that you only read things like hangups and audio.
Definition at line 1616 of file channel.c.
References AST_FLAG_DEFER_DTMF, ast_set_flag, and ast_test_flag.
Referenced by __adsi_transmit_messages(), and find_cache().
01617 { 01618 int pre = 0; 01619 01620 if (chan) { 01621 pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF); 01622 ast_set_flag(chan, AST_FLAG_DEFER_DTMF); 01623 } 01624 return pre; 01625 }
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 |
Bridge two channels (c0 and c1) together early. This implies either side may not be answered yet.
Definition at line 7406 of file channel.c.
References ast_channel_tech::early_bridge, and ast_channel::tech.
Referenced by dial_exec_full(), and wait_for_answer().
07407 { 07408 /* Make sure we can early bridge, if not error out */ 07409 if (!c0->tech->early_bridge || (c1 && (!c1->tech->early_bridge || c0->tech->early_bridge != c1->tech->early_bridge))) 07410 return -1; 07411 07412 return c0->tech->early_bridge(c0, c1); 07413 }
struct ast_channel* ast_channel_get_by_exten | ( | const char * | exten, | |
const char * | context | |||
) | [read] |
Find a channel by extension and context.
Return a channel that is currently at the specified extension and context.
a | channel that is at the specified extension and context | |
NULL | if no channel was found |
Definition at line 1813 of file channel.c.
References ast_channel_get_full().
01814 { 01815 return ast_channel_get_full(NULL, 0, exten, context); 01816 }
struct ast_channel* ast_channel_get_by_name | ( | const char * | name | ) | [read] |
Find a channel by name.
Channel search functions
Find a channel that has the same name as the provided argument.
a | channel with the name specified by the argument | |
NULL | if no channel was found |
Definition at line 1803 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().
01804 { 01805 return ast_channel_get_full(name, 0, NULL, NULL); 01806 }
struct ast_channel* ast_channel_get_by_name_prefix | ( | const char * | name, | |
size_t | name_len | |||
) | [read] |
Find a channel by a name prefix.
Find a channel that has the same name prefix as specified by the arguments.
a | channel with the name prefix specified by the arguments | |
NULL | if no channel was found |
Definition at line 1808 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().
01809 { 01810 return ast_channel_get_full(name, name_len, NULL, NULL); 01811 }
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.
During call completion, we will need to create a call completion agent structure. To figure out the type of agent to construct, we need to ask the channel driver for the appropriate type.
Prior to adding this function, the call completion core attempted to figure this out for itself by stripping the technology off the channel's name. However, in the case of chan_dahdi, there are multiple agent types registered, and so simply searching for an agent type called "DAHDI" is not possible. In a case where multiple agent types are defined, the channel driver must have a queryoption callback defined in its channel_tech, and the queryoption callback must handle AST_OPTION_CC_AGENT_TYPE
If a channel driver does not have a queryoption callback or if the queryoption callback does not handle AST_OPTION_CC_AGENT_TYPE, then the old behavior of using the technology portion of the channel name is used instead. This is perfectly suitable for channel drivers whose channel technologies are a one-to-one match with the agent types defined within.
Note that this function is only called when the agent policy on a given channel is set to "native." Generic agents' type can be determined automatically by the core.
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 9793 of file channel.c.
References ast_channel_queryoption(), ast_copy_string(), and AST_OPTION_CC_AGENT_TYPE.
Referenced by find_agent_callbacks().
09794 { 09795 int len = size; 09796 char *slash; 09797 09798 if (!ast_channel_queryoption(chan, AST_OPTION_CC_AGENT_TYPE, agent_type, &len, 0)) { 09799 return 0; 09800 } 09801 09802 ast_copy_string(agent_type, chan->name, size); 09803 if ((slash = strchr(agent_type, '/'))) { 09804 *slash = '\0'; 09805 } 09806 return 0; 09807 }
struct ast_cc_config_params* ast_channel_get_cc_config_params | ( | struct ast_channel * | chan | ) | [read] |
Get the CCSS parameters from a channel.
This function makes use of datastore operations on the channel, so it is important to lock the channel before calling this function.
chan | Channel to retrieve parameters from |
NULL | Failure | |
non-NULL | The parameters desired |
Definition at line 9754 of file channel.c.
References ast_assert, ast_channel_cc_params_init(), ast_channel_datastore_find(), 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(), and local_request().
09755 { 09756 struct ast_datastore *cc_datastore; 09757 09758 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) { 09759 /* If we can't find the datastore, it almost definitely means that the channel type being 09760 * used has not had its driver modified to parse CC config parameters. The best action 09761 * to take here is to create the parameters on the spot with the defaults set. 09762 */ 09763 if (ast_channel_cc_params_init(chan, NULL)) { 09764 return NULL; 09765 } 09766 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) { 09767 /* Should be impossible */ 09768 return NULL; 09769 } 09770 } 09771 09772 ast_assert(cc_datastore->data != NULL); 09773 return cc_datastore->data; 09774 }
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.
A common practice in Asterisk is to determine the device being talked to by dissecting the channel name. For certain channel types, this is not accurate. For instance, an ISDN channel is named based on what B channel is used, not the device being communicated with.
This function interfaces with a channel tech's queryoption callback to retrieve the name of the device being communicated with. If the channel does not implement this specific option, then the traditional method of using the channel name is used instead.
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 9776 of file channel.c.
References ast_channel_queryoption(), ast_copy_string(), and AST_OPTION_DEVICE_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(), sip_call(), and sip_handle_cc().
09777 { 09778 int len = name_buffer_length; 09779 char *dash; 09780 if (!ast_channel_queryoption(chan, AST_OPTION_DEVICE_NAME, device_name, &len, 0)) { 09781 return 0; 09782 } 09783 09784 /* Dang. Do it the old-fashioned way */ 09785 ast_copy_string(device_name, chan->name, name_buffer_length); 09786 if ((dash = strrchr(device_name, '-'))) { 09787 *dash = '\0'; 09788 } 09789 09790 return 0; 09791 }
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 2417 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().
02418 { 02419 enum ast_t38_state state = T38_STATE_UNAVAILABLE; 02420 int datalen = sizeof(state); 02421 02422 ast_channel_queryoption(chan, AST_OPTION_T38_STATE, &state, &datalen, 0); 02423 02424 return state; 02425 }
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 |
Scans all channel variables in the parent channel, looking for those that should be copied into the child channel. Variables whose names begin with a single '_' are copied into the child channel with the prefix removed. Variables whose names begin with '__' are copied into the child channel with their names unchanged.
Definition at line 6241 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(), and ast_channel::varshead.
Referenced by __ast_request_and_dial(), begin_dial_channel(), call_forward_inherit(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), ring_entry(), and wait_for_answer().
06242 { 06243 struct ast_var_t *current, *newvar; 06244 const char *varname; 06245 06246 AST_LIST_TRAVERSE(&parent->varshead, current, entries) { 06247 int vartype = 0; 06248 06249 varname = ast_var_full_name(current); 06250 if (!varname) 06251 continue; 06252 06253 if (varname[0] == '_') { 06254 vartype = 1; 06255 if (varname[1] == '_') 06256 vartype = 2; 06257 } 06258 06259 switch (vartype) { 06260 case 1: 06261 newvar = ast_var_assign(&varname[1], ast_var_value(current)); 06262 if (newvar) { 06263 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 06264 ast_debug(1, "Inheriting variable %s from %s to %s.\n", 06265 ast_var_name(newvar), parent->name, child->name); 06266 } 06267 break; 06268 case 2: 06269 newvar = ast_var_assign(varname, ast_var_value(current)); 06270 if (newvar) { 06271 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 06272 ast_debug(1, "Inheriting variable %s from %s to %s.\n", 06273 ast_var_name(newvar), parent->name, child->name); 06274 } 06275 break; 06276 default: 06277 break; 06278 } 06279 } 06280 }
struct ast_channel_iterator* ast_channel_iterator_all_new | ( | void | ) | [read] |
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 1701 of file channel.c.
References ast_channel_iterator::active_iterator, 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().
01702 { 01703 struct ast_channel_iterator *i; 01704 01705 if (!(i = ast_calloc(1, sizeof(*i)))) { 01706 return NULL; 01707 } 01708 01709 i->simple_iterator = ao2_iterator_init(channels, 0); 01710 i->active_iterator = &i->simple_iterator; 01711 01712 return i; 01713 }
struct ast_channel_iterator* ast_channel_iterator_by_exten_new | ( | const char * | exten, | |
const char * | context | |||
) | [read] |
Create a new channel iterator based on extension.
After creating an iterator using this function, the ast_channel_iterator_next() function can be used to iterate through all channels that are currently in the specified context and extension.
NULL | on failure | |
a | new channel iterator based on the specified parameters |
Definition at line 1691 of file channel.c.
References channel_iterator_search().
Referenced by common_exec(), and pickup_by_exten().
01692 { 01693 return channel_iterator_search(NULL, 0, exten, context); 01694 }
struct ast_channel_iterator* ast_channel_iterator_by_name_new | ( | const char * | name, | |
size_t | name_len | |||
) | [read] |
Create a new channel iterator based on name.
After creating an iterator using this function, the ast_channel_iterator_next() function can be used to iterate through all channels that exist that have the specified name or name prefix.
NULL | on failure | |
a | new channel iterator based on the specified parameters |
Definition at line 1696 of file channel.c.
References channel_iterator_search().
Referenced by ast_complete_channels(), common_exec(), and softhangup_exec().
01697 { 01698 return channel_iterator_search(name, name_len, NULL, NULL); 01699 }
struct ast_channel_iterator* ast_channel_iterator_destroy | ( | struct ast_channel_iterator * | i | ) | [read] |
Destroy a channel iterator.
This function is used to destroy a channel iterator that was retrieved by using one of the channel_iterator_new() functions.
Definition at line 1649 of file channel.c.
References ast_channel_iterator::active_iterator, ao2_iterator_destroy(), and ast_free.
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(), handle_softhangup(), pickup_by_exten(), and softhangup_exec().
01650 { 01651 ao2_iterator_destroy(i->active_iterator); 01652 ast_free(i); 01653 01654 return NULL; 01655 }
struct ast_channel* ast_channel_iterator_next | ( | struct ast_channel_iterator * | i | ) | [read] |
Get the next channel for a channel iterator.
This function should be used to iterate through all channels that match a specified set of parameters that were provided when the iterator was created.
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 1715 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().
01716 { 01717 return ao2_iterator_next(i->active_iterator); 01718 }
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 |
Set two channels to compatible formats -- call before ast_channel_bridge in general.
Definition at line 5970 of file channel.c.
References ast_channel_make_compatible_helper().
Referenced by action_bridge(), app_exec(), ast_channel_bridge(), bridge_exec(), check_compat(), dial_exec_full(), do_forward(), multiplexed_bridge_join(), parked_call_exec(), simple_bridge_join(), try_calling(), and wait_for_answer().
05971 { 05972 /* Some callers do not check return code, and we must try to set all call legs correctly */ 05973 int rc = 0; 05974 05975 /* Set up translation from the chan to the peer */ 05976 rc = ast_channel_make_compatible_helper(chan, peer); 05977 05978 if (rc < 0) 05979 return rc; 05980 05981 /* Set up translation from the peer to the chan */ 05982 rc = ast_channel_make_compatible_helper(peer, chan); 05983 05984 return rc; 05985 }
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 |
This is a very strange and freaky function used primarily for transfer. Suppose that "original" and "clone" are two channels in random situations. This function takes the guts out of "clone" and puts them into the "original" channel, then alerts the channel driver of the change, asking it to fixup any private information (like the p->owner pointer) that is affected by the change. The physical layer of the original channel is hung up.
Definition at line 6110 of file channel.c.
References __ast_channel_masquerade().
Referenced by ast_async_goto(), ast_do_pickup(), attempt_transfer(), builtin_atxfer(), check_availability(), check_bridge(), check_goto_on_transfer(), do_bridge_masquerade(), handle_invite_replaces(), iax_park(), masq_park_call(), sip_park(), and skinny_transfer().
06111 { 06112 return __ast_channel_masquerade(original, clone, NULL); 06113 }
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 7815 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_log(), 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().
07816 { 07817 int res; 07818 07819 ast_channel_lock(chan); 07820 if (!chan->tech->queryoption) { 07821 errno = ENOSYS; 07822 ast_channel_unlock(chan); 07823 return -1; 07824 } 07825 07826 if (block) 07827 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 07828 07829 res = chan->tech->queryoption(chan, option, data, datalen); 07830 ast_channel_unlock(chan); 07831 07832 return res; 07833 }
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 9098 of file channel.c.
References ast_connected_line_build_data(), AST_CONTROL_CONNECTED_LINE, and ast_queue_control_data().
Referenced by ast_do_pickup(), handle_request_invite(), handle_request_update(), handle_response_invite(), local_attended_transfer(), masquerade_colp_transfer(), misdn_queue_connected_line_update(), and sip_call().
09099 { 09100 unsigned char data[1024]; /* This should be large enough */ 09101 size_t datalen; 09102 09103 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update); 09104 if (datalen == (size_t) -1) { 09105 return; 09106 } 09107 09108 ast_queue_control_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen); 09109 }
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 9605 of file channel.c.
References AST_CONTROL_REDIRECTING, ast_queue_control_data(), and ast_redirecting_build_data().
Referenced by cb_events(), handle_response_invite(), and misdn_facility_ie_handler().
09606 { 09607 unsigned char data[1024]; /* This should be large enough */ 09608 size_t datalen; 09609 09610 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update); 09611 if (datalen == (size_t) -1) { 09612 return; 09613 } 09614 09615 ast_queue_control_data(chan, AST_CONTROL_REDIRECTING, data, datalen); 09616 }
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 5313 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().
05314 { 05315 switch (reason) /* the following appear to be the only ones actually returned by request_and_dial */ 05316 { 05317 case 0: 05318 return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)"; 05319 case AST_CONTROL_HANGUP: 05320 return "Hangup"; 05321 case AST_CONTROL_RING: 05322 return "Local Ring"; 05323 case AST_CONTROL_RINGING: 05324 return "Remote end Ringing"; 05325 case AST_CONTROL_ANSWER: 05326 return "Remote end has Answered"; 05327 case AST_CONTROL_BUSY: 05328 return "Remote end is Busy"; 05329 case AST_CONTROL_CONGESTION: 05330 return "Congestion (circuits busy)"; 05331 default: 05332 return "Unknown Reason!!"; 05333 } 05334 }
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.
Whenever we want to update a channel's redirecting information, we may need to run a macro so that an administrator can manipulate the information before sending it out. This function both runs the macro and sends the update to the channel.
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 |
Have multiple return codes based on the MACRO_RESULT
Make constants so that caller and frame can be more expressive than just '1' and '0'
Definition at line 9663 of file channel.c.
References ast_app_run_macro(), ast_channel_lock, ast_channel_unlock, ast_channel_update_redirecting(), ast_party_redirecting_copy(), ast_party_redirecting_free(), ast_party_redirecting_init(), ast_redirecting_parse_data(), ast_strdupa, ast_strlen_zero(), ast_frame::data, ast_frame::datalen, pbx_builtin_getvar_helper(), ast_frame::ptr, ast_channel::redirecting, and S_OR.
Referenced by ast_bridge_call(), ast_generic_bridge(), call_forward_inherit(), do_forward(), feature_request_and_dial(), handle_frame(), local_bridge_loop(), remote_bridge_loop(), and wait_for_answer().
09664 { 09665 const char *macro; 09666 const char *macro_args; 09667 int retval; 09668 09669 ast_channel_lock(macro_chan); 09670 macro = pbx_builtin_getvar_helper(macro_chan, is_caller 09671 ? "REDIRECTING_CALLER_SEND_MACRO" : "REDIRECTING_CALLEE_SEND_MACRO"); 09672 macro = ast_strdupa(S_OR(macro, "")); 09673 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller 09674 ? "REDIRECTING_CALLER_SEND_MACRO_ARGS" : "REDIRECTING_CALLEE_SEND_MACRO_ARGS"); 09675 macro_args = ast_strdupa(S_OR(macro_args, "")); 09676 09677 if (ast_strlen_zero(macro)) { 09678 ast_channel_unlock(macro_chan); 09679 return -1; 09680 } 09681 09682 if (is_frame) { 09683 const struct ast_frame *frame = redirecting_info; 09684 09685 ast_redirecting_parse_data(frame->data.ptr, frame->datalen, ¯o_chan->redirecting); 09686 } else { 09687 const struct ast_party_redirecting *redirecting = redirecting_info; 09688 09689 ast_party_redirecting_copy(¯o_chan->redirecting, redirecting); 09690 } 09691 ast_channel_unlock(macro_chan); 09692 09693 retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args); 09694 if (!retval) { 09695 struct ast_party_redirecting saved_redirecting; 09696 09697 ast_party_redirecting_init(&saved_redirecting); 09698 ast_channel_lock(macro_chan); 09699 ast_party_redirecting_copy(&saved_redirecting, ¯o_chan->redirecting); 09700 ast_channel_unlock(macro_chan); 09701 ast_channel_update_redirecting(macro_chan, &saved_redirecting, NULL); 09702 ast_party_redirecting_free(&saved_redirecting); 09703 } 09704 09705 return retval; 09706 }
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 907 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, ast_channel_tech::description, LOG_WARNING, chanlist::tech, and ast_channel_tech::type.
Referenced by load_module(), and unload_module().
00908 { 00909 struct chanlist *chan; 00910 00911 AST_RWLIST_WRLOCK(&backends); 00912 00913 AST_RWLIST_TRAVERSE(&backends, chan, list) { 00914 if (!strcasecmp(tech->type, chan->tech->type)) { 00915 ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type); 00916 AST_RWLIST_UNLOCK(&backends); 00917 return -1; 00918 } 00919 } 00920 00921 if (!(chan = ast_calloc(1, sizeof(*chan)))) { 00922 AST_RWLIST_UNLOCK(&backends); 00923 return -1; 00924 } 00925 chan->tech = tech; 00926 AST_RWLIST_INSERT_HEAD(&backends, chan, list); 00927 00928 ast_debug(1, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description); 00929 00930 ast_verb(2, "Registered channel type '%s' (%s)\n", chan->tech->type, chan->tech->description); 00931 00932 AST_RWLIST_UNLOCK(&backends); 00933 00934 return 0; 00935 }
struct ast_channel* ast_channel_release | ( | struct ast_channel * | chan | ) | [read] |
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 1921 of file channel.c.
References ao2_unlink, ast_channel_unref, and channels.
Referenced by agent_cleanup(), ast_iax2_new(), ast_request(), bridge_request(), do_notify(), gtalk_newcall(), local_new(), and local_request().
01922 { 01923 /* Safe, even if already unlinked. */ 01924 ao2_unlink(channels, chan); 01925 return ast_channel_unref(chan); 01926 }
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 5907 of file channel.c.
References ast_channel_tech::send_html, and ast_channel::tech.
Referenced by agent_sendhtml(), ast_channel_sendurl(), and wait_for_answer().
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 5914 of file channel.c.
References ast_channel_sendhtml(), and AST_HTML_URL.
Referenced by dial_exec_full(), sendurl_exec(), and try_calling().
05915 { 05916 return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1); 05917 }
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 7079 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_party_caller_set(), and ast_channel::caller.
07080 { 07081 if (&chan->caller == caller) { 07082 /* Don't set to self */ 07083 return; 07084 } 07085 07086 ast_channel_lock(chan); 07087 ast_party_caller_set(&chan->caller, caller, update); 07088 ast_channel_unlock(chan); 07089 }
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 7091 of file channel.c.
References ast_cdr_setcid(), ast_channel_lock, ast_channel_unlock, ast_party_caller_set(), ast_channel::caller, ast_channel::cdr, ast_party_caller::id, ast_party_id::name, ast_party_id::number, report_new_callerid(), S_COR, ast_party_name::str, ast_party_number::str, ast_party_name::valid, and ast_party_number::valid.
Referenced by callerid_write(), dial_exec_full(), do_forward(), misdn_update_caller_id(), and ring_entry().
07092 { 07093 const char *pre_set_number; 07094 const char *pre_set_name; 07095 07096 if (&chan->caller == caller) { 07097 /* Don't set to self */ 07098 return; 07099 } 07100 07101 ast_channel_lock(chan); 07102 pre_set_number = 07103 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL); 07104 pre_set_name = S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL); 07105 ast_party_caller_set(&chan->caller, caller, update); 07106 if (S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL) 07107 != pre_set_number 07108 || S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL) 07109 != pre_set_name) { 07110 /* The caller id name or number changed. */ 07111 report_new_callerid(chan); 07112 } 07113 if (chan->cdr) { 07114 ast_cdr_setcid(chan->cdr, chan); 07115 } 07116 ast_channel_unlock(chan); 07117 }
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 8458 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_party_connected_line_set(), and ast_channel::connected.
Referenced by __ast_request_and_dial(), ast_indicate_data(), connectedline_write(), dial_exec_full(), and feature_request_and_dial().
08459 { 08460 if (&chan->connected == connected) { 08461 /* Don't set to self */ 08462 return; 08463 } 08464 08465 ast_channel_lock(chan); 08466 ast_party_connected_line_set(&chan->connected, connected, update); 08467 ast_channel_unlock(chan); 08468 }
void ast_channel_set_fd | ( | struct ast_channel * | chan, | |
int | which, | |||
int | fd | |||
) |
Set the file descriptor on the channel
Definition at line 2631 of file channel.c.
References ast_calloc, ast_epoll_data::chan, ast_channel::fds, free, and ast_epoll_data::which.
Referenced by __ast_channel_alloc_ap(), __oh323_new(), __oh323_rtp_create(), __oh323_update_info(), alsa_new(), ast_do_masquerade(), dahdi_new(), deactivate_generator_nolock(), gtalk_new(), initialize_udptl(), jingle_new(), mgcp_new(), misdn_new(), my_swap_subchannels(), nbs_new(), oss_new(), phone_new(), process_sdp(), setformat(), sip_new(), sip_set_rtp_peer(), skinny_new(), start_rtp(), and swap_subs().
02632 { 02633 #ifdef HAVE_EPOLL 02634 struct epoll_event ev; 02635 struct ast_epoll_data *aed = NULL; 02636 02637 if (chan->fds[which] > -1) { 02638 epoll_ctl(chan->epfd, EPOLL_CTL_DEL, chan->fds[which], &ev); 02639 aed = chan->epfd_data[which]; 02640 } 02641 02642 /* If this new fd is valid, add it to the epoll */ 02643 if (fd > -1) { 02644 if (!aed && (!(aed = ast_calloc(1, sizeof(*aed))))) 02645 return; 02646 02647 chan->epfd_data[which] = aed; 02648 aed->chan = chan; 02649 aed->which = which; 02650 02651 ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP; 02652 ev.data.ptr = aed; 02653 epoll_ctl(chan->epfd, EPOLL_CTL_ADD, fd, &ev); 02654 } else if (aed) { 02655 /* We don't have to keep around this epoll data structure now */ 02656 free(aed); 02657 chan->epfd_data[which] = NULL; 02658 } 02659 #endif 02660 chan->fds[which] = fd; 02661 return; 02662 }
void ast_channel_set_linkgroup | ( | struct ast_channel * | chan, | |
struct ast_channel * | peer | |||
) |
propagate the linked id between chan and peer
Definition at line 6387 of file channel.c.
References ast_channel::_bridge, ast_bridged_channel(), ast_channel_change_linkedid(), ast_strdupa, and oldest_linkedid().
Referenced by ast_bridge_call(), and ast_do_masquerade().
06388 { 06389 const char* linkedid=NULL; 06390 struct ast_channel *bridged; 06391 06392 linkedid = oldest_linkedid(chan->linkedid, peer->linkedid); 06393 linkedid = oldest_linkedid(linkedid, chan->uniqueid); 06394 linkedid = oldest_linkedid(linkedid, peer->uniqueid); 06395 if (chan->_bridge) { 06396 bridged = ast_bridged_channel(chan); 06397 if (bridged && bridged != peer) { 06398 linkedid = oldest_linkedid(linkedid, bridged->linkedid); 06399 linkedid = oldest_linkedid(linkedid, bridged->uniqueid); 06400 } 06401 } 06402 if (peer->_bridge) { 06403 bridged = ast_bridged_channel(peer); 06404 if (bridged && bridged != chan) { 06405 linkedid = oldest_linkedid(linkedid, bridged->linkedid); 06406 linkedid = oldest_linkedid(linkedid, bridged->uniqueid); 06407 } 06408 } 06409 06410 /* just in case setting a stringfield to itself causes problems */ 06411 linkedid = ast_strdupa(linkedid); 06412 06413 ast_channel_change_linkedid(chan, linkedid); 06414 ast_channel_change_linkedid(peer, linkedid); 06415 if (chan->_bridge) { 06416 bridged = ast_bridged_channel(chan); 06417 if (bridged && bridged != peer) { 06418 ast_channel_change_linkedid(bridged, linkedid); 06419 } 06420 } 06421 if (peer->_bridge) { 06422 bridged = ast_bridged_channel(peer); 06423 if (bridged && bridged != chan) { 06424 ast_channel_change_linkedid(bridged, linkedid); 06425 } 06426 } 06427 }
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 9111 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_party_redirecting_set(), and ast_channel::redirecting.
Referenced by ast_indicate_data(), handle_request_invite(), handle_response(), misdn_copy_redirecting_to_ast(), and redirecting_write().
09112 { 09113 if (&chan->redirecting == redirecting) { 09114 /* Don't set to self */ 09115 return; 09116 } 09117 09118 ast_channel_lock(chan); 09119 ast_party_redirecting_set(&chan->redirecting, redirecting, update); 09120 ast_channel_unlock(chan); 09121 }
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 |
Set an option on a channel (see frame.h), optionally blocking awaiting the reply
Definition at line 7795 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_log(), errno, LOG_ERROR, ast_channel_tech::setoption, and ast_channel::tech.
Referenced by analog_hangup(), ast_bridge_call(), ast_channel_make_compatible_helper(), common_exec(), conf_run(), dahdi_hangup(), dial_exec_full(), func_channel_write(), func_channel_write_real(), handle_tddmode(), play_record_review(), rcvfax_exec(), reset_volumes(), set_format(), set_listen_volume(), set_security_requirements(), set_talk_volume(), sndfax_exec(), try_calling(), and vm_forwardoptions().
07796 { 07797 int res; 07798 07799 ast_channel_lock(chan); 07800 if (!chan->tech->setoption) { 07801 errno = ENOSYS; 07802 ast_channel_unlock(chan); 07803 return -1; 07804 } 07805 07806 if (block) 07807 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 07808 07809 res = chan->tech->setoption(chan, option, data, datalen); 07810 ast_channel_unlock(chan); 07811 07812 return res; 07813 }
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 |
This function sets the absolute time out on a channel (when to hang up).
Definition at line 878 of file channel.c.
References ast_channel_setwhentohangup_tv().
00879 { 00880 struct timeval when = { offset, }; 00881 ast_channel_setwhentohangup_tv(chan, when); 00882 }
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 |
This function sets the absolute time out on a channel (when to hang up).
Definition at line 871 of file channel.c.
References ast_null_frame, ast_queue_frame(), ast_tvadd(), ast_tvnow(), ast_tvzero(), and ast_channel::whentohangup.
Referenced by action_timeout(), ast_channel_setwhentohangup(), handle_autohangup(), and timeout_write().
00872 { 00873 chan->whentohangup = ast_tvzero(offset) ? offset : ast_tvadd(offset, ast_tvnow()); 00874 ast_queue_frame(chan, &ast_null_frame); 00875 return; 00876 }
struct ast_silence_generator* ast_channel_start_silence_generator | ( | struct ast_channel * | chan | ) | [read] |
Starts a silence generator on the given channel.
chan | The channel to generate silence on |
This function will cause SLINEAR silence to be generated on the supplied channel until it is disabled; if the channel cannot be put into SLINEAR mode then the function will fail.
Definition at line 8309 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_silence_generator::old_write_format, and ast_channel::writeformat.
Referenced by __ast_play_and_record(), ast_bridge_call(), ast_dtmf_stream(), ast_readstring_full(), ast_safe_sleep_conditional(), channel_spy(), record_exec(), TransferCallStep1(), waitfor_exec(), and waitforring_exec().
08310 { 08311 struct ast_silence_generator *state; 08312 08313 if (!(state = ast_calloc(1, sizeof(*state)))) { 08314 return NULL; 08315 } 08316 08317 state->old_write_format = chan->writeformat; 08318 08319 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) { 08320 ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n"); 08321 ast_free(state); 08322 return NULL; 08323 } 08324 08325 ast_activate_generator(chan, &silence_generator, state); 08326 08327 ast_debug(1, "Started silence generator on '%s'\n", chan->name); 08328 08329 return state; 08330 }
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. |
This function will stop the operating silence generator and return the channel to its previous write format.
Definition at line 8355 of file channel.c.
References ast_debug, ast_free, ast_log(), ast_set_write_format(), deactivate_silence_generator(), LOG_ERROR, and ast_silence_generator::old_write_format.
Referenced by __ast_play_and_record(), ast_bridge_call(), ast_dtmf_stream(), ast_readstring_full(), ast_safe_sleep_conditional(), channel_spy(), HandleCallOutgoing(), key_dial_page(), record_exec(), unistim_hangup(), waitfor_exec(), and waitforring_exec().
08356 { 08357 if (!state) { 08358 return; 08359 } 08360 08361 if (deactivate_silence_generator(chan)) { 08362 ast_debug(1, "Stopped silence generator on '%s'\n", chan->name); 08363 08364 if (ast_set_write_format(chan, state->old_write_format) < 0) 08365 ast_log(LOG_ERROR, "Could not return write format to its original state\n"); 08366 } 08367 ast_free(state); 08368 }
int ast_channel_supports_html | ( | struct ast_channel * | channel | ) |
Checks for HTML support on a channel.
Definition at line 5902 of file channel.c.
References ast_channel_tech::send_html, and ast_channel::tech.
Referenced by dial_exec_full(), sendurl_exec(), and try_calling().
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 A - Transferee Party B - Transferer Party C - Target of transfer
Party B transfers A to C.
Party A is connected to bridged channel B1. Party B is connected to channels C1 and C2. Party C is connected to bridged channel B2.
Party B -- C1 == B1 -- Party A __/ / Party B -- C2 == B2 -- Party C
Bridged channel B1 is masqueraded into channel C2. Where B1 is the masquerade clone channel and C2 is the masquerade original channel.
0 | on success. | |
-1 | on error. |
Definition at line 6184 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_held, xfer_masquerade_ds::target_id, xfer_masquerade_ds::transferee_held, and xfer_masquerade_ds::transferee_id.
Referenced by analog_attempt_transfer(), and misdn_attempt_transfer().
06191 { 06192 struct ast_datastore *xfer_ds; 06193 struct xfer_masquerade_ds *xfer_colp; 06194 int res; 06195 06196 xfer_ds = ast_datastore_alloc(&xfer_ds_info, NULL); 06197 if (!xfer_ds) { 06198 return -1; 06199 } 06200 06201 xfer_colp = ast_calloc(1, sizeof(*xfer_colp)); 06202 if (!xfer_colp) { 06203 ast_datastore_free(xfer_ds); 06204 return -1; 06205 } 06206 party_connected_line_copy_transfer(&xfer_colp->target_id, target_id); 06207 xfer_colp->target_held = target_held; 06208 party_connected_line_copy_transfer(&xfer_colp->transferee_id, transferee_id); 06209 xfer_colp->transferee_held = transferee_held; 06210 xfer_ds->data = xfer_colp; 06211 06212 res = __ast_channel_masquerade(target_chan, transferee_chan, xfer_ds); 06213 if (res) { 06214 ast_datastore_free(xfer_ds); 06215 } 06216 return res; 06217 }
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 1628 of file channel.c.
References ast_clear_flag, and AST_FLAG_DEFER_DTMF.
Referenced by __adsi_transmit_messages(), and find_cache().
01629 { 01630 if (chan) 01631 ast_clear_flag(chan, AST_FLAG_DEFER_DTMF); 01632 }
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 938 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::tech, and ast_channel_tech::type.
Referenced by __unload_module(), load_module(), and unload_module().
00939 { 00940 struct chanlist *chan; 00941 00942 ast_debug(1, "Unregistering channel type '%s'\n", tech->type); 00943 00944 AST_RWLIST_WRLOCK(&backends); 00945 00946 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) { 00947 if (chan->tech == tech) { 00948 AST_LIST_REMOVE_CURRENT(list); 00949 ast_free(chan); 00950 ast_verb(2, "Unregistered channel type '%s'\n", tech->type); 00951 break; 00952 } 00953 } 00954 AST_LIST_TRAVERSE_SAFE_END; 00955 00956 AST_RWLIST_UNLOCK(&backends); 00957 }
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 9085 of file channel.c.
References ast_connected_line_build_data(), AST_CONTROL_CONNECTED_LINE, and ast_indicate_data().
Referenced by app_exec(), ast_channel_connected_line_macro(), ast_do_pickup(), atxfer_fail_cleanup(), builtin_atxfer(), connectedline_write(), parked_call_exec(), and wait_for_answer().
09086 { 09087 unsigned char data[1024]; /* This should be large enough */ 09088 size_t datalen; 09089 09090 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update); 09091 if (datalen == (size_t) -1) { 09092 return; 09093 } 09094 09095 ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen); 09096 }
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 9592 of file channel.c.
References AST_CONTROL_REDIRECTING, ast_indicate_data(), and ast_redirecting_build_data().
Referenced by ast_channel_redirecting_macro(), call_forward_inherit(), do_forward(), redirecting_write(), and wait_for_answer().
09593 { 09594 unsigned char data[1024]; /* This should be large enough */ 09595 size_t datalen; 09596 09597 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update); 09598 if (datalen == (size_t) -1) { 09599 return; 09600 } 09601 09602 ast_indicate_data(chan, AST_CONTROL_REDIRECTING, data, datalen); 09603 }
struct ast_variable* ast_channeltype_list | ( | void | ) | [read] |
return an ast_variable list of channeltypes
Definition at line 261 of file channel.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_variable_new(), ast_channel_tech::description, chanlist::tech, ast_channel_tech::type, and var.
Referenced by ast_var_channel_types(), and ast_var_channel_types_table().
00262 { 00263 struct chanlist *cl; 00264 struct ast_variable *var = NULL, *prev = NULL; 00265 00266 AST_RWLIST_RDLOCK(&backends); 00267 AST_RWLIST_TRAVERSE(&backends, cl, list) { 00268 if (prev) { 00269 if ((prev->next = ast_variable_new(cl->tech->type, cl->tech->description, ""))) 00270 prev = prev->next; 00271 } else { 00272 var = ast_variable_new(cl->tech->type, cl->tech->description, ""); 00273 prev = var; 00274 } 00275 } 00276 AST_RWLIST_UNLOCK(&backends); 00277 00278 return var; 00279 }
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 806 of file channel.c.
References ast_channel::_softhangup, ast_debug, AST_SOFTHANGUP_TIMEOUT, ast_test_suite_event_notify, ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), and ast_channel::whentohangup.
Referenced by __ast_pbx_run(), __ast_read(), _macro_exec(), agent_indicate(), agi_exec(), agi_handle_command(), announce_thread(), ast_bridge_call(), ast_call(), ast_channel_bridge(), ast_check_hangup_locked(), ast_indicate_data(), ast_raw_answer(), ast_readstring_full(), ast_recvtext(), ast_rtp_instance_bridge(), ast_sendtext(), ast_transfer(), ast_udptl_bridge(), ast_waitfordigit_full(), ast_write(), autoservice_run(), bridge_call_thread(), bridge_exec(), builtin_atxfer(), call_forward_inherit(), channel_spy(), check_bridge(), common_exec(), conf_play(), conf_run(), dahdi_sendtext(), dahdi_setoption(), dial_exec_full(), dundi_lookup_internal(), eagi_exec(), eivr_comm(), feature_request_and_dial(), findmeexec(), func_channel_read(), gosub_run(), handle_sendimage(), iax2_bridge(), launch_asyncagi(), local_bridge_loop(), local_fixup(), login_exec(), lua_check_hangup(), ospfinished_exec(), pbx_builtin_incomplete(), pbx_builtin_waitexten(), pbx_exec(), read_exec(), readexten_exec(), remote_bridge_loop(), run_agi(), run_ras(), try_calling(), and wait_for_answer().
00807 { 00808 if (chan->_softhangup) /* yes if soft hangup flag set */ 00809 return 1; 00810 if (ast_tvzero(chan->whentohangup)) /* no if no hangup scheduled */ 00811 return 0; 00812 if (ast_tvdiff_ms(chan->whentohangup, ast_tvnow()) > 0) /* no if hangup time has not come yet. */ 00813 return 0; 00814 ast_debug(4, "Hangup time has come: %" PRIi64 "\n", ast_tvdiff_ms(chan->whentohangup, ast_tvnow())); 00815 ast_test_suite_event_notify("HANGUP_TIME", "Channel: %s", chan->name); 00816 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT; /* record event */ 00817 return 1; 00818 }
int ast_check_hangup_locked | ( | struct ast_channel * | chan | ) |
Definition at line 820 of file channel.c.
References ast_channel_lock, ast_channel_unlock, and ast_check_hangup().
Referenced by action_redirect(), and ast_channel_bridge().
00821 { 00822 int res; 00823 ast_channel_lock(chan); 00824 res = ast_check_hangup(chan); 00825 ast_channel_unlock(chan); 00826 return res; 00827 }
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 8825 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(), ast_set_party_connected_line::id, ast_party_connected_line::id, LOG_WARNING, ast_party_id_ies::name, party_id_build_data(), ast_party_connected_line::source, ast_party_name_ies::str, and value.
Referenced by ast_channel_queue_connected_line_update(), ast_channel_update_connected_line(), local_attended_transfer(), local_indicate(), and masquerade_colp_transfer().
08826 { 08827 int32_t value; 08828 size_t pos = 0; 08829 int res; 08830 08831 static const struct ast_party_id_ies ies = { 08832 .name.str = AST_CONNECTED_LINE_NAME, 08833 .name.char_set = AST_CONNECTED_LINE_NAME_CHAR_SET, 08834 .name.presentation = AST_CONNECTED_LINE_NAME_PRESENTATION, 08835 .name.valid = AST_CONNECTED_LINE_NAME_VALID, 08836 08837 .number.str = AST_CONNECTED_LINE_NUMBER, 08838 .number.plan = AST_CONNECTED_LINE_NUMBER_PLAN, 08839 .number.presentation = AST_CONNECTED_LINE_NUMBER_PRESENTATION, 08840 .number.valid = AST_CONNECTED_LINE_NUMBER_VALID, 08841 08842 .subaddress.str = AST_CONNECTED_LINE_SUBADDRESS, 08843 .subaddress.type = AST_CONNECTED_LINE_SUBADDRESS_TYPE, 08844 .subaddress.odd_even_indicator = AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN, 08845 .subaddress.valid = AST_CONNECTED_LINE_SUBADDRESS_VALID, 08846 08847 .tag = AST_CONNECTED_LINE_TAG, 08848 .combined_presentation = AST_CONNECTED_LINE_ID_PRESENTATION, 08849 }; 08850 08851 /* 08852 * The size of integer values must be fixed in case the frame is 08853 * shipped to another machine. 08854 */ 08855 08856 /* Connected line frame version */ 08857 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08858 ast_log(LOG_WARNING, "No space left for connected line frame version\n"); 08859 return -1; 08860 } 08861 data[pos++] = AST_CONNECTED_LINE_VERSION; 08862 data[pos++] = 1; 08863 data[pos++] = 2;/* Version 1 did not have a version ie */ 08864 08865 res = party_id_build_data(data + pos, datalen - pos, &connected->id, 08866 "connected line", &ies, update ? &update->id : NULL); 08867 if (res < 0) { 08868 return -1; 08869 } 08870 pos += res; 08871 08872 /* Connected line source */ 08873 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) { 08874 ast_log(LOG_WARNING, "No space left for connected line source\n"); 08875 return -1; 08876 } 08877 data[pos++] = AST_CONNECTED_LINE_SOURCE; 08878 data[pos++] = sizeof(value); 08879 value = htonl(connected->source); 08880 memcpy(data + pos, &value, sizeof(value)); 08881 pos += sizeof(value); 08882 08883 return pos; 08884 }
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 8443 of file channel.c.
References ast_party_caller::ani, ast_party_connected_line::ani, ast_party_caller::ani2, ast_party_connected_line::ani2, ast_party_id_copy(), ast_party_caller::id, and ast_party_connected_line::id.
Referenced by app_exec(), ast_do_pickup(), begin_dial_channel(), builtin_atxfer(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), local_call(), parked_call_exec(), ring_entry(), and wait_for_answer().
08444 { 08445 ast_party_id_copy(&dest->id, &src->id); 08446 ast_party_id_copy(&dest->ani, &src->ani); 08447 dest->ani2 = src->ani2; 08448 }
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 8450 of file channel.c.
References ast_party_connected_line::ani, ast_party_caller::ani, ast_party_connected_line::ani2, ast_party_caller::ani2, ast_party_id_copy(), ast_party_connected_line::id, and ast_party_caller::id.
Referenced by local_call(), and local_indicate().
08451 { 08452 ast_party_id_copy(&dest->id, &src->id); 08453 ast_party_id_copy(&dest->ani, &src->ani); 08454 08455 dest->ani2 = src->ani2; 08456 }
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. |
Definition at line 8886 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_name::char_set, ast_party_id_ies::combined_presentation, ast_party_connected_line::id, LOG_DEBUG, LOG_WARNING, ast_party_id::name, ast_party_id::number, ast_party_subaddress::odd_even_indicator, ast_party_number::plan, ast_party_number::presentation, ast_party_name::presentation, ast_party_connected_line::source, ast_party_subaddress::str, ast_party_number::str, ast_party_name::str, ast_party_id::subaddress, ast_party_id::tag, ast_party_subaddress::type, ast_party_subaddress::valid, ast_party_number::valid, ast_party_name::valid, and value.
Referenced by __ast_read(), ast_channel_connected_line_macro(), ast_indicate_data(), feature_request_and_dial(), socket_process(), wait_for_answer(), and wait_for_winner().
08887 { 08888 size_t pos; 08889 unsigned char ie_len; 08890 unsigned char ie_id; 08891 int32_t value; 08892 int frame_version = 1; 08893 int combined_presentation = 0; 08894 int got_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */ 08895 08896 for (pos = 0; pos < datalen; pos += ie_len) { 08897 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) { 08898 ast_log(LOG_WARNING, "Invalid connected line update\n"); 08899 return -1; 08900 } 08901 ie_id = data[pos++]; 08902 ie_len = data[pos++]; 08903 if (datalen < pos + ie_len) { 08904 ast_log(LOG_WARNING, "Invalid connected line update\n"); 08905 return -1; 08906 } 08907 08908 switch (ie_id) { 08909 /* Connected line party frame version */ 08910 case AST_CONNECTED_LINE_VERSION: 08911 if (ie_len != 1) { 08912 ast_log(LOG_WARNING, "Invalid connected line frame version (%u)\n", 08913 (unsigned) ie_len); 08914 break; 08915 } 08916 frame_version = data[pos]; 08917 break; 08918 /* Connected line party id name */ 08919 case AST_CONNECTED_LINE_NAME: 08920 ast_free(connected->id.name.str); 08921 connected->id.name.str = ast_malloc(ie_len + 1); 08922 if (connected->id.name.str) { 08923 memcpy(connected->id.name.str, data + pos, ie_len); 08924 connected->id.name.str[ie_len] = 0; 08925 } 08926 break; 08927 case AST_CONNECTED_LINE_NAME_CHAR_SET: 08928 if (ie_len != 1) { 08929 ast_log(LOG_WARNING, "Invalid connected line name char set (%u)\n", 08930 (unsigned) ie_len); 08931 break; 08932 } 08933 connected->id.name.char_set = data[pos]; 08934 break; 08935 case AST_CONNECTED_LINE_NAME_PRESENTATION: 08936 if (ie_len != 1) { 08937 ast_log(LOG_WARNING, "Invalid connected line name presentation (%u)\n", 08938 (unsigned) ie_len); 08939 break; 08940 } 08941 connected->id.name.presentation = data[pos]; 08942 break; 08943 case AST_CONNECTED_LINE_NAME_VALID: 08944 if (ie_len != 1) { 08945 ast_log(LOG_WARNING, "Invalid connected line name valid (%u)\n", 08946 (unsigned) ie_len); 08947 break; 08948 } 08949 connected->id.name.valid = data[pos]; 08950 break; 08951 /* Connected line party id number */ 08952 case AST_CONNECTED_LINE_NUMBER: 08953 ast_free(connected->id.number.str); 08954 connected->id.number.str = ast_malloc(ie_len + 1); 08955 if (connected->id.number.str) { 08956 memcpy(connected->id.number.str, data + pos, ie_len); 08957 connected->id.number.str[ie_len] = 0; 08958 } 08959 break; 08960 case AST_CONNECTED_LINE_NUMBER_PLAN: 08961 if (ie_len != 1) { 08962 ast_log(LOG_WARNING, "Invalid connected line numbering plan (%u)\n", 08963 (unsigned) ie_len); 08964 break; 08965 } 08966 connected->id.number.plan = data[pos]; 08967 break; 08968 case AST_CONNECTED_LINE_NUMBER_PRESENTATION: 08969 if (ie_len != 1) { 08970 ast_log(LOG_WARNING, "Invalid connected line number presentation (%u)\n", 08971 (unsigned) ie_len); 08972 break; 08973 } 08974 connected->id.number.presentation = data[pos]; 08975 break; 08976 case AST_CONNECTED_LINE_NUMBER_VALID: 08977 if (ie_len != 1) { 08978 ast_log(LOG_WARNING, "Invalid connected line number valid (%u)\n", 08979 (unsigned) ie_len); 08980 break; 08981 } 08982 connected->id.number.valid = data[pos]; 08983 break; 08984 /* Connected line party id combined presentation */ 08985 case AST_CONNECTED_LINE_ID_PRESENTATION: 08986 if (ie_len != 1) { 08987 ast_log(LOG_WARNING, "Invalid connected line combined presentation (%u)\n", 08988 (unsigned) ie_len); 08989 break; 08990 } 08991 combined_presentation = data[pos]; 08992 got_combined_presentation = 1; 08993 break; 08994 /* Connected line party id subaddress */ 08995 case AST_CONNECTED_LINE_SUBADDRESS: 08996 ast_free(connected->id.subaddress.str); 08997 connected->id.subaddress.str = ast_malloc(ie_len + 1); 08998 if (connected->id.subaddress.str) { 08999 memcpy(connected->id.subaddress.str, data + pos, ie_len); 09000 connected->id.subaddress.str[ie_len] = 0; 09001 } 09002 break; 09003 case AST_CONNECTED_LINE_SUBADDRESS_TYPE: 09004 if (ie_len != 1) { 09005 ast_log(LOG_WARNING, "Invalid connected line type of subaddress (%u)\n", 09006 (unsigned) ie_len); 09007 break; 09008 } 09009 connected->id.subaddress.type = data[pos]; 09010 break; 09011 case AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN: 09012 if (ie_len != 1) { 09013 ast_log(LOG_WARNING, 09014 "Invalid connected line subaddress odd-even indicator (%u)\n", 09015 (unsigned) ie_len); 09016 break; 09017 } 09018 connected->id.subaddress.odd_even_indicator = data[pos]; 09019 break; 09020 case AST_CONNECTED_LINE_SUBADDRESS_VALID: 09021 if (ie_len != 1) { 09022 ast_log(LOG_WARNING, "Invalid connected line subaddress valid (%u)\n", 09023 (unsigned) ie_len); 09024 break; 09025 } 09026 connected->id.subaddress.valid = data[pos]; 09027 break; 09028 /* Connected line party tag */ 09029 case AST_CONNECTED_LINE_TAG: 09030 ast_free(connected->id.tag); 09031 connected->id.tag = ast_malloc(ie_len + 1); 09032 if (connected->id.tag) { 09033 memcpy(connected->id.tag, data + pos, ie_len); 09034 connected->id.tag[ie_len] = 0; 09035 } 09036 break; 09037 /* Connected line party source */ 09038 case AST_CONNECTED_LINE_SOURCE: 09039 if (ie_len != sizeof(value)) { 09040 ast_log(LOG_WARNING, "Invalid connected line source (%u)\n", 09041 (unsigned) ie_len); 09042 break; 09043 } 09044 memcpy(&value, data + pos, sizeof(value)); 09045 connected->source = ntohl(value); 09046 break; 09047 /* Connected line party unknown element */ 09048 default: 09049 ast_log(LOG_DEBUG, "Unknown connected line element: %u (%u)\n", 09050 (unsigned) ie_id, (unsigned) ie_len); 09051 break; 09052 } 09053 } 09054 09055 switch (frame_version) { 09056 case 1: 09057 /* 09058 * The other end is an earlier version that we need to adjust 09059 * for compatibility. 09060 */ 09061 connected->id.name.valid = 1; 09062 connected->id.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1; 09063 connected->id.number.valid = 1; 09064 if (got_combined_presentation) { 09065 connected->id.name.presentation = combined_presentation; 09066 connected->id.number.presentation = combined_presentation; 09067 } 09068 break; 09069 case 2: 09070 /* The other end is at the same level as we are. */ 09071 break; 09072 default: 09073 /* 09074 * The other end is newer than we are. 09075 * We need to assume that they are compatible with us. 09076 */ 09077 ast_log(LOG_DEBUG, "Connected line frame has newer version: %u\n", 09078 (unsigned) frame_version); 09079 break; 09080 } 09081 09082 return 0; 09083 }
void ast_deactivate_generator | ( | struct ast_channel * | chan | ) |
Deactivate an active generator
Definition at line 3107 of file channel.c.
References ast_channel_lock, ast_channel_unlock, and deactivate_generator_nolock().
Referenced by __ast_read(), app_exec(), 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().
03108 { 03109 ast_channel_lock(chan); 03110 deactivate_generator_nolock(chan); 03111 ast_channel_unlock(chan); 03112 }
int ast_do_masquerade | ( | struct ast_channel * | original | ) |
Start masquerading a channel.
XXX This is a seriously whacked out operation. We're essentially putting the guts of the clone channel into the original channel. Start by killing off the original channel's backend. I'm not sure we're going to keep this function, because while the features are nice, the cost is very high in terms of pure nastiness. XXX
chan | Channel to masquerade |
Start masquerading a channel.
< TRUE if the clonechan was a zombie before the masquerade.
Definition at line 6546 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_bridge_end_dtmf(), ast_bridged_channel(), ast_cause2str(), AST_CEL_BRIDGE_UPDATE, ast_cel_report_event(), ast_channel_datastore_find(), ast_channel_datastore_remove(), ast_channel_lock, ast_channel_lock_both, AST_CHANNEL_NAME, ast_channel_ref, ast_channel_set_fd(), ast_channel_set_linkgroup(), ast_channel_unlock, ast_channel_unref, ast_clear_flag, AST_CONTROL_SRCCHANGE, AST_CONTROL_UNHOLD, ast_copy_string(), ast_datastore_free(), ast_debug, AST_FLAG_BLOCKING, AST_FLAG_DISABLE_DEVSTATE_CACHE, AST_FLAG_EXCEPTION, AST_FLAG_MOH, AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, AST_GENERATOR_FD, ast_getformatname(), ast_indicate(), ast_kill_tech, AST_LIST_APPEND_LIST, AST_LIST_FIRST, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_HEAD_NOLOCK, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), ast_manager_event, ast_manager_event_multichan, AST_MAX_FDS, ast_moh_start(), ast_null_frame, ast_queue_frame(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_SOFTHANGUP_DEV, ast_state2str(), ast_string_field_set, ast_test_flag, AST_TIMING_FD, ast_channel::blocker, ast_channel::caller, ast_channel::cdr, ast_datastore_info::chan_fixup, channels, clone_variables(), ast_channel::connected, ast_datastore::data, ast_channel::dialed, errno, EVENT_FLAG_CALL, ast_channel::fdno, ast_channel::fds, ast_channel_tech::fixup, free_translation(), ast_channel_tech::hangup, ast_channel::hangupcause, ast_datastore::info, language, LOG_WARNING, ast_channel::masq, ast_channel::masqr, masquerade_colp_transfer(), ast_channel::monitor, musicclass, ast_channel::nativeformats, parkinglot, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::redirecting, report_new_callerid(), S_OR, ast_channel::sending_dtmf_digit, ast_channel::sending_dtmf_tv, ast_channel::tech, ast_channel::tech_pvt, ast_channel::timingfd, xfer_masquerade_ds::transferee_held, ast_channel_tech::type, ast_cdr::uniqueid, ast_channel::visible_indication, ast_channel::whentohangup, and ast_channel::writeformat.
Referenced by __ast_read(), ast_async_goto(), ast_do_pickup(), ast_hangup(), ast_waitfor_nandfds(), ast_write(), builtin_atxfer(), check_bridge(), check_goto_on_transfer(), do_bridge_masquerade(), handle_invite_replaces(), iax_park(), local_attended_transfer(), masq_park_call(), and sip_park().
06547 { 06548 int x; 06549 int i; 06550 int origstate; 06551 unsigned int orig_disablestatecache; 06552 unsigned int clone_disablestatecache; 06553 int visible_indication; 06554 int moh_is_playing; 06555 int clone_was_zombie = 0;/*!< TRUE if the clonechan was a zombie before the masquerade. */ 06556 struct ast_frame *current; 06557 const struct ast_channel_tech *t; 06558 void *t_pvt; 06559 union { 06560 struct ast_party_dialed dialed; 06561 struct ast_party_caller caller; 06562 struct ast_party_connected_line connected; 06563 struct ast_party_redirecting redirecting; 06564 } exchange; 06565 struct ast_channel *clonechan, *chans[2]; 06566 struct ast_channel *bridged; 06567 struct ast_cdr *cdr; 06568 struct ast_datastore *xfer_ds; 06569 struct xfer_masquerade_ds *xfer_colp; 06570 format_t rformat; 06571 format_t wformat; 06572 format_t tmp_format; 06573 char newn[AST_CHANNEL_NAME]; 06574 char orig[AST_CHANNEL_NAME]; 06575 char masqn[AST_CHANNEL_NAME]; 06576 char zombn[AST_CHANNEL_NAME]; 06577 char clone_sending_dtmf_digit; 06578 struct timeval clone_sending_dtmf_tv; 06579 06580 /* XXX This operation is a bit odd. We're essentially putting the guts of 06581 * the clone channel into the original channel. Start by killing off the 06582 * original channel's backend. While the features are nice, which is the 06583 * reason we're keeping it, it's still awesomely weird. XXX */ 06584 06585 /* 06586 * The reasoning for the channels ao2_container lock here is 06587 * complex. 06588 * 06589 * There is a race condition that exists for this function. 06590 * Since all pvt and channel locks must be let go before calling 06591 * ast_do_masquerade, it is possible that it could be called 06592 * multiple times for the same channel. In order to prevent the 06593 * race condition with competing threads to do the masquerade 06594 * and new masquerade attempts, the channels container must be 06595 * locked for the entire masquerade. The original and clonechan 06596 * need to be unlocked earlier to avoid potential deadlocks with 06597 * the chan_local deadlock avoidance method. 06598 * 06599 * The container lock blocks competing masquerade attempts from 06600 * starting as well as being necessary for proper locking order 06601 * because the channels must to be unlinked to change their 06602 * names. 06603 * 06604 * The original and clonechan locks must be held while the 06605 * channel contents are shuffled around for the masquerade. 06606 * 06607 * The masq and masqr pointers need to be left alone until the 06608 * masquerade has restabilized the channels to prevent another 06609 * masquerade request until the AST_FLAG_ZOMBIE can be set on 06610 * the clonechan. 06611 */ 06612 ao2_lock(channels); 06613 06614 /* 06615 * Lock the original channel to determine if the masquerade is 06616 * still required. 06617 */ 06618 ast_channel_lock(original); 06619 06620 clonechan = original->masq; 06621 if (!clonechan) { 06622 /* 06623 * The masq is already completed by another thread or never 06624 * needed to be done to begin with. 06625 */ 06626 ast_channel_unlock(original); 06627 ao2_unlock(channels); 06628 return 0; 06629 } 06630 06631 /* Bump the refs to ensure that they won't dissapear on us. */ 06632 ast_channel_ref(original); 06633 ast_channel_ref(clonechan); 06634 06635 /* unlink from channels container as name (which is the hash value) will change */ 06636 ao2_unlink(channels, original); 06637 ao2_unlink(channels, clonechan); 06638 06639 /* Get any transfer masquerade connected line exchange data. */ 06640 xfer_ds = ast_channel_datastore_find(original, &xfer_ds_info, NULL); 06641 if (xfer_ds) { 06642 ast_channel_datastore_remove(original, xfer_ds); 06643 xfer_colp = xfer_ds->data; 06644 } else { 06645 xfer_colp = NULL; 06646 } 06647 06648 moh_is_playing = ast_test_flag(original, AST_FLAG_MOH); 06649 06650 /* 06651 * Stop any visible indication on the original channel so we can 06652 * transfer it to the clonechan taking the original's place. 06653 */ 06654 visible_indication = original->visible_indication; 06655 ast_channel_unlock(original); 06656 ast_indicate(original, -1); 06657 06658 /* 06659 * Release any hold on the transferee channel before going any 06660 * further with the masquerade. 06661 */ 06662 if (xfer_colp && xfer_colp->transferee_held) { 06663 ast_indicate(clonechan, AST_CONTROL_UNHOLD); 06664 } 06665 06666 /* Start the masquerade channel contents rearangement. */ 06667 ast_channel_lock_both(original, clonechan); 06668 06669 ast_debug(4, "Actually Masquerading %s(%u) into the structure of %s(%u)\n", 06670 clonechan->name, clonechan->_state, original->name, original->_state); 06671 06672 chans[0] = clonechan; 06673 chans[1] = original; 06674 ast_manager_event_multichan(EVENT_FLAG_CALL, "Masquerade", 2, chans, 06675 "Clone: %s\r\n" 06676 "CloneState: %s\r\n" 06677 "Original: %s\r\n" 06678 "OriginalState: %s\r\n", 06679 clonechan->name, ast_state2str(clonechan->_state), original->name, ast_state2str(original->_state)); 06680 06681 /* 06682 * Remember the original read/write formats. We turn off any 06683 * translation on either one 06684 */ 06685 rformat = original->readformat; 06686 wformat = original->writeformat; 06687 free_translation(clonechan); 06688 free_translation(original); 06689 06690 /* Save the current DTMF digit being sent if any. */ 06691 clone_sending_dtmf_digit = clonechan->sending_dtmf_digit; 06692 clone_sending_dtmf_tv = clonechan->sending_dtmf_tv; 06693 06694 /* Save the original name */ 06695 ast_copy_string(orig, original->name, sizeof(orig)); 06696 /* Save the new name */ 06697 ast_copy_string(newn, clonechan->name, sizeof(newn)); 06698 /* Create the masq name */ 06699 snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn); 06700 06701 /* Mangle the name of the clone channel */ 06702 __ast_change_name_nolink(clonechan, masqn); 06703 06704 /* Copy the name from the clone channel */ 06705 __ast_change_name_nolink(original, newn); 06706 06707 /* share linked id's */ 06708 ast_channel_set_linkgroup(original, clonechan); 06709 06710 /* Swap the technologies */ 06711 t = original->tech; 06712 original->tech = clonechan->tech; 06713 clonechan->tech = t; 06714 06715 t_pvt = original->tech_pvt; 06716 original->tech_pvt = clonechan->tech_pvt; 06717 clonechan->tech_pvt = t_pvt; 06718 06719 /* Swap the cdrs */ 06720 cdr = original->cdr; 06721 /* swap cdr uniqueid between channels, to get cdr uniqueid = channel uniqueid */ 06722 ast_copy_string(clonechan->cdr->uniqueid, cdr->uniqueid, sizeof(cdr->uniqueid)); 06723 original->cdr = clonechan->cdr; 06724 clonechan->cdr = cdr; 06725 06726 /* Swap the alertpipes */ 06727 for (i = 0; i < 2; i++) { 06728 x = original->alertpipe[i]; 06729 original->alertpipe[i] = clonechan->alertpipe[i]; 06730 clonechan->alertpipe[i] = x; 06731 } 06732 06733 /* 06734 * Swap the readq's. The end result should be this: 06735 * 06736 * 1) All frames should be on the new (original) channel. 06737 * 2) Any frames that were already on the new channel before this 06738 * masquerade need to be at the end of the readq, after all of the 06739 * frames on the old (clone) channel. 06740 * 3) The alertpipe needs to get poked for every frame that was already 06741 * on the new channel, since we are now using the alert pipe from the 06742 * old (clone) channel. 06743 */ 06744 { 06745 AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq; 06746 06747 AST_LIST_HEAD_INIT_NOLOCK(&tmp_readq); 06748 AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list); 06749 AST_LIST_APPEND_LIST(&original->readq, &clonechan->readq, frame_list); 06750 06751 while ((current = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) { 06752 AST_LIST_INSERT_TAIL(&original->readq, current, frame_list); 06753 if (original->alertpipe[1] > -1) { 06754 int poke = 0; 06755 06756 if (write(original->alertpipe[1], &poke, sizeof(poke)) < 0) { 06757 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 06758 } 06759 } 06760 } 06761 } 06762 06763 /* Swap the raw formats */ 06764 tmp_format = original->rawreadformat; 06765 original->rawreadformat = clonechan->rawreadformat; 06766 clonechan->rawreadformat = tmp_format; 06767 06768 tmp_format = original->rawwriteformat; 06769 original->rawwriteformat = clonechan->rawwriteformat; 06770 clonechan->rawwriteformat = tmp_format; 06771 06772 clonechan->_softhangup = AST_SOFTHANGUP_DEV; 06773 06774 /* And of course, so does our current state. Note we need not 06775 call ast_setstate since the event manager doesn't really consider 06776 these separate. We do this early so that the clone has the proper 06777 state of the original channel. */ 06778 origstate = original->_state; 06779 original->_state = clonechan->_state; 06780 clonechan->_state = origstate; 06781 06782 /* And the swap the cachable state too. Otherwise we'd start caching 06783 * Local channels and ignoring real ones. */ 06784 orig_disablestatecache = ast_test_flag(original, AST_FLAG_DISABLE_DEVSTATE_CACHE); 06785 clone_disablestatecache = ast_test_flag(clonechan, AST_FLAG_DISABLE_DEVSTATE_CACHE); 06786 if (orig_disablestatecache != clone_disablestatecache) { 06787 if (orig_disablestatecache) { 06788 ast_clear_flag(original, AST_FLAG_DISABLE_DEVSTATE_CACHE); 06789 ast_set_flag(clonechan, AST_FLAG_DISABLE_DEVSTATE_CACHE); 06790 } else { 06791 ast_set_flag(original, AST_FLAG_DISABLE_DEVSTATE_CACHE); 06792 ast_clear_flag(clonechan, AST_FLAG_DISABLE_DEVSTATE_CACHE); 06793 } 06794 } 06795 06796 /* Mangle the name of the clone channel */ 06797 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig); /* quick, hide the brains! */ 06798 __ast_change_name_nolink(clonechan, zombn); 06799 06800 /* Update the type. */ 06801 t_pvt = original->monitor; 06802 original->monitor = clonechan->monitor; 06803 clonechan->monitor = t_pvt; 06804 06805 /* Keep the same language. */ 06806 ast_string_field_set(original, language, clonechan->language); 06807 06808 /* Keep the same parkinglot. */ 06809 ast_string_field_set(original, parkinglot, clonechan->parkinglot); 06810 06811 /* Copy the FD's other than the generator fd */ 06812 for (x = 0; x < AST_MAX_FDS; x++) { 06813 if (x != AST_GENERATOR_FD) 06814 ast_channel_set_fd(original, x, clonechan->fds[x]); 06815 } 06816 06817 ast_app_group_update(clonechan, original); 06818 06819 /* Move data stores over */ 06820 if (AST_LIST_FIRST(&clonechan->datastores)) { 06821 struct ast_datastore *ds; 06822 /* We use a safe traversal here because some fixup routines actually 06823 * remove the datastore from the list and free them. 06824 */ 06825 AST_LIST_TRAVERSE_SAFE_BEGIN(&clonechan->datastores, ds, entry) { 06826 if (ds->info->chan_fixup) 06827 ds->info->chan_fixup(ds->data, clonechan, original); 06828 } 06829 AST_LIST_TRAVERSE_SAFE_END; 06830 AST_LIST_APPEND_LIST(&original->datastores, &clonechan->datastores, entry); 06831 } 06832 06833 ast_autochan_new_channel(clonechan, original); 06834 06835 clone_variables(original, clonechan); 06836 /* Presense of ADSI capable CPE follows clone */ 06837 original->adsicpe = clonechan->adsicpe; 06838 /* Bridge remains the same */ 06839 /* CDR fields remain the same */ 06840 /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */ 06841 /* Application and data remain the same */ 06842 /* Clone exception becomes real one, as with fdno */ 06843 ast_set_flag(original, ast_test_flag(clonechan, AST_FLAG_EXCEPTION | AST_FLAG_OUTGOING)); 06844 original->fdno = clonechan->fdno; 06845 /* Schedule context remains the same */ 06846 /* Stream stuff stays the same */ 06847 /* Keep the original state. The fixup code will need to work with it most likely */ 06848 06849 /* 06850 * Just swap the whole structures, nevermind the allocations, 06851 * they'll work themselves out. 06852 */ 06853 exchange.dialed = original->dialed; 06854 original->dialed = clonechan->dialed; 06855 clonechan->dialed = exchange.dialed; 06856 06857 exchange.caller = original->caller; 06858 original->caller = clonechan->caller; 06859 clonechan->caller = exchange.caller; 06860 06861 exchange.connected = original->connected; 06862 original->connected = clonechan->connected; 06863 clonechan->connected = exchange.connected; 06864 06865 exchange.redirecting = original->redirecting; 06866 original->redirecting = clonechan->redirecting; 06867 clonechan->redirecting = exchange.redirecting; 06868 06869 report_new_callerid(original); 06870 06871 /* Restore original timing file descriptor */ 06872 ast_channel_set_fd(original, AST_TIMING_FD, original->timingfd); 06873 06874 /* Our native formats are different now */ 06875 original->nativeformats = clonechan->nativeformats; 06876 06877 /* Context, extension, priority, app data, jump table, remain the same */ 06878 /* pvt switches. pbx stays the same, as does next */ 06879 06880 /* Set the write format */ 06881 ast_set_write_format(original, wformat); 06882 06883 /* Set the read format */ 06884 ast_set_read_format(original, rformat); 06885 06886 /* Copy the music class */ 06887 ast_string_field_set(original, musicclass, clonechan->musicclass); 06888 06889 /* Copy whentohangup time */ 06890 original->whentohangup = clonechan->whentohangup; 06891 06892 /* copy over accuntcode and set peeraccount across the bridge */ 06893 ast_string_field_set(original, accountcode, S_OR(clonechan->accountcode, "")); 06894 if (original->_bridge) { 06895 /* XXX - should we try to lock original->_bridge here? */ 06896 ast_string_field_set(original->_bridge, peeraccount, S_OR(clonechan->accountcode, "")); 06897 ast_cel_report_event(original, AST_CEL_BRIDGE_UPDATE, NULL, NULL, NULL); 06898 } 06899 06900 ast_debug(1, "Putting channel %s in %s/%s formats\n", original->name, 06901 ast_getformatname(wformat), ast_getformatname(rformat)); 06902 06903 /* Fixup the original clonechan's physical side */ 06904 if (original->tech->fixup && original->tech->fixup(clonechan, original)) { 06905 ast_log(LOG_WARNING, "Channel type '%s' could not fixup channel %s, strange things may happen. (clonechan)\n", 06906 original->tech->type, original->name); 06907 } 06908 06909 /* Fixup the original original's physical side */ 06910 if (clonechan->tech->fixup && clonechan->tech->fixup(original, clonechan)) { 06911 ast_log(LOG_WARNING, "Channel type '%s' could not fixup channel %s, strange things may happen. (original)\n", 06912 clonechan->tech->type, clonechan->name); 06913 } 06914 06915 /* 06916 * Now, at this point, the "clone" channel is totally F'd up. 06917 * We mark it as a zombie so nothing tries to touch it. If it's 06918 * already been marked as a zombie, then we must free it (since 06919 * it already is considered invalid). 06920 * 06921 * This must be done before we unlock clonechan to prevent 06922 * setting up another masquerade on the clonechan. 06923 */ 06924 if (ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) { 06925 clone_was_zombie = 1; 06926 } else { 06927 ast_set_flag(clonechan, AST_FLAG_ZOMBIE); 06928 ast_queue_frame(clonechan, &ast_null_frame); 06929 } 06930 06931 /* clear the masquerade channels */ 06932 original->masq = NULL; 06933 clonechan->masqr = NULL; 06934 06935 /* 06936 * When we unlock original here, it can be immediately setup to 06937 * masquerade again or hungup. The new masquerade or hangup 06938 * will not actually happen until we release the channels 06939 * container lock. 06940 */ 06941 ast_channel_unlock(original); 06942 06943 /* Disconnect the original original's physical side */ 06944 if (clonechan->tech->hangup && clonechan->tech->hangup(clonechan)) { 06945 ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n"); 06946 } else { 06947 /* 06948 * We just hung up the original original's physical side of the 06949 * channel. Set the new zombie to use the kill channel driver 06950 * for safety. 06951 */ 06952 clonechan->tech = &ast_kill_tech; 06953 } 06954 06955 ast_channel_unlock(clonechan); 06956 06957 if (clone_sending_dtmf_digit) { 06958 /* 06959 * The clonechan was sending a DTMF digit that was not completed 06960 * before the masquerade. 06961 */ 06962 ast_bridge_end_dtmf(original, clone_sending_dtmf_digit, clone_sending_dtmf_tv, 06963 "masquerade"); 06964 } 06965 06966 /* 06967 * If an indication is currently playing, maintain it on the 06968 * channel that is taking the place of original. 06969 * 06970 * This is needed because the masquerade is swapping out the 06971 * internals of the channel, and the new channel private data 06972 * needs to be made aware of the current visible indication 06973 * (RINGING, CONGESTION, etc.) 06974 */ 06975 if (visible_indication) { 06976 ast_indicate(original, visible_indication); 06977 } 06978 06979 /* if moh is playing on the original channel then it needs to be 06980 maintained on the channel that is replacing it. */ 06981 if (moh_is_playing) { 06982 ast_moh_start(original, NULL, NULL); 06983 } 06984 06985 ast_channel_lock(original); 06986 06987 /* Signal any blocker */ 06988 if (ast_test_flag(original, AST_FLAG_BLOCKING)) { 06989 pthread_kill(original->blocker, SIGURG); 06990 } 06991 06992 ast_debug(1, "Done Masquerading %s (%u)\n", original->name, original->_state); 06993 06994 if ((bridged = ast_bridged_channel(original))) { 06995 ast_channel_ref(bridged); 06996 ast_channel_unlock(original); 06997 ast_indicate(bridged, AST_CONTROL_SRCCHANGE); 06998 ast_channel_unref(bridged); 06999 } else { 07000 ast_channel_unlock(original); 07001 } 07002 ast_indicate(original, AST_CONTROL_SRCCHANGE); 07003 07004 if (xfer_colp) { 07005 /* 07006 * After the masquerade, the original channel pointer actually 07007 * points to the new transferee channel and the bridged channel 07008 * is still the intended transfer target party. 07009 */ 07010 masquerade_colp_transfer(original, xfer_colp); 07011 } 07012 07013 if (xfer_ds) { 07014 ast_datastore_free(xfer_ds); 07015 } 07016 07017 if (clone_was_zombie) { 07018 ast_channel_lock(clonechan); 07019 ast_debug(1, "Destroying channel clone '%s'\n", clonechan->name); 07020 ast_manager_event(clonechan, EVENT_FLAG_CALL, "Hangup", 07021 "Channel: %s\r\n" 07022 "Uniqueid: %s\r\n" 07023 "Cause: %d\r\n" 07024 "Cause-txt: %s\r\n", 07025 clonechan->name, 07026 clonechan->uniqueid, 07027 clonechan->hangupcause, 07028 ast_cause2str(clonechan->hangupcause) 07029 ); 07030 ast_channel_unlock(clonechan); 07031 07032 /* 07033 * Drop the system reference to destroy the channel since it is 07034 * already unlinked. 07035 */ 07036 ast_channel_unref(clonechan); 07037 } else { 07038 ao2_link(channels, clonechan); 07039 } 07040 07041 ao2_link(channels, original); 07042 ao2_unlock(channels); 07043 07044 /* Release our held safety references. */ 07045 ast_channel_unref(original); 07046 ast_channel_unref(clonechan); 07047 07048 return 0; 07049 }
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 2398 of file channel.h.
References dummy().
Referenced by do_monitor().
02399 { 02400 int x; 02401 int dummy = 0; 02402 02403 if (fd < 0) 02404 return 0; 02405 if (!start) 02406 start = &dummy; 02407 for (x = *start; x < maximum; x++) 02408 if (pfds[x].fd == fd) { 02409 if (x == *start) 02410 (*start)++; 02411 return pfds[x].revents; 02412 } 02413 return 0; 02414 }
struct ast_channel_tech* ast_get_channel_tech | ( | const char * | name | ) | [read] |
Get a channel technology structure by name.
name | name of technology to find |
Definition at line 960 of file channel.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, 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().
00961 { 00962 struct chanlist *chanls; 00963 const struct ast_channel_tech *ret = NULL; 00964 00965 AST_RWLIST_RDLOCK(&backends); 00966 00967 AST_RWLIST_TRAVERSE(&backends, chanls, list) { 00968 if (!strcasecmp(name, chanls->tech->type)) { 00969 ret = chanls->tech; 00970 break; 00971 } 00972 } 00973 00974 AST_RWLIST_UNLOCK(&backends); 00975 00976 return ret; 00977 }
ast_group_t ast_get_group | ( | const char * | s | ) |
Definition at line 7987 of file channel.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), LOG_ERROR, and LOG_WARNING.
Referenced by _parse(), build_device(), build_gateway(), build_peer(), config_parse_variables(), func_channel_write_real(), process_dahdi(), and read_agent_config().
07988 { 07989 char *piece; 07990 char *c; 07991 int start=0, finish=0, x; 07992 ast_group_t group = 0; 07993 07994 if (ast_strlen_zero(s)) 07995 return 0; 07996 07997 c = ast_strdupa(s); 07998 07999 while ((piece = strsep(&c, ","))) { 08000 if (sscanf(piece, "%30d-%30d", &start, &finish) == 2) { 08001 /* Range */ 08002 } else if (sscanf(piece, "%30d", &start)) { 08003 /* Just one */ 08004 finish = start; 08005 } else { 08006 ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece); 08007 continue; 08008 } 08009 for (x = start; x <= finish; x++) { 08010 if ((x > 63) || (x < 0)) { 08011 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x); 08012 } else 08013 group |= ((ast_group_t) 1 << x); 08014 } 08015 } 08016 return group; 08017 }
int ast_hangup | ( | struct ast_channel * | chan | ) |
Hang up a channel.
chan | channel to hang up |
Definition at line 2804 of file channel.c.
References ao2_unlink, ast_assert, ast_autoservice_stop(), ast_cause2str(), ast_cc_offer(), ast_cdr_detach(), ast_cdr_end(), AST_CDR_FLAG_BRIDGED, AST_CDR_FLAG_DIALED, AST_CDR_FLAG_POST_DISABLED, AST_CDR_NULL, AST_CEL_HANGUP, ast_cel_report_event(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_closestream(), ast_debug, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_log(), ast_manager_event, ast_set_flag, ast_test_flag, ast_channel::blocker, ast_channel::blockproc, ast_channel::caller, ast_channel::cdr, channels, ast_channel::connected, destroy_hooks(), ast_cdr::disposition, EVENT_FLAG_CALL, free_translation(), ast_channel::generator, ast_channel::generatordata, ast_channel_tech::hangup, ast_channel::hangupcause, ast_party_connected_line::id, ast_party_caller::id, LOG_WARNING, ast_channel::masq, ast_channel::masqr, 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_name::str, ast_party_number::str, ast_channel::stream, ast_channel::tech, ast_party_name::valid, ast_party_number::valid, and ast_channel::vstream.
Referenced by __analog_handle_event(), __analog_ss_thread(), __ast_pbx_run(), __ast_request_and_dial(), __oh323_new(), action_bridge(), agent_request(), alsa_new(), analog_handle_init_event(), analog_ss_thread(), answer_exec_run(), app_exec(), ast_async_goto(), ast_call_forward(), ast_dial_destroy(), ast_dial_hangup(), ast_iax2_new(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pbx_run_app(), async_wait(), begin_dial_channel(), bridge_call_thread(), bridge_call_thread_launch(), bridge_channel_thread(), bridge_exec(), build_conf(), builtin_atxfer(), chanavail_exec(), check_availability(), check_compat(), check_goto_on_transfer(), clear_caller(), conf_free(), conf_run(), console_new(), dahdi_handle_event(), dahdi_new(), destroy_conference_bridge(), dial_exec_full(), dial_transfer(), do_forward(), do_hang(), do_monitor(), feature_attended_transfer(), feature_request_and_dial(), findmeexec(), generic_recall(), gtalk_new(), handle_call_forward(), handle_callforward_button(), handle_enbloc_call_message(), handle_frame(), handle_frame_ownerless(), handle_hd_hf(), handle_init_event(), handle_invite_replaces(), handle_offhook_message(), handle_request_invite(), handle_soft_key_event_message(), handle_stimulus_message(), handle_timeout_trip(), handle_transfer_button(), HandleCallOutgoing(), hangup_chan(), hangupcalls(), hanguptree(), iax2_request(), iax_park(), iax_park_thread(), jingle_new(), local_hangup(), manage_parked_call(), masq_park_call(), meetme_menu_admin_extended(), mgcp_new(), mgcp_ss(), monitor_dial(), mwi_thread(), my_distinctive_ring(), my_handle_notify_message(), nbs_new(), oss_new(), parkandannounce_exec(), parked_call_exec(), phone_new(), play_sound_file(), sip_park(), sip_park_thread(), sip_pickup_thread(), skinny_new(), skinny_ss(), try_calling(), unistim_new(), wait_for_answer(), and wait_for_winner().
02805 { 02806 char extra_str[64]; /* used for cel logging below */ 02807 int was_zombie; 02808 02809 ast_autoservice_stop(chan); 02810 02811 ast_channel_lock(chan); 02812 02813 /* 02814 * Do the masquerade if someone is setup to masquerade into us. 02815 * 02816 * NOTE: We must hold the channel lock after testing for a 02817 * pending masquerade and setting the channel as a zombie to 02818 * prevent __ast_channel_masquerade() from setting up a 02819 * masquerade with a dead channel. 02820 */ 02821 while (chan->masq) { 02822 ast_channel_unlock(chan); 02823 ast_do_masquerade(chan); 02824 ast_channel_lock(chan); 02825 } 02826 02827 if (chan->masqr) { 02828 /* 02829 * This channel is one which will be masqueraded into something. 02830 * Mark it as a zombie already so ast_do_masquerade() will know 02831 * to free it later. 02832 */ 02833 ast_set_flag(chan, AST_FLAG_ZOMBIE); 02834 destroy_hooks(chan); 02835 ast_channel_unlock(chan); 02836 return 0; 02837 } 02838 02839 /* Mark as a zombie so a masquerade cannot be setup on this channel. */ 02840 if (!(was_zombie = ast_test_flag(chan, AST_FLAG_ZOMBIE))) { 02841 ast_set_flag(chan, AST_FLAG_ZOMBIE); 02842 } 02843 02844 ast_channel_unlock(chan); 02845 ao2_unlink(channels, chan); 02846 ast_channel_lock(chan); 02847 02848 destroy_hooks(chan); 02849 02850 free_translation(chan); 02851 /* Close audio stream */ 02852 if (chan->stream) { 02853 ast_closestream(chan->stream); 02854 chan->stream = NULL; 02855 } 02856 /* Close video stream */ 02857 if (chan->vstream) { 02858 ast_closestream(chan->vstream); 02859 chan->vstream = NULL; 02860 } 02861 if (chan->sched) { 02862 sched_context_destroy(chan->sched); 02863 chan->sched = NULL; 02864 } 02865 02866 if (chan->generatordata) { /* Clear any tone stuff remaining */ 02867 if (chan->generator && chan->generator->release) { 02868 chan->generator->release(chan, chan->generatordata); 02869 } 02870 } 02871 chan->generatordata = NULL; 02872 chan->generator = NULL; 02873 02874 snprintf(extra_str, sizeof(extra_str), "%d,%s,%s", chan->hangupcause, chan->hangupsource, S_OR(pbx_builtin_getvar_helper(chan, "DIALSTATUS"), "")); 02875 ast_cel_report_event(chan, AST_CEL_HANGUP, NULL, extra_str, NULL); 02876 02877 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) { 02878 ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd " 02879 "is blocked by thread %ld in procedure %s! Expect a failure\n", 02880 (long) pthread_self(), chan->name, (long)chan->blocker, chan->blockproc); 02881 ast_assert(ast_test_flag(chan, AST_FLAG_BLOCKING) == 0); 02882 } 02883 if (!was_zombie) { 02884 ast_debug(1, "Hanging up channel '%s'\n", chan->name); 02885 02886 if (chan->tech->hangup) { 02887 chan->tech->hangup(chan); 02888 } 02889 } else { 02890 ast_debug(1, "Hanging up zombie '%s'\n", chan->name); 02891 } 02892 02893 ast_channel_unlock(chan); 02894 02895 ast_cc_offer(chan); 02896 ast_manager_event(chan, EVENT_FLAG_CALL, "Hangup", 02897 "Channel: %s\r\n" 02898 "Uniqueid: %s\r\n" 02899 "CallerIDNum: %s\r\n" 02900 "CallerIDName: %s\r\n" 02901 "ConnectedLineNum: %s\r\n" 02902 "ConnectedLineName: %s\r\n" 02903 "Cause: %d\r\n" 02904 "Cause-txt: %s\r\n", 02905 chan->name, 02906 chan->uniqueid, 02907 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "<unknown>"), 02908 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, "<unknown>"), 02909 S_COR(chan->connected.id.number.valid, chan->connected.id.number.str, "<unknown>"), 02910 S_COR(chan->connected.id.name.valid, chan->connected.id.name.str, "<unknown>"), 02911 chan->hangupcause, 02912 ast_cause2str(chan->hangupcause) 02913 ); 02914 02915 if (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_BRIDGED) && 02916 !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED) && 02917 (chan->cdr->disposition != AST_CDR_NULL || ast_test_flag(chan->cdr, AST_CDR_FLAG_DIALED))) { 02918 ast_channel_lock(chan); 02919 ast_cdr_end(chan->cdr); 02920 ast_cdr_detach(chan->cdr); 02921 chan->cdr = NULL; 02922 ast_channel_unlock(chan); 02923 } 02924 02925 ast_channel_unref(chan); 02926 02927 return 0; 02928 }
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 4393 of file channel.c.
References ast_indicate_data().
Referenced by __ast_play_and_record(), agent_request(), alsa_call(), answer_trunk_chan(), ast_bridge_call(), ast_channel_bridge(), ast_do_masquerade(), ast_dtmf_stream(), ast_raw_answer(), attempt_transfer(), builtin_atxfer(), builtin_blindtransfer(), cli_console_answer(), conf_run(), console_call(), dial_exec_full(), dial_trunk(), disa_exec(), do_forward(), feature_request_and_dial(), finishup(), handle_callforward_button(), handle_frame(), handle_recordfile(), handle_request_refer(), local_attended_transfer(), manage_parked_call(), mgcp_ss(), monitor_dial(), oss_call(), park_call_full(), parked_call_exec(), pbx_builtin_busy(), pbx_builtin_congestion(), pbx_builtin_incomplete(), pbx_builtin_proceeding(), pbx_builtin_progress(), pbx_builtin_ringing(), pbx_builtin_waitexten(), queue_exec(), record_exec(), rna(), say_periodic_announcement(), say_position(), send_waveform_to_channel(), skinny_ss(), sla_handle_hold_event(), sla_station_exec(), sla_trunk_exec(), try_calling(), and wait_for_answer().
04394 { 04395 return ast_indicate_data(chan, condition, NULL, 0); 04396 }
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 4447 of file channel.c.
References ast_channel::_state, _XXX_AST_CONTROL_T38, ast_channel_lock, ast_channel_set_connected_line(), ast_channel_set_redirecting(), ast_channel_unlock, ast_check_hangup(), ast_connected_line_parse_data(), AST_CONTROL_ANSWER, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CC, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_END_OF_Q, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_READ_ACTION, AST_CONTROL_REDIRECTING, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_TRANSFER, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_CONTROL_VIDUPDATE, AST_CONTROL_WINK, ast_debug, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, ast_framehook_list_is_empty(), ast_framehook_list_write_event(), ast_frdup(), ast_frfree, ast_get_indication_tone(), ast_log(), ast_party_connected_line_free(), ast_party_connected_line_set_init(), ast_party_redirecting_free(), ast_party_redirecting_set_init(), ast_playtones_start(), ast_playtones_stop(), ast_redirecting_parse_data(), AST_STATE_UP, ast_test_flag, ast_tone_zone_sound_unref(), ast_channel::connected, ast_tone_zone_sound::data, ast_frame::data, ast_frame::datalen, ast_channel::framehooks, ast_frame::frametype, ast_channel_tech::indicate, ast_frame_subclass::integer, is_visible_indication(), LOG_WARNING, ast_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_generic_bridge(), ast_handle_cc_control_frame(), ast_indicate(), disable_t38(), feature_request_and_dial(), generic_fax_exec(), handle_frame(), local_bridge_loop(), login_exec(), manage_parked_call(), park_call_full(), pbx_builtin_waitexten(), receivefax_t38_init(), remote_bridge_loop(), sendfax_t38_init(), set_fax_t38_caps(), transmit_audio(), transmit_t38(), and wait_for_answer().
04449 { 04450 /* By using an enum, we'll get compiler warnings for values not handled 04451 * in switch statements. */ 04452 enum ast_control_frame_type condition = _condition; 04453 struct ast_tone_zone_sound *ts = NULL; 04454 int res; 04455 /* this frame is used by framehooks. if it is set, we must free it at the end of this function */ 04456 struct ast_frame *awesome_frame = NULL; 04457 04458 ast_channel_lock(chan); 04459 04460 /* Don't bother if the channel is about to go away, anyway. */ 04461 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 04462 res = -1; 04463 goto indicate_cleanup; 04464 } 04465 04466 if (!ast_framehook_list_is_empty(chan->framehooks)) { 04467 /* Do framehooks now, do it, go, go now */ 04468 struct ast_frame frame = { 04469 .frametype = AST_FRAME_CONTROL, 04470 .subclass.integer = condition, 04471 .data.ptr = (void *) data, /* this cast from const is only okay because we do the ast_frdup below */ 04472 .datalen = datalen 04473 }; 04474 04475 /* we have now committed to freeing this frame */ 04476 awesome_frame = ast_frdup(&frame); 04477 04478 /* who knows what we will get back! the anticipation is killing me. */ 04479 if (!(awesome_frame = ast_framehook_list_write_event(chan->framehooks, awesome_frame)) 04480 || awesome_frame->frametype != AST_FRAME_CONTROL) { 04481 04482 res = 0; 04483 goto indicate_cleanup; 04484 } 04485 04486 condition = awesome_frame->subclass.integer; 04487 data = awesome_frame->data.ptr; 04488 datalen = awesome_frame->datalen; 04489 } 04490 04491 switch (condition) { 04492 case AST_CONTROL_CONNECTED_LINE: 04493 { 04494 struct ast_party_connected_line connected; 04495 04496 ast_party_connected_line_set_init(&connected, &chan->connected); 04497 res = ast_connected_line_parse_data(data, datalen, &connected); 04498 if (!res) { 04499 ast_channel_set_connected_line(chan, &connected, NULL); 04500 } 04501 ast_party_connected_line_free(&connected); 04502 } 04503 break; 04504 04505 case AST_CONTROL_REDIRECTING: 04506 { 04507 struct ast_party_redirecting redirecting; 04508 04509 ast_party_redirecting_set_init(&redirecting, &chan->redirecting); 04510 res = ast_redirecting_parse_data(data, datalen, &redirecting); 04511 if (!res) { 04512 ast_channel_set_redirecting(chan, &redirecting, NULL); 04513 } 04514 ast_party_redirecting_free(&redirecting); 04515 } 04516 break; 04517 04518 default: 04519 break; 04520 } 04521 04522 if (is_visible_indication(condition)) { 04523 /* A new visible indication is requested. */ 04524 chan->visible_indication = condition; 04525 } else if (condition == AST_CONTROL_UNHOLD || _condition < 0) { 04526 /* Visible indication is cleared/stopped. */ 04527 chan->visible_indication = 0; 04528 } 04529 04530 if (chan->tech->indicate) { 04531 /* See if the channel driver can handle this condition. */ 04532 res = chan->tech->indicate(chan, condition, data, datalen); 04533 } else { 04534 res = -1; 04535 } 04536 04537 if (!res) { 04538 /* The channel driver successfully handled this indication */ 04539 res = 0; 04540 goto indicate_cleanup; 04541 } 04542 04543 /* The channel driver does not support this indication, let's fake 04544 * it by doing our own tone generation if applicable. */ 04545 04546 /*!\note If we compare the enumeration type, which does not have any 04547 * negative constants, the compiler may optimize this code away. 04548 * Therefore, we must perform an integer comparison here. */ 04549 if (_condition < 0) { 04550 /* Stop any tones that are playing */ 04551 ast_playtones_stop(chan); 04552 res = 0; 04553 goto indicate_cleanup; 04554 } 04555 04556 /* Handle conditions that we have tones for. */ 04557 switch (condition) { 04558 case _XXX_AST_CONTROL_T38: 04559 /* deprecated T.38 control frame */ 04560 res = -1; 04561 goto indicate_cleanup; 04562 case AST_CONTROL_T38_PARAMETERS: 04563 /* there is no way to provide 'default' behavior for these 04564 * control frames, so we need to return failure, but there 04565 * is also no value in the log message below being emitted 04566 * since failure to handle these frames is not an 'error' 04567 * so just return right now. in addition, we want to return 04568 * whatever value the channel driver returned, in case it 04569 * has some meaning.*/ 04570 goto indicate_cleanup; 04571 case AST_CONTROL_RINGING: 04572 ts = ast_get_indication_tone(chan->zone, "ring"); 04573 /* It is common practice for channel drivers to return -1 if trying 04574 * to indicate ringing on a channel which is up. The idea is to let the 04575 * core generate the ringing inband. However, we don't want the 04576 * warning message about not being able to handle the specific indication 04577 * to print nor do we want ast_indicate_data to return an "error" for this 04578 * condition 04579 */ 04580 if (chan->_state == AST_STATE_UP) { 04581 res = 0; 04582 } 04583 break; 04584 case AST_CONTROL_BUSY: 04585 ts = ast_get_indication_tone(chan->zone, "busy"); 04586 break; 04587 case AST_CONTROL_INCOMPLETE: 04588 case AST_CONTROL_CONGESTION: 04589 ts = ast_get_indication_tone(chan->zone, "congestion"); 04590 break; 04591 case AST_CONTROL_PROGRESS: 04592 case AST_CONTROL_PROCEEDING: 04593 case AST_CONTROL_VIDUPDATE: 04594 case AST_CONTROL_SRCUPDATE: 04595 case AST_CONTROL_SRCCHANGE: 04596 case AST_CONTROL_RADIO_KEY: 04597 case AST_CONTROL_RADIO_UNKEY: 04598 case AST_CONTROL_OPTION: 04599 case AST_CONTROL_WINK: 04600 case AST_CONTROL_FLASH: 04601 case AST_CONTROL_OFFHOOK: 04602 case AST_CONTROL_TAKEOFFHOOK: 04603 case AST_CONTROL_ANSWER: 04604 case AST_CONTROL_HANGUP: 04605 case AST_CONTROL_RING: 04606 case AST_CONTROL_HOLD: 04607 case AST_CONTROL_UNHOLD: 04608 case AST_CONTROL_TRANSFER: 04609 case AST_CONTROL_CONNECTED_LINE: 04610 case AST_CONTROL_REDIRECTING: 04611 case AST_CONTROL_CC: 04612 case AST_CONTROL_READ_ACTION: 04613 case AST_CONTROL_AOC: 04614 case AST_CONTROL_END_OF_Q: 04615 case AST_CONTROL_UPDATE_RTP_PEER: 04616 /* Nothing left to do for these. */ 04617 res = 0; 04618 break; 04619 } 04620 04621 if (ts) { 04622 /* We have a tone to play, yay. */ 04623 ast_debug(1, "Driver for channel '%s' does not support indication %u, emulating it\n", chan->name, condition); 04624 res = ast_playtones_start(chan, 0, ts->data, 1); 04625 ts = ast_tone_zone_sound_unref(ts); 04626 } 04627 04628 if (res) { 04629 /* not handled */ 04630 ast_log(LOG_WARNING, "Unable to handle indication %u for '%s'\n", condition, chan->name); 04631 } 04632 04633 indicate_cleanup: 04634 ast_channel_unlock(chan); 04635 if (awesome_frame) { 04636 ast_frfree(awesome_frame); 04637 } 04638 04639 return res; 04640 }
int ast_internal_timing_enabled | ( | struct ast_channel * | chan | ) |
Check if the channel can run in internal timing mode.
chan | The channel to check |
This function will return 1 if internal timing is enabled and the timing device is available.
Definition at line 4378 of file channel.c.
References ast_channel::timingfd.
04379 { 04380 return chan->timingfd > -1; 04381 }
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 1818 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().
01819 { 01820 /* Do not add a default entry in this switch statement. Each new 01821 * frame type should be addressed directly as to whether it should 01822 * be queued up or not. 01823 */ 01824 switch (frame->frametype) { 01825 case AST_FRAME_CONTROL: 01826 case AST_FRAME_TEXT: 01827 case AST_FRAME_IMAGE: 01828 case AST_FRAME_HTML: 01829 return 1; 01830 01831 case AST_FRAME_DTMF_END: 01832 case AST_FRAME_DTMF_BEGIN: 01833 case AST_FRAME_VOICE: 01834 case AST_FRAME_VIDEO: 01835 case AST_FRAME_NULL: 01836 case AST_FRAME_IAX: 01837 case AST_FRAME_CNG: 01838 case AST_FRAME_MODEM: 01839 return 0; 01840 } 01841 return 0; 01842 }
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 2276 of file channel.c.
References ast_party_caller::ani, ast_party_caller::ani2, ast_party_id_copy(), and ast_party_caller::id.
02277 { 02278 if (dest == src) { 02279 /* Don't copy to self */ 02280 return; 02281 } 02282 02283 ast_party_id_copy(&dest->id, &src->id); 02284 ast_party_id_copy(&dest->ani, &src->ani); 02285 dest->ani2 = src->ani2; 02286 }
void ast_party_caller_free | ( | struct ast_party_caller * | doomed | ) |
Destroy the caller party contents.
doomed | The caller party to destroy. |
Definition at line 2302 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().
02303 { 02304 ast_party_id_free(&doomed->id); 02305 ast_party_id_free(&doomed->ani); 02306 }
void ast_party_caller_init | ( | struct ast_party_caller * | init | ) |
Initialize the given caller structure.
init | Caller structure to initialize. |
Definition at line 2269 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(), and sla_ring_station().
02270 { 02271 ast_party_id_init(&init->id); 02272 ast_party_id_init(&init->ani); 02273 init->ani2 = 0; 02274 }
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.
This is similar to ast_party_caller_copy, except that NULL values for strings in the src parameter indicate not to update the corresponding dest values.
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 2295 of file channel.c.
References ast_set_party_caller::ani, ast_party_caller::ani, ast_party_caller::ani2, ast_party_id_set(), ast_set_party_caller::id, and ast_party_caller::id.
Referenced by ast_channel_set_caller(), ast_channel_set_caller_event(), and callerid_write().
02296 { 02297 ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL); 02298 ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL); 02299 dest->ani2 = src->ani2; 02300 }
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.
The initialization is needed to allow a set operation to know if a value needs to be updated. Simple integers need the guide's original value in case the set operation is not trying to set a new value. String values are simply set to NULL pointers if they are not going to be updated.
init | Caller structure to initialize. | |
guide | Source caller to use as a guide in initializing. |
Definition at line 2288 of file channel.c.
References ast_party_caller::ani, ast_party_caller::ani2, ast_party_id_set_init(), and ast_party_caller::id.
Referenced by callerid_write(), dial_exec_full(), do_forward(), misdn_update_caller_id(), and ring_entry().
02289 { 02290 ast_party_id_set_init(&init->id, &guide->id); 02291 ast_party_id_set_init(&init->ani, &guide->ani); 02292 init->ani2 = guide->ani2; 02293 }
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. |
Definition at line 2345 of file channel.c.
References ast_party_caller::ani, ast_party_connected_line::ani, ast_party_caller::ani2, ast_party_connected_line::ani2, AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN, ast_party_caller::id, ast_party_connected_line::id, and ast_party_connected_line::source.
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 2316 of file channel.c.
References ast_party_connected_line::ani, ast_party_connected_line::ani2, ast_party_id_copy(), ast_party_connected_line::id, and ast_party_connected_line::source.
Referenced by __ast_read(), ast_call_forward(), ast_channel_connected_line_macro(), ast_do_pickup(), builtin_atxfer(), dial_exec_full(), do_forward(), local_attended_transfer(), misdn_attempt_transfer(), party_connected_line_copy_transfer(), try_calling(), and wait_for_answer().
02317 { 02318 if (dest == src) { 02319 /* Don't copy to self */ 02320 return; 02321 } 02322 02323 ast_party_id_copy(&dest->id, &src->id); 02324 ast_party_id_copy(&dest->ani, &src->ani); 02325 dest->ani2 = src->ani2; 02326 dest->source = src->source; 02327 }
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 2353 of file channel.c.
References ast_party_connected_line::ani, ast_party_id_free(), and ast_party_connected_line::id.
Referenced by __ast_read(), app_exec(), ast_channel_connected_line_macro(), ast_channel_destructor(), ast_do_pickup(), ast_dummy_channel_destructor(), ast_indicate_data(), atxfer_fail_cleanup(), builtin_atxfer(), callattempt_free(), chanlist_free(), connectedline_write(), destroy_calling_tree(), feature_request_and_dial(), findmeexec(), local_attended_transfer(), misdn_attempt_transfer(), parked_call_exec(), socket_process(), wait_for_answer(), wait_for_winner(), and xfer_ds_destroy().
02354 { 02355 ast_party_id_free(&doomed->id); 02356 ast_party_id_free(&doomed->ani); 02357 }
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 2308 of file channel.c.
References ast_party_connected_line::ani, ast_party_connected_line::ani2, AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN, ast_party_id_init(), ast_party_connected_line::id, and ast_party_connected_line::source.
Referenced by __ast_channel_alloc_ap(), __ast_read(), ast_channel_connected_line_macro(), ast_do_pickup(), builtin_atxfer(), do_forward(), handle_request_invite(), handle_request_update(), handle_response_invite(), local_attended_transfer(), misdn_attempt_transfer(), misdn_queue_connected_line_update(), parked_call_exec(), sip_call(), socket_process(), and wait_for_answer().
02309 { 02310 ast_party_id_init(&init->id); 02311 ast_party_id_init(&init->ani); 02312 init->ani2 = 0; 02313 init->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN; 02314 }
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 2337 of file channel.c.
References ast_set_party_connected_line::ani, ast_party_connected_line::ani, ast_party_connected_line::ani2, ast_party_id_set(), ast_set_party_connected_line::id, ast_party_connected_line::id, and ast_party_connected_line::source.
Referenced by ast_channel_set_connected_line(), wait_for_answer(), and wait_for_winner().
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.
The initialization is needed to allow a set operation to know if a value needs to be updated. Simple integers need the guide's original value in case the set operation is not trying to set a new value. String values are simply set to NULL pointers if they are not going to be updated.
init | Connected line structure to initialize. | |
guide | Source connected line to use as a guide in initializing. |
Definition at line 2329 of file channel.c.
References ast_party_connected_line::ani, ast_party_connected_line::ani2, ast_party_id_set_init(), ast_party_connected_line::id, and ast_party_connected_line::source.
Referenced by __ast_request_and_dial(), ast_indicate_data(), connectedline_write(), dial_exec_full(), feature_request_and_dial(), wait_for_answer(), and wait_for_winner().
02330 { 02331 ast_party_id_set_init(&init->id, &guide->id); 02332 ast_party_id_set_init(&init->ani, &guide->ani); 02333 init->ani2 = guide->ani2; 02334 init->source = guide->source; 02335 }
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 2227 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().
02228 { 02229 if (dest == src) { 02230 /* Don't copy to self */ 02231 return; 02232 } 02233 02234 ast_free(dest->number.str); 02235 dest->number.str = ast_strdup(src->number.str); 02236 dest->number.plan = src->number.plan; 02237 ast_party_subaddress_copy(&dest->subaddress, &src->subaddress); 02238 dest->transit_network_select = src->transit_network_select; 02239 }
void ast_party_dialed_free | ( | struct ast_party_dialed * | doomed | ) |
Destroy the dialed party contents.
doomed | The dialed party to destroy. |
Definition at line 2262 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().
02263 { 02264 ast_free(doomed->number.str); 02265 doomed->number.str = NULL; 02266 ast_party_subaddress_free(&doomed->subaddress); 02267 }
void ast_party_dialed_init | ( | struct ast_party_dialed * | init | ) |
Initialize the given dialed structure.
init | Dialed structure to initialize. |
Definition at line 2219 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().
02220 { 02221 init->number.str = NULL; 02222 init->number.plan = 0;/* Unknown */ 02223 ast_party_subaddress_init(&init->subaddress); 02224 init->transit_network_select = 0; 02225 }
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.
This is similar to ast_party_dialed_copy, except that NULL values for strings in the src parameter indicate not to update the corresponding dest values.
dest | The dialed one wishes to update | |
src | The new dialed values to update the dest |
Definition at line 2249 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().
02250 { 02251 if (src->number.str && src->number.str != dest->number.str) { 02252 ast_free(dest->number.str); 02253 dest->number.str = ast_strdup(src->number.str); 02254 } 02255 dest->number.plan = src->number.plan; 02256 02257 ast_party_subaddress_set(&dest->subaddress, &src->subaddress); 02258 02259 dest->transit_network_select = src->transit_network_select; 02260 }
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.
The initialization is needed to allow a set operation to know if a value needs to be updated. Simple integers need the guide's original value in case the set operation is not trying to set a new value. String values are simply set to NULL pointers if they are not going to be updated.
init | Caller structure to initialize. | |
guide | Source dialed to use as a guide in initializing. |
Definition at line 2241 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().
02242 { 02243 init->number.str = NULL; 02244 init->number.plan = guide->number.plan; 02245 ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress); 02246 init->transit_network_select = guide->transit_network_select; 02247 }
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 2095 of file channel.c.
References ast_free, ast_party_name_copy(), ast_party_number_copy(), ast_party_subaddress_copy(), ast_strdup, ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, and ast_party_id::tag.
Referenced by ast_connected_line_copy_from_caller(), ast_connected_line_copy_to_caller(), ast_party_caller_copy(), ast_party_connected_line_copy(), ast_party_redirecting_copy(), and parkandannounce_exec().
02096 { 02097 if (dest == src) { 02098 /* Don't copy to self */ 02099 return; 02100 } 02101 02102 ast_party_name_copy(&dest->name, &src->name); 02103 ast_party_number_copy(&dest->number, &src->number); 02104 ast_party_subaddress_copy(&dest->subaddress, &src->subaddress); 02105 02106 ast_free(dest->tag); 02107 dest->tag = ast_strdup(src->tag); 02108 }
void ast_party_id_free | ( | struct ast_party_id * | doomed | ) |
Destroy the party id contents.
doomed | The party id to destroy. |
Definition at line 2141 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 parkandannounce_exec().
02142 { 02143 ast_party_name_free(&doomed->name); 02144 ast_party_number_free(&doomed->number); 02145 ast_party_subaddress_free(&doomed->subaddress); 02146 02147 ast_free(doomed->tag); 02148 doomed->tag = NULL; 02149 }
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 2087 of file channel.c.
References ast_party_name_init(), ast_party_number_init(), ast_party_subaddress_init(), ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, and ast_party_id::tag.
Referenced by ast_party_caller_init(), ast_party_connected_line_init(), ast_party_redirecting_init(), dial_exec_full(), and parkandannounce_exec().
02088 { 02089 ast_party_name_init(&init->name); 02090 ast_party_number_init(&init->number); 02091 ast_party_subaddress_init(&init->subaddress); 02092 init->tag = NULL; 02093 }
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 2151 of file channel.c.
References AST_PRES_ALLOWED, AST_PRES_NUMBER_NOT_AVAILABLE, AST_PRES_NUMBER_TYPE, AST_PRES_RESTRICTED, AST_PRES_RESTRICTION, AST_PRES_UNAVAILABLE, AST_PRES_USER_NUMBER_UNSCREENED, ast_party_id::name, ast_party_id::number, ast_party_number::valid, and ast_party_name::valid.
Referenced by add_rpid(), ast_str_retrieve_variable(), ast_var_channels_table(), callerpres_read(), iax2_call(), initreqprep(), oh323_call(), party_id_build_data(), party_id_read(), redirecting_read(), report_new_callerid(), setup_env(), sip_call(), and socket_process().
02152 { 02153 int number_priority; 02154 int number_value; 02155 int number_screening; 02156 int name_priority; 02157 int name_value; 02158 02159 /* Determine name presentation priority. */ 02160 if (!id->name.valid) { 02161 name_value = AST_PRES_UNAVAILABLE; 02162 name_priority = 3; 02163 } else { 02164 name_value = id->name.presentation & AST_PRES_RESTRICTION; 02165 switch (name_value) { 02166 case AST_PRES_RESTRICTED: 02167 name_priority = 0; 02168 break; 02169 case AST_PRES_ALLOWED: 02170 name_priority = 1; 02171 break; 02172 case AST_PRES_UNAVAILABLE: 02173 name_priority = 2; 02174 break; 02175 default: 02176 name_value = AST_PRES_UNAVAILABLE; 02177 name_priority = 3; 02178 break; 02179 } 02180 } 02181 02182 /* Determine number presentation priority. */ 02183 if (!id->number.valid) { 02184 number_screening = AST_PRES_USER_NUMBER_UNSCREENED; 02185 number_value = AST_PRES_UNAVAILABLE; 02186 number_priority = 3; 02187 } else { 02188 number_screening = id->number.presentation & AST_PRES_NUMBER_TYPE; 02189 number_value = id->number.presentation & AST_PRES_RESTRICTION; 02190 switch (number_value) { 02191 case AST_PRES_RESTRICTED: 02192 number_priority = 0; 02193 break; 02194 case AST_PRES_ALLOWED: 02195 number_priority = 1; 02196 break; 02197 case AST_PRES_UNAVAILABLE: 02198 number_priority = 2; 02199 break; 02200 default: 02201 number_screening = AST_PRES_USER_NUMBER_UNSCREENED; 02202 number_value = AST_PRES_UNAVAILABLE; 02203 number_priority = 3; 02204 break; 02205 } 02206 } 02207 02208 /* Select the wining presentation value. */ 02209 if (name_priority < number_priority) { 02210 number_value = name_value; 02211 } 02212 if (number_value == AST_PRES_UNAVAILABLE) { 02213 return AST_PRES_NUMBER_NOT_AVAILABLE; 02214 } 02215 02216 return number_value | number_screening; 02217 }
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 2118 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_set_party_id::name, ast_party_id::number, ast_set_party_id::number, ast_party_id::subaddress, ast_set_party_id::subaddress, and ast_party_id::tag.
Referenced by ast_party_caller_set(), ast_party_connected_line_set(), and ast_party_redirecting_set().
02119 { 02120 if (dest == src) { 02121 /* Don't set to self */ 02122 return; 02123 } 02124 02125 if (!update || update->name) { 02126 ast_party_name_set(&dest->name, &src->name); 02127 } 02128 if (!update || update->number) { 02129 ast_party_number_set(&dest->number, &src->number); 02130 } 02131 if (!update || update->subaddress) { 02132 ast_party_subaddress_set(&dest->subaddress, &src->subaddress); 02133 } 02134 02135 if (src->tag && src->tag != dest->tag) { 02136 ast_free(dest->tag); 02137 dest->tag = ast_strdup(src->tag); 02138 } 02139 }
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.
The initialization is needed to allow a set operation to know if a value needs to be updated. Simple integers need the guide's original value in case the set operation is not trying to set a new value. String values are simply set to NULL pointers if they are not going to be updated.
init | Party id structure to initialize. | |
guide | Source party id to use as a guide in initializing. |
Definition at line 2110 of file channel.c.
References ast_party_name_set_init(), ast_party_number_set_init(), ast_party_subaddress_set_init(), ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, and ast_party_id::tag.
Referenced by ast_party_caller_set_init(), ast_party_connected_line_set_init(), ast_party_redirecting_set_init(), and dial_exec_full().
02111 { 02112 ast_party_name_set_init(&init->name, &guide->name); 02113 ast_party_number_set_init(&init->number, &guide->number); 02114 ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress); 02115 init->tag = NULL; 02116 }
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 1936 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().
01937 { 01938 if (dest == src) { 01939 /* Don't copy to self */ 01940 return; 01941 } 01942 01943 ast_free(dest->str); 01944 dest->str = ast_strdup(src->str); 01945 dest->char_set = src->char_set; 01946 dest->presentation = src->presentation; 01947 dest->valid = src->valid; 01948 }
void ast_party_name_free | ( | struct ast_party_name * | doomed | ) |
Destroy the party name contents.
doomed | The party name to destroy. |
Definition at line 1975 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 1928 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().
01929 { 01930 init->str = NULL; 01931 init->char_set = AST_PARTY_CHAR_SET_ISO8859_1; 01932 init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 01933 init->valid = 0; 01934 }
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 1958 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().
01959 { 01960 if (dest == src) { 01961 /* Don't set to self */ 01962 return; 01963 } 01964 01965 if (src->str && src->str != dest->str) { 01966 ast_free(dest->str); 01967 dest->str = ast_strdup(src->str); 01968 } 01969 01970 dest->char_set = src->char_set; 01971 dest->presentation = src->presentation; 01972 dest->valid = src->valid; 01973 }
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.
The initialization is needed to allow a set operation to know if a value needs to be updated. Simple integers need the guide's original value in case the set operation is not trying to set a new value. String values are simply set to NULL pointers if they are not going to be updated.
init | Party name structure to initialize. | |
guide | Source party name to use as a guide in initializing. |
Definition at line 1950 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().
01951 { 01952 init->str = NULL; 01953 init->char_set = guide->char_set; 01954 init->presentation = guide->presentation; 01955 init->valid = guide->valid; 01956 }
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.
Definition at line 1989 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().
01990 { 01991 if (dest == src) { 01992 /* Don't copy to self */ 01993 return; 01994 } 01995 01996 ast_free(dest->str); 01997 dest->str = ast_strdup(src->str); 01998 dest->plan = src->plan; 01999 dest->presentation = src->presentation; 02000 dest->valid = src->valid; 02001 }
void ast_party_number_free | ( | struct ast_party_number * | doomed | ) |
Destroy the party number contents.
doomed | The party number to destroy. |
Definition at line 2028 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(), skinny_newcall(), and wait_for_answer().
void ast_party_number_init | ( | struct ast_party_number * | init | ) |
Initialize the given number structure.
init | Number structure to initialize. |
Definition at line 1981 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(), skinny_newcall(), and wait_for_answer().
01982 { 01983 init->str = NULL; 01984 init->plan = 0;/* Unknown */ 01985 init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 01986 init->valid = 0; 01987 }
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.
Definition at line 2011 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().
02012 { 02013 if (dest == src) { 02014 /* Don't set to self */ 02015 return; 02016 } 02017 02018 if (src->str && src->str != dest->str) { 02019 ast_free(dest->str); 02020 dest->str = ast_strdup(src->str); 02021 } 02022 02023 dest->plan = src->plan; 02024 dest->presentation = src->presentation; 02025 dest->valid = src->valid; 02026 }
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.
The initialization is needed to allow a set operation to know if a value needs to be updated. Simple integers need the guide's original value in case the set operation is not trying to set a new value. String values are simply set to NULL pointers if they are not going to be updated.
init | Party number structure to initialize. | |
guide | Source party number to use as a guide in initializing. |
Definition at line 2003 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().
02004 { 02005 init->str = NULL; 02006 init->plan = guide->plan; 02007 init->presentation = guide->presentation; 02008 init->valid = guide->valid; 02009 }
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 2367 of file channel.c.
References ast_party_id_copy(), ast_party_redirecting::count, ast_party_redirecting::from, ast_party_redirecting::reason, and ast_party_redirecting::to.
Referenced by ast_call_forward(), ast_channel_redirecting_macro(), begin_dial_channel(), call_forward_inherit(), dial_exec_full(), do_forward(), local_call(), ring_entry(), and wait_for_answer().
02368 { 02369 if (dest == src) { 02370 /* Don't copy to self */ 02371 return; 02372 } 02373 02374 ast_party_id_copy(&dest->from, &src->from); 02375 ast_party_id_copy(&dest->to, &src->to); 02376 dest->count = src->count; 02377 dest->reason = src->reason; 02378 }
void ast_party_redirecting_free | ( | struct ast_party_redirecting * | doomed | ) |
Destroy the redirecting information contents.
doomed | The redirecting information to destroy. |
Definition at line 2396 of file channel.c.
References ast_party_id_free(), ast_party_redirecting::from, and ast_party_redirecting::to.
Referenced by ast_channel_destructor(), ast_channel_redirecting_macro(), ast_dummy_channel_destructor(), ast_indicate_data(), call_forward_inherit(), do_forward(), handle_request_invite(), handle_response(), handle_response_invite(), redirecting_write(), and wait_for_answer().
02397 { 02398 ast_party_id_free(&doomed->from); 02399 ast_party_id_free(&doomed->to); 02400 }
void ast_party_redirecting_init | ( | struct ast_party_redirecting * | init | ) |
Initialize the given redirecting structure.
init | Redirecting structure to initialize. |
Definition at line 2359 of file channel.c.
References ast_party_id_init(), AST_REDIRECTING_REASON_UNKNOWN, ast_party_redirecting::count, ast_party_redirecting::from, ast_party_redirecting::reason, and ast_party_redirecting::to.
Referenced by __ast_channel_alloc_ap(), ast_channel_redirecting_macro(), call_forward_inherit(), do_forward(), handle_request_invite(), handle_response(), handle_response_invite(), and wait_for_answer().
02360 { 02361 ast_party_id_init(&init->from); 02362 ast_party_id_init(&init->to); 02363 init->count = 0; 02364 init->reason = AST_REDIRECTING_REASON_UNKNOWN; 02365 }
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.
This is similar to ast_party_redirecting_copy, except that NULL values for strings in the src parameter indicate not to update the corresponding dest values.
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 2388 of file channel.c.
References ast_party_id_set(), ast_party_redirecting::count, ast_set_party_redirecting::from, ast_party_redirecting::from, ast_party_redirecting::reason, ast_set_party_redirecting::to, and ast_party_redirecting::to.
Referenced by ast_channel_set_redirecting().
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.
The initialization is needed to allow a set operation to know if a value needs to be updated. Simple integers need the guide's original value in case the set operation is not trying to set a new value. String values are simply set to NULL pointers if they are not going to be updated.
init | Redirecting id structure to initialize. | |
guide | Source redirecting id to use as a guide in initializing. |
Definition at line 2380 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(), and redirecting_write().
02381 { 02382 ast_party_id_set_init(&init->from, &guide->from); 02383 ast_party_id_set_init(&init->to, &guide->to); 02384 init->count = guide->count; 02385 init->reason = guide->reason; 02386 }
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 2042 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().
02043 { 02044 if (dest == src) { 02045 /* Don't copy to self */ 02046 return; 02047 } 02048 02049 ast_free(dest->str); 02050 dest->str = ast_strdup(src->str); 02051 dest->type = src->type; 02052 dest->odd_even_indicator = src->odd_even_indicator; 02053 dest->valid = src->valid; 02054 }
void ast_party_subaddress_free | ( | struct ast_party_subaddress * | doomed | ) |
Destroy the party subaddress contents.
doomed | The party subaddress to destroy. |
Definition at line 2081 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 2034 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(), and ast_party_id_init().
02035 { 02036 init->str = NULL; 02037 init->type = 0; 02038 init->odd_even_indicator = 0; 02039 init->valid = 0; 02040 }
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 2064 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(), and ast_party_id_set().
02065 { 02066 if (dest == src) { 02067 /* Don't set to self */ 02068 return; 02069 } 02070 02071 if (src->str && src->str != dest->str) { 02072 ast_free(dest->str); 02073 dest->str = ast_strdup(src->str); 02074 } 02075 02076 dest->type = src->type; 02077 dest->odd_even_indicator = src->odd_even_indicator; 02078 dest->valid = src->valid; 02079 }
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.
The initialization is needed to allow a set operation to know if a value needs to be updated. Simple integers need the guide's original value in case the set operation is not trying to set a new value. String values are simply set to NULL pointers if they are not going to be updated.
init | Party subaddress structure to initialize. | |
guide | Source party subaddress to use as a guide in initializing. |
Definition at line 2056 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().
02057 { 02058 init->str = NULL; 02059 init->type = guide->type; 02060 init->odd_even_indicator = guide->odd_even_indicator; 02061 init->valid = guide->valid; 02062 }
void ast_poll_channel_add | ( | struct ast_channel * | chan0, | |
struct ast_channel * | chan1 | |||
) |
Add a channel to an optimized waitfor
Definition at line 2665 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().
02666 { 02667 #ifdef HAVE_EPOLL 02668 struct epoll_event ev; 02669 int i = 0; 02670 02671 if (chan0->epfd == -1) 02672 return; 02673 02674 /* Iterate through the file descriptors on chan1, adding them to chan0 */ 02675 for (i = 0; i < AST_MAX_FDS; i++) { 02676 if (chan1->fds[i] == -1) 02677 continue; 02678 ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP; 02679 ev.data.ptr = chan1->epfd_data[i]; 02680 epoll_ctl(chan0->epfd, EPOLL_CTL_ADD, chan1->fds[i], &ev); 02681 } 02682 02683 #endif 02684 return; 02685 }
void ast_poll_channel_del | ( | struct ast_channel * | chan0, | |
struct ast_channel * | chan1 | |||
) |
Delete a channel from an optimized waitfor
Definition at line 2688 of file channel.c.
References AST_MAX_FDS, and ast_channel::fds.
Referenced by ast_generic_bridge(), feature_request_and_dial(), local_bridge_loop(), monitor_dial(), remote_bridge_loop(), and wait_for_answer().
02689 { 02690 #ifdef HAVE_EPOLL 02691 struct epoll_event ev; 02692 int i = 0; 02693 02694 if (chan0->epfd == -1) 02695 return; 02696 02697 for (i = 0; i < AST_MAX_FDS; i++) { 02698 if (chan1->fds[i] == -1) 02699 continue; 02700 epoll_ctl(chan0->epfd, EPOLL_CTL_DEL, chan1->fds[i], &ev); 02701 } 02702 02703 #endif 02704 return; 02705 }
char* ast_print_group | ( | char * | buf, | |
int | buflen, | |||
ast_group_t | group | |||
) |
print call- and pickup groups into buffer
Definition at line 8236 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().
08237 { 08238 unsigned int i; 08239 int first = 1; 08240 char num[3]; 08241 08242 buf[0] = '\0'; 08243 08244 if (!group) /* Return empty string if no group */ 08245 return buf; 08246 08247 for (i = 0; i <= 63; i++) { /* Max group is 63 */ 08248 if (group & ((ast_group_t) 1 << i)) { 08249 if (!first) { 08250 strncat(buf, ", ", buflen - strlen(buf) - 1); 08251 } else { 08252 first = 0; 08253 } 08254 snprintf(num, sizeof(num), "%u", i); 08255 strncat(buf, num, buflen - strlen(buf) - 1); 08256 } 08257 } 08258 return buf; 08259 }
int ast_prod | ( | struct ast_channel * | chan | ) |
Send empty audio to prime a channel driver.
Definition at line 4784 of file channel.c.
References ast_channel::_state, ast_debug, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), AST_STATE_UP, ast_write(), ast_frame_subclass::codec, ast_frame::data, LOG_WARNING, ast_frame::ptr, ast_channel::rawwriteformat, ast_frame::src, and ast_frame::subclass.
Referenced by ast_activate_generator().
04785 { 04786 struct ast_frame a = { AST_FRAME_VOICE }; 04787 char nothing[128]; 04788 04789 /* Send an empty audio frame to get things moving */ 04790 if (chan->_state != AST_STATE_UP) { 04791 ast_debug(1, "Prodding channel '%s'\n", chan->name); 04792 a.subclass.codec = chan->rawwriteformat; 04793 a.data.ptr = nothing + AST_FRIENDLY_OFFSET; 04794 a.src = "ast_prod"; /* this better match check in ast_write */ 04795 if (ast_write(chan, &a)) 04796 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name); 04797 } 04798 return 0; 04799 }
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 1601 of file channel.c.
References AST_FRAME_CONTROL, and ast_queue_frame().
Referenced by __analog_handle_event(), __analog_ss_thread(), __ast_read(), __dahdi_exception(), __oh323_update_info(), analog_call(), analog_exception(), analog_hangup(), analog_ss_thread(), ast_do_pickup(), attempt_transfer(), auto_congest(), cb_events(), cli_console_answer(), cli_console_flash(), console_answer(), console_call(), console_sendtext(), dahdi_handle_event(), dahdi_hangup(), gtalk_is_answered(), gtalk_ringing_ack(), handle_hd_hf(), handle_incoming(), handle_offhook_message(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), handle_response_refer(), handle_soft_key_event_message(), handle_stimulus_message(), HandleCallIncoming(), jingle_is_answered(), jingle_ringing_ack(), masquerade_colp_transfer(), misdn_facility_ie_handler(), multicast_rtp_call(), nbs_call(), phone_call(), process_sdp(), receive_digit(), remote_hold(), send_cause2ast(), setup_rtp_connection(), skinny_call(), skinny_transfer(), skinny_unhold(), unistim_call(), and update_state().
01602 { 01603 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control }; 01604 return ast_queue_frame(chan, &f); 01605 }
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 supplied payload data is copied into the frame, so the caller's copy is not modified nor freed, and the resulting frame will retain a copy of the data even if the caller frees their local copy.
Definition at line 1608 of file channel.c.
References AST_FRAME_CONTROL, and ast_queue_frame().
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().
01610 { 01611 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control, .data.ptr = (void *) data, .datalen = datalen }; 01612 return ast_queue_frame(chan, &f); 01613 }
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 1558 of file channel.c.
References __ast_queue_frame().
Referenced by __ast_channel_masquerade(), __ast_read(), __oh323_rtp_create(), __oh323_update_info(), action_atxfer(), agent_request(), alsa_call(), ast_channel_setwhentohangup_tv(), ast_do_masquerade(), ast_dsp_process(), 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(), local_queue_frame(), mgcp_queue_frame(), oh323_simulate_dtmf_end(), oss_call(), process_sdp(), queue_dtmf_readq(), receive_digit(), receive_message(), stream_monitor(), unistim_do_senddigit(), unistim_senddigit_end(), and wakeup_sub().
01559 { 01560 return __ast_queue_frame(chan, fin, 0, NULL); 01561 }
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 1563 of file channel.c.
References __ast_queue_frame().
Referenced by __ast_answer(), __ast_read(), ast_autoservice_stop(), ast_safe_sleep_conditional(), and feature_request_and_dial().
01564 { 01565 return __ast_queue_frame(chan, fin, 1, NULL); 01566 }
int ast_queue_hangup | ( | struct ast_channel * | chan | ) |
Queue a hangup frame.
Definition at line 1569 of file channel.c.
References ast_channel::_softhangup, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, ast_queue_frame(), and AST_SOFTHANGUP_DEV.
Referenced by bridge_queue_hangup(), cleanup_connection(), cli_console_hangup(), close_call(), gtalk_hangup_farend(), gtalk_is_answered(), handle_onhook_message(), handle_request_bye(), handle_soft_key_event_message(), iax2_destroy(), iax2_queue_hangup(), jingle_hangup_farend(), local_fixup(), local_hangup(), mgcp_queue_hangup(), and sip_queue_hangup_cause().
01570 { 01571 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP }; 01572 /* Yeah, let's not change a lock-critical value without locking */ 01573 if (!ast_channel_trylock(chan)) { 01574 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01575 ast_channel_unlock(chan); 01576 } 01577 return ast_queue_frame(chan, &f); 01578 }
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 1581 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, ast_frame::data, ast_channel::hangupcause, and ast_frame::uint32.
Referenced by __analog_handle_event(), __oh323_update_info(), __sip_autodestruct(), close_call(), close_client(), console_hangup(), dahdi_handle_event(), handle_request_bye(), handle_response(), handle_response_invite(), HandleCallOutgoing(), hangup_chan(), hangup_connection(), local_hangup(), misdn_answer(), retrans_pkt(), sip_queue_hangup_cause(), and TransferCallStep1().
01582 { 01583 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP }; 01584 01585 if (cause >= 0) 01586 f.data.uint32 = cause; 01587 01588 /* Yeah, let's not change a lock-critical value without locking */ 01589 if (!ast_channel_trylock(chan)) { 01590 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01591 if (cause < 0) 01592 f.data.uint32 = chan->hangupcause; 01593 01594 ast_channel_unlock(chan); 01595 } 01596 01597 return ast_queue_frame(chan, &f); 01598 }
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' |
This function answers a channel and handles all necessary call setup functions.
0 | on success | |
non-zero | on failure |
Definition at line 2930 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, and ast_channel::tech.
Referenced by __ast_answer(), and ast_bridge_call().
02931 { 02932 int res = 0; 02933 02934 ast_channel_lock(chan); 02935 02936 /* You can't answer an outbound call */ 02937 if (ast_test_flag(chan, AST_FLAG_OUTGOING)) { 02938 ast_channel_unlock(chan); 02939 return 0; 02940 } 02941 02942 /* Stop if we're a zombie or need a soft hangup */ 02943 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 02944 ast_channel_unlock(chan); 02945 return -1; 02946 } 02947 02948 ast_channel_unlock(chan); 02949 02950 switch (chan->_state) { 02951 case AST_STATE_RINGING: 02952 case AST_STATE_RING: 02953 ast_channel_lock(chan); 02954 if (chan->tech->answer) { 02955 res = chan->tech->answer(chan); 02956 } 02957 ast_setstate(chan, AST_STATE_UP); 02958 if (cdr_answer) { 02959 ast_cdr_answer(chan->cdr); 02960 } 02961 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL); 02962 ast_channel_unlock(chan); 02963 break; 02964 case AST_STATE_UP: 02965 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL); 02966 /* Calling ast_cdr_answer when it it has previously been called 02967 * is essentially a no-op, so it is safe. 02968 */ 02969 if (cdr_answer) { 02970 ast_cdr_answer(chan->cdr); 02971 } 02972 break; 02973 default: 02974 break; 02975 } 02976 02977 ast_indicate(chan, -1); 02978 02979 return res; 02980 }
struct ast_frame* ast_read | ( | struct ast_channel * | chan | ) | [read] |
Reads a frame.
chan | channel to read a frame from |
Definition at line 4383 of file channel.c.
References __ast_read().
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_generic_bridge(), ast_recvtext(), ast_safe_sleep_conditional(), ast_tonepair(), ast_transfer(), ast_udptl_bridge(), ast_waitfordigit_full(), async_agi_read_frame(), async_wait(), autoservice_run(), background_detect_exec(), channel_spy(), conf_flush(), conf_run(), dahdi_bridge(), dial_exec_full(), dictate_exec(), disa_exec(), disable_t38(), do_waiting(), echo_exec(), eivr_comm(), feature_request_and_dial(), find_cache(), generic_fax_exec(), handle_recordfile(), handle_speechrecognize(), iax2_bridge(), ices_exec(), isAnsweringMachine(), jack_exec(), local_bridge_loop(), manage_parked_call(), measurenoise(), misdn_bridge(), monitor_dial(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), receivefax_t38_init(), record_exec(), recordthread(), remote_bridge_loop(), run_agi(), send_tone_burst(), send_waveform_to_channel(), sendfax_t38_init(), sendurl_exec(), speech_background(), transmit_audio(), transmit_t38(), wait_for_answer(), wait_for_hangup(), wait_for_winner(), waitforring_exec(), and waitstream_core().
04384 { 04385 return __ast_read(chan, 0); 04386 }
struct ast_frame* ast_read_noaudio | ( | struct ast_channel * | chan | ) | [read] |
Reads a frame, returning AST_FRAME_NULL frame if audio.
chan | channel to read a frame from |
Definition at line 4388 of file channel.c.
References __ast_read().
Referenced by ast_bridge_handle_trip(), and conf_run().
04389 { 04390 return __ast_read(chan, 1); 04391 }
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 |
Read in a digit string "s", max length "len", maximum timeout between digits "timeout" (-1 for none), terminated by anything in "enders". Give them rtimeout for the first digit.
Definition at line 5837 of file channel.c.
References ast_readstring_full().
Referenced by __adsi_transmit_messages(), adsi_begin_download(), adsi_get_cpeinfo(), adsi_load_session(), ast_app_getdata(), dialout(), do_directory(), forward_message(), privacy_exec(), vm_authenticate(), vm_newuser(), and vm_options().
05838 { 05839 return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1); 05840 }
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 5842 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().
05843 { 05844 int pos = 0; /* index in the buffer where we accumulate digits */ 05845 int to = ftimeout; 05846 05847 struct ast_silence_generator *silgen = NULL; 05848 05849 /* Stop if we're a zombie or need a soft hangup */ 05850 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 05851 return -1; 05852 if (!len) 05853 return -1; 05854 for (;;) { 05855 int d; 05856 if (c->stream) { 05857 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd); 05858 ast_stopstream(c); 05859 if (!silgen && ast_opt_transmit_silence) 05860 silgen = ast_channel_start_silence_generator(c); 05861 usleep(1000); 05862 if (!d) 05863 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 05864 } else { 05865 if (!silgen && ast_opt_transmit_silence) 05866 silgen = ast_channel_start_silence_generator(c); 05867 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 05868 } 05869 if (d < 0) { 05870 ast_channel_stop_silence_generator(c, silgen); 05871 return AST_GETDATA_FAILED; 05872 } 05873 if (d == 0) { 05874 s[pos] = '\0'; 05875 ast_channel_stop_silence_generator(c, silgen); 05876 return AST_GETDATA_TIMEOUT; 05877 } 05878 if (d == 1) { 05879 s[pos] = '\0'; 05880 ast_channel_stop_silence_generator(c, silgen); 05881 return AST_GETDATA_INTERRUPTED; 05882 } 05883 if (strchr(enders, d) && (pos == 0)) { 05884 s[pos] = '\0'; 05885 ast_channel_stop_silence_generator(c, silgen); 05886 return AST_GETDATA_EMPTY_END_TERMINATED; 05887 } 05888 if (!strchr(enders, d)) { 05889 s[pos++] = d; 05890 } 05891 if (strchr(enders, d) || (pos >= len)) { 05892 s[pos] = '\0'; 05893 ast_channel_stop_silence_generator(c, silgen); 05894 return AST_GETDATA_COMPLETE; 05895 } 05896 to = timeout; 05897 } 05898 /* Never reached */ 05899 return 0; 05900 }
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) |
Read a char of text from a channel
Definition at line 4642 of file channel.c.
References ast_free, and ast_recvtext().
Referenced by handle_recvchar().
04643 { 04644 int c; 04645 char *buf = ast_recvtext(chan, timeout); 04646 if (buf == NULL) 04647 return -1; /* error or timeout */ 04648 c = *(unsigned char *)buf; 04649 ast_free(buf); 04650 return c; 04651 }
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 4653 of file channel.c.
References ast_check_hangup(), AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_TEXT, ast_frfree, ast_read(), ast_remaining_ms(), ast_strndup, ast_tvnow(), ast_waitfor(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, ast_frame_subclass::integer, ast_frame::ptr, and ast_frame::subclass.
Referenced by ast_recvchar(), and handle_recvtext().
04654 { 04655 int res; 04656 char *buf = NULL; 04657 struct timeval start = ast_tvnow(); 04658 int ms; 04659 04660 while ((ms = ast_remaining_ms(start, timeout))) { 04661 struct ast_frame *f; 04662 04663 if (ast_check_hangup(chan)) { 04664 break; 04665 } 04666 res = ast_waitfor(chan, ms); 04667 if (res <= 0) {/* timeout or error */ 04668 break; 04669 } 04670 f = ast_read(chan); 04671 if (f == NULL) { 04672 break; /* no frame */ 04673 } 04674 if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_HANGUP) { 04675 ast_frfree(f); 04676 break; 04677 } else if (f->frametype == AST_FRAME_TEXT) { /* what we want */ 04678 buf = ast_strndup((char *) f->data.ptr, f->datalen); /* dup and break */ 04679 ast_frfree(f); 04680 break; 04681 } 04682 ast_frfree(f); 04683 } 04684 return buf; 04685 }
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 9161 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_set_party_redirecting::from, 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_set_party_redirecting::to, ast_party_redirecting::to, and value.
Referenced by ast_channel_queue_redirecting_update(), ast_channel_update_redirecting(), and local_indicate().
09162 { 09163 int32_t value; 09164 size_t pos = 0; 09165 int res; 09166 09167 static const struct ast_party_id_ies from_ies = { 09168 .name.str = AST_REDIRECTING_FROM_NAME, 09169 .name.char_set = AST_REDIRECTING_FROM_NAME_CHAR_SET, 09170 .name.presentation = AST_REDIRECTING_FROM_NAME_PRESENTATION, 09171 .name.valid = AST_REDIRECTING_FROM_NAME_VALID, 09172 09173 .number.str = AST_REDIRECTING_FROM_NUMBER, 09174 .number.plan = AST_REDIRECTING_FROM_NUMBER_PLAN, 09175 .number.presentation = AST_REDIRECTING_FROM_NUMBER_PRESENTATION, 09176 .number.valid = AST_REDIRECTING_FROM_NUMBER_VALID, 09177 09178 .subaddress.str = AST_REDIRECTING_FROM_SUBADDRESS, 09179 .subaddress.type = AST_REDIRECTING_FROM_SUBADDRESS_TYPE, 09180 .subaddress.odd_even_indicator = AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN, 09181 .subaddress.valid = AST_REDIRECTING_FROM_SUBADDRESS_VALID, 09182 09183 .tag = AST_REDIRECTING_FROM_TAG, 09184 .combined_presentation = AST_REDIRECTING_FROM_ID_PRESENTATION, 09185 }; 09186 static const struct ast_party_id_ies to_ies = { 09187 .name.str = AST_REDIRECTING_TO_NAME, 09188 .name.char_set = AST_REDIRECTING_TO_NAME_CHAR_SET, 09189 .name.presentation = AST_REDIRECTING_TO_NAME_PRESENTATION, 09190 .name.valid = AST_REDIRECTING_TO_NAME_VALID, 09191 09192 .number.str = AST_REDIRECTING_TO_NUMBER, 09193 .number.plan = AST_REDIRECTING_TO_NUMBER_PLAN, 09194 .number.presentation = AST_REDIRECTING_TO_NUMBER_PRESENTATION, 09195 .number.valid = AST_REDIRECTING_TO_NUMBER_VALID, 09196 09197 .subaddress.str = AST_REDIRECTING_TO_SUBADDRESS, 09198 .subaddress.type = AST_REDIRECTING_TO_SUBADDRESS_TYPE, 09199 .subaddress.odd_even_indicator = AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN, 09200 .subaddress.valid = AST_REDIRECTING_TO_SUBADDRESS_VALID, 09201 09202 .tag = AST_REDIRECTING_TO_TAG, 09203 .combined_presentation = AST_REDIRECTING_TO_ID_PRESENTATION, 09204 }; 09205 09206 /* Redirecting frame version */ 09207 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 09208 ast_log(LOG_WARNING, "No space left for redirecting frame version\n"); 09209 return -1; 09210 } 09211 data[pos++] = AST_REDIRECTING_VERSION; 09212 data[pos++] = 1; 09213 data[pos++] = 2;/* Version 1 did not have a version ie */ 09214 09215 res = party_id_build_data(data + pos, datalen - pos, &redirecting->from, 09216 "redirecting-from", &from_ies, update ? &update->from : NULL); 09217 if (res < 0) { 09218 return -1; 09219 } 09220 pos += res; 09221 09222 res = party_id_build_data(data + pos, datalen - pos, &redirecting->to, 09223 "redirecting-to", &to_ies, update ? &update->to : NULL); 09224 if (res < 0) { 09225 return -1; 09226 } 09227 pos += res; 09228 09229 /* Redirecting reason */ 09230 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) { 09231 ast_log(LOG_WARNING, "No space left for redirecting reason\n"); 09232 return -1; 09233 } 09234 data[pos++] = AST_REDIRECTING_REASON; 09235 data[pos++] = sizeof(value); 09236 value = htonl(redirecting->reason); 09237 memcpy(data + pos, &value, sizeof(value)); 09238 pos += sizeof(value); 09239 09240 /* Redirecting count */ 09241 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) { 09242 ast_log(LOG_WARNING, "No space left for redirecting count\n"); 09243 return -1; 09244 } 09245 data[pos++] = AST_REDIRECTING_COUNT; 09246 data[pos++] = sizeof(value); 09247 value = htonl(redirecting->count); 09248 memcpy(data + pos, &value, sizeof(value)); 09249 pos += sizeof(value); 09250 09251 return pos; 09252 }
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. |
Definition at line 9254 of file channel.c.
References ast_free, ast_log(), ast_malloc, AST_PARTY_CHAR_SET_ISO8859_1, AST_REDIRECTING_COUNT, AST_REDIRECTING_FROM_ID_PRESENTATION, AST_REDIRECTING_FROM_NAME, AST_REDIRECTING_FROM_NAME_CHAR_SET, AST_REDIRECTING_FROM_NAME_PRESENTATION, AST_REDIRECTING_FROM_NAME_VALID, AST_REDIRECTING_FROM_NUMBER, AST_REDIRECTING_FROM_NUMBER_PLAN, AST_REDIRECTING_FROM_NUMBER_PRESENTATION, AST_REDIRECTING_FROM_NUMBER_VALID, AST_REDIRECTING_FROM_SUBADDRESS, AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_FROM_SUBADDRESS_TYPE, AST_REDIRECTING_FROM_SUBADDRESS_VALID, AST_REDIRECTING_FROM_TAG, AST_REDIRECTING_TO_ID_PRESENTATION, AST_REDIRECTING_TO_NAME, AST_REDIRECTING_TO_NAME_CHAR_SET, AST_REDIRECTING_TO_NAME_PRESENTATION, AST_REDIRECTING_TO_NAME_VALID, AST_REDIRECTING_TO_NUMBER, AST_REDIRECTING_TO_NUMBER_PLAN, AST_REDIRECTING_TO_NUMBER_PRESENTATION, AST_REDIRECTING_TO_NUMBER_VALID, AST_REDIRECTING_TO_SUBADDRESS, AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_TO_SUBADDRESS_TYPE, AST_REDIRECTING_TO_SUBADDRESS_VALID, AST_REDIRECTING_TO_TAG, AST_REDIRECTING_VERSION, ast_party_name::char_set, ast_party_redirecting::count, ast_party_redirecting::from, LOG_DEBUG, LOG_WARNING, ast_party_id::name, ast_party_id::number, ast_party_subaddress::odd_even_indicator, ast_party_number::plan, ast_party_number::presentation, ast_party_name::presentation, ast_party_redirecting::reason, ast_party_subaddress::str, ast_party_number::str, ast_party_name::str, ast_party_id::subaddress, ast_party_id::tag, ast_party_redirecting::to, ast_party_subaddress::type, ast_party_subaddress::valid, ast_party_number::valid, ast_party_name::valid, and value.
Referenced by ast_channel_redirecting_macro(), and ast_indicate_data().
09255 { 09256 size_t pos; 09257 unsigned char ie_len; 09258 unsigned char ie_id; 09259 int32_t value; 09260 int frame_version = 1; 09261 int from_combined_presentation = 0; 09262 int got_from_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */ 09263 int to_combined_presentation = 0; 09264 int got_to_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */ 09265 09266 for (pos = 0; pos < datalen; pos += ie_len) { 09267 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) { 09268 ast_log(LOG_WARNING, "Invalid redirecting update\n"); 09269 return -1; 09270 } 09271 ie_id = data[pos++]; 09272 ie_len = data[pos++]; 09273 if (datalen < pos + ie_len) { 09274 ast_log(LOG_WARNING, "Invalid redirecting update\n"); 09275 return -1; 09276 } 09277 09278 switch (ie_id) { 09279 /* Redirecting frame version */ 09280 case AST_REDIRECTING_VERSION: 09281 if (ie_len != 1) { 09282 ast_log(LOG_WARNING, "Invalid redirecting frame version (%u)\n", 09283 (unsigned) ie_len); 09284 break; 09285 } 09286 frame_version = data[pos]; 09287 break; 09288 /* Redirecting-from party id name */ 09289 case AST_REDIRECTING_FROM_NAME: 09290 ast_free(redirecting->from.name.str); 09291 redirecting->from.name.str = ast_malloc(ie_len + 1); 09292 if (redirecting->from.name.str) { 09293 memcpy(redirecting->from.name.str, data + pos, ie_len); 09294 redirecting->from.name.str[ie_len] = 0; 09295 } 09296 break; 09297 case AST_REDIRECTING_FROM_NAME_CHAR_SET: 09298 if (ie_len != 1) { 09299 ast_log(LOG_WARNING, "Invalid redirecting-from name char set (%u)\n", 09300 (unsigned) ie_len); 09301 break; 09302 } 09303 redirecting->from.name.char_set = data[pos]; 09304 break; 09305 case AST_REDIRECTING_FROM_NAME_PRESENTATION: 09306 if (ie_len != 1) { 09307 ast_log(LOG_WARNING, "Invalid redirecting-from name presentation (%u)\n", 09308 (unsigned) ie_len); 09309 break; 09310 } 09311 redirecting->from.name.presentation = data[pos]; 09312 break; 09313 case AST_REDIRECTING_FROM_NAME_VALID: 09314 if (ie_len != 1) { 09315 ast_log(LOG_WARNING, "Invalid redirecting-from name valid (%u)\n", 09316 (unsigned) ie_len); 09317 break; 09318 } 09319 redirecting->from.name.valid = data[pos]; 09320 break; 09321 /* Redirecting-from party id number */ 09322 case AST_REDIRECTING_FROM_NUMBER: 09323 ast_free(redirecting->from.number.str); 09324 redirecting->from.number.str = ast_malloc(ie_len + 1); 09325 if (redirecting->from.number.str) { 09326 memcpy(redirecting->from.number.str, data + pos, ie_len); 09327 redirecting->from.number.str[ie_len] = 0; 09328 } 09329 break; 09330 case AST_REDIRECTING_FROM_NUMBER_PLAN: 09331 if (ie_len != 1) { 09332 ast_log(LOG_WARNING, "Invalid redirecting-from numbering plan (%u)\n", 09333 (unsigned) ie_len); 09334 break; 09335 } 09336 redirecting->from.number.plan = data[pos]; 09337 break; 09338 case AST_REDIRECTING_FROM_NUMBER_PRESENTATION: 09339 if (ie_len != 1) { 09340 ast_log(LOG_WARNING, "Invalid redirecting-from number presentation (%u)\n", 09341 (unsigned) ie_len); 09342 break; 09343 } 09344 redirecting->from.number.presentation = data[pos]; 09345 break; 09346 case AST_REDIRECTING_FROM_NUMBER_VALID: 09347 if (ie_len != 1) { 09348 ast_log(LOG_WARNING, "Invalid redirecting-from number valid (%u)\n", 09349 (unsigned) ie_len); 09350 break; 09351 } 09352 redirecting->from.number.valid = data[pos]; 09353 break; 09354 /* Redirecting-from party id combined presentation */ 09355 case AST_REDIRECTING_FROM_ID_PRESENTATION: 09356 if (ie_len != 1) { 09357 ast_log(LOG_WARNING, "Invalid redirecting-from combined presentation (%u)\n", 09358 (unsigned) ie_len); 09359 break; 09360 } 09361 from_combined_presentation = data[pos]; 09362 got_from_combined_presentation = 1; 09363 break; 09364 /* Redirecting-from party id subaddress */ 09365 case AST_REDIRECTING_FROM_SUBADDRESS: 09366 ast_free(redirecting->from.subaddress.str); 09367 redirecting->from.subaddress.str = ast_malloc(ie_len + 1); 09368 if (redirecting->from.subaddress.str) { 09369 memcpy(redirecting->from.subaddress.str, data + pos, ie_len); 09370 redirecting->from.subaddress.str[ie_len] = 0; 09371 } 09372 break; 09373 case AST_REDIRECTING_FROM_SUBADDRESS_TYPE: 09374 if (ie_len != 1) { 09375 ast_log(LOG_WARNING, "Invalid redirecting-from type of subaddress (%u)\n", 09376 (unsigned) ie_len); 09377 break; 09378 } 09379 redirecting->from.subaddress.type = data[pos]; 09380 break; 09381 case AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN: 09382 if (ie_len != 1) { 09383 ast_log(LOG_WARNING, 09384 "Invalid redirecting-from subaddress odd-even indicator (%u)\n", 09385 (unsigned) ie_len); 09386 break; 09387 } 09388 redirecting->from.subaddress.odd_even_indicator = data[pos]; 09389 break; 09390 case AST_REDIRECTING_FROM_SUBADDRESS_VALID: 09391 if (ie_len != 1) { 09392 ast_log(LOG_WARNING, "Invalid redirecting-from subaddress valid (%u)\n", 09393 (unsigned) ie_len); 09394 break; 09395 } 09396 redirecting->from.subaddress.valid = data[pos]; 09397 break; 09398 /* Redirecting-from party id tag */ 09399 case AST_REDIRECTING_FROM_TAG: 09400 ast_free(redirecting->from.tag); 09401 redirecting->from.tag = ast_malloc(ie_len + 1); 09402 if (redirecting->from.tag) { 09403 memcpy(redirecting->from.tag, data + pos, ie_len); 09404 redirecting->from.tag[ie_len] = 0; 09405 } 09406 break; 09407 /* Redirecting-to party id name */ 09408 case AST_REDIRECTING_TO_NAME: 09409 ast_free(redirecting->to.name.str); 09410 redirecting->to.name.str = ast_malloc(ie_len + 1); 09411 if (redirecting->to.name.str) { 09412 memcpy(redirecting->to.name.str, data + pos, ie_len); 09413 redirecting->to.name.str[ie_len] = 0; 09414 } 09415 break; 09416 case AST_REDIRECTING_TO_NAME_CHAR_SET: 09417 if (ie_len != 1) { 09418 ast_log(LOG_WARNING, "Invalid redirecting-to name char set (%u)\n", 09419 (unsigned) ie_len); 09420 break; 09421 } 09422 redirecting->to.name.char_set = data[pos]; 09423 break; 09424 case AST_REDIRECTING_TO_NAME_PRESENTATION: 09425 if (ie_len != 1) { 09426 ast_log(LOG_WARNING, "Invalid redirecting-to name presentation (%u)\n", 09427 (unsigned) ie_len); 09428 break; 09429 } 09430 redirecting->to.name.presentation = data[pos]; 09431 break; 09432 case AST_REDIRECTING_TO_NAME_VALID: 09433 if (ie_len != 1) { 09434 ast_log(LOG_WARNING, "Invalid redirecting-to name valid (%u)\n", 09435 (unsigned) ie_len); 09436 break; 09437 } 09438 redirecting->to.name.valid = data[pos]; 09439 break; 09440 /* Redirecting-to party id number */ 09441 case AST_REDIRECTING_TO_NUMBER: 09442 ast_free(redirecting->to.number.str); 09443 redirecting->to.number.str = ast_malloc(ie_len + 1); 09444 if (redirecting->to.number.str) { 09445 memcpy(redirecting->to.number.str, data + pos, ie_len); 09446 redirecting->to.number.str[ie_len] = 0; 09447 } 09448 break; 09449 case AST_REDIRECTING_TO_NUMBER_PLAN: 09450 if (ie_len != 1) { 09451 ast_log(LOG_WARNING, "Invalid redirecting-to numbering plan (%u)\n", 09452 (unsigned) ie_len); 09453 break; 09454 } 09455 redirecting->to.number.plan = data[pos]; 09456 break; 09457 case AST_REDIRECTING_TO_NUMBER_PRESENTATION: 09458 if (ie_len != 1) { 09459 ast_log(LOG_WARNING, "Invalid redirecting-to number presentation (%u)\n", 09460 (unsigned) ie_len); 09461 break; 09462 } 09463 redirecting->to.number.presentation = data[pos]; 09464 break; 09465 case AST_REDIRECTING_TO_NUMBER_VALID: 09466 if (ie_len != 1) { 09467 ast_log(LOG_WARNING, "Invalid redirecting-to number valid (%u)\n", 09468 (unsigned) ie_len); 09469 break; 09470 } 09471 redirecting->to.number.valid = data[pos]; 09472 break; 09473 /* Redirecting-to party id combined presentation */ 09474 case AST_REDIRECTING_TO_ID_PRESENTATION: 09475 if (ie_len != 1) { 09476 ast_log(LOG_WARNING, "Invalid redirecting-to combined presentation (%u)\n", 09477 (unsigned) ie_len); 09478 break; 09479 } 09480 to_combined_presentation = data[pos]; 09481 got_to_combined_presentation = 1; 09482 break; 09483 /* Redirecting-to party id subaddress */ 09484 case AST_REDIRECTING_TO_SUBADDRESS: 09485 ast_free(redirecting->to.subaddress.str); 09486 redirecting->to.subaddress.str = ast_malloc(ie_len + 1); 09487 if (redirecting->to.subaddress.str) { 09488 memcpy(redirecting->to.subaddress.str, data + pos, ie_len); 09489 redirecting->to.subaddress.str[ie_len] = 0; 09490 } 09491 break; 09492 case AST_REDIRECTING_TO_SUBADDRESS_TYPE: 09493 if (ie_len != 1) { 09494 ast_log(LOG_WARNING, "Invalid redirecting-to type of subaddress (%u)\n", 09495 (unsigned) ie_len); 09496 break; 09497 } 09498 redirecting->to.subaddress.type = data[pos]; 09499 break; 09500 case AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN: 09501 if (ie_len != 1) { 09502 ast_log(LOG_WARNING, 09503 "Invalid redirecting-to subaddress odd-even indicator (%u)\n", 09504 (unsigned) ie_len); 09505 break; 09506 } 09507 redirecting->to.subaddress.odd_even_indicator = data[pos]; 09508 break; 09509 case AST_REDIRECTING_TO_SUBADDRESS_VALID: 09510 if (ie_len != 1) { 09511 ast_log(LOG_WARNING, "Invalid redirecting-to subaddress valid (%u)\n", 09512 (unsigned) ie_len); 09513 break; 09514 } 09515 redirecting->to.subaddress.valid = data[pos]; 09516 break; 09517 /* Redirecting-to party id tag */ 09518 case AST_REDIRECTING_TO_TAG: 09519 ast_free(redirecting->to.tag); 09520 redirecting->to.tag = ast_malloc(ie_len + 1); 09521 if (redirecting->to.tag) { 09522 memcpy(redirecting->to.tag, data + pos, ie_len); 09523 redirecting->to.tag[ie_len] = 0; 09524 } 09525 break; 09526 /* Redirecting reason */ 09527 case AST_REDIRECTING_REASON: 09528 if (ie_len != sizeof(value)) { 09529 ast_log(LOG_WARNING, "Invalid redirecting reason (%u)\n", 09530 (unsigned) ie_len); 09531 break; 09532 } 09533 memcpy(&value, data + pos, sizeof(value)); 09534 redirecting->reason = ntohl(value); 09535 break; 09536 /* Redirecting count */ 09537 case AST_REDIRECTING_COUNT: 09538 if (ie_len != sizeof(value)) { 09539 ast_log(LOG_WARNING, "Invalid redirecting count (%u)\n", 09540 (unsigned) ie_len); 09541 break; 09542 } 09543 memcpy(&value, data + pos, sizeof(value)); 09544 redirecting->count = ntohl(value); 09545 break; 09546 /* Redirecting unknown element */ 09547 default: 09548 ast_log(LOG_DEBUG, "Unknown redirecting element: %u (%u)\n", 09549 (unsigned) ie_id, (unsigned) ie_len); 09550 break; 09551 } 09552 } 09553 09554 switch (frame_version) { 09555 case 1: 09556 /* 09557 * The other end is an earlier version that we need to adjust 09558 * for compatibility. 09559 */ 09560 redirecting->from.name.valid = 1; 09561 redirecting->from.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1; 09562 redirecting->from.number.valid = 1; 09563 if (got_from_combined_presentation) { 09564 redirecting->from.name.presentation = from_combined_presentation; 09565 redirecting->from.number.presentation = from_combined_presentation; 09566 } 09567 09568 redirecting->to.name.valid = 1; 09569 redirecting->to.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1; 09570 redirecting->to.number.valid = 1; 09571 if (got_to_combined_presentation) { 09572 redirecting->to.name.presentation = to_combined_presentation; 09573 redirecting->to.number.presentation = to_combined_presentation; 09574 } 09575 break; 09576 case 2: 09577 /* The other end is at the same level as we are. */ 09578 break; 09579 default: 09580 /* 09581 * The other end is newer than we are. 09582 * We need to assume that they are compatible with us. 09583 */ 09584 ast_log(LOG_DEBUG, "Redirecting frame has newer version: %u\n", 09585 (unsigned) frame_version); 09586 break; 09587 } 09588 09589 return 0; 09590 }
struct ast_channel* ast_request | ( | const char * | type, | |
format_t | format, | |||
const struct ast_channel * | requestor, | |||
void * | data, | |||
int * | status | |||
) | [read] |
Requests a channel.
type | type of channel to request | |
format | requested channel format (codec) | |
requestor | channel asking for data | |
data | data to pass to the channel requester (Should be treated as const char *) | |
status | status |
Request a channel of a given type, with data as optional information used by the low level module
NULL | failure | |
non-NULL | channel on success |
Definition at line 5695 of file channel.c.
References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_NOSUCHDRIVER, AST_CAUSE_NOTDEFINED, ast_channel_release(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_translator_best_choice(), ast_channel_tech::capabilities, capabilities, LOG_WARNING, ast_channel_tech::requester, set_security_requirements(), chanlist::tech, and ast_channel_tech::type.
Referenced by __ast_request_and_dial(), ast_call_forward(), begin_dial_channel(), build_conf(), chanavail_exec(), conf_run(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), meetme_menu_admin_extended(), play_sound_file(), ring_entry(), and wait_for_answer().
05696 { 05697 struct chanlist *chan; 05698 struct ast_channel *c; 05699 format_t capabilities; 05700 format_t fmt; 05701 int res; 05702 int foo; 05703 format_t videoformat = format & AST_FORMAT_VIDEO_MASK; 05704 format_t textformat = format & AST_FORMAT_TEXT_MASK; 05705 05706 if (!cause) 05707 cause = &foo; 05708 *cause = AST_CAUSE_NOTDEFINED; 05709 05710 if (AST_RWLIST_RDLOCK(&backends)) { 05711 ast_log(LOG_WARNING, "Unable to lock technology backend list\n"); 05712 return NULL; 05713 } 05714 05715 AST_RWLIST_TRAVERSE(&backends, chan, list) { 05716 if (strcasecmp(type, chan->tech->type)) 05717 continue; 05718 05719 capabilities = chan->tech->capabilities; 05720 fmt = format & AST_FORMAT_AUDIO_MASK; 05721 if (fmt) { 05722 /* We have audio - is it possible to connect the various calls to each other? 05723 (Avoid this check for calls without audio, like text+video calls) 05724 */ 05725 res = ast_translator_best_choice(&fmt, &capabilities); 05726 if (res < 0) { 05727 char tmp1[256], tmp2[256]; 05728 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %s) to %s\n", type, 05729 ast_getformatname_multiple(tmp1, sizeof(tmp1), chan->tech->capabilities), 05730 ast_getformatname_multiple(tmp2, sizeof(tmp2), format)); 05731 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05732 AST_RWLIST_UNLOCK(&backends); 05733 return NULL; 05734 } 05735 } 05736 AST_RWLIST_UNLOCK(&backends); 05737 if (!chan->tech->requester) 05738 return NULL; 05739 05740 if (!(c = chan->tech->requester(type, capabilities | videoformat | textformat, requestor, data, cause))) 05741 return NULL; 05742 05743 if (set_security_requirements(requestor, c)) { 05744 ast_log(LOG_WARNING, "Setting security requirements failed\n"); 05745 c = ast_channel_release(c); 05746 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05747 return NULL; 05748 } 05749 05750 /* no need to generate a Newchannel event here; it is done in the channel_alloc call */ 05751 return c; 05752 } 05753 05754 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type); 05755 *cause = AST_CAUSE_NOSUCHDRIVER; 05756 AST_RWLIST_UNLOCK(&backends); 05757 05758 return NULL; 05759 }
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 | |||
) | [read] |
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 5650 of file channel.c.
References __ast_request_and_dial().
Referenced by ast_pbx_outgoing_exten(), and generic_recall().
05651 { 05652 return __ast_request_and_dial(type, format, requestor, data, timeout, outstate, cidnum, cidname, NULL); 05653 }
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. This should never be less than zero. |
Waits for a specified amount of time, servicing the channel as required.
Definition at line 1916 of file channel.c.
References ast_safe_sleep_conditional().
Referenced by __analog_ss_thread(), adsi_transmit_message_full(), alarmreceiver_exec(), analog_ss_thread(), ast_dtmf_stream(), ast_senddigit(), builtin_atxfer(), builtin_parkcall(), conf_run(), dial_trunk(), dictate_exec(), disa_exec(), flash_exec(), handle_callforward_button(), login_exec(), mgcp_ss(), milliwatt_exec(), misdn_check_l2l1(), old_milliwatt_exec(), park_call_exec(), pbx_builtin_wait(), play_moh_exec(), playtone(), privacy_exec(), receive_ademco_contact_id(), skinny_ss(), testclient_exec(), testserver_exec(), try_calling(), wait_for_hangup(), wait_moh_exec(), waituntil_exec(), and zapateller_exec().
01917 { 01918 return ast_safe_sleep_conditional(chan, ms, NULL, NULL); 01919 }
int ast_safe_sleep_conditional | ( | struct ast_channel * | chan, | |
int | timeout_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 |
Waits for a specified amount of time, servicing the channel as required. If cond returns 0, this function returns.
Definition at line 1845 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_remaining_ms(), ast_tvnow(), ast_waitfor(), cond, and ast_channel::generatordata.
Referenced by ast_safe_sleep(), and login_exec().
01846 { 01847 struct ast_frame *f; 01848 struct ast_silence_generator *silgen = NULL; 01849 int res = 0; 01850 struct timeval start; 01851 int ms; 01852 AST_LIST_HEAD_NOLOCK(, ast_frame) deferred_frames; 01853 01854 AST_LIST_HEAD_INIT_NOLOCK(&deferred_frames); 01855 01856 /* If no other generator is present, start silencegen while waiting */ 01857 if (ast_opt_transmit_silence && !chan->generatordata) { 01858 silgen = ast_channel_start_silence_generator(chan); 01859 } 01860 01861 start = ast_tvnow(); 01862 while ((ms = ast_remaining_ms(start, timeout_ms))) { 01863 struct ast_frame *dup_f = NULL; 01864 01865 if (cond && ((*cond)(data) == 0)) { 01866 break; 01867 } 01868 ms = ast_waitfor(chan, ms); 01869 if (ms < 0) { 01870 res = -1; 01871 break; 01872 } 01873 if (ms > 0) { 01874 f = ast_read(chan); 01875 if (!f) { 01876 res = -1; 01877 break; 01878 } 01879 01880 if (!ast_is_deferrable_frame(f)) { 01881 ast_frfree(f); 01882 continue; 01883 } 01884 01885 if ((dup_f = ast_frisolate(f))) { 01886 if (dup_f != f) { 01887 ast_frfree(f); 01888 } 01889 AST_LIST_INSERT_HEAD(&deferred_frames, dup_f, frame_list); 01890 } 01891 } 01892 } 01893 01894 /* stop silgen if present */ 01895 if (silgen) { 01896 ast_channel_stop_silence_generator(chan, silgen); 01897 } 01898 01899 /* We need to free all the deferred frames, but we only need to 01900 * queue the deferred frames if there was no error and no 01901 * hangup was received 01902 */ 01903 ast_channel_lock(chan); 01904 while ((f = AST_LIST_REMOVE_HEAD(&deferred_frames, frame_list))) { 01905 if (!res) { 01906 ast_queue_frame_head(chan, f); 01907 } 01908 ast_frfree(f); 01909 } 01910 ast_channel_unlock(chan); 01911 01912 return res; 01913 }
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 4774 of file channel.c.
References AST_DEFAULT_EMULATE_DTMF_DURATION, ast_safe_sleep(), ast_senddigit_begin(), ast_senddigit_end(), ast_channel_tech::send_digit_begin, and ast_channel::tech.
Referenced by ast_dtmf_stream(), dial_exec_full(), and manager_play_dtmf().
04775 { 04776 if (chan->tech->send_digit_begin) { 04777 ast_senddigit_begin(chan, digit); 04778 ast_safe_sleep(chan, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION)); 04779 } 04780 04781 return ast_senddigit_end(chan, digit, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION)); 04782 }
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 4705 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_debug, ast_playtones_start(), ast_tvnow(), ast_channel_tech::send_digit_begin, ast_channel::sending_dtmf_digit, ast_channel::sending_dtmf_tv, and ast_channel::tech.
Referenced by agent_digit_begin(), ast_senddigit(), and ast_write().
04706 { 04707 /* Device does not support DTMF tones, lets fake 04708 * it by doing our own generation. */ 04709 static const char * const dtmf_tones[] = { 04710 "941+1336", /* 0 */ 04711 "697+1209", /* 1 */ 04712 "697+1336", /* 2 */ 04713 "697+1477", /* 3 */ 04714 "770+1209", /* 4 */ 04715 "770+1336", /* 5 */ 04716 "770+1477", /* 6 */ 04717 "852+1209", /* 7 */ 04718 "852+1336", /* 8 */ 04719 "852+1477", /* 9 */ 04720 "697+1633", /* A */ 04721 "770+1633", /* B */ 04722 "852+1633", /* C */ 04723 "941+1633", /* D */ 04724 "941+1209", /* * */ 04725 "941+1477" /* # */ 04726 }; 04727 04728 if (!chan->tech->send_digit_begin) 04729 return 0; 04730 04731 ast_channel_lock(chan); 04732 chan->sending_dtmf_digit = digit; 04733 chan->sending_dtmf_tv = ast_tvnow(); 04734 ast_channel_unlock(chan); 04735 04736 if (!chan->tech->send_digit_begin(chan, digit)) 04737 return 0; 04738 04739 if (digit >= '0' && digit <='9') 04740 ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0); 04741 else if (digit >= 'A' && digit <= 'D') 04742 ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0); 04743 else if (digit == '*') 04744 ast_playtones_start(chan, 0, dtmf_tones[14], 0); 04745 else if (digit == '#') 04746 ast_playtones_start(chan, 0, dtmf_tones[15], 0); 04747 else { 04748 /* not handled */ 04749 ast_debug(1, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name); 04750 } 04751 04752 return 0; 04753 }
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 4755 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_playtones_stop(), ast_channel::generator, ast_channel_tech::send_digit_end, ast_channel::sending_dtmf_digit, and ast_channel::tech.
Referenced by agent_digit_end(), ast_bridge_end_dtmf(), ast_senddigit(), and ast_write().
04756 { 04757 int res = -1; 04758 04759 ast_channel_lock(chan); 04760 if (chan->sending_dtmf_digit == digit) { 04761 chan->sending_dtmf_digit = 0; 04762 } 04763 ast_channel_unlock(chan); 04764 04765 if (chan->tech->send_digit_end) 04766 res = chan->tech->send_digit_end(chan, digit, duration); 04767 04768 if (res && chan->generator) 04769 ast_playtones_stop(chan); 04770 04771 return 0; 04772 }
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 |
Write text to a display on a channel
0 | on success | |
-1 | on failure |
Definition at line 4687 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_test_flag, CHECK_BLOCKING, ast_channel_tech::send_text, and ast_channel::tech.
Referenced by action_sendtext(), agent_sendtext(), handle_sendtext(), and sendtext_exec().
04688 { 04689 int res = 0; 04690 04691 ast_channel_lock(chan); 04692 /* Stop if we're a zombie or need a soft hangup */ 04693 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 04694 ast_channel_unlock(chan); 04695 return -1; 04696 } 04697 CHECK_BLOCKING(chan); 04698 if (chan->tech->send_text) 04699 res = chan->tech->send_text(chan, text); 04700 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04701 ast_channel_unlock(chan); 04702 return res; 04703 }
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.
Definition at line 7051 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, ast_party_caller::id, ast_party_id::name, ast_party_id::number, report_new_callerid(), ast_party_name::str, ast_party_number::str, ast_party_name::valid, and ast_party_number::valid.
Referenced by __analog_ss_thread(), __ast_request_and_dial(), analog_ss_thread(), cb_events(), disa_exec(), get_pai(), get_rpid(), handle_setcallerid(), mgcp_ss(), privacy_exec(), ring_entry(), skinny_newcall(), and socket_process().
07052 { 07053 ast_channel_lock(chan); 07054 07055 if (cid_num) { 07056 chan->caller.id.number.valid = 1; 07057 ast_free(chan->caller.id.number.str); 07058 chan->caller.id.number.str = ast_strdup(cid_num); 07059 } 07060 if (cid_name) { 07061 chan->caller.id.name.valid = 1; 07062 ast_free(chan->caller.id.name.str); 07063 chan->caller.id.name.str = ast_strdup(cid_name); 07064 } 07065 if (cid_ani) { 07066 chan->caller.ani.number.valid = 1; 07067 ast_free(chan->caller.ani.number.str); 07068 chan->caller.ani.number.str = ast_strdup(cid_ani); 07069 } 07070 if (chan->cdr) { 07071 ast_cdr_setcid(chan->cdr, chan); 07072 } 07073 07074 report_new_callerid(chan); 07075 07076 ast_channel_unlock(chan); 07077 }
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 |
Hangupsource is generally the channel name that caused the bridge to be hung up, but it can also be other things such as "dialplan/agi" This can then be logged in the CDR or CEL
Definition at line 2769 of file channel.c.
References ast_bridged_channel(), ast_channel_lock, ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_string_field_set, ast_strlen_zero(), and ast_channel::bridge.
Referenced by __dahdi_exception(), analog_exception(), func_channel_write_real(), handle_hangup(), pbx_builtin_hangup(), set_hangup_source_and_cause(), and sip_queue_hangup_cause().
02770 { 02771 struct ast_channel *bridge; 02772 02773 ast_channel_lock(chan); 02774 if (force || ast_strlen_zero(chan->hangupsource)) { 02775 ast_string_field_set(chan, hangupsource, source); 02776 } 02777 bridge = ast_bridged_channel(chan); 02778 if (bridge) { 02779 ast_channel_ref(bridge); 02780 } 02781 ast_channel_unlock(chan); 02782 02783 if (bridge) { 02784 ast_channel_lock(bridge); 02785 if (force || ast_strlen_zero(bridge->hangupsource)) { 02786 ast_string_field_set(bridge, hangupsource, source); 02787 } 02788 ast_channel_unlock(bridge); 02789 ast_channel_unref(bridge); 02790 } 02791 }
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 5301 of file channel.c.
References ast_channel::rawreadformat, ast_channel::readformat, ast_channel::readtrans, and set_format().
Referenced by __ast_play_and_record(), __oh323_update_info(), adsi_transmit_message_full(), agent_call(), alarmreceiver_exec(), ast_channel_make_compatible_helper(), ast_do_masquerade(), background_detect_exec(), bridge_channel_join(), bridge_make_compatible(), build_conf(), conf_run(), dictate_exec(), do_waiting(), eagi_exec(), echo_exec(), generic_fax_exec(), gtalk_rtp_read(), handle_recordfile(), handle_speechrecognize(), ices_exec(), isAnsweringMachine(), jack_exec(), jingle_rtp_read(), login_exec(), measurenoise(), meetme_menu_admin_extended(), mgcp_rtp_read(), oh323_rtp_read(), old_milliwatt_exec(), process_sdp(), record_exec(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_process(), speech_background(), transmit_audio(), and unistim_rtp_read().
05302 { 05303 return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat, 05304 &chan->readtrans, 0); 05305 }
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 |
Variable names can be for a regular channel variable or a dialplan function that has the ability to be written to.
Definition at line 8261 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().
08262 { 08263 struct ast_variable *cur; 08264 08265 for (cur = vars; cur; cur = cur->next) 08266 pbx_builtin_setvar_helper(chan, cur->name, cur->value); 08267 }
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 5307 of file channel.c.
References ast_channel::rawwriteformat, set_format(), ast_channel::writeformat, and ast_channel::writetrans.
Referenced by __oh323_update_info(), adsi_transmit_message_full(), agent_call(), alarmreceiver_exec(), ast_channel_make_compatible_helper(), ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_do_masquerade(), ast_openstream_full(), ast_stopstream(), ast_write(), bridge_channel_join(), bridge_make_compatible(), build_conf(), chanspy_exec(), conf_run(), dahdiscan_exec(), echo_exec(), extenspy_exec(), generic_fax_exec(), gtalk_rtp_read(), jack_exec(), jingle_rtp_read(), linear_alloc(), linear_release(), login_exec(), meetme_menu_admin_extended(), mgcp_rtp_read(), moh_alloc(), moh_files_release(), moh_release(), mp3_exec(), NBScat_exec(), oh323_rtp_read(), old_milliwatt_exec(), playtones_alloc(), playtones_release(), process_sdp(), send_waveform_to_channel(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_process(), tonepair_alloc(), tonepair_release(), transmit_audio(), and unistim_rtp_read().
05308 { 05309 return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat, 05310 &chan->writetrans, 1); 05311 }
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 |
If timers are supported, force a scheduled expiration on the timer fd, at which point we call the callback function / data
Definition at line 3557 of file channel.c.
References ast_settimeout_full().
Referenced by ast_activate_generator(), ast_readaudio_callback(), deactivate_generator_nolock(), and filestream_close().
03558 { 03559 return ast_settimeout_full(c, rate, func, data, 0); 03560 }
int ast_settimeout_full | ( | struct ast_channel * | c, | |
unsigned int | rate, | |||
int(*)(const void *data) | func, | |||
void * | data, | |||
unsigned int | is_ao2_obj | |||
) |
Definition at line 3562 of file channel.c.
References ao2_ref, ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_debug, AST_FLAG_TIMINGDATA_IS_AO2_OBJ, ast_set_flag, ast_test_flag, ast_timer_get_max_rate(), ast_timer_set_rate(), AST_TIMING_FD, ast_channel::fdno, ast_channel::timer, ast_channel::timingdata, ast_channel::timingfd, and ast_channel::timingfunc.
Referenced by ast_readaudio_callback(), and ast_settimeout().
03563 { 03564 int res; 03565 unsigned int real_rate = rate, max_rate; 03566 03567 ast_channel_lock(c); 03568 03569 if (c->timingfd == -1) { 03570 ast_channel_unlock(c); 03571 return -1; 03572 } 03573 03574 if (!func) { 03575 rate = 0; 03576 data = NULL; 03577 } 03578 03579 if (rate && rate > (max_rate = ast_timer_get_max_rate(c->timer))) { 03580 real_rate = max_rate; 03581 } 03582 03583 ast_debug(1, "Scheduling timer at (%u requested / %u actual) timer ticks per second\n", rate, real_rate); 03584 03585 res = ast_timer_set_rate(c->timer, real_rate); 03586 03587 if (c->timingdata && ast_test_flag(c, AST_FLAG_TIMINGDATA_IS_AO2_OBJ)) { 03588 ao2_ref(c->timingdata, -1); 03589 } 03590 03591 c->timingfunc = func; 03592 c->timingdata = data; 03593 03594 if (data && is_ao2_obj) { 03595 ao2_ref(data, 1); 03596 ast_set_flag(c, AST_FLAG_TIMINGDATA_IS_AO2_OBJ); 03597 } else { 03598 ast_clear_flag(c, AST_FLAG_TIMINGDATA_IS_AO2_OBJ); 03599 } 03600 03601 if (func == NULL && rate == 0 && c->fdno == AST_TIMING_FD) { 03602 /* Clearing the timing func and setting the rate to 0 03603 * means that we don't want to be reading from the timingfd 03604 * any more. Setting c->fdno to -1 means we won't have any 03605 * errant reads from the timingfd, meaning we won't potentially 03606 * miss any important frames. 03607 */ 03608 c->fdno = -1; 03609 } 03610 03611 ast_channel_unlock(c); 03612 03613 return res; 03614 }
int ast_shutting_down | ( | void | ) |
Returns non-zero if Asterisk is being shut down.
Definition at line 865 of file channel.c.
Referenced by handle_request_options().
00866 { 00867 return shutting_down; 00868 }
int ast_softhangup | ( | struct ast_channel * | chan, | |
int | cause | |||
) |
Softly hangup up a channel.
chan | channel to be soft-hung-up | |
reason | an AST_SOFTHANGUP_* reason code |
Call the protocol layer, but don't destroy the channel structure (use this if you are trying to safely hangup a channel managed by another thread.
Definition at line 2746 of file channel.c.
References ast_channel_lock, ast_channel_unlock, and ast_softhangup_nolock().
Referenced by __analog_handle_event(), __ast_module_user_hangup_all(), __ast_pbx_run(), __unload_module(), agent_hangup(), agent_logoff(), agent_read(), ast_bridge_call(), ast_channel_softhangup_cb(), ast_dial_join(), cc_generic_agent_stop_ringing(), conf_free(), dahdi_handle_event(), handle_hangup(), handle_softhangup(), login_exec(), manager_park(), mgcp_pktcgate_remove(), read_agent_config(), sla_handle_hold_event(), softhangup_exec(), start_spying(), startmon(), and unload_module().
02747 { 02748 int res; 02749 02750 ast_channel_lock(chan); 02751 res = ast_softhangup_nolock(chan, cause); 02752 ast_channel_unlock(chan); 02753 02754 return res; 02755 }
int ast_softhangup_nolock | ( | struct ast_channel * | chan, | |
int | cause | |||
) |
Softly hangup up a channel (no channel lock).
chan | channel to be soft-hung-up | |
reason | an AST_SOFTHANGUP_* reason code |
Definition at line 2733 of file channel.c.
References ast_channel::_softhangup, ast_debug, AST_FLAG_BLOCKING, ast_null_frame, ast_queue_frame(), ast_test_flag, and ast_channel::blocker.
Referenced by __analog_handle_event(), action_hangup(), analog_attempt_transfer(), ast_async_goto(), ast_softhangup(), attempt_transfer(), check_pendings(), check_rtp_timeout(), dahdi_softhangup_all(), gosub_run(), oh323_indicate(), proc_session_timer(), sip_indicate(), and skinny_indicate().
02734 { 02735 ast_debug(1, "Soft-Hanging up channel '%s'\n", chan->name); 02736 /* Inform channel driver that we need to be hung up, if it cares */ 02737 chan->_softhangup |= cause; 02738 ast_queue_frame(chan, &ast_null_frame); 02739 /* Interrupt any poll call or such */ 02740 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) 02741 pthread_kill(chan->blocker, SIGURG); 02742 return 0; 02743 }
const char* ast_state2str | ( | enum ast_channel_state | state | ) |
Gives the string form of a given channel state.
ast_channel_state | state to get the name of |
Definition at line 1007 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(), action_status(), 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().
01008 { 01009 char *buf; 01010 01011 switch (state) { 01012 case AST_STATE_DOWN: 01013 return "Down"; 01014 case AST_STATE_RESERVED: 01015 return "Rsrvd"; 01016 case AST_STATE_OFFHOOK: 01017 return "OffHook"; 01018 case AST_STATE_DIALING: 01019 return "Dialing"; 01020 case AST_STATE_RING: 01021 return "Ring"; 01022 case AST_STATE_RINGING: 01023 return "Ringing"; 01024 case AST_STATE_UP: 01025 return "Up"; 01026 case AST_STATE_BUSY: 01027 return "Busy"; 01028 case AST_STATE_DIALING_OFFHOOK: 01029 return "Dialing Offhook"; 01030 case AST_STATE_PRERING: 01031 return "Pre-ring"; 01032 default: 01033 if (!(buf = ast_threadstorage_get(&state2str_threadbuf, STATE2STR_BUFSIZE))) 01034 return "Unknown"; 01035 snprintf(buf, STATE2STR_BUFSIZE, "Unknown (%u)", state); 01036 return buf; 01037 } 01038 }
int ast_str2cause | ( | const char * | name | ) |
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 7969 of file channel.c.
References ast_frfree, ast_read(), ast_tonepair_start(), ast_waitfor(), and ast_channel::generatordata.
Referenced by zapateller_exec().
07970 { 07971 int res; 07972 07973 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol))) 07974 return res; 07975 07976 /* Give us some wiggle room */ 07977 while (chan->generatordata && ast_waitfor(chan, 100) >= 0) { 07978 struct ast_frame *f = ast_read(chan); 07979 if (f) 07980 ast_frfree(f); 07981 else 07982 return -1; 07983 } 07984 return 0; 07985 }
int ast_tonepair_start | ( | struct ast_channel * | chan, | |
int | freq1, | |||
int | freq2, | |||
int | duration, | |||
int | vol | |||
) |
Start a tone going
Definition at line 7951 of file channel.c.
References ast_activate_generator(), tonepair_def::duration, tonepair_def::freq1, tonepair_def::freq2, and tonepair_def::vol.
Referenced by ast_tonepair(), pbx_builtin_waitexten(), play_dialtone(), and sendnoise().
void ast_tonepair_stop | ( | struct ast_channel * | chan | ) |
Stop a tone from playing
Definition at line 7964 of file channel.c.
References ast_deactivate_generator().
Referenced by sendnoise().
07965 { 07966 ast_deactivate_generator(chan); 07967 }
int ast_transfer | ( | struct ast_channel * | chan, | |
char * | dest | |||
) |
Transfer a channel (if supported).
-1 | on error | |
0 | if not supported | |
1 | if supported and requested |
chan | current channel | |
dest | destination extension for transfer |
Transfer a channel (if supported).
Called by:
Definition at line 5788 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(), ast_frame::data, ast_frame::frametype, ast_frame_subclass::integer, ast_frame::ptr, ast_frame::subclass, ast_channel::tech, and ast_channel_tech::transfer.
Referenced by transfer_exec().
05789 { 05790 int res = -1; 05791 05792 /* Stop if we're a zombie or need a soft hangup */ 05793 ast_channel_lock(chan); 05794 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) { 05795 if (chan->tech->transfer) { 05796 res = chan->tech->transfer(chan, dest); 05797 if (!res) 05798 res = 1; 05799 } else 05800 res = 0; 05801 } 05802 ast_channel_unlock(chan); 05803 05804 if (res <= 0) { 05805 return res; 05806 } 05807 05808 for (;;) { 05809 struct ast_frame *fr; 05810 05811 res = ast_waitfor(chan, -1); 05812 05813 if (res < 0 || !(fr = ast_read(chan))) { 05814 res = -1; 05815 break; 05816 } 05817 05818 if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_TRANSFER) { 05819 enum ast_control_transfer *message = fr->data.ptr; 05820 05821 if (*message == AST_TRANSFER_SUCCESS) { 05822 res = 1; 05823 } else { 05824 res = -1; 05825 } 05826 05827 ast_frfree(fr); 05828 break; 05829 } 05830 05831 ast_frfree(fr); 05832 } 05833 05834 return res; 05835 }
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 1041 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(), and oh323_call().
01042 { 01043 switch (transfercapability) { 01044 case AST_TRANS_CAP_SPEECH: 01045 return "SPEECH"; 01046 case AST_TRANS_CAP_DIGITAL: 01047 return "DIGITAL"; 01048 case AST_TRANS_CAP_RESTRICTED_DIGITAL: 01049 return "RESTRICTED_DIGITAL"; 01050 case AST_TRANS_CAP_3_1K_AUDIO: 01051 return "3K1AUDIO"; 01052 case AST_TRANS_CAP_DIGITAL_W_TONES: 01053 return "DIGITAL_W_TONES"; 01054 case AST_TRANS_CAP_VIDEO: 01055 return "VIDEO"; 01056 default: 01057 return "UNKNOWN"; 01058 } 01059 }
int ast_undestroyed_channels | ( | void | ) |
Definition at line 853 of file channel.c.
References ast_atomic_fetchadd_int().
Referenced by can_safely_quit().
00854 { 00855 return ast_atomic_fetchadd_int(&chancount, 0); 00856 }
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 |
Wait for input on a channel for a given # of milliseconds (<0 for indefinite).
< | 0 on failure | |
0 | if nothing ever arrived | |
the | # of ms remaining otherwise |
Definition at line 3539 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_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(), record_exec(), 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().
03540 { 03541 if (ms < 0) { 03542 do { 03543 ms = 100000; 03544 ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms); 03545 } while (!ms); 03546 } else { 03547 ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms); 03548 } 03549 return ms; 03550 }
struct ast_channel* ast_waitfor_n | ( | struct ast_channel ** | chan, | |
int | n, | |||
int * | ms | |||
) | [read] |
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 3534 of file channel.c.
References ast_waitfor_nandfds().
Referenced by ast_generic_bridge(), ast_udptl_bridge(), autoservice_run(), dahdi_bridge(), dial_exec_full(), feature_request_and_dial(), generic_thread_loop(), iax2_bridge(), local_bridge_loop(), misdn_bridge(), monitor_dial(), remote_bridge_loop(), wait_for_answer(), and wait_for_winner().
03535 { 03536 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms); 03537 }
int ast_waitfor_n_fd | ( | int * | fds, | |
int | n, | |||
int * | ms, | |||
int * | exception | |||
) |
Waits for input on an fd.
Definition at line 3176 of file channel.c.
References ast_waitfor_nandfds().
Referenced by dundi_lookup_internal(), dundi_precache_internal(), and softmix_bridge_thread().
03177 { 03178 int winner = -1; 03179 ast_waitfor_nandfds(NULL, 0, fds, n, exception, &winner, ms); 03180 return winner; 03181 }
struct ast_channel* ast_waitfor_nandfds | ( | struct ast_channel ** | c, | |
int | n, | |||
int * | fds, | |||
int | nfds, | |||
int * | exception, | |||
int * | outfd, | |||
int * | ms | |||
) | [read] |
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 |
Big momma function here. Wait for activity on any of the n channels, or any of the nfds file descriptors.
Definition at line 3188 of file channel.c.
References ast_channel::_softhangup, ast_add_fd(), ast_alloca, ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, AST_MAX_FDS, ast_poll, ast_set_flag, AST_SOFTHANGUP_TIMEOUT, ast_test_suite_event_notify, ast_tvcmp(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), CHECK_BLOCKING, errno, ast_channel::fdno, and name.
Referenced by ast_waitfor(), ast_waitfor_n(), ast_waitfor_n_fd(), ast_waitfordigit_full(), bridge_channel_join_multithreaded(), conf_run(), eivr_comm(), find_cache(), generic_fax_exec(), multiplexed_thread_function(), run_agi(), and waitstream_core().
03191 { 03192 struct timeval start = { 0 , 0 }; 03193 struct pollfd *pfds = NULL; 03194 int res; 03195 long rms; 03196 int x, y, max; 03197 int sz; 03198 struct timeval now = { 0, 0 }; 03199 struct timeval whentohangup = { 0, 0 }, diff; 03200 struct ast_channel *winner = NULL; 03201 struct fdmap { 03202 int chan; 03203 int fdno; 03204 } *fdmap = NULL; 03205 03206 if (outfd) 03207 *outfd = -99999; 03208 if (exception) 03209 *exception = 0; 03210 03211 if ((sz = n * AST_MAX_FDS + nfds)) { 03212 pfds = ast_alloca(sizeof(*pfds) * sz); 03213 fdmap = ast_alloca(sizeof(*fdmap) * sz); 03214 } else { 03215 /* nothing to allocate and no FDs to check */ 03216 return NULL; 03217 } 03218 03219 /* Perform any pending masquerades */ 03220 for (x = 0; x < n; x++) { 03221 while (c[x]->masq) { 03222 ast_do_masquerade(c[x]); 03223 } 03224 03225 ast_channel_lock(c[x]); 03226 if (!ast_tvzero(c[x]->whentohangup)) { 03227 if (ast_tvzero(whentohangup)) 03228 now = ast_tvnow(); 03229 diff = ast_tvsub(c[x]->whentohangup, now); 03230 if (diff.tv_sec < 0 || ast_tvzero(diff)) { 03231 ast_test_suite_event_notify("HANGUP_TIME", "Channel: %s", c[x]->name); 03232 /* Should already be hungup */ 03233 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 03234 ast_channel_unlock(c[x]); 03235 return c[x]; 03236 } 03237 if (ast_tvzero(whentohangup) || ast_tvcmp(diff, whentohangup) < 0) 03238 whentohangup = diff; 03239 } 03240 ast_channel_unlock(c[x]); 03241 } 03242 /* Wait full interval */ 03243 rms = *ms; 03244 /* INT_MAX, not LONG_MAX, because it matters on 64-bit */ 03245 if (!ast_tvzero(whentohangup) && whentohangup.tv_sec < INT_MAX / 1000) { 03246 rms = whentohangup.tv_sec * 1000 + whentohangup.tv_usec / 1000; /* timeout in milliseconds */ 03247 if (*ms >= 0 && *ms < rms) { /* original *ms still smaller */ 03248 rms = *ms; 03249 } 03250 } else if (!ast_tvzero(whentohangup) && rms < 0) { 03251 /* Tiny corner case... call would need to last >24 days */ 03252 rms = INT_MAX; 03253 } 03254 /* 03255 * Build the pollfd array, putting the channels' fds first, 03256 * followed by individual fds. Order is important because 03257 * individual fd's must have priority over channel fds. 03258 */ 03259 max = 0; 03260 for (x = 0; x < n; x++) { 03261 for (y = 0; y < AST_MAX_FDS; y++) { 03262 fdmap[max].fdno = y; /* fd y is linked to this pfds */ 03263 fdmap[max].chan = x; /* channel x is linked to this pfds */ 03264 max += ast_add_fd(&pfds[max], c[x]->fds[y]); 03265 } 03266 CHECK_BLOCKING(c[x]); 03267 } 03268 /* Add the individual fds */ 03269 for (x = 0; x < nfds; x++) { 03270 fdmap[max].chan = -1; 03271 max += ast_add_fd(&pfds[max], fds[x]); 03272 } 03273 03274 if (*ms > 0) 03275 start = ast_tvnow(); 03276 03277 if (sizeof(int) == 4) { /* XXX fix timeout > 600000 on linux x86-32 */ 03278 do { 03279 int kbrms = rms; 03280 if (kbrms > 600000) 03281 kbrms = 600000; 03282 res = ast_poll(pfds, max, kbrms); 03283 if (!res) 03284 rms -= kbrms; 03285 } while (!res && (rms > 0)); 03286 } else { 03287 res = ast_poll(pfds, max, rms); 03288 } 03289 for (x = 0; x < n; x++) 03290 ast_clear_flag(c[x], AST_FLAG_BLOCKING); 03291 if (res < 0) { /* Simulate a timeout if we were interrupted */ 03292 if (errno != EINTR) 03293 *ms = -1; 03294 return NULL; 03295 } 03296 if (!ast_tvzero(whentohangup)) { /* if we have a timeout, check who expired */ 03297 now = ast_tvnow(); 03298 for (x = 0; x < n; x++) { 03299 if (!ast_tvzero(c[x]->whentohangup) && ast_tvcmp(c[x]->whentohangup, now) <= 0) { 03300 ast_test_suite_event_notify("HANGUP_TIME", "Channel: %s", c[x]->name); 03301 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 03302 if (winner == NULL) 03303 winner = c[x]; 03304 } 03305 } 03306 } 03307 if (res == 0) { /* no fd ready, reset timeout and done */ 03308 *ms = 0; /* XXX use 0 since we may not have an exact timeout. */ 03309 return winner; 03310 } 03311 /* 03312 * Then check if any channel or fd has a pending event. 03313 * Remember to check channels first and fds last, as they 03314 * must have priority on setting 'winner' 03315 */ 03316 for (x = 0; x < max; x++) { 03317 res = pfds[x].revents; 03318 if (res == 0) 03319 continue; 03320 if (fdmap[x].chan >= 0) { /* this is a channel */ 03321 winner = c[fdmap[x].chan]; /* override previous winners */ 03322 if (res & POLLPRI) 03323 ast_set_flag(winner, AST_FLAG_EXCEPTION); 03324 else 03325 ast_clear_flag(winner, AST_FLAG_EXCEPTION); 03326 winner->fdno = fdmap[x].fdno; 03327 } else { /* this is an fd */ 03328 if (outfd) 03329 *outfd = pfds[x].fd; 03330 if (exception) 03331 *exception = (res & POLLPRI) ? -1 : 0; 03332 winner = NULL; 03333 } 03334 } 03335 if (*ms > 0) { 03336 *ms -= ast_tvdiff_ms(ast_tvnow(), start); 03337 if (*ms < 0) 03338 *ms = 0; 03339 } 03340 return winner; 03341 }
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 (<0 for indefinite). |
Definition at line 3552 of file channel.c.
References ast_waitfordigit_full().
Referenced by __analog_ss_thread(), _while_exec(), adsi_get_cpeid(), adsi_get_cpeinfo(), adsi_print(), adsi_read_encoded_dtmf(), adsi_transmit_message_full(), advanced_options(), analog_my_getsigstr(), analog_ss_thread(), ast_app_dtget(), ast_control_streamfile(), ast_record_review(), bridge_channel_feature(), builtin_atxfer(), collect_digits(), common_exec(), cpeid_exec(), dialout(), directory_exec(), forward_message(), get_folder(), ivr_dispatch(), mgcp_ss(), my_getsigstr(), pbx_builtin_waitexten(), play_record_review(), 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(), wait_a_bit(), and wait_our_turn().
03553 { 03554 return ast_waitfordigit_full(c, ms, -1, -1); 03555 }
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 (<0 for indefinite). | |
audiofd | audio file descriptor to write to if audio frames are received | |
ctrlfd | control file descriptor to monitor for reading |
Definition at line 3616 of file channel.c.
References ast_check_hangup(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_FLAG_END_DTMF_ONLY, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_frfree, ast_log(), ast_read(), ast_remaining_ms(), ast_set_flag, ast_test_flag, ast_tvnow(), ast_waitfor_nandfds(), ast_frame::data, ast_frame::datalen, errno, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, ast_frame::ptr, and ast_frame::subclass.
Referenced by ast_readstring_full(), ast_waitfordigit(), handle_getoption(), and handle_waitfordigit().
03617 { 03618 struct timeval start = ast_tvnow(); 03619 int ms; 03620 03621 /* Stop if we're a zombie or need a soft hangup */ 03622 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 03623 return -1; 03624 03625 /* Only look for the end of DTMF, don't bother with the beginning and don't emulate things */ 03626 ast_set_flag(c, AST_FLAG_END_DTMF_ONLY); 03627 03628 /* Wait for a digit, no more than timeout_ms milliseconds total. 03629 * Or, wait indefinitely if timeout_ms is <0. 03630 */ 03631 while ((ms = ast_remaining_ms(start, timeout_ms))) { 03632 struct ast_channel *rchan; 03633 int outfd = -1; 03634 03635 errno = 0; 03636 /* While ast_waitfor_nandfds tries to help by reducing the timeout by how much was waited, 03637 * it is unhelpful if it waited less than a millisecond. 03638 */ 03639 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 03640 03641 if (!rchan && outfd < 0 && ms) { 03642 if (errno == 0 || errno == EINTR) 03643 continue; 03644 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 03645 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03646 return -1; 03647 } else if (outfd > -1) { 03648 /* The FD we were watching has something waiting */ 03649 ast_log(LOG_WARNING, "The FD we were waiting for has something waiting. Waitfordigit returning numeric 1\n"); 03650 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03651 return 1; 03652 } else if (rchan) { 03653 int res; 03654 struct ast_frame *f = ast_read(c); 03655 if (!f) 03656 return -1; 03657 03658 switch (f->frametype) { 03659 case AST_FRAME_DTMF_BEGIN: 03660 break; 03661 case AST_FRAME_DTMF_END: 03662 res = f->subclass.integer; 03663 ast_frfree(f); 03664 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03665 return res; 03666 case AST_FRAME_CONTROL: 03667 switch (f->subclass.integer) { 03668 case AST_CONTROL_HANGUP: 03669 ast_frfree(f); 03670 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03671 return -1; 03672 case AST_CONTROL_RINGING: 03673 case AST_CONTROL_ANSWER: 03674 case AST_CONTROL_SRCUPDATE: 03675 case AST_CONTROL_SRCCHANGE: 03676 case AST_CONTROL_CONNECTED_LINE: 03677 case AST_CONTROL_REDIRECTING: 03678 case AST_CONTROL_UPDATE_RTP_PEER: 03679 case AST_CONTROL_HOLD: 03680 case AST_CONTROL_UNHOLD: 03681 case -1: 03682 /* Unimportant */ 03683 break; 03684 default: 03685 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass.integer); 03686 break; 03687 } 03688 break; 03689 case AST_FRAME_VOICE: 03690 /* Write audio if appropriate */ 03691 if (audiofd > -1) { 03692 if (write(audiofd, f->data.ptr, f->datalen) < 0) { 03693 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 03694 } 03695 } 03696 default: 03697 /* Ignore */ 03698 break; 03699 } 03700 ast_frfree(f); 03701 } 03702 } 03703 03704 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03705 03706 return 0; /* Time is up */ 03707 }
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 4916 of file channel.c.
References ast_channel::_softhangup, apply_plc(), ast_audiohook_detach_list(), AST_AUDIOHOOK_DIRECTION_WRITE, ast_audiohook_write_list(), ast_audiohook_write_list_empty(), ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_CONTROL_UNHOLD, ast_deactivate_generator(), ast_debug, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_WRITE_INT, AST_FLAG_ZOMBIE, AST_FORMAT_AUDIO_MASK, ast_format_rate(), AST_FORMAT_SLINEAR, AST_FORMAT_T140, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_frame_dump(), AST_FRAME_HTML, AST_FRAME_IAX, AST_FRAME_MODEM, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_framehook_list_write_event(), ast_frfree, ast_frisolate(), ast_getformatname(), ast_getformatname_multiple(), AST_LIST_NEXT, ast_log(), AST_MONITOR_RUNNING, ast_opt_generic_plc, ast_seekstream(), ast_senddigit_begin(), ast_senddigit_end(), ast_set_write_format(), AST_SOFTHANGUP_DEV, ast_test_flag, ast_translate(), ast_writestream(), ast_channel::audiohooks, calc_monitor_jump(), CHECK_BLOCKING, ast_frame_subclass::codec, ast_frame::data, ast_frame::datalen, DEBUGCHAN_FLAG, 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::nativeformats, chanlist::next, ast_channel::outsmpl, ast_frame::ptr, ast_channel::rawwriteformat, ast_channel_monitor::read_stream, ast_frame::samples, SEEK_FORCECUR, send_dtmf_event(), ast_channel_tech::send_html, ast_channel_tech::send_text, ast_frame::src, ast_channel_monitor::state, ast_frame::subclass, ast_channel::tech, ast_channel_tech::write, ast_channel_monitor::write_stream, ast_channel_tech::write_text, ast_channel_tech::write_video, ast_channel::writeformat, and ast_channel::writetrans.
Referenced by adsi_careful_send(), agent_write(), ast_bridge_call(), ast_generic_bridge(), ast_prod(), ast_readaudio_callback(), ast_readvideo_callback(), ast_udptl_bridge(), ast_write_video(), conf_queue_dtmf(), conf_run(), dahdi_bridge(), dictate_exec(), echo_exec(), fax_generator_generate(), feature_request_and_dial(), gen_generate(), generic_fax_exec(), handle_jack_audio(), iax2_bridge(), jb_get_and_deliver(), linear_generator(), local_bridge_loop(), milliwatt_generate(), misdn_bridge(), moh_files_generator(), moh_generate(), mp3_exec(), multiplexed_bridge_write(), NBScat_exec(), playtones_generator(), remote_bridge_loop(), send_tone_burst(), send_waveform_to_channel(), silence_generator_generate(), simple_bridge_write(), sms_generate(), softmix_bridge_poke(), softmix_bridge_write(), spy_generate(), t38_tx_packet_handler(), tonepair_generator(), and wait_for_answer().
04917 { 04918 int res = -1; 04919 struct ast_frame *f = NULL; 04920 int count = 0; 04921 04922 /*Deadlock avoidance*/ 04923 while(ast_channel_trylock(chan)) { 04924 /*cannot goto done since the channel is not locked*/ 04925 if(count++ > 10) { 04926 ast_debug(1, "Deadlock avoided for write to channel '%s'\n", chan->name); 04927 return 0; 04928 } 04929 usleep(1); 04930 } 04931 /* Stop if we're a zombie or need a soft hangup */ 04932 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) 04933 goto done; 04934 04935 /* Handle any pending masquerades */ 04936 while (chan->masq) { 04937 ast_channel_unlock(chan); 04938 ast_do_masquerade(chan); 04939 ast_channel_lock(chan); 04940 } 04941 if (chan->masqr) { 04942 res = 0; /* XXX explain, why 0 ? */ 04943 goto done; 04944 } 04945 04946 /* Perform the framehook write event here. After the frame enters the framehook list 04947 * there is no telling what will happen, how awesome is that!!! */ 04948 if (!(fr = ast_framehook_list_write_event(chan->framehooks, fr))) { 04949 res = 0; 04950 goto done; 04951 } 04952 04953 if (chan->generatordata && (!fr->src || strcasecmp(fr->src, "ast_prod"))) { 04954 if (ast_test_flag(chan, AST_FLAG_WRITE_INT)) { 04955 ast_deactivate_generator(chan); 04956 } else { 04957 if (fr->frametype == AST_FRAME_DTMF_END) { 04958 /* There is a generator running while we're in the middle of a digit. 04959 * It's probably inband DTMF, so go ahead and pass it so it can 04960 * stop the generator */ 04961 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04962 ast_channel_unlock(chan); 04963 res = ast_senddigit_end(chan, fr->subclass.integer, fr->len); 04964 ast_channel_lock(chan); 04965 CHECK_BLOCKING(chan); 04966 } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_UNHOLD) { 04967 /* This is a side case where Echo is basically being called and the person put themselves on hold and took themselves off hold */ 04968 res = (chan->tech->indicate == NULL) ? 0 : 04969 chan->tech->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen); 04970 } 04971 res = 0; /* XXX explain, why 0 ? */ 04972 goto done; 04973 } 04974 } 04975 /* High bit prints debugging */ 04976 if (chan->fout & DEBUGCHAN_FLAG) 04977 ast_frame_dump(chan->name, fr, ">>"); 04978 CHECK_BLOCKING(chan); 04979 switch (fr->frametype) { 04980 case AST_FRAME_CONTROL: 04981 res = (chan->tech->indicate == NULL) ? 0 : 04982 chan->tech->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen); 04983 break; 04984 case AST_FRAME_DTMF_BEGIN: 04985 if (chan->audiohooks) { 04986 struct ast_frame *old_frame = fr; 04987 fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr); 04988 if (old_frame != fr) 04989 f = fr; 04990 } 04991 send_dtmf_event(chan, "Sent", fr->subclass.integer, "Yes", "No"); 04992 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04993 ast_channel_unlock(chan); 04994 res = ast_senddigit_begin(chan, fr->subclass.integer); 04995 ast_channel_lock(chan); 04996 CHECK_BLOCKING(chan); 04997 break; 04998 case AST_FRAME_DTMF_END: 04999 if (chan->audiohooks) { 05000 struct ast_frame *new_frame = fr; 05001 05002 new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr); 05003 if (new_frame != fr) { 05004 ast_frfree(new_frame); 05005 } 05006 } 05007 send_dtmf_event(chan, "Sent", fr->subclass.integer, "No", "Yes"); 05008 ast_clear_flag(chan, AST_FLAG_BLOCKING); 05009 ast_channel_unlock(chan); 05010 res = ast_senddigit_end(chan, fr->subclass.integer, fr->len); 05011 ast_channel_lock(chan); 05012 CHECK_BLOCKING(chan); 05013 break; 05014 case AST_FRAME_TEXT: 05015 if (fr->subclass.integer == AST_FORMAT_T140) { 05016 res = (chan->tech->write_text == NULL) ? 0 : 05017 chan->tech->write_text(chan, fr); 05018 } else { 05019 res = (chan->tech->send_text == NULL) ? 0 : 05020 chan->tech->send_text(chan, (char *) fr->data.ptr); 05021 } 05022 break; 05023 case AST_FRAME_HTML: 05024 res = (chan->tech->send_html == NULL) ? 0 : 05025 chan->tech->send_html(chan, fr->subclass.integer, (char *) fr->data.ptr, fr->datalen); 05026 break; 05027 case AST_FRAME_VIDEO: 05028 /* XXX Handle translation of video codecs one day XXX */ 05029 res = (chan->tech->write_video == NULL) ? 0 : 05030 chan->tech->write_video(chan, fr); 05031 break; 05032 case AST_FRAME_MODEM: 05033 res = (chan->tech->write == NULL) ? 0 : 05034 chan->tech->write(chan, fr); 05035 break; 05036 case AST_FRAME_VOICE: 05037 if (chan->tech->write == NULL) 05038 break; /*! \todo XXX should return 0 maybe ? */ 05039 05040 if (ast_opt_generic_plc && fr->subclass.codec == AST_FORMAT_SLINEAR) { 05041 apply_plc(chan, fr); 05042 } 05043 05044 /* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */ 05045 if (fr->subclass.codec == chan->rawwriteformat) { 05046 f = fr; 05047 } else { 05048 if ((!(fr->subclass.codec & chan->nativeformats)) && (chan->writeformat != fr->subclass.codec)) { 05049 char nf[512]; 05050 05051 /* 05052 * XXX Something is not right. We are not compatible with this 05053 * frame. Bad things can happen. Problems range from no audio, 05054 * one-way audio, to unexplained line hangups. As a last resort 05055 * try to adjust the format. Ideally, we do not want to do this 05056 * because it indicates a deeper problem. For now, we log these 05057 * events to reduce user impact and help identify the problem 05058 * areas. 05059 */ 05060 ast_log(LOG_WARNING, "Codec mismatch on channel %s setting write format to %s from %s native formats %s\n", 05061 chan->name, ast_getformatname(fr->subclass.codec), ast_getformatname(chan->writeformat), 05062 ast_getformatname_multiple(nf, sizeof(nf), chan->nativeformats & AST_FORMAT_AUDIO_MASK)); 05063 ast_set_write_format(chan, fr->subclass.codec); 05064 } 05065 05066 f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr; 05067 } 05068 05069 if (!f) { 05070 res = 0; 05071 break; 05072 } 05073 05074 if (chan->audiohooks) { 05075 struct ast_frame *prev = NULL, *new_frame, *cur, *dup; 05076 int freeoldlist = 0; 05077 05078 if (f != fr) { 05079 freeoldlist = 1; 05080 } 05081 05082 /* Since ast_audiohook_write may return a new frame, and the cur frame is 05083 * an item in a list of frames, create a new list adding each cur frame back to it 05084 * regardless if the cur frame changes or not. */ 05085 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 05086 new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, cur); 05087 05088 /* if this frame is different than cur, preserve the end of the list, 05089 * free the old frames, and set cur to be the new frame */ 05090 if (new_frame != cur) { 05091 05092 /* doing an ast_frisolate here seems silly, but we are not guaranteed the new_frame 05093 * isn't part of local storage, meaning if ast_audiohook_write is called multiple 05094 * times it may override the previous frame we got from it unless we dup it */ 05095 if ((dup = ast_frisolate(new_frame))) { 05096 AST_LIST_NEXT(dup, frame_list) = AST_LIST_NEXT(cur, frame_list); 05097 if (freeoldlist) { 05098 AST_LIST_NEXT(cur, frame_list) = NULL; 05099 ast_frfree(cur); 05100 } 05101 if (new_frame != dup) { 05102 ast_frfree(new_frame); 05103 } 05104 cur = dup; 05105 } 05106 } 05107 05108 /* now, regardless if cur is new or not, add it to the new list, 05109 * if the new list has not started, cur will become the first item. */ 05110 if (prev) { 05111 AST_LIST_NEXT(prev, frame_list) = cur; 05112 } else { 05113 f = cur; /* set f to be the beginning of our new list */ 05114 } 05115 prev = cur; 05116 } 05117 } 05118 05119 /* If Monitor is running on this channel, then we have to write frames out there too */ 05120 /* the translator on chan->writetrans may have returned multiple frames 05121 from the single frame we passed in; if so, feed each one of them to the 05122 monitor */ 05123 if (chan->monitor && chan->monitor->write_stream) { 05124 struct ast_frame *cur; 05125 05126 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 05127 /* XXX must explain this code */ 05128 #ifndef MONITOR_CONSTANT_DELAY 05129 int jump = chan->insmpl - chan->outsmpl - 4 * cur->samples; 05130 if (jump >= 0) { 05131 jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format)); 05132 if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1) 05133 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 05134 chan->outsmpl += (chan->insmpl - chan->outsmpl) + cur->samples; 05135 } else { 05136 chan->outsmpl += cur->samples; 05137 } 05138 #else 05139 int jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format)); 05140 if (jump - MONITOR_DELAY >= 0) { 05141 if (ast_seekstream(chan->monitor->write_stream, jump - cur->samples, SEEK_FORCECUR) == -1) 05142 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 05143 chan->outsmpl += chan->insmpl - chan->outsmpl; 05144 } else { 05145 chan->outsmpl += cur->samples; 05146 } 05147 #endif 05148 if (chan->monitor->state == AST_MONITOR_RUNNING) { 05149 if (ast_writestream(chan->monitor->write_stream, cur) < 0) 05150 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n"); 05151 } 05152 } 05153 } 05154 05155 /* the translator on chan->writetrans may have returned multiple frames 05156 from the single frame we passed in; if so, feed each one of them to the 05157 channel, freeing each one after it has been written */ 05158 if ((f != fr) && AST_LIST_NEXT(f, frame_list)) { 05159 struct ast_frame *cur, *next; 05160 unsigned int skip = 0; 05161 05162 for (cur = f, next = AST_LIST_NEXT(cur, frame_list); 05163 cur; 05164 cur = next, next = cur ? AST_LIST_NEXT(cur, frame_list) : NULL) { 05165 if (!skip) { 05166 if ((res = chan->tech->write(chan, cur)) < 0) { 05167 chan->_softhangup |= AST_SOFTHANGUP_DEV; 05168 skip = 1; 05169 } else if (next) { 05170 /* don't do this for the last frame in the list, 05171 as the code outside the loop will do it once 05172 */ 05173 chan->fout = FRAMECOUNT_INC(chan->fout); 05174 } 05175 } 05176 ast_frfree(cur); 05177 } 05178 05179 /* reset f so the code below doesn't attempt to free it */ 05180 f = NULL; 05181 } else { 05182 res = chan->tech->write(chan, f); 05183 } 05184 break; 05185 case AST_FRAME_NULL: 05186 case AST_FRAME_IAX: 05187 /* Ignore these */ 05188 res = 0; 05189 break; 05190 default: 05191 /* At this point, fr is the incoming frame and f is NULL. Channels do 05192 * not expect to get NULL as a frame pointer and will segfault. Hence, 05193 * we output the original frame passed in. */ 05194 res = chan->tech->write(chan, fr); 05195 break; 05196 } 05197 05198 if (f && f != fr) 05199 ast_frfree(f); 05200 ast_clear_flag(chan, AST_FLAG_BLOCKING); 05201 05202 /* Consider a write failure to force a soft hangup */ 05203 if (res < 0) { 05204 chan->_softhangup |= AST_SOFTHANGUP_DEV; 05205 } else { 05206 chan->fout = FRAMECOUNT_INC(chan->fout); 05207 } 05208 done: 05209 if (chan->audiohooks && ast_audiohook_write_list_empty(chan->audiohooks)) { 05210 /* The list gets recreated if audiohooks are added again later */ 05211 ast_audiohook_detach_list(chan->audiohooks); 05212 chan->audiohooks = NULL; 05213 } 05214 ast_channel_unlock(chan); 05215 return res; 05216 }
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 4801 of file channel.c.
References ast_write(), ast_channel::tech, and ast_channel_tech::write_video.
04802 { 04803 int res; 04804 if (!chan->tech->write_video) 04805 return 0; 04806 res = ast_write(chan, fr); 04807 if (!res) 04808 res = 1; 04809 return res; 04810 }
const char* channelreloadreason2txt | ( | enum channelreloadreason | reason | ) |
Convert enum channelreloadreason to text string for manager event.
reason | The reason for reload (manager, cli, start etc) |
\ brief Convert channel reloadreason (ENUM) to text string for manager event
Definition at line 8372 of file channel.c.
References CHANNEL_CLI_RELOAD, CHANNEL_MODULE_LOAD, and CHANNEL_MODULE_RELOAD.
Referenced by reload_config().
08373 { 08374 switch (reason) { 08375 case CHANNEL_MODULE_LOAD: 08376 return "LOAD (Channel module load)"; 08377 08378 case CHANNEL_MODULE_RELOAD: 08379 return "RELOAD (Channel module reload)"; 08380 08381 case CHANNEL_CLI_RELOAD: 08382 return "CLIRELOAD (Channel module reload by CLI command)"; 08383 08384 default: 08385 return "MANAGERRELOAD (Channel module reload by manager)"; 08386 } 08387 };
struct ast_channel_tech ast_kill_tech |
Kill the channel channel driver technology descriptor.
The purpose of this channel technology is to encourage the channel to hangup as quickly as possible.
Definition at line 668 of file channel.c.
Referenced by ast_do_masquerade().
unsigned long global_fin |
The current value of the debug flags is stored in the two variables global_fin and global_fout (declared in main/channel.c)
Definition at line 104 of file channel.c.
Referenced by handle_core_set_debug_channel().
unsigned long global_fout |
Definition at line 104 of file channel.c.
Referenced by handle_core_set_debug_channel().