#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"

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_channel * | ast_bridged_channel (struct ast_channel *chan) |
| Find bridged channel. | |
| int | ast_call (struct ast_channel *chan, char *addr, int timeout) |
| Make a call. | |
| 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_channel * | ast_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_frame * | ast_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_generator * | ast_channel_start_silence_generator (struct ast_channel *chan) |
| Starts a silence generator on the given channel. | |
| void | ast_channel_stop_silence_generator (struct ast_channel *chan, struct ast_silence_generator *state) |
| Stops a previously-started silence generator on the given channel. | |
| int | ast_channel_supports_html (struct ast_channel *channel) |
| void | ast_channel_undefer_dtmf (struct ast_channel *chan) |
| void | ast_channel_unregister (const struct ast_channel_tech *tech) |
| Unregister a channel technology. | |
| struct ast_channel * | ast_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_channel * | ast_get_channel_by_exten_locked (const char *exten, const char *context) |
| struct ast_channel * | ast_get_channel_by_name_locked (const char *chan) |
| struct ast_channel * | ast_get_channel_by_name_prefix_locked (const char *name, const int namelen) |
| struct ast_channel_tech * | ast_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_frame * | ast_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_channel * | ast_request (const char *type, int format, void *data, int *status) |
| Requests a channel. | |
| struct ast_channel * | ast_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_channel * | ast_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_channel * | ast_waitfor_nandfds (struct ast_channel **chan, int n, int *fds, int nfds, int *exception, int *outfd, int *ms) |
| Waits for activity on a group of channels. | |
| int | ast_waitfordigit (struct ast_channel *c, int ms) |
| int | ast_waitfordigit_full (struct ast_channel *c, int ms, int audiofd, int ctrlfd) |
| struct ast_channel * | ast_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) |
Definition in file channel.h.
| #define AST_ADSI_AVAILABLE (1) |
Definition at line 496 of file channel.h.
Referenced by __adsi_transmit_messages(), and adsi_available().
| #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) |
| #define AST_BRIDGE_DTMF_CHANNEL_0 (1 << 0) |
Report DTMF on channel 0
Definition at line 872 of file channel.h.
Referenced by ast_generic_bridge(), ast_rtp_bridge(), iax2_bridge(), misdn_bridge(), monitor_handle_owned(), set_config_flags(), vpb_bridge(), and zt_bridge().
| #define AST_BRIDGE_DTMF_CHANNEL_1 (1 << 1) |
Report DTMF on channel 1
Definition at line 874 of file channel.h.
Referenced by ast_generic_bridge(), ast_rtp_bridge(), iax2_bridge(), misdn_bridge(), monitor_handle_owned(), set_config_flags(), vpb_bridge(), and zt_bridge().
| #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) |
| #define AST_CHAN_TP_WANTSJITTER (1 << 0) |
| #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_AUTOMON (1 << 4) |
| #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) |
| #define AST_FEATURE_FLAG_NEEDSDTMF (1 << 0) |
| #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) |
if we are blocking
Definition at line 428 of file channel.h.
Referenced by agent_new(), ast_autoservice_stop(), ast_do_masquerade(), ast_hangup(), ast_queue_frame(), ast_sendtext(), ast_serialize_showchan(), ast_softhangup_nolock(), ast_waitfor_nandfds(), ast_write(), handle_showchan(), phone_read(), and zt_read().
| #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) |
if we are a zombie
Definition at line 429 of file channel.h.
Referenced by app_exec(), ast_answer(), ast_call(), ast_channel_bridge(), ast_do_masquerade(), ast_hangup(), ast_indicate(), ast_read(), ast_readstring(), ast_readstring_full(), ast_sendtext(), ast_transfer(), ast_waitfordigit(), ast_waitfordigit_full(), ast_write(), and check_availability().
| #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 |
Max length of an extension
Definition at line 102 of file channel.h.
Referenced by advanced_options(), ast_cdr_init(), ast_cdr_setcid(), ast_cdr_update(), ast_device_state_changed(), ast_extension_state2(), ast_hint_state_changed(), ast_ivr_menu_run_internal(), ast_park_call(), ast_waitstream_exten(), conf_exec(), conf_run(), dial_exec_full(), disa_exec(), do_parking_thread(), dundi_lookup_local(), fillin_process(), find_conf(), forward_message(), get_destination(), gosub_exec(), load_config(), mgcp_ss(), monitor_handle_notowned(), park_exec(), phone_check_exception(), realtime_switch_common(), show_dialplan_helper(), skinny_ss(), ss_thread(), transmit_state_notify(), try_calling(), vm_authenticate(), vmauthenticate(), and wait_for_answer().
| #define AST_MAX_FDS 8 |
Definition at line 122 of file channel.h.
Referenced by agent_read(), ast_channel_alloc(), ast_do_masquerade(), ast_read(), ast_waitfor_nandfds(), do_parking_thread(), restore_channel(), and update_features().
| #define AST_SOFTHANGUP_APPUNLOAD (1 << 4) |
| #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) |
Soft hangup by device
Definition at line 500 of file channel.h.
Referenced by __oh323_update_info(), ast_do_masquerade(), ast_dsp_process(), ast_queue_hangup(), ast_read(), ast_write(), attempt_transfer(), cleanup_connection(), do_monitor(), function_ilink(), handle_link_data(), hangup_connection(), iax2_bridge(), iax2_destroy(), iax2_predestroy(), oh323_indicate(), rpt(), rpt_call(), sip_indicate(), skinny_indicate(), zt_handle_event(), and zt_indicate().
| #define AST_SOFTHANGUP_EXPLICIT (1 << 5) |
Definition at line 505 of file channel.h.
Referenced by __login_exec(), action_hangup(), agent_hangup(), agent_logoff(), handle_hangup(), handle_softhangup(), read_agent_config(), softhangup_exec(), and zt_handle_event().
| #define AST_SOFTHANGUP_SHUTDOWN (1 << 2) |
| #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 | ( | s | ) |
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 | ( | c | ) |
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) |
Definition at line 1187 of file channel.h.
Referenced by agent_new(), ast_hangup(), ast_queue_frame(), ast_rtcp_read(), ast_rtp_read(), ast_sched_del(), and oss_read().
| #define LOAD_OH | ( | oh | ) |
| #define MAX_LANGUAGE 20 |
| typedef unsigned long long ast_group_t |
| enum ast_bridge_result |
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 };
| 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.
| chan | channel to answer This function answers a channel and handles all necessary call setup functions. |
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] |
Find bridged channel.
| chan | Current channel |
Definition at line 3295 of file channel.c.
References ast_channel::_bridge, ast_channel_tech::bridged_channel, and ast_channel::tech.
Referenced by __zt_exception(), agents_show(), ast_channel_masquerade(), attempt_transfer(), chanspy_exec(), check_bridge(), console_transfer(), get_refer_info(), handle_chanlist(), handle_hd_hf(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_refer(), handle_showchan(), mgcp_hangup(), mgcp_ss(), mixmonitor_thread(), process_sdp(), schedule_delivery(), skinny_ss(), socket_read(), ss_thread(), start_spying(), startmon(), zt_handle_event(), and zt_hangup().
03296 { 03297 struct ast_channel *bridged; 03298 bridged = chan->_bridge; 03299 if (bridged && bridged->tech->bridged_channel) 03300 bridged = bridged->tech->bridged_channel(chan, bridged); 03301 return bridged; 03302 }
| int ast_call | ( | struct ast_channel * | chan, | |
| char * | addr, | |||
| int | timeout | |||
| ) |
Make a call.
| chan | which channel to make the call on | |
| addr | destination of the call | |
| timeout | time to wait on for connect Place a call, take no longer than timeout ms. |
Definition at line 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
| 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.
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
| 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.
| chan | channel on which to check for hang up | |
| offset | offset in seconds from current time |
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.
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
| 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
| 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.
| tech | Structure defining channel technology or "type" |
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
| 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.
| 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.
| chan | The channel to generate silence on |
The pointer returned by this function must be preserved and passed to ast_channel_stop_silence_generator when you wish to stop the silence generation.
Definition at line 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.
| chan | The channel to operate on | |
| state | The ast_silence_generator pointer return by a previous call to ast_channel_start_silence_generator. |
Definition at line 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().
| 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.
| tech | Structure defining channel technology or "type" that was previously registered |
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
| 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.
| chan | channel on which to check for hang up This function determines if the channel is being requested to be hung up. |
Definition at line 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 | ) |
Deactive an active generator
Definition at line 1443 of file channel.c.
References ast_clear_flag, AST_FLAG_WRITE_INT, ast_mutex_lock(), ast_mutex_unlock(), ast_settimeout(), ast_channel::generator, ast_channel::generatordata, ast_channel::lock, and ast_generator::release.
Referenced by app_exec(), ast_channel_stop_silence_generator(), ast_openstream_full(), ast_playtones_stop(), ast_quiet_chan(), ast_read(), ast_tonepair_stop(), ast_write(), cb_events(), channel_spy(), dial_exec_full(), generator_force(), local_ast_moh_stop(), milliwatt_exec(), moh_on_off(), and wait_for_answer().
01444 { 01445 ast_mutex_lock(&chan->lock); 01446 if (chan->generatordata) { 01447 if (chan->generator && chan->generator->release) 01448 chan->generator->release(chan, chan->generatordata); 01449 chan->generatordata = NULL; 01450 chan->generator = NULL; 01451 ast_clear_flag(chan, AST_FLAG_WRITE_INT); 01452 ast_settimeout(chan, 0, NULL, NULL); 01453 } 01454 ast_mutex_unlock(&chan->lock); 01455 }
| 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.
| 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] |
Get channel by name (locks channel)
Definition at line 808 of file channel.c.
References channel_find_locked().
Referenced by action_getvar(), action_hangup(), action_redirect(), action_setcdruserfield(), action_setvar(), action_status(), action_timeout(), ast_async_goto_by_name(), change_monitor_action(), get_zap_channel_locked(), handle_channelstatus(), handle_debugchan(), handle_getvariablefull(), handle_hangup(), handle_nodebugchan(), handle_showchan(), handle_softhangup(), pbx_builtin_importvar(), pickup_exec(), start_monitor_action(), and stop_monitor_action().
00809 { 00810 return channel_find_locked(NULL, name, 0, NULL, NULL); 00811 }
| 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.
| name | name of technology to find |
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.
| chan | channel to hang up |
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.
| chan | channel to change the indication | |
| condition | which condition to indicate on the channel |
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 | |||
| ) |
Queue a control frame.
Definition at line 685 of file channel.c.
References AST_FRAME_CONTROL, ast_queue_frame(), and ast_frame::subclass.
Referenced by __oh323_update_info(), ast_pickup_call(), auto_congest(), cb_events(), handle_message(), handle_request_info(), handle_response(), handle_response_invite(), mgcp_call(), nbs_call(), phone_call(), pickup_exec(), send_cause2ast(), setup_rtp_connection(), skinny_call(), update_state(), and vpb_call().
00686 { 00687 struct ast_frame f = { AST_FRAME_CONTROL, }; 00688 f.subclass = control; 00689 return ast_queue_frame(chan, &f); 00690 }
| 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 | ) |
Queue a hangup frame.
Definition at line 673 of file channel.c.
References ast_channel::_softhangup, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), AST_SOFTHANGUP_DEV, and ast_channel::lock.
Referenced by __oh323_update_info(), __sip_autodestruct(), cleanup_connection(), console_hangup(), handle_message(), handle_request_bye(), handle_request_cancel(), handle_request_refer(), handle_response(), handle_response_invite(), hangup_chan(), hangup_connection(), iax2_destroy(), iax2_predestroy(), mgcp_queue_hangup(), misdn_answer(), retrans_pkt(), and zt_handle_event().
00674 { 00675 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP }; 00676 /* Yeah, let's not change a lock-critical value without locking */ 00677 if (!ast_mutex_trylock(&chan->lock)) { 00678 chan->_softhangup |= AST_SOFTHANGUP_DEV; 00679 ast_mutex_unlock(&chan->lock); 00680 } 00681 return ast_queue_frame(chan, &f); 00682 }
| struct ast_frame* ast_read | ( | struct ast_channel * | chan | ) | [read] |
Reads a frame
| 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
| 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
| 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
| chan | channel to act upon | |
| timeout | timeout in milliseconds (0 for infinite wait) |
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.
| 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 |
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.
| 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 |
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.
| chan | channel to wait for | |
| ms | length of time in milliseconds to sleep Waits for a specified amount of time, servicing the channel as required. |
Definition at line 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.
| chan | channel to wait for | |
| ms | length of time in milliseconds to sleep | |
| cond | a function pointer for testing continue condition | |
| data | argument to be passed to the condition test function |
Definition at line 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.
| 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
| 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
| 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 | |||
| ) |
Sets read format on channel chan
| chan | channel to change | |
| format | format to change to Set read format for channel to whichever component of "format" is best. Returns 0 on success, -1 on failure |
Definition at line 2437 of file channel.c.
References ast_channel::rawreadformat, ast_channel::readformat, ast_channel::readtrans, and set_format().
Referenced by __login_exec(), __oh323_update_info(), adsi_transmit_message_full(), agent_call(), alarmreceiver_exec(), ast_app_getvoice(), ast_channel_make_compatible(), ast_do_masquerade(), ast_play_and_prepend(), ast_play_and_record_full(), attempt_reconnect(), background_detect_exec(), chanspy_exec(), conf_run(), dictate_exec(), disa_exec(), do_waiting(), eagi_exec(), echo_exec(), function_ilink(), handle_recordfile(), ices_exec(), measurenoise(), mgcp_rtp_read(), milliwatt_exec(), oh323_rtp_read(), process_sdp(), record_exec(), rpt(), rpt_exec(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), sms_exec(), socket_read(), and update_features().
02438 { 02439 return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat, 02440 &chan->readtrans, 0); 02441 }
| void ast_set_variables | ( | struct ast_channel * | chan, | |
| struct ast_variable * | vars | |||
| ) |
adds a list of channel variables to a channel
| chan | the channel | |
| vars | a linked list of variables |
Definition at line 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 | |||
| ) |
Sets write format on channel chan
| chan | channel to change | |
| format | new format for writing Set write format for channel to whichever compoent of "format" is best. Returns 0 on success, -1 on failure |
Definition at line 2443 of file channel.c.
References ast_channel::rawwriteformat, set_format(), ast_channel::writeformat, and ast_channel::writetrans.
Referenced by __login_exec(), __oh323_update_info(), adsi_transmit_message_full(), agent_call(), alarmreceiver_exec(), ast_channel_make_compatible(), ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_do_masquerade(), ast_openstream_full(), ast_stopstream(), attempt_reconnect(), chanspy_exec(), conf_run(), disa_exec(), echo_exec(), function_ilink(), linear_alloc(), linear_release(), mgcp_rtp_read(), milliwatt_exec(), moh_alloc(), moh_files_release(), moh_release(), mp3_exec(), NBScat_exec(), oh323_rtp_read(), playtones_alloc(), playtones_release(), process_sdp(), rpt(), rpt_exec(), send_waveform_to_channel(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), sms_exec(), socket_read(), tonepair_alloc(), tonepair_release(), and update_features().
02444 { 02445 return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat, 02446 &chan->writetrans, 1); 02447 }
| 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.
| 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 |
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).
| 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
| 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.
| 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
| 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.
| chan | channel to wait on | |
| ms | length of time to wait on the channel Wait for input on a channel for a given # of milliseconds (<0 for indefinite). |
Definition at line 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.
| chan | an array of pointers to channels | |
| n | number of channels that are to be waited upon | |
| fds | an array of fds to wait upon | |
| nfds | the number of fds to wait upon | |
| exception | exception flag | |
| outfd | fd that had activity on it | |
| ms | how long the wait was Big momma function here. Wait for activity on any of the n channels, or any of the nfds file descriptors. |
Definition at line 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
| 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
| 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
| 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 }
1.5.6