#include "asterisk/abstract_jb.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"
Go to the source code of this file.
Data Structures | |
struct | ast_bridge_config |
bridge configuration More... | |
struct | ast_callerid |
Structure for all kinds of caller ID identifications. More... | |
struct | ast_channel |
Main Channel structure associated with a channel. This is the side of it mostly used by the pbx and call management. More... | |
struct | ast_channel::datastores |
struct | ast_channel_tech |
Structure to describe a channel "technology", ie a channel driver See for examples:. More... | |
struct | ast_datastore |
Structure for a channel data store. More... | |
struct | ast_datastore_info |
Structure for a data store type. More... | |
struct | ast_generator |
struct | ast_group_info |
channel group info 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_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, amaflag,) |
#define | AST_CHANNEL_NAME 80 |
#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 20 |
#define | MAX_MUSICCLASS 80 |
Typedefs | |
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_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_CDR_TRANSFER = (1 << 0), AST_CDR_FORWARD = (1 << 1), AST_CDR_CALLWAIT = (1 << 2), AST_CDR_CONFERENCE = (1 << 3) } |
enum | { AST_SOFTHANGUP_DEV = (1 << 0), AST_SOFTHANGUP_ASYNCGOTO = (1 << 1), AST_SOFTHANGUP_SHUTDOWN = (1 << 2), AST_SOFTHANGUP_TIMEOUT = (1 << 3), AST_SOFTHANGUP_APPUNLOAD = (1 << 4), AST_SOFTHANGUP_EXPLICIT = (1 << 5), AST_SOFTHANGUP_UNBRIDGE = (1 << 6) } |
enum | ast_bridge_result { AST_BRIDGE_COMPLETE = 0, AST_BRIDGE_FAILED = -1, AST_BRIDGE_FAILED_NOWARN = -2, AST_BRIDGE_RETRY = -3 } |
enum | ast_channel_adsicpe { AST_ADSI_UNKNOWN, AST_ADSI_AVAILABLE, AST_ADSI_UNAVAILABLE, AST_ADSI_OFFHOOKONLY } |
enum | ast_channel_state { AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_OFFHOOK, AST_STATE_DIALING, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, AST_STATE_BUSY, AST_STATE_DIALING_OFFHOOK, AST_STATE_PRERING, AST_STATE_MUTE = (1 << 16) } |
ast_channel states More... | |
enum | ast_t38_state { T38_STATE_UNAVAILABLE, T38_STATE_UNKNOWN, T38_STATE_NEGOTIATING, T38_STATE_REJECTED, T38_STATE_NEGOTIATED } |
Possible T38 states on channels. More... | |
enum | channelreloadreason { CHANNEL_MODULE_LOAD, CHANNEL_MODULE_RELOAD, CHANNEL_CLI_RELOAD, CHANNEL_MANAGER_RELOAD } |
Channel reload reasons for manager events at load or reload of configuration. More... | |
Functions | |
int | __ast_answer (struct ast_channel *chan, unsigned int delay, int cdr_answer) |
Answer a channel, with a selectable delay before returning. | |
ast_channel *attribute_malloc | __ast_channel_alloc (int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const int amaflag, const char *file, int line, const char *function, const char *name_fmt,...) |
Create a channel structure. | |
ast_channel * | __ast_request_and_dial (const char *type, int format, 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_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) |
Initiate system shutdown. | |
int | ast_best_codec (int fmts) |
Pick the best audio codec. | |
ast_channel * | ast_bridged_channel (struct ast_channel *chan) |
Find bridged channel. | |
int | ast_call (struct ast_channel *chan, char *addr, int timeout) |
Make a call. | |
ast_channel * | ast_call_forward (struct ast_channel *caller, struct ast_channel *orig, int *timeout, int 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 hangup cause. | |
void | ast_change_name (struct ast_channel *chan, 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. | |
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_datastore_add (struct ast_channel *chan, struct ast_datastore *datastore) |
Add a datastore to a channel. | |
ast_datastore * | ast_channel_datastore_alloc (const struct ast_datastore_info *info, const char *uid) |
Create a channel datastore structure. | |
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 datastore structure. | |
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) |
Set defer DTMF flag on channel. | |
int | ast_channel_early_bridge (struct ast_channel *c0, struct ast_channel *c1) |
Bridge two channels together (early). | |
void | ast_channel_free (struct ast_channel *) |
Free a 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) |
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_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. | |
int | ast_channel_sendhtml (struct ast_channel *channel, int subclass, const char *data, int datalen) |
int | ast_channel_sendurl (struct ast_channel *channel, const char *url) |
void | ast_channel_set_fd (struct ast_channel *chan, int which, int fd) |
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. | |
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) |
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. | |
ast_channel * | ast_channel_walk_locked (const struct ast_channel *prev) |
Browse channels in use Browse the channels currently in use. | |
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. | |
void | ast_deactivate_generator (struct ast_channel *chan) |
int | ast_do_masquerade (struct ast_channel *chan) |
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. | |
static int | ast_fdisset (struct pollfd *pfds, int fd, int max, int *start) |
Helper function for migrating select to poll. | |
ast_channel * | ast_get_channel_by_exten_locked (const char *exten, const char *context) |
Get channel by exten (and optionally context) and lock it. | |
ast_channel * | ast_get_channel_by_name_locked (const char *chan) |
Get channel by name or uniqueid (locks channel). | |
ast_channel * | ast_get_channel_by_name_prefix_locked (const char *name, const int namelen) |
Get channel by name or uniqueid prefix (locks channel). | |
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. | |
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_raw_answer (struct ast_channel *chan, int cdr_answer) |
Answer a channel. | |
ast_frame * | ast_read (struct ast_channel *chan) |
Reads a frame. | |
ast_frame * | ast_read_noaudio (struct ast_channel *chan) |
Reads a frame, returning AST_FRAME_NULL frame if audio. | |
int | ast_readstring (struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders) |
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. | |
ast_channel * | ast_request (const char *type, int format, void *data, int *status) |
Requests a channel. | |
ast_channel * | ast_request_and_dial (const char *type, int format, 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. | |
static int | ast_select (int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tvp) |
Waits for activity on a group of channels. | |
int | ast_senddigit (struct ast_channel *chan, char digit, unsigned int duration) |
Send a DTMF digit to a channel Send a DTMF digit to a channel. | |
int | ast_senddigit_begin (struct ast_channel *chan, char digit) |
Send a DTMF digit to a channel 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. | |
int | ast_set_read_format (struct ast_channel *chan, int 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, int format) |
Sets write format on channel chan Set write format for channel to whichever component of "format" is best. | |
int | ast_setstate (struct ast_channel *chan, enum ast_channel_state) |
Change the state of a channel. | |
int | ast_settimeout (struct ast_channel *c, int samples, int(*func)(const void *data), void *data) |
int | ast_shutting_down (void) |
Returns non-zero if Asterisk is being shut down. | |
int | ast_softhangup (struct ast_channel *chan, int cause) |
Softly hangup up a channel. | |
int | ast_softhangup_nolock (struct ast_channel *chan, int cause) |
Softly hangup up a channel (no channel lock). | |
const char * | ast_state2str (enum ast_channel_state) |
Gives the string form of a given channel state. | |
int | ast_str2cause (const char *name) attribute_pure |
Convert a symbolic hangup cause to 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). Returns -1 on error, 0 if not supported and 1 if supported and requested. | |
char * | ast_transfercapability2str (int transfercapability) attribute_const |
Gives the string form of a given transfer capability. | |
int | ast_waitfor (struct ast_channel *chan, int ms) |
Wait for input on a channel. | |
ast_channel * | ast_waitfor_n (struct ast_channel **chan, int n, int *ms) |
Waits for input on a group of channels Wait for input on an array of channels for a given # of milliseconds. | |
int | ast_waitfor_n_fd (int *fds, int n, int *ms, int *exception) |
Waits for input on an fd This version works on fd's only. Be careful with it. | |
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. | |
ast_channel * | ast_walk_channel_by_exten_locked (const struct ast_channel *chan, const char *exten, const char *context) |
Get next channel by exten (and optionally context) and lock it. | |
ast_channel * | ast_walk_channel_by_name_prefix_locked (const struct ast_channel *chan, const char *name, const int namelen) |
Get channel by name or uniqueid prefix (locks channel). | |
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. | |
static void | timersub (struct timeval *tvend, struct timeval *tvstart, struct timeval *tvdiff) |
Variables | |
unsigned long | global_fin |
unsigned long | global_fout |
Definition in file channel.h.
#define AST_AGENT_FD (AST_MAX_FDS-3) |
used by agents for pass through
Definition at line 159 of file channel.h.
Referenced by agent_read().
#define AST_ALERT_FD (AST_MAX_FDS-1) |
used for alertpipe
Definition at line 157 of file channel.h.
Referenced by __ast_channel_alloc_ap(), and restore_channel().
#define AST_BRIDGE_DTMF_CHANNEL_0 (1 << 0) |
Report DTMF on channel 0.
Definition at line 1323 of file channel.h.
Referenced by ast_generic_bridge(), bridge_native_loop(), dahdi_bridge(), iax2_bridge(), misdn_bridge(), and set_config_flags().
#define AST_BRIDGE_DTMF_CHANNEL_1 (1 << 1) |
Report DTMF on channel 1.
Definition at line 1325 of file channel.h.
Referenced by ast_generic_bridge(), bridge_native_loop(), dahdi_bridge(), iax2_bridge(), misdn_bridge(), and set_config_flags().
#define AST_BRIDGE_IGNORE_SIGS (1 << 4) |
Ignore all signal frames except NULL.
Definition at line 1331 of file channel.h.
Referenced by bridge_native_loop().
#define AST_BRIDGE_REC_CHANNEL_0 (1 << 2) |
#define AST_BRIDGE_REC_CHANNEL_1 (1 << 3) |
#define ast_channel_alloc | ( | needqueue, | |||
state, | |||||
cid_num, | |||||
cid_name, | |||||
acctcode, | |||||
exten, | |||||
context, | |||||
amaflag | ) |
Value:
__ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, amaflag, \ __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
Definition at line 740 of file channel.h.
Referenced by __oh323_new(), acf_odbc_read(), acf_odbc_write(), action_bridge(), action_getvar(), agent_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_pbx_outgoing_cdr_failed(), ast_pbx_outgoing_exten(), bridge_exec(), builtin_atxfer(), check_goto_on_transfer(), console_new(), dahdi_new(), gtalk_new(), iax_park(), jingle_new(), local_new(), make_email_file(), masq_park_call(), mgcp_new(), misdn_new(), nbs_new(), oss_new(), pbx_substitute_variables_helper_full(), phone_new(), rotate_file(), sendmail(), sendpage(), sip_new(), sip_park(), skinny_new(), unistim_new(), and usbradio_new().
#define AST_CHANNEL_NAME 80 |
Max length of an ast_channel name
Definition at line 136 of file channel.h.
Referenced by ast_channel_free(), ast_do_masquerade(), ast_parse_device_state(), ast_setstate(), common_exec(), create_jb(), fast_originate(), page_exec(), park_call_full(), and softhangup_exec().
#define AST_GENERATOR_FD (AST_MAX_FDS-4) |
used by generator
Definition at line 160 of file channel.h.
Referenced by __ast_read(), ast_deactivate_generator(), and ast_do_masquerade().
#define AST_MAX_CONTEXT 80 |
Max length of a context
Definition at line 135 of file channel.h.
Referenced by _macro_exec(), cleanup_stale_contexts(), common_exec(), conf_run(), gtalk_load_config(), handle_gosub(), reload_config(), and try_calling().
#define AST_MAX_EXTENSION 80 |
Max length of an extension
Definition at line 134 of file channel.h.
Referenced by advanced_options(), ast_device_state_changed(), ast_devstate_changed(), ast_extension_state2(), ast_ivr_menu_run_internal(), begin_dial_channel(), build_device(), conf_run(), destroy_station(), dial_exec_full(), disa_exec(), do_forward(), dundi_lookup_local(), forward_message(), function_enum(), get_destination(), handle_gosub(), handle_statechange(), load_config(), load_module(), log_exec(), manager_show_dialplan_helper(), mgcp_ss(), park_add_hints(), park_call_exec(), phone_check_exception(), realtime_switch_common(), search_directory(), show_dialplan_helper(), skinny_answer(), skinny_extensionstate_cb(), skinny_indicate(), skinny_ss(), speech_background(), ss_thread(), transmit_state_notify(), try_calling(), vm_authenticate(), and vmauthenticate().
#define AST_MAX_FDS 10 |
Definition at line 152 of file channel.h.
Referenced by __ast_channel_alloc_ap(), ast_channel_free(), ast_do_masquerade(), ast_poll_channel_add(), ast_poll_channel_del(), ast_waitfor_nandfds(), do_parking_thread(), and update_features().
#define AST_TIMING_FD (AST_MAX_FDS-2) |
used for timingfd
Definition at line 158 of file channel.h.
Referenced by __ast_channel_alloc_ap(), __ast_read(), agent_read(), ast_do_masquerade(), and restore_channel().
#define CHECK_BLOCKING | ( | c | ) |
Definition at line 1706 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 150 of file channel.h.
Referenced by _macro_exec(), acf_iaxvar_write(), add_features_datastores(), ast_channel_datastore_inherit(), ast_iax2_new(), authenticate_reply(), dial_exec_full(), 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 364 of file channel.h.
Referenced by __ast_read(), ast_write(), handle_core_set_debug_channel(), handle_showchan(), and serialize_showchan().
#define FRAMECOUNT_INC | ( | x | ) | ( ((x) & DEBUGCHAN_FLAG) | (((x)+1) & ~DEBUGCHAN_FLAG) ) |
#define MAX_LANGUAGE 20 |
#define MAX_MUSICCLASS 80 |
typedef unsigned long long ast_group_t |
anonymous enum |
ast_channel_tech Properties
Definition at line 540 of file channel.h.
00540 { 00541 /*! \brief Channels have this property if they can accept input with jitter; 00542 * i.e. most VoIP channels */ 00543 AST_CHAN_TP_WANTSJITTER = (1 << 0), 00544 /*! \brief Channels have this property if they can create jitter; 00545 * i.e. most VoIP channels */ 00546 AST_CHAN_TP_CREATESJITTER = (1 << 1), 00547 };
anonymous enum |
ast_channel flags
Definition at line 550 of file channel.h.
00550 { 00551 /*! Queue incoming dtmf, to be released when this flag is turned off */ 00552 AST_FLAG_DEFER_DTMF = (1 << 1), 00553 /*! write should be interrupt generator */ 00554 AST_FLAG_WRITE_INT = (1 << 2), 00555 /*! a thread is blocking on this channel */ 00556 AST_FLAG_BLOCKING = (1 << 3), 00557 /*! This is a zombie channel */ 00558 AST_FLAG_ZOMBIE = (1 << 4), 00559 /*! There is an exception pending */ 00560 AST_FLAG_EXCEPTION = (1 << 5), 00561 /*! Listening to moh XXX anthm promises me this will disappear XXX */ 00562 AST_FLAG_MOH = (1 << 6), 00563 /*! This channel is spying on another channel */ 00564 AST_FLAG_SPYING = (1 << 7), 00565 /*! This channel is in a native bridge */ 00566 AST_FLAG_NBRIDGE = (1 << 8), 00567 /*! the channel is in an auto-incrementing dialplan processor, 00568 * so when ->priority is set, it will get incremented before 00569 * finding the next priority to run */ 00570 AST_FLAG_IN_AUTOLOOP = (1 << 9), 00571 /*! This is an outgoing call */ 00572 AST_FLAG_OUTGOING = (1 << 10), 00573 /*! A DTMF_BEGIN frame has been read from this channel, but not yet an END */ 00574 AST_FLAG_IN_DTMF = (1 << 12), 00575 /*! A DTMF_END was received when not IN_DTMF, so the length of the digit is 00576 * currently being emulated */ 00577 AST_FLAG_EMULATE_DTMF = (1 << 13), 00578 /*! This is set to tell the channel not to generate DTMF begin frames, and 00579 * to instead only generate END frames. */ 00580 AST_FLAG_END_DTMF_ONLY = (1 << 14), 00581 /*! Flag to show channels that this call is hangup due to the fact that the call 00582 was indeed anwered, but in another channel */ 00583 AST_FLAG_ANSWERED_ELSEWHERE = (1 << 15), 00584 /*! This flag indicates that on a masquerade, an active stream should not 00585 * be carried over */ 00586 AST_FLAG_MASQ_NOSTREAM = (1 << 16), 00587 /*! This flag indicates that the hangup exten was run when the bridge terminated, 00588 * a message aimed at preventing a subsequent hangup exten being run at the pbx_run 00589 * level */ 00590 AST_FLAG_BRIDGE_HANGUP_RUN = (1 << 17), 00591 /*! This flag indicates that the hangup exten should NOT be run when the 00592 * bridge terminates, this will allow the hangup in the pbx loop to be run instead. 00593 * */ 00594 AST_FLAG_BRIDGE_HANGUP_DONT = (1 << 18), 00595 };
anonymous enum |
ast_bridge_config flags
Definition at line 598 of file channel.h.
00598 { 00599 AST_FEATURE_PLAY_WARNING = (1 << 0), 00600 AST_FEATURE_REDIRECT = (1 << 1), 00601 AST_FEATURE_DISCONNECT = (1 << 2), 00602 AST_FEATURE_ATXFER = (1 << 3), 00603 AST_FEATURE_AUTOMON = (1 << 4), 00604 AST_FEATURE_PARKCALL = (1 << 5), 00605 AST_FEATURE_AUTOMIXMON = (1 << 6), 00606 AST_FEATURE_NO_H_EXTEN = (1 << 7), 00607 AST_FEATURE_WARNING_ACTIVE = (1 << 8), 00608 };
anonymous enum |
Definition at line 647 of file channel.h.
00647 { 00648 AST_CDR_TRANSFER = (1 << 0), 00649 AST_CDR_FORWARD = (1 << 1), 00650 AST_CDR_CALLWAIT = (1 << 2), 00651 AST_CDR_CONFERENCE = (1 << 3), 00652 };
anonymous enum |
Definition at line 654 of file channel.h.
00654 { 00655 /*! Soft hangup by device */ 00656 AST_SOFTHANGUP_DEV = (1 << 0), 00657 /*! Soft hangup for async goto */ 00658 AST_SOFTHANGUP_ASYNCGOTO = (1 << 1), 00659 AST_SOFTHANGUP_SHUTDOWN = (1 << 2), 00660 AST_SOFTHANGUP_TIMEOUT = (1 << 3), 00661 AST_SOFTHANGUP_APPUNLOAD = (1 << 4), 00662 AST_SOFTHANGUP_EXPLICIT = (1 << 5), 00663 AST_SOFTHANGUP_UNBRIDGE = (1 << 6), 00664 };
enum ast_bridge_result |
Definition at line 162 of file channel.h.
00162 { 00163 AST_BRIDGE_COMPLETE = 0, 00164 AST_BRIDGE_FAILED = -1, 00165 AST_BRIDGE_FAILED_NOWARN = -2, 00166 AST_BRIDGE_RETRY = -3, 00167 };
enum ast_channel_adsicpe |
Definition at line 375 of file channel.h.
00375 { 00376 AST_ADSI_UNKNOWN, 00377 AST_ADSI_AVAILABLE, 00378 AST_ADSI_UNAVAILABLE, 00379 AST_ADSI_OFFHOOKONLY, 00380 };
enum ast_channel_state |
ast_channel states
Definition at line 388 of file channel.h.
00388 { 00389 AST_STATE_DOWN, /*!< Channel is down and available */ 00390 AST_STATE_RESERVED, /*!< Channel is down, but reserved */ 00391 AST_STATE_OFFHOOK, /*!< Channel is off hook */ 00392 AST_STATE_DIALING, /*!< Digits (or equivalent) have been dialed */ 00393 AST_STATE_RING, /*!< Line is ringing */ 00394 AST_STATE_RINGING, /*!< Remote end is ringing */ 00395 AST_STATE_UP, /*!< Line is up */ 00396 AST_STATE_BUSY, /*!< Line is busy */ 00397 AST_STATE_DIALING_OFFHOOK, /*!< Digits (or equivalent) have been dialed while offhook */ 00398 AST_STATE_PRERING, /*!< Channel has detected an incoming call and is waiting for ring */ 00399 00400 AST_STATE_MUTE = (1 << 16), /*!< Do not transmit voice data */ 00401 };
enum ast_t38_state |
Possible T38 states on channels.
Definition at line 406 of file channel.h.
00406 { 00407 T38_STATE_UNAVAILABLE, /*!< T38 is unavailable on this channel or disabled by configuration */ 00408 T38_STATE_UNKNOWN, /*!< The channel supports T38 but the current status is unknown */ 00409 T38_STATE_NEGOTIATING, /*!< T38 is being negotiated */ 00410 T38_STATE_REJECTED, /*!< Remote side has rejected our offer */ 00411 T38_STATE_NEGOTIATED, /*!< T38 established */ 00412 };
enum channelreloadreason |
Channel reload reasons for manager events at load or reload of configuration.
Definition at line 668 of file channel.h.
00668 { 00669 CHANNEL_MODULE_LOAD, 00670 CHANNEL_MODULE_RELOAD, 00671 CHANNEL_CLI_RELOAD, 00672 CHANNEL_MANAGER_RELOAD, 00673 };
int __ast_answer | ( | struct ast_channel * | chan, | |
unsigned int | delay, | |||
int | cdr_answer | |||
) |
Answer a channel, with a selectable delay before returning.
chan | channel to answer | |
delay | maximum amount of time to wait for incoming media | |
cdr_answer | flag to control whether any associated CDR should be marked as 'answered' |
This function will wait up to 'delay' milliseconds for media to arrive on the channel before returning to the caller, so that the caller can properly assume the channel is 'ready' for media flow. If 'delay' is less than 500, the function will wait up to 500 milliseconds.
0 | on success | |
non-zero | on failure |
Definition at line 1791 of file channel.c.
References ast_channel::_state, ast_channel_lock, ast_channel_unlock, AST_CONTROL_HANGUP, ast_debug, AST_FRAME_CNG, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_HTML, AST_FRAME_IAX, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_frisolate(), AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_HEAD_NOLOCK, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_HEAD, ast_log(), ast_queue_frame_head(), ast_raw_answer(), ast_read(), AST_STATE_RING, AST_STATE_RINGING, ast_waitfor(), chanlist::chan, errno, ast_frame::frame_list, frames, ast_frame::frametype, LOG_WARNING, MAX, ast_channel::name, and ast_frame::subclass.
Referenced by ast_answer(), dial_exec_full(), and pbx_builtin_answer().
01792 { 01793 int res = 0; 01794 enum ast_channel_state old_state; 01795 01796 old_state = chan->_state; 01797 if ((res = ast_raw_answer(chan, cdr_answer))) { 01798 return res; 01799 } 01800 01801 switch (old_state) { 01802 case AST_STATE_RINGING: 01803 case AST_STATE_RING: 01804 /* wait for media to start flowing, but don't wait any longer 01805 * than 'delay' or 500 milliseconds, whichever is longer 01806 */ 01807 do { 01808 AST_LIST_HEAD_NOLOCK(, ast_frame) frames; 01809 struct ast_frame *cur, *new; 01810 int ms = MAX(delay, 500); 01811 unsigned int done = 0; 01812 01813 AST_LIST_HEAD_INIT_NOLOCK(&frames); 01814 01815 for (;;) { 01816 ms = ast_waitfor(chan, ms); 01817 if (ms < 0) { 01818 ast_log(LOG_WARNING, "Error condition occurred when polling channel %s for a voice frame: %s\n", chan->name, strerror(errno)); 01819 res = -1; 01820 break; 01821 } 01822 if (ms == 0) { 01823 ast_debug(2, "Didn't receive a media frame from %s within %d ms of answering. Continuing anyway\n", chan->name, MAX(delay, 500)); 01824 break; 01825 } 01826 cur = ast_read(chan); 01827 if (!cur || ((cur->frametype == AST_FRAME_CONTROL) && 01828 (cur->subclass == AST_CONTROL_HANGUP))) { 01829 if (cur) { 01830 ast_frfree(cur); 01831 } 01832 res = -1; 01833 ast_debug(2, "Hangup of channel %s detected in answer routine\n", chan->name); 01834 break; 01835 } 01836 01837 if ((new = ast_frisolate(cur)) != cur) { 01838 ast_frfree(cur); 01839 } 01840 01841 AST_LIST_INSERT_HEAD(&frames, new, frame_list); 01842 01843 /* if a specific delay period was requested, continue 01844 * until that delay has passed. don't stop just because 01845 * incoming media has arrived. 01846 */ 01847 if (delay) { 01848 continue; 01849 } 01850 01851 switch (new->frametype) { 01852 /* all of these frametypes qualify as 'media' */ 01853 case AST_FRAME_VOICE: 01854 case AST_FRAME_VIDEO: 01855 case AST_FRAME_TEXT: 01856 case AST_FRAME_DTMF_BEGIN: 01857 case AST_FRAME_DTMF_END: 01858 case AST_FRAME_IMAGE: 01859 case AST_FRAME_HTML: 01860 case AST_FRAME_MODEM: 01861 done = 1; 01862 break; 01863 case AST_FRAME_CONTROL: 01864 case AST_FRAME_IAX: 01865 case AST_FRAME_NULL: 01866 case AST_FRAME_CNG: 01867 break; 01868 } 01869 01870 if (done) { 01871 break; 01872 } 01873 } 01874 01875 if (res == 0) { 01876 ast_channel_lock(chan); 01877 while ((cur = AST_LIST_REMOVE_HEAD(&frames, frame_list))) { 01878 ast_queue_frame_head(chan, cur); 01879 ast_frfree(cur); 01880 } 01881 ast_channel_unlock(chan); 01882 } 01883 } while (0); 01884 break; 01885 default: 01886 break; 01887 } 01888 01889 return res; 01890 }
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 int | amaflag, | |||
const char * | file, | |||
int | line, | |||
const char * | function, | |||
const char * | name_fmt, | |||
... | ||||
) |
Create a channel structure.
NULL | failure | |
non-NULL | successfully allocated channel |
Definition at line 965 of file channel.c.
References __ast_channel_alloc_ap().
00970 { 00971 va_list ap1, ap2; 00972 struct ast_channel *result; 00973 00974 va_start(ap1, name_fmt); 00975 va_start(ap2, name_fmt); 00976 result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context, 00977 amaflag, file, line, function, name_fmt, ap1, ap2); 00978 va_end(ap1); 00979 va_end(ap2); 00980 00981 return result; 00982 }
struct ast_channel* __ast_request_and_dial | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int | timeout, | |||
int * | reason, | |||
const char * | cid_num, | |||
const char * | cid_name, | |||
struct outgoing_helper * | oh | |||
) |
Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it.
type | type of channel to request | |
format | requested channel format | |
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 3722 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_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_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_copy_string(), AST_FRAME_CONTROL, ast_frfree, ast_hangup(), ast_log(), ast_read(), ast_request(), ast_set_callerid(), ast_set_flag, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_waitfor(), ast_channel::call_forward, ast_channel::cdr, chanlist::chan, outgoing_helper::cid_name, outgoing_helper::cid_num, ast_channel::context, outgoing_helper::context, ast_channel::exten, outgoing_helper::exten, f, handle_cause(), ast_channel::hangupcause, LOG_NOTICE, outgoing_helper::parent_channel, ast_channel::priority, outgoing_helper::priority, and outgoing_helper::vars.
Referenced by ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_request_and_dial(), and parkandannounce_exec().
03723 { 03724 int dummy_outstate; 03725 int cause = 0; 03726 struct ast_channel *chan; 03727 int res = 0; 03728 int last_subclass = 0; 03729 03730 if (outstate) 03731 *outstate = 0; 03732 else 03733 outstate = &dummy_outstate; /* make outstate always a valid pointer */ 03734 03735 chan = ast_request(type, format, data, &cause); 03736 if (!chan) { 03737 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data); 03738 handle_cause(cause, outstate); 03739 return NULL; 03740 } 03741 03742 if (oh) { 03743 if (oh->vars) 03744 ast_set_variables(chan, oh->vars); 03745 /* XXX why is this necessary, for the parent_channel perhaps ? */ 03746 if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) 03747 ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num); 03748 if (oh->parent_channel) { 03749 ast_channel_inherit_variables(oh->parent_channel, chan); 03750 ast_channel_datastore_inherit(oh->parent_channel, chan); 03751 } 03752 if (oh->account) 03753 ast_cdr_setaccount(chan, oh->account); 03754 } 03755 ast_set_callerid(chan, cid_num, cid_name, cid_num); 03756 ast_set_flag(chan->cdr, AST_CDR_FLAG_ORIGINATED); 03757 03758 if (ast_call(chan, data, 0)) { /* ast_call failed... */ 03759 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data); 03760 } else { 03761 res = 1; /* mark success in case chan->_state is already AST_STATE_UP */ 03762 while (timeout && chan->_state != AST_STATE_UP) { 03763 struct ast_frame *f; 03764 res = ast_waitfor(chan, timeout); 03765 if (res <= 0) /* error, timeout, or done */ 03766 break; 03767 if (timeout > -1) 03768 timeout = res; 03769 if (!ast_strlen_zero(chan->call_forward)) { 03770 if (!(chan = ast_call_forward(NULL, chan, &timeout, format, oh, outstate))) { 03771 return NULL; 03772 } 03773 continue; 03774 } 03775 03776 f = ast_read(chan); 03777 if (!f) { 03778 *outstate = AST_CONTROL_HANGUP; 03779 res = 0; 03780 break; 03781 } 03782 if (f->frametype == AST_FRAME_CONTROL) { 03783 switch (f->subclass) { 03784 case AST_CONTROL_RINGING: /* record but keep going */ 03785 *outstate = f->subclass; 03786 break; 03787 03788 case AST_CONTROL_BUSY: 03789 case AST_CONTROL_CONGESTION: 03790 case AST_CONTROL_ANSWER: 03791 *outstate = f->subclass; 03792 timeout = 0; /* trick to force exit from the while() */ 03793 break; 03794 03795 /* Ignore these */ 03796 case AST_CONTROL_PROGRESS: 03797 case AST_CONTROL_PROCEEDING: 03798 case AST_CONTROL_HOLD: 03799 case AST_CONTROL_UNHOLD: 03800 case AST_CONTROL_VIDUPDATE: 03801 case AST_CONTROL_SRCUPDATE: 03802 case -1: /* Ignore -- just stopping indications */ 03803 break; 03804 03805 default: 03806 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass); 03807 } 03808 last_subclass = f->subclass; 03809 } 03810 ast_frfree(f); 03811 } 03812 } 03813 03814 /* Final fixups */ 03815 if (oh) { 03816 if (!ast_strlen_zero(oh->context)) 03817 ast_copy_string(chan->context, oh->context, sizeof(chan->context)); 03818 if (!ast_strlen_zero(oh->exten)) 03819 ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten)); 03820 if (oh->priority) 03821 chan->priority = oh->priority; 03822 } 03823 if (chan->_state == AST_STATE_UP) 03824 *outstate = AST_CONTROL_ANSWER; 03825 03826 if (res <= 0) { 03827 if ( AST_CONTROL_RINGING == last_subclass ) 03828 chan->hangupcause = AST_CAUSE_NO_ANSWER; 03829 if (!chan->cdr && (chan->cdr = ast_cdr_alloc())) 03830 ast_cdr_init(chan->cdr, chan); 03831 if (chan->cdr) { 03832 char tmp[256]; 03833 snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data); 03834 ast_cdr_setapp(chan->cdr,"Dial",tmp); 03835 ast_cdr_update(chan); 03836 ast_cdr_start(chan->cdr); 03837 ast_cdr_end(chan->cdr); 03838 /* If the cause wasn't handled properly */ 03839 if (ast_cdr_disposition(chan->cdr,chan->hangupcause)) 03840 ast_cdr_failed(chan->cdr); 03841 } 03842 ast_hangup(chan); 03843 chan = NULL; 03844 } 03845 return chan; 03846 }
int ast_activate_generator | ( | struct ast_channel * | chan, | |
struct ast_generator * | gen, | |||
void * | params | |||
) |
Activate a given generator
Definition at line 1942 of file channel.c.
References ast_generator::alloc, ast_channel_lock, ast_channel_unlock, ast_prod(), ast_settimeout(), chanlist::chan, gen, ast_channel::generator, generator_force(), ast_channel::generatordata, and ast_generator::release.
Referenced by app_exec(), ast_channel_start_silence_generator(), ast_linear_stream(), ast_playtones_start(), ast_tonepair_start(), channel_spy(), old_milliwatt_exec(), and transmit_audio().
01943 { 01944 int res = 0; 01945 01946 ast_channel_lock(chan); 01947 01948 if (chan->generatordata) { 01949 if (chan->generator && chan->generator->release) 01950 chan->generator->release(chan, chan->generatordata); 01951 chan->generatordata = NULL; 01952 } 01953 01954 ast_prod(chan); 01955 if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) { 01956 res = -1; 01957 } 01958 01959 if (!res) { 01960 ast_settimeout(chan, 160, generator_force, chan); 01961 chan->generator = gen; 01962 } 01963 01964 ast_channel_unlock(chan); 01965 01966 return res; 01967 }
int ast_active_channels | ( | void | ) |
returns number of active/allocated channels
Returns number of active/allocated channels
Definition at line 499 of file channel.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, and AST_RWLIST_UNLOCK.
Referenced by action_corestatus(), dahdi_restart(), handle_show_settings(), and quit_handler().
00500 { 00501 struct ast_channel *c; 00502 int cnt = 0; 00503 AST_RWLIST_RDLOCK(&channels); 00504 AST_RWLIST_TRAVERSE(&channels, c, chan_list) 00505 cnt++; 00506 AST_RWLIST_UNLOCK(&channels); 00507 return cnt; 00508 }
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 1620 of file channel.h.
Referenced by ast_waitfor_nandfds().
int ast_answer | ( | struct ast_channel * | chan | ) |
Answer a channel.
chan | channel to answer |
This function will wait up to 500 milliseconds for media to arrive on the channel before returning to the caller, so that the caller can properly assume the channel is 'ready' for media flow.
0 | on success | |
non-zero | on failure |
Definition at line 1892 of file channel.c.
References __ast_answer(), and chanlist::chan.
Referenced by action_bridge(), agi_exec_full(), alarmreceiver_exec(), answer_trunk_chan(), app_exec(), ast_control_streamfile(), ast_pickup_call(), auth_exec(), background_detect_exec(), bridge_exec(), builtin_parkcall(), common_exec(), conf_exec(), count_exec(), dahdiras_exec(), dictate_exec(), directory_exec(), disa_exec(), features_answer(), handle_answer(), ices_exec(), login_exec(), minivm_accmess_exec(), minivm_greet_exec(), minivm_record_exec(), old_milliwatt_exec(), park_call_exec(), park_exec(), pbx_builtin_background(), pickup_do(), playback_exec(), privacy_exec(), read_exec(), readexten_exec(), sayunixtime_exec(), send_waveform_to_channel(), setup_privacy_args(), skel_exec(), sla_station_exec(), speech_background(), testclient_exec(), testserver_exec(), transmit(), vm_exec(), vm_execmain(), waitforsilence_exec(), and zapateller_exec().
01893 { 01894 return __ast_answer(chan, 0, 1); 01895 }
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 191 of file autoservice.c.
References as_cond, ast_calloc, ast_channel_lock, ast_channel_unlock, ast_cond_signal(), AST_FLAG_END_DTMF_ONLY, AST_LIST_EMPTY, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_pthread_create_background, AST_PTHREADT_NULL, ast_set_flag, ast_test_flag, asthread, autoservice_run(), asent::chan, free, asent::list, LOG_WARNING, and asent::use_count.
Referenced by _macro_exec(), acf_curl_exec(), acf_odbc_read(), acf_odbc_write(), ast_dtmf_stream(), ast_get_enum(), ast_get_srv(), ast_get_txt(), bridge_playfile(), builtin_atxfer(), builtin_automixmonitor(), builtin_automonitor(), builtin_blindtransfer(), conf_play(), dial_exec_full(), feature_exec_app(), function_realtime_read(), function_realtime_readdestroy(), function_realtime_store(), function_realtime_write(), lock_read(), lua_autoservice_start(), lua_get_variable_value(), lua_pbx_exec(), lua_set_variable(), lua_set_variable_value(), osplookup_exec(), pbx_find_extension(), shell_helper(), sla_station_exec(), smdi_msg_retrieve_read(), system_exec_helper(), and trylock_read().
00192 { 00193 int res = 0; 00194 struct asent *as; 00195 00196 AST_LIST_LOCK(&aslist); 00197 AST_LIST_TRAVERSE(&aslist, as, list) { 00198 if (as->chan == chan) { 00199 as->use_count++; 00200 break; 00201 } 00202 } 00203 AST_LIST_UNLOCK(&aslist); 00204 00205 if (as) { 00206 /* Entry exists, autoservice is already handling this channel */ 00207 return 0; 00208 } 00209 00210 if (!(as = ast_calloc(1, sizeof(*as)))) 00211 return -1; 00212 00213 /* New entry created */ 00214 as->chan = chan; 00215 as->use_count = 1; 00216 00217 ast_channel_lock(chan); 00218 as->orig_end_dtmf_flag = ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY) ? 1 : 0; 00219 if (!as->orig_end_dtmf_flag) 00220 ast_set_flag(chan, AST_FLAG_END_DTMF_ONLY); 00221 ast_channel_unlock(chan); 00222 00223 AST_LIST_LOCK(&aslist); 00224 00225 if (AST_LIST_EMPTY(&aslist) && asthread != AST_PTHREADT_NULL) { 00226 ast_cond_signal(&as_cond); 00227 } 00228 00229 AST_LIST_INSERT_HEAD(&aslist, as, list); 00230 00231 if (asthread == AST_PTHREADT_NULL) { /* need start the thread */ 00232 if (ast_pthread_create_background(&asthread, NULL, autoservice_run, NULL)) { 00233 ast_log(LOG_WARNING, "Unable to create autoservice thread :(\n"); 00234 /* There will only be a single member in the list at this point, 00235 the one we just added. */ 00236 AST_LIST_REMOVE(&aslist, as, list); 00237 free(as); 00238 asthread = AST_PTHREADT_NULL; 00239 res = -1; 00240 } else { 00241 pthread_kill(asthread, SIGURG); 00242 } 00243 } 00244 00245 AST_LIST_UNLOCK(&aslist); 00246 00247 return res; 00248 }
int ast_autoservice_stop | ( | struct ast_channel * | chan | ) |
Stop servicing a channel for us...
0 | success | |
-1 | error, or the channel has been hungup |
Definition at line 250 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::frame_list, free, asent::list, asent::orig_end_dtmf_flag, and asent::use_count.
Referenced by _macro_exec(), acf_curl_exec(), acf_odbc_write(), array(), ast_dtmf_stream(), ast_get_srv(), ast_get_txt(), ast_hangup(), bridge_playfile(), builtin_atxfer(), builtin_automixmonitor(), builtin_automonitor(), conf_play(), dial_exec_full(), feature_exec_app(), finishup(), function_realtime_read(), function_realtime_readdestroy(), function_realtime_store(), function_realtime_write(), lock_read(), lua_autoservice_stop(), lua_get_variable_value(), lua_pbx_exec(), lua_set_variable(), lua_set_variable_value(), osplookup_exec(), pbx_find_extension(), shell_helper(), sla_station_exec(), smdi_msg_retrieve_read(), system_exec_helper(), and trylock_read().
00251 { 00252 int res = -1; 00253 struct asent *as, *removed = NULL; 00254 struct ast_frame *f; 00255 int chan_list_state; 00256 00257 AST_LIST_LOCK(&aslist); 00258 00259 /* Save the autoservice channel list state. We _must_ verify that the channel 00260 * list has been rebuilt before we return. Because, after we return, the channel 00261 * could get destroyed and we don't want our poor autoservice thread to step on 00262 * it after its gone! */ 00263 chan_list_state = as_chan_list_state; 00264 00265 /* Find the entry, but do not free it because it still can be in the 00266 autoservice thread array */ 00267 AST_LIST_TRAVERSE_SAFE_BEGIN(&aslist, as, list) { 00268 if (as->chan == chan) { 00269 as->use_count--; 00270 if (as->use_count < 1) { 00271 AST_LIST_REMOVE_CURRENT(list); 00272 removed = as; 00273 } 00274 break; 00275 } 00276 } 00277 AST_LIST_TRAVERSE_SAFE_END; 00278 00279 if (removed && asthread != AST_PTHREADT_NULL) { 00280 pthread_kill(asthread, SIGURG); 00281 } 00282 00283 AST_LIST_UNLOCK(&aslist); 00284 00285 if (!removed) { 00286 return 0; 00287 } 00288 00289 /* Wait while autoservice thread rebuilds its list. */ 00290 while (chan_list_state == as_chan_list_state) { 00291 usleep(1000); 00292 } 00293 00294 /* Now autoservice thread should have no references to our entry 00295 and we can safely destroy it */ 00296 00297 if (!chan->_softhangup) { 00298 res = 0; 00299 } 00300 00301 if (!as->orig_end_dtmf_flag) { 00302 ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY); 00303 } 00304 00305 ast_channel_lock(chan); 00306 while ((f = AST_LIST_REMOVE_HEAD(&as->deferred_frames, frame_list))) { 00307 ast_queue_frame_head(chan, f); 00308 ast_frfree(f); 00309 } 00310 ast_channel_unlock(chan); 00311 00312 free(as); 00313 00314 return res; 00315 }
void ast_begin_shutdown | ( | int | hangup | ) |
Initiate system shutdown.
Initiate system shutdown -- prevents new channels from being allocated. If "hangup" is non-zero, all existing channels will receive soft hangups
Definition at line 486 of file channel.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_softhangup(), and AST_SOFTHANGUP_SHUTDOWN.
Referenced by quit_handler().
00487 { 00488 struct ast_channel *c; 00489 shutting_down = 1; 00490 if (hangup) { 00491 AST_RWLIST_RDLOCK(&channels); 00492 AST_RWLIST_TRAVERSE(&channels, c, chan_list) 00493 ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN); 00494 AST_RWLIST_UNLOCK(&channels); 00495 } 00496 }
int ast_best_codec | ( | int | fmts | ) |
Pick the best audio codec.
Pick the best codec
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 706 of file channel.c.
References ARRAY_LEN, AST_FORMAT_ADPCM, AST_FORMAT_ALAW, AST_FORMAT_AUDIO_MASK, 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_SLINEAR, AST_FORMAT_SLINEAR16, AST_FORMAT_SPEEX, AST_FORMAT_ULAW, ast_log(), LOG_WARNING, and prefs.
Referenced by __oh323_new(), agent_call(), ast_codec_choose(), ast_iax2_new(), ast_speech_new(), builtin_atxfer(), echo_exec(), findmeexec(), gtalk_new(), handle_open_receive_channel_ack_message(), iax2_request(), jingle_new(), local_new(), login_exec(), mgcp_new(), sip_new(), skinny_new(), skinny_set_rtp_peer(), socket_process(), start_rtp(), transmit_connect(), and unistim_new().
00707 { 00708 /* This just our opinion, expressed in code. We are asked to choose 00709 the best codec to use, given no information */ 00710 int x; 00711 static const int prefs[] = 00712 { 00713 /*! Okay, ulaw is used by all telephony equipment, so start with it */ 00714 AST_FORMAT_ULAW, 00715 /*! Unless of course, you're a silly European, so then prefer ALAW */ 00716 AST_FORMAT_ALAW, 00717 /*! G.722 is better then all below, but not as common as the above... so give ulaw and alaw priority */ 00718 AST_FORMAT_G722, 00719 /*! Okay, well, signed linear is easy to translate into other stuff */ 00720 AST_FORMAT_SLINEAR16, 00721 AST_FORMAT_SLINEAR, 00722 /*! G.726 is standard ADPCM, in RFC3551 packing order */ 00723 AST_FORMAT_G726, 00724 /*! G.726 is standard ADPCM, in AAL2 packing order */ 00725 AST_FORMAT_G726_AAL2, 00726 /*! ADPCM has great sound quality and is still pretty easy to translate */ 00727 AST_FORMAT_ADPCM, 00728 /*! Okay, we're down to vocoders now, so pick GSM because it's small and easier to 00729 translate and sounds pretty good */ 00730 AST_FORMAT_GSM, 00731 /*! iLBC is not too bad */ 00732 AST_FORMAT_ILBC, 00733 /*! Speex is free, but computationally more expensive than GSM */ 00734 AST_FORMAT_SPEEX, 00735 /*! Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough 00736 to use it */ 00737 AST_FORMAT_LPC10, 00738 /*! G.729a is faster than 723 and slightly less expensive */ 00739 AST_FORMAT_G729A, 00740 /*! Down to G.723.1 which is proprietary but at least designed for voice */ 00741 AST_FORMAT_G723_1, 00742 }; 00743 00744 /* Strip out video */ 00745 fmts &= AST_FORMAT_AUDIO_MASK; 00746 00747 /* Find the first preferred codec in the format given */ 00748 for (x = 0; x < ARRAY_LEN(prefs); x++) { 00749 if (fmts & prefs[x]) 00750 return prefs[x]; 00751 } 00752 00753 ast_log(LOG_WARNING, "Don't know any of 0x%x formats\n", fmts); 00754 00755 return 0; 00756 }
struct ast_channel* ast_bridged_channel | ( | struct ast_channel * | chan | ) |
Find bridged channel.
chan | Current channel |
Definition at line 4593 of file channel.c.
References ast_channel::_bridge, ast_channel_tech::bridged_channel, chanlist::chan, and ast_channel::tech.
Referenced by __dahdi_exception(), action_agents(), action_coreshowchannels(), agents_show(), agents_show_online(), ast_bridge_call(), ast_channel_masquerade(), attempt_transfer(), cb_events(), check_bridge(), common_exec(), console_transfer(), create_jb(), dahdi_handle_event(), dahdi_hangup(), export_aoc_vars(), get_refer_info(), handle_chanlist(), handle_hd_hf(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_refer(), handle_showchan(), key_call(), key_dial_page(), local_attended_transfer(), mgcp_hangup(), mgcp_ss(), misdn_transfer_bc(), mixmonitor_thread(), park_call_full(), schedule_delivery(), sip_read(), sip_set_rtp_peer(), socket_process(), ss_thread(), start_spying(), startmon(), TransferCallStep1(), and unistim_hangup().
04594 { 04595 struct ast_channel *bridged; 04596 bridged = chan->_bridge; 04597 if (bridged && bridged->tech->bridged_channel) 04598 bridged = bridged->tech->bridged_channel(chan, bridged); 04599 return bridged; 04600 }
int ast_call | ( | struct ast_channel * | chan, | |
char * | addr, | |||
int | timeout | |||
) |
Make a call.
chan | which channel to make the call on | |
addr | destination of the call | |
timeout | time to wait on for connect Place a call, take no longer than timeout ms. |
Definition at line 3909 of file channel.c.
References AST_CDR_FLAG_DIALED, ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, ast_set_flag, ast_test_flag, ast_channel_tech::call, ast_channel::cdr, chanlist::chan, and ast_channel::tech.
Referenced by __ast_request_and_dial(), agent_call(), ast_call_forward(), ast_feature_request_and_dial(), attempt_reconnect(), begin_dial_channel(), dial_exec_full(), do_forward(), do_idle_thread(), features_call(), findmeexec(), function_ilink(), ring_entry(), and rpt().
03910 { 03911 /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 03912 If the remote end does not answer within the timeout, then do NOT hang up, but 03913 return anyway. */ 03914 int res = -1; 03915 /* Stop if we're a zombie or need a soft hangup */ 03916 ast_channel_lock(chan); 03917 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) { 03918 if (chan->cdr) 03919 ast_set_flag(chan->cdr, AST_CDR_FLAG_DIALED); 03920 if (chan->tech->call) 03921 res = chan->tech->call(chan, addr, timeout); 03922 ast_set_flag(chan, AST_FLAG_OUTGOING); 03923 } 03924 ast_channel_unlock(chan); 03925 return res; 03926 }
struct ast_channel* ast_call_forward | ( | struct ast_channel * | caller, | |
struct ast_channel * | orig, | |||
int * | timeout, | |||
int | format, | |||
struct outgoing_helper * | oh, | |||
int * | outstate | |||
) |
Forwards a call to a new channel specified by the original channel's call_forward str. If possible, the new forwarded channel is created and returned while the original one is terminated.
caller | in channel that requested orig | |
orig | channel being replaced by the call forward channel | |
timeout | maximum amount of time to wait for setup of new forward channel | |
format | requested channel format | |
oh | outgoing helper used with original channel | |
outstate | reason why unsuccessful (if uncuccessful) |
Definition at line 3650 of file channel.c.
References outgoing_helper::account, ast_channel::accountcode, accountcode, ast_call(), AST_CDR_FLAG_ORIGINATED, ast_cdr_setaccount(), ast_channel_datastore_inherit(), ast_channel_inherit_variables(), ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_copy_flags, ast_copy_string(), ast_hangup(), ast_log(), ast_request(), ast_set_callerid(), ast_set_variables(), ast_string_field_set, ast_strlen_zero(), ast_channel::call_forward, ast_channel::cdr, CHANNEL_DEADLOCK_AVOIDANCE, ast_channel::cid, ast_callerid::cid_name, outgoing_helper::cid_name, ast_callerid::cid_num, outgoing_helper::cid_num, ast_channel::context, handle_cause(), LOG_NOTICE, outgoing_helper::parent_channel, pbx_builtin_getvar_helper(), S_OR, type, and outgoing_helper::vars.
Referenced by __ast_request_and_dial(), and ast_feature_request_and_dial().
03651 { 03652 char tmpchan[256]; 03653 struct ast_channel *new = NULL; 03654 char *data, *type; 03655 int cause = 0; 03656 03657 /* gather data and request the new forward channel */ 03658 ast_copy_string(tmpchan, orig->call_forward, sizeof(tmpchan)); 03659 if ((data = strchr(tmpchan, '/'))) { 03660 *data++ = '\0'; 03661 type = tmpchan; 03662 } else { 03663 const char *forward_context; 03664 ast_channel_lock(orig); 03665 forward_context = pbx_builtin_getvar_helper(orig, "FORWARD_CONTEXT"); 03666 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", orig->call_forward, S_OR(forward_context, orig->context)); 03667 ast_channel_unlock(orig); 03668 data = tmpchan; 03669 type = "Local"; 03670 } 03671 if (!(new = ast_request(type, format, data, &cause))) { 03672 ast_log(LOG_NOTICE, "Unable to create channel for call forward to '%s/%s' (cause = %d)\n", type, data, cause); 03673 handle_cause(cause, outstate); 03674 ast_hangup(orig); 03675 return NULL; 03676 } 03677 03678 /* Copy/inherit important information into new channel */ 03679 if (oh) { 03680 if (oh->vars) { 03681 ast_set_variables(new, oh->vars); 03682 } 03683 if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) { 03684 ast_set_callerid(new, oh->cid_num, oh->cid_name, oh->cid_num); 03685 } 03686 if (oh->parent_channel) { 03687 ast_channel_inherit_variables(oh->parent_channel, new); 03688 ast_channel_datastore_inherit(oh->parent_channel, new); 03689 } 03690 if (oh->account) { 03691 ast_cdr_setaccount(new, oh->account); 03692 } 03693 } else if (caller) { /* no outgoing helper so use caller if avaliable */ 03694 ast_channel_inherit_variables(caller, new); 03695 ast_channel_datastore_inherit(caller, new); 03696 } 03697 03698 ast_channel_lock(orig); 03699 while (ast_channel_trylock(new)) { 03700 CHANNEL_DEADLOCK_AVOIDANCE(orig); 03701 } 03702 ast_copy_flags(new->cdr, orig->cdr, AST_CDR_FLAG_ORIGINATED); 03703 ast_string_field_set(new, accountcode, orig->accountcode); 03704 if (!ast_strlen_zero(orig->cid.cid_num) && !ast_strlen_zero(new->cid.cid_name)) { 03705 ast_set_callerid(new, orig->cid.cid_num, orig->cid.cid_name, orig->cid.cid_num); 03706 } 03707 ast_channel_unlock(new); 03708 ast_channel_unlock(orig); 03709 03710 /* call new channel */ 03711 if ((*timeout = ast_call(new, data, 0))) { 03712 ast_log(LOG_NOTICE, "Unable to call forward to channel %s/%s\n", type, (char *)data); 03713 ast_hangup(orig); 03714 ast_hangup(new); 03715 return NULL; 03716 } 03717 ast_hangup(orig); 03718 03719 return new; 03720 }
void ast_cancel_shutdown | ( | void | ) |
Cancel a shutdown in progress.
Cancels an existing shutdown and returns to normal operation
Definition at line 511 of file channel.c.
Referenced by handle_abort_shutdown().
00512 { 00513 shutting_down = 0; 00514 }
const char* ast_cause2str | ( | int | state | ) |
Gives the string form of a given hangup cause.
state | cause to get the description of Give a name to a cause code Returns the text form of the binary cause code given |
Definition at line 624 of file channel.c.
References ARRAY_LEN, causes, and ast_cause::desc.
Referenced by __transmit_response(), ast_do_masquerade(), ast_hangup(), dial_exec_full(), findmeexec(), sip_hangup(), and transmit_request_with_auth().
00625 { 00626 int x; 00627 00628 for (x = 0; x < ARRAY_LEN(causes); x++) { 00629 if (causes[x].cause == cause) 00630 return causes[x].desc; 00631 } 00632 00633 return "Unknown"; 00634 }
void ast_change_name | ( | struct ast_channel * | chan, | |
char * | newname | |||
) |
Change channel name.
Definition at line 4161 of file channel.c.
References ast_string_field_set, chanlist::chan, EVENT_FLAG_CALL, manager_event, name, ast_channel::name, and ast_channel::uniqueid.
04162 { 04163 manager_event(EVENT_FLAG_CALL, "Rename", "Channel: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", chan->name, newname, chan->uniqueid); 04164 ast_string_field_set(chan, name, newname); 04165 }
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.
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 4888 of file channel.c.
References ast_channel::_bridge, ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_RETRY, ast_channel_make_compatible(), ast_check_hangup(), ast_check_hangup_locked(), ast_clear_flag, AST_CONTROL_SRCUPDATE, ast_debug, AST_FEATURE_PLAY_WARNING, AST_FEATURE_WARNING_ACTIVE, AST_FLAG_END_DTMF_ONLY, AST_FLAG_NBRIDGE, AST_FLAG_ZOMBIE, ast_generic_bridge(), ast_indicate(), ast_log(), ast_samp2tv(), ast_set_flag, AST_SOFTHANGUP_UNBRIDGE, ast_test_flag, ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), ast_verb, ast_channel::audiohooks, ast_channel_tech::bridge, bridge_playfile(), ast_channel::cid, ast_callerid::cid_num, config, EVENT_FLAG_CALL, ast_channel::generator, LOG_WARNING, manager_bridge_event(), manager_event, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::name, ast_channel::nativeformats, ast_channel::readformat, ast_channel_tech::send_digit_begin, ast_channel::tech, ast_channel::uniqueid, update_bridge_vars(), and ast_channel::writeformat.
Referenced by ast_bridge_call().
04890 { 04891 struct ast_channel *who = NULL; 04892 enum ast_bridge_result res = AST_BRIDGE_COMPLETE; 04893 int nativefailed=0; 04894 int firstpass; 04895 int o0nativeformats; 04896 int o1nativeformats; 04897 long time_left_ms=0; 04898 char caller_warning = 0; 04899 char callee_warning = 0; 04900 04901 if (c0->_bridge) { 04902 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 04903 c0->name, c0->_bridge->name); 04904 return -1; 04905 } 04906 if (c1->_bridge) { 04907 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 04908 c1->name, c1->_bridge->name); 04909 return -1; 04910 } 04911 04912 /* Stop if we're a zombie or need a soft hangup */ 04913 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 04914 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) 04915 return -1; 04916 04917 *fo = NULL; 04918 firstpass = config->firstpass; 04919 config->firstpass = 0; 04920 04921 if (ast_tvzero(config->start_time)) 04922 config->start_time = ast_tvnow(); 04923 time_left_ms = config->timelimit; 04924 04925 caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING); 04926 callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING); 04927 04928 if (config->start_sound && firstpass) { 04929 if (caller_warning) 04930 bridge_playfile(c0, c1, config->start_sound, time_left_ms / 1000); 04931 if (callee_warning) 04932 bridge_playfile(c1, c0, config->start_sound, time_left_ms / 1000); 04933 } 04934 04935 /* Keep track of bridge */ 04936 c0->_bridge = c1; 04937 c1->_bridge = c0; 04938 04939 04940 o0nativeformats = c0->nativeformats; 04941 o1nativeformats = c1->nativeformats; 04942 04943 if (config->feature_timer && !ast_tvzero(config->nexteventts)) { 04944 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->feature_timer, 1000)); 04945 } else if (config->timelimit && firstpass) { 04946 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 04947 if (caller_warning || callee_warning) 04948 config->nexteventts = ast_tvsub(config->nexteventts, ast_samp2tv(config->play_warning, 1000)); 04949 } 04950 04951 if (!c0->tech->send_digit_begin) 04952 ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY); 04953 if (!c1->tech->send_digit_begin) 04954 ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY); 04955 manager_bridge_event(1, 1, c0, c1); 04956 04957 /* Before we enter in and bridge these two together tell them both the source of audio has changed */ 04958 ast_indicate(c0, AST_CONTROL_SRCUPDATE); 04959 ast_indicate(c1, AST_CONTROL_SRCUPDATE); 04960 04961 for (/* ever */;;) { 04962 struct timeval now = { 0, }; 04963 int to; 04964 04965 to = -1; 04966 04967 if (!ast_tvzero(config->nexteventts)) { 04968 now = ast_tvnow(); 04969 to = ast_tvdiff_ms(config->nexteventts, now); 04970 if (to <= 0) { 04971 if (!config->timelimit) { 04972 res = AST_BRIDGE_COMPLETE; 04973 break; 04974 } 04975 to = 0; 04976 } 04977 } 04978 04979 if (config->timelimit) { 04980 time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time); 04981 if (time_left_ms < to) 04982 to = time_left_ms; 04983 04984 if (time_left_ms <= 0) { 04985 if (caller_warning && config->end_sound) 04986 bridge_playfile(c0, c1, config->end_sound, 0); 04987 if (callee_warning && config->end_sound) 04988 bridge_playfile(c1, c0, config->end_sound, 0); 04989 *fo = NULL; 04990 if (who) 04991 *rc = who; 04992 res = 0; 04993 break; 04994 } 04995 04996 if (!to) { 04997 if (time_left_ms >= 5000 && config->warning_sound && config->play_warning && ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) { 04998 int t = (time_left_ms + 500) / 1000; /* round to nearest second */ 04999 if (caller_warning) 05000 bridge_playfile(c0, c1, config->warning_sound, t); 05001 if (callee_warning) 05002 bridge_playfile(c1, c0, config->warning_sound, t); 05003 } 05004 if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000))) 05005 config->nexteventts = ast_tvadd(config->nexteventts, ast_samp2tv(config->warning_freq, 1000)); 05006 else 05007 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 05008 } 05009 ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE); 05010 } 05011 05012 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) { 05013 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 05014 c0->_softhangup = 0; 05015 if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 05016 c1->_softhangup = 0; 05017 c0->_bridge = c1; 05018 c1->_bridge = c0; 05019 ast_debug(1, "Unbridge signal received. Ending native bridge.\n"); 05020 continue; 05021 } 05022 05023 /* Stop if we're a zombie or need a soft hangup */ 05024 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 05025 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) { 05026 *fo = NULL; 05027 if (who) 05028 *rc = who; 05029 res = 0; 05030 ast_debug(1, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n", 05031 c0->name, c1->name, 05032 ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No", 05033 ast_check_hangup(c0) ? "Yes" : "No", 05034 ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No", 05035 ast_check_hangup(c1) ? "Yes" : "No"); 05036 break; 05037 } 05038 05039 update_bridge_vars(c0, c1); 05040 05041 if (c0->tech->bridge && 05042 (c0->tech->bridge == c1->tech->bridge) && 05043 !nativefailed && !c0->monitor && !c1->monitor && 05044 !c0->audiohooks && !c1->audiohooks && 05045 !c0->masq && !c0->masqr && !c1->masq && !c1->masqr) { 05046 /* Looks like they share a bridge method and nothing else is in the way */ 05047 ast_set_flag(c0, AST_FLAG_NBRIDGE); 05048 ast_set_flag(c1, AST_FLAG_NBRIDGE); 05049 if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, to)) == AST_BRIDGE_COMPLETE) { 05050 /* \todo XXX here should check that cid_num is not NULL */ 05051 manager_event(EVENT_FLAG_CALL, "Unlink", 05052 "Channel1: %s\r\n" 05053 "Channel2: %s\r\n" 05054 "Uniqueid1: %s\r\n" 05055 "Uniqueid2: %s\r\n" 05056 "CallerID1: %s\r\n" 05057 "CallerID2: %s\r\n", 05058 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 05059 ast_debug(1, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name); 05060 05061 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 05062 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 05063 05064 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 05065 continue; 05066 05067 c0->_bridge = NULL; 05068 c1->_bridge = NULL; 05069 05070 return res; 05071 } else { 05072 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 05073 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 05074 } 05075 switch (res) { 05076 case AST_BRIDGE_RETRY: 05077 if (config->play_warning) { 05078 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE); 05079 } 05080 continue; 05081 default: 05082 ast_verb(3, "Native bridging %s and %s ended\n", c0->name, c1->name); 05083 /* fallthrough */ 05084 case AST_BRIDGE_FAILED_NOWARN: 05085 nativefailed++; 05086 break; 05087 } 05088 } 05089 05090 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) || 05091 (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) && 05092 !(c0->generator || c1->generator)) { 05093 if (ast_channel_make_compatible(c0, c1)) { 05094 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name); 05095 manager_bridge_event(0, 1, c0, c1); 05096 return AST_BRIDGE_FAILED; 05097 } 05098 o0nativeformats = c0->nativeformats; 05099 o1nativeformats = c1->nativeformats; 05100 } 05101 05102 update_bridge_vars(c0, c1); 05103 05104 res = ast_generic_bridge(c0, c1, config, fo, rc, config->nexteventts); 05105 if (res != AST_BRIDGE_RETRY) { 05106 break; 05107 } else if (config->feature_timer) { 05108 /* feature timer expired but has not been updated, sending to ast_bridge_call to do so */ 05109 break; 05110 } 05111 } 05112 05113 ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY); 05114 ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY); 05115 05116 /* Now that we have broken the bridge the source will change yet again */ 05117 ast_indicate(c0, AST_CONTROL_SRCUPDATE); 05118 ast_indicate(c1, AST_CONTROL_SRCUPDATE); 05119 05120 c0->_bridge = NULL; 05121 c1->_bridge = NULL; 05122 05123 /* \todo XXX here should check that cid_num is not NULL */ 05124 manager_event(EVENT_FLAG_CALL, "Unlink", 05125 "Channel1: %s\r\n" 05126 "Channel2: %s\r\n" 05127 "Uniqueid1: %s\r\n" 05128 "Uniqueid2: %s\r\n" 05129 "CallerID1: %s\r\n" 05130 "CallerID2: %s\r\n", 05131 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 05132 ast_debug(1, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name); 05133 05134 return res; 05135 }
int ast_channel_cmpwhentohangup | ( | struct ast_channel * | chan, | |
time_t | offset | |||
) |
Compare a offset with the settings of when to hang a channel up.
chan | channel on which to check for hang up | |
offset | offset in seconds from current time |
Definition at line 531 of file channel.c.
References chanlist::chan, and ast_channel::whentohangup.
00532 { 00533 time_t whentohangup; 00534 00535 if (!chan->whentohangup) 00536 return (offset == 0) ? 0 : -1; 00537 00538 if (!offset) /* XXX why is this special? */ 00539 return 1; 00540 00541 whentohangup = offset + time(NULL); 00542 00543 if (chan->whentohangup < whentohangup) 00544 return 1; 00545 else if (chan->whentohangup == whentohangup) 00546 return 0; 00547 else 00548 return -1; 00549 }
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 1491 of file channel.c.
References AST_LIST_INSERT_HEAD, chanlist::chan, ast_channel::datastores, and ast_datastore::entry.
Referenced by _macro_exec(), acf_iaxvar_write(), add_features_datastores(), add_to_agi(), ast_iax2_new(), authenticate_reply(), dial_exec_full(), dundi_query_read(), enable_jack_hook(), enum_query_read(), get_lock(), gosub_exec(), lua_get_state(), pbx_builtin_raise_exception(), setup_chanspy_ds(), setup_inheritance_datastore(), setup_mixmonitor_ds(), setup_transfer_datastore(), shared_write(), smdi_msg_retrieve_read(), socket_process(), speech_create(), try_calling(), and volume_write().
01492 { 01493 int res = 0; 01494 01495 AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry); 01496 01497 return res; 01498 }
struct ast_datastore* ast_channel_datastore_alloc | ( | const struct ast_datastore_info * | info, | |
const char * | uid | |||
) |
Create a channel datastore structure.
Definition at line 1430 of file channel.c.
References ast_calloc, ast_strdup, and ast_datastore::info.
Referenced by _macro_exec(), acf_iaxvar_write(), add_features_datastores(), add_to_agi(), ast_channel_datastore_inherit(), ast_iax2_new(), authenticate_reply(), dial_exec_full(), dundi_query_read(), enable_jack_hook(), enum_query_read(), get_lock(), gosub_exec(), lua_get_state(), pbx_builtin_raise_exception(), setup_chanspy_ds(), setup_inheritance_datastore(), setup_mixmonitor_ds(), setup_transfer_datastore(), shared_write(), smdi_msg_retrieve_read(), socket_process(), speech_create(), try_calling(), and volume_write().
01431 { 01432 struct ast_datastore *datastore = NULL; 01433 01434 /* Make sure we at least have type so we can identify this */ 01435 if (!info) { 01436 return NULL; 01437 } 01438 01439 /* Allocate memory for datastore and clear it */ 01440 datastore = ast_calloc(1, sizeof(*datastore)); 01441 if (!datastore) { 01442 return NULL; 01443 } 01444 01445 datastore->info = info; 01446 01447 datastore->uid = ast_strdup(uid); 01448 01449 return datastore; 01450 }
struct ast_datastore* ast_channel_datastore_find | ( | struct ast_channel * | chan, | |
const struct ast_datastore_info * | info, | |||
const char * | uid | |||
) |
Find a datastore on a channel.
The datastore returned from this function must not be used if the reference to the channel is released.
Definition at line 1505 of file channel.c.
References AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, chanlist::chan, ast_channel::datastores, ast_datastore::entry, ast_datastore::info, and ast_datastore::uid.
Referenced by _macro_exec(), acf_exception_read(), acf_fetch(), acf_iaxvar_read(), acf_iaxvar_write(), add_agi_cmd(), add_features_datastores(), add_to_agi(), attended_transfer_occurred(), builtin_atxfer(), chanspy_ds_free(), dial_exec_full(), disable_jack_hook(), do_parking_thread(), dundi_result_read(), enable_jack_hook(), enum_result_read(), exec_odbcfinish(), find_speech(), func_inheritance_write(), get_agi_cmd(), get_lock(), gosub_exec(), iax2_call(), jack_hook_callback(), local_read(), local_write(), lua_get_state(), park_exec(), pbx_builtin_raise_exception(), pop_exec(), queue_transfer_fixup(), return_exec(), shared_read(), shared_write(), smdi_msg_read(), speech_background(), speech_destroy(), stop_mixmonitor_exec(), try_calling(), unlock_read(), volume_callback(), and volume_write().
01506 { 01507 struct ast_datastore *datastore = NULL; 01508 01509 if (info == NULL) 01510 return NULL; 01511 01512 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore, entry) { 01513 if (datastore->info == info) { 01514 if (uid != NULL && datastore->uid != NULL) { 01515 if (!strcasecmp(uid, datastore->uid)) { 01516 /* Matched by type AND uid */ 01517 break; 01518 } 01519 } else { 01520 /* Matched by type at least */ 01521 break; 01522 } 01523 } 01524 } 01525 AST_LIST_TRAVERSE_SAFE_END 01526 01527 return datastore; 01528 }
int ast_channel_datastore_free | ( | struct ast_datastore * | datastore | ) |
Free a channel datastore structure.
Definition at line 1452 of file channel.c.
References ast_free, ast_datastore::data, ast_datastore_info::destroy, ast_datastore::info, and ast_datastore::uid.
Referenced by acf_fetch(), add_features_datastores(), add_to_agi(), ast_channel_free(), ast_iax2_new(), authenticate_reply(), chanspy_ds_free(), dial_exec_full(), disable_jack_hook(), exec_odbcfinish(), get_lock(), gosub_exec(), lua_get_state(), pbx_builtin_raise_exception(), setup_inheritance_datastore(), shared_write(), socket_process(), try_calling(), and volume_write().
01453 { 01454 int res = 0; 01455 01456 /* Using the destroy function (if present) destroy the data */ 01457 if (datastore->info->destroy != NULL && datastore->data != NULL) { 01458 datastore->info->destroy(datastore->data); 01459 datastore->data = NULL; 01460 } 01461 01462 /* Free allocated UID memory */ 01463 if (datastore->uid != NULL) { 01464 ast_free((void *) datastore->uid); 01465 datastore->uid = NULL; 01466 } 01467 01468 /* Finally free memory used by ourselves */ 01469 ast_free(datastore); 01470 01471 return res; 01472 }
int ast_channel_datastore_inherit | ( | struct ast_channel * | from, | |
struct ast_channel * | to | |||
) |
Inherit datastores from a parent to a child.
Definition at line 1474 of file channel.c.
References ast_channel_datastore_alloc(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_datastore::data, DATASTORE_INHERIT_FOREVER, ast_channel::datastores, ast_datastore_info::duplicate, ast_datastore::entry, ast_datastore::info, ast_datastore::inheritance, and ast_datastore::uid.
Referenced by __ast_request_and_dial(), ast_call_forward(), dial_exec_full(), do_forward(), and local_call().
01475 { 01476 struct ast_datastore *datastore = NULL, *datastore2; 01477 01478 AST_LIST_TRAVERSE(&from->datastores, datastore, entry) { 01479 if (datastore->inheritance > 0) { 01480 datastore2 = ast_channel_datastore_alloc(datastore->info, datastore->uid); 01481 if (datastore2) { 01482 datastore2->data = datastore->info->duplicate ? datastore->info->duplicate(datastore->data) : NULL; 01483 datastore2->inheritance = datastore->inheritance == DATASTORE_INHERIT_FOREVER ? DATASTORE_INHERIT_FOREVER : datastore->inheritance - 1; 01484 AST_LIST_INSERT_TAIL(&to->datastores, datastore2, entry); 01485 } 01486 } 01487 } 01488 return 0; 01489 }
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 1500 of file channel.c.
References AST_LIST_REMOVE, chanlist::chan, ast_channel::datastores, and ast_datastore::entry.
Referenced by acf_fetch(), chanspy_ds_free(), dial_exec_full(), disable_jack_hook(), exec_odbcfinish(), lua_get_state(), queue_transfer_fixup(), speech_background(), speech_destroy(), and try_calling().
01501 { 01502 return AST_LIST_REMOVE(&chan->datastores, datastore, entry) ? 0 : -1; 01503 }
int ast_channel_defer_dtmf | ( | struct ast_channel * | chan | ) |
Set defer DTMF flag on channel.
Defer DTMF so that you only read things like hangups and audio. Returns non-zero if channel was already DTMF-deferred or 0 if channel is just now being DTMF-deferred
Definition at line 1120 of file channel.c.
References AST_FLAG_DEFER_DTMF, ast_set_flag, ast_test_flag, and chanlist::chan.
Referenced by find_cache().
01121 { 01122 int pre = 0; 01123 01124 if (chan) { 01125 pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF); 01126 ast_set_flag(chan, AST_FLAG_DEFER_DTMF); 01127 } 01128 return pre; 01129 }
int ast_channel_early_bridge | ( | struct ast_channel * | c0, | |
struct ast_channel * | c1 | |||
) |
Bridge two channels together (early).
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 4817 of file channel.c.
References ast_channel_tech::early_bridge, and ast_channel::tech.
Referenced by dial_exec_full(), and wait_for_answer().
04818 { 04819 /* Make sure we can early bridge, if not error out */ 04820 if (!c0->tech->early_bridge || (c1 && (!c1->tech->early_bridge || c0->tech->early_bridge != c1->tech->early_bridge))) 04821 return -1; 04822 04823 return c0->tech->early_bridge(c0, c1); 04824 }
void ast_channel_free | ( | struct ast_channel * | ) |
Free a channel structure.
Definition at line 1326 of file channel.c.
References ast_channel::alertpipe, ast_app_group_discard(), ast_cdr_discard(), ast_channel_datastore_free(), ast_channel_lock, AST_CHANNEL_NAME, ast_channel_unlock, ast_copy_string(), ast_device_state_changed_literal(), ast_free, ast_frfree, ast_jb_destroy(), AST_LIST_REMOVE_HEAD, ast_log(), AST_MAX_FDS, ast_moh_cleanup(), ast_mutex_destroy(), AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_string_field_free_memory, ast_translator_free_path(), ast_var_delete(), ast_channel::cdr, chanlist::chan, ast_channel::cid, ast_channel::datastores, ast_datastore::entry, f, free, free_cid(), ast_channel::lock_dont_use, LOG_ERROR, LOG_WARNING, ast_channel::monitor, ast_channel::music_state, ast_channel::name, name, ast_channel::pbx, ast_channel::readq, ast_channel::readtrans, ast_channel::sched, sched_context_destroy(), ast_channel_monitor::stop, ast_channel::tech_pvt, ast_channel::timingfd, ast_channel::varshead, and ast_channel::writetrans.
Referenced by acf_odbc_write(), action_getvar(), agent_cleanup(), agent_new(), ast_do_masquerade(), ast_hangup(), ast_iax2_new(), ast_pbx_outgoing_cdr_failed(), gtalk_newcall(), local_new(), make_email_file(), pbx_substitute_variables_helper_full(), rotate_file(), sendmail(), and sendpage().
01327 { 01328 int fd; 01329 #ifdef HAVE_EPOLL 01330 int i; 01331 #endif 01332 struct ast_var_t *vardata; 01333 struct ast_frame *f; 01334 struct varshead *headp; 01335 struct ast_datastore *datastore = NULL; 01336 char name[AST_CHANNEL_NAME], *dashptr; 01337 01338 headp=&chan->varshead; 01339 01340 AST_RWLIST_WRLOCK(&channels); 01341 if (!AST_RWLIST_REMOVE(&channels, chan, chan_list)) { 01342 ast_log(LOG_ERROR, "Unable to find channel in list to free. Assuming it has already been done.\n"); 01343 } 01344 /* Lock and unlock the channel just to be sure nobody has it locked still 01345 due to a reference retrieved from the channel list. */ 01346 ast_channel_lock(chan); 01347 ast_channel_unlock(chan); 01348 01349 /* Get rid of each of the data stores on the channel */ 01350 while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry))) 01351 /* Free the data store */ 01352 ast_channel_datastore_free(datastore); 01353 01354 /* Lock and unlock the channel just to be sure nobody has it locked still 01355 due to a reference that was stored in a datastore. (i.e. app_chanspy) */ 01356 ast_channel_lock(chan); 01357 ast_channel_unlock(chan); 01358 01359 if (chan->tech_pvt) { 01360 ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name); 01361 ast_free(chan->tech_pvt); 01362 } 01363 01364 if (chan->sched) 01365 sched_context_destroy(chan->sched); 01366 01367 ast_copy_string(name, chan->name, sizeof(name)); 01368 if ((dashptr = strrchr(name, '-'))) { 01369 *dashptr = '\0'; 01370 } 01371 01372 /* Stop monitoring */ 01373 if (chan->monitor) 01374 chan->monitor->stop( chan, 0 ); 01375 01376 /* If there is native format music-on-hold state, free it */ 01377 if (chan->music_state) 01378 ast_moh_cleanup(chan); 01379 01380 /* Free translators */ 01381 if (chan->readtrans) 01382 ast_translator_free_path(chan->readtrans); 01383 if (chan->writetrans) 01384 ast_translator_free_path(chan->writetrans); 01385 if (chan->pbx) 01386 ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name); 01387 free_cid(&chan->cid); 01388 /* Close pipes if appropriate */ 01389 if ((fd = chan->alertpipe[0]) > -1) 01390 close(fd); 01391 if ((fd = chan->alertpipe[1]) > -1) 01392 close(fd); 01393 if ((fd = chan->timingfd) > -1) 01394 close(fd); 01395 #ifdef HAVE_EPOLL 01396 for (i = 0; i < AST_MAX_FDS; i++) { 01397 if (chan->epfd_data[i]) 01398 free(chan->epfd_data[i]); 01399 } 01400 close(chan->epfd); 01401 #endif 01402 while ((f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list))) 01403 ast_frfree(f); 01404 01405 /* loop over the variables list, freeing all data and deleting list items */ 01406 /* no need to lock the list, as the channel is already locked */ 01407 01408 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries))) 01409 ast_var_delete(vardata); 01410 01411 ast_app_group_discard(chan); 01412 01413 /* Destroy the jitterbuffer */ 01414 ast_jb_destroy(chan); 01415 01416 if (chan->cdr) { 01417 ast_cdr_discard(chan->cdr); 01418 chan->cdr = NULL; 01419 } 01420 01421 ast_mutex_destroy(&chan->lock_dont_use); 01422 01423 ast_string_field_free_memory(chan); 01424 ast_free(chan); 01425 AST_RWLIST_UNLOCK(&channels); 01426 01427 ast_device_state_changed_literal(name); 01428 }
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 1696 of file channel.h.
References ast_channel_queryoption(), AST_OPTION_T38_STATE, chan, and T38_STATE_UNAVAILABLE.
Referenced by transmit().
01697 { 01698 enum ast_t38_state state = T38_STATE_UNAVAILABLE; 01699 int datalen = sizeof(state); 01700 01701 ast_channel_queryoption(chan, AST_OPTION_T38_STATE, &state, &datalen, 0); 01702 01703 return state; 01704 }
void ast_channel_inherit_variables | ( | const struct ast_channel * | parent, | |
struct ast_channel * | child | |||
) |
Inherits channel variable from parent to child channel.
parent | Parent channel | |
child | Child channel |
Definition at line 4167 of file channel.c.
References ast_debug, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_var_assign(), ast_var_full_name(), ast_var_name(), ast_var_value(), ast_var_t::entries, and ast_channel::varshead.
Referenced by __ast_request_and_dial(), agent_call(), ast_call_forward(), ast_feature_request_and_dial(), begin_dial_channel(), dial_exec_full(), do_forward(), findmeexec(), and ring_entry().
04168 { 04169 struct ast_var_t *current, *newvar; 04170 const char *varname; 04171 04172 AST_LIST_TRAVERSE(&parent->varshead, current, entries) { 04173 int vartype = 0; 04174 04175 varname = ast_var_full_name(current); 04176 if (!varname) 04177 continue; 04178 04179 if (varname[0] == '_') { 04180 vartype = 1; 04181 if (varname[1] == '_') 04182 vartype = 2; 04183 } 04184 04185 switch (vartype) { 04186 case 1: 04187 newvar = ast_var_assign(&varname[1], ast_var_value(current)); 04188 if (newvar) { 04189 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 04190 ast_debug(1, "Copying soft-transferable variable %s.\n", ast_var_name(newvar)); 04191 } 04192 break; 04193 case 2: 04194 newvar = ast_var_assign(varname, ast_var_value(current)); 04195 if (newvar) { 04196 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 04197 ast_debug(1, "Copying hard-transferable variable %s.\n", ast_var_name(newvar)); 04198 } 04199 break; 04200 default: 04201 ast_debug(1, "Not copying variable %s.\n", ast_var_name(current)); 04202 break; 04203 } 04204 } 04205 }
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 4065 of file channel.c.
References ast_channel_make_compatible_helper(), and chanlist::chan.
Referenced by action_bridge(), app_exec(), ast_channel_bridge(), bridge_exec(), check_compat(), dial_exec_full(), do_forward(), park_exec(), and wait_for_answer().
04066 { 04067 /* Some callers do not check return code, and we must try to set all call legs correctly */ 04068 int rc = 0; 04069 04070 /* Set up translation from the chan to the peer */ 04071 rc = ast_channel_make_compatible_helper(chan, peer); 04072 04073 if (rc < 0) 04074 return rc; 04075 04076 /* Set up translation from the peer to the chan */ 04077 rc = ast_channel_make_compatible_helper(peer, chan); 04078 04079 return rc; 04080 }
int ast_channel_masquerade | ( | struct ast_channel * | original, | |
struct ast_channel * | clone | |||
) |
Weird function made for call transfers.
original | channel to make a copy of | |
clone | copy of the original channel |
Definition at line 4082 of file channel.c.
References ast_channel::_bridge, ast_bridged_channel(), ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_debug, ast_log(), ast_null_frame, ast_queue_frame(), ast_channel_tech::get_base_channel, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::name, and ast_channel::tech.
Referenced by ast_async_goto(), ast_pickup_call(), attempt_transfer(), builtin_atxfer(), check_availability(), check_bridge(), check_goto_on_transfer(), do_bridge_masquerade(), handle_invite_replaces(), iax_park(), masq_park_call(), misdn_transfer_bc(), pickup_do(), and sip_park().
04083 { 04084 int res = -1; 04085 struct ast_channel *final_orig, *final_clone, *base; 04086 04087 retrymasq: 04088 final_orig = original; 04089 final_clone = clone; 04090 04091 ast_channel_lock(original); 04092 while (ast_channel_trylock(clone)) { 04093 ast_channel_unlock(original); 04094 usleep(1); 04095 ast_channel_lock(original); 04096 } 04097 04098 /* each of these channels may be sitting behind a channel proxy (i.e. chan_agent) 04099 and if so, we don't really want to masquerade it, but its proxy */ 04100 if (original->_bridge && (original->_bridge != ast_bridged_channel(original)) && (original->_bridge->_bridge != original)) 04101 final_orig = original->_bridge; 04102 04103 if (clone->_bridge && (clone->_bridge != ast_bridged_channel(clone)) && (clone->_bridge->_bridge != clone)) 04104 final_clone = clone->_bridge; 04105 04106 if (final_clone->tech->get_base_channel && (base = final_clone->tech->get_base_channel(final_clone))) { 04107 final_clone = base; 04108 } 04109 04110 if ((final_orig != original) || (final_clone != clone)) { 04111 /* Lots and lots of deadlock avoidance. The main one we're competing with 04112 * is ast_write(), which locks channels recursively, when working with a 04113 * proxy channel. */ 04114 if (ast_channel_trylock(final_orig)) { 04115 ast_channel_unlock(clone); 04116 ast_channel_unlock(original); 04117 goto retrymasq; 04118 } 04119 if (ast_channel_trylock(final_clone)) { 04120 ast_channel_unlock(final_orig); 04121 ast_channel_unlock(clone); 04122 ast_channel_unlock(original); 04123 goto retrymasq; 04124 } 04125 ast_channel_unlock(clone); 04126 ast_channel_unlock(original); 04127 original = final_orig; 04128 clone = final_clone; 04129 } 04130 04131 if (original == clone) { 04132 ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name); 04133 ast_channel_unlock(clone); 04134 ast_channel_unlock(original); 04135 return -1; 04136 } 04137 04138 ast_debug(1, "Planning to masquerade channel %s into the structure of %s\n", 04139 clone->name, original->name); 04140 if (original->masq) { 04141 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 04142 original->masq->name, original->name); 04143 } else if (clone->masqr) { 04144 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 04145 clone->name, clone->masqr->name); 04146 } else { 04147 original->masq = clone; 04148 clone->masqr = original; 04149 ast_queue_frame(original, &ast_null_frame); 04150 ast_queue_frame(clone, &ast_null_frame); 04151 ast_debug(1, "Done planning to masquerade channel %s into the structure of %s\n", clone->name, original->name); 04152 res = 0; 04153 } 04154 04155 ast_channel_unlock(clone); 04156 ast_channel_unlock(original); 04157 04158 return res; 04159 }
int ast_channel_queryoption | ( | struct ast_channel * | channel, | |
int | option, | |||
void * | data, | |||
int * | datalen, | |||
int | block | |||
) |
Query the value of an option Works similarly to setoption except only reads the options.
Definition at line 5151 of file channel.c.
References ast_log(), chan, errno, LOG_ERROR, ast_channel_tech::queryoption, and ast_channel::tech.
Referenced by ast_channel_get_t38_state().
05152 { 05153 if (!chan->tech->queryoption) { 05154 errno = ENOSYS; 05155 return -1; 05156 } 05157 05158 if (block) 05159 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 05160 05161 return chan->tech->queryoption(chan, option, data, datalen); 05162 }
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 3614 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().
03615 { 03616 switch (reason) /* the following appear to be the only ones actually returned by request_and_dial */ 03617 { 03618 case 0: 03619 return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)"; 03620 case AST_CONTROL_HANGUP: 03621 return "Hangup"; 03622 case AST_CONTROL_RING: 03623 return "Local Ring"; 03624 case AST_CONTROL_RINGING: 03625 return "Remote end Ringing"; 03626 case AST_CONTROL_ANSWER: 03627 return "Remote end has Answered"; 03628 case AST_CONTROL_BUSY: 03629 return "Remote end is Busy"; 03630 case AST_CONTROL_CONGESTION: 03631 return "Congestion (circuits busy)"; 03632 default: 03633 return "Unknown Reason!!"; 03634 } 03635 }
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 552 of file channel.c.
References ast_calloc, ast_debug, AST_LIST_INSERT_HEAD, AST_LIST_TRAVERSE, ast_log(), AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, chanlist::chan, chanlist::list, LOG_WARNING, ast_channel::tech, chanlist::tech, and ast_channel_tech::type.
Referenced by load_module(), and unload_module().
00553 { 00554 struct chanlist *chan; 00555 00556 AST_RWLIST_WRLOCK(&channels); 00557 00558 AST_LIST_TRAVERSE(&backends, chan, list) { 00559 if (!strcasecmp(tech->type, chan->tech->type)) { 00560 ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type); 00561 AST_RWLIST_UNLOCK(&channels); 00562 return -1; 00563 } 00564 } 00565 00566 if (!(chan = ast_calloc(1, sizeof(*chan)))) { 00567 AST_RWLIST_UNLOCK(&channels); 00568 return -1; 00569 } 00570 chan->tech = tech; 00571 AST_LIST_INSERT_HEAD(&backends, chan, list); 00572 00573 ast_debug(1, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description); 00574 00575 ast_verb(2, "Registered channel type '%s' (%s)\n", chan->tech->type, chan->tech->description); 00576 00577 AST_RWLIST_UNLOCK(&channels); 00578 return 0; 00579 }
int ast_channel_sendhtml | ( | struct ast_channel * | channel, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) |
Send HTML or URL on link. Returns 0 on success or -1 on failure
Definition at line 4011 of file channel.c.
References chanlist::chan, ast_channel_tech::send_html, and ast_channel::tech.
Referenced by agent_sendhtml(), ast_channel_sendurl(), and wait_for_answer().
04012 { 04013 if (chan->tech->send_html) 04014 return chan->tech->send_html(chan, subclass, data, datalen); 04015 return -1; 04016 }
int ast_channel_sendurl | ( | struct ast_channel * | channel, | |
const char * | url | |||
) |
Send URL on link. Returns 0 on success or -1 on failure
Definition at line 4018 of file channel.c.
References ast_channel_sendhtml(), AST_HTML_URL, and chanlist::chan.
Referenced by dial_exec_full(), and sendurl_exec().
04019 { 04020 return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1); 04021 }
void ast_channel_set_fd | ( | struct ast_channel * | chan, | |
int | which, | |||
int | fd | |||
) |
Set the file descriptor on the channel
Definition at line 1531 of file channel.c.
References ast_calloc, chanlist::chan, ast_channel::data, ast_channel::fds, and free.
Referenced by __ast_channel_alloc_ap(), __oh323_new(), __oh323_rtp_create(), __oh323_update_info(), alsa_new(), ast_deactivate_generator(), ast_do_masquerade(), dahdi_new(), gtalk_new(), jingle_new(), mgcp_new(), misdn_new(), nbs_new(), oss_new(), phone_new(), pri_assign_bearer(), pri_fixup_principle(), restore_channel(), setformat(), sip_new(), skinny_new(), start_rtp(), swap_subs(), and update_features().
01532 { 01533 #ifdef HAVE_EPOLL 01534 struct epoll_event ev; 01535 struct ast_epoll_data *aed = NULL; 01536 01537 if (chan->fds[which] > -1) { 01538 epoll_ctl(chan->epfd, EPOLL_CTL_DEL, chan->fds[which], &ev); 01539 aed = chan->epfd_data[which]; 01540 } 01541 01542 /* If this new fd is valid, add it to the epoll */ 01543 if (fd > -1) { 01544 if (!aed && (!(aed = ast_calloc(1, sizeof(*aed))))) 01545 return; 01546 01547 chan->epfd_data[which] = aed; 01548 aed->chan = chan; 01549 aed->which = which; 01550 01551 ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP; 01552 ev.data.ptr = aed; 01553 epoll_ctl(chan->epfd, EPOLL_CTL_ADD, fd, &ev); 01554 } else if (aed) { 01555 /* We don't have to keep around this epoll data structure now */ 01556 free(aed); 01557 chan->epfd_data[which] = NULL; 01558 } 01559 #endif 01560 chan->fds[which] = fd; 01561 return; 01562 }
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 Returns 0 on success and -1 on failure |
Definition at line 5138 of file channel.c.
References ast_log(), chan, errno, LOG_ERROR, ast_channel_tech::setoption, and ast_channel::tech.
Referenced by ast_bridge_call(), common_exec(), conf_run(), dahdi_hangup(), dial_exec_full(), func_channel_write(), handle_tddmode(), play_record_review(), reset_volumes(), rpt(), set_listen_volume(), set_talk_volume(), and vm_forwardoptions().
05139 { 05140 if (!chan->tech->setoption) { 05141 errno = ENOSYS; 05142 return -1; 05143 } 05144 05145 if (block) 05146 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 05147 05148 return chan->tech->setoption(chan, option, data, datalen); 05149 }
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 from current time of when to hang up |
Definition at line 523 of file channel.c.
References ast_null_frame, ast_queue_frame(), chanlist::chan, and ast_channel::whentohangup.
Referenced by action_timeout(), and timeout_write().
00524 { 00525 chan->whentohangup = offset ? time(NULL) + offset : 0; 00526 ast_queue_frame(chan, &ast_null_frame); 00527 return; 00528 }
struct ast_silence_generator* ast_channel_start_silence_generator | ( | struct ast_channel * | chan | ) |
Starts a silence generator on the given channel.
chan | The channel to generate silence on |
The pointer returned by this function must be preserved and passed to ast_channel_stop_silence_generator when you wish to stop the silence generation.
Definition at line 5471 of file channel.c.
References ast_activate_generator(), ast_calloc, ast_debug, AST_FORMAT_SLINEAR, ast_free, ast_log(), ast_set_write_format(), chan, LOG_ERROR, ast_channel::name, ast_silence_generator::old_write_format, silence_generator, and ast_channel::writeformat.
Referenced by __ast_play_and_record(), ast_dtmf_stream(), channel_spy(), and TransferCallStep1().
05472 { 05473 struct ast_silence_generator *state; 05474 05475 if (!(state = ast_calloc(1, sizeof(*state)))) { 05476 return NULL; 05477 } 05478 05479 state->old_write_format = chan->writeformat; 05480 05481 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) { 05482 ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n"); 05483 ast_free(state); 05484 return NULL; 05485 } 05486 05487 ast_activate_generator(chan, &silence_generator, state); 05488 05489 ast_debug(1, "Started silence generator on '%s'\n", chan->name); 05490 05491 return state; 05492 }
void ast_channel_stop_silence_generator | ( | struct ast_channel * | chan, | |
struct ast_silence_generator * | state | |||
) |
Stops a previously-started silence generator on the given channel.
chan | The channel to operate on | |
state | The ast_silence_generator pointer return by a previous call to ast_channel_start_silence_generator. |
Definition at line 5494 of file channel.c.
References ast_deactivate_generator(), ast_debug, ast_free, ast_log(), ast_set_write_format(), chan, LOG_ERROR, ast_channel::name, and ast_silence_generator::old_write_format.
Referenced by __ast_play_and_record(), ast_dtmf_stream(), channel_spy(), HandleCallOutgoing(), key_dial_page(), and unistim_hangup().
05495 { 05496 if (!state) 05497 return; 05498 05499 ast_deactivate_generator(chan); 05500 05501 ast_debug(1, "Stopped silence generator on '%s'\n", chan->name); 05502 05503 if (ast_set_write_format(chan, state->old_write_format) < 0) 05504 ast_log(LOG_ERROR, "Could not return write format to its original state\n"); 05505 05506 ast_free(state); 05507 }
int ast_channel_supports_html | ( | struct ast_channel * | channel | ) |
Returns 0 if channel does not support HTML or non-zero if it does
Definition at line 4006 of file channel.c.
References chanlist::chan, ast_channel_tech::send_html, and ast_channel::tech.
Referenced by dial_exec_full(), and sendurl_exec().
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 1132 of file channel.c.
References ast_clear_flag, AST_FLAG_DEFER_DTMF, and chanlist::chan.
Referenced by find_cache(), and rpt_call().
01133 { 01134 if (chan) 01135 ast_clear_flag(chan, AST_FLAG_DEFER_DTMF); 01136 }
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 582 of file channel.c.
References ast_debug, ast_free, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, chanlist::chan, chanlist::list, ast_channel::tech, chanlist::tech, and ast_channel_tech::type.
Referenced by __unload_module(), load_module(), and unload_module().
00583 { 00584 struct chanlist *chan; 00585 00586 ast_debug(1, "Unregistering channel type '%s'\n", tech->type); 00587 00588 AST_RWLIST_WRLOCK(&channels); 00589 00590 AST_LIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) { 00591 if (chan->tech == tech) { 00592 AST_LIST_REMOVE_CURRENT(list); 00593 ast_free(chan); 00594 ast_verb(2, "Unregistered channel type '%s'\n", tech->type); 00595 break; 00596 } 00597 } 00598 AST_LIST_TRAVERSE_SAFE_END; 00599 00600 AST_RWLIST_UNLOCK(&channels); 00601 }
struct ast_channel* ast_channel_walk_locked | ( | const struct ast_channel * | prev | ) |
Browse channels in use Browse the channels currently in use.
prev | where you want to start in the channel list |
Definition at line 1246 of file channel.c.
References channel_find_locked().
Referenced by action_coreshowchannels(), action_status(), ast_complete_channels(), ast_pickup_call(), conf_exec(), handle_chanlist(), handle_core_set_debug_channel(), next_channel(), pickup_by_exten(), and pickup_by_mark().
01247 { 01248 return channel_find_locked(prev, NULL, 0, NULL, NULL); 01249 }
struct ast_variable* ast_channeltype_list | ( | void | ) |
return an ast_variable list of channeltypes
Definition at line 188 of file channel.c.
References AST_LIST_TRAVERSE, ast_variable_new(), ast_channel_tech::description, chanlist::list, chanlist::tech, ast_channel_tech::type, and var.
00189 { 00190 struct chanlist *cl; 00191 struct ast_variable *var=NULL, *prev = NULL; 00192 AST_LIST_TRAVERSE(&backends, cl, list) { 00193 if (prev) { 00194 if ((prev->next = ast_variable_new(cl->tech->type, cl->tech->description, ""))) 00195 prev = prev->next; 00196 } else { 00197 var = ast_variable_new(cl->tech->type, cl->tech->description, ""); 00198 prev = var; 00199 } 00200 } 00201 return var; 00202 }
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 464 of file channel.c.
References ast_channel::_softhangup, AST_SOFTHANGUP_TIMEOUT, chanlist::chan, and ast_channel::whentohangup.
Referenced by __ast_read(), _macro_exec(), action_redirect(), agent_indicate(), agi_exec(), agi_handle_command(), announce_thread(), ast_bridge_call(), ast_bridge_call_thread(), ast_call(), ast_channel_bridge(), ast_check_hangup_locked(), ast_feature_request_and_dial(), ast_indicate_data(), ast_raw_answer(), ast_readstring_full(), ast_recvtext(), ast_rtp_bridge(), ast_sendtext(), ast_transfer(), ast_udptl_bridge(), ast_waitfordigit_full(), ast_write(), autoservice_run(), bridge_exec(), bridge_native_loop(), builtin_atxfer(), channel_spy(), check_bridge(), common_exec(), conf_play(), conf_run(), dahdi_sendtext(), dahdi_setoption(), dial_exec_full(), dundi_lookup_internal(), eagi_exec(), eivr_comm(), findmeexec(), handle_sendimage(), launch_asyncagi(), lua_check_hangup(), ospfinished_exec(), pbx_exec(), read_exec(), readexten_exec(), rpt(), and run_ras().
00465 { 00466 if (chan->_softhangup) /* yes if soft hangup flag set */ 00467 return 1; 00468 if (!chan->whentohangup) /* no if no hangup scheduled */ 00469 return 0; 00470 if (chan->whentohangup > time(NULL)) /* no if hangup time has not come yet. */ 00471 return 0; 00472 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT; /* record event */ 00473 return 1; 00474 }
void ast_deactivate_generator | ( | struct ast_channel * | chan | ) |
Deactivate an active generator
Definition at line 1897 of file channel.c.
References ast_channel_lock, ast_channel_set_fd(), ast_channel_unlock, ast_clear_flag, AST_FLAG_WRITE_INT, AST_GENERATOR_FD, ast_settimeout(), chanlist::chan, ast_channel::generator, ast_channel::generatordata, and ast_generator::release.
Referenced by __ast_read(), app_exec(), ast_channel_stop_silence_generator(), ast_openstream_full(), ast_playtones_stop(), ast_quiet_chan(), ast_read_generator_actions(), ast_tonepair_stop(), ast_write(), cb_events(), channel_spy(), dial_exec_full(), generator_force(), local_ast_moh_stop(), old_milliwatt_exec(), transmit_audio(), and wait_for_answer().
01898 { 01899 ast_channel_lock(chan); 01900 if (chan->generatordata) { 01901 if (chan->generator && chan->generator->release) 01902 chan->generator->release(chan, chan->generatordata); 01903 chan->generatordata = NULL; 01904 chan->generator = NULL; 01905 ast_channel_set_fd(chan, AST_GENERATOR_FD, -1); 01906 ast_clear_flag(chan, AST_FLAG_WRITE_INT); 01907 ast_settimeout(chan, 0, NULL, NULL); 01908 } 01909 ast_channel_unlock(chan); 01910 }
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.
Definition at line 4258 of file channel.c.
References ast_channel::_softhangup, ast_channel::_state, ast_channel::adsicpe, ast_channel::alertpipe, ast_app_group_update(), ast_cause2str(), ast_channel_free(), ast_channel_lock, AST_CHANNEL_NAME, ast_channel_set_fd(), ast_channel_unlock, ast_copy_string(), ast_debug, AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, AST_GENERATOR_FD, ast_indicate(), AST_LIST_APPEND_LIST, AST_LIST_FIRST, AST_LIST_HEAD_NOLOCK, AST_LIST_HEAD_SET_NOLOCK, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), AST_MAX_FDS, ast_null_frame, ast_queue_frame(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_SOFTHANGUP_DEV, ast_state2str(), ast_string_field_set, ast_test_flag, AST_TIMING_FD, ast_channel::blocker, ast_channel::cdr, ast_datastore_info::chan_fixup, ast_channel::cid, clone_variables(), ast_datastore::data, ast_channel::datastores, ast_datastore::entry, errno, EVENT_FLAG_CALL, ast_channel::fdno, ast_channel::fds, ast_channel_tech::fixup, free_translation(), ast_channel_tech::hangup, ast_datastore::info, ast_channel::language, language, ast_channel::lock_dont_use, LOG_WARNING, manager_event, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, musicclass, name, ast_channel::name, ast_channel::nativeformats, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::readq, report_new_callerid(), ast_channel::tech, ast_channel::tech_pvt, ast_channel::timingfd, ast_channel_tech::type, ast_channel::uniqueid, ast_channel::visible_indication, and ast_channel::writeformat.
Referenced by __ast_read(), ast_async_goto(), ast_hangup(), ast_waitfor_nandfds(), ast_write(), do_bridge_masquerade(), iax_park(), sip_park(), and sip_park_thread().
04259 { 04260 int x,i; 04261 int res=0; 04262 int origstate; 04263 struct ast_frame *cur; 04264 const struct ast_channel_tech *t; 04265 void *t_pvt; 04266 struct ast_callerid tmpcid; 04267 struct ast_channel *clone = original->masq; 04268 struct ast_cdr *cdr; 04269 int rformat = original->readformat; 04270 int wformat = original->writeformat; 04271 char newn[AST_CHANNEL_NAME]; 04272 char orig[AST_CHANNEL_NAME]; 04273 char masqn[AST_CHANNEL_NAME]; 04274 char zombn[AST_CHANNEL_NAME]; 04275 04276 ast_debug(4, "Actually Masquerading %s(%d) into the structure of %s(%d)\n", 04277 clone->name, clone->_state, original->name, original->_state); 04278 04279 manager_event(EVENT_FLAG_CALL, "Masquerade", "Clone: %s\r\nCloneState: %s\r\nOriginal: %s\r\nOriginalState: %s\r\n", 04280 clone->name, ast_state2str(clone->_state), original->name, ast_state2str(original->_state)); 04281 04282 /* XXX This is a seriously wacked out operation. We're essentially putting the guts of 04283 the clone channel into the original channel. Start by killing off the original 04284 channel's backend. I'm not sure we're going to keep this function, because 04285 while the features are nice, the cost is very high in terms of pure nastiness. XXX */ 04286 04287 /* We need the clone's lock, too */ 04288 ast_channel_lock(clone); 04289 04290 ast_debug(2, "Got clone lock for masquerade on '%s' at %p\n", clone->name, &clone->lock_dont_use); 04291 04292 /* Having remembered the original read/write formats, we turn off any translation on either 04293 one */ 04294 free_translation(clone); 04295 free_translation(original); 04296 04297 04298 /* Unlink the masquerade */ 04299 original->masq = NULL; 04300 clone->masqr = NULL; 04301 04302 /* Save the original name */ 04303 ast_copy_string(orig, original->name, sizeof(orig)); 04304 /* Save the new name */ 04305 ast_copy_string(newn, clone->name, sizeof(newn)); 04306 /* Create the masq name */ 04307 snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn); 04308 04309 /* Copy the name from the clone channel */ 04310 ast_string_field_set(original, name, newn); 04311 04312 /* Mangle the name of the clone channel */ 04313 ast_string_field_set(clone, name, masqn); 04314 04315 /* Notify any managers of the change, first the masq then the other */ 04316 manager_event(EVENT_FLAG_CALL, "Rename", "Channel: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", newn, masqn, clone->uniqueid); 04317 manager_event(EVENT_FLAG_CALL, "Rename", "Channel: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", orig, newn, original->uniqueid); 04318 04319 /* Swap the technologies */ 04320 t = original->tech; 04321 original->tech = clone->tech; 04322 clone->tech = t; 04323 04324 /* Swap the cdrs */ 04325 cdr = original->cdr; 04326 original->cdr = clone->cdr; 04327 clone->cdr = cdr; 04328 04329 t_pvt = original->tech_pvt; 04330 original->tech_pvt = clone->tech_pvt; 04331 clone->tech_pvt = t_pvt; 04332 04333 /* Swap the alertpipes */ 04334 for (i = 0; i < 2; i++) { 04335 x = original->alertpipe[i]; 04336 original->alertpipe[i] = clone->alertpipe[i]; 04337 clone->alertpipe[i] = x; 04338 } 04339 04340 /* 04341 * Swap the readq's. The end result should be this: 04342 * 04343 * 1) All frames should be on the new (original) channel. 04344 * 2) Any frames that were already on the new channel before this 04345 * masquerade need to be at the end of the readq, after all of the 04346 * frames on the old (clone) channel. 04347 * 3) The alertpipe needs to get poked for every frame that was already 04348 * on the new channel, since we are now using the alert pipe from the 04349 * old (clone) channel. 04350 */ 04351 { 04352 AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq; 04353 AST_LIST_HEAD_SET_NOLOCK(&tmp_readq, NULL); 04354 04355 AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list); 04356 AST_LIST_APPEND_LIST(&original->readq, &clone->readq, frame_list); 04357 04358 while ((cur = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) { 04359 AST_LIST_INSERT_TAIL(&original->readq, cur, frame_list); 04360 if (original->alertpipe[1] > -1) { 04361 int poke = 0; 04362 04363 if (write(original->alertpipe[1], &poke, sizeof(poke)) < 0) { 04364 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 04365 } 04366 } 04367 } 04368 } 04369 04370 /* Swap the raw formats */ 04371 x = original->rawreadformat; 04372 original->rawreadformat = clone->rawreadformat; 04373 clone->rawreadformat = x; 04374 x = original->rawwriteformat; 04375 original->rawwriteformat = clone->rawwriteformat; 04376 clone->rawwriteformat = x; 04377 04378 clone->_softhangup = AST_SOFTHANGUP_DEV; 04379 04380 /* And of course, so does our current state. Note we need not 04381 call ast_setstate since the event manager doesn't really consider 04382 these separate. We do this early so that the clone has the proper 04383 state of the original channel. */ 04384 origstate = original->_state; 04385 original->_state = clone->_state; 04386 clone->_state = origstate; 04387 04388 if (clone->tech->fixup){ 04389 res = clone->tech->fixup(original, clone); 04390 if (res) 04391 ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name); 04392 } 04393 04394 /* Start by disconnecting the original's physical side */ 04395 if (clone->tech->hangup) 04396 res = clone->tech->hangup(clone); 04397 if (res) { 04398 ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n"); 04399 ast_channel_unlock(clone); 04400 return -1; 04401 } 04402 04403 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig); 04404 /* Mangle the name of the clone channel */ 04405 ast_string_field_set(clone, name, zombn); 04406 manager_event(EVENT_FLAG_CALL, "Rename", "Channel: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", masqn, zombn, clone->uniqueid); 04407 04408 /* Update the type. */ 04409 t_pvt = original->monitor; 04410 original->monitor = clone->monitor; 04411 clone->monitor = t_pvt; 04412 04413 /* Keep the same language. */ 04414 ast_string_field_set(original, language, clone->language); 04415 /* Copy the FD's other than the generator fd */ 04416 for (x = 0; x < AST_MAX_FDS; x++) { 04417 if (x != AST_GENERATOR_FD) 04418 ast_channel_set_fd(original, x, clone->fds[x]); 04419 } 04420 04421 ast_app_group_update(clone, original); 04422 04423 /* Move data stores over */ 04424 if (AST_LIST_FIRST(&clone->datastores)) { 04425 struct ast_datastore *ds; 04426 /* We use a safe traversal here because some fixup routines actually 04427 * remove the datastore from the list and free them. 04428 */ 04429 AST_LIST_TRAVERSE_SAFE_BEGIN(&clone->datastores, ds, entry) { 04430 if (ds->info->chan_fixup) 04431 ds->info->chan_fixup(ds->data, clone, original); 04432 } 04433 AST_LIST_TRAVERSE_SAFE_END; 04434 AST_LIST_APPEND_LIST(&original->datastores, &clone->datastores, entry); 04435 } 04436 04437 clone_variables(original, clone); 04438 /* Presense of ADSI capable CPE follows clone */ 04439 original->adsicpe = clone->adsicpe; 04440 /* Bridge remains the same */ 04441 /* CDR fields remain the same */ 04442 /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */ 04443 /* Application and data remain the same */ 04444 /* Clone exception becomes real one, as with fdno */ 04445 ast_set_flag(original, ast_test_flag(clone, AST_FLAG_OUTGOING | AST_FLAG_EXCEPTION)); 04446 original->fdno = clone->fdno; 04447 /* Schedule context remains the same */ 04448 /* Stream stuff stays the same */ 04449 /* Keep the original state. The fixup code will need to work with it most likely */ 04450 04451 /* Just swap the whole structures, nevermind the allocations, they'll work themselves 04452 out. */ 04453 tmpcid = original->cid; 04454 original->cid = clone->cid; 04455 clone->cid = tmpcid; 04456 report_new_callerid(original); 04457 04458 /* Restore original timing file descriptor */ 04459 ast_channel_set_fd(original, AST_TIMING_FD, original->timingfd); 04460 04461 /* Our native formats are different now */ 04462 original->nativeformats = clone->nativeformats; 04463 04464 /* Context, extension, priority, app data, jump table, remain the same */ 04465 /* pvt switches. pbx stays the same, as does next */ 04466 04467 /* Set the write format */ 04468 ast_set_write_format(original, wformat); 04469 04470 /* Set the read format */ 04471 ast_set_read_format(original, rformat); 04472 04473 /* Copy the music class */ 04474 ast_string_field_set(original, musicclass, clone->musicclass); 04475 04476 ast_debug(1, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat); 04477 04478 /* Okay. Last thing is to let the channel driver know about all this mess, so he 04479 can fix up everything as best as possible */ 04480 if (original->tech->fixup) { 04481 res = original->tech->fixup(clone, original); 04482 if (res) { 04483 ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n", 04484 original->tech->type, original->name); 04485 ast_channel_unlock(clone); 04486 return -1; 04487 } 04488 } else 04489 ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)! Bad things may happen.\n", 04490 original->tech->type, original->name); 04491 04492 /* 04493 * If an indication is currently playing, maintain it on the channel 04494 * that is taking the place of original 04495 * 04496 * This is needed because the masquerade is swapping out in the internals 04497 * of this channel, and the new channel private data needs to be made 04498 * aware of the current visible indication (RINGING, CONGESTION, etc.) 04499 */ 04500 if (original->visible_indication) { 04501 ast_indicate(original, original->visible_indication); 04502 } 04503 04504 /* Now, at this point, the "clone" channel is totally F'd up. We mark it as 04505 a zombie so nothing tries to touch it. If it's already been marked as a 04506 zombie, then free it now (since it already is considered invalid). */ 04507 if (ast_test_flag(clone, AST_FLAG_ZOMBIE)) { 04508 ast_debug(1, "Destroying channel clone '%s'\n", clone->name); 04509 ast_channel_unlock(clone); 04510 manager_event(EVENT_FLAG_CALL, "Hangup", 04511 "Channel: %s\r\n" 04512 "Uniqueid: %s\r\n" 04513 "Cause: %d\r\n" 04514 "Cause-txt: %s\r\n", 04515 clone->name, 04516 clone->uniqueid, 04517 clone->hangupcause, 04518 ast_cause2str(clone->hangupcause) 04519 ); 04520 ast_channel_free(clone); 04521 } else { 04522 ast_debug(1, "Released clone lock on '%s'\n", clone->name); 04523 ast_set_flag(clone, AST_FLAG_ZOMBIE); 04524 ast_queue_frame(clone, &ast_null_frame); 04525 ast_channel_unlock(clone); 04526 } 04527 04528 /* Signal any blocker */ 04529 if (ast_test_flag(original, AST_FLAG_BLOCKING)) 04530 pthread_kill(original->blocker, SIGURG); 04531 ast_debug(1, "Done Masquerading %s (%d)\n", original->name, original->_state); 04532 return 0; 04533 }
static int ast_fdisset | ( | struct pollfd * | pfds, | |
int | fd, | |||
int | max, | |||
int * | start | |||
) | [inline, static] |
Helper function for migrating select to poll.
Definition at line 1628 of file channel.h.
References dummy().
01629 { 01630 int x; 01631 int dummy=0; 01632 01633 if (fd < 0) 01634 return 0; 01635 if (!start) 01636 start = &dummy; 01637 for (x = *start; x<max; x++) 01638 if (pfds[x].fd == fd) { 01639 if (x == *start) 01640 (*start)++; 01641 return pfds[x].revents; 01642 } 01643 return 0; 01644 }
struct ast_channel* ast_get_channel_by_exten_locked | ( | const char * | exten, | |
const char * | context | |||
) |
Get channel by exten (and optionally context) and lock it.
Definition at line 1271 of file channel.c.
References channel_find_locked().
01272 { 01273 return channel_find_locked(NULL, NULL, 0, context, exten); 01274 }
struct ast_channel* ast_get_channel_by_name_locked | ( | const char * | chan | ) |
Get channel by name or uniqueid (locks channel).
Definition at line 1252 of file channel.c.
References channel_find_locked().
Referenced by acf_import(), action_add_agi_cmd(), 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(), get_dahdi_channel_locked(), handle_channelstatus(), handle_cli_agi_add_cmd(), handle_core_set_debug_channel(), handle_getvariablefull(), handle_hangup(), handle_set_chanvar(), handle_showchan(), handle_softhangup(), manager_park(), manager_play_dtmf(), park_call_full(), pbx_builtin_importvar(), shared_read(), shared_write(), start_monitor_action(), and stop_monitor_action().
01253 { 01254 return channel_find_locked(NULL, name, 0, NULL, NULL); 01255 }
struct ast_channel* ast_get_channel_by_name_prefix_locked | ( | const char * | name, | |
const int | namelen | |||
) |
Get channel by name or uniqueid prefix (locks channel).
Definition at line 1258 of file channel.c.
References channel_find_locked().
Referenced by action_bridge(), ast_parse_device_state(), bridge_exec(), common_exec(), handle_cli_mixmonitor(), shared_read(), and shared_write().
01259 { 01260 return channel_find_locked(NULL, name, namelen, NULL, NULL); 01261 }
struct ast_channel_tech* ast_get_channel_tech | ( | const char * | name | ) |
Get a channel technology structure by name.
name | name of technology to find |
Definition at line 604 of file channel.c.
References AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, chanlist::list, chanlist::tech, and ast_channel_tech::type.
Referenced by _ast_device_state().
00605 { 00606 struct chanlist *chanls; 00607 const struct ast_channel_tech *ret = NULL; 00608 00609 AST_RWLIST_RDLOCK(&channels); 00610 00611 AST_LIST_TRAVERSE(&backends, chanls, list) { 00612 if (!strcasecmp(name, chanls->tech->type)) { 00613 ret = chanls->tech; 00614 break; 00615 } 00616 } 00617 00618 AST_RWLIST_UNLOCK(&channels); 00619 00620 return ret; 00621 }
ast_group_t ast_get_group | ( | const char * | s | ) |
Definition at line 5316 of file channel.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), LOG_ERROR, LOG_WARNING, and strsep().
Referenced by _parse(), build_device(), build_gateway(), build_peer(), build_user(), func_channel_write(), process_dahdi(), and read_agent_config().
05317 { 05318 char *piece; 05319 char *c; 05320 int start=0, finish=0, x; 05321 ast_group_t group = 0; 05322 05323 if (ast_strlen_zero(s)) 05324 return 0; 05325 05326 c = ast_strdupa(s); 05327 05328 while ((piece = strsep(&c, ","))) { 05329 if (sscanf(piece, "%d-%d", &start, &finish) == 2) { 05330 /* Range */ 05331 } else if (sscanf(piece, "%d", &start)) { 05332 /* Just one */ 05333 finish = start; 05334 } else { 05335 ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece); 05336 continue; 05337 } 05338 for (x = start; x <= finish; x++) { 05339 if ((x > 63) || (x < 0)) { 05340 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x); 05341 } else 05342 group |= ((ast_group_t) 1 << x); 05343 } 05344 } 05345 return group; 05346 }
int ast_hangup | ( | struct ast_channel * | chan | ) |
Hang up a channel.
chan | channel to hang up |
Definition at line 1643 of file channel.c.
References ast_assert, ast_audiohook_detach_list(), ast_autoservice_stop(), ast_cause2str(), ast_cdr_detach(), ast_cdr_end(), AST_CDR_FLAG_BRIDGED, AST_CDR_FLAG_DIALED, AST_CDR_FLAG_POST_DISABLED, AST_CDR_NULL, ast_channel_free(), ast_channel_lock, ast_channel_unlock, ast_closestream(), ast_debug, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_log(), ast_set_flag, ast_test_flag, ast_channel::audiohooks, ast_channel::blocker, ast_channel::blockproc, ast_channel::cdr, chanlist::chan, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_cdr::disposition, EVENT_FLAG_CALL, free_translation(), ast_channel::generator, ast_channel::generatordata, ast_channel_tech::hangup, ast_channel::hangupcause, LOG_WARNING, manager_event, ast_channel::masq, ast_channel::masqr, ast_channel::name, ast_generator::release, S_OR, ast_channel::sched, sched_context_destroy(), ast_channel::stream, ast_channel::tech, ast_channel::uniqueid, and ast_channel::vstream.
Referenced by __ast_request_and_dial(), __oh323_new(), action_bridge(), agent_hangup(), agent_read(), alsa_new(), answer_exec_run(), app_exec(), ast_async_goto(), ast_bridge_call_thread(), ast_call_forward(), ast_dial_destroy(), ast_dial_hangup(), ast_feature_request_and_dial(), ast_iax2_new(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pbx_run_app(), async_wait(), begin_dial_channel(), bridge_exec(), build_conf(), builtin_atxfer(), chanavail_exec(), check_compat(), check_goto_on_transfer(), clear_caller(), conf_run(), console_new(), dahdi_handle_event(), dahdi_new(), dial_exec_full(), do_forward(), do_hang(), do_idle_thread(), do_parking_thread(), features_hangup(), findmeexec(), function_ilink(), 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(), HandleCallOutgoing(), hangup_chan(), hangupcalls(), hanguptree(), iax2_request(), iax_park(), iax_park_thread(), jingle_new(), local_hangup(), masq_park_call(), mgcp_new(), mgcp_ss(), monitor_dial(), mwi_thread(), nbs_new(), oss_new(), park_exec(), parkandannounce_exec(), phone_new(), rpt(), rpt_call(), rpt_tele_thread(), sip_new(), sip_park(), sip_park_thread(), skinny_new(), skinny_ss(), ss_thread(), unistim_new(), usbradio_new(), wait_for_answer(), and wait_for_winner().
01644 { 01645 int res = 0; 01646 01647 /* Don't actually hang up a channel that will masquerade as someone else, or 01648 if someone is going to masquerade as us */ 01649 ast_channel_lock(chan); 01650 01651 if (chan->audiohooks) { 01652 ast_audiohook_detach_list(chan->audiohooks); 01653 chan->audiohooks = NULL; 01654 } 01655 01656 ast_autoservice_stop(chan); 01657 01658 if (chan->masq) { 01659 if (ast_do_masquerade(chan)) 01660 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 01661 } 01662 01663 if (chan->masq) { 01664 ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name); 01665 ast_channel_unlock(chan); 01666 return 0; 01667 } 01668 /* If this channel is one which will be masqueraded into something, 01669 mark it as a zombie already, so we know to free it later */ 01670 if (chan->masqr) { 01671 ast_set_flag(chan, AST_FLAG_ZOMBIE); 01672 ast_channel_unlock(chan); 01673 return 0; 01674 } 01675 free_translation(chan); 01676 /* Close audio stream */ 01677 if (chan->stream) { 01678 ast_closestream(chan->stream); 01679 chan->stream = NULL; 01680 } 01681 /* Close video stream */ 01682 if (chan->vstream) { 01683 ast_closestream(chan->vstream); 01684 chan->vstream = NULL; 01685 } 01686 if (chan->sched) { 01687 sched_context_destroy(chan->sched); 01688 chan->sched = NULL; 01689 } 01690 01691 if (chan->generatordata) /* Clear any tone stuff remaining */ 01692 if (chan->generator && chan->generator->release) 01693 chan->generator->release(chan, chan->generatordata); 01694 chan->generatordata = NULL; 01695 chan->generator = NULL; 01696 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) { 01697 ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd " 01698 "is blocked by thread %ld in procedure %s! Expect a failure\n", 01699 (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc); 01700 ast_assert(ast_test_flag(chan, AST_FLAG_BLOCKING) == 0); 01701 } 01702 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) { 01703 ast_debug(1, "Hanging up channel '%s'\n", chan->name); 01704 if (chan->tech->hangup) 01705 res = chan->tech->hangup(chan); 01706 } else { 01707 ast_debug(1, "Hanging up zombie '%s'\n", chan->name); 01708 } 01709 01710 ast_channel_unlock(chan); 01711 manager_event(EVENT_FLAG_CALL, "Hangup", 01712 "Channel: %s\r\n" 01713 "Uniqueid: %s\r\n" 01714 "CallerIDNum: %s\r\n" 01715 "CallerIDName: %s\r\n" 01716 "Cause: %d\r\n" 01717 "Cause-txt: %s\r\n", 01718 chan->name, 01719 chan->uniqueid, 01720 S_OR(chan->cid.cid_num, "<unknown>"), 01721 S_OR(chan->cid.cid_name, "<unknown>"), 01722 chan->hangupcause, 01723 ast_cause2str(chan->hangupcause) 01724 ); 01725 01726 if (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_BRIDGED) && 01727 !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED) && 01728 (chan->cdr->disposition != AST_CDR_NULL || ast_test_flag(chan->cdr, AST_CDR_FLAG_DIALED))) { 01729 01730 ast_cdr_end(chan->cdr); 01731 ast_cdr_detach(chan->cdr); 01732 chan->cdr = NULL; 01733 } 01734 01735 ast_channel_free(chan); 01736 01737 return res; 01738 }
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 3024 of file channel.c.
References ast_indicate_data(), and chanlist::chan.
Referenced by __ast_play_and_record(), agent_new(), alsa_call(), answer_trunk_chan(), ast_bridge_call(), ast_channel_bridge(), ast_do_masquerade(), ast_dtmf_stream(), ast_feature_request_and_dial(), ast_raw_answer(), attempt_transfer(), builtin_atxfer(), builtin_blindtransfer(), cli_console_answer(), conf_run(), console_call(), dial_exec_full(), do_forward(), do_parking_thread(), features_indicate(), finishup(), function_remote(), handle_callforward_button(), handle_frame(), handle_recordfile(), handle_remote_data(), handle_remote_phone_dtmf(), mgcp_ss(), monitor_dial(), oss_call(), park_exec(), pbx_builtin_busy(), pbx_builtin_congestion(), pbx_builtin_proceeding(), pbx_builtin_progress(), pbx_builtin_ringing(), pbx_builtin_waitexten(), queue_exec(), rmt_telem_finish(), rmt_telem_start(), rpt(), say_periodic_announcement(), say_position(), send_waveform_to_channel(), skinny_ss(), sla_handle_hold_event(), sla_station_exec(), sla_trunk_exec(), and wait_for_answer().
03025 { 03026 return ast_indicate_data(chan, condition, NULL, 0); 03027 }
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 3063 of file channel.c.
References ast_channel::_state, ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, AST_CONTROL_WINK, ast_debug, AST_FLAG_ZOMBIE, ast_get_indication_tone(), ast_log(), ast_playtones_start(), ast_playtones_stop(), AST_STATE_UP, ast_test_flag, chanlist::chan, tone_zone_sound::data, ast_channel_tech::indicate, is_visible_indication(), LOG_WARNING, ast_channel::name, ast_channel::tech, ast_channel::visible_indication, and ast_channel::zone.
Referenced by agent_hangup(), ast_bridge_call(), ast_indicate(), bridge_native_loop(), do_parking_thread(), login_exec(), park_call_full(), pbx_builtin_waitexten(), and transmit_audio().
03065 { 03066 /* By using an enum, we'll get compiler warnings for values not handled 03067 * in switch statements. */ 03068 enum ast_control_frame_type condition = _condition; 03069 const struct tone_zone_sound *ts = NULL; 03070 int res = -1; 03071 03072 ast_channel_lock(chan); 03073 03074 /* Don't bother if the channel is about to go away, anyway. */ 03075 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 03076 ast_channel_unlock(chan); 03077 return -1; 03078 } 03079 03080 if (chan->tech->indicate) { 03081 /* See if the channel driver can handle this condition. */ 03082 res = chan->tech->indicate(chan, condition, data, datalen); 03083 } 03084 03085 ast_channel_unlock(chan); 03086 03087 if (chan->tech->indicate && !res) { 03088 /* The channel driver successfully handled this indication */ 03089 if (is_visible_indication(condition)) { 03090 chan->visible_indication = condition; 03091 } 03092 return 0; 03093 } 03094 03095 /* The channel driver does not support this indication, let's fake 03096 * it by doing our own tone generation if applicable. */ 03097 03098 /*!\note If we compare the enumeration type, which does not have any 03099 * negative constants, the compiler may optimize this code away. 03100 * Therefore, we must perform an integer comparison here. */ 03101 if (_condition < 0) { 03102 /* Stop any tones that are playing */ 03103 ast_playtones_stop(chan); 03104 return 0; 03105 } 03106 03107 /* Handle conditions that we have tones for. */ 03108 switch (condition) { 03109 case AST_CONTROL_RINGING: 03110 ts = ast_get_indication_tone(chan->zone, "ring"); 03111 /* It is common practice for channel drivers to return -1 if trying 03112 * to indicate ringing on a channel which is up. The idea is to let the 03113 * core generate the ringing inband. However, we don't want the 03114 * warning message about not being able to handle the specific indication 03115 * to print nor do we want ast_indicate_data to return an "error" for this 03116 * condition 03117 */ 03118 if (chan->_state == AST_STATE_UP) { 03119 res = 0; 03120 } 03121 break; 03122 case AST_CONTROL_BUSY: 03123 ts = ast_get_indication_tone(chan->zone, "busy"); 03124 break; 03125 case AST_CONTROL_CONGESTION: 03126 ts = ast_get_indication_tone(chan->zone, "congestion"); 03127 break; 03128 case AST_CONTROL_PROGRESS: 03129 case AST_CONTROL_PROCEEDING: 03130 case AST_CONTROL_VIDUPDATE: 03131 case AST_CONTROL_SRCUPDATE: 03132 case AST_CONTROL_RADIO_KEY: 03133 case AST_CONTROL_RADIO_UNKEY: 03134 case AST_CONTROL_OPTION: 03135 case AST_CONTROL_WINK: 03136 case AST_CONTROL_FLASH: 03137 case AST_CONTROL_OFFHOOK: 03138 case AST_CONTROL_TAKEOFFHOOK: 03139 case AST_CONTROL_ANSWER: 03140 case AST_CONTROL_HANGUP: 03141 case AST_CONTROL_RING: 03142 case AST_CONTROL_HOLD: 03143 case AST_CONTROL_UNHOLD: 03144 case AST_CONTROL_T38: 03145 /* Nothing left to do for these. */ 03146 res = 0; 03147 break; 03148 } 03149 03150 if (ts && ts->data[0]) { 03151 /* We have a tone to play, yay. */ 03152 ast_debug(1, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition); 03153 ast_playtones_start(chan, 0, ts->data, 1); 03154 res = 0; 03155 chan->visible_indication = condition; 03156 } 03157 03158 if (res) { 03159 /* not handled */ 03160 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name); 03161 } 03162 03163 return res; 03164 }
int ast_internal_timing_enabled | ( | struct ast_channel * | chan | ) |
Check if the channel can run in internal timing mode.
chan | The channel to check |
Definition at line 3007 of file channel.c.
References ast_debug, ast_opt_internal_timing, chanlist::chan, and ast_channel::timingfd.
Referenced by add_sdp(), and ast_read_generator_actions().
03008 { 03009 int ret = ast_opt_internal_timing && chan->timingfd > -1; 03010 ast_debug(5, "Internal timing is %s (option_internal_timing=%d chan->timingfd=%d)\n", ret? "enabled": "disabled", ast_opt_internal_timing, chan->timingfd); 03011 return ret; 03012 }
void ast_poll_channel_add | ( | struct ast_channel * | chan0, | |
struct ast_channel * | chan1 | |||
) |
Add a channel to an optimized waitfor
Definition at line 1565 of file channel.c.
References AST_MAX_FDS, and ast_channel::fds.
Referenced by ast_feature_request_and_dial(), ast_generic_bridge(), begin_dial_channel(), bridge_native_loop(), bridge_p2p_loop(), and wait_for_answer().
01566 { 01567 #ifdef HAVE_EPOLL 01568 struct epoll_event ev; 01569 int i = 0; 01570 01571 if (chan0->epfd == -1) 01572 return; 01573 01574 /* Iterate through the file descriptors on chan1, adding them to chan0 */ 01575 for (i = 0; i < AST_MAX_FDS; i++) { 01576 if (chan1->fds[i] == -1) 01577 continue; 01578 ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP; 01579 ev.data.ptr = chan1->epfd_data[i]; 01580 epoll_ctl(chan0->epfd, EPOLL_CTL_ADD, chan1->fds[i], &ev); 01581 } 01582 01583 #endif 01584 return; 01585 }
void ast_poll_channel_del | ( | struct ast_channel * | chan0, | |
struct ast_channel * | chan1 | |||
) |
Delete a channel from an optimized waitfor
Definition at line 1588 of file channel.c.
References AST_MAX_FDS, and ast_channel::fds.
Referenced by ast_feature_request_and_dial(), bridge_native_loop(), monitor_dial(), and wait_for_answer().
01589 { 01590 #ifdef HAVE_EPOLL 01591 struct epoll_event ev; 01592 int i = 0; 01593 01594 if (chan0->epfd == -1) 01595 return; 01596 01597 for (i = 0; i < AST_MAX_FDS; i++) { 01598 if (chan1->fds[i] == -1) 01599 continue; 01600 epoll_ctl(chan0->epfd, EPOLL_CTL_DEL, chan1->fds[i], &ev); 01601 } 01602 01603 #endif 01604 return; 01605 }
char* ast_print_group | ( | char * | buf, | |
int | buflen, | |||
ast_group_t | group | |||
) |
print call- and pickup groups into buffer
Definition at line 5398 of file channel.c.
Referenced by _sip_show_peer(), func_channel_read(), function_sippeer(), handle_skinny_show_line(), misdn_cfg_get_config_string(), print_group(), read_config(), and serialize_showchan().
05399 { 05400 unsigned int i; 05401 int first = 1; 05402 char num[3]; 05403 05404 buf[0] = '\0'; 05405 05406 if (!group) /* Return empty string if no group */ 05407 return buf; 05408 05409 for (i = 0; i <= 63; i++) { /* Max group is 63 */ 05410 if (group & ((ast_group_t) 1 << i)) { 05411 if (!first) { 05412 strncat(buf, ", ", buflen - strlen(buf) - 1); 05413 } else { 05414 first = 0; 05415 } 05416 snprintf(num, sizeof(num), "%u", i); 05417 strncat(buf, num, buflen - strlen(buf) - 1); 05418 } 05419 } 05420 return buf; 05421 }
int ast_prod | ( | struct ast_channel * | chan | ) |
Send empty audio to prime a channel driver.
Definition at line 3285 of file channel.c.
References ast_channel::_state, ast_debug, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), AST_STATE_UP, ast_write(), chanlist::chan, ast_frame::data, LOG_WARNING, ast_channel::name, ast_channel::rawwriteformat, ast_frame::src, and ast_frame::subclass.
Referenced by ast_activate_generator().
03286 { 03287 struct ast_frame a = { AST_FRAME_VOICE }; 03288 char nothing[128]; 03289 03290 /* Send an empty audio frame to get things moving */ 03291 if (chan->_state != AST_STATE_UP) { 03292 ast_debug(1, "Prodding channel '%s'\n", chan->name); 03293 a.subclass = chan->rawwriteformat; 03294 a.data = nothing + AST_FRIENDLY_OFFSET; 03295 a.src = "ast_prod"; 03296 if (ast_write(chan, &a)) 03297 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name); 03298 } 03299 return 0; 03300 }
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 1097 of file channel.c.
References AST_FRAME_CONTROL, ast_queue_frame(), chanlist::chan, and f.
Referenced by __dahdi_exception(), __oh323_update_info(), ast_pickup_call(), attempt_transfer(), auto_congest(), cb_events(), dahdi_handle_event(), dahdi_hangup(), gtalk_is_answered(), gtalk_ringing_ack(), handle_hd_hf(), handle_offhook_message(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), handle_response_refer(), handle_soft_key_event_message(), handle_stimulus_message(), HandleCallIncoming(), jingle_is_answered(), jingle_ringing_ack(), mgcp_call(), nbs_call(), phone_call(), pickup_do(), process_sdp(), receive_digit(), remote_hold(), send_cause2ast(), setup_rtp_connection(), skinny_call(), skinny_unhold(), ss_thread(), unistim_call(), and update_state().
01098 { 01099 struct ast_frame f = { AST_FRAME_CONTROL, }; 01100 01101 f.subclass = control; 01102 01103 return ast_queue_frame(chan, &f); 01104 }
int ast_queue_control_data | ( | struct ast_channel * | chan, | |
enum ast_control_frame_type | control, | |||
const void * | data, | |||
size_t | datalen | |||
) |
Queue a control frame with payload.
chan | channel to queue frame onto | |
control | type of control frame | |
data | pointer to payload data to be included in frame | |
datalen | number of bytes of payload data |
0 | success | |
non-zero | failure |
The channel does not need to be locked before calling this function.
Definition at line 1107 of file channel.c.
References AST_FRAME_CONTROL, ast_queue_frame(), chanlist::chan, and f.
Referenced by change_t38_state(), dahdi_handle_event(), dahdi_hangup(), iax2_queue_control_data(), process_sdp(), and skinny_hold().
01109 { 01110 struct ast_frame f = { AST_FRAME_CONTROL, }; 01111 01112 f.subclass = control; 01113 f.data = (void *) data; 01114 f.datalen = datalen; 01115 01116 return ast_queue_frame(chan, &f); 01117 }
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 1074 of file channel.c.
References __ast_queue_frame(), and chanlist::chan.
Referenced by __ast_read(), __oh323_rtp_create(), __oh323_update_info(), agent_new(), alsa_call(), ast_channel_masquerade(), ast_channel_setwhentohangup(), ast_do_masquerade(), ast_dsp_process(), ast_queue_control(), ast_queue_control_data(), ast_queue_hangup(), ast_softhangup_nolock(), cb_events(), cli_console_answer(), cli_console_dial(), cli_console_flash(), cli_console_sendtext(), console_answer(), console_call(), console_dial(), console_do_answer(), console_flash(), console_sendtext(), dahdi_queue_frame(), dictate_exec(), do_immediate_setup(), gtalk_handle_dtmf(), handle_keypad_button_message(), handle_request_info(), handle_request_invite(), handle_response_invite(), iax2_queue_frame(), jingle_handle_dtmf(), keypad_digit(), local_queue_frame(), mgcp_queue_frame(), oh323_simulate_dtmf_end(), oss_call(), process_sdp(), queue_dtmf_readq(), receive_digit(), receive_message(), stream_monitor(), unistim_do_senddigit(), unistim_senddigit_end(), usbradio_read(), and wakeup_sub().
01075 { 01076 return __ast_queue_frame(chan, fin, 0, NULL); 01077 }
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 1079 of file channel.c.
References __ast_queue_frame(), and chanlist::chan.
Referenced by __ast_answer(), __ast_read(), and ast_autoservice_stop().
01080 { 01081 return __ast_queue_frame(chan, fin, 1, NULL); 01082 }
int ast_queue_hangup | ( | struct ast_channel * | chan | ) |
Queue a hangup frame.
Definition at line 1085 of file channel.c.
References ast_channel::_softhangup, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, ast_queue_frame(), AST_SOFTHANGUP_DEV, chanlist::chan, and f.
Referenced by __oh323_update_info(), __sip_autodestruct(), cleanup_connection(), cli_console_hangup(), close_call(), close_client(), console_hangup(), dahdi_handle_event(), gtalk_hangup_farend(), gtalk_is_answered(), handle_onhook_message(), handle_request_bye(), handle_request_cancel(), handle_response(), handle_response_invite(), handle_soft_key_event_message(), HandleCallOutgoing(), hangup_chan(), hangup_connection(), iax2_destroy(), iax2_queue_hangup(), jingle_hangup_farend(), local_hangup(), mgcp_queue_hangup(), misdn_answer(), pri_hangup_all(), retrans_pkt(), and TransferCallStep1().
01086 { 01087 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP }; 01088 /* Yeah, let's not change a lock-critical value without locking */ 01089 if (!ast_channel_trylock(chan)) { 01090 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01091 ast_channel_unlock(chan); 01092 } 01093 return ast_queue_frame(chan, &f); 01094 }
int ast_raw_answer | ( | struct ast_channel * | chan, | |
int | cdr_answer | |||
) |
Answer a channel.
chan | channel to answer | |
cdr_answer | flag to control whether any associated CDR should be marked as 'answered' |
Unlike ast_answer(), this function will not wait for media flow to begin. The caller should be careful before sending media to the channel before incoming media arrives, as the outgoing media may be lost.
0 | on success | |
non-zero | on failure |
Definition at line 1740 of file channel.c.
References ast_channel::_state, ast_channel_tech::answer, ast_cdr_answer(), ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, ast_indicate(), ast_setstate(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_test_flag, ast_channel::cdr, chanlist::chan, ast_channel::tech, and ast_channel::visible_indication.
Referenced by __ast_answer(), and ast_bridge_call().
01741 { 01742 int res = 0; 01743 01744 ast_channel_lock(chan); 01745 01746 /* You can't answer an outbound call */ 01747 if (ast_test_flag(chan, AST_FLAG_OUTGOING)) { 01748 ast_channel_unlock(chan); 01749 return 0; 01750 } 01751 01752 /* Stop if we're a zombie or need a soft hangup */ 01753 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 01754 ast_channel_unlock(chan); 01755 return -1; 01756 } 01757 01758 ast_channel_unlock(chan); 01759 01760 switch (chan->_state) { 01761 case AST_STATE_RINGING: 01762 case AST_STATE_RING: 01763 ast_channel_lock(chan); 01764 if (chan->tech->answer) { 01765 res = chan->tech->answer(chan); 01766 } 01767 ast_setstate(chan, AST_STATE_UP); 01768 if (cdr_answer) { 01769 ast_cdr_answer(chan->cdr); 01770 } 01771 ast_channel_unlock(chan); 01772 break; 01773 case AST_STATE_UP: 01774 /* Calling ast_cdr_answer when it it has previously been called 01775 * is essentially a no-op, so it is safe. 01776 */ 01777 if (cdr_answer) { 01778 ast_cdr_answer(chan->cdr); 01779 } 01780 break; 01781 default: 01782 break; 01783 } 01784 01785 ast_indicate(chan, -1); 01786 chan->visible_indication = 0; 01787 01788 return res; 01789 }
struct ast_frame* ast_read | ( | struct ast_channel * | chan | ) |
Reads a frame.
chan | channel to read a frame from |
Definition at line 3014 of file channel.c.
References __ast_read(), and chanlist::chan.
Referenced by __adsi_transmit_messages(), __ast_answer(), __ast_play_and_record(), __ast_request_and_dial(), adsi_careful_send(), agent_ack_sleep(), agent_read(), ast_feature_request_and_dial(), ast_recvtext(), ast_safe_sleep_conditional(), ast_tonepair(), ast_udptl_bridge(), ast_waitfordigit_full(), async_wait(), autoservice_run(), background_detect_exec(), bridge_native_loop(), bridge_p2p_loop(), builtin_atxfer(), channel_spy(), check_goto_on_transfer(), conf_exec(), conf_flush(), conf_run(), dahdi_bridge(), dictate_exec(), disa_exec(), do_idle_thread(), do_parking_thread(), do_waiting(), echo_exec(), eivr_comm(), features_read(), find_cache(), handle_invite_replaces(), handle_recordfile(), handle_speechrecognize(), iax_park_thread(), ices_exec(), isAnsweringMachine(), launch_asyncagi(), masq_park_call(), measurenoise(), misdn_bridge(), monitor_dial(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), recordthread(), rpt(), run_agi(), send_tone_burst(), send_waveform_to_channel(), sendurl_exec(), speech_background(), ss_thread(), transmit_audio(), transmit_t38(), wait_for_answer(), wait_for_hangup(), wait_for_winner(), waitforring_exec(), and waitstream_core().
03015 { 03016 return __ast_read(chan, 0); 03017 }
struct ast_frame* ast_read_noaudio | ( | struct ast_channel * | chan | ) |
Reads a frame, returning AST_FRAME_NULL frame if audio.
chan | channel to read a frame from |
Definition at line 3019 of file channel.c.
References __ast_read(), and chanlist::chan.
Referenced by conf_run().
03020 { 03021 return __ast_read(chan, 1); 03022 }
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. Returns 0 on normal return, or 1 on a timeout. In the case of a timeout, any digits that were read before the timeout will still be available in s. RETURNS 2 in full version when ctrlfd is available, NOT 1 |
Definition at line 3953 of file channel.c.
References ast_readstring_full().
Referenced by _ast_adsi_begin_download(), _ast_adsi_get_cpeinfo(), _ast_adsi_load_session(), ast_app_getdata(), dialout(), do_directory(), forward_message(), privacy_exec(), vm_authenticate(), vm_newuser(), and vm_options().
03954 { 03955 return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1); 03956 }
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 3958 of file channel.c.
References 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_stopstream(), ast_test_flag, ast_waitfordigit_full(), ast_waitstream_full(), and ast_channel::stream.
Referenced by ast_app_getdata_full(), and ast_readstring().
03959 { 03960 int pos = 0; /* index in the buffer where we accumulate digits */ 03961 int to = ftimeout; 03962 03963 /* Stop if we're a zombie or need a soft hangup */ 03964 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 03965 return -1; 03966 if (!len) 03967 return -1; 03968 for (;;) { 03969 int d; 03970 if (c->stream) { 03971 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd); 03972 ast_stopstream(c); 03973 usleep(1000); 03974 if (!d) 03975 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 03976 } else { 03977 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 03978 } 03979 if (d < 0) 03980 return AST_GETDATA_FAILED; 03981 if (d == 0) { 03982 s[pos] = '\0'; 03983 return AST_GETDATA_TIMEOUT; 03984 } 03985 if (d == 1) { 03986 s[pos] = '\0'; 03987 return AST_GETDATA_INTERRUPTED; 03988 } 03989 if (strchr(enders, d) && (pos == 0)) { 03990 s[pos] = '\0'; 03991 return AST_GETDATA_EMPTY_END_TERMINATED; 03992 } 03993 if (!strchr(enders, d)) { 03994 s[pos++] = d; 03995 } 03996 if (strchr(enders, d) || (pos >= len)) { 03997 s[pos] = '\0'; 03998 return AST_GETDATA_COMPLETE; 03999 } 04000 to = timeout; 04001 } 04002 /* Never reached */ 04003 return 0; 04004 }
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 Returns 0 on success, -1 on failure |
Definition at line 3166 of file channel.c.
References ast_free, ast_recvtext(), buf, and chanlist::chan.
Referenced by handle_recvchar().
03167 { 03168 int c; 03169 char *buf = ast_recvtext(chan, timeout); 03170 if (buf == NULL) 03171 return -1; /* error or timeout */ 03172 c = *(unsigned char *)buf; 03173 ast_free(buf); 03174 return c; 03175 }
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 3177 of file channel.c.
References ast_check_hangup(), AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_TEXT, ast_frfree, ast_read(), ast_strndup, ast_waitfor(), buf, chanlist::chan, and f.
Referenced by ast_recvchar(), and handle_recvtext().
03178 { 03179 int res, done = 0; 03180 char *buf = NULL; 03181 03182 while (!done) { 03183 struct ast_frame *f; 03184 if (ast_check_hangup(chan)) 03185 break; 03186 res = ast_waitfor(chan, timeout); 03187 if (res <= 0) /* timeout or error */ 03188 break; 03189 timeout = res; /* update timeout */ 03190 f = ast_read(chan); 03191 if (f == NULL) 03192 break; /* no frame */ 03193 if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP) 03194 done = 1; /* force a break */ 03195 else if (f->frametype == AST_FRAME_TEXT) { /* what we want */ 03196 buf = ast_strndup((char *) f->data, f->datalen); /* dup and break */ 03197 done = 1; 03198 } 03199 ast_frfree(f); 03200 } 03201 return buf; 03202 }
struct ast_channel* ast_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | status | |||
) |
Requests a channel.
type | type of channel to request | |
format | requested channel format (codec) | |
data | data to pass to the channel requester | |
status | status |
NULL | failure | |
non-NULL | channel on success |
Definition at line 3853 of file channel.c.
References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_NOSUCHDRIVER, AST_CAUSE_NOTDEFINED, AST_FORMAT_AUDIO_MASK, AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, AST_LIST_TRAVERSE, ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_translator_best_choice(), ast_channel_tech::capabilities, capabilities, chanlist::chan, chanlist::list, LOG_WARNING, ast_channel_tech::requester, ast_channel::tech, and ast_channel_tech::type.
Referenced by __ast_request_and_dial(), agent_request(), ast_call_forward(), ast_feature_request_and_dial(), attempt_reconnect(), begin_dial_channel(), build_conf(), chanavail_exec(), conf_run(), dial_exec_full(), do_forward(), features_alloc(), findmeexec(), function_ilink(), ring_entry(), rpt(), rpt_call(), and rpt_tele_thread().
03854 { 03855 struct chanlist *chan; 03856 struct ast_channel *c; 03857 int capabilities; 03858 int fmt; 03859 int res; 03860 int foo; 03861 int videoformat = format & AST_FORMAT_VIDEO_MASK; 03862 int textformat = format & AST_FORMAT_TEXT_MASK; 03863 03864 if (!cause) 03865 cause = &foo; 03866 *cause = AST_CAUSE_NOTDEFINED; 03867 03868 if (AST_RWLIST_RDLOCK(&channels)) { 03869 ast_log(LOG_WARNING, "Unable to lock channel list\n"); 03870 return NULL; 03871 } 03872 03873 AST_LIST_TRAVERSE(&backends, chan, list) { 03874 if (strcasecmp(type, chan->tech->type)) 03875 continue; 03876 03877 capabilities = chan->tech->capabilities; 03878 fmt = format & AST_FORMAT_AUDIO_MASK; 03879 if (fmt) { 03880 /* We have audio - is it possible to connect the various calls to each other? 03881 (Avoid this check for calls without audio, like text+video calls) 03882 */ 03883 res = ast_translator_best_choice(&fmt, &capabilities); 03884 if (res < 0) { 03885 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native 0x%x) to 0x%x\n", type, chan->tech->capabilities, format); 03886 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03887 AST_RWLIST_UNLOCK(&channels); 03888 return NULL; 03889 } 03890 } 03891 AST_RWLIST_UNLOCK(&channels); 03892 if (!chan->tech->requester) 03893 return NULL; 03894 03895 if (!(c = chan->tech->requester(type, capabilities | videoformat | textformat, data, cause))) 03896 return NULL; 03897 03898 /* no need to generate a Newchannel event here; it is done in the channel_alloc call */ 03899 return c; 03900 } 03901 03902 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type); 03903 *cause = AST_CAUSE_NOSUCHDRIVER; 03904 AST_RWLIST_UNLOCK(&channels); 03905 03906 return NULL; 03907 }
struct ast_channel* ast_request_and_dial | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int | timeout, | |||
int * | reason, | |||
const char * | cid_num, | |||
const char * | cid_name | |||
) |
Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it.
type | type of channel to request | |
format | requested channel format | |
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 3848 of file channel.c.
References __ast_request_and_dial().
Referenced by ast_pbx_outgoing_exten().
03849 { 03850 return __ast_request_and_dial(type, format, data, timeout, outstate, cidnum, cidname, NULL); 03851 }
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 Waits for a specified amount of time, servicing the channel as required. |
Definition at line 1305 of file channel.c.
References ast_safe_sleep_conditional(), and chanlist::chan.
Referenced by _ast_adsi_transmit_message_full(), alarmreceiver_exec(), ast_dtmf_stream(), ast_senddigit(), builtin_atxfer(), builtin_parkcall(), conf_run(), dictate_exec(), flash_exec(), function_ilink(), function_remote(), handle_callforward_button(), handle_remote_data(), handle_remote_phone_dtmf(), login_exec(), mgcp_ss(), milliwatt_exec(), misdn_check_l2l1(), old_milliwatt_exec(), park_call_exec(), pbx_builtin_wait(), play_moh_exec(), play_tone_pair(), playtone(), privacy_exec(), receive_ademco_contact_id(), rmt_telem_start(), rpt_call(), rpt_tele_thread(), send_morse(), send_tone_telemetry(), skinny_ss(), ss_thread(), testclient_exec(), testserver_exec(), wait_for_hangup(), wait_interval(), wait_moh_exec(), waituntil_exec(), and zapateller_exec().
01306 { 01307 return ast_safe_sleep_conditional(chan, ms, NULL, NULL); 01308 }
int ast_safe_sleep_conditional | ( | struct ast_channel * | chan, | |
int | ms, | |||
int(*)(void *) | cond, | |||
void * | data | |||
) |
Wait for a specified amount of time, looking for hangups and a condition argument.
chan | channel to wait for | |
ms | length of time in milliseconds to sleep | |
cond | a function pointer for testing continue condition | |
data | argument to be passed to the condition test function |
Definition at line 1284 of file channel.c.
References ast_frfree, ast_read(), ast_waitfor(), chanlist::chan, and f.
Referenced by ast_safe_sleep(), and login_exec().
01285 { 01286 struct ast_frame *f; 01287 01288 while (ms > 0) { 01289 if (cond && ((*cond)(data) == 0)) 01290 return 0; 01291 ms = ast_waitfor(chan, ms); 01292 if (ms < 0) 01293 return -1; 01294 if (ms > 0) { 01295 f = ast_read(chan); 01296 if (!f) 01297 return -1; 01298 ast_frfree(f); 01299 } 01300 } 01301 return 0; 01302 }
static int ast_select | ( | int | nfds, | |
fd_set * | rfds, | |||
fd_set * | wfds, | |||
fd_set * | efds, | |||
struct timeval * | tvp | |||
) | [inline, static] |
Waits for activity on a group of channels.
nfds | the maximum number of file descriptors in the sets | |
rfds | file descriptors to check for read availability | |
wfds | file descriptors to check for write availability | |
efds | file descriptors to check for exceptions (OOB data) | |
tvp | timeout while waiting for events This is the same as a standard select(), except it guarantees the behaviour where the passed struct timeval is updated with how much time was not slept while waiting for the specified events |
Definition at line 1669 of file channel.h.
References timersub().
Referenced by aji_io_recv(), ast_stun_request(), do_monitor(), and do_parking_thread().
01670 { 01671 #ifdef __linux__ 01672 return select(nfds, rfds, wfds, efds, tvp); 01673 #else 01674 if (tvp) { 01675 struct timeval tv, tvstart, tvend, tvlen; 01676 int res; 01677 01678 tv = *tvp; 01679 gettimeofday(&tvstart, NULL); 01680 res = select(nfds, rfds, wfds, efds, tvp); 01681 gettimeofday(&tvend, NULL); 01682 timersub(&tvend, &tvstart, &tvlen); 01683 timersub(&tv, &tvlen, tvp); 01684 if (tvp->tv_sec < 0 || (tvp->tv_sec == 0 && tvp->tv_usec < 0)) { 01685 tvp->tv_sec = 0; 01686 tvp->tv_usec = 0; 01687 } 01688 return res; 01689 } 01690 else 01691 return select(nfds, rfds, wfds, efds, NULL); 01692 #endif 01693 }
int ast_senddigit | ( | struct ast_channel * | chan, | |
char | digit, | |||
unsigned int | duration | |||
) |
Send a DTMF digit to a channel 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 3275 of file channel.c.
References AST_DEFAULT_EMULATE_DTMF_DURATION, ast_safe_sleep(), ast_senddigit_begin(), ast_senddigit_end(), chanlist::chan, ast_channel_tech::send_digit_begin, and ast_channel::tech.
Referenced by ast_dtmf_stream(), dial_exec_full(), and manager_play_dtmf().
03276 { 03277 if (chan->tech->send_digit_begin) { 03278 ast_senddigit_begin(chan, digit); 03279 ast_safe_sleep(chan, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION)); 03280 } 03281 03282 return ast_senddigit_end(chan, digit, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION)); 03283 }
int ast_senddigit_begin | ( | struct ast_channel * | chan, | |
char | digit | |||
) |
Send a DTMF digit to a channel Send a DTMF digit to a channel.
chan | channel to act upon | |
digit | the DTMF digit to send, encoded in ASCII |
Definition at line 3217 of file channel.c.
References ast_debug, ast_playtones_start(), chanlist::chan, ast_channel::name, ast_channel_tech::send_digit_begin, and ast_channel::tech.
Referenced by agent_digit_begin(), ast_senddigit(), ast_write(), and features_digit_begin().
03218 { 03219 /* Device does not support DTMF tones, lets fake 03220 * it by doing our own generation. */ 03221 static const char* dtmf_tones[] = { 03222 "941+1336", /* 0 */ 03223 "697+1209", /* 1 */ 03224 "697+1336", /* 2 */ 03225 "697+1477", /* 3 */ 03226 "770+1209", /* 4 */ 03227 "770+1336", /* 5 */ 03228 "770+1477", /* 6 */ 03229 "852+1209", /* 7 */ 03230 "852+1336", /* 8 */ 03231 "852+1477", /* 9 */ 03232 "697+1633", /* A */ 03233 "770+1633", /* B */ 03234 "852+1633", /* C */ 03235 "941+1633", /* D */ 03236 "941+1209", /* * */ 03237 "941+1477" /* # */ 03238 }; 03239 03240 if (!chan->tech->send_digit_begin) 03241 return 0; 03242 03243 if (!chan->tech->send_digit_begin(chan, digit)) 03244 return 0; 03245 03246 if (digit >= '0' && digit <='9') 03247 ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0); 03248 else if (digit >= 'A' && digit <= 'D') 03249 ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0); 03250 else if (digit == '*') 03251 ast_playtones_start(chan, 0, dtmf_tones[14], 0); 03252 else if (digit == '#') 03253 ast_playtones_start(chan, 0, dtmf_tones[15], 0); 03254 else { 03255 /* not handled */ 03256 ast_debug(1, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name); 03257 } 03258 03259 return 0; 03260 }
int ast_senddigit_end | ( | struct ast_channel * | chan, | |
char | digit, | |||
unsigned int | duration | |||
) |
Send a DTMF digit to a channel.
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 3262 of file channel.c.
References ast_playtones_stop(), chanlist::chan, ast_channel::generator, ast_channel_tech::send_digit_end, and ast_channel::tech.
Referenced by agent_digit_end(), ast_senddigit(), ast_write(), and features_digit_end().
03263 { 03264 int res = -1; 03265 03266 if (chan->tech->send_digit_end) 03267 res = chan->tech->send_digit_end(chan, digit, duration); 03268 03269 if (res && chan->generator) 03270 ast_playtones_stop(chan); 03271 03272 return 0; 03273 }
int ast_sendtext | ( | struct ast_channel * | chan, | |
const char * | text | |||
) |
Sends text to a channel.
chan | channel to act upon | |
text | string of text to send on the channel |
0 | on success | |
-1 | on failure |
Definition at line 3204 of file channel.c.
References ast_check_hangup(), ast_clear_flag, AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_test_flag, chanlist::chan, CHECK_BLOCKING, ast_channel_tech::send_text, and ast_channel::tech.
Referenced by action_sendtext(), agent_sendtext(), handle_sendtext(), and sendtext_exec().
03205 { 03206 int res = 0; 03207 /* Stop if we're a zombie or need a soft hangup */ 03208 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) 03209 return -1; 03210 CHECK_BLOCKING(chan); 03211 if (chan->tech->send_text) 03212 res = chan->tech->send_text(chan, text); 03213 ast_clear_flag(chan, AST_FLAG_BLOCKING); 03214 return res; 03215 }
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.
Definition at line 4535 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_free, ast_strdup, chanlist::chan, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_name, ast_callerid::cid_num, and report_new_callerid().
Referenced by __ast_request_and_dial(), agent_call(), ast_call_forward(), ast_feature_request_and_dial(), callerid_write(), dahdi_read(), dial_exec_full(), do_forward(), findmeexec(), handle_setcallerid(), mgcp_ss(), privacy_exec(), read_config(), skinny_newcall(), and ss_thread().
04536 { 04537 ast_channel_lock(chan); 04538 04539 if (cid_num) { 04540 if (chan->cid.cid_num) 04541 ast_free(chan->cid.cid_num); 04542 chan->cid.cid_num = ast_strdup(cid_num); 04543 } 04544 if (cid_name) { 04545 if (chan->cid.cid_name) 04546 ast_free(chan->cid.cid_name); 04547 chan->cid.cid_name = ast_strdup(cid_name); 04548 } 04549 if (cid_ani) { 04550 if (chan->cid.cid_ani) 04551 ast_free(chan->cid.cid_ani); 04552 chan->cid.cid_ani = ast_strdup(cid_ani); 04553 } 04554 04555 report_new_callerid(chan); 04556 04557 ast_channel_unlock(chan); 04558 }
int ast_set_read_format | ( | struct ast_channel * | chan, | |
int | 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 3602 of file channel.c.
References chanlist::chan, ast_channel::rawreadformat, ast_channel::readformat, ast_channel::readtrans, and set_format().
Referenced by __ast_play_and_record(), __oh323_update_info(), _ast_adsi_transmit_message_full(), agent_call(), alarmreceiver_exec(), ast_channel_make_compatible_helper(), ast_do_masquerade(), attempt_reconnect(), background_detect_exec(), build_conf(), conf_run(), dictate_exec(), do_waiting(), eagi_exec(), echo_exec(), function_ilink(), gtalk_rtp_read(), handle_recordfile(), handle_speechrecognize(), ices_exec(), isAnsweringMachine(), jingle_rtp_read(), login_exec(), measurenoise(), mgcp_rtp_read(), oh323_rtp_read(), old_milliwatt_exec(), process_sdp(), rpt(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_process(), speech_background(), transmit_audio(), unistim_rtp_read(), and update_features().
03603 { 03604 return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat, 03605 &chan->readtrans, 0); 03606 }
void ast_set_variables | ( | struct ast_channel * | chan, | |
struct ast_variable * | vars | |||
) |
adds a list of channel variables to a channel
chan | the channel | |
vars | a linked list of variables |
Definition at line 5423 of file channel.c.
References chan, 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().
05424 { 05425 struct ast_variable *cur; 05426 05427 for (cur = vars; cur; cur = cur->next) 05428 pbx_builtin_setvar_helper(chan, cur->name, cur->value); 05429 }
int ast_set_write_format | ( | struct ast_channel * | chan, | |
int | 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 3608 of file channel.c.
References chanlist::chan, ast_channel::rawwriteformat, set_format(), ast_channel::writeformat, and ast_channel::writetrans.
Referenced by __oh323_update_info(), _ast_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(), attempt_reconnect(), build_conf(), chanspy_exec(), conf_run(), echo_exec(), extenspy_exec(), function_ilink(), gtalk_rtp_read(), jingle_rtp_read(), linear_alloc(), linear_release(), login_exec(), mgcp_rtp_read(), moh_alloc(), moh_files_release(), moh_release(), mp3_exec(), NBScat_exec(), oh323_rtp_read(), old_milliwatt_exec(), playtones_alloc(), playtones_release(), process_sdp(), rpt(), send_waveform_to_channel(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_process(), tonepair_alloc(), tonepair_release(), transmit_audio(), unistim_rtp_read(), and update_features().
03609 { 03610 return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat, 03611 &chan->writetrans, 1); 03612 }
int ast_setstate | ( | struct ast_channel * | chan, | |
enum | ast_channel_state | |||
) |
Change the state of a channel.
Definition at line 4560 of file channel.c.
References ast_channel::_state, AST_CHANNEL_NAME, ast_copy_string(), ast_device_state_changed_literal(), ast_state2str(), chanlist::chan, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, EVENT_FLAG_CALL, manager_event, ast_channel::name, name, S_OR, and ast_channel::uniqueid.
Referenced by __ast_read(), __dahdi_exception(), __oh323_update_info(), agent_call(), alsa_answer(), ast_raw_answer(), cb_events(), check_availability(), console_answer(), dahdi_answer(), dahdi_call(), dahdi_handle_event(), dahdi_indicate(), dahdi_read(), do_bridge_masquerade(), gtalk_call(), gtalk_newcall(), handle_invite_replaces(), handle_offhook_message(), handle_request_invite(), handle_response_invite(), handle_soft_key_event_message(), handle_stimulus_message(), iax2_call(), jingle_call(), jingle_newcall(), mgcp_answer(), mgcp_call(), mgcp_ss(), misdn_call(), misdn_indication(), nbs_call(), nbs_hangup(), oh323_answer(), oss_answer(), pbx_builtin_busy(), pbx_builtin_congestion(), phone_answer(), phone_call(), phone_exception(), phone_hangup(), phone_write(), release_chan(), sip_answer(), skinny_answer(), skinny_call(), skinny_newcall(), ss_thread(), unistim_answer(), unistim_call(), unistim_new(), unistim_ss(), update_state(), usbradio_answer(), and usbradio_call().
04561 { 04562 int oldstate = chan->_state; 04563 char name[AST_CHANNEL_NAME], *dashptr; 04564 04565 if (oldstate == state) 04566 return 0; 04567 04568 ast_copy_string(name, chan->name, sizeof(name)); 04569 if ((dashptr = strrchr(name, '-'))) { 04570 *dashptr = '\0'; 04571 } 04572 04573 chan->_state = state; 04574 ast_device_state_changed_literal(name); 04575 /* setstate used to conditionally report Newchannel; this is no more */ 04576 manager_event(EVENT_FLAG_CALL, 04577 "Newstate", 04578 "Channel: %s\r\n" 04579 "ChannelState: %d\r\n" 04580 "ChannelStateDesc: %s\r\n" 04581 "CallerIDNum: %s\r\n" 04582 "CallerIDName: %s\r\n" 04583 "Uniqueid: %s\r\n", 04584 chan->name, chan->_state, ast_state2str(chan->_state), 04585 S_OR(chan->cid.cid_num, ""), 04586 S_OR(chan->cid.cid_name, ""), 04587 chan->uniqueid); 04588 04589 return 0; 04590 }
int ast_settimeout | ( | struct ast_channel * | c, | |
int | samples, | |||
int(*)(const void *data) | func, | |||
void * | data | |||
) |
Definition at line 2350 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_debug, ast_channel::timingdata, ast_channel::timingfd, and ast_channel::timingfunc.
Referenced by ast_activate_generator(), ast_deactivate_generator(), ast_read_generator_actions(), ast_readaudio_callback(), and filestream_destructor().
02351 { 02352 int res = -1; 02353 #ifdef HAVE_DAHDI 02354 ast_channel_lock(c); 02355 if (c->timingfd > -1) { 02356 if (!func) { 02357 samples = 0; 02358 data = 0; 02359 } 02360 ast_debug(1, "Scheduling timer at %d sample intervals\n", samples); 02361 res = ioctl(c->timingfd, DAHDI_TIMERCONFIG, &samples); 02362 c->timingfunc = func; 02363 c->timingdata = data; 02364 } 02365 ast_channel_unlock(c); 02366 #endif 02367 return res; 02368 }
int ast_shutting_down | ( | void | ) |
Returns non-zero if Asterisk is being shut down.
Returns non-zero if Asterisk is being shut down
Definition at line 517 of file channel.c.
Referenced by handle_request_options().
00518 { 00519 return shutting_down; 00520 }
int ast_softhangup | ( | struct ast_channel * | chan, | |
int | cause | |||
) |
Softly hangup up a channel.
chan | channel to be soft-hung-up | |
cause | Ast hangupcause for hangup |
Definition at line 1621 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_softhangup_nolock(), and chanlist::chan.
Referenced by __ast_module_user_hangup_all(), __unload_module(), action_hangup(), agent_hangup(), agent_logoff(), ast_begin_shutdown(), ast_dial_join(), conf_free(), dahdi_handle_event(), function_ilink(), handle_cli_rpt_restart(), handle_hangup(), handle_link_data(), handle_softhangup(), login_exec(), manager_park(), read_agent_config(), rpt(), rpt_call(), sla_handle_hold_event(), softhangup_exec(), start_spying(), startmon(), and unload_module().
01622 { 01623 int res; 01624 ast_channel_lock(chan); 01625 res = ast_softhangup_nolock(chan, cause); 01626 ast_channel_unlock(chan); 01627 return res; 01628 }
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 | |
cause | Ast hangupcause for hangup (see cause.h) |
Definition at line 1608 of file channel.c.
References ast_channel::_softhangup, ast_debug, AST_FLAG_BLOCKING, ast_null_frame, ast_queue_frame(), ast_test_flag, ast_channel::blocker, chanlist::chan, and ast_channel::name.
Referenced by ast_async_goto(), ast_softhangup(), attempt_transfer(), check_rtp_timeout(), dahdi_softhangup_all(), oh323_indicate(), proc_session_timer(), sip_indicate(), and skinny_indicate().
01609 { 01610 ast_debug(1, "Soft-Hanging up channel '%s'\n", chan->name); 01611 /* Inform channel driver that we need to be hung up, if it cares */ 01612 chan->_softhangup |= cause; 01613 ast_queue_frame(chan, &ast_null_frame); 01614 /* Interrupt any poll call or such */ 01615 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) 01616 pthread_kill(chan->blocker, SIGURG); 01617 return 0; 01618 }
const char* ast_state2str | ( | enum ast_channel_state | state | ) |
Gives the string form of a given channel state.
Definition at line 651 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(), buf, STATE2STR_BUFSIZE, and state2str_threadbuf.
Referenced by __ast_channel_alloc_ap(), action_coreshowchannels(), action_status(), agent_hangup(), ast_do_masquerade(), ast_setstate(), attempt_transfer(), can_pickup(), func_channel_read(), handle_chanlist(), handle_invite_replaces(), handle_showchan(), local_attended_transfer(), mgcp_new(), serialize_showchan(), and sip_hangup().
00652 { 00653 char *buf; 00654 00655 switch (state) { 00656 case AST_STATE_DOWN: 00657 return "Down"; 00658 case AST_STATE_RESERVED: 00659 return "Rsrvd"; 00660 case AST_STATE_OFFHOOK: 00661 return "OffHook"; 00662 case AST_STATE_DIALING: 00663 return "Dialing"; 00664 case AST_STATE_RING: 00665 return "Ring"; 00666 case AST_STATE_RINGING: 00667 return "Ringing"; 00668 case AST_STATE_UP: 00669 return "Up"; 00670 case AST_STATE_BUSY: 00671 return "Busy"; 00672 case AST_STATE_DIALING_OFFHOOK: 00673 return "Dialing Offhook"; 00674 case AST_STATE_PRERING: 00675 return "Pre-ring"; 00676 default: 00677 if (!(buf = ast_threadstorage_get(&state2str_threadbuf, STATE2STR_BUFSIZE))) 00678 return "Unknown"; 00679 snprintf(buf, STATE2STR_BUFSIZE, "Unknown (%d)", state); 00680 return buf; 00681 } 00682 }
int ast_str2cause | ( | const char * | name | ) |
Convert a symbolic hangup cause to number.
name | string form of the cause Returns the cause code |
Definition at line 637 of file channel.c.
References ARRAY_LEN, ast_cause::cause, and causes.
Referenced by pbx_builtin_hangup().
00638 { 00639 int x; 00640 00641 for (x = 0; x < ARRAY_LEN(causes); x++) 00642 if (!strncasecmp(causes[x].name, name, strlen(causes[x].name))) 00643 return causes[x].cause; 00644 00645 return -1; 00646 }
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 5298 of file channel.c.
References ast_frfree, ast_read(), ast_tonepair_start(), ast_waitfor(), chan, f, and ast_channel::generatordata.
Referenced by zapateller_exec().
05299 { 05300 int res; 05301 05302 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol))) 05303 return res; 05304 05305 /* Give us some wiggle room */ 05306 while (chan->generatordata && ast_waitfor(chan, 100) >= 0) { 05307 struct ast_frame *f = ast_read(chan); 05308 if (f) 05309 ast_frfree(f); 05310 else 05311 return -1; 05312 } 05313 return 0; 05314 }
int ast_tonepair_start | ( | struct ast_channel * | chan, | |
int | freq1, | |||
int | freq2, | |||
int | duration, | |||
int | vol | |||
) |
Start a tone going
Definition at line 5280 of file channel.c.
References ast_activate_generator(), chan, tonepair_def::duration, tonepair_def::freq1, tonepair_def::freq2, tonepair, and tonepair_def::vol.
Referenced by ast_tonepair(), pbx_builtin_waitexten(), play_dialtone(), play_tone_pair(), rpt_tele_thread(), and sendnoise().
05281 { 05282 struct tonepair_def d = { 0, }; 05283 05284 d.freq1 = freq1; 05285 d.freq2 = freq2; 05286 d.duration = duration; 05287 d.vol = (vol < 1) ? 8192 : vol; /* force invalid to 8192 */ 05288 if (ast_activate_generator(chan, &tonepair, &d)) 05289 return -1; 05290 return 0; 05291 }
void ast_tonepair_stop | ( | struct ast_channel * | chan | ) |
Stop a tone from playing
Definition at line 5293 of file channel.c.
References ast_deactivate_generator(), and chan.
Referenced by sendnoise().
05294 { 05295 ast_deactivate_generator(chan); 05296 }
int ast_transfer | ( | struct ast_channel * | chan, | |
char * | dest | |||
) |
Transfer a channel (if supported). Returns -1 on error, 0 if not supported and 1 if supported and requested.
Called by:
Definition at line 3935 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_FLAG_ZOMBIE, ast_test_flag, chanlist::chan, ast_channel::tech, and ast_channel_tech::transfer.
Referenced by transfer_exec().
03936 { 03937 int res = -1; 03938 03939 /* Stop if we're a zombie or need a soft hangup */ 03940 ast_channel_lock(chan); 03941 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) { 03942 if (chan->tech->transfer) { 03943 res = chan->tech->transfer(chan, dest); 03944 if (!res) 03945 res = 1; 03946 } else 03947 res = 0; 03948 } 03949 ast_channel_unlock(chan); 03950 return res; 03951 }
char* ast_transfercapability2str | ( | int | transfercapability | ) | const |
Gives the string form of a given transfer capability.
transfercapability | transfercapabilty to get the name of Give a name to a transfercapbility See above Returns the text form of the binary transfer capability |
Definition at line 685 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 cb_events(), dahdi_call(), dahdi_new(), misdn_call(), and oh323_call().
00686 { 00687 switch (transfercapability) { 00688 case AST_TRANS_CAP_SPEECH: 00689 return "SPEECH"; 00690 case AST_TRANS_CAP_DIGITAL: 00691 return "DIGITAL"; 00692 case AST_TRANS_CAP_RESTRICTED_DIGITAL: 00693 return "RESTRICTED_DIGITAL"; 00694 case AST_TRANS_CAP_3_1K_AUDIO: 00695 return "3K1AUDIO"; 00696 case AST_TRANS_CAP_DIGITAL_W_TONES: 00697 return "DIGITAL_W_TONES"; 00698 case AST_TRANS_CAP_VIDEO: 00699 return "VIDEO"; 00700 default: 00701 return "UNKNOWN"; 00702 } 00703 }
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). |
Definition at line 2334 of file channel.c.
References ast_waitfor_nandfds().
Referenced by __adsi_transmit_messages(), __ast_answer(), __ast_play_and_record(), __ast_request_and_dial(), adsi_careful_send(), agent_ack_sleep(), ast_dtmf_stream(), ast_recvtext(), ast_safe_sleep_conditional(), ast_tonepair(), async_wait(), background_detect_exec(), channel_spy(), conf_exec(), conf_flush(), dictate_exec(), disa_exec(), do_idle_thread(), do_waiting(), echo_exec(), handle_recordfile(), handle_speechrecognize(), ices_exec(), isAnsweringMachine(), launch_asyncagi(), measurenoise(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), recordthread(), send_tone_burst(), send_waveform_to_channel(), sendurl_exec(), speech_background(), ss_thread(), transmit_audio(), transmit_t38(), wait_for_hangup(), waitforring_exec(), and waitstream_core().
02335 { 02336 int oldms = ms; /* -1 if no timeout */ 02337 02338 ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms); 02339 if ((ms < 0) && (oldms < 0)) 02340 ms = 0; 02341 return ms; 02342 }
struct ast_channel* ast_waitfor_n | ( | struct ast_channel ** | chan, | |
int | n, | |||
int * | ms | |||
) |
Waits for input on a group of channels Wait for input on an array of channels for a given # of milliseconds.
chan | an array of pointers to channels | |
n | number of channels that are to be waited upon | |
ms | time "ms" is modified in-place, if applicable |
Definition at line 2329 of file channel.c.
References ast_waitfor_nandfds().
Referenced by ast_feature_request_and_dial(), ast_udptl_bridge(), autoservice_run(), bridge_native_loop(), dahdi_bridge(), misdn_bridge(), monitor_dial(), rpt(), wait_for_answer(), and wait_for_winner().
02330 { 02331 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms); 02332 }
int ast_waitfor_n_fd | ( | int * | fds, | |
int | n, | |||
int * | ms, | |||
int * | exception | |||
) |
Waits for input on an fd This version works on fd's only. Be careful with it.
Definition at line 1970 of file channel.c.
References ast_waitfor_nandfds().
Referenced by dundi_lookup_internal(), and dundi_precache_internal().
01971 { 01972 int winner = -1; 01973 ast_waitfor_nandfds(NULL, 0, fds, n, exception, &winner, ms); 01974 return winner; 01975 }
struct ast_channel* ast_waitfor_nandfds | ( | struct ast_channel ** | chan, | |
int | n, | |||
int * | fds, | |||
int | nfds, | |||
int * | exception, | |||
int * | outfd, | |||
int * | ms | |||
) |
Waits for activity on a group of channels.
chan | an array of pointers to channels | |
n | number of channels that are to be waited upon | |
fds | an array of fds to wait upon | |
nfds | the number of fds to wait upon | |
exception | exception flag | |
outfd | fd that had activity on it | |
ms | how long the wait was Big momma function here. Wait for activity on any of the n channels, or any of the nfds file descriptors. |
Definition at line 1982 of file channel.c.
References ast_channel::_softhangup, ast_add_fd(), ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, ast_log(), AST_MAX_FDS, ast_poll, ast_set_flag, AST_SOFTHANGUP_TIMEOUT, ast_tvdiff_ms(), ast_tvnow(), chanlist::chan, CHECK_BLOCKING, errno, LOG_WARNING, and ast_channel::whentohangup.
Referenced by ast_waitfor(), ast_waitfor_n(), ast_waitfor_n_fd(), ast_waitfordigit_full(), conf_run(), eivr_comm(), find_cache(), run_agi(), and waitstream_core().
01985 { 01986 struct timeval start = { 0 , 0 }; 01987 struct pollfd *pfds = NULL; 01988 int res; 01989 long rms; 01990 int x, y, max; 01991 int sz; 01992 time_t now = 0; 01993 long whentohangup = 0, diff; 01994 struct ast_channel *winner = NULL; 01995 struct fdmap { 01996 int chan; 01997 int fdno; 01998 } *fdmap = NULL; 01999 02000 if ((sz = n * AST_MAX_FDS + nfds)) { 02001 pfds = alloca(sizeof(*pfds) * sz); 02002 fdmap = alloca(sizeof(*fdmap) * sz); 02003 } 02004 02005 if (outfd) 02006 *outfd = -99999; 02007 if (exception) 02008 *exception = 0; 02009 02010 /* Perform any pending masquerades */ 02011 for (x = 0; x < n; x++) { 02012 ast_channel_lock(c[x]); 02013 if (c[x]->masq && ast_do_masquerade(c[x])) { 02014 ast_log(LOG_WARNING, "Masquerade failed\n"); 02015 *ms = -1; 02016 ast_channel_unlock(c[x]); 02017 return NULL; 02018 } 02019 if (c[x]->whentohangup) { 02020 if (!whentohangup) 02021 time(&now); 02022 diff = c[x]->whentohangup - now; 02023 if (diff < 1) { 02024 /* Should already be hungup */ 02025 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 02026 ast_channel_unlock(c[x]); 02027 return c[x]; 02028 } 02029 if (!whentohangup || (diff < whentohangup)) 02030 whentohangup = diff; 02031 } 02032 ast_channel_unlock(c[x]); 02033 } 02034 /* Wait full interval */ 02035 rms = *ms; 02036 if (whentohangup) { 02037 rms = whentohangup * 1000; /* timeout in milliseconds */ 02038 if (*ms >= 0 && *ms < rms) /* original *ms still smaller */ 02039 rms = *ms; 02040 } 02041 /* 02042 * Build the pollfd array, putting the channels' fds first, 02043 * followed by individual fds. Order is important because 02044 * individual fd's must have priority over channel fds. 02045 */ 02046 max = 0; 02047 for (x = 0; x < n; x++) { 02048 for (y = 0; y < AST_MAX_FDS; y++) { 02049 fdmap[max].fdno = y; /* fd y is linked to this pfds */ 02050 fdmap[max].chan = x; /* channel x is linked to this pfds */ 02051 max += ast_add_fd(&pfds[max], c[x]->fds[y]); 02052 } 02053 CHECK_BLOCKING(c[x]); 02054 } 02055 /* Add the individual fds */ 02056 for (x = 0; x < nfds; x++) { 02057 fdmap[max].chan = -1; 02058 max += ast_add_fd(&pfds[max], fds[x]); 02059 } 02060 02061 if (*ms > 0) 02062 start = ast_tvnow(); 02063 02064 if (sizeof(int) == 4) { /* XXX fix timeout > 600000 on linux x86-32 */ 02065 do { 02066 int kbrms = rms; 02067 if (kbrms > 600000) 02068 kbrms = 600000; 02069 res = ast_poll(pfds, max, kbrms); 02070 if (!res) 02071 rms -= kbrms; 02072 } while (!res && (rms > 0)); 02073 } else { 02074 res = ast_poll(pfds, max, rms); 02075 } 02076 for (x = 0; x < n; x++) 02077 ast_clear_flag(c[x], AST_FLAG_BLOCKING); 02078 if (res < 0) { /* Simulate a timeout if we were interrupted */ 02079 if (errno != EINTR) 02080 *ms = -1; 02081 return NULL; 02082 } 02083 if (whentohangup) { /* if we have a timeout, check who expired */ 02084 time(&now); 02085 for (x = 0; x < n; x++) { 02086 if (c[x]->whentohangup && now >= c[x]->whentohangup) { 02087 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 02088 if (winner == NULL) 02089 winner = c[x]; 02090 } 02091 } 02092 } 02093 if (res == 0) { /* no fd ready, reset timeout and done */ 02094 *ms = 0; /* XXX use 0 since we may not have an exact timeout. */ 02095 return winner; 02096 } 02097 /* 02098 * Then check if any channel or fd has a pending event. 02099 * Remember to check channels first and fds last, as they 02100 * must have priority on setting 'winner' 02101 */ 02102 for (x = 0; x < max; x++) { 02103 res = pfds[x].revents; 02104 if (res == 0) 02105 continue; 02106 if (fdmap[x].chan >= 0) { /* this is a channel */ 02107 winner = c[fdmap[x].chan]; /* override previous winners */ 02108 if (res & POLLPRI) 02109 ast_set_flag(winner, AST_FLAG_EXCEPTION); 02110 else 02111 ast_clear_flag(winner, AST_FLAG_EXCEPTION); 02112 winner->fdno = fdmap[x].fdno; 02113 } else { /* this is an fd */ 02114 if (outfd) 02115 *outfd = pfds[x].fd; 02116 if (exception) 02117 *exception = (res & POLLPRI) ? -1 : 0; 02118 winner = NULL; 02119 } 02120 } 02121 if (*ms > 0) { 02122 *ms -= ast_tvdiff_ms(ast_tvnow(), start); 02123 if (*ms < 0) 02124 *ms = 0; 02125 } 02126 return winner; 02127 }
int ast_waitfordigit | ( | struct ast_channel * | c, | |
int | ms | |||
) |
Waits for a digit.
!
c | channel to wait for a digit on | |
ms | how many milliseconds to wait |
Definition at line 2345 of file channel.c.
References ast_waitfordigit_full().
Referenced by _ast_adsi_get_cpeid(), _ast_adsi_get_cpeinfo(), _ast_adsi_print(), _ast_adsi_read_encoded_dtmf(), _ast_adsi_transmit_message_full(), _while_exec(), advanced_options(), ast_app_dtget(), ast_control_streamfile(), ast_record_review(), 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_seq(), sendnoise(), ss_thread(), testclient_exec(), testserver_exec(), vm_execmain(), vm_forwardoptions(), vm_instructions_en(), vm_options(), vm_tempgreeting(), wait_a_bit(), and wait_our_turn().
02346 { 02347 return ast_waitfordigit_full(c, ms, -1, -1); 02348 }
int ast_waitfordigit_full | ( | struct ast_channel * | c, | |
int | ms, | |||
int | audiofd, | |||
int | ctrlfd | |||
) |
Wait for a digit Same as ast_waitfordigit() with audio fd for outputting read audio and ctrlfd to monitor for reading.
c | channel to wait for a digit on | |
ms | how many milliseconds to wait | |
audiofd | audio file descriptor to write to if audio frames are received | |
ctrlfd | control file descriptor to monitor for reading |
Definition at line 2370 of file channel.c.
References ast_check_hangup(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_FLAG_END_DTMF_ONLY, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_frfree, ast_log(), ast_read(), ast_set_flag, ast_test_flag, ast_waitfor_nandfds(), errno, f, and LOG_WARNING.
Referenced by ast_readstring_full(), ast_waitfordigit(), handle_getoption(), and handle_waitfordigit().
02371 { 02372 /* Stop if we're a zombie or need a soft hangup */ 02373 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 02374 return -1; 02375 02376 /* Only look for the end of DTMF, don't bother with the beginning and don't emulate things */ 02377 ast_set_flag(c, AST_FLAG_END_DTMF_ONLY); 02378 02379 /* Wait for a digit, no more than ms milliseconds total. */ 02380 02381 while (ms) { 02382 struct ast_channel *rchan; 02383 int outfd=-1; 02384 02385 errno = 0; 02386 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 02387 02388 if (!rchan && outfd < 0 && ms) { 02389 if (errno == 0 || errno == EINTR) 02390 continue; 02391 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 02392 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 02393 return -1; 02394 } else if (outfd > -1) { 02395 /* The FD we were watching has something waiting */ 02396 ast_log(LOG_WARNING, "The FD we were waiting for has something waiting. Waitfordigit returning numeric 1\n"); 02397 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 02398 return 1; 02399 } else if (rchan) { 02400 int res; 02401 struct ast_frame *f = ast_read(c); 02402 if (!f) 02403 return -1; 02404 02405 switch (f->frametype) { 02406 case AST_FRAME_DTMF_BEGIN: 02407 break; 02408 case AST_FRAME_DTMF_END: 02409 res = f->subclass; 02410 ast_frfree(f); 02411 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 02412 return res; 02413 case AST_FRAME_CONTROL: 02414 switch (f->subclass) { 02415 case AST_CONTROL_HANGUP: 02416 ast_frfree(f); 02417 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 02418 return -1; 02419 case AST_CONTROL_RINGING: 02420 case AST_CONTROL_ANSWER: 02421 case AST_CONTROL_SRCUPDATE: 02422 /* Unimportant */ 02423 break; 02424 default: 02425 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass); 02426 break; 02427 } 02428 break; 02429 case AST_FRAME_VOICE: 02430 /* Write audio if appropriate */ 02431 if (audiofd > -1) { 02432 if (write(audiofd, f->data, f->datalen) < 0) { 02433 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 02434 } 02435 } 02436 default: 02437 /* Ignore */ 02438 break; 02439 } 02440 ast_frfree(f); 02441 } 02442 } 02443 02444 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 02445 02446 return 0; /* Time is up */ 02447 }
struct ast_channel* ast_walk_channel_by_exten_locked | ( | const struct ast_channel * | chan, | |
const char * | exten, | |||
const char * | context | |||
) |
Get next channel by exten (and optionally context) and lock it.
Definition at line 1277 of file channel.c.
References chanlist::chan, and channel_find_locked().
Referenced by next_channel().
01279 { 01280 return channel_find_locked(chan, NULL, 0, context, exten); 01281 }
struct ast_channel* ast_walk_channel_by_name_prefix_locked | ( | const struct ast_channel * | chan, | |
const char * | name, | |||
const int | namelen | |||
) |
Get channel by name or uniqueid prefix (locks channel).
Definition at line 1264 of file channel.c.
References chanlist::chan, and channel_find_locked().
Referenced by my_ast_get_channel_by_name_locked(), next_channel(), and softhangup_exec().
01266 { 01267 return channel_find_locked(chan, name, namelen, NULL, NULL); 01268 }
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 3313 of file channel.c.
References ast_channel::_softhangup, AST_AUDIOHOOK_DIRECTION_WRITE, ast_audiohook_write_list(), 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_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_frfree, AST_LIST_NEXT, ast_log(), AST_MONITOR_RUNNING, ast_seekstream(), ast_senddigit_begin(), ast_senddigit_end(), AST_SOFTHANGUP_DEV, ast_test_flag, ast_translate(), ast_writestream(), ast_channel::audiohooks, chanlist::chan, CHECK_BLOCKING, ast_frame::data, ast_frame::datalen, DEBUGCHAN_FLAG, f, ast_channel::fout, ast_frame::frame_list, FRAMECOUNT_INC, ast_frame::frametype, ast_channel::generatordata, ast_channel_tech::indicate, ast_channel::insmpl, ast_frame::len, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::name, chanlist::next, ast_channel::outsmpl, ast_channel::rawwriteformat, ast_frame::samples, SEEK_FORCECUR, send_dtmf_event(), ast_channel_tech::send_html, ast_channel_tech::send_text, ast_channel_monitor::state, ast_frame::subclass, ast_channel::tech, ast_channel_tech::write, ast_channel_monitor::write_stream, ast_channel_tech::write_text, ast_channel_tech::write_video, and ast_channel::writetrans.
Referenced by adsi_careful_send(), agent_write(), ast_prod(), ast_readaudio_callback(), ast_readvideo_callback(), ast_udptl_bridge(), ast_write_video(), bridge_native_loop(), conf_queue_dtmf(), conf_run(), dahdi_bridge(), dictate_exec(), echo_exec(), fax_generator_generate(), features_write(), function_ilink(), gen_generate(), handle_jack_audio(), handle_link_data(), jb_get_and_deliver(), linear_generator(), milliwatt_generate(), misdn_bridge(), moh_files_generator(), moh_generate(), mp3_exec(), NBScat_exec(), rpt(), rpt_call(), send_link_dtmf(), send_tone_burst(), send_waveform_to_channel(), silence_generator_generate(), spy_generate(), t38_tx_packet_handler(), and wait_for_answer().
03314 { 03315 int res = -1; 03316 struct ast_frame *f = NULL; 03317 int count = 0; 03318 03319 /*Deadlock avoidance*/ 03320 while(ast_channel_trylock(chan)) { 03321 /*cannot goto done since the channel is not locked*/ 03322 if(count++ > 10) { 03323 ast_debug(1, "Deadlock avoided for write to channel '%s'\n", chan->name); 03324 return 0; 03325 } 03326 usleep(1); 03327 } 03328 /* Stop if we're a zombie or need a soft hangup */ 03329 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) 03330 goto done; 03331 03332 /* Handle any pending masquerades */ 03333 if (chan->masq && ast_do_masquerade(chan)) { 03334 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 03335 goto done; 03336 } 03337 if (chan->masqr) { 03338 res = 0; /* XXX explain, why 0 ? */ 03339 goto done; 03340 } 03341 if (chan->generatordata) { 03342 if (ast_test_flag(chan, AST_FLAG_WRITE_INT)) 03343 ast_deactivate_generator(chan); 03344 else { 03345 if (fr->frametype == AST_FRAME_DTMF_END) { 03346 /* There is a generator running while we're in the middle of a digit. 03347 * It's probably inband DTMF, so go ahead and pass it so it can 03348 * stop the generator */ 03349 ast_clear_flag(chan, AST_FLAG_BLOCKING); 03350 ast_channel_unlock(chan); 03351 res = ast_senddigit_end(chan, fr->subclass, fr->len); 03352 ast_channel_lock(chan); 03353 CHECK_BLOCKING(chan); 03354 } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass == AST_CONTROL_UNHOLD) { 03355 /* This is a side case where Echo is basically being called and the person put themselves on hold and took themselves off hold */ 03356 res = (chan->tech->indicate == NULL) ? 0 : 03357 chan->tech->indicate(chan, fr->subclass, fr->data, fr->datalen); 03358 } 03359 res = 0; /* XXX explain, why 0 ? */ 03360 goto done; 03361 } 03362 } 03363 /* High bit prints debugging */ 03364 if (chan->fout & DEBUGCHAN_FLAG) 03365 ast_frame_dump(chan->name, fr, ">>"); 03366 CHECK_BLOCKING(chan); 03367 switch (fr->frametype) { 03368 case AST_FRAME_CONTROL: 03369 res = (chan->tech->indicate == NULL) ? 0 : 03370 chan->tech->indicate(chan, fr->subclass, fr->data, fr->datalen); 03371 break; 03372 case AST_FRAME_DTMF_BEGIN: 03373 if (chan->audiohooks) { 03374 struct ast_frame *old_frame = fr; 03375 fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr); 03376 if (old_frame != fr) 03377 f = fr; 03378 } 03379 send_dtmf_event(chan, "Sent", fr->subclass, "Yes", "No"); 03380 ast_clear_flag(chan, AST_FLAG_BLOCKING); 03381 ast_channel_unlock(chan); 03382 res = ast_senddigit_begin(chan, fr->subclass); 03383 ast_channel_lock(chan); 03384 CHECK_BLOCKING(chan); 03385 break; 03386 case AST_FRAME_DTMF_END: 03387 if (chan->audiohooks) { 03388 struct ast_frame *new_frame = fr; 03389 03390 new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr); 03391 if (new_frame != fr) { 03392 ast_frfree(new_frame); 03393 } 03394 } 03395 send_dtmf_event(chan, "Sent", fr->subclass, "No", "Yes"); 03396 ast_clear_flag(chan, AST_FLAG_BLOCKING); 03397 ast_channel_unlock(chan); 03398 res = ast_senddigit_end(chan, fr->subclass, fr->len); 03399 ast_channel_lock(chan); 03400 CHECK_BLOCKING(chan); 03401 break; 03402 case AST_FRAME_TEXT: 03403 if (fr->subclass == AST_FORMAT_T140) { 03404 res = (chan->tech->write_text == NULL) ? 0 : 03405 chan->tech->write_text(chan, fr); 03406 } else { 03407 res = (chan->tech->send_text == NULL) ? 0 : 03408 chan->tech->send_text(chan, (char *) fr->data); 03409 } 03410 break; 03411 case AST_FRAME_HTML: 03412 res = (chan->tech->send_html == NULL) ? 0 : 03413 chan->tech->send_html(chan, fr->subclass, (char *) fr->data, fr->datalen); 03414 break; 03415 case AST_FRAME_VIDEO: 03416 /* XXX Handle translation of video codecs one day XXX */ 03417 res = (chan->tech->write_video == NULL) ? 0 : 03418 chan->tech->write_video(chan, fr); 03419 break; 03420 case AST_FRAME_MODEM: 03421 res = (chan->tech->write == NULL) ? 0 : 03422 chan->tech->write(chan, fr); 03423 break; 03424 case AST_FRAME_VOICE: 03425 if (chan->tech->write == NULL) 03426 break; /*! \todo XXX should return 0 maybe ? */ 03427 03428 /* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */ 03429 if (fr->subclass == chan->rawwriteformat) 03430 f = fr; 03431 else 03432 f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr; 03433 03434 if (!f) { 03435 res = 0; 03436 break; 03437 } 03438 03439 if (chan->audiohooks) { 03440 struct ast_frame *new_frame, *cur; 03441 03442 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 03443 new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, cur); 03444 if (new_frame != cur) { 03445 ast_frfree(new_frame); 03446 } 03447 } 03448 } 03449 03450 /* If Monitor is running on this channel, then we have to write frames out there too */ 03451 /* the translator on chan->writetrans may have returned multiple frames 03452 from the single frame we passed in; if so, feed each one of them to the 03453 monitor */ 03454 if (chan->monitor && chan->monitor->write_stream) { 03455 struct ast_frame *cur; 03456 03457 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 03458 /* XXX must explain this code */ 03459 #ifndef MONITOR_CONSTANT_DELAY 03460 int jump = chan->insmpl - chan->outsmpl - 4 * cur->samples; 03461 if (jump >= 0) { 03462 jump = chan->insmpl - chan->outsmpl; 03463 if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1) 03464 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 03465 chan->outsmpl += jump + cur->samples; 03466 } else { 03467 chan->outsmpl += cur->samples; 03468 } 03469 #else 03470 int jump = chan->insmpl - chan->outsmpl; 03471 if (jump - MONITOR_DELAY >= 0) { 03472 if (ast_seekstream(chan->monitor->write_stream, jump - cur->samples, SEEK_FORCECUR) == -1) 03473 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 03474 chan->outsmpl += jump; 03475 } else { 03476 chan->outsmpl += cur->samples; 03477 } 03478 #endif 03479 if (chan->monitor->state == AST_MONITOR_RUNNING) { 03480 if (ast_writestream(chan->monitor->write_stream, cur) < 0) 03481 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n"); 03482 } 03483 } 03484 } 03485 03486 /* the translator on chan->writetrans may have returned multiple frames 03487 from the single frame we passed in; if so, feed each one of them to the 03488 channel, freeing each one after it has been written */ 03489 if ((f != fr) && AST_LIST_NEXT(f, frame_list)) { 03490 struct ast_frame *cur, *next; 03491 unsigned int skip = 0; 03492 03493 for (cur = f, next = AST_LIST_NEXT(cur, frame_list); 03494 cur; 03495 cur = next, next = cur ? AST_LIST_NEXT(cur, frame_list) : NULL) { 03496 if (!skip) { 03497 if ((res = chan->tech->write(chan, cur)) < 0) { 03498 chan->_softhangup |= AST_SOFTHANGUP_DEV; 03499 skip = 1; 03500 } else if (next) { 03501 /* don't do this for the last frame in the list, 03502 as the code outside the loop will do it once 03503 */ 03504 chan->fout = FRAMECOUNT_INC(chan->fout); 03505 } 03506 } 03507 ast_frfree(cur); 03508 } 03509 03510 /* reset f so the code below doesn't attempt to free it */ 03511 f = NULL; 03512 } else { 03513 res = chan->tech->write(chan, f); 03514 } 03515 break; 03516 case AST_FRAME_NULL: 03517 case AST_FRAME_IAX: 03518 /* Ignore these */ 03519 res = 0; 03520 break; 03521 default: 03522 /* At this point, fr is the incoming frame and f is NULL. Channels do 03523 * not expect to get NULL as a frame pointer and will segfault. Hence, 03524 * we output the original frame passed in. */ 03525 res = chan->tech->write(chan, fr); 03526 break; 03527 } 03528 03529 if (f && f != fr) 03530 ast_frfree(f); 03531 ast_clear_flag(chan, AST_FLAG_BLOCKING); 03532 03533 /* Consider a write failure to force a soft hangup */ 03534 if (res < 0) { 03535 chan->_softhangup |= AST_SOFTHANGUP_DEV; 03536 } else { 03537 chan->fout = FRAMECOUNT_INC(chan->fout); 03538 } 03539 done: 03540 ast_channel_unlock(chan); 03541 return res; 03542 }
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 3302 of file channel.c.
References ast_write(), chanlist::chan, ast_channel::tech, and ast_channel_tech::write_video.
03303 { 03304 int res; 03305 if (!chan->tech->write_video) 03306 return 0; 03307 res = ast_write(chan, fr); 03308 if (!res) 03309 res = 1; 03310 return res; 03311 }
const char* channelreloadreason2txt | ( | enum channelreloadreason | reason | ) |
Convert enum channelreloadreason to text string for manager event.
\ brief Convert channel reloadreason (ENUM) to text string for manager event
Definition at line 5511 of file channel.c.
References CHANNEL_CLI_RELOAD, CHANNEL_MODULE_LOAD, and CHANNEL_MODULE_RELOAD.
05512 { 05513 switch (reason) { 05514 case CHANNEL_MODULE_LOAD: 05515 return "LOAD (Channel module load)"; 05516 05517 case CHANNEL_MODULE_RELOAD: 05518 return "RELOAD (Channel module reload)"; 05519 05520 case CHANNEL_CLI_RELOAD: 05521 return "CLIRELOAD (Channel module reload by CLI command)"; 05522 05523 default: 05524 return "MANAGERRELOAD (Channel module reload by manager)"; 05525 } 05526 };
static void timersub | ( | struct timeval * | tvend, | |
struct timeval * | tvstart, | |||
struct timeval * | tvdiff | |||
) | [inline, static] |
Definition at line 1647 of file channel.h.
Referenced by ast_rtcp_write_rr(), ast_rtcp_write_sr(), and ast_select().
01648 { 01649 tvdiff->tv_sec = tvend->tv_sec - tvstart->tv_sec; 01650 tvdiff->tv_usec = tvend->tv_usec - tvstart->tv_usec; 01651 if (tvdiff->tv_usec < 0) { 01652 tvdiff->tv_sec --; 01653 tvdiff->tv_usec += 1000000; 01654 } 01655 01656 }
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 88 of file channel.c.
Referenced by handle_core_set_debug_channel().
unsigned long global_fout |