Wed Oct 28 15:48:40 2009

Asterisk developer's documentation


channel.h File Reference

General Asterisk PBX channel definitions. More...

#include <unistd.h>
#include <setjmp.h>
#include <sys/poll.h>
#include "asterisk/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 dependency graph for channel.h:

Go to the source code of this file.

Data Structures

struct  ast_bridge_config
struct  ast_callerid
struct  ast_channel
struct  ast_channel_tech
struct  ast_generator
struct  outgoing_helper

Defines

#define AST_ADSI_AVAILABLE   (1)
#define AST_ADSI_OFFHOOKONLY   (3)
#define AST_ADSI_UNAVAILABLE   (2)
#define AST_ADSI_UNKNOWN   (0)
#define AST_BRIDGE_DTMF_CHANNEL_0   (1 << 0)
#define AST_BRIDGE_DTMF_CHANNEL_1   (1 << 1)
#define AST_BRIDGE_IGNORE_SIGS   (1 << 4)
#define AST_BRIDGE_REC_CHANNEL_0   (1 << 2)
#define AST_BRIDGE_REC_CHANNEL_1   (1 << 3)
#define AST_CDR_CALLWAIT   (1 << 2)
#define AST_CDR_CONFERENCE   (1 << 3)
#define AST_CDR_FORWARD   (1 << 1)
#define AST_CDR_TRANSFER   (1 << 0)
#define AST_CHANNEL_NAME   80
#define AST_FEATURE_ATXFER   (1 << 3)
#define AST_FEATURE_AUTOMON   (1 << 4)
#define AST_FEATURE_DISCONNECT   (1 << 2)
#define AST_FEATURE_FLAG_CALLEE   (1 << 1)
#define AST_FEATURE_FLAG_CALLER   (1 << 2)
#define AST_FEATURE_FLAG_NEEDSDTMF   (1 << 0)
#define AST_FEATURE_PLAY_WARNING   (1 << 0)
#define AST_FEATURE_REDIRECT   (1 << 1)
#define AST_MAX_CONTEXT   80
#define AST_MAX_EXTENSION   80
#define AST_MAX_FDS   8
#define AST_SOFTHANGUP_APPUNLOAD   (1 << 4)
#define AST_SOFTHANGUP_ASYNCGOTO   (1 << 1)
#define AST_SOFTHANGUP_DEV   (1 << 0)
#define AST_SOFTHANGUP_EXPLICIT   (1 << 5)
#define AST_SOFTHANGUP_SHUTDOWN   (1 << 2)
#define AST_SOFTHANGUP_TIMEOUT   (1 << 3)
#define AST_SOFTHANGUP_UNBRIDGE   (1 << 6)
#define AST_STATE_BUSY   7
#define AST_STATE_DIALING   3
#define AST_STATE_DIALING_OFFHOOK   8
#define AST_STATE_DOWN   0
#define AST_STATE_MUTE   (1 << 16)
#define AST_STATE_OFFHOOK   2
#define AST_STATE_PRERING   9
#define AST_STATE_RESERVED   1
#define AST_STATE_RING   4
#define AST_STATE_RINGING   5
#define AST_STATE_UP   6
#define ast_strdupa(s)
#define CHECK_BLOCKING(c)
#define CRASH   do { } while(0)
#define LOAD_OH(oh)
#define MAX_LANGUAGE   20
#define MAX_MUSICCLASS   20
#define AST_CHAN_TP_WANTSJITTER   (1 << 0)
#define AST_FLAG_BLOCKING   (1 << 3)
#define AST_FLAG_DEFER_DTMF   (1 << 1)
#define AST_FLAG_EXCEPTION   (1 << 5)
#define AST_FLAG_IN_AUTOLOOP   (1 << 9)
#define AST_FLAG_MOH   (1 << 6)
#define AST_FLAG_NBRIDGE   (1 << 8)
#define AST_FLAG_NOTNEW   (1 << 10)
#define AST_FLAG_SPYING   (1 << 7)
#define AST_FLAG_WRITE_INT   (1 << 2)
#define AST_FLAG_ZOMBIE   (1 << 4)

Typedefs

typedef unsigned long long ast_group_t

Enumerations

enum  ast_bridge_result { AST_BRIDGE_COMPLETE = 0, AST_BRIDGE_FAILED = -1, AST_BRIDGE_FAILED_NOWARN = -2, AST_BRIDGE_RETRY = -3 }

Functions

struct ast_channel__ast_request_and_dial (const char *type, int format, void *data, int timeout, int *reason, const char *cidnum, const char *cidname, struct outgoing_helper *oh)
int ast_activate_generator (struct ast_channel *chan, struct ast_generator *gen, void *params)
int ast_active_channels (void)
int ast_answer (struct ast_channel *chan)
 Answer a ringing call.
int ast_autoservice_start (struct ast_channel *chan)
int ast_autoservice_stop (struct ast_channel *chan)
void ast_begin_shutdown (int hangup)
int ast_best_codec (int fmts)
struct ast_channelast_bridged_channel (struct ast_channel *chan)
 Find bridged channel.
int ast_call (struct ast_channel *chan, char *addr, int timeout)
 Make a call.
void ast_cancel_shutdown (void)
const char * ast_cause2str (int state)
void ast_change_name (struct ast_channel *chan, char *newname)
 Change channel name.
struct ast_channelast_channel_alloc (int needalertpipe)
 Create a channel structure.
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)
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_defer_dtmf (struct ast_channel *chan)
void ast_channel_free (struct ast_channel *)
 Free a channel structure.
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)
int ast_channel_masquerade (struct ast_channel *original, struct ast_channel *clone)
struct ast_frameast_channel_queryoption (struct ast_channel *channel, int option, void *data, int *datalen, int block)
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)
int ast_channel_setoption (struct ast_channel *channel, int option, void *data, int datalen, int block)
void ast_channel_setwhentohangup (struct ast_channel *chan, time_t offset)
 Set when to hang a channel up.
struct ast_silence_generatorast_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)
void ast_channel_unregister (const struct ast_channel_tech *tech)
 Unregister a channel technology.
struct ast_channelast_channel_walk_locked (const struct ast_channel *prev)
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 wacked 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)
struct ast_channelast_get_channel_by_exten_locked (const char *exten, const char *context)
struct ast_channelast_get_channel_by_name_locked (const char *chan)
struct ast_channelast_get_channel_by_name_prefix_locked (const char *name, const int namelen)
struct ast_channel_techast_get_channel_tech (const char *name)
 Get a channel technology structure by name.
ast_group_t ast_get_group (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.
char * ast_print_group (char *buf, int buflen, ast_group_t group)
int ast_prod (struct ast_channel *chan)
int ast_queue_control (struct ast_channel *chan, int control)
 Queue a control frame.
int ast_queue_frame (struct ast_channel *chan, struct ast_frame *f)
 Queue an outgoing frame.
int ast_queue_hangup (struct ast_channel *chan)
 Queue a hangup frame.
struct ast_frameast_read (struct ast_channel *chan)
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)
char * ast_recvtext (struct ast_channel *chan, int timeout)
struct ast_channelast_request (const char *type, int format, void *data, int *status)
 Requests a channel.
struct ast_channelast_request_and_dial (const char *type, int format, void *data, int timeout, int *reason, const char *cidnum, const char *cidname)
 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 specied 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 specied 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)
int ast_sendtext (struct ast_channel *chan, const char *text)
void ast_set_callerid (struct ast_channel *chan, const char *cidnum, const char *cidname, const char *ani)
int ast_set_read_format (struct ast_channel *chan, int format)
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)
int ast_setstate (struct ast_channel *chan, int state)
 Change the state of a channel.
int ast_settimeout (struct ast_channel *c, int samples, int(*func)(void *data), void *data)
int ast_shutting_down (void)
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).
char * ast_state2str (int state)
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)
int ast_waitfor (struct ast_channel *chan, int ms)
 Wait for input on a channel.
struct ast_channelast_waitfor_n (struct ast_channel **chan, int n, int *ms)
int ast_waitfor_n_fd (int *fds, int n, int *ms, int *exception)
struct ast_channelast_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)
int ast_waitfordigit_full (struct ast_channel *c, int ms, int audiofd, int ctrlfd)
struct ast_channelast_walk_channel_by_name_prefix_locked (struct ast_channel *chan, const char *name, const int namelen)
int ast_write (struct ast_channel *chan, struct ast_frame *frame)
int ast_write_video (struct ast_channel *chan, struct ast_frame *frame)


Detailed Description

General Asterisk PBX channel definitions.

See also:

Definition in file channel.h.


Define Documentation

#define AST_ADSI_AVAILABLE   (1)

Definition at line 496 of file channel.h.

Referenced by __adsi_transmit_messages(), and adsi_available().

#define AST_ADSI_OFFHOOKONLY   (3)

Definition at line 498 of file channel.h.

#define AST_ADSI_UNAVAILABLE   (2)

Definition at line 497 of file channel.h.

Referenced by __adsi_transmit_messages(), mgcp_new(), sip_new(), skinny_new(), and zt_new().

#define AST_ADSI_UNKNOWN   (0)

Definition at line 495 of file channel.h.

Referenced by adsi_available().

#define AST_BRIDGE_DTMF_CHANNEL_0   (1 << 0)

#define AST_BRIDGE_DTMF_CHANNEL_1   (1 << 1)

#define AST_BRIDGE_IGNORE_SIGS   (1 << 4)

Ignore all signal frames except NULL

Definition at line 880 of file channel.h.

Referenced by ast_generic_bridge(), ast_rtp_bridge(), iax2_bridge(), and monitor_handle_owned().

#define AST_BRIDGE_REC_CHANNEL_0   (1 << 2)

Return all voice frames on channel 0

Definition at line 876 of file channel.h.

Referenced by do_chanreads().

#define AST_BRIDGE_REC_CHANNEL_1   (1 << 3)

Return all voice frames on channel 1

Definition at line 878 of file channel.h.

Referenced by do_chanreads().

#define AST_CDR_CALLWAIT   (1 << 2)

Definition at line 492 of file channel.h.

Referenced by zt_request().

#define AST_CDR_CONFERENCE   (1 << 3)

Definition at line 493 of file channel.h.

#define AST_CDR_FORWARD   (1 << 1)

Definition at line 491 of file channel.h.

#define AST_CDR_TRANSFER   (1 << 0)

Definition at line 490 of file channel.h.

#define AST_CHAN_TP_WANTSJITTER   (1 << 0)

Definition at line 422 of file channel.h.

Referenced by schedule_delivery().

#define AST_CHANNEL_NAME   80

Definition at line 106 of file channel.h.

Referenced by ast_channel_free(), ast_parse_device_state(), page_exec(), and softhangup_exec().

#define AST_FEATURE_ATXFER   (1 << 3)

Definition at line 444 of file channel.h.

#define AST_FEATURE_AUTOMON   (1 << 4)

Definition at line 445 of file channel.h.

Referenced by dial_exec_full(), and try_calling().

#define AST_FEATURE_DISCONNECT   (1 << 2)

Definition at line 443 of file channel.h.

Referenced by builtin_atxfer(), dial_exec_full(), and try_calling().

#define AST_FEATURE_FLAG_CALLEE   (1 << 1)

Definition at line 448 of file channel.h.

Referenced by feature_exec_app(), load_config(), and set_config_flags().

#define AST_FEATURE_FLAG_CALLER   (1 << 2)

Definition at line 449 of file channel.h.

Referenced by load_config(), and set_config_flags().

#define AST_FEATURE_FLAG_NEEDSDTMF   (1 << 0)

Definition at line 447 of file channel.h.

Referenced by load_config(), and set_config_flags().

#define AST_FEATURE_PLAY_WARNING   (1 << 0)

Definition at line 441 of file channel.h.

Referenced by ast_bridge_call(), ast_channel_bridge(), and dial_exec_full().

#define AST_FEATURE_REDIRECT   (1 << 1)

Definition at line 442 of file channel.h.

Referenced by ast_channel_bridge(), dial_exec_full(), park_exec(), and try_calling().

#define AST_FLAG_BLOCKING   (1 << 3)

#define AST_FLAG_DEFER_DTMF   (1 << 1)

if dtmf should be deferred

Definition at line 426 of file channel.h.

Referenced by ast_channel_defer_dtmf(), ast_channel_undefer_dtmf(), and ast_read().

#define AST_FLAG_EXCEPTION   (1 << 5)

if there is a pending exception

Definition at line 430 of file channel.h.

Referenced by agent_read(), ast_do_masquerade(), ast_read(), ast_waitfor_nandfds(), do_parking_thread(), and zt_read().

#define AST_FLAG_IN_AUTOLOOP   (1 << 9)

the channel is in an auto-incrementing dialplan processor, so when ->priority is set, it will get incremented before finding the next priority to run

Definition at line 434 of file channel.h.

Referenced by __ast_pbx_run(), ast_explicit_goto(), and macro_exec().

#define AST_FLAG_MOH   (1 << 6)

XXX anthm promises me this will disappear XXX listening to moh

Definition at line 431 of file channel.h.

Referenced by local_ast_moh_start(), local_ast_moh_stop(), moh_on_off(), and retrydial_exec().

#define AST_FLAG_NBRIDGE   (1 << 8)

is it in a native bridge

Definition at line 433 of file channel.h.

Referenced by ast_channel_bridge(), start_spying(), and startmon().

#define AST_FLAG_NOTNEW   (1 << 10)

see bug:7855 incorrect Newchannel event generation

Definition at line 438 of file channel.h.

Referenced by ast_request(), and ast_setstate().

#define AST_FLAG_SPYING   (1 << 7)

XXX might also go away XXX is spying on someone

Definition at line 432 of file channel.h.

Referenced by chanspy_exec().

#define AST_FLAG_WRITE_INT   (1 << 2)

if write should be interrupt generator

Definition at line 427 of file channel.h.

Referenced by ast_deactivate_generator(), ast_write(), linear_alloc(), playtones_alloc(), and tonepair_alloc().

#define AST_FLAG_ZOMBIE   (1 << 4)

#define AST_MAX_CONTEXT   80

Definition at line 104 of file channel.h.

Referenced by conf_run(), macro_exec(), and try_calling().

#define AST_MAX_EXTENSION   80

#define AST_MAX_FDS   8

#define AST_SOFTHANGUP_APPUNLOAD   (1 << 4)

Definition at line 504 of file channel.h.

Referenced by __unload_module(), and unload_module().

#define AST_SOFTHANGUP_ASYNCGOTO   (1 << 1)

Soft hangup for async goto

Definition at line 501 of file channel.h.

Referenced by __ast_pbx_run(), ast_async_goto(), and macro_exec().

#define AST_SOFTHANGUP_DEV   (1 << 0)

#define AST_SOFTHANGUP_EXPLICIT   (1 << 5)

#define AST_SOFTHANGUP_SHUTDOWN   (1 << 2)

Definition at line 502 of file channel.h.

Referenced by ast_begin_shutdown().

#define AST_SOFTHANGUP_TIMEOUT   (1 << 3)

Definition at line 503 of file channel.h.

Referenced by __ast_pbx_run(), ast_check_hangup(), and ast_waitfor_nandfds().

#define AST_SOFTHANGUP_UNBRIDGE   (1 << 6)

Definition at line 506 of file channel.h.

Referenced by ast_channel_bridge(), ast_generic_bridge(), start_spying(), and startmon().

#define ast_strdupa (  ) 

Definition at line 1174 of file channel.h.

Referenced by __login_exec(), _while_exec(), acf_curl_exec(), acf_strftime(), acf_vmcount_exec(), action_agents(), action_getvar(), add_agent(), admin_exec(), advanced_options(), app_exec(), append_mailbox(), apply_options(), aqm_exec(), ast_callerid_split(), ast_device_state(), ast_device_state_changed_literal(), ast_feature_interpret(), ast_filehelper(), ast_func_read(), ast_func_write(), ast_get_group(), ast_monitor_start(), ast_netsock_bind(), ast_osp_validate(), ast_parse_allow_disallow(), ast_parseable_goto(), ast_play_and_prepend(), ast_play_and_record_full(), ast_playtones_start(), ast_register_file_version(), ast_writefile(), astman_get_variables(), authenticate_verify(), background_detect_exec(), build_mapping(), build_peer(), build_user(), builtin_automonitor(), builtin_function_cdr_read(), builtin_function_cdr_write(), builtin_function_checkmd5(), builtin_function_if(), builtin_function_iftime(), builtin_function_math(), builtin_function_regex(), builtin_function_set(), cache_get_callno_locked(), chanavail_exec(), changethread(), channel_spy(), chanspy_exec(), check_access(), check_user_full(), complete_confcmd(), conf_exec(), conf_run(), controlplayback_exec(), count_exec(), create_addr(), curl_exec(), cut_exec(), cut_internal(), decrypt_frame(), del_exec(), deltree_exec(), dial_exec_full(), dictate_exec(), directory_exec(), disa_exec(), do_parking_thread(), dundi_lookup_exec(), dundifunc_read(), enumlookup_exec(), eval_exec(), exec_exec(), execif_exec(), features_alloc(), festival_exec(), find_conf(), find_sdp(), function_db_exists(), function_db_read(), function_db_write(), function_fieldqty(), function_iaxpeer(), function_sippeer(), get_exec(), get_group(), get_refer_info(), get_wait_interval(), gosubif_exec(), group_check_exec(), handle_save_dialplan(), handle_show_dialplan(), hasvoicemail_exec(), iax2_call(), iax2_devicestate(), iax2_prov_app(), iax2_request(), ind_load_module(), ivr_dispatch(), launch_monitor_thread(), launch_netscript(), load_config(), macro_exec(), macroif_exec(), math_exec(), md5_exec(), md5check_exec(), mixmonitor_exec(), notify_new_message(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), page_exec(), parse_sip_options(), pbx_builtin_background(), pbx_builtin_execiftime(), pbx_builtin_gotoif(), pbx_builtin_gotoiftime(), pbx_builtin_importvar(), pbx_builtin_resetcdr(), pbx_builtin_setvar(), pbx_builtin_waitexten(), peer_set_srcaddr(), play_message(), playback_exec(), pqm_exec(), privacy_exec(), process_sdp(), put_exec(), random_exec(), read_exec(), readfile_exec(), realtime_exec(), realtime_multi_odbc(), realtime_update_exec(), record_exec(), register_verify(), reload_config(), retrydial_exec(), rpt_tele_thread(), rqm_exec(), sayunixtime_exec(), send_tone_telemetry(), senddtmf_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), set_config_flags(), setcallerid_exec(), setrdnis_exec(), settransfercapability_exec(), sip_devicestate(), sip_getheader(), sip_sipredirect(), softhangup_exec(), sort_exec(), sort_internal(), start_monitor_exec(), telem_lookup(), transfer_exec(), transmit_invite(), txtcidname_exec(), upqm_exec(), userevent_exec(), verbose_exec(), vm_box_exists(), vm_exec(), vm_execmain(), vmauthenticate(), zapras_exec(), and zt_request().

#define CHECK_BLOCKING (  ) 

Definition at line 1190 of file channel.h.

Referenced by ast_sendtext(), ast_waitfor_nandfds(), ast_write(), phone_read(), and zt_read().

#define CRASH   do { } while(0)

#define LOAD_OH ( oh   ) 

Definition at line 468 of file channel.h.

Referenced by ast_pbx_outgoing_exten().

#define MAX_LANGUAGE   20

Definition at line 118 of file channel.h.

Referenced by ast_fileexists(), and ast_openvstream().

#define MAX_MUSICCLASS   20

Definition at line 120 of file channel.h.


Typedef Documentation

typedef unsigned long long ast_group_t

Definition at line 131 of file channel.h.


Enumeration Type Documentation

Enumerator:
AST_BRIDGE_COMPLETE 
AST_BRIDGE_FAILED 
AST_BRIDGE_FAILED_NOWARN 
AST_BRIDGE_RETRY 

Definition at line 124 of file channel.h.

00124                        {
00125    AST_BRIDGE_COMPLETE = 0,
00126    AST_BRIDGE_FAILED = -1,
00127    AST_BRIDGE_FAILED_NOWARN = -2,
00128    AST_BRIDGE_RETRY = -3,
00129 };


Function Documentation

struct ast_channel* __ast_request_and_dial ( const char *  type,
int  format,
void *  data,
int  timeout,
int *  reason,
const char *  cidnum,
const char *  cidname,
struct outgoing_helper oh 
) [read]

Definition at line 2449 of file channel.c.

References ast_channel::_state, outgoing_helper::account, ast_call(), AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, ast_cdr_alloc(), ast_cdr_disposition(), ast_cdr_end(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_setapp(), ast_cdr_start(), ast_cdr_update(), ast_channel_inherit_variables(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_FRAME_CONTROL, ast_frfree(), ast_hangup(), ast_log(), ast_read(), ast_request(), ast_set_callerid(), ast_set_variables(), AST_STATE_UP, ast_waitfor(), ast_channel::cdr, outgoing_helper::cid_name, outgoing_helper::cid_num, ast_channel::context, outgoing_helper::context, ast_channel::exten, outgoing_helper::exten, ast_frame::frametype, ast_channel::hangupcause, LOG_NOTICE, LOG_WARNING, outgoing_helper::parent_channel, ast_channel::priority, outgoing_helper::priority, ast_frame::subclass, and outgoing_helper::vars.

Referenced by ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_request_and_dial(), and parkandannounce_exec().

02450 {
02451    int state = 0;
02452    int cause = 0;
02453    struct ast_channel *chan;
02454    struct ast_frame *f;
02455    int res = 0;
02456    
02457    chan = ast_request(type, format, data, &cause);
02458    if (chan) {
02459       if (oh) {
02460          if (oh->vars)  
02461             ast_set_variables(chan, oh->vars);
02462          if (oh->cid_num && *oh->cid_num && oh->cid_name && *oh->cid_name)
02463             ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num);
02464          if (oh->parent_channel)
02465             ast_channel_inherit_variables(oh->parent_channel, chan);
02466          if (oh->account)
02467             ast_cdr_setaccount(chan, oh->account); 
02468       }
02469       ast_set_callerid(chan, cid_num, cid_name, cid_num);
02470 
02471       if (!ast_call(chan, data, 0)) {
02472          res = 1; /* in case chan->_state is already AST_STATE_UP */
02473          while (timeout && (chan->_state != AST_STATE_UP)) {
02474             res = ast_waitfor(chan, timeout);
02475             if (res < 0) {
02476                /* Something not cool, or timed out */
02477                break;
02478             }
02479             /* If done, break out */
02480             if (!res)
02481                break;
02482             if (timeout > -1)
02483                timeout = res;
02484             f = ast_read(chan);
02485             if (!f) {
02486                state = AST_CONTROL_HANGUP;
02487                res = 0;
02488                break;
02489             }
02490             if (f->frametype == AST_FRAME_CONTROL) {
02491                if (f->subclass == AST_CONTROL_RINGING)
02492                   state = AST_CONTROL_RINGING;
02493                else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) {
02494                   state = f->subclass;
02495                   ast_frfree(f);
02496                   break;
02497                } else if (f->subclass == AST_CONTROL_ANSWER) {
02498                   state = f->subclass;
02499                   ast_frfree(f);
02500                   break;
02501                } else if (f->subclass == AST_CONTROL_PROGRESS || f->subclass == AST_CONTROL_PROCEEDING) {
02502                   /* Ignore */
02503                } else if (f->subclass == -1) {
02504                   /* Ignore -- just stopping indications */
02505                } else {
02506                   ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
02507                }
02508             }
02509             ast_frfree(f);
02510          }
02511       } else
02512          ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
02513    } else {
02514       ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
02515       switch(cause) {
02516       case AST_CAUSE_BUSY:
02517          state = AST_CONTROL_BUSY;
02518          break;
02519       case AST_CAUSE_CONGESTION:
02520          state = AST_CONTROL_CONGESTION;
02521          break;
02522       }
02523    }
02524    if (chan) {
02525       /* Final fixups */
02526       if (oh) {
02527          if (oh->context && *oh->context)
02528             ast_copy_string(chan->context, oh->context, sizeof(chan->context));
02529          if (oh->exten && *oh->exten)
02530             ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten));
02531          if (oh->priority) 
02532             chan->priority = oh->priority;
02533       }
02534       if (chan->_state == AST_STATE_UP) 
02535          state = AST_CONTROL_ANSWER;
02536    }
02537    if (outstate)
02538       *outstate = state;
02539    if (chan && res <= 0) {
02540       if (!chan->cdr) {
02541          chan->cdr = ast_cdr_alloc();
02542          if (chan->cdr)
02543             ast_cdr_init(chan->cdr, chan);
02544       }
02545       if (chan->cdr) {
02546          char tmp[256];
02547          snprintf(tmp, 256, "%s/%s", type, (char *)data);
02548          ast_cdr_setapp(chan->cdr,"Dial",tmp);
02549          ast_cdr_update(chan);
02550          ast_cdr_start(chan->cdr);
02551          ast_cdr_end(chan->cdr);
02552          /* If the cause wasn't handled properly */
02553          if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
02554             ast_cdr_failed(chan->cdr);
02555       } else 
02556          ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
02557       ast_hangup(chan);
02558       chan = NULL;
02559    }
02560    return chan;
02561 }

int ast_activate_generator ( struct ast_channel chan,
struct ast_generator gen,
void *  params 
)

Activate a given generator

Definition at line 1476 of file channel.c.

References ast_generator::alloc, ast_mutex_lock(), ast_mutex_unlock(), ast_prod(), ast_settimeout(), ast_channel::generator, generator_force(), ast_channel::generatordata, ast_channel::lock, and ast_generator::release.

Referenced by app_exec(), ast_channel_start_silence_generator(), ast_linear_stream(), ast_playtones_start(), ast_tonepair_start(), channel_spy(), local_ast_moh_start(), milliwatt_exec(), and sms_exec().

01477 {
01478    int res = 0;
01479 
01480    ast_mutex_lock(&chan->lock);
01481 
01482    if (chan->generatordata) {
01483       if (chan->generator && chan->generator->release)
01484          chan->generator->release(chan, chan->generatordata);
01485       chan->generatordata = NULL;
01486    }
01487 
01488    ast_prod(chan);
01489    if (gen->alloc) {
01490       if (!(chan->generatordata = gen->alloc(chan, params)))
01491          res = -1;
01492    }
01493    
01494    if (!res) {
01495       ast_settimeout(chan, 160, generator_force, chan);
01496       chan->generator = gen;
01497    }
01498 
01499    ast_mutex_unlock(&chan->lock);
01500 
01501    return res;
01502 }

int ast_active_channels ( void   ) 

Returns number of active/allocated channels

Definition at line 250 of file channel.c.

References ast_mutex_lock(), ast_mutex_unlock(), channels, and ast_channel::next.

Referenced by quit_handler().

00251 {
00252    struct ast_channel *c;
00253    int cnt = 0;
00254    ast_mutex_lock(&chlock);
00255    c = channels;
00256    while(c) {
00257       cnt++;
00258       c = c->next;
00259    }
00260    ast_mutex_unlock(&chlock);
00261    return cnt;
00262 }

int ast_answer ( struct ast_channel chan  ) 

Answer a ringing call.

Parameters:
chan channel to answer This function answers a channel and handles all necessary call setup functions.
Returns:
Returns 0 on success, -1 on failure

Definition at line 1412 of file channel.c.

References ast_channel::_state, ast_channel_tech::answer, ast_cdr_answer(), ast_check_hangup(), AST_FLAG_ZOMBIE, ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_test_flag, ast_channel::cdr, ast_channel::lock, and ast_channel::tech.

Referenced by __login_exec(), agi_exec_full(), alarmreceiver_exec(), app_exec(), ast_bridge_call(), ast_control_streamfile(), ast_pickup_call(), auth_exec(), background_detect_exec(), chanspy_exec(), conf_exec(), count_exec(), datetime_exec(), dial_exec_full(), dictate_exec(), directory_exec(), disa_exec(), features_answer(), handle_answer(), ices_exec(), milliwatt_exec(), park_call_exec(), park_exec(), pbx_builtin_answer(), pbx_builtin_background(), pickup_exec(), playback_exec(), privacy_exec(), read_exec(), record_exec(), rpt_exec(), sayunixtime_exec(), send_waveform_to_channel(), skel_exec(), sms_exec(), testclient_exec(), testserver_exec(), vm_exec(), vm_execmain(), waitforsilence_exec(), zapateller_exec(), and zapras_exec().

01413 {
01414    int res = 0;
01415    ast_mutex_lock(&chan->lock);
01416    /* Stop if we're a zombie or need a soft hangup */
01417    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
01418       ast_mutex_unlock(&chan->lock);
01419       return -1;
01420    }
01421    switch(chan->_state) {
01422    case AST_STATE_RINGING:
01423    case AST_STATE_RING:
01424       if (chan->tech->answer)
01425          res = chan->tech->answer(chan);
01426       ast_setstate(chan, AST_STATE_UP);
01427       if (chan->cdr)
01428          ast_cdr_answer(chan->cdr);
01429       ast_mutex_unlock(&chan->lock);
01430       return res;
01431       break;
01432    case AST_STATE_UP:
01433       if (chan->cdr)
01434          ast_cdr_answer(chan->cdr);
01435       break;
01436    }
01437    ast_mutex_unlock(&chan->lock);
01438    return 0;
01439 }

int ast_autoservice_start ( struct ast_channel chan  ) 

Automatically service a channel for us...

Definition at line 103 of file autoservice.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, AST_PTHREADT_NULL, autoservice_run(), asent::chan, free, LOG_WARNING, malloc, and asent::next.

Referenced by ast_dtmf_stream(), ast_get_enum(), ast_get_srv(), ast_get_txt(), ast_osp_lookup(), bridge_playfile(), builtin_atxfer(), builtin_automonitor(), builtin_blindtransfer(), conf_play(), dial_exec_full(), and try_calling().

00104 {
00105    int res = -1;
00106    struct asent *as;
00107    int needstart;
00108    ast_mutex_lock(&autolock);
00109    needstart = (asthread == AST_PTHREADT_NULL) ? 1 : 0 /* aslist ? 0 : 1 */;
00110    as = aslist;
00111    while(as) {
00112       if (as->chan == chan)
00113          break;
00114       as = as->next;
00115    }
00116    if (!as) {
00117       as = malloc(sizeof(struct asent));
00118       if (as) {
00119          memset(as, 0, sizeof(struct asent));
00120          as->chan = chan;
00121          as->next = aslist;
00122          aslist = as;
00123          res = 0;
00124          if (needstart) {
00125             if (ast_pthread_create(&asthread, NULL, autoservice_run, NULL)) {
00126                ast_log(LOG_WARNING, "Unable to create autoservice thread :(\n");
00127                free(aslist);
00128                aslist = NULL;
00129                res = -1;
00130             } else
00131                pthread_kill(asthread, SIGURG);
00132          }
00133       }
00134    }
00135    ast_mutex_unlock(&autolock);
00136    return res;
00137 }

int ast_autoservice_stop ( struct ast_channel chan  ) 

Stop servicing a channel for us... Returns -1 on error or if channel has been hungup

Definition at line 139 of file autoservice.c.

References ast_channel::_softhangup, AST_FLAG_BLOCKING, ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, ast_test_flag, asent::chan, free, and asent::next.

Referenced by ast_dtmf_stream(), ast_get_enum(), ast_get_srv(), ast_get_txt(), ast_osp_lookup(), bridge_playfile(), builtin_atxfer(), builtin_automonitor(), builtin_blindtransfer(), conf_play(), dial_exec_full(), and try_calling().

00140 {
00141    int res = -1;
00142    struct asent *as, *prev;
00143    ast_mutex_lock(&autolock);
00144    as = aslist;
00145    prev = NULL;
00146    while(as) {
00147       if (as->chan == chan)
00148          break;
00149       prev = as;
00150       as = as->next;
00151    }
00152    if (as) {
00153       if (prev)
00154          prev->next = as->next;
00155       else
00156          aslist = as->next;
00157       free(as);
00158       if (!chan->_softhangup)
00159          res = 0;
00160    }
00161    if (asthread != AST_PTHREADT_NULL) 
00162       pthread_kill(asthread, SIGURG);
00163    ast_mutex_unlock(&autolock);
00164    /* Wait for it to un-block */
00165    while(ast_test_flag(chan, AST_FLAG_BLOCKING))
00166       usleep(1000);
00167    return res;
00168 }

void ast_begin_shutdown ( int  hangup  ) 

Initiate system shutdown -- prevents new channels from being allocated. If "hangup" is non-zero, all existing channels will receive soft hangups

Definition at line 234 of file channel.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_softhangup(), AST_SOFTHANGUP_SHUTDOWN, channels, ast_channel::next, and shutting_down.

Referenced by quit_handler().

00235 {
00236    struct ast_channel *c;
00237    shutting_down = 1;
00238    if (hangup) {
00239       ast_mutex_lock(&chlock);
00240       c = channels;
00241       while(c) {
00242          ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN);
00243          c = c->next;
00244       }
00245       ast_mutex_unlock(&chlock);
00246    }
00247 }

int ast_best_codec ( int  fmts  ) 

Pick the best codec

Definition at line 471 of file channel.c.

References AST_FORMAT_ADPCM, AST_FORMAT_ALAW, AST_FORMAT_G723_1, AST_FORMAT_G726, AST_FORMAT_G729A, AST_FORMAT_GSM, AST_FORMAT_ILBC, AST_FORMAT_LPC10, AST_FORMAT_SLINEAR, AST_FORMAT_SPEEX, AST_FORMAT_ULAW, ast_log(), LOG_WARNING, and prefs.

Referenced by __login_exec(), __oh323_new(), agent_call(), ast_codec_choose(), ast_iax2_new(), builtin_atxfer(), echo_exec(), iax2_request(), local_new(), mgcp_new(), sip_new(), skinny_new(), and socket_read().

00472 {
00473    /* This just our opinion, expressed in code.  We are asked to choose
00474       the best codec to use, given no information */
00475    int x;
00476    static int prefs[] = 
00477    {
00478       /* Okay, ulaw is used by all telephony equipment, so start with it */
00479       AST_FORMAT_ULAW,
00480       /* Unless of course, you're a silly European, so then prefer ALAW */
00481       AST_FORMAT_ALAW,
00482       /* Okay, well, signed linear is easy to translate into other stuff */
00483       AST_FORMAT_SLINEAR,
00484       /* G.726 is standard ADPCM */
00485       AST_FORMAT_G726,
00486       /* ADPCM has great sound quality and is still pretty easy to translate */
00487       AST_FORMAT_ADPCM,
00488       /* Okay, we're down to vocoders now, so pick GSM because it's small and easier to
00489          translate and sounds pretty good */
00490       AST_FORMAT_GSM,
00491       /* iLBC is not too bad */
00492       AST_FORMAT_ILBC,
00493       /* Speex is free, but computationally more expensive than GSM */
00494       AST_FORMAT_SPEEX,
00495       /* Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough
00496          to use it */
00497       AST_FORMAT_LPC10,
00498       /* G.729a is faster than 723 and slightly less expensive */
00499       AST_FORMAT_G729A,
00500       /* Down to G.723.1 which is proprietary but at least designed for voice */
00501       AST_FORMAT_G723_1,
00502    };
00503    
00504    
00505    /* Find the first prefered codec in the format given */
00506    for (x=0; x < (sizeof(prefs) / sizeof(prefs[0]) ); x++)
00507       if (fmts & prefs[x])
00508          return prefs[x];
00509    ast_log(LOG_WARNING, "Don't know any of 0x%x formats\n", fmts);
00510    return 0;
00511 }

struct ast_channel* ast_bridged_channel ( struct ast_channel chan  )  [read]

int ast_call ( struct ast_channel chan,
char *  addr,
int  timeout 
)

Make a call.

Parameters:
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.
Returns:
Returns -1 on failure, 0 on not enough time (does not automatically stop ringing), and the number of seconds the connect took otherwise.

Definition at line 2628 of file channel.c.

References ast_check_hangup(), AST_FLAG_ZOMBIE, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_channel_tech::call, ast_channel::lock, and ast_channel::tech.

Referenced by __ast_request_and_dial(), agent_call(), ast_feature_request_and_dial(), attempt_reconnect(), dial_exec_full(), features_call(), function_ilink(), ring_entry(), rpt(), rpt_exec(), and wait_for_answer().

02629 {
02630    /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 
02631       If the remote end does not answer within the timeout, then do NOT hang up, but 
02632       return anyway.  */
02633    int res = -1;
02634    /* Stop if we're a zombie or need a soft hangup */
02635    ast_mutex_lock(&chan->lock);
02636    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) 
02637       if (chan->tech->call)
02638          res = chan->tech->call(chan, addr, timeout);
02639    ast_mutex_unlock(&chan->lock);
02640    return res;
02641 }

void ast_cancel_shutdown ( void   ) 

Cancels an existing shutdown and returns to normal operation

Definition at line 265 of file channel.c.

References shutting_down.

Referenced by handle_abort_halt().

00266 {
00267    shutting_down = 0;
00268 }

const char* ast_cause2str ( int  state  ) 

Gives the string form of a given cause code

Parameters:
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 410 of file channel.c.

References causes, and ast_cause::desc.

Referenced by __transmit_response(), ast_do_masquerade(), ast_hangup(), dial_exec_full(), and transmit_request_with_auth().

00411 {
00412    int x;
00413 
00414    for (x=0; x < sizeof(causes) / sizeof(causes[0]); x++) 
00415       if (causes[x].cause == cause)
00416          return causes[x].desc;
00417 
00418    return "Unknown";
00419 }

void ast_change_name ( struct ast_channel chan,
char *  newname 
)

Change channel name.

Definition at line 2886 of file channel.c.

References EVENT_FLAG_CALL, manager_event(), ast_channel::name, and ast_channel::uniqueid.

02887 {
02888    char tmp[256];
02889    ast_copy_string(tmp, chan->name, sizeof(tmp));
02890    ast_copy_string(chan->name, newname, sizeof(chan->name));
02891    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", tmp, chan->name, chan->uniqueid);
02892 }

struct ast_channel* ast_channel_alloc ( int  needalertpipe  )  [read]

Create a channel structure.

Returns:
Returns NULL on failure to allocate.
Note:
New channels are by default set to the "default" context and extension "s"

Definition at line 519 of file channel.c.

References ast_channel::_state, ast_channel::accountcode, ast_channel::alertpipe, ast_channel::amaflags, ast_channel::appl, ast_default_accountcode, ast_default_amaflags, AST_LIST_HEAD_INIT_NOLOCK, ast_log(), AST_MAX_FDS, ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_DOWN, channels, ast_channel::context, ast_channel::data, defaultlanguage, ast_channel::exten, ast_channel::fds, ast_channel::fin, ast_channel::flags, ast_channel::fout, free, global_fin, global_fout, ast_channel::language, ast_channel::lock, LOG_WARNING, malloc, ast_channel::name, ast_channel::next, null_tech, ast_channel::priority, ast_channel::sched, sched_context_create(), shutting_down, ast_channel::streamid, ast_channel::tech, ast_channel::timingfd, ast_channel::uniqueid, uniqueint, and ast_channel::varshead.

Referenced by __oh323_new(), agent_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_masq_park_call(), ast_modem_new(), ast_pbx_outgoing_cdr_failed(), ast_pbx_outgoing_exten(), builtin_atxfer(), check_goto_on_transfer(), features_new(), iax_park(), local_new(), mgcp_new(), misdn_new(), nbs_new(), oss_new(), phone_new(), sendmail(), sendpage(), sip_new(), sip_park(), skinny_new(), vpb_new(), and zt_new().

00520 {
00521    struct ast_channel *tmp;
00522    int x;
00523    int flags;
00524    struct varshead *headp;        
00525            
00526 
00527    /* If shutting down, don't allocate any new channels */
00528    if (shutting_down) {
00529       ast_log(LOG_WARNING, "Channel allocation failed: Refusing due to active shutdown\n");
00530       return NULL;
00531    }
00532 
00533    tmp = malloc(sizeof(struct ast_channel));
00534    if (!tmp) {
00535       ast_log(LOG_WARNING, "Channel allocation failed: Out of memory\n");
00536       return NULL;
00537    }
00538 
00539    memset(tmp, 0, sizeof(struct ast_channel));
00540    tmp->sched = sched_context_create();
00541    if (!tmp->sched) {
00542       ast_log(LOG_WARNING, "Channel allocation failed: Unable to create schedule context\n");
00543       free(tmp);
00544       return NULL;
00545    }
00546    
00547    for (x=0; x<AST_MAX_FDS - 1; x++)
00548       tmp->fds[x] = -1;
00549 
00550 #ifdef ZAPTEL_OPTIMIZATIONS
00551    tmp->timingfd = open("/dev/zap/timer", O_RDWR);
00552    if (tmp->timingfd > -1) {
00553       /* Check if timing interface supports new
00554          ping/pong scheme */
00555       flags = 1;
00556       if (!ioctl(tmp->timingfd, ZT_TIMERPONG, &flags))
00557          needqueue = 0;
00558    }
00559 #else
00560    tmp->timingfd = -1;              
00561 #endif               
00562 
00563    if (needqueue) {
00564       if (pipe(tmp->alertpipe)) {
00565          ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe!\n");
00566          free(tmp);
00567          return NULL;
00568       } else {
00569          flags = fcntl(tmp->alertpipe[0], F_GETFL);
00570          fcntl(tmp->alertpipe[0], F_SETFL, flags | O_NONBLOCK);
00571          flags = fcntl(tmp->alertpipe[1], F_GETFL);
00572          fcntl(tmp->alertpipe[1], F_SETFL, flags | O_NONBLOCK);
00573       }
00574    } else 
00575       /* Make sure we've got it done right if they don't */
00576       tmp->alertpipe[0] = tmp->alertpipe[1] = -1;
00577 
00578    /* Always watch the alertpipe */
00579    tmp->fds[AST_MAX_FDS-1] = tmp->alertpipe[0];
00580    /* And timing pipe */
00581    tmp->fds[AST_MAX_FDS-2] = tmp->timingfd;
00582    strcpy(tmp->name, "**Unknown**");
00583    /* Initial state */
00584    tmp->_state = AST_STATE_DOWN;
00585    tmp->streamid = -1;
00586    tmp->appl = NULL;
00587    tmp->data = NULL;
00588    tmp->fin = global_fin;
00589    tmp->fout = global_fout;
00590    ast_mutex_lock(&uniquelock);
00591    snprintf(tmp->uniqueid, sizeof(tmp->uniqueid), "%li.%d", (long) time(NULL), uniqueint++);
00592    ast_mutex_unlock(&uniquelock);
00593    headp = &tmp->varshead;
00594    ast_mutex_init(&tmp->lock);
00595    AST_LIST_HEAD_INIT_NOLOCK(headp);
00596    strcpy(tmp->context, "default");
00597    ast_copy_string(tmp->language, defaultlanguage, sizeof(tmp->language));
00598    strcpy(tmp->exten, "s");
00599    tmp->priority = 1;
00600    tmp->amaflags = ast_default_amaflags;
00601    ast_copy_string(tmp->accountcode, ast_default_accountcode, sizeof(tmp->accountcode));
00602 
00603    tmp->tech = &null_tech;
00604 
00605    ast_mutex_lock(&chlock);
00606    tmp->next = channels;
00607    channels = tmp;
00608 
00609    ast_mutex_unlock(&chlock);
00610    return tmp;
00611 }

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

Parameters:
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 3459 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_FEATURE_PLAY_WARNING, AST_FEATURE_REDIRECT, AST_FLAG_NBRIDGE, AST_FLAG_ZOMBIE, ast_generic_bridge(), ast_log(), ast_set_flag, AST_SOFTHANGUP_UNBRIDGE, ast_strlen_zero(), ast_test_flag, ast_tvadd(), ast_tvsub(), ast_verbose(), ast_channel_tech::bridge, bridge_playfile(), ast_channel::cid, ast_callerid::cid_num, ast_bridge_config::end_sound, EVENT_FLAG_CALL, ast_bridge_config::feature_timer, ast_bridge_config::features_callee, ast_bridge_config::features_caller, ast_bridge_config::firstpass, ast_bridge_config::flags, ast_channel::generator, LOG_DEBUG, LOG_WARNING, manager_event(), ast_channel::monitor, ast_channel::name, ast_channel::nativeformats, option_verbose, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), ast_bridge_config::play_warning, ast_channel::readformat, ast_channel::spies, ast_bridge_config::start_sound, ast_bridge_config::start_time, ast_channel::tech, ast_bridge_config::timelimit, ast_channel::uniqueid, VERBOSE_PREFIX_3, ast_bridge_config::warning_freq, ast_bridge_config::warning_sound, and ast_channel::writeformat.

Referenced by ast_bridge_call().

03461 {
03462    struct ast_channel *who = NULL;
03463    enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
03464    int nativefailed=0;
03465    int firstpass;
03466    int o0nativeformats;
03467    int o1nativeformats;
03468    long time_left_ms=0;
03469    struct timeval nexteventts = { 0, };
03470    char caller_warning = 0;
03471    char callee_warning = 0;
03472 
03473    if (c0->_bridge) {
03474       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 
03475          c0->name, c0->_bridge->name);
03476       return -1;
03477    }
03478    if (c1->_bridge) {
03479       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 
03480          c1->name, c1->_bridge->name);
03481       return -1;
03482    }
03483    
03484    /* Stop if we're a zombie or need a soft hangup */
03485    if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
03486        ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) 
03487       return -1;
03488 
03489    *fo = NULL;
03490    firstpass = config->firstpass;
03491    config->firstpass = 0;
03492 
03493    if (ast_tvzero(config->start_time))
03494       config->start_time = ast_tvnow();
03495    time_left_ms = config->timelimit;
03496 
03497    caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING);
03498    callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING);
03499 
03500    if (config->start_sound && firstpass) {
03501       if (caller_warning)
03502          bridge_playfile(c0, c1, config->start_sound, time_left_ms / 1000);
03503       if (callee_warning)
03504          bridge_playfile(c1, c0, config->start_sound, time_left_ms / 1000);
03505    }
03506 
03507    /* Keep track of bridge */
03508    c0->_bridge = c1;
03509    c1->_bridge = c0;
03510    
03511    manager_event(EVENT_FLAG_CALL, "Link", 
03512             "Channel1: %s\r\n"
03513             "Channel2: %s\r\n"
03514             "Uniqueid1: %s\r\n"
03515             "Uniqueid2: %s\r\n"
03516             "CallerID1: %s\r\n"
03517             "CallerID2: %s\r\n",
03518             c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
03519                                                                         
03520    o0nativeformats = c0->nativeformats;
03521    o1nativeformats = c1->nativeformats;
03522 
03523    if (config->feature_timer) {
03524       nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->feature_timer, 1000));
03525    } else if (config->timelimit) {
03526       nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
03527       if (caller_warning || callee_warning)
03528          nexteventts = ast_tvsub(nexteventts, ast_samp2tv(config->play_warning, 1000));
03529    }
03530 
03531    for (/* ever */;;) {
03532       struct timeval now = { 0, };
03533       int to;
03534 
03535       to = -1;
03536 
03537       if (!ast_tvzero(nexteventts)) {
03538          now = ast_tvnow();
03539          to = ast_tvdiff_ms(nexteventts, now);
03540          if (to <= 0 && !config->timelimit) {   
03541             res = AST_BRIDGE_COMPLETE;
03542             break;
03543          }  
03544             
03545       }
03546 
03547       if (config->timelimit) {
03548          time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time);
03549          if (time_left_ms < to)
03550             to = time_left_ms;
03551 
03552          if (time_left_ms <= 0) {
03553             if (caller_warning && config->end_sound)
03554                bridge_playfile(c0, c1, config->end_sound, 0);
03555             if (callee_warning && config->end_sound)
03556                bridge_playfile(c1, c0, config->end_sound, 0);
03557             *fo = NULL;
03558             if (who) 
03559                *rc = who;
03560             res = 0;
03561             break;
03562          }
03563          
03564          if (to <= 0) {
03565             if (time_left_ms >= 5000) {
03566                /* force the time left to round up if appropriate */
03567                if (caller_warning && config->warning_sound && config->play_warning)
03568                   bridge_playfile(c0, c1, config->warning_sound,
03569                         (time_left_ms + 500) / 1000);
03570                if (callee_warning && config->warning_sound && config->play_warning)
03571                   bridge_playfile(c1, c0, config->warning_sound,
03572                         (time_left_ms + 500) / 1000);
03573             }
03574             if (config->warning_freq) {
03575                nexteventts = ast_tvadd(nexteventts, ast_samp2tv(config->warning_freq, 1000));
03576             }
03577                
03578             if ( (!config->warning_freq) ||  ( config->timelimit - ast_tvdiff_ms(nexteventts, config->start_time) < 0)) {
03579                nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
03580             }
03581          }
03582       }
03583 
03584       if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
03585          if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03586             c0->_softhangup = 0;
03587          if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03588             c1->_softhangup = 0;
03589          c0->_bridge = c1;
03590          c1->_bridge = c0;
03591          ast_log(LOG_DEBUG, "Unbridge signal received. Ending native bridge.\n");
03592          continue;
03593       }
03594       
03595       /* Stop if we're a zombie or need a soft hangup */
03596       if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
03597           ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) {
03598          *fo = NULL;
03599          if (who)
03600             *rc = who;
03601          res = 0;
03602          ast_log(LOG_DEBUG, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n",
03603             c0->name, c1->name,
03604             ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No",
03605             ast_check_hangup(c0) ? "Yes" : "No",
03606             ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No",
03607             ast_check_hangup(c1) ? "Yes" : "No");
03608          break;
03609       }
03610 
03611       /* See if the BRIDGEPEER variable needs to be updated */
03612       if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER")))
03613          pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1->name);
03614       if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER")))
03615          pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0->name);
03616 
03617       if (c0->tech->bridge &&
03618           (config->timelimit == 0) &&
03619           (c0->tech->bridge == c1->tech->bridge) &&
03620           !nativefailed && !c0->monitor && !c1->monitor &&
03621           !c0->spies && !c1->spies && !ast_test_flag(&(config->features_callee),AST_FEATURE_REDIRECT) &&
03622           !ast_test_flag(&(config->features_caller),AST_FEATURE_REDIRECT) ) {
03623          /* Looks like they share a bridge method and nothing else is in the way */
03624          if (option_verbose > 2) 
03625             ast_verbose(VERBOSE_PREFIX_3 "Attempting native bridge of %s and %s\n", c0->name, c1->name);
03626          ast_set_flag(c0, AST_FLAG_NBRIDGE);
03627          ast_set_flag(c1, AST_FLAG_NBRIDGE);
03628          if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, to)) == AST_BRIDGE_COMPLETE) {
03629             manager_event(EVENT_FLAG_CALL, "Unlink", 
03630                      "Channel1: %s\r\n"
03631                      "Channel2: %s\r\n"
03632                      "Uniqueid1: %s\r\n"
03633                      "Uniqueid2: %s\r\n"
03634                      "CallerID1: %s\r\n"
03635                      "CallerID2: %s\r\n",
03636                      c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
03637             ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name);
03638 
03639             ast_clear_flag(c0, AST_FLAG_NBRIDGE);
03640             ast_clear_flag(c1, AST_FLAG_NBRIDGE);
03641 
03642             if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03643                continue;
03644 
03645             c0->_bridge = NULL;
03646             c1->_bridge = NULL;
03647 
03648             return res;
03649          } else {
03650             ast_clear_flag(c0, AST_FLAG_NBRIDGE);
03651             ast_clear_flag(c1, AST_FLAG_NBRIDGE);
03652          }
03653          switch (res) {
03654          case AST_BRIDGE_RETRY:
03655             continue;
03656          default:
03657             ast_log(LOG_WARNING, "Private bridge between %s and %s failed\n", c0->name, c1->name);
03658             /* fallthrough */
03659          case AST_BRIDGE_FAILED_NOWARN:
03660             nativefailed++;
03661             break;
03662          }
03663       }
03664    
03665       if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) ||
03666           (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) &&
03667           !(c0->generator || c1->generator)) {
03668          if (ast_channel_make_compatible(c0, c1)) {
03669             ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
03670                                 manager_event(EVENT_FLAG_CALL, "Unlink",
03671                      "Channel1: %s\r\n"
03672                      "Channel2: %s\r\n"
03673                      "Uniqueid1: %s\r\n"
03674                      "Uniqueid2: %s\r\n"
03675                      "CallerID1: %s\r\n"
03676                      "CallerID2: %s\r\n",
03677                      c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
03678             return AST_BRIDGE_FAILED;
03679          }
03680          o0nativeformats = c0->nativeformats;
03681          o1nativeformats = c1->nativeformats;
03682       }
03683       res = ast_generic_bridge(c0, c1, config, fo, rc, nexteventts);
03684       if (res != AST_BRIDGE_RETRY && fo)
03685          break;
03686    }
03687 
03688    c0->_bridge = NULL;
03689    c1->_bridge = NULL;
03690 
03691    manager_event(EVENT_FLAG_CALL, "Unlink",
03692             "Channel1: %s\r\n"
03693             "Channel2: %s\r\n"
03694             "Uniqueid1: %s\r\n"
03695             "Uniqueid2: %s\r\n"
03696             "CallerID1: %s\r\n"
03697             "CallerID2: %s\r\n",
03698             c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
03699    ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name);
03700 
03701    return res;
03702 }

int ast_channel_cmpwhentohangup ( struct ast_channel chan,
time_t  offset 
)

Compare a offset with the settings of when to hang a channel up.

Parameters:
chan channel on which to check for hang up
offset offset in seconds from current time
Returns:
1, 0, or -1 This function compares a offset from current time with the absolute time out on a channel (when to hang up). If the absolute time out on a channel is earlier than current time plus the offset, it returns 1, if the two time values are equal, it return 0, otherwise, it retturn -1.

Definition at line 292 of file channel.c.

References ast_channel::whentohangup.

Referenced by ast_osp_lookup().

00293 {
00294    time_t whentohangup;
00295 
00296    if (chan->whentohangup == 0) {
00297       if (offset == 0)
00298          return (0);
00299       else
00300          return (-1);
00301    } else { 
00302       if (offset == 0)
00303          return (1);
00304       else {
00305          whentohangup = offset + time (NULL);
00306          if (chan->whentohangup < whentohangup)
00307             return (1);
00308          else if (chan->whentohangup == whentohangup)
00309             return (0);
00310          else
00311             return (-1);
00312       }
00313    }
00314 }

int ast_channel_defer_dtmf ( struct ast_channel chan  ) 

Defers DTMF

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 693 of file channel.c.

References AST_FLAG_DEFER_DTMF, ast_set_flag, and ast_test_flag.

Referenced by __adsi_transmit_messages(), and find_cache().

00694 {
00695    int pre = 0;
00696 
00697    if (chan) {
00698       pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF);
00699       ast_set_flag(chan, AST_FLAG_DEFER_DTMF);
00700    }
00701    return pre;
00702 }

void ast_channel_free ( struct ast_channel  ) 

Free a channel structure.

Definition at line 886 of file channel.c.

References ast_channel::alertpipe, ast_app_group_discard(), AST_CHANNEL_NAME, ast_device_state_changed_literal(), ast_frfree(), AST_LIST_REMOVE_HEAD, ast_log(), ast_moh_cleanup(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_translator_free_path(), ast_var_delete(), channels, ast_channel::cid, free, free_cid(), last, ast_channel::lock, LOG_ERROR, LOG_WARNING, ast_channel::monitor, ast_channel::music_state, ast_channel::name, name, ast_frame::next, ast_channel::next, 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 agent_cleanup(), agent_new(), ast_do_masquerade(), ast_hangup(), ast_pbx_outgoing_cdr_failed(), local_new(), sendmail(), and sendpage().

00887 {
00888    struct ast_channel *last=NULL, *cur;
00889    int fd;
00890    struct ast_var_t *vardata;
00891    struct ast_frame *f, *fp;
00892    struct varshead *headp;
00893    char name[AST_CHANNEL_NAME];
00894    
00895    headp=&chan->varshead;
00896    
00897    ast_mutex_lock(&chlock);
00898    cur = channels;
00899    while(cur) {
00900       if (cur == chan) {
00901          if (last)
00902             last->next = cur->next;
00903          else
00904             channels = cur->next;
00905          break;
00906       }
00907       last = cur;
00908       cur = cur->next;
00909    }
00910    if (!cur) {
00911       ast_mutex_unlock(&chlock);
00912       ast_log(LOG_ERROR, "Unable to find channel in list to free. Assuming it has already been done.\n");
00913       return;
00914    }
00915 
00916    /* Lock and unlock the channel just to be sure nobody
00917       has it locked still */
00918    ast_mutex_lock(&cur->lock);
00919    ast_mutex_unlock(&cur->lock);
00920    if (chan->tech_pvt) {
00921       ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
00922       free(chan->tech_pvt);
00923    }
00924 
00925    if (chan->sched)
00926       sched_context_destroy(chan->sched);
00927 
00928    ast_copy_string(name, chan->name, sizeof(name));
00929 
00930    /* Stop monitoring */
00931    if (chan->monitor) {
00932       chan->monitor->stop( chan, 0 );
00933    }
00934 
00935    /* If there is native format music-on-hold state, free it */
00936    if(chan->music_state)
00937       ast_moh_cleanup(chan);
00938 
00939    /* Free translatosr */
00940    if (chan->readtrans)
00941       ast_translator_free_path(chan->readtrans);
00942    if (chan->writetrans)
00943       ast_translator_free_path(chan->writetrans);
00944    if (chan->pbx) 
00945       ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
00946    free_cid(&chan->cid);
00947    ast_mutex_destroy(&chan->lock);
00948    /* Close pipes if appropriate */
00949    if ((fd = chan->alertpipe[0]) > -1)
00950       close(fd);
00951    if ((fd = chan->alertpipe[1]) > -1)
00952       close(fd);
00953    if ((fd = chan->timingfd) > -1)
00954       close(fd);
00955    f = chan->readq;
00956    chan->readq = NULL;
00957    while(f) {
00958       fp = f;
00959       f = f->next;
00960       ast_frfree(fp);
00961    }
00962    
00963    /* loop over the variables list, freeing all data and deleting list items */
00964    /* no need to lock the list, as the channel is already locked */
00965    
00966    while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
00967       ast_var_delete(vardata);
00968 
00969    /* Drop out of the group counting radar */
00970    ast_app_group_discard(chan);
00971 
00972    free(chan);
00973    ast_mutex_unlock(&chlock);
00974 
00975    ast_device_state_changed_literal(name);
00976 }

void ast_channel_inherit_variables ( const struct ast_channel parent,
struct ast_channel child 
)

Inherits channel variable from parent to child channel.

Parameters:
parent Parent channel
child Child channel
Scans all channel variables in the parent channel, looking for those that should be copied into the child channel. Variables whose names begin with a single '_' are copied into the child channel with the prefix removed. Variables whose names begin with '__' are copied into the child channel with their names unchanged.

Definition at line 2894 of file channel.c.

References AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_var_assign(), ast_var_full_name(), ast_var_name(), ast_var_value(), LOG_DEBUG, option_debug, and ast_channel::varshead.

Referenced by __ast_request_and_dial(), agent_call(), ast_feature_request_and_dial(), dial_exec_full(), ring_entry(), and wait_for_answer().

02895 {
02896    struct ast_var_t *current, *newvar;
02897    char *varname;
02898 
02899    AST_LIST_TRAVERSE(&parent->varshead, current, entries) {
02900       int vartype = 0;
02901 
02902       varname = ast_var_full_name(current);
02903       if (!varname)
02904          continue;
02905 
02906       if (varname[0] == '_') {
02907          vartype = 1;
02908          if (varname[1] == '_')
02909             vartype = 2;
02910       }
02911 
02912       switch (vartype) {
02913       case 1:
02914          newvar = ast_var_assign(&varname[1], ast_var_value(current));
02915          if (newvar) {
02916             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
02917             if (option_debug)
02918                ast_log(LOG_DEBUG, "Copying soft-transferable variable %s.\n", ast_var_name(newvar));
02919          }
02920          break;
02921       case 2:
02922          newvar = ast_var_assign(ast_var_full_name(current), ast_var_value(current));
02923          if (newvar) {
02924             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
02925             if (option_debug)
02926                ast_log(LOG_DEBUG, "Copying hard-transferable variable %s.\n", ast_var_name(newvar));
02927          }
02928          break;
02929       default:
02930          if (option_debug)
02931             ast_log(LOG_DEBUG, "Not copying variable %s.\n", ast_var_name(current));
02932          break;
02933       }
02934    }
02935 }

int ast_channel_make_compatible ( struct ast_channel c0,
struct ast_channel c1 
)

Makes two channel formats compatible

Parameters:
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 . Returns 0 on success and -1 if it could not be done

Definition at line 2767 of file channel.c.

References AST_FORMAT_SLINEAR, ast_log(), ast_set_read_format(), ast_set_write_format(), ast_translator_best_choice(), LOG_WARNING, ast_channel::name, ast_channel::nativeformats, option_transcode_slin, ast_channel::readformat, and ast_channel::writeformat.

Referenced by ast_channel_bridge(), builtin_atxfer(), dial_exec_full(), park_exec(), try_calling(), and wait_for_answer().

02768 {
02769    int src;
02770    int dst;
02771 
02772    if (chan->readformat == peer->writeformat && chan->writeformat == peer->readformat) {
02773       /* Already compatible!  Moving on ... */
02774       return 0;
02775    }
02776 
02777    /* Set up translation from the chan to the peer */
02778    src = chan->nativeformats;
02779    dst = peer->nativeformats;
02780    if (ast_translator_best_choice(&dst, &src) < 0) {
02781       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, src, peer->name, dst);
02782       return -1;
02783    }
02784 
02785    /* if the best path is not 'pass through', then
02786       transcoding is needed; if desired, force transcode path
02787       to use SLINEAR between channels */
02788    if ((src != dst) && option_transcode_slin)
02789       dst = AST_FORMAT_SLINEAR;
02790    if (ast_set_read_format(chan, dst) < 0) {
02791       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, dst);
02792       return -1;
02793    }
02794    if (ast_set_write_format(peer, dst) < 0) {
02795       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, dst);
02796       return -1;
02797    }
02798 
02799    /* Set up translation from the peer to the chan */
02800    src = peer->nativeformats;
02801    dst = chan->nativeformats;
02802    if (ast_translator_best_choice(&dst, &src) < 0) {
02803       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, src, chan->name, dst);
02804       return -1;
02805    }
02806    /* if the best path is not 'pass through', then
02807       transcoding is needed; if desired, force transcode path
02808       to use SLINEAR between channels */
02809    if ((src != dst) && option_transcode_slin)
02810       dst = AST_FORMAT_SLINEAR;
02811    if (ast_set_read_format(peer, dst) < 0) {
02812       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, dst);
02813       return -1;
02814    }
02815    if (ast_set_write_format(chan, dst) < 0) {
02816       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, dst);
02817       return -1;
02818    }
02819    return 0;
02820 }

int ast_channel_masquerade ( struct ast_channel original,
struct ast_channel clone 
)

Weird function made for call transfers

Parameters:
original channel to make a copy of
clone copy of the original channel This is a very strange and freaky function used primarily for transfer. Suppose that "original" and "clone" are two channels in random situations. This function takes the guts out of "clone" and puts them into the "original" channel, then alerts the channel driver of the change, asking it to fixup any private information (like the p->owner pointer) that is affected by the change. The physical layer of the original channel is hung up.

Definition at line 2822 of file channel.c.

References ast_channel::_bridge, ast_bridged_channel(), AST_FRAME_NULL, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::masq, ast_channel::masqr, and ast_channel::name.

Referenced by ast_async_goto(), ast_masq_park_call(), ast_pickup_call(), attempt_transfer(), builtin_atxfer(), check_availability(), check_bridge(), check_goto_on_transfer(), iax_park(), misdn_transfer_bc(), pickup_exec(), and sip_park().

02823 {
02824    struct ast_frame null = { AST_FRAME_NULL, };
02825    int res = -1;
02826    struct ast_channel *final_orig = original, *final_clone = clone;
02827 
02828    ast_mutex_lock(&original->lock);
02829    while(ast_mutex_trylock(&clone->lock)) {
02830       ast_mutex_unlock(&original->lock);
02831       usleep(1);
02832       ast_mutex_lock(&original->lock);
02833    }
02834 
02835    /* each of these channels may be sitting behind a channel proxy (i.e. chan_agent)
02836       and if so, we don't really want to masquerade it, but its proxy */
02837    if (original->_bridge && (original->_bridge != ast_bridged_channel(original)) && (original->_bridge->_bridge != original))
02838       final_orig = original->_bridge;
02839 
02840    if (clone->_bridge && (clone->_bridge != ast_bridged_channel(clone)) && (clone->_bridge->_bridge != clone))
02841       final_clone = clone->_bridge;
02842 
02843    if ((final_orig != original) || (final_clone != clone)) {
02844       ast_mutex_lock(&final_orig->lock);
02845       while(ast_mutex_trylock(&final_clone->lock)) {
02846          ast_mutex_unlock(&final_orig->lock);
02847          usleep(1);
02848          ast_mutex_lock(&final_orig->lock);
02849       }
02850       ast_mutex_unlock(&clone->lock);
02851       ast_mutex_unlock(&original->lock);
02852       original = final_orig;
02853       clone = final_clone;
02854    }
02855 
02856    if (original == clone) {
02857       ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name);
02858       ast_mutex_unlock(&clone->lock);
02859       ast_mutex_unlock(&original->lock);
02860       return -1;
02861    }
02862 
02863    ast_log(LOG_DEBUG, "Planning to masquerade channel %s into the structure of %s\n",
02864       clone->name, original->name);
02865    if (original->masq) {
02866       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 
02867          original->masq->name, original->name);
02868    } else if (clone->masqr) {
02869       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 
02870          clone->name, clone->masqr->name);
02871    } else {
02872       original->masq = clone;
02873       clone->masqr = original;
02874       ast_queue_frame(original, &null);
02875       ast_queue_frame(clone, &null);
02876       ast_log(LOG_DEBUG, "Done planning to masquerade channel %s into the structure of %s\n", clone->name, original->name);
02877       res = 0;
02878    }
02879 
02880    ast_mutex_unlock(&clone->lock);
02881    ast_mutex_unlock(&original->lock);
02882 
02883    return res;
02884 }

struct ast_frame* ast_channel_queryoption ( struct ast_channel channel,
int  option,
void *  data,
int *  datalen,
int  block 
) [read]

Checks the value of an option

Query the value of an option, optionally blocking until a reply is received Works similarly to setoption except only reads the options.

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.

Parameters:
tech Structure defining channel technology or "type"
Returns:
Returns 0 on success, -1 on failure.

Definition at line 317 of file channel.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), backends, ast_channel_tech::description, LOG_DEBUG, LOG_WARNING, malloc, chanlist::next, option_debug, option_verbose, chanlist::tech, ast_channel_tech::type, and VERBOSE_PREFIX_2.

Referenced by load_module(), and unload_module().

00318 {
00319    struct chanlist *chan;
00320 
00321    ast_mutex_lock(&chlock);
00322 
00323    chan = backends;
00324    while (chan) {
00325       if (!strcasecmp(tech->type, chan->tech->type)) {
00326          ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type);
00327          ast_mutex_unlock(&chlock);
00328          return -1;
00329       }
00330       chan = chan->next;
00331    }
00332 
00333    chan = malloc(sizeof(*chan));
00334    if (!chan) {
00335       ast_log(LOG_WARNING, "Out of memory\n");
00336       ast_mutex_unlock(&chlock);
00337       return -1;
00338    }
00339    chan->tech = tech;
00340    chan->next = backends;
00341    backends = chan;
00342 
00343    if (option_debug)
00344       ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description);
00345 
00346    if (option_verbose > 1)
00347       ast_verbose(VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->tech->type,
00348              chan->tech->description);
00349 
00350    ast_mutex_unlock(&chlock);
00351    return 0;
00352 }

int ast_channel_sendhtml ( struct ast_channel channel,
int  subclass,
const char *  data,
int  datalen 
)

Sends HTML on given channel

Send HTML or URL on link. Returns 0 on success or -1 on failure

Definition at line 2753 of file channel.c.

References ast_channel_tech::send_html, and ast_channel::tech.

Referenced by agent_sendhtml(), and wait_for_answer().

02754 {
02755    if (chan->tech->send_html)
02756       return chan->tech->send_html(chan, subclass, data, datalen);
02757    return -1;
02758 }

int ast_channel_sendurl ( struct ast_channel channel,
const char *  url 
)

Sends a URL on a given link

Send URL on link. Returns 0 on success or -1 on failure

Definition at line 2760 of file channel.c.

References AST_HTML_URL, ast_channel_tech::send_html, and ast_channel::tech.

Referenced by dial_exec_full(), sendurl_exec(), and try_calling().

02761 {
02762    if (chan->tech->send_html)
02763       return chan->tech->send_html(chan, AST_HTML_URL, url, strlen(url) + 1);
02764    return -1;
02765 }

int ast_channel_setoption ( struct ast_channel channel,
int  option,
void *  data,
int  datalen,
int  block 
)

Sets an option on a channel

Parameters:
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 3705 of file channel.c.

References ast_log(), LOG_ERROR, ast_channel_tech::setoption, and ast_channel::tech.

Referenced by ast_bridge_call(), chanspy_exec(), conf_run(), handle_tddmode(), play_record_review(), reset_volumes(), rpt(), set_listen_volume(), set_talk_volume(), set_volume(), try_calling(), vm_forwardoptions(), and zt_hangup().

03706 {
03707    int res;
03708 
03709    if (chan->tech->setoption) {
03710       res = chan->tech->setoption(chan, option, data, datalen);
03711       if (res < 0)
03712          return res;
03713    } else {
03714       errno = ENOSYS;
03715       return -1;
03716    }
03717    if (block) {
03718       /* XXX Implement blocking -- just wait for our option frame reply, discarding
03719          intermediate packets. XXX */
03720       ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
03721       return -1;
03722    }
03723    return 0;
03724 }

void ast_channel_setwhentohangup ( struct ast_channel chan,
time_t  offset 
)

Set when to hang a channel up.

Parameters:
chan channel on which to check for hang up
offset offset in seconds from current time of when to hang up This function sets the absolute time out on a channel (when to hang up).

Definition at line 277 of file channel.c.

References AST_FRAME_NULL, ast_queue_frame(), and ast_channel::whentohangup.

Referenced by action_timeout(), ast_osp_lookup(), builtin_function_timeout_write(), handle_request_invite(), and pbx_builtin_atimeout().

00278 {
00279    time_t   myt;
00280    struct ast_frame fr = { AST_FRAME_NULL, };
00281 
00282    time(&myt);
00283    if (offset)
00284       chan->whentohangup = myt + offset;
00285    else
00286       chan->whentohangup = 0;
00287    ast_queue_frame(chan, &fr);
00288    return;
00289 }

struct ast_silence_generator* ast_channel_start_silence_generator ( struct ast_channel chan  )  [read]

Starts a silence generator on the given channel.

Parameters:
chan The channel to generate silence on
Returns:
An ast_silence_generator pointer, or NULL if an error occurs
This function will cause SLINEAR silence to be generated on the supplied channel until it is disabled; if the channel cannot be put into SLINEAR mode then the function will fail.

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 4172 of file channel.c.

References ast_activate_generator(), AST_FORMAT_SLINEAR, ast_log(), ast_set_write_format(), calloc, free, LOG_DEBUG, LOG_ERROR, LOG_WARNING, ast_channel::name, ast_silence_generator::old_write_format, option_debug, and ast_channel::writeformat.

Referenced by ast_play_and_record_full(), and record_exec().

04173 {
04174    struct ast_silence_generator *state;
04175 
04176    if (!(state = calloc(1, sizeof(*state)))) {
04177       ast_log(LOG_WARNING, "Could not allocate state structure\n");
04178       return NULL;
04179    }
04180 
04181    state->old_write_format = chan->writeformat;
04182 
04183    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
04184       ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
04185       free(state);
04186       return NULL;
04187    }
04188 
04189    ast_activate_generator(chan, &silence_generator, state);
04190 
04191    if (option_debug)
04192       ast_log(LOG_DEBUG, "Started silence generator on '%s'\n", chan->name);
04193 
04194    return state;
04195 }

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.

Parameters:
chan The channel to operate on
state The ast_silence_generator pointer return by a previous call to ast_channel_start_silence_generator.
Returns:
nothing
This function will stop the operating silence generator and return the channel to its previous write format.

Definition at line 4197 of file channel.c.

References ast_deactivate_generator(), ast_log(), ast_set_write_format(), free, LOG_DEBUG, LOG_ERROR, ast_channel::name, ast_silence_generator::old_write_format, and option_debug.

Referenced by ast_play_and_record_full(), and record_exec().

04198 {
04199    if (!state)
04200       return;
04201 
04202    ast_deactivate_generator(chan);
04203 
04204    if (option_debug)
04205       ast_log(LOG_DEBUG, "Stopped silence generator on '%s'\n", chan->name);
04206 
04207    if (ast_set_write_format(chan, state->old_write_format) < 0)
04208       ast_log(LOG_ERROR, "Could not return write format to its original state\n");
04209 
04210    free(state);
04211 }

int ast_channel_supports_html ( struct ast_channel channel  ) 

Checks for HTML support on a channel

Returns 0 if channel does not support HTML or non-zero if it does

Definition at line 2746 of file channel.c.

References ast_channel_tech::send_html, and ast_channel::tech.

Referenced by dial_exec_full(), sendurl_exec(), and try_calling().

02747 {
02748    if (chan->tech->send_html)
02749       return 1;
02750    return 0;
02751 }

void ast_channel_undefer_dtmf ( struct ast_channel chan  ) 

Undeos a defer

Undo defer. ast_read will return any dtmf characters that were queued

Definition at line 705 of file channel.c.

References ast_clear_flag, and AST_FLAG_DEFER_DTMF.

Referenced by __adsi_transmit_messages(), find_cache(), and rpt_call().

00706 {
00707    if (chan)
00708       ast_clear_flag(chan, AST_FLAG_DEFER_DTMF);
00709 }

void ast_channel_unregister ( const struct ast_channel_tech tech  ) 

Unregister a channel technology.

Parameters:
tech Structure defining channel technology or "type" that was previously registered
Returns:
No return value.

Definition at line 354 of file channel.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), backends, free, last, LOG_DEBUG, chanlist::next, option_debug, option_verbose, chanlist::tech, ast_channel_tech::type, and VERBOSE_PREFIX_2.

Referenced by __unload_module(), and unload_module().

00355 {
00356    struct chanlist *chan, *last=NULL;
00357 
00358    if (option_debug && tech && tech->type )
00359       ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", tech->type);
00360    else if (option_debug)
00361       ast_log(LOG_DEBUG, "Unregistering channel, tech is NULL!!!\n");
00362       
00363 
00364    ast_mutex_lock(&chlock);
00365 
00366    chan = backends;
00367    while (chan) {
00368       if (chan->tech == tech) {
00369          if (last)
00370             last->next = chan->next;
00371          else
00372             backends = backends->next;
00373          free(chan);
00374          ast_mutex_unlock(&chlock);
00375 
00376          if (option_verbose > 1)
00377             ast_verbose( VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", tech->type);
00378 
00379          return;
00380       }
00381       last = chan;
00382       chan = chan->next;
00383    }
00384 
00385    ast_mutex_unlock(&chlock);
00386 }

struct ast_channel* ast_channel_walk_locked ( const struct ast_channel prev  )  [read]

Browse channels in use

Parameters:
prev where you want to start in the channel list Browse the channels currently in use Returns the next channel in the list, NULL on end. If it returns a channel, that channel *has been locked*!

Definition at line 802 of file channel.c.

References channel_find_locked().

Referenced by action_status(), ast_pickup_call(), complete_ch_helper(), conf_exec(), handle_chanlist(), handle_debugchan(), handle_nodebugchan(), local_channel_walk(), moh_on_off(), and softhangup_exec().

00803 {
00804    return channel_find_locked(prev, NULL, 0, NULL, NULL);
00805 }

int ast_check_hangup ( struct ast_channel chan  ) 

Check to see if a channel is needing hang up.

Parameters:
chan channel on which to check for hang up This function determines if the channel is being requested to be hung up.
Returns:
Returns 0 if not, or 1 if hang up is requested (including time-out).

Definition at line 203 of file channel.c.

References ast_channel::_softhangup, AST_SOFTHANGUP_TIMEOUT, ast_channel::tech_pvt, and ast_channel::whentohangup.

Referenced by action_redirect(), app_exec(), ast_answer(), ast_call(), ast_cdr_update(), ast_channel_bridge(), ast_check_hangup_locked(), ast_feature_request_and_dial(), ast_indicate(), ast_read(), ast_readstring(), ast_readstring_full(), ast_recvtext(), ast_rtp_bridge(), ast_sendtext(), ast_transfer(), ast_waitfordigit(), ast_waitfordigit_full(), ast_write(), builtin_atxfer(), channel_spy(), chanspy_exec(), conf_run(), handle_sendimage(), iax2_bridge(), pbx_exec(), rpt(), rpt_exec(), vpb_bridge(), wait_for_answer(), zt_sendtext(), and zt_setoption().

00204 {
00205    time_t   myt;
00206 
00207    /* if soft hangup flag, return true */
00208    if (chan->_softhangup) 
00209       return 1;
00210    /* if no technology private data, return true */
00211    if (!chan->tech_pvt) 
00212       return 1;
00213    /* if no hangup scheduled, just return here */
00214    if (!chan->whentohangup) 
00215       return 0;
00216    time(&myt); /* get current time */
00217    /* return, if not yet */
00218    if (chan->whentohangup > myt) 
00219       return 0;
00220    chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
00221    return 1;
00222 }

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 wacked 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.

Parameters:
chan Channel to masquerade

Definition at line 2964 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_copy_flags, AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, AST_FLAG_ZOMBIE, AST_FRAME_NULL, AST_LIST_TRAVERSE, ast_log(), AST_MAX_FDS, ast_mutex_lock(), ast_mutex_unlock(), ast_queue_frame(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_SOFTHANGUP_DEV, ast_test_flag, ast_channel::blocker, ast_channel_spy::chan, ast_channel::cid, clone_variables(), EVENT_FLAG_CALL, ast_channel::fdno, ast_channel::fds, ast_channel_tech::fixup, free_translation(), ast_channel_tech::hangup, ast_channel::hangupcause, ast_channel::language, ast_channel_spy::lock, ast_channel::lock, LOG_DEBUG, LOG_WARNING, manager_event(), ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::musicclass, ast_channel::name, ast_channel::nativeformats, ast_frame::next, option_debug, ast_frame::prev, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::readq, ast_channel::spies, t, ast_channel::tech, ast_channel::tech_pvt, ast_channel::timingfd, ast_channel::type, ast_channel::uniqueid, and ast_channel::writeformat.

Referenced by ast_async_goto(), ast_hangup(), ast_read(), ast_waitfor_nandfds(), ast_write(), iax_park(), sip_park(), and sip_park_thread().

02965 {
02966    int x,i;
02967    int res=0;
02968    int origstate;
02969    struct ast_frame *cur, *prev;
02970    const struct ast_channel_tech *t;
02971    void *t_pvt;
02972    struct ast_callerid tmpcid;
02973    struct ast_channel *clone = original->masq;
02974    struct ast_channel_spy_list *spy_list;
02975    struct ast_channel_spy *spy = NULL;
02976    int rformat = original->readformat;
02977    int wformat = original->writeformat;
02978    char newn[100];
02979    char orig[100];
02980    char masqn[100];
02981    char zombn[100];
02982 
02983    if (option_debug > 3)
02984       ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",
02985          clone->name, clone->_state, original->name, original->_state);
02986 
02987    /* XXX This is a seriously wacked out operation.  We're essentially putting the guts of
02988       the clone channel into the original channel.  Start by killing off the original
02989       channel's backend.   I'm not sure we're going to keep this function, because 
02990       while the features are nice, the cost is very high in terms of pure nastiness. XXX */
02991 
02992    /* We need the clone's lock, too */
02993    ast_mutex_lock(&clone->lock);
02994 
02995    ast_log(LOG_DEBUG, "Got clone lock for masquerade on '%s' at %p\n", clone->name, &clone->lock);
02996 
02997    /* Having remembered the original read/write formats, we turn off any translation on either
02998       one */
02999    free_translation(clone);
03000    free_translation(original);
03001 
03002 
03003    /* Unlink the masquerade */
03004    original->masq = NULL;
03005    clone->masqr = NULL;
03006    
03007    /* Save the original name */
03008    ast_copy_string(orig, original->name, sizeof(orig));
03009    /* Save the new name */
03010    ast_copy_string(newn, clone->name, sizeof(newn));
03011    /* Create the masq name */
03012    snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn);
03013       
03014    /* Copy the name from the clone channel */
03015    ast_copy_string(original->name, newn, sizeof(original->name));
03016 
03017    /* Mangle the name of the clone channel */
03018    ast_copy_string(clone->name, masqn, sizeof(clone->name));
03019    
03020    /* Notify any managers of the change, first the masq then the other */
03021    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", newn, masqn, clone->uniqueid);
03022    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", orig, newn, original->uniqueid);
03023 
03024    /* Swap the technlogies */ 
03025    t = original->tech;
03026    original->tech = clone->tech;
03027    clone->tech = t;
03028 
03029    t_pvt = original->tech_pvt;
03030    original->tech_pvt = clone->tech_pvt;
03031    clone->tech_pvt = t_pvt;
03032 
03033    /* Swap the readq's */
03034    cur = original->readq;
03035    original->readq = clone->readq;
03036    clone->readq = cur;
03037 
03038    /* Swap the alertpipes */
03039    for (i = 0; i < 2; i++) {
03040       x = original->alertpipe[i];
03041       original->alertpipe[i] = clone->alertpipe[i];
03042       clone->alertpipe[i] = x;
03043    }
03044 
03045    /* Swap the raw formats */
03046    x = original->rawreadformat;
03047    original->rawreadformat = clone->rawreadformat;
03048    clone->rawreadformat = x;
03049    x = original->rawwriteformat;
03050    original->rawwriteformat = clone->rawwriteformat;
03051    clone->rawwriteformat = x;
03052 
03053    /* Swap the spies */
03054    spy_list = original->spies;
03055    original->spies = clone->spies;
03056    clone->spies = spy_list;
03057 
03058    /* Update channel on respective spy lists if present */
03059    if (original->spies) {
03060       AST_LIST_TRAVERSE(&original->spies->list, spy, list) {
03061          ast_mutex_lock(&spy->lock);
03062          spy->chan = original;
03063          ast_mutex_unlock(&spy->lock);
03064       }
03065    }
03066    if (clone->spies) {
03067       AST_LIST_TRAVERSE(&clone->spies->list, spy, list) {
03068          ast_mutex_lock(&spy->lock);
03069          spy->chan = clone;
03070          ast_mutex_unlock(&spy->lock);
03071       }
03072    }
03073 
03074    /* Save any pending frames on both sides.  Start by counting
03075     * how many we're going to need... */
03076    prev = NULL;
03077    cur = clone->readq;
03078    x = 0;
03079    while(cur) {
03080       x++;
03081       prev = cur;
03082       cur = cur->next;
03083    }
03084    /* If we had any, prepend them to the ones already in the queue, and 
03085     * load up the alertpipe */
03086    if (prev) {
03087       prev->next = original->readq;
03088       original->readq = clone->readq;
03089       clone->readq = NULL;
03090       if (original->alertpipe[1] > -1) {
03091          for (i = 0; i < x; i++)
03092             write(original->alertpipe[1], &x, sizeof(x));
03093       }
03094    }
03095    clone->_softhangup = AST_SOFTHANGUP_DEV;
03096 
03097 
03098    /* And of course, so does our current state.  Note we need not
03099       call ast_setstate since the event manager doesn't really consider
03100       these separate.  We do this early so that the clone has the proper
03101       state of the original channel. */
03102    origstate = original->_state;
03103    original->_state = clone->_state;
03104    clone->_state = origstate;
03105 
03106    if (clone->tech->fixup){
03107       res = clone->tech->fixup(original, clone);
03108       if (res) 
03109          ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name);
03110    }
03111 
03112    /* Start by disconnecting the original's physical side */
03113    if (clone->tech->hangup)
03114       res = clone->tech->hangup(clone);
03115    if (res) {
03116       ast_log(LOG_WARNING, "Hangup failed!  Strange things may happen!\n");
03117       ast_mutex_unlock(&clone->lock);
03118       return -1;
03119    }
03120    
03121    snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig);
03122    /* Mangle the name of the clone channel */
03123    ast_copy_string(clone->name, zombn, sizeof(clone->name));
03124    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", masqn, zombn, clone->uniqueid);
03125 
03126    /* Update the type. */
03127    original->type = clone->type;
03128    t_pvt = original->monitor;
03129    original->monitor = clone->monitor;
03130    clone->monitor = t_pvt;
03131    
03132    /* Keep the same language.  */
03133    ast_copy_string(original->language, clone->language, sizeof(original->language));
03134    /* Copy the FD's */
03135    for (x = 0; x < AST_MAX_FDS; x++) {
03136       original->fds[x] = clone->fds[x];
03137    }
03138    /* Drop group from original */
03139    ast_app_group_update(clone, original);
03140    clone_variables(original, clone);
03141    /* Presense of ADSI capable CPE follows clone */
03142    original->adsicpe = clone->adsicpe;
03143    /* Bridge remains the same */
03144    /* CDR fields remain the same */
03145    /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */
03146    /* Application and data remain the same */
03147    /* Clone exception  becomes real one, as with fdno */
03148    ast_copy_flags(original, clone, AST_FLAG_EXCEPTION);
03149    original->fdno = clone->fdno;
03150    /* Schedule context remains the same */
03151    /* Stream stuff stays the same */
03152    /* Keep the original state.  The fixup code will need to work with it most likely */
03153 
03154    /* Just swap the whole structures, nevermind the allocations, they'll work themselves
03155       out. */
03156    tmpcid = original->cid;
03157    original->cid = clone->cid;
03158    clone->cid = tmpcid;
03159    
03160    /* Restore original timing file descriptor */
03161    original->fds[AST_MAX_FDS - 2] = original->timingfd;
03162    
03163    /* Our native formats are different now */
03164    original->nativeformats = clone->nativeformats;
03165    
03166    /* Context, extension, priority, app data, jump table,  remain the same */
03167    /* pvt switches.  pbx stays the same, as does next */
03168    
03169    /* Set the write format */
03170    ast_set_write_format(original, wformat);
03171 
03172    /* Set the read format */
03173    ast_set_read_format(original, rformat);
03174 
03175    /* Copy the music class */
03176    ast_copy_string(original->musicclass, clone->musicclass, sizeof(original->musicclass));
03177 
03178    ast_log(LOG_DEBUG, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat);
03179 
03180    /* Okay.  Last thing is to let the channel driver know about all this mess, so he
03181       can fix up everything as best as possible */
03182    if (original->tech->fixup) {
03183       res = original->tech->fixup(clone, original);
03184       if (res) {
03185          ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n",
03186             original->type, original->name);
03187          ast_mutex_unlock(&clone->lock);
03188          return -1;
03189       }
03190    } else
03191       ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)!  Bad things may happen.\n",
03192          original->type, original->name);
03193    
03194    /* Now, at this point, the "clone" channel is totally F'd up.  We mark it as
03195       a zombie so nothing tries to touch it.  If it's already been marked as a
03196       zombie, then free it now (since it already is considered invalid). */
03197    if (ast_test_flag(clone, AST_FLAG_ZOMBIE)) {
03198       ast_log(LOG_DEBUG, "Destroying channel clone '%s'\n", clone->name);
03199       ast_mutex_unlock(&clone->lock);
03200       manager_event(EVENT_FLAG_CALL, "Hangup", 
03201          "Channel: %s\r\n"
03202          "Uniqueid: %s\r\n"
03203          "Cause: %d\r\n"
03204          "Cause-txt: %s\r\n",
03205          clone->name, 
03206          clone->uniqueid, 
03207          clone->hangupcause,
03208          ast_cause2str(clone->hangupcause)
03209          );
03210       ast_channel_free(clone);
03211    } else {
03212       struct ast_frame null_frame = { AST_FRAME_NULL, };
03213       ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name);
03214       ast_set_flag(clone, AST_FLAG_ZOMBIE);
03215       ast_queue_frame(clone, &null_frame);
03216       ast_mutex_unlock(&clone->lock);
03217    }
03218    
03219    /* Signal any blocker */
03220    if (ast_test_flag(original, AST_FLAG_BLOCKING))
03221       pthread_kill(original->blocker, SIGURG);
03222    ast_log(LOG_DEBUG, "Done Masquerading %s (%d)\n", original->name, original->_state);
03223    return 0;
03224 }

static int ast_fdisset ( struct pollfd pfds,
int  fd,
int  max,
int *  start 
) [inline, static]

Definition at line 1110 of file channel.h.

References pollfd::revents.

Referenced by ast_waitfor_n_fd(), ast_waitfor_nandfds(), and do_monitor().

01111 {
01112    int x;
01113    for (x=start ? *start : 0;x<max;x++)
01114       if (pfds[x].fd == fd) {
01115          if (start) {
01116             if (x==*start)
01117                (*start)++;
01118          }
01119          return pfds[x].revents;
01120       }
01121    return 0;
01122 }

struct ast_channel* ast_get_channel_by_exten_locked ( const char *  exten,
const char *  context 
) [read]

Definition at line 826 of file channel.c.

References channel_find_locked().

Referenced by pickup_exec().

00827 {
00828    return channel_find_locked(NULL, NULL, 0, context, exten);
00829 }

struct ast_channel* ast_get_channel_by_name_locked ( const char *  chan  )  [read]

struct ast_channel* ast_get_channel_by_name_prefix_locked ( const char *  name,
const int  namelen 
) [read]

Get channel by name prefix (locks channel)

Definition at line 814 of file channel.c.

References channel_find_locked().

Referenced by ast_parse_device_state(), and mixmonitor_cli().

00815 {
00816    return channel_find_locked(NULL, name, namelen, NULL, NULL);
00817 }

struct ast_channel_tech* ast_get_channel_tech ( const char *  name  )  [read]

Get a channel technology structure by name.

Parameters:
name name of technology to find
Returns:
a pointer to the structure, or NULL if no matching technology found

Definition at line 388 of file channel.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), backends, LOG_WARNING, chanlist::next, chanlist::tech, and ast_channel_tech::type.

Referenced by ast_device_state().

00389 {
00390    struct chanlist *chanls;
00391 
00392    if (ast_mutex_lock(&chlock)) {
00393       ast_log(LOG_WARNING, "Unable to lock channel tech list\n");
00394       return NULL;
00395    }
00396 
00397    for (chanls = backends; chanls; chanls = chanls->next) {
00398       if (strcasecmp(name, chanls->tech->type))
00399          continue;
00400 
00401       ast_mutex_unlock(&chlock);
00402       return chanls->tech;
00403    }
00404 
00405    ast_mutex_unlock(&chlock);
00406    return NULL;
00407 }

ast_group_t ast_get_group ( char *  s  ) 

Definition at line 3862 of file channel.c.

References ast_log(), ast_strdupa, copy(), group, LOG_ERROR, LOG_WARNING, and strsep().

Referenced by _parse(), build_device(), build_gateway(), build_peer(), build_user(), load_module(), read_agent_config(), and setup_zap().

03863 {
03864    char *copy;
03865    char *piece;
03866    char *c=NULL;
03867    int start=0, finish=0, x;
03868    ast_group_t group = 0;
03869 
03870    copy = ast_strdupa(s);
03871    if (!copy) {
03872       ast_log(LOG_ERROR, "Out of memory\n");
03873       return 0;
03874    }
03875    c = copy;
03876    
03877    while((piece = strsep(&c, ","))) {
03878       if (sscanf(piece, "%30d-%30d", &start, &finish) == 2) {
03879          /* Range */
03880       } else if (sscanf(piece, "%30d", &start)) {
03881          /* Just one */
03882          finish = start;
03883       } else {
03884          ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece);
03885          continue;
03886       }
03887       for (x = start; x <= finish; x++) {
03888          if ((x > 63) || (x < 0)) {
03889             ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x);
03890          } else
03891             group |= ((ast_group_t) 1 << x);
03892       }
03893    }
03894    return group;
03895 }

int ast_hangup ( struct ast_channel chan  ) 

Hang up a channel.

Note:
This function performs a hard hangup on a channel. Unlike the soft-hangup, this function performs all stream stopping, etc, on the channel that needs to end. chan is no longer valid after this call.
Parameters:
chan channel to hang up
Returns:
Returns 0 on success, -1 on failure.

Definition at line 1323 of file channel.c.

References ast_cause2str(), ast_cdr_detach(), ast_cdr_end(), ast_channel_free(), ast_closestream(), ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_channel::blocker, ast_channel::blockproc, ast_channel::cdr, CRASH, detach_spies(), EVENT_FLAG_CALL, free_translation(), ast_channel::generator, ast_channel::generatordata, ast_channel_tech::hangup, ast_channel::hangupcause, ast_channel::lock, LOG_DEBUG, LOG_WARNING, manager_event(), ast_channel::masq, ast_channel::masqr, ast_channel::name, option_debug, ast_generator::release, ast_channel::sched, sched_context_destroy(), ast_channel::stream, ast_channel::tech, ast_channel::uniqueid, and ast_channel::vstream.

Referenced by __ast_pbx_run(), __ast_request_and_dial(), __oh323_new(), agent_hangup(), agent_read(), alsa_new(), ast_async_goto(), ast_bridge_call_thread(), ast_feature_request_and_dial(), ast_iax2_new(), ast_modem_new(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pbx_run_app(), async_wait(), build_conf(), builtin_atxfer(), chanavail_exec(), check_goto_on_transfer(), conf_free(), dial_exec_full(), do_parking_thread(), features_hangup(), function_ilink(), handle_hd_hf(), handle_init_event(), handle_message(), handle_request_invite(), hangup_chan(), hangupcalls(), hanguptree(), iax2_request(), iax_park(), iax_park_thread(), local_hangup(), mgcp_new(), mgcp_ss(), nbs_new(), oss_new(), park_exec(), parkandannounce_exec(), phone_new(), ring_entry(), rpt(), rpt_call(), rpt_exec(), rpt_tele_thread(), sip_new(), sip_park(), sip_park_thread(), skinny_new(), skinny_ss(), ss_thread(), try_calling(), vpb_new(), wait_for_answer(), zt_handle_event(), and zt_new().

01324 {
01325    int res = 0;
01326    struct ast_cdr *cdr = NULL;
01327 
01328    /* Don't actually hang up a channel that will masquerade as someone else, or
01329       if someone is going to masquerade as us */
01330    ast_mutex_lock(&chan->lock);
01331 
01332    detach_spies(chan);     /* get rid of spies */
01333 
01334    if (chan->masq) {
01335       if (ast_do_masquerade(chan)) 
01336          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
01337    }
01338 
01339    if (chan->masq) {
01340       ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name);
01341       ast_mutex_unlock(&chan->lock);
01342       return 0;
01343    }
01344    /* If this channel is one which will be masqueraded into something, 
01345       mark it as a zombie already, so we know to free it later */
01346    if (chan->masqr) {
01347       ast_set_flag(chan, AST_FLAG_ZOMBIE);
01348       ast_mutex_unlock(&chan->lock);
01349       return 0;
01350    }
01351    free_translation(chan);
01352    /* Close audio stream */
01353    if (chan->stream) {
01354       ast_closestream(chan->stream);
01355       chan->stream = NULL;
01356    }
01357    /* Close video stream */
01358    if (chan->vstream) {
01359       ast_closestream(chan->vstream);
01360       chan->vstream = NULL;
01361    }
01362    if (chan->sched) {
01363       sched_context_destroy(chan->sched);
01364       chan->sched = NULL;
01365    }
01366    
01367    if (chan->generatordata)   /* Clear any tone stuff remaining */ 
01368       chan->generator->release(chan, chan->generatordata);
01369    chan->generatordata = NULL;
01370    chan->generator = NULL;
01371    if (chan->cdr) {     /* End the CDR if it hasn't already */ 
01372       ast_cdr_end(chan->cdr);
01373       cdr = chan->cdr;
01374       chan->cdr = NULL;
01375    }
01376    if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
01377       ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
01378                "is blocked by thread %ld in procedure %s!  Expect a failure\n",
01379                (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc);
01380       CRASH;
01381    }
01382    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) {
01383       if (option_debug)
01384          ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name);
01385       if (chan->tech->hangup)
01386          res = chan->tech->hangup(chan);
01387    } else {
01388       if (option_debug)
01389          ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name);
01390    }
01391          
01392    ast_mutex_unlock(&chan->lock);
01393    manager_event(EVENT_FLAG_CALL, "Hangup", 
01394          "Channel: %s\r\n"
01395          "Uniqueid: %s\r\n"
01396          "Cause: %d\r\n"
01397          "Cause-txt: %s\r\n",
01398          chan->name, 
01399          chan->uniqueid, 
01400          chan->hangupcause,
01401          ast_cause2str(chan->hangupcause)
01402          );
01403    ast_channel_free(chan);
01404 
01405    /* Defer CDR processing until later */
01406    if (cdr)
01407       ast_cdr_detach(cdr);
01408 
01409    return res;
01410 }

int ast_indicate ( struct ast_channel chan,
int  condition 
)

Indicates condition of channel.

Note:
Indicate a condition such as AST_CONTROL_BUSY, AST_CONTROL_RINGING, or AST_CONTROL_CONGESTION on a channel
Parameters:
chan channel to change the indication
condition which condition to indicate on the channel
Returns:
Returns 0 on success, -1 on failure

Definition at line 2073 of file channel.c.

References ast_check_hangup(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, AST_FLAG_ZOMBIE, ast_get_indication_tone(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_playtones_start(), ast_playtones_stop(), ast_test_flag, tone_zone_sound::data, ast_channel_tech::indicate, ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_channel::tech, and ast_channel::zone.

Referenced by ast_bridge_call(), ast_feature_request_and_dial(), ast_generic_bridge(), ast_park_call(), ast_play_and_record_full(), ast_rtp_bridge(), attempt_transfer(), builtin_atxfer(), builtin_blindtransfer(), conf_run(), dial_exec_full(), disa_exec(), do_parking_thread(), features_indicate(), function_remote(), handle_recordfile(), handle_remote_data(), handle_remote_phone_dtmf(), mgcp_ss(), park_exec(), pbx_builtin_busy(), pbx_builtin_congestion(), pbx_builtin_progress(), pbx_builtin_ringing(), queue_exec(), record_exec(), rmt_telem_finish(), rmt_telem_start(), rpt(), rpt_exec(), send_waveform_to_channel(), skinny_ss(), vpb_fixup(), and wait_for_answer().

02074 {
02075    int res = -1;
02076 
02077    ast_mutex_lock(&chan->lock);
02078    /* Stop if we're a zombie or need a soft hangup */
02079    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
02080       ast_mutex_unlock(&chan->lock);
02081       return -1;
02082    }
02083    if (chan->tech->indicate)
02084       res = chan->tech->indicate(chan, condition);
02085    ast_mutex_unlock(&chan->lock);
02086    if (!chan->tech->indicate || res) {
02087       /*
02088        * Device does not support (that) indication, lets fake
02089        * it by doing our own tone generation. (PM2002)
02090        */
02091       if (condition >= 0) {
02092          const struct tone_zone_sound *ts = NULL;
02093          switch (condition) {
02094          case AST_CONTROL_RINGING:
02095             ts = ast_get_indication_tone(chan->zone, "ring");
02096             break;
02097          case AST_CONTROL_BUSY:
02098             ts = ast_get_indication_tone(chan->zone, "busy");
02099             break;
02100          case AST_CONTROL_CONGESTION:
02101             ts = ast_get_indication_tone(chan->zone, "congestion");
02102             break;
02103          }
02104          if (ts && ts->data[0]) {
02105             ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
02106             ast_playtones_start(chan,0,ts->data, 1);
02107             res = 0;
02108          } else if (condition == AST_CONTROL_PROGRESS) {
02109             /* ast_playtones_stop(chan); */
02110          } else if (condition == AST_CONTROL_PROCEEDING) {
02111             /* Do nothing, really */
02112          } else if (condition == AST_CONTROL_HOLD) {
02113             /* Do nothing.... */
02114          } else if (condition == AST_CONTROL_UNHOLD) {
02115             /* Do nothing.... */
02116          } else if (condition == AST_CONTROL_VIDUPDATE) {
02117             /* Do nothing.... */
02118          } else {
02119             /* not handled */
02120             ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
02121             res = -1;
02122          }
02123       }
02124       else ast_playtones_stop(chan);
02125    }
02126    return res;
02127 }

char* ast_print_group ( char *  buf,
int  buflen,
ast_group_t  group 
)

Definition at line 3950 of file channel.c.

Referenced by ast_serialize_showchan(), misdn_cfg_get_config_string(), print_group(), and read_config().

03951 {
03952    unsigned int i;
03953    int first=1;
03954    char num[3];
03955 
03956    buf[0] = '\0';
03957    
03958    if (!group) /* Return empty string if no group */
03959       return(buf);
03960 
03961    for (i=0; i<=63; i++) { /* Max group is 63 */
03962       if (group & ((ast_group_t) 1 << i)) {
03963             if (!first) {
03964             strncat(buf, ", ", buflen);
03965          } else {
03966             first=0;
03967          }
03968          snprintf(num, sizeof(num), "%u", i);
03969          strncat(buf, num, buflen);
03970       }
03971    }
03972    return(buf);
03973 }

int ast_prod ( struct ast_channel chan  ) 

Definition at line 2229 of file channel.c.

References ast_channel::_state, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), AST_STATE_UP, ast_write(), ast_frame::data, LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_channel::rawwriteformat, ast_frame::src, and ast_frame::subclass.

Referenced by ast_activate_generator().

02230 {
02231    struct ast_frame a = { AST_FRAME_VOICE };
02232    char nothing[128];
02233 
02234    /* Send an empty audio frame to get things moving */
02235    if (chan->_state != AST_STATE_UP) {
02236       ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name);
02237       a.subclass = chan->rawwriteformat;
02238       a.data = nothing + AST_FRIENDLY_OFFSET;
02239       a.src = "ast_prod";
02240       if (ast_write(chan, &a))
02241          ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name);
02242    }
02243    return 0;
02244 }

int ast_queue_control ( struct ast_channel chan,
int  control 
)

int ast_queue_frame ( struct ast_channel chan,
struct ast_frame f 
)

Queue an outgoing frame.

Definition at line 614 of file channel.c.

References ast_channel::alertpipe, AST_CONTROL_HANGUP, AST_FLAG_BLOCKING, AST_FRAME_CONTROL, AST_FRAME_VOICE, ast_frdup(), ast_frfree(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_channel::blocker, CRASH, ast_frame::frametype, ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_frame::next, ast_frame::prev, ast_channel::readq, ast_frame::subclass, and ast_channel::timingfd.

Referenced by agent_new(), alsa_call(), ast_channel_masquerade(), ast_channel_setwhentohangup(), ast_do_masquerade(), ast_dsp_process(), ast_queue_control(), ast_queue_hangup(), ast_softhangup_nolock(), cb_events(), console_answer(), console_dial(), console_flash(), console_sendtext(), dictate_exec(), do_chanreads(), do_immediate_setup(), handle_message(), handle_request_info(), handle_request_invite(), handle_response_invite(), iax2_queue_frame(), local_queue_frame(), mgcp_queue_frame(), monitor_handle_owned(), oss_call(), process_sdp(), receive_message(), send_digit(), wakeup_sub(), and zap_queue_frame().

00615 {
00616    struct ast_frame *f;
00617    struct ast_frame *prev, *cur;
00618    int blah = 1;
00619    int qlen = 0;
00620 
00621    /* Build us a copy and free the original one */
00622    f = ast_frdup(fin);
00623    if (!f) {
00624       ast_log(LOG_WARNING, "Unable to duplicate frame\n");
00625       return -1;
00626    }
00627    ast_mutex_lock(&chan->lock);
00628    prev = NULL;
00629    cur = chan->readq;
00630    while(cur) {
00631       if ((cur->frametype == AST_FRAME_CONTROL) && (cur->subclass == AST_CONTROL_HANGUP)) {
00632          /* Don't bother actually queueing anything after a hangup */
00633          ast_frfree(f);
00634          ast_mutex_unlock(&chan->lock);
00635          return 0;
00636       }
00637       prev = cur;
00638       cur = cur->next;
00639       qlen++;
00640    }
00641    /* Allow up to 96 voice frames outstanding, and up to 128 total frames */
00642    if (((fin->frametype == AST_FRAME_VOICE) && (qlen > 96)) || (qlen  > 128)) {
00643       if (fin->frametype != AST_FRAME_VOICE) {
00644          ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name);
00645          CRASH;
00646       } else {
00647          ast_log(LOG_DEBUG, "Dropping voice to exceptionally long queue on %s\n", chan->name);
00648          ast_frfree(f);
00649          ast_mutex_unlock(&chan->lock);
00650          return 0;
00651       }
00652    }
00653    if (prev)
00654       prev->next = f;
00655    else
00656       chan->readq = f;
00657    if (chan->alertpipe[1] > -1) {
00658       if (write(chan->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah))
00659          ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d (qlen = %d): %s!\n",
00660             chan->name, f->frametype, f->subclass, qlen, strerror(errno));
00661 #ifdef ZAPTEL_OPTIMIZATIONS
00662    } else if (chan->timingfd > -1) {
00663       ioctl(chan->timingfd, ZT_TIMERPING, &blah);
00664 #endif            
00665    } else if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
00666       pthread_kill(chan->blocker, SIGURG);
00667    }
00668    ast_mutex_unlock(&chan->lock);
00669    return 0;
00670 }

int ast_queue_hangup ( struct ast_channel chan  ) 

struct ast_frame* ast_read ( struct ast_channel chan  )  [read]

Reads a frame

Parameters:
chan channel to read a frame from Read a frame. Returns a frame, or NULL on error. If it returns NULL, you best just stop reading frames and assume the channel has been disconnected.

Definition at line 1845 of file channel.c.

References ast_channel::_softhangup, ast_channel::_state, ast_channel::alertpipe, ast_cdr_answer(), ast_cdr_end(), ast_check_hangup(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, ast_deactivate_generator(), ast_do_masquerade(), AST_FLAG_DEFER_DTMF, AST_FLAG_EXCEPTION, AST_FLAG_ZOMBIE, AST_FRAME_CNG, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frame_dump(), AST_FRAME_NULL, AST_FRAME_VOICE, ast_frfree(), ast_getformatname(), ast_log(), AST_MAX_FDS, ast_mutex_lock(), ast_mutex_unlock(), ast_seekstream(), ast_setstate(), ast_settimeout(), AST_SOFTHANGUP_DEV, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, ast_translate(), ast_writestream(), ast_channel::blocker, ast_channel::cdr, ast_frame::data, ast_frame::datalen, ast_channel::dtmff, ast_channel::dtmfq, ast_channel_tech::exception, ast_channel::fdno, ast_channel::fin, ast_frame::frametype, ast_generator::generate, ast_channel::generator, generator_force(), ast_channel::generatordata, ast_channel::insmpl, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::masq, ast_channel::monitor, ast_channel::name, ast_channel::nativeformats, ast_frame::next, ast_channel::outsmpl, queue_frame_to_spies(), ast_channel_tech::read, ast_channel_monitor::read_stream, ast_channel::readq, ast_channel::readtrans, ast_frame::samples, SEEK_FORCECUR, ast_channel::spies, SPY_READ, ast_frame::subclass, ast_channel::tech, ast_channel::timingdata, ast_channel::timingfd, and ast_channel::timingfunc.

Referenced by __adsi_transmit_messages(), __ast_request_and_dial(), adsi_careful_send(), agent_ack_sleep(), agent_read(), app_exec(), ast_app_getvoice(), ast_feature_request_and_dial(), ast_generic_bridge(), ast_masq_park_call(), ast_play_and_prepend(), ast_play_and_record_full(), ast_recvtext(), ast_rtp_bridge(), ast_safe_sleep(), ast_safe_sleep_conditional(), ast_tonepair(), ast_waitfordigit(), ast_waitfordigit_full(), ast_waitstream(), ast_waitstream_exten(), ast_waitstream_fr(), ast_waitstream_full(), async_wait(), autoservice_run(), background_detect_exec(), builtin_atxfer(), channel_spy(), check_goto_on_transfer(), conf_exec(), conf_flush(), conf_run(), dictate_exec(), disa_exec(), do_parking_thread(), do_waiting(), echo_exec(), features_read(), find_cache(), handle_recordfile(), iax2_bridge(), iax_park_thread(), ices_exec(), measurenoise(), misdn_bridge(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), record_exec(), recordthread(), rpt(), rpt_exec(), run_agi(), send_tone_burst(), send_waveform_to_channel(), sendurl_exec(), sms_exec(), ss_thread(), vpb_bridge(), wait_for_answer(), wait_for_hangup(), waitforring_exec(), and zt_bridge().

01846 {
01847    struct ast_frame *f = NULL;
01848    int blah;
01849    int prestate;
01850 #ifdef ZAPTEL_OPTIMIZATIONS
01851    int (*func)(void *);
01852    void *data;
01853    int res;
01854 #endif
01855    static struct ast_frame null_frame = {
01856       AST_FRAME_NULL,
01857    };
01858    
01859    ast_mutex_lock(&chan->lock);
01860    if (chan->masq) {
01861       if (ast_do_masquerade(chan)) {
01862          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
01863          f = NULL;
01864       } else
01865          f =  &null_frame;
01866       ast_mutex_unlock(&chan->lock);
01867       return f;
01868    }
01869 
01870    /* Stop if we're a zombie or need a soft hangup */
01871    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
01872       if (chan->generator)
01873          ast_deactivate_generator(chan);
01874       ast_mutex_unlock(&chan->lock);
01875       return NULL;
01876    }
01877    prestate = chan->_state;
01878 
01879    if (!ast_test_flag(chan, AST_FLAG_DEFER_DTMF) && !ast_strlen_zero(chan->dtmfq)) {
01880       /* We have DTMF that has been deferred.  Return it now */
01881       chan->dtmff.frametype = AST_FRAME_DTMF;
01882       chan->dtmff.subclass = chan->dtmfq[0];
01883       /* Drop first digit */
01884       memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1);
01885       ast_mutex_unlock(&chan->lock);
01886       return &chan->dtmff;
01887    }
01888    
01889    /* Read and ignore anything on the alertpipe, but read only
01890       one sizeof(blah) per frame that we send from it */
01891    if (chan->alertpipe[0] > -1) {
01892       read(chan->alertpipe[0], &blah, sizeof(blah));
01893    }
01894 #ifdef ZAPTEL_OPTIMIZATIONS
01895    if ((chan->timingfd > -1) && (chan->fdno == AST_MAX_FDS - 2) && ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
01896       ast_clear_flag(chan, AST_FLAG_EXCEPTION);
01897       blah = -1;
01898       /* IF we can't get event, assume it's an expired as-per the old interface */
01899       res = ioctl(chan->timingfd, ZT_GETEVENT, &blah);
01900       if (res) 
01901          blah = ZT_EVENT_TIMER_EXPIRED;
01902 
01903       if (blah == ZT_EVENT_TIMER_PING) {
01904 #if 0
01905          ast_log(LOG_NOTICE, "Oooh, there's a PING!\n");
01906 #endif         
01907          if (!chan->readq || !chan->readq->next) {
01908             /* Acknowledge PONG unless we need it again */
01909 #if 0
01910             ast_log(LOG_NOTICE, "Sending a PONG!\n");
01911 #endif            
01912             if (ioctl(chan->timingfd, ZT_TIMERPONG, &blah)) {
01913                ast_log(LOG_WARNING, "Failed to pong timer on '%s': %s\n", chan->name, strerror(errno));
01914             }
01915          }
01916       } else if (blah == ZT_EVENT_TIMER_EXPIRED) {
01917          ioctl(chan->timingfd, ZT_TIMERACK, &blah);
01918          func = chan->timingfunc;
01919          data = chan->timingdata;
01920          ast_mutex_unlock(&chan->lock);
01921          if (func) {
01922 #if 0
01923             ast_log(LOG_DEBUG, "Calling private function\n");
01924 #endif         
01925             func(data);
01926          } else {
01927             blah = 0;
01928             ast_mutex_lock(&chan->lock);
01929             ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah);
01930             chan->timingdata = NULL;
01931             ast_mutex_unlock(&chan->lock);
01932          }
01933          f =  &null_frame;
01934          return f;
01935       } else
01936          ast_log(LOG_NOTICE, "No/unknown event '%d' on timer for '%s'?\n", blah, chan->name);
01937    }
01938 #endif
01939    /* Check for pending read queue */
01940    if (chan->readq) {
01941       f = chan->readq;
01942       chan->readq = f->next;
01943       /* Interpret hangup and return NULL */
01944       if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) {
01945          ast_frfree(f);
01946          f = NULL;
01947       }
01948    } else {
01949       chan->blocker = pthread_self();
01950       if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
01951          if (chan->tech->exception) 
01952             f = chan->tech->exception(chan);
01953          else {
01954             ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name);
01955             f = &null_frame;
01956          }
01957          /* Clear the exception flag */
01958          ast_clear_flag(chan, AST_FLAG_EXCEPTION);
01959       } else {
01960          if (chan->tech->read)
01961             f = chan->tech->read(chan);
01962          else
01963             ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
01964       }
01965    }
01966 
01967 
01968    if (f && (f->frametype == AST_FRAME_VOICE)) {
01969       if (!(f->subclass & chan->nativeformats)) {
01970          /* This frame can't be from the current native formats -- drop it on the
01971             floor */
01972          ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n", chan->name, ast_getformatname(f->subclass), ast_getformatname(chan->nativeformats));
01973          ast_frfree(f);
01974          f = &null_frame;
01975       } else {
01976          if (chan->spies)
01977             queue_frame_to_spies(chan, f, SPY_READ);
01978 
01979          if (chan->monitor && chan->monitor->read_stream ) {
01980 #ifndef MONITOR_CONSTANT_DELAY
01981             int jump = chan->outsmpl - chan->insmpl - 4 * f->samples;
01982             if (jump >= 0) {
01983                jump = chan->outsmpl - chan->insmpl;
01984                if (ast_seekstream(chan->monitor->read_stream, jump, SEEK_FORCECUR) == -1)
01985                   ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
01986                chan->insmpl += jump + f->samples;
01987             } else
01988                chan->insmpl+= f->samples;
01989 #else
01990             int jump = chan->outsmpl - chan->insmpl;
01991             if (jump - MONITOR_DELAY >= 0) {
01992                if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
01993                   ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
01994                chan->insmpl += jump;
01995             } else
01996                chan->insmpl += f->samples;
01997 #endif
01998             if (ast_writestream(chan->monitor->read_stream, f) < 0)
01999                ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
02000          }
02001          if (chan->readtrans) {
02002             f = ast_translate(chan->readtrans, f, 1);
02003             if (!f)
02004                f = &null_frame;
02005          }
02006       }
02007    }
02008 
02009    /* Make sure we always return NULL in the future */
02010    if (!f) {
02011       chan->_softhangup |= AST_SOFTHANGUP_DEV;
02012       if (chan->generator)
02013          ast_deactivate_generator(chan);
02014       /* End the CDR if appropriate */
02015       if (chan->cdr)
02016          ast_cdr_end(chan->cdr);
02017    } else if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF) && f->frametype == AST_FRAME_DTMF) {
02018       if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2)
02019          chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
02020       else
02021          ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
02022       ast_frfree(f);
02023       f = &null_frame;
02024    } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_ANSWER)) {
02025       if (prestate == AST_STATE_UP) {
02026          ast_log(LOG_DEBUG, "Dropping duplicate answer!\n");
02027          ast_frfree(f);
02028          f = &null_frame;
02029       }
02030       /* Answer the CDR */
02031       ast_setstate(chan, AST_STATE_UP);
02032       ast_cdr_answer(chan->cdr);
02033    } 
02034 
02035    /* Run any generator sitting on the line */
02036    if (f && (f->frametype == AST_FRAME_VOICE) && chan->generatordata) {
02037       /* Mask generator data temporarily and apply.  If there is a timing function, it
02038          will be calling the generator instead */
02039       void *tmp;
02040       int res;
02041       int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples);
02042 
02043       if (chan->timingfunc) {
02044          ast_log(LOG_DEBUG, "Generator got voice, switching to phase locked mode\n");
02045          ast_settimeout(chan, 0, NULL, NULL);
02046       }
02047       tmp = chan->generatordata;
02048       chan->generatordata = NULL;
02049       generate = chan->generator->generate;
02050       res = generate(chan, tmp, f->datalen, f->samples);
02051       chan->generatordata = tmp;
02052       if (res) {
02053          ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
02054          ast_deactivate_generator(chan);
02055       }
02056    } else if (f && (f->frametype == AST_FRAME_CNG)) {
02057       if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) {
02058          ast_log(LOG_DEBUG, "Generator got CNG, switching to zap timed mode\n");
02059          ast_settimeout(chan, 160, generator_force, chan);
02060       }
02061    }
02062    /* High bit prints debugging */
02063    if (chan->fin & 0x80000000)
02064       ast_frame_dump(chan->name, f, "<<");
02065    if ((chan->fin & 0x7fffffff) == 0x7fffffff)
02066       chan->fin &= 0x80000000;
02067    else
02068       chan->fin++;
02069    ast_mutex_unlock(&chan->lock);
02070    return f;
02071 }

int ast_readstring ( struct ast_channel c,
char *  s,
int  len,
int  timeout,
int  rtimeout,
char *  enders 
)

Reads multiple digits

Parameters:
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 2663 of file channel.c.

References ast_check_hangup(), AST_DIGIT_ANY, AST_FLAG_ZOMBIE, ast_stopstream(), ast_test_flag, ast_waitfordigit(), ast_waitstream(), and ast_channel::stream.

Referenced by __adsi_transmit_messages(), adsi_begin_download(), adsi_get_cpeinfo(), adsi_load_session(), ast_app_getdata(), dialout(), do_directory(), forward_message(), privacy_exec(), vm_authenticate(), vm_newuser(), and vm_options().

02664 {
02665    int pos=0;
02666    int to = ftimeout;
02667    int d;
02668 
02669    /* XXX Merge with full version? XXX */
02670    /* Stop if we're a zombie or need a soft hangup */
02671    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 
02672       return -1;
02673    if (!len)
02674       return -1;
02675    do {
02676       if (c->stream) {
02677          d = ast_waitstream(c, AST_DIGIT_ANY);
02678          ast_stopstream(c);
02679          usleep(1000);
02680          if (!d)
02681             d = ast_waitfordigit(c, to);
02682       } else {
02683          d = ast_waitfordigit(c, to);
02684       }
02685       if (d < 0)
02686          return -1;
02687       if (d == 0) {
02688          s[pos]='\0';
02689          return 1;
02690       }
02691       if (!strchr(enders, d))
02692          s[pos++] = d;
02693       if (strchr(enders, d) || (pos >= len)) {
02694          s[pos]='\0';
02695          return 0;
02696       }
02697       to = timeout;
02698    } while(1);
02699    /* Never reached */
02700    return 0;
02701 }

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 2703 of file channel.c.

References ast_check_hangup(), AST_DIGIT_ANY, AST_FLAG_ZOMBIE, ast_stopstream(), ast_test_flag, ast_waitfordigit_full(), ast_waitstream_full(), and ast_channel::stream.

Referenced by ast_app_getdata_full().

02704 {
02705    int pos=0;
02706    int to = ftimeout;
02707    int d;
02708 
02709    /* Stop if we're a zombie or need a soft hangup */
02710    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 
02711       return -1;
02712    if (!len)
02713       return -1;
02714    do {
02715       if (c->stream) {
02716          d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
02717          ast_stopstream(c);
02718          usleep(1000);
02719          if (!d)
02720             d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
02721       } else {
02722          d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
02723       }
02724       if (d < 0)
02725          return -1;
02726       if (d == 0) {
02727          s[pos]='\0';
02728          return 1;
02729       }
02730       if (d == 1) {
02731          s[pos]='\0';
02732          return 2;
02733       }
02734       if (!strchr(enders, d))
02735          s[pos++] = d;
02736       if (strchr(enders, d) || (pos >= len)) {
02737          s[pos]='\0';
02738          return 0;
02739       }
02740       to = timeout;
02741    } while(1);
02742    /* Never reached */
02743    return 0;
02744 }

int ast_recvchar ( struct ast_channel chan,
int  timeout 
)

Receives a text character from a channel

Parameters:
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 2129 of file channel.c.

References ast_recvtext(), and free.

Referenced by handle_recvchar().

02130 {
02131    int c;
02132    char *buf = ast_recvtext(chan, timeout);
02133    if (buf == NULL)
02134       return -1;  /* error or timeout */
02135    c = *(unsigned char *)buf;
02136    free(buf);
02137    return c;
02138 }

char* ast_recvtext ( struct ast_channel chan,
int  timeout 
)

Receives a text string from a channel

Parameters:
chan channel to act upon
timeout timeout in milliseconds (0 for infinite wait)
Returns:
the received text, or NULL to signify failure. Read a string of text from a channel

Definition at line 2140 of file channel.c.

References ast_check_hangup(), AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_TEXT, ast_frfree(), ast_read(), ast_waitfor(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, strndup, and ast_frame::subclass.

Referenced by ast_recvchar(), and handle_recvtext().

02141 {
02142    int res, done = 0;
02143    char *buf = NULL;
02144    
02145    while (!done) {
02146       struct ast_frame *f;
02147       if (ast_check_hangup(chan))
02148          break;
02149       res = ast_waitfor(chan, timeout);
02150       if (res <= 0) /* timeout or error */
02151          break;
02152       timeout = res; /* update timeout */
02153       f = ast_read(chan);
02154       if (f == NULL)
02155          break; /* no frame */
02156       if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP)
02157          done = 1;   /* force a break */
02158       else if (f->frametype == AST_FRAME_TEXT) {      /* what we want */
02159          buf = strndup((char *) f->data, f->datalen); /* dup and break */
02160          done = 1;
02161       }
02162       ast_frfree(f);
02163    }
02164    return buf;
02165 }

struct ast_channel* ast_request ( const char *  type,
int  format,
void *  data,
int *  status 
) [read]

Requests a channel.

Parameters:
type type of channel to request
format requested channel format
data data to pass to the channel requester
status status Request a channel of a given type, with data as optional information used by the low level module
Returns:
Returns an ast_channel on success, NULL on failure.

Definition at line 2568 of file channel.c.

References ast_channel::_state, AST_CAUSE_NOSUCHDRIVER, AST_CAUSE_NOTDEFINED, AST_FLAG_NOTNEW, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_state2str(), AST_STATE_DOWN, ast_translator_best_choice(), backends, ast_channel_tech::capabilities, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, EVENT_FLAG_CALL, fmt, LOG_WARNING, manager_event(), ast_channel::name, chanlist::next, ast_channel_tech::requester, chanlist::tech, ast_channel_tech::type, and ast_channel::uniqueid.

Referenced by __ast_request_and_dial(), agent_request(), ast_feature_request_and_dial(), attempt_reconnect(), build_conf(), chanavail_exec(), dial_exec_full(), features_alloc(), function_ilink(), ring_entry(), rpt(), rpt_call(), rpt_exec(), rpt_tele_thread(), and wait_for_answer().

02569 {
02570    struct chanlist *chan;
02571    struct ast_channel *c;
02572    int capabilities;
02573    int fmt;
02574    int res;
02575    int foo;
02576 
02577    if (!cause)
02578       cause = &foo;
02579    *cause = AST_CAUSE_NOTDEFINED;
02580 
02581    if (ast_mutex_lock(&chlock)) {
02582       ast_log(LOG_WARNING, "Unable to lock channel list\n");
02583       return NULL;
02584    }
02585 
02586    for (chan = backends; chan; chan = chan->next) {
02587       if (strcasecmp(type, chan->tech->type))
02588          continue;
02589 
02590       capabilities = chan->tech->capabilities;
02591       fmt = format;
02592       res = ast_translator_best_choice(&fmt, &capabilities);
02593       if (res < 0) {
02594          ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->tech->capabilities, format);
02595          ast_mutex_unlock(&chlock);
02596          return NULL;
02597       }
02598       ast_mutex_unlock(&chlock);
02599       if (!chan->tech->requester)
02600          return NULL;
02601       
02602       if (!(c = chan->tech->requester(type, capabilities, data, cause)))
02603          return NULL;
02604 
02605       if (c->_state == AST_STATE_DOWN) {
02606          manager_event(EVENT_FLAG_CALL, "Newchannel",
02607                   "Channel: %s\r\n"
02608                   "State: %s\r\n"
02609                   "CallerID: %s\r\n"
02610                   "CallerIDName: %s\r\n"
02611                   "Uniqueid: %s\r\n",
02612                   c->name, ast_state2str(c->_state),
02613                   c->cid.cid_num ? c->cid.cid_num : "<unknown>",
02614                   c->cid.cid_name ? c->cid.cid_name : "<unknown>",
02615                   c->uniqueid);
02616          ast_set_flag(c, AST_FLAG_NOTNEW);
02617       }
02618       return c;
02619    }
02620 
02621    ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
02622    *cause = AST_CAUSE_NOSUCHDRIVER;
02623    ast_mutex_unlock(&chlock);
02624 
02625    return NULL;
02626 }

struct ast_channel* ast_request_and_dial ( const char *  type,
int  format,
void *  data,
int  timeout,
int *  reason,
const char *  cidnum,
const char *  cidname 
) [read]

Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it.

Parameters:
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 unsuceessful)
cidnum Caller-ID Number
cidname Caller-ID Name
Returns:
Returns an ast_channel on success or no answer, NULL on failure. Check the value of chan->_state to know if the call was answered or not.

Definition at line 2563 of file channel.c.

References __ast_request_and_dial().

Referenced by ast_pbx_outgoing_exten().

02564 {
02565    return __ast_request_and_dial(type, format, data, timeout, outstate, cidnum, cidname, NULL);
02566 }

int ast_safe_sleep ( struct ast_channel chan,
int  ms 
)

Wait for a specied amount of time, looking for hangups.

Parameters:
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.
Returns:
returns -1 on hangup, otherwise 0.

Definition at line 854 of file channel.c.

References ast_frfree(), ast_read(), and ast_waitfor().

Referenced by __login_exec(), adsi_transmit_message_full(), alarmreceiver_exec(), ast_dtmf_stream(), dictate_exec(), flash_exec(), function_ilink(), function_remote(), handle_remote_data(), handle_remote_phone_dtmf(), milliwatt_exec(), moh0_exec(), moh1_exec(), park_call_exec(), pbx_builtin_answer(), pbx_builtin_wait(), play_tone_pair(), privacy_exec(), receive_ademco_contact_id(), rmt_telem_start(), rpt_call(), rpt_exec(), rpt_tele_thread(), send_morse(), send_tone_telemetry(), skinny_ss(), testclient_exec(), testserver_exec(), try_calling(), wait_for_hangup(), wait_interval(), and zapateller_exec().

00855 {
00856    struct ast_frame *f;
00857    while(ms > 0) {
00858       ms = ast_waitfor(chan, ms);
00859       if (ms <0)
00860          return -1;
00861       if (ms > 0) {
00862          f = ast_read(chan);
00863          if (!f)
00864             return -1;
00865          ast_frfree(f);
00866       }
00867    }
00868    return 0;
00869 }

int ast_safe_sleep_conditional ( struct ast_channel chan,
int  ms,
int(*)(void *)  cond,
void *  data 
)

Wait for a specied amount of time, looking for hangups and a condition argument.

Parameters:
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
Returns:
returns -1 on hangup, otherwise 0. Waits for a specified amount of time, servicing the channel as required. If cond returns 0, this function returns.

Definition at line 832 of file channel.c.

References ast_frfree(), ast_read(), and ast_waitfor().

Referenced by __login_exec().

00834 {
00835    struct ast_frame *f;
00836 
00837    while(ms > 0) {
00838       if( cond && ((*cond)(data) == 0 ) )
00839          return 0;
00840       ms = ast_waitfor(chan, ms);
00841       if (ms <0)
00842          return -1;
00843       if (ms > 0) {
00844          f = ast_read(chan);
00845          if (!f)
00846             return -1;
00847          ast_frfree(f);
00848       }
00849    }
00850    return 0;
00851 }

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.

Parameters:
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 1147 of file channel.h.

Referenced by do_monitor(), do_parking_thread(), and sound_thread().

01148 {
01149 #ifdef __linux__
01150    return select(nfds, rfds, wfds, efds, tvp);
01151 #else
01152    if (tvp) {
01153       struct timeval tv, tvstart, tvend, tvlen;
01154       int res;
01155 
01156       tv = *tvp;
01157       gettimeofday(&tvstart, NULL);
01158       res = select(nfds, rfds, wfds, efds, tvp);
01159       gettimeofday(&tvend, NULL);
01160       timersub(&tvend, &tvstart, &tvlen);
01161       timersub(&tv, &tvlen, tvp);
01162       if (tvp->tv_sec < 0 || (tvp->tv_sec == 0 && tvp->tv_usec < 0)) {
01163          tvp->tv_sec = 0;
01164          tvp->tv_usec = 0;
01165       }
01166       return res;
01167    }
01168    else
01169       return select(nfds, rfds, wfds, efds, NULL);
01170 #endif
01171 }

int ast_senddigit ( struct ast_channel chan,
char  digit 
)

Send a DTMF digit to a channel

Parameters:
chan channel to act upon
digit the DTMF digit to send, encoded in ASCII Send a DTMF digit to a channel. Returns 0 on success, -1 on failure

Definition at line 2224 of file channel.c.

References do_senddigit().

Referenced by dial_exec_full(), and features_digit().

02225 {
02226    return do_senddigit(chan, digit);
02227 }

int ast_sendtext ( struct ast_channel chan,
const char *  text 
)

Sends text to a channel

Parameters:
chan channel to act upon
text string of text to send on the channel Write text to a display on a channel Returns 0 on success, -1 on failure

Definition at line 2167 of file channel.c.

References ast_check_hangup(), ast_clear_flag, AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_test_flag, CHECK_BLOCKING, ast_channel_tech::send_text, and ast_channel::tech.

Referenced by agent_sendtext(), handle_sendtext(), and sendtext_exec().

02168 {
02169    int res = 0;
02170    /* Stop if we're a zombie or need a soft hangup */
02171    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) 
02172       return -1;
02173    CHECK_BLOCKING(chan);
02174    if (chan->tech->send_text)
02175       res = chan->tech->send_text(chan, text);
02176    ast_clear_flag(chan, AST_FLAG_BLOCKING);
02177    return res;
02178 }

void ast_set_callerid ( struct ast_channel chan,
const char *  cidnum,
const char *  cidname,
const char *  ani 
)

Definition at line 3226 of file channel.c.

References ast_cdr_setcid(), ast_describe_caller_presentation(), ast_strlen_zero(), ast_channel::cdr, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, EVENT_FLAG_CALL, free, manager_event(), ast_channel::name, strdup, and ast_channel::uniqueid.

Referenced by __ast_request_and_dial(), agent_call(), ast_feature_request_and_dial(), callerid_write(), dial_exec_full(), disa_exec(), get_callerid(), handle_setcallerid(), local_call(), lookupcidname_exec(), mgcp_ss(), monitor_handle_notowned(), privacy_exec(), read_config(), rpt_exec(), setcallerid_exec(), skinny_ss(), ss_thread(), wait_for_answer(), and zt_read().

03227 {
03228    if (callerid) {
03229       if (chan->cid.cid_num)
03230          free(chan->cid.cid_num);
03231       if (ast_strlen_zero(callerid))
03232          chan->cid.cid_num = NULL;
03233       else
03234          chan->cid.cid_num = strdup(callerid);
03235    }
03236    if (calleridname) {
03237       if (chan->cid.cid_name)
03238          free(chan->cid.cid_name);
03239       if (ast_strlen_zero(calleridname))
03240          chan->cid.cid_name = NULL;
03241       else
03242          chan->cid.cid_name = strdup(calleridname);
03243    }
03244    if (ani) {
03245       if (chan->cid.cid_ani)
03246          free(chan->cid.cid_ani);
03247       if (ast_strlen_zero(ani))
03248          chan->cid.cid_ani = NULL;
03249       else
03250          chan->cid.cid_ani = strdup(ani);
03251    }
03252    if (chan->cdr)
03253       ast_cdr_setcid(chan->cdr, chan);
03254    manager_event(EVENT_FLAG_CALL, "Newcallerid", 
03255             "Channel: %s\r\n"
03256             "CallerID: %s\r\n"
03257             "CallerIDName: %s\r\n"
03258             "Uniqueid: %s\r\n"
03259             "CID-CallingPres: %d (%s)\r\n",
03260             chan->name, chan->cid.cid_num ? 
03261             chan->cid.cid_num : "<Unknown>",
03262             chan->cid.cid_name ? 
03263             chan->cid.cid_name : "<Unknown>",
03264             chan->uniqueid,
03265             chan->cid.cid_pres,
03266             ast_describe_caller_presentation(chan->cid.cid_pres)
03267             );
03268 }

int ast_set_read_format ( struct ast_channel chan,
int  format 
)

void ast_set_variables ( struct ast_channel chan,
struct ast_variable vars 
)

adds a list of channel variables to a channel

Parameters:
chan the channel
vars a linked list of variables
Variable names can be for a regular channel variable or a dialplan function that has the ability to be written to.

Definition at line 3975 of file channel.c.

References ast_variable::name, ast_variable::next, pbx_builtin_setvar_helper(), and ast_variable::value.

Referenced by __ast_request_and_dial(), ast_pbx_outgoing_app(), and ast_pbx_outgoing_exten().

03976 {
03977    struct ast_variable *cur;
03978 
03979    for (cur = vars; cur; cur = cur->next)
03980       pbx_builtin_setvar_helper(chan, cur->name, cur->value);  
03981 }

int ast_set_write_format ( struct ast_channel chan,
int  format 
)

int ast_setstate ( struct ast_channel chan,
int  state 
)

Change the state of a channel.

Definition at line 3270 of file channel.c.

References ast_channel::_state, ast_device_state_changed_literal(), AST_FLAG_NOTNEW, ast_state2str(), AST_STATE_DOWN, ast_test_flag, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, EVENT_FLAG_CALL, manager_event(), ast_channel::name, and ast_channel::uniqueid.

Referenced by __oh323_new(), __oh323_update_info(), __zt_exception(), agent_call(), agent_new(), alsa_answer(), alsa_new(), aopen_handle_escape(), ast_answer(), ast_async_goto(), ast_iax2_new(), ast_modem_new(), ast_read(), bestdata_handle_escape(), cb_events(), check_availability(), features_new(), handle_message(), handle_request_invite(), handle_response_invite(), i4l_handle_escape(), iax2_call(), local_new(), mgcp_answer(), mgcp_call(), mgcp_new(), mgcp_ss(), misdn_call(), misdn_indication(), misdn_new(), modem_answer(), modem_call(), modem_hangup(), nbs_call(), nbs_hangup(), nbs_new(), oh323_answer(), oss_answer(), oss_new(), pbx_builtin_busy(), pbx_builtin_congestion(), phone_answer(), phone_call(), phone_exception(), phone_hangup(), phone_new(), phone_write(), release_chan(), sip_answer(), sip_new(), skinny_answer(), skinny_call(), skinny_new(), skinny_ss(), ss_thread(), update_state(), vpb_answer(), vpb_call(), vpb_hangup(), vpb_new(), zt_answer(), zt_call(), zt_handle_event(), zt_indicate(), zt_new(), and zt_read().

03271 {
03272    int oldstate = chan->_state;
03273 
03274    if (oldstate == state)
03275       return 0;
03276 
03277    chan->_state = state;
03278    ast_device_state_changed_literal(chan->name);
03279    manager_event(EVENT_FLAG_CALL,
03280             (oldstate == AST_STATE_DOWN && !ast_test_flag(chan, AST_FLAG_NOTNEW)) ? "Newchannel" : "Newstate",
03281             "Channel: %s\r\n"
03282             "State: %s\r\n"
03283             "CallerID: %s\r\n"
03284             "CallerIDName: %s\r\n"
03285             "Uniqueid: %s\r\n",
03286             chan->name, ast_state2str(chan->_state), 
03287             chan->cid.cid_num ? chan->cid.cid_num : "<unknown>", 
03288             chan->cid.cid_name ? chan->cid.cid_name : "<unknown>", 
03289             chan->uniqueid);
03290 
03291    return 0;
03292 }

int ast_settimeout ( struct ast_channel c,
int  samples,
int(*)(void *data)  func,
void *  data 
)

Definition at line 1768 of file channel.c.

References ast_log(), LOG_DEBUG, ast_channel::timingdata, ast_channel::timingfd, and ast_channel::timingfunc.

Referenced by ast_activate_generator(), ast_closestream(), ast_deactivate_generator(), ast_read(), and ast_readaudio_callback().

01769 {
01770    int res = -1;
01771 #ifdef ZAPTEL_OPTIMIZATIONS
01772    if (c->timingfd > -1) {
01773       if (!func) {
01774          samples = 0;
01775          data = 0;
01776       }
01777       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01778       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01779       c->timingfunc = func;
01780       c->timingdata = data;
01781    }
01782 #endif   
01783    return res;
01784 }

int ast_shutting_down ( void   ) 

Returns non-zero if Asterisk is being shut down

Definition at line 271 of file channel.c.

References shutting_down.

00272 {
00273    return shutting_down;
00274 }

int ast_softhangup ( struct ast_channel chan,
int  cause 
)

Softly hangup up a channel.

Parameters:
chan channel to be soft-hung-up Call the protocol layer, but don't destroy the channel structure (use this if you are trying to safely hangup a channel managed by another thread.
cause Ast hangupcause for hangup
Returns:
Returns 0 regardless

Definition at line 1169 of file channel.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_softhangup_nolock(), and ast_channel::lock.

Referenced by __login_exec(), __unload_module(), action_hangup(), agent_hangup(), agent_logoff(), ast_begin_shutdown(), function_ilink(), handle_hangup(), handle_link_data(), handle_softhangup(), read_agent_config(), rpt(), rpt_call(), softhangup_exec(), start_spying(), startmon(), unload_module(), and zt_handle_event().

01170 {
01171    int res;
01172    ast_mutex_lock(&chan->lock);
01173    res = ast_softhangup_nolock(chan, cause);
01174    ast_mutex_unlock(&chan->lock);
01175    return res;
01176 }

int ast_softhangup_nolock ( struct ast_channel chan,
int  cause 
)

Softly hangup up a channel (no channel lock).

Parameters:
chan channel to be soft-hung-up
cause Ast hangupcause for hangup (see cause.h)

Definition at line 1153 of file channel.c.

References ast_channel::_softhangup, AST_FLAG_BLOCKING, AST_FRAME_NULL, ast_log(), ast_queue_frame(), ast_test_flag, ast_channel::blocker, LOG_DEBUG, ast_channel::name, and option_debug.

Referenced by ast_async_goto(), ast_softhangup(), attempt_transfer(), do_monitor(), oh323_indicate(), sip_indicate(), and skinny_indicate().

01154 {
01155    int res = 0;
01156    struct ast_frame f = { AST_FRAME_NULL };
01157    if (option_debug)
01158       ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name);
01159    /* Inform channel driver that we need to be hung up, if it cares */
01160    chan->_softhangup |= cause;
01161    ast_queue_frame(chan, &f);
01162    /* Interrupt any poll call or such */
01163    if (ast_test_flag(chan, AST_FLAG_BLOCKING))
01164       pthread_kill(chan->blocker, SIGURG);
01165    return res;
01166 }

char* ast_state2str ( int  state  ) 

Gives the string form of a given channel state

Parameters:
state state to get the name of Give a name to a state Returns the text form of the binary state given

Definition at line 422 of file channel.c.

References AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_OFFHOOK, AST_STATE_RESERVED, AST_STATE_RING, AST_STATE_RINGING, and AST_STATE_UP.

Referenced by action_status(), agent_hangup(), ast_request(), ast_serialize_showchan(), ast_setstate(), handle_chanlist(), handle_showchan(), and mgcp_new().

00423 {
00424    /* XXX Not reentrant XXX */
00425    static char localtmp[256];
00426    switch(state) {
00427    case AST_STATE_DOWN:
00428       return "Down";
00429    case AST_STATE_RESERVED:
00430       return "Rsrvd";
00431    case AST_STATE_OFFHOOK:
00432       return "OffHook";
00433    case AST_STATE_DIALING:
00434       return "Dialing";
00435    case AST_STATE_RING:
00436       return "Ring";
00437    case AST_STATE_RINGING:
00438       return "Ringing";
00439    case AST_STATE_UP:
00440       return "Up";
00441    case AST_STATE_BUSY:
00442       return "Busy";
00443    default:
00444       snprintf(localtmp, sizeof(localtmp), "Unknown (%d)\n", state);
00445       return localtmp;
00446    }
00447 }

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 3843 of file channel.c.

References ast_frfree(), ast_read(), ast_tonepair_start(), ast_waitfor(), and ast_channel::generatordata.

Referenced by zapateller_exec().

03844 {
03845    struct ast_frame *f;
03846    int res;
03847 
03848    if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
03849       return res;
03850 
03851    /* Give us some wiggle room */
03852    while(chan->generatordata && (ast_waitfor(chan, 100) >= 0)) {
03853       f = ast_read(chan);
03854       if (f)
03855          ast_frfree(f);
03856       else
03857          return -1;
03858    }
03859    return 0;
03860 }

int ast_tonepair_start ( struct ast_channel chan,
int  freq1,
int  freq2,
int  duration,
int  vol 
)

Start a tone going

Definition at line 3822 of file channel.c.

References ast_activate_generator(), tonepair_def::duration, tonepair_def::freq1, tonepair_def::freq2, tonepair, and tonepair_def::vol.

Referenced by ast_tonepair(), play_dialtone(), play_tone_pair(), rpt_tele_thread(), and sendnoise().

03823 {
03824    struct tonepair_def d = { 0, };
03825 
03826    d.freq1 = freq1;
03827    d.freq2 = freq2;
03828    d.duration = duration;
03829    if (vol < 1)
03830       d.vol = 8192;
03831    else
03832       d.vol = vol;
03833    if (ast_activate_generator(chan, &tonepair, &d))
03834       return -1;
03835    return 0;
03836 }

void ast_tonepair_stop ( struct ast_channel chan  ) 

Stop a tone from playing

Definition at line 3838 of file channel.c.

References ast_deactivate_generator().

Referenced by sendnoise().

03839 {
03840    ast_deactivate_generator(chan);
03841 }

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.

Parameters:
chan current channel
dest destination extension for transfer

Definition at line 2645 of file channel.c.

References ast_check_hangup(), AST_FLAG_ZOMBIE, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_channel::lock, ast_channel::tech, and ast_channel_tech::transfer.

Referenced by transfer_exec().

02646 {
02647    int res = -1;
02648 
02649    /* Stop if we're a zombie or need a soft hangup */
02650    ast_mutex_lock(&chan->lock);
02651    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
02652       if (chan->tech->transfer) {
02653          res = chan->tech->transfer(chan, dest);
02654          if (!res)
02655             res = 1;
02656       } else
02657          res = 0;
02658    }
02659    ast_mutex_unlock(&chan->lock);
02660    return res;
02661 }

char* ast_transfercapability2str ( int  transfercapability  ) 

Gives the string form of a given transfer capability

Parameters:
transfercapability transfercapabilty to get the name of Give a name to a transfercapbility See above Returns the text form of the binary transfer capbility

Definition at line 450 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(), misdn_call(), zt_call(), and zt_new().

00451 {
00452    switch(transfercapability) {
00453    case AST_TRANS_CAP_SPEECH:
00454       return "SPEECH";
00455    case AST_TRANS_CAP_DIGITAL:
00456       return "DIGITAL";
00457    case AST_TRANS_CAP_RESTRICTED_DIGITAL:
00458       return "RESTRICTED_DIGITAL";
00459    case AST_TRANS_CAP_3_1K_AUDIO:
00460       return "3K1AUDIO";
00461    case AST_TRANS_CAP_DIGITAL_W_TONES:
00462       return "DIGITAL_W_TONES";
00463    case AST_TRANS_CAP_VIDEO:
00464       return "VIDEO";
00465    default:
00466       return "UNKNOWN";
00467    }
00468 }

int ast_waitfor ( struct ast_channel chan,
int  ms 
)

Wait for input on a channel.

Parameters:
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).
Returns:
Returns < 0 on failure, 0 if nothing ever arrived, and the # of ms remaining otherwise

Definition at line 1724 of file channel.c.

References ast_waitfor_n().

Referenced by __adsi_transmit_messages(), __ast_request_and_dial(), adsi_careful_send(), agent_ack_sleep(), ast_app_getvoice(), ast_dtmf_stream(), ast_play_and_prepend(), ast_play_and_record_full(), ast_recvtext(), ast_safe_sleep(), ast_safe_sleep_conditional(), ast_tonepair(), ast_waitfordigit(), ast_waitstream(), ast_waitstream_exten(), ast_waitstream_fr(), async_wait(), background_detect_exec(), channel_spy(), conf_exec(), conf_flush(), dictate_exec(), disa_exec(), do_waiting(), echo_exec(), handle_recordfile(), ices_exec(), measurenoise(), modem_call(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), record_exec(), recordthread(), send_tone_burst(), send_waveform_to_channel(), sendurl_exec(), sms_exec(), ss_thread(), wait_for_hangup(), and waitforring_exec().

01725 {
01726    struct ast_channel *chan;
01727    int oldms = ms;
01728 
01729    chan = ast_waitfor_n(&c, 1, &ms);
01730    if (ms < 0) {
01731       if (oldms < 0)
01732          return 0;
01733       else
01734          return -1;
01735    }
01736    return ms;
01737 }

struct ast_channel* ast_waitfor_n ( struct ast_channel **  chan,
int  n,
int *  ms 
) [read]

Waits for input on a group of channels

Wait for input on an array of channels for a given # of milliseconds. Return channel with activity, or NULL if none has activity. time "ms" is modified in-place, if applicable

Definition at line 1719 of file channel.c.

References ast_waitfor_nandfds().

Referenced by ast_feature_request_and_dial(), ast_generic_bridge(), ast_rtp_bridge(), ast_waitfor(), autoservice_run(), iax2_bridge(), misdn_bridge(), rpt(), rpt_exec(), vpb_bridge(), wait_for_answer(), and zt_bridge().

01720 {
01721    return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
01722 }

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 1505 of file channel.c.

References ast_fdisset(), ast_log(), pollfd::events, pollfd::fd, LOG_ERROR, poll(), POLLIN, and POLLPRI.

Referenced by ast_modem_expect(), ast_modem_read_response(), bestdata_read(), dundi_lookup_internal(), and dundi_precache_internal().

01506 {
01507    struct timeval start = { 0 , 0 };
01508    int res;
01509    int x, y;
01510    int winner = -1;
01511    int spoint;
01512    struct pollfd *pfds;
01513    
01514    pfds = alloca(sizeof(struct pollfd) * n);
01515    if (!pfds) {
01516       ast_log(LOG_ERROR, "Out of memory\n");
01517       return -1;
01518    }
01519    if (*ms > 0)
01520       start = ast_tvnow();
01521    y = 0;
01522    for (x=0; x < n; x++) {
01523       if (fds[x] > -1) {
01524          pfds[y].fd = fds[x];
01525          pfds[y].events = POLLIN | POLLPRI;
01526          y++;
01527       }
01528    }
01529    res = poll(pfds, y, *ms);
01530    if (res < 0) {
01531       /* Simulate a timeout if we were interrupted */
01532       if (errno != EINTR)
01533          *ms = -1;
01534       else
01535          *ms = 0;
01536       return -1;
01537    }
01538    spoint = 0;
01539    for (x=0; x < n; x++) {
01540       if (fds[x] > -1) {
01541          if ((res = ast_fdisset(pfds, fds[x], y, &spoint))) {
01542             winner = fds[x];
01543             if (exception) {
01544                if (res & POLLPRI)
01545                   *exception = -1;
01546                else
01547                   *exception = 0;
01548             }
01549          }
01550       }
01551    }
01552    if (*ms > 0) {
01553       *ms -= ast_tvdiff_ms(ast_tvnow(), start);
01554       if (*ms < 0)
01555          *ms = 0;
01556    }
01557    return winner;
01558 }

struct ast_channel* ast_waitfor_nandfds ( struct ast_channel **  chan,
int  n,
int *  fds,
int  nfds,
int *  exception,
int *  outfd,
int *  ms 
) [read]

Waits for activity on a group of channels.

Parameters:
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.
Returns:
Returns the channel with activity, or NULL on error or if an FD came first. If the FD came first, it will be returned in outfd, otherwise, outfd will be -1

Definition at line 1561 of file channel.c.

References ast_channel::_softhangup, ast_clear_flag, ast_do_masquerade(), ast_fdisset(), AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, ast_log(), AST_MAX_FDS, ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, AST_SOFTHANGUP_TIMEOUT, CHECK_BLOCKING, pollfd::events, pollfd::fd, ast_channel::fdno, ast_channel::fds, lock, LOG_ERROR, LOG_WARNING, ast_channel::masq, poll(), POLLIN, POLLPRI, pollfd::revents, and ast_channel::whentohangup.

Referenced by app_exec(), ast_waitfor_n(), ast_waitfordigit_full(), ast_waitstream_full(), conf_run(), find_cache(), and run_agi().

01563 {
01564    struct timeval start = { 0 , 0 };
01565    struct pollfd *pfds;
01566    int res;
01567    long rms;
01568    int x, y, max;
01569    int spoint;
01570    time_t now = 0;
01571    long whentohangup = 0, havewhen = 0, diff;
01572    struct ast_channel *winner = NULL;
01573 
01574    pfds = alloca(sizeof(struct pollfd) * (n * AST_MAX_FDS + nfds));
01575    if (!pfds) {
01576       ast_log(LOG_ERROR, "Out of memory\n");
01577       *outfd = -1;
01578       return NULL;
01579    }
01580 
01581    if (outfd)
01582       *outfd = -99999;
01583    if (exception)
01584       *exception = 0;
01585    
01586    /* Perform any pending masquerades */
01587    for (x=0; x < n; x++) {
01588       ast_mutex_lock(&c[x]->lock);
01589       if (c[x]->whentohangup) {
01590          if (!havewhen)
01591             time(&now);
01592          diff = c[x]->whentohangup - now;
01593          if (!havewhen || (diff < whentohangup)) {
01594             havewhen++;
01595             whentohangup = diff;
01596          }
01597       }
01598       if (c[x]->masq) {
01599          if (ast_do_masquerade(c[x])) {
01600             ast_log(LOG_WARNING, "Masquerade failed\n");
01601             *ms = -1;
01602             ast_mutex_unlock(&c[x]->lock);
01603             return NULL;
01604          }
01605       }
01606       ast_mutex_unlock(&c[x]->lock);
01607    }
01608 
01609    rms = *ms;
01610    
01611    if (havewhen) {
01612       if ((*ms < 0) || (whentohangup * 1000 < *ms)) {
01613          rms =  whentohangup * 1000;
01614       }
01615    }
01616    max = 0;
01617    for (x=0; x < n; x++) {
01618       for (y=0; y< AST_MAX_FDS; y++) {
01619          if (c[x]->fds[y] > -1) {
01620             pfds[max].fd = c[x]->fds[y];
01621             pfds[max].events = POLLIN | POLLPRI;
01622             pfds[max].revents = 0;
01623             max++;
01624          }
01625       }
01626       CHECK_BLOCKING(c[x]);
01627    }
01628    for (x=0; x < nfds; x++) {
01629       if (fds[x] > -1) {
01630          pfds[max].fd = fds[x];
01631          pfds[max].events = POLLIN | POLLPRI;
01632          pfds[max].revents = 0;
01633          max++;
01634       }
01635    }
01636    if (*ms > 0) 
01637       start = ast_tvnow();
01638    
01639    if (sizeof(int) == 4) {
01640       do {
01641          int kbrms = rms;
01642          if (kbrms > 600000)
01643             kbrms = 600000;
01644          res = poll(pfds, max, kbrms);
01645          if (!res)
01646             rms -= kbrms;
01647       } while (!res && (rms > 0));
01648    } else {
01649       res = poll(pfds, max, rms);
01650    }
01651    
01652    if (res < 0) {
01653       for (x=0; x < n; x++) 
01654          ast_clear_flag(c[x], AST_FLAG_BLOCKING);
01655       /* Simulate a timeout if we were interrupted */
01656       if (errno != EINTR)
01657          *ms = -1;
01658       else {
01659          /* Just an interrupt */
01660 #if 0
01661          *ms = 0;
01662 #endif         
01663       }
01664       return NULL;
01665         } else {
01666          /* If no fds signalled, then timeout. So set ms = 0
01667          since we may not have an exact timeout.
01668       */
01669       if (res == 0)
01670          *ms = 0;
01671    }
01672 
01673    if (havewhen)
01674       time(&now);
01675    spoint = 0;
01676    for (x=0; x < n; x++) {
01677       ast_clear_flag(c[x], AST_FLAG_BLOCKING);
01678       if (havewhen && c[x]->whentohangup && (now > c[x]->whentohangup)) {
01679          c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
01680          if (!winner)
01681             winner = c[x];
01682       }
01683       for (y=0; y < AST_MAX_FDS; y++) {
01684          if (c[x]->fds[y] > -1) {
01685             if ((res = ast_fdisset(pfds, c[x]->fds[y], max, &spoint))) {
01686                if (res & POLLPRI)
01687                   ast_set_flag(c[x], AST_FLAG_EXCEPTION);
01688                else
01689                   ast_clear_flag(c[x], AST_FLAG_EXCEPTION);
01690                c[x]->fdno = y;
01691                winner = c[x];
01692             }
01693          }
01694       }
01695    }
01696    for (x=0; x < nfds; x++) {
01697       if (fds[x] > -1) {
01698          if ((res = ast_fdisset(pfds, fds[x], max, &spoint))) {
01699             if (outfd)
01700                *outfd = fds[x];
01701             if (exception) {  
01702                if (res & POLLPRI) 
01703                   *exception = -1;
01704                else
01705                   *exception = 0;
01706             }
01707             winner = NULL;
01708          }
01709       }  
01710    }
01711    if (*ms > 0) {
01712       *ms -= ast_tvdiff_ms(ast_tvnow(), start);
01713       if (*ms < 0)
01714          *ms = 0;
01715    }
01716    return winner;
01717 }

int ast_waitfordigit ( struct ast_channel c,
int  ms 
)

Waits for a digit

Parameters:
c channel to wait for a digit on
ms how many milliseconds to wait Wait for a digit. Returns <0 on error, 0 on no entry, and the digit on success.

Definition at line 1739 of file channel.c.

References ast_check_hangup(), AST_FLAG_ZOMBIE, AST_FRAME_DTMF, ast_frfree(), ast_read(), ast_test_flag, ast_waitfor(), ast_frame::frametype, result, and ast_frame::subclass.

Referenced by __ast_pbx_run(), _while_exec(), adsi_get_cpeid(), adsi_get_cpeinfo(), adsi_print(), adsi_read_encoded_dtmf(), adsi_transmit_message_full(), advanced_options(), ast_app_dtget(), ast_control_streamfile(), ast_readstring(), ast_record_review(), builtin_atxfer(), chanspy_exec(), cpeid_exec(), dialout(), directory_exec(), forward_message(), get_folder(), ivr_dispatch(), mgcp_ss(), my_getsigstr(), pbx_builtin_waitexten(), play_mailbox_owner(), play_record_review(), read_newoption(), retrydial_exec(), sendnoise(), skinny_ss(), ss_thread(), testclient_exec(), testserver_exec(), vm_execmain(), vm_forwardoptions(), vm_instructions(), vm_options(), vm_tempgreeting(), wait_a_bit(), and wait_our_turn().

01740 {
01741    /* XXX Should I be merged with waitfordigit_full XXX */
01742    struct ast_frame *f;
01743    int result = 0;
01744 
01745    /* Stop if we're a zombie or need a soft hangup */
01746    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 
01747       return -1;
01748 
01749    /* Wait for a digit, no more than ms milliseconds total. */
01750    while(ms && !result) {
01751       ms = ast_waitfor(c, ms);
01752       if (ms < 0) /* Error */
01753          result = -1; 
01754       else if (ms > 0) {
01755          /* Read something */
01756          f = ast_read(c);
01757          if (f) {
01758             if (f->frametype == AST_FRAME_DTMF) 
01759                result = f->subclass;
01760             ast_frfree(f);
01761          } else
01762             result = -1;
01763       }
01764    }
01765    return result;
01766 }

int ast_waitfordigit_full ( struct ast_channel c,
int  ms,
int  audiofd,
int  ctrlfd 
)

Definition at line 1786 of file channel.c.

References ast_check_hangup(), AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_frfree(), ast_log(), ast_read(), ast_test_flag, ast_waitfor_nandfds(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_WARNING, and ast_frame::subclass.

Referenced by ast_readstring_full(), handle_getoption(), and handle_waitfordigit().

01787 {
01788    struct ast_frame *f;
01789    struct ast_channel *rchan;
01790    int outfd;
01791    int res;
01792 
01793    /* Stop if we're a zombie or need a soft hangup */
01794    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 
01795       return -1;
01796    /* Wait for a digit, no more than ms milliseconds total. */
01797    while(ms) {
01798       errno = 0;
01799       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01800       if ((!rchan) && (outfd < 0) && (ms)) { 
01801          if (errno == 0 || errno == EINTR)
01802             continue;
01803          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01804          return -1;
01805       } else if (outfd > -1) {
01806          /* The FD we were watching has something waiting */
01807          return 1;
01808       } else if (rchan) {
01809          f = ast_read(c);
01810          if(!f) {
01811             return -1;
01812          }
01813 
01814          switch(f->frametype) {
01815          case AST_FRAME_DTMF:
01816             res = f->subclass;
01817             ast_frfree(f);
01818             return res;
01819          case AST_FRAME_CONTROL:
01820             switch(f->subclass) {
01821             case AST_CONTROL_HANGUP:
01822                ast_frfree(f);
01823                return -1;
01824             case AST_CONTROL_RINGING:
01825             case AST_CONTROL_ANSWER:
01826                /* Unimportant */
01827                break;
01828             default:
01829                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01830                break;
01831             }
01832             break;
01833          case AST_FRAME_VOICE:
01834             /* Write audio if appropriate */
01835             if (audiofd > -1)
01836                write(audiofd, f->data, f->datalen);
01837          }
01838          /* Ignore */
01839          ast_frfree(f);
01840       }
01841    }
01842    return 0; /* Time is up */
01843 }

struct ast_channel* ast_walk_channel_by_name_prefix_locked ( struct ast_channel chan,
const char *  name,
const int  namelen 
) [read]

Get channel by name prefix (locks channel)

Definition at line 820 of file channel.c.

References channel_find_locked().

00821 {
00822    return channel_find_locked(chan, name, namelen, NULL, NULL);
00823 }

int ast_write ( struct ast_channel chan,
struct ast_frame frame 
)

Write a frame to a channel

Parameters:
chan destination channel of the frame
frame frame that will be written This function writes the given frame to the indicated channel. It returns 0 on success, -1 on failure.

Definition at line 2257 of file channel.c.

References ast_channel::_softhangup, ast_check_hangup(), ast_clear_flag, ast_deactivate_generator(), ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_WRITE_INT, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frame_dump(), AST_FRAME_HTML, AST_FRAME_IAX, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_seekstream(), AST_SOFTHANGUP_DEV, ast_test_flag, ast_translate(), ast_writestream(), CHECK_BLOCKING, ast_frame::data, ast_frame::datalen, do_senddigit(), ast_channel::fout, ast_frame::frametype, ast_channel::generatordata, ast_channel::insmpl, ast_channel::lock, LOG_DTMF, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::name, ast_channel::outsmpl, queue_frame_to_spies(), ast_frame::samples, SEEK_FORCECUR, ast_channel_tech::send_html, ast_channel_tech::send_text, ast_channel::spies, SPY_WRITE, ast_frame::subclass, ast_channel::tech, ast_channel_tech::write, ast_channel_monitor::write_stream, ast_channel_tech::write_video, and ast_channel::writetrans.

Referenced by adsi_careful_send(), agent_write(), ast_dtmf_stream(), ast_generic_bridge(), ast_prod(), ast_readaudio_callback(), ast_readvideo_callback(), ast_rtp_bridge(), ast_write_video(), conf_run(), dictate_exec(), echo_exec(), features_write(), function_ilink(), gen_generate(), handle_link_data(), iax2_bridge(), linear_generator(), milliwatt_generate(), misdn_bridge(), moh_files_generator(), moh_generate(), mp3_exec(), NBScat_exec(), playtones_generator(), rpt(), rpt_call(), rpt_exec(), send_link_dtmf(), send_tone_burst(), send_waveform_to_channel(), silence_generator_generate(), sms_generate(), spy_generate(), tonepair_generator(), wait_for_answer(), and zt_bridge().

02258 {
02259    int res = -1;
02260    struct ast_frame *f = NULL;
02261    /* Stop if we're a zombie or need a soft hangup */
02262    ast_mutex_lock(&chan->lock);
02263    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))  {
02264       ast_mutex_unlock(&chan->lock);
02265       return -1;
02266    }
02267    /* Handle any pending masquerades */
02268    if (chan->masq) {
02269       if (ast_do_masquerade(chan)) {
02270          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
02271          ast_mutex_unlock(&chan->lock);
02272          return -1;
02273       }
02274    }
02275    if (chan->masqr) {
02276       ast_mutex_unlock(&chan->lock);
02277       return 0;
02278    }
02279    if (chan->generatordata) {
02280       if (ast_test_flag(chan, AST_FLAG_WRITE_INT))
02281          ast_deactivate_generator(chan);
02282       else {
02283          ast_mutex_unlock(&chan->lock);
02284          return 0;
02285       }
02286    }
02287    /* High bit prints debugging */
02288    if (chan->fout & 0x80000000)
02289       ast_frame_dump(chan->name, fr, ">>");
02290    CHECK_BLOCKING(chan);
02291    switch(fr->frametype) {
02292    case AST_FRAME_CONTROL:
02293       /* XXX Interpret control frames XXX */
02294       ast_log(LOG_WARNING, "Don't know how to handle control frames yet\n");
02295       break;
02296    case AST_FRAME_DTMF:
02297       ast_clear_flag(chan, AST_FLAG_BLOCKING);
02298       ast_mutex_unlock(&chan->lock);
02299       res = do_senddigit(chan,fr->subclass);
02300       ast_mutex_lock(&chan->lock);
02301       CHECK_BLOCKING(chan);
02302       break;
02303    case AST_FRAME_TEXT:
02304       if (chan->tech->send_text)
02305          res = chan->tech->send_text(chan, (char *) fr->data);
02306       else
02307          res = 0;
02308       break;
02309    case AST_FRAME_HTML:
02310       if (chan->tech->send_html)
02311          res = chan->tech->send_html(chan, fr->subclass, (char *) fr->data, fr->datalen);
02312       else
02313          res = 0;
02314       break;
02315    case AST_FRAME_VIDEO:
02316       /* XXX Handle translation of video codecs one day XXX */
02317       if (chan->tech->write_video)
02318          res = chan->tech->write_video(chan, fr);
02319       else
02320          res = 0;
02321       break;
02322    case AST_FRAME_NULL:
02323    case AST_FRAME_IAX:
02324       /* Ignore these */
02325       res = 0;
02326       break;
02327    default:
02328       if (chan->tech->write) {
02329          f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
02330          if (f) {
02331             if (f->frametype == AST_FRAME_VOICE && chan->spies)
02332                queue_frame_to_spies(chan, f, SPY_WRITE);
02333 
02334             if( chan->monitor && chan->monitor->write_stream &&
02335                   f && ( f->frametype == AST_FRAME_VOICE ) ) {
02336 #ifndef MONITOR_CONSTANT_DELAY
02337                int jump = chan->insmpl - chan->outsmpl - 4 * f->samples;
02338                if (jump >= 0) {
02339                   jump = chan->insmpl - chan->outsmpl;
02340                   if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1)
02341                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
02342                   chan->outsmpl += jump + f->samples;
02343                } else
02344                   chan->outsmpl += f->samples;
02345 #else
02346                int jump = chan->insmpl - chan->outsmpl;
02347                if (jump - MONITOR_DELAY >= 0) {
02348                   if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1)
02349                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
02350                   chan->outsmpl += jump;
02351                } else
02352                   chan->outsmpl += f->samples;
02353 #endif
02354                if (ast_writestream(chan->monitor->write_stream, f) < 0)
02355                   ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
02356             }
02357 
02358             res = chan->tech->write(chan, f);
02359          } else
02360             res = 0;
02361       }
02362    }
02363 
02364    /* It's possible this is a translated frame */
02365    if (f && f->frametype == AST_FRAME_DTMF) {
02366       ast_log(LOG_DTMF, "%s : %c\n", chan->name, f->subclass);
02367    } else if (fr->frametype == AST_FRAME_DTMF) {
02368       ast_log(LOG_DTMF, "%s : %c\n", chan->name, fr->subclass);
02369    }
02370 
02371    if (f && (f != fr))
02372       ast_frfree(f);
02373    ast_clear_flag(chan, AST_FLAG_BLOCKING);
02374    /* Consider a write failure to force a soft hangup */
02375    if (res < 0)
02376       chan->_softhangup |= AST_SOFTHANGUP_DEV;
02377    else {
02378       if ((chan->fout & 0x7fffffff) == 0x7fffffff)
02379          chan->fout &= 0x80000000;
02380       else
02381          chan->fout++;
02382    }
02383    ast_mutex_unlock(&chan->lock);
02384    return res;
02385 }

int ast_write_video ( struct ast_channel chan,
struct ast_frame frame 
)

Write video frame to a channel

Parameters:
chan destination channel of the frame
frame frame that will be written This function writes the given frame to the indicated channel. It returns 1 on success, 0 if not implemented, and -1 on failure.

Definition at line 2246 of file channel.c.

References ast_write(), ast_channel::tech, and ast_channel_tech::write_video.

02247 {
02248    int res;
02249    if (!chan->tech->write_video)
02250       return 0;
02251    res = ast_write(chan, fr);
02252    if (!res)
02253       res = 1;
02254    return res;
02255 }


Generated on Wed Oct 28 15:48:41 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6