#include <unistd.h>
#include <setjmp.h>
#include <sys/poll.h>
#include "asterisk/compat.h"
#include "asterisk/frame.h"
#include "asterisk/sched.h"
#include "asterisk/chanvars.h"
#include "asterisk/config.h"
#include "asterisk/lock.h"
#include "asterisk/cdr.h"
#include "asterisk/utils.h"
#include "asterisk/linkedlists.h"
Include dependency graph for channel.h:
This graph shows which files directly or indirectly include this file:
Go to the source code of this file.
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_CHAN_TP_WANTSJITTER (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_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_SPYING (1 << 7) |
#define | AST_FLAG_WRITE_INT (1 << 2) |
#define | AST_FLAG_ZOMBIE (1 << 4) |
#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 |
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 | |
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) |
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. | |
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) |
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. | |
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. | |
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) |
ast_channel * | ast_get_channel_by_exten_locked (const char *exten, const char *context) |
ast_channel * | ast_get_channel_by_name_locked (const char *chan) |
ast_channel * | ast_get_channel_by_name_prefix_locked (const char *name, const int namelen) |
const 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. | |
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) |
ast_channel * | ast_request (const char *type, int format, void *data, int *status) |
Requests a channel. | |
ast_channel * | ast_request_and_dial (const char *type, int format, void *data, int timeout, int *reason, const char *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. | |
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) |
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) |
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.
|
Definition at line 495 of file channel.h. Referenced by __adsi_transmit_messages(), and adsi_available(). |
|
|
|
Definition at line 496 of file channel.h. Referenced by __adsi_transmit_messages(), mgcp_new(), sip_new(), skinny_new(), and zt_new(). |
|
Definition at line 494 of file channel.h. Referenced by adsi_available(). |
|
Report DTMF on channel 0 Definition at line 871 of file channel.h. Referenced by ast_generic_bridge(), ast_rtp_bridge(), iax2_bridge(), monitor_handle_owned(), set_config_flags(), vpb_bridge(), and zt_bridge(). |
|
Report DTMF on channel 1 Definition at line 873 of file channel.h. Referenced by ast_generic_bridge(), ast_rtp_bridge(), iax2_bridge(), monitor_handle_owned(), set_config_flags(), vpb_bridge(), and zt_bridge(). |
|
Ignore all signal frames except NULL Definition at line 879 of file channel.h. Referenced by ast_generic_bridge(), ast_rtp_bridge(), iax2_bridge(), and monitor_handle_owned(). |
|
Return all voice frames on channel 0 Definition at line 875 of file channel.h. Referenced by do_chanreads(). |
|
Return all voice frames on channel 1 Definition at line 877 of file channel.h. Referenced by do_chanreads(). |
|
Definition at line 491 of file channel.h. Referenced by zt_request(). |
|
|
|
|
|
|
|
Definition at line 422 of file channel.h. Referenced by schedule_delivery(). |
|
Definition at line 106 of file channel.h. Referenced by ast_channel_free(), ast_parse_device_state(), page_exec(), and softhangup_exec(). |
|
|
|
Definition at line 444 of file channel.h. Referenced by dial_exec_full(), and try_calling(). |
|
Definition at line 442 of file channel.h. Referenced by builtin_atxfer(), dial_exec_full(), and try_calling(). |
|
Definition at line 447 of file channel.h. Referenced by feature_exec_app(), load_config(), and set_config_flags(). |
|
Definition at line 448 of file channel.h. Referenced by load_config(), and set_config_flags(). |
|
Definition at line 446 of file channel.h. Referenced by load_config(), and set_config_flags(). |
|
Definition at line 440 of file channel.h. Referenced by ast_bridge_call(), ast_channel_bridge(), and dial_exec_full(). |
|
Definition at line 441 of file channel.h. Referenced by ast_channel_bridge(), dial_exec_full(), park_exec(), and try_calling(). |
|
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(). |
|
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(). |
|
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(). |
|
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(). |
|
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(). |
|
is it in a native bridge Definition at line 433 of file channel.h. Referenced by ast_channel_bridge(), start_spying(), and startmon(). |
|
XXX might also go away XXX is spying on someone Definition at line 432 of file channel.h. Referenced by chanspy_exec(). |
|
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(). |
|
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(). |
|
Definition at line 104 of file channel.h. Referenced by conf_run(), macro_exec(), and try_calling(). |
|
|
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(). |
|
Definition at line 503 of file channel.h. Referenced by __unload_module(), and unload_module(). |
|
Soft hangup for async goto Definition at line 500 of file channel.h. Referenced by __ast_pbx_run(), ast_async_goto(), and macro_exec(). |
|
Soft hangup by device Definition at line 499 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(). |
|
Definition at line 504 of file channel.h. Referenced by action_hangup(), agent_hangup(), agent_logoff(), handle_hangup(), handle_softhangup(), read_agent_config(), softhangup_exec(), and zt_handle_event(). |
|
Definition at line 501 of file channel.h. Referenced by ast_begin_shutdown(). |
|
Definition at line 502 of file channel.h. Referenced by __ast_pbx_run(), ast_check_hangup(), and ast_waitfor_nandfds(). |
|
Definition at line 505 of file channel.h. Referenced by ast_channel_bridge(), ast_generic_bridge(), start_spying(), and startmon(). |
|
|
Definition at line 1189 of file channel.h. Referenced by ast_sendtext(), ast_waitfor_nandfds(), ast_write(), phone_read(), and zt_read(). |
|
Definition at line 1186 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(). |
|
Definition at line 467 of file channel.h. Referenced by ast_pbx_outgoing_exten(). |
|
Definition at line 118 of file channel.h. Referenced by ast_fileexists(), and ast_openvstream(). |
|
|
|
|
|
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 };
|
|
Definition at line 2380 of file channel.c. References ast_channel::_state, 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_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, ast_channel::context, ast_channel::exten, ast_frame::frametype, ast_channel::hangupcause, LOG_NOTICE, LOG_WARNING, ast_channel::priority, and ast_frame::subclass. Referenced by ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_request_and_dial(), and parkandannounce_exec(). 02381 { 02382 int state = 0; 02383 int cause = 0; 02384 struct ast_channel *chan; 02385 struct ast_frame *f; 02386 int res = 0; 02387 02388 chan = ast_request(type, format, data, &cause); 02389 if (chan) { 02390 if (oh) { 02391 if (oh->vars) 02392 ast_set_variables(chan, oh->vars); 02393 if (oh->cid_num && *oh->cid_num && oh->cid_name && *oh->cid_name) 02394 ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num); 02395 if (oh->parent_channel) 02396 ast_channel_inherit_variables(oh->parent_channel, chan); 02397 if (oh->account) 02398 ast_cdr_setaccount(chan, oh->account); 02399 } 02400 ast_set_callerid(chan, cid_num, cid_name, cid_num); 02401 02402 if (!ast_call(chan, data, 0)) { 02403 res = 1; /* in case chan->_state is already AST_STATE_UP */ 02404 while (timeout && (chan->_state != AST_STATE_UP)) { 02405 res = ast_waitfor(chan, timeout); 02406 if (res < 0) { 02407 /* Something not cool, or timed out */ 02408 break; 02409 } 02410 /* If done, break out */ 02411 if (!res) 02412 break; 02413 if (timeout > -1) 02414 timeout = res; 02415 f = ast_read(chan); 02416 if (!f) { 02417 state = AST_CONTROL_HANGUP; 02418 res = 0; 02419 break; 02420 } 02421 if (f->frametype == AST_FRAME_CONTROL) { 02422 if (f->subclass == AST_CONTROL_RINGING) 02423 state = AST_CONTROL_RINGING; 02424 else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) { 02425 state = f->subclass; 02426 ast_frfree(f); 02427 break; 02428 } else if (f->subclass == AST_CONTROL_ANSWER) { 02429 state = f->subclass; 02430 ast_frfree(f); 02431 break; 02432 } else if (f->subclass == AST_CONTROL_PROGRESS) { 02433 /* Ignore */ 02434 } else if (f->subclass == -1) { 02435 /* Ignore -- just stopping indications */ 02436 } else { 02437 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass); 02438 } 02439 } 02440 ast_frfree(f); 02441 } 02442 } else 02443 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data); 02444 } else { 02445 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data); 02446 switch(cause) { 02447 case AST_CAUSE_BUSY: 02448 state = AST_CONTROL_BUSY; 02449 break; 02450 case AST_CAUSE_CONGESTION: 02451 state = AST_CONTROL_CONGESTION; 02452 break; 02453 } 02454 } 02455 if (chan) { 02456 /* Final fixups */ 02457 if (oh) { 02458 if (oh->context && *oh->context) 02459 ast_copy_string(chan->context, oh->context, sizeof(chan->context)); 02460 if (oh->exten && *oh->exten) 02461 ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten)); 02462 if (oh->priority) 02463 chan->priority = oh->priority; 02464 } 02465 if (chan->_state == AST_STATE_UP) 02466 state = AST_CONTROL_ANSWER; 02467 } 02468 if (outstate) 02469 *outstate = state; 02470 if (chan && res <= 0) { 02471 if (!chan->cdr) { 02472 chan->cdr = ast_cdr_alloc(); 02473 if (chan->cdr) 02474 ast_cdr_init(chan->cdr, chan); 02475 } 02476 if (chan->cdr) { 02477 char tmp[256]; 02478 snprintf(tmp, 256, "%s/%s", type, (char *)data); 02479 ast_cdr_setapp(chan->cdr,"Dial",tmp); 02480 ast_cdr_update(chan); 02481 ast_cdr_start(chan->cdr); 02482 ast_cdr_end(chan->cdr); 02483 /* If the cause wasn't handled properly */ 02484 if (ast_cdr_disposition(chan->cdr,chan->hangupcause)) 02485 ast_cdr_failed(chan->cdr); 02486 } else 02487 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 02488 ast_hangup(chan); 02489 chan = NULL; 02490 } 02491 return chan; 02492 }
|
|
|
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 }
|
|
|
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, asthread, autoservice_run(), asent::chan, free, LOG_WARNING, malloc, ast_channel::next, 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 }
|
|
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, asthread, 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 }
|
|
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 }
|
|
Pick the best codec Definition at line 468 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(), mgcp_new(), sip_new(), skinny_new(), and socket_read(). 00469 { 00470 /* This just our opinion, expressed in code. We are asked to choose 00471 the best codec to use, given no information */ 00472 int x; 00473 static int prefs[] = 00474 { 00475 /* Okay, ulaw is used by all telephony equipment, so start with it */ 00476 AST_FORMAT_ULAW, 00477 /* Unless of course, you're a silly European, so then prefer ALAW */ 00478 AST_FORMAT_ALAW, 00479 /* Okay, well, signed linear is easy to translate into other stuff */ 00480 AST_FORMAT_SLINEAR, 00481 /* G.726 is standard ADPCM */ 00482 AST_FORMAT_G726, 00483 /* ADPCM has great sound quality and is still pretty easy to translate */ 00484 AST_FORMAT_ADPCM, 00485 /* Okay, we're down to vocoders now, so pick GSM because it's small and easier to 00486 translate and sounds pretty good */ 00487 AST_FORMAT_GSM, 00488 /* iLBC is not too bad */ 00489 AST_FORMAT_ILBC, 00490 /* Speex is free, but computationally more expensive than GSM */ 00491 AST_FORMAT_SPEEX, 00492 /* Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough 00493 to use it */ 00494 AST_FORMAT_LPC10, 00495 /* G.729a is faster than 723 and slightly less expensive */ 00496 AST_FORMAT_G729A, 00497 /* Down to G.723.1 which is proprietary but at least designed for voice */ 00498 AST_FORMAT_G723_1, 00499 }; 00500 00501 00502 /* Find the first prefered codec in the format given */ 00503 for (x=0; x < (sizeof(prefs) / sizeof(prefs[0]) ); x++) 00504 if (fmts & prefs[x]) 00505 return prefs[x]; 00506 ast_log(LOG_WARNING, "Don't know any of 0x%x formats\n", fmts); 00507 return 0; 00508 }
|
|
Find bridged channel.
Definition at line 3202 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(), 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(). 03203 { 03204 struct ast_channel *bridged; 03205 bridged = chan->_bridge; 03206 if (bridged && bridged->tech->bridged_channel) 03207 bridged = bridged->tech->bridged_channel(chan, bridged); 03208 return bridged; 03209 }
|
|
Make a call.
Definition at line 2558 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(). 02559 { 02560 /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 02561 If the remote end does not answer within the timeout, then do NOT hang up, but 02562 return anyway. */ 02563 int res = -1; 02564 /* Stop if we're a zombie or need a soft hangup */ 02565 ast_mutex_lock(&chan->lock); 02566 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) 02567 if (chan->tech->call) 02568 res = chan->tech->call(chan, addr, timeout); 02569 ast_mutex_unlock(&chan->lock); 02570 return res; 02571 }
|
|
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 }
|
|
Definition at line 407 of file channel.c. References causes. Referenced by __transmit_response(), ast_do_masquerade(), ast_hangup(), dial_exec_full(), and transmit_request_with_auth(). 00408 { 00409 int x; 00410 00411 for (x=0; x < sizeof(causes) / sizeof(causes[0]); x++) 00412 if (causes[x].cause == cause) 00413 return causes[x].desc; 00414 00415 return "Unknown"; 00416 }
|
|
Change channel name.
Definition at line 2811 of file channel.c. References EVENT_FLAG_CALL, manager_event(), ast_channel::name, and ast_channel::uniqueid. 02812 { 02813 char tmp[256]; 02814 ast_copy_string(tmp, chan->name, sizeof(tmp)); 02815 ast_copy_string(chan->name, newname, sizeof(chan->name)); 02816 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", tmp, chan->name, chan->uniqueid); 02817 }
|
|
Create a channel structure.
Definition at line 516 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, 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(), acf_odbc_write(), 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(). 00517 { 00518 struct ast_channel *tmp; 00519 int x; 00520 int flags; 00521 struct varshead *headp; 00522 00523 00524 /* If shutting down, don't allocate any new channels */ 00525 if (shutting_down) { 00526 ast_log(LOG_WARNING, "Channel allocation failed: Refusing due to active shutdown\n"); 00527 return NULL; 00528 } 00529 00530 tmp = malloc(sizeof(struct ast_channel)); 00531 if (!tmp) { 00532 ast_log(LOG_WARNING, "Channel allocation failed: Out of memory\n"); 00533 return NULL; 00534 } 00535 00536 memset(tmp, 0, sizeof(struct ast_channel)); 00537 tmp->sched = sched_context_create(); 00538 if (!tmp->sched) { 00539 ast_log(LOG_WARNING, "Channel allocation failed: Unable to create schedule context\n"); 00540 free(tmp); 00541 return NULL; 00542 } 00543 00544 for (x=0; x<AST_MAX_FDS - 1; x++) 00545 tmp->fds[x] = -1; 00546 00547 #ifdef ZAPTEL_OPTIMIZATIONS 00548 tmp->timingfd = open("/dev/zap/timer", O_RDWR); 00549 if (tmp->timingfd > -1) { 00550 /* Check if timing interface supports new 00551 ping/pong scheme */ 00552 flags = 1; 00553 if (!ioctl(tmp->timingfd, ZT_TIMERPONG, &flags)) 00554 needqueue = 0; 00555 } 00556 #else 00557 tmp->timingfd = -1; 00558 #endif 00559 00560 if (needqueue) { 00561 if (pipe(tmp->alertpipe)) { 00562 ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe!\n"); 00563 free(tmp); 00564 return NULL; 00565 } else { 00566 flags = fcntl(tmp->alertpipe[0], F_GETFL); 00567 fcntl(tmp->alertpipe[0], F_SETFL, flags | O_NONBLOCK); 00568 flags = fcntl(tmp->alertpipe[1], F_GETFL); 00569 fcntl(tmp->alertpipe[1], F_SETFL, flags | O_NONBLOCK); 00570 } 00571 } else 00572 /* Make sure we've got it done right if they don't */ 00573 tmp->alertpipe[0] = tmp->alertpipe[1] = -1; 00574 00575 /* Always watch the alertpipe */ 00576 tmp->fds[AST_MAX_FDS-1] = tmp->alertpipe[0]; 00577 /* And timing pipe */ 00578 tmp->fds[AST_MAX_FDS-2] = tmp->timingfd; 00579 strcpy(tmp->name, "**Unknown**"); 00580 /* Initial state */ 00581 tmp->_state = AST_STATE_DOWN; 00582 tmp->streamid = -1; 00583 tmp->appl = NULL; 00584 tmp->data = NULL; 00585 tmp->fin = global_fin; 00586 tmp->fout = global_fout; 00587 ast_mutex_lock(&uniquelock); 00588 snprintf(tmp->uniqueid, sizeof(tmp->uniqueid), "%li.%d", (long) time(NULL), uniqueint++); 00589 ast_mutex_unlock(&uniquelock); 00590 headp = &tmp->varshead; 00591 ast_mutex_init(&tmp->lock); 00592 AST_LIST_HEAD_INIT_NOLOCK(headp); 00593 strcpy(tmp->context, "default"); 00594 ast_copy_string(tmp->language, defaultlanguage, sizeof(tmp->language)); 00595 strcpy(tmp->exten, "s"); 00596 tmp->priority = 1; 00597 tmp->amaflags = ast_default_amaflags; 00598 ast_copy_string(tmp->accountcode, ast_default_accountcode, sizeof(tmp->accountcode)); 00599 00600 tmp->tech = &null_tech; 00601 00602 ast_mutex_lock(&chlock); 00603 tmp->next = channels; 00604 channels = tmp; 00605 00606 ast_mutex_unlock(&chlock); 00607 return tmp; 00608 }
|
|
Definition at line 3363 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_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::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, 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(). 03365 { 03366 struct ast_channel *who = NULL; 03367 enum ast_bridge_result res = AST_BRIDGE_COMPLETE; 03368 int nativefailed=0; 03369 int firstpass; 03370 int o0nativeformats; 03371 int o1nativeformats; 03372 long time_left_ms=0; 03373 struct timeval nexteventts = { 0, }; 03374 char caller_warning = 0; 03375 char callee_warning = 0; 03376 int to; 03377 03378 if (c0->_bridge) { 03379 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 03380 c0->name, c0->_bridge->name); 03381 return -1; 03382 } 03383 if (c1->_bridge) { 03384 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 03385 c1->name, c1->_bridge->name); 03386 return -1; 03387 } 03388 03389 /* Stop if we're a zombie or need a soft hangup */ 03390 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 03391 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) 03392 return -1; 03393 03394 *fo = NULL; 03395 firstpass = config->firstpass; 03396 config->firstpass = 0; 03397 03398 if (ast_tvzero(config->start_time)) 03399 config->start_time = ast_tvnow(); 03400 time_left_ms = config->timelimit; 03401 03402 caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING); 03403 callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING); 03404 03405 if (config->start_sound && firstpass) { 03406 if (caller_warning) 03407 bridge_playfile(c0, c1, config->start_sound, time_left_ms / 1000); 03408 if (callee_warning) 03409 bridge_playfile(c1, c0, config->start_sound, time_left_ms / 1000); 03410 } 03411 03412 /* Keep track of bridge */ 03413 c0->_bridge = c1; 03414 c1->_bridge = c0; 03415 03416 manager_event(EVENT_FLAG_CALL, "Link", 03417 "Channel1: %s\r\n" 03418 "Channel2: %s\r\n" 03419 "Uniqueid1: %s\r\n" 03420 "Uniqueid2: %s\r\n" 03421 "CallerID1: %s\r\n" 03422 "CallerID2: %s\r\n", 03423 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 03424 03425 o0nativeformats = c0->nativeformats; 03426 o1nativeformats = c1->nativeformats; 03427 03428 if (config->timelimit) { 03429 nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 03430 if (caller_warning || callee_warning) 03431 nexteventts = ast_tvsub(nexteventts, ast_samp2tv(config->play_warning, 1000)); 03432 } 03433 03434 for (/* ever */;;) { 03435 to = -1; 03436 if (config->timelimit) { 03437 struct timeval now; 03438 now = ast_tvnow(); 03439 to = ast_tvdiff_ms(nexteventts, now); 03440 if (to < 0) 03441 to = 0; 03442 time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time); 03443 if (time_left_ms < to) 03444 to = time_left_ms; 03445 03446 if (time_left_ms <= 0) { 03447 if (caller_warning && config->end_sound) 03448 bridge_playfile(c0, c1, config->end_sound, 0); 03449 if (callee_warning && config->end_sound) 03450 bridge_playfile(c1, c0, config->end_sound, 0); 03451 *fo = NULL; 03452 if (who) 03453 *rc = who; 03454 res = 0; 03455 break; 03456 } 03457 03458 if (!to) { 03459 if (time_left_ms >= 5000) { 03460 /* force the time left to round up if appropriate */ 03461 if (caller_warning && config->warning_sound && config->play_warning) 03462 bridge_playfile(c0, c1, config->warning_sound, 03463 (time_left_ms + 500) / 1000); 03464 if (callee_warning && config->warning_sound && config->play_warning) 03465 bridge_playfile(c1, c0, config->warning_sound, 03466 (time_left_ms + 500) / 1000); 03467 } 03468 if (config->warning_freq) { 03469 nexteventts = ast_tvadd(nexteventts, ast_samp2tv(config->warning_freq, 1000)); 03470 } else 03471 nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 03472 } 03473 } 03474 03475 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) { 03476 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 03477 c0->_softhangup = 0; 03478 if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 03479 c1->_softhangup = 0; 03480 c0->_bridge = c1; 03481 c1->_bridge = c0; 03482 ast_log(LOG_DEBUG, "Unbridge signal received. Ending native bridge.\n"); 03483 continue; 03484 } 03485 03486 /* Stop if we're a zombie or need a soft hangup */ 03487 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 03488 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) { 03489 *fo = NULL; 03490 if (who) 03491 *rc = who; 03492 res = 0; 03493 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", 03494 c0->name, c1->name, 03495 ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No", 03496 ast_check_hangup(c0) ? "Yes" : "No", 03497 ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No", 03498 ast_check_hangup(c1) ? "Yes" : "No"); 03499 break; 03500 } 03501 03502 if (c0->tech->bridge && 03503 (config->timelimit == 0) && 03504 (c0->tech->bridge == c1->tech->bridge) && 03505 !nativefailed && !c0->monitor && !c1->monitor && 03506 !c0->spies && !c1->spies && !ast_test_flag(&(config->features_callee),AST_FEATURE_REDIRECT) && 03507 !ast_test_flag(&(config->features_caller),AST_FEATURE_REDIRECT) ) { 03508 /* Looks like they share a bridge method and nothing else is in the way */ 03509 if (option_verbose > 2) 03510 ast_verbose(VERBOSE_PREFIX_3 "Attempting native bridge of %s and %s\n", c0->name, c1->name); 03511 ast_set_flag(c0, AST_FLAG_NBRIDGE); 03512 ast_set_flag(c1, AST_FLAG_NBRIDGE); 03513 if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, to)) == AST_BRIDGE_COMPLETE) { 03514 manager_event(EVENT_FLAG_CALL, "Unlink", 03515 "Channel1: %s\r\n" 03516 "Channel2: %s\r\n" 03517 "Uniqueid1: %s\r\n" 03518 "Uniqueid2: %s\r\n" 03519 "CallerID1: %s\r\n" 03520 "CallerID2: %s\r\n", 03521 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 03522 ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name); 03523 03524 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 03525 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 03526 03527 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 03528 continue; 03529 03530 c0->_bridge = NULL; 03531 c1->_bridge = NULL; 03532 03533 return res; 03534 } else { 03535 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 03536 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 03537 } 03538 switch (res) { 03539 case AST_BRIDGE_RETRY: 03540 continue; 03541 default: 03542 ast_log(LOG_WARNING, "Private bridge between %s and %s failed\n", c0->name, c1->name); 03543 /* fallthrough */ 03544 case AST_BRIDGE_FAILED_NOWARN: 03545 nativefailed++; 03546 break; 03547 } 03548 } 03549 03550 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) || 03551 (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) && 03552 !(c0->generator || c1->generator)) { 03553 if (ast_channel_make_compatible(c0, c1)) { 03554 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name); 03555 manager_event(EVENT_FLAG_CALL, "Unlink", 03556 "Channel1: %s\r\n" 03557 "Channel2: %s\r\n" 03558 "Uniqueid1: %s\r\n" 03559 "Uniqueid2: %s\r\n" 03560 "CallerID1: %s\r\n" 03561 "CallerID2: %s\r\n", 03562 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 03563 return AST_BRIDGE_FAILED; 03564 } 03565 o0nativeformats = c0->nativeformats; 03566 o1nativeformats = c1->nativeformats; 03567 } 03568 res = ast_generic_bridge(c0, c1, config, fo, rc, nexteventts); 03569 if (res != AST_BRIDGE_RETRY) 03570 break; 03571 } 03572 03573 c0->_bridge = NULL; 03574 c1->_bridge = NULL; 03575 03576 manager_event(EVENT_FLAG_CALL, "Unlink", 03577 "Channel1: %s\r\n" 03578 "Channel2: %s\r\n" 03579 "Uniqueid1: %s\r\n" 03580 "Uniqueid2: %s\r\n" 03581 "CallerID1: %s\r\n" 03582 "CallerID2: %s\r\n", 03583 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 03584 ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name); 03585 03586 return res; 03587 }
|
|
Compare a offset with the settings of when to hang a channel up.
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 }
|
|
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 690 of file channel.c. References AST_FLAG_DEFER_DTMF, ast_set_flag, and ast_test_flag. Referenced by __adsi_transmit_messages(), and find_cache(). 00691 { 00692 int pre = 0; 00693 00694 if (chan) { 00695 pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF); 00696 ast_set_flag(chan, AST_FLAG_DEFER_DTMF); 00697 } 00698 return pre; 00699 }
|
|
Free a channel structure.
Definition at line 878 of file channel.c. References ast_channel::alertpipe, 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_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 acf_odbc_write(), agent_cleanup(), agent_new(), ast_do_masquerade(), ast_hangup(), ast_pbx_outgoing_cdr_failed(), local_new(), sendmail(), and sendpage(). 00879 { 00880 struct ast_channel *last=NULL, *cur; 00881 int fd; 00882 struct ast_var_t *vardata; 00883 struct ast_frame *f, *fp; 00884 struct varshead *headp; 00885 char name[AST_CHANNEL_NAME]; 00886 00887 headp=&chan->varshead; 00888 00889 ast_mutex_lock(&chlock); 00890 cur = channels; 00891 while(cur) { 00892 if (cur == chan) { 00893 if (last) 00894 last->next = cur->next; 00895 else 00896 channels = cur->next; 00897 break; 00898 } 00899 last = cur; 00900 cur = cur->next; 00901 } 00902 if (!cur) 00903 ast_log(LOG_WARNING, "Unable to find channel in list\n"); 00904 else { 00905 /* Lock and unlock the channel just to be sure nobody 00906 has it locked still */ 00907 ast_mutex_lock(&cur->lock); 00908 ast_mutex_unlock(&cur->lock); 00909 } 00910 if (chan->tech_pvt) { 00911 ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name); 00912 free(chan->tech_pvt); 00913 } 00914 00915 if (chan->sched) 00916 sched_context_destroy(chan->sched); 00917 00918 ast_copy_string(name, chan->name, sizeof(name)); 00919 00920 /* Stop monitoring */ 00921 if (chan->monitor) { 00922 chan->monitor->stop( chan, 0 ); 00923 } 00924 00925 /* If there is native format music-on-hold state, free it */ 00926 if(chan->music_state) 00927 ast_moh_cleanup(chan); 00928 00929 /* Free translatosr */ 00930 if (chan->readtrans) 00931 ast_translator_free_path(chan->readtrans); 00932 if (chan->writetrans) 00933 ast_translator_free_path(chan->writetrans); 00934 if (chan->pbx) 00935 ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name); 00936 free_cid(&chan->cid); 00937 ast_mutex_destroy(&chan->lock); 00938 /* Close pipes if appropriate */ 00939 if ((fd = chan->alertpipe[0]) > -1) 00940 close(fd); 00941 if ((fd = chan->alertpipe[1]) > -1) 00942 close(fd); 00943 if ((fd = chan->timingfd) > -1) 00944 close(fd); 00945 f = chan->readq; 00946 chan->readq = NULL; 00947 while(f) { 00948 fp = f; 00949 f = f->next; 00950 ast_frfree(fp); 00951 } 00952 00953 /* loop over the variables list, freeing all data and deleting list items */ 00954 /* no need to lock the list, as the channel is already locked */ 00955 00956 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries))) 00957 ast_var_delete(vardata); 00958 00959 free(chan); 00960 ast_mutex_unlock(&chlock); 00961 00962 ast_device_state_changed_literal(name); 00963 }
|
|
Inherits channel variable from parent to child channel.
Definition at line 2819 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(). 02820 { 02821 struct ast_var_t *current, *newvar; 02822 char *varname; 02823 02824 AST_LIST_TRAVERSE(&parent->varshead, current, entries) { 02825 int vartype = 0; 02826 02827 varname = ast_var_full_name(current); 02828 if (!varname) 02829 continue; 02830 02831 if (varname[0] == '_') { 02832 vartype = 1; 02833 if (varname[1] == '_') 02834 vartype = 2; 02835 } 02836 02837 switch (vartype) { 02838 case 1: 02839 newvar = ast_var_assign(&varname[1], ast_var_value(current)); 02840 if (newvar) { 02841 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 02842 if (option_debug) 02843 ast_log(LOG_DEBUG, "Copying soft-transferable variable %s.\n", ast_var_name(newvar)); 02844 } 02845 break; 02846 case 2: 02847 newvar = ast_var_assign(ast_var_full_name(current), ast_var_value(current)); 02848 if (newvar) { 02849 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 02850 if (option_debug) 02851 ast_log(LOG_DEBUG, "Copying hard-transferable variable %s.\n", ast_var_name(newvar)); 02852 } 02853 break; 02854 default: 02855 if (option_debug) 02856 ast_log(LOG_DEBUG, "Not copying variable %s.\n", ast_var_name(current)); 02857 break; 02858 } 02859 } 02860 }
|
|
Definition at line 2697 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, and option_transcode_slin. Referenced by ast_channel_bridge(), builtin_atxfer(), dial_exec_full(), park_exec(), try_calling(), and wait_for_answer(). 02698 { 02699 int src; 02700 int dst; 02701 02702 /* Set up translation from the chan to the peer */ 02703 src = chan->nativeformats; 02704 dst = peer->nativeformats; 02705 if (ast_translator_best_choice(&dst, &src) < 0) { 02706 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, src, peer->name, dst); 02707 return -1; 02708 } 02709 02710 /* if the best path is not 'pass through', then 02711 transcoding is needed; if desired, force transcode path 02712 to use SLINEAR between channels */ 02713 if ((src != dst) && option_transcode_slin) 02714 dst = AST_FORMAT_SLINEAR; 02715 if (ast_set_read_format(chan, dst) < 0) { 02716 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, dst); 02717 return -1; 02718 } 02719 if (ast_set_write_format(peer, dst) < 0) { 02720 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, dst); 02721 return -1; 02722 } 02723 02724 /* Set up translation from the peer to the chan */ 02725 src = peer->nativeformats; 02726 dst = chan->nativeformats; 02727 if (ast_translator_best_choice(&dst, &src) < 0) { 02728 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, src, chan->name, dst); 02729 return -1; 02730 } 02731 /* if the best path is not 'pass through', then 02732 transcoding is needed; if desired, force transcode path 02733 to use SLINEAR between channels */ 02734 if ((src != dst) && option_transcode_slin) 02735 dst = AST_FORMAT_SLINEAR; 02736 if (ast_set_read_format(peer, dst) < 0) { 02737 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, dst); 02738 return -1; 02739 } 02740 if (ast_set_write_format(chan, dst) < 0) { 02741 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, dst); 02742 return -1; 02743 } 02744 return 0; 02745 }
|
|
Definition at line 2747 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(). 02748 { 02749 struct ast_frame null = { AST_FRAME_NULL, }; 02750 int res = -1; 02751 struct ast_channel *final_orig = original, *final_clone = clone; 02752 02753 ast_mutex_lock(&original->lock); 02754 while(ast_mutex_trylock(&clone->lock)) { 02755 ast_mutex_unlock(&original->lock); 02756 usleep(1); 02757 ast_mutex_lock(&original->lock); 02758 } 02759 02760 /* each of these channels may be sitting behind a channel proxy (i.e. chan_agent) 02761 and if so, we don't really want to masquerade it, but its proxy */ 02762 if (original->_bridge && (original->_bridge != ast_bridged_channel(original))) 02763 final_orig = original->_bridge; 02764 02765 if (clone->_bridge && (clone->_bridge != ast_bridged_channel(clone))) 02766 final_clone = clone->_bridge; 02767 02768 if ((final_orig != original) || (final_clone != clone)) { 02769 ast_mutex_lock(&final_orig->lock); 02770 while(ast_mutex_trylock(&final_clone->lock)) { 02771 ast_mutex_unlock(&final_orig->lock); 02772 usleep(1); 02773 ast_mutex_lock(&final_orig->lock); 02774 } 02775 ast_mutex_unlock(&clone->lock); 02776 ast_mutex_unlock(&original->lock); 02777 original = final_orig; 02778 clone = final_clone; 02779 } 02780 02781 if (original == clone) { 02782 ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name); 02783 ast_mutex_unlock(&clone->lock); 02784 ast_mutex_unlock(&original->lock); 02785 return -1; 02786 } 02787 02788 ast_log(LOG_DEBUG, "Planning to masquerade channel %s into the structure of %s\n", 02789 clone->name, original->name); 02790 if (original->masq) { 02791 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 02792 original->masq->name, original->name); 02793 } else if (clone->masqr) { 02794 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 02795 clone->name, clone->masqr->name); 02796 } else { 02797 original->masq = clone; 02798 clone->masqr = original; 02799 ast_queue_frame(original, &null); 02800 ast_queue_frame(clone, &null); 02801 ast_log(LOG_DEBUG, "Done planning to masquerade channel %s into the structure of %s\n", clone->name, original->name); 02802 res = 0; 02803 } 02804 02805 ast_mutex_unlock(&clone->lock); 02806 ast_mutex_unlock(&original->lock); 02807 02808 return res; 02809 }
|
|
Query the value of an option, optionally blocking until a reply is received Works similarly to setoption except only reads the options. |
|
Register a channel technology (a new channel driver) Called by a channel module to register the kind of channels it supports.
Definition at line 317 of file channel.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), backends, 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 }
|
|
Send HTML or URL on link. Returns 0 on success or -1 on failure Definition at line 2683 of file channel.c. References ast_channel_tech::send_html, and ast_channel::tech. Referenced by agent_sendhtml(), and wait_for_answer(). 02684 { 02685 if (chan->tech->send_html) 02686 return chan->tech->send_html(chan, subclass, data, datalen); 02687 return -1; 02688 }
|
|
Send URL on link. Returns 0 on success or -1 on failure Definition at line 2690 of file channel.c. References AST_HTML_URL. Referenced by dial_exec_full(), sendurl_exec(), and try_calling(). 02691 { 02692 if (chan->tech->send_html) 02693 return chan->tech->send_html(chan, AST_HTML_URL, url, strlen(url) + 1); 02694 return -1; 02695 }
|
|
Definition at line 3590 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(). 03591 { 03592 int res; 03593 03594 if (chan->tech->setoption) { 03595 res = chan->tech->setoption(chan, option, data, datalen); 03596 if (res < 0) 03597 return res; 03598 } else { 03599 errno = ENOSYS; 03600 return -1; 03601 } 03602 if (block) { 03603 /* XXX Implement blocking -- just wait for our option frame reply, discarding 03604 intermediate packets. XXX */ 03605 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 03606 return -1; 03607 } 03608 return 0; 03609 }
|
|
Set when to hang a channel 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 }
|
|
Starts a silence generator on the given channel.
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 4057 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, and option_debug. Referenced by ast_play_and_record_full(), and record_exec(). 04058 { 04059 struct ast_silence_generator *state; 04060 04061 if (!(state = calloc(1, sizeof(*state)))) { 04062 ast_log(LOG_WARNING, "Could not allocate state structure\n"); 04063 return NULL; 04064 } 04065 04066 state->old_write_format = chan->writeformat; 04067 04068 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) { 04069 ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n"); 04070 free(state); 04071 return NULL; 04072 } 04073 04074 ast_activate_generator(chan, &silence_generator, state); 04075 04076 if (option_debug) 04077 ast_log(LOG_DEBUG, "Started silence generator on '%s'\n", chan->name); 04078 04079 return state; 04080 }
|
|
Stops a previously-started silence generator on the given channel.
Definition at line 4082 of file channel.c. References ast_deactivate_generator(), ast_log(), ast_set_write_format(), free, LOG_DEBUG, LOG_ERROR, state::name, ast_silence_generator::old_write_format, and option_debug. Referenced by ast_play_and_record_full(), and record_exec(). 04083 { 04084 if (!state) 04085 return; 04086 04087 ast_deactivate_generator(chan); 04088 04089 if (option_debug) 04090 ast_log(LOG_DEBUG, "Stopped silence generator on '%s'\n", chan->name); 04091 04092 if (ast_set_write_format(chan, state->old_write_format) < 0) 04093 ast_log(LOG_ERROR, "Could not return write format to its original state\n"); 04094 04095 free(state); 04096 }
|
|
Returns 0 if channel does not support HTML or non-zero if it does Definition at line 2676 of file channel.c. Referenced by dial_exec_full(), sendurl_exec(), and try_calling(). 02677 { 02678 if (chan->tech->send_html) 02679 return 1; 02680 return 0; 02681 }
|
|
Undo defer. ast_read will return any dtmf characters that were queued Definition at line 702 of file channel.c. References ast_clear_flag, and AST_FLAG_DEFER_DTMF. Referenced by __adsi_transmit_messages(), find_cache(), and rpt_call(). 00703 { 00704 if (chan) 00705 ast_clear_flag(chan, AST_FLAG_DEFER_DTMF); 00706 }
|
|
Unregister a channel technology.
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) 00359 ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", tech->type); 00360 00361 ast_mutex_lock(&chlock); 00362 00363 chan = backends; 00364 while (chan) { 00365 if (chan->tech == tech) { 00366 if (last) 00367 last->next = chan->next; 00368 else 00369 backends = backends->next; 00370 free(chan); 00371 ast_mutex_unlock(&chlock); 00372 00373 if (option_verbose > 1) 00374 ast_verbose( VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", tech->type); 00375 00376 return; 00377 } 00378 last = chan; 00379 chan = chan->next; 00380 } 00381 00382 ast_mutex_unlock(&chlock); 00383 }
|
|
Definition at line 794 of file channel.c. References channel_find_locked(). Referenced by action_status(), ast_app_group_get_count(), ast_app_group_match_get_count(), ast_pickup_call(), complete_ch_helper(), conf_exec(), group_show_channels(), handle_chanlist(), handle_debugchan(), handle_nodebugchan(), local_channel_walk(), moh_on_off(), and softhangup_exec(). 00795 { 00796 return channel_find_locked(prev, NULL, 0, NULL, NULL); 00797 }
|
|
Check to see if a channel is needing hang 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 app_exec(), ast_answer(), ast_call(), 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(), handle_sendimage(), iax2_bridge(), rpt(), rpt_exec(), vpb_bridge(), 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 }
|
|
Deactive an active generator Definition at line 1390 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(), channel_spy(), dial_exec_full(), generator_force(), local_ast_moh_stop(), milliwatt_exec(), moh_on_off(), and wait_for_answer(). 01391 { 01392 ast_mutex_lock(&chan->lock); 01393 if (chan->generatordata) { 01394 if (chan->generator && chan->generator->release) 01395 chan->generator->release(chan, chan->generatordata); 01396 chan->generatordata = NULL; 01397 chan->generator = NULL; 01398 ast_clear_flag(chan, AST_FLAG_WRITE_INT); 01399 ast_settimeout(chan, 0, NULL, NULL); 01400 } 01401 ast_mutex_unlock(&chan->lock); 01402 }
|
|
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.
Definition at line 2895 of file channel.c. References ast_channel::_softhangup, ast_channel::_state, ast_channel::adsicpe, ast_channel::alertpipe, ast_cause2str(), ast_channel_free(), ast_copy_flags, AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, AST_FLAG_ZOMBIE, AST_FRAME_NULL, AST_LIST_HEAD_INIT_NOLOCK, 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::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::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, t, ast_channel::tech, ast_channel::tech_pvt, ast_channel::timingfd, ast_channel::type, ast_channel::uniqueid, ast_channel::varshead, 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(). 02896 { 02897 int x,i; 02898 int res=0; 02899 int origstate; 02900 struct ast_frame *cur, *prev; 02901 const struct ast_channel_tech *t; 02902 void *t_pvt; 02903 struct ast_callerid tmpcid; 02904 struct ast_channel *clone = original->masq; 02905 int rformat = original->readformat; 02906 int wformat = original->writeformat; 02907 char newn[100]; 02908 char orig[100]; 02909 char masqn[100]; 02910 char zombn[100]; 02911 02912 if (option_debug > 3) 02913 ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n", 02914 clone->name, clone->_state, original->name, original->_state); 02915 02916 /* XXX This is a seriously wacked out operation. We're essentially putting the guts of 02917 the clone channel into the original channel. Start by killing off the original 02918 channel's backend. I'm not sure we're going to keep this function, because 02919 while the features are nice, the cost is very high in terms of pure nastiness. XXX */ 02920 02921 /* We need the clone's lock, too */ 02922 ast_mutex_lock(&clone->lock); 02923 02924 ast_log(LOG_DEBUG, "Got clone lock for masquerade on '%s' at %p\n", clone->name, &clone->lock); 02925 02926 /* Having remembered the original read/write formats, we turn off any translation on either 02927 one */ 02928 free_translation(clone); 02929 free_translation(original); 02930 02931 02932 /* Unlink the masquerade */ 02933 original->masq = NULL; 02934 clone->masqr = NULL; 02935 02936 /* Save the original name */ 02937 ast_copy_string(orig, original->name, sizeof(orig)); 02938 /* Save the new name */ 02939 ast_copy_string(newn, clone->name, sizeof(newn)); 02940 /* Create the masq name */ 02941 snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn); 02942 02943 /* Copy the name from the clone channel */ 02944 ast_copy_string(original->name, newn, sizeof(original->name)); 02945 02946 /* Mangle the name of the clone channel */ 02947 ast_copy_string(clone->name, masqn, sizeof(clone->name)); 02948 02949 /* Notify any managers of the change, first the masq then the other */ 02950 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", newn, masqn, clone->uniqueid); 02951 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", orig, newn, original->uniqueid); 02952 02953 /* Swap the technlogies */ 02954 t = original->tech; 02955 original->tech = clone->tech; 02956 clone->tech = t; 02957 02958 t_pvt = original->tech_pvt; 02959 original->tech_pvt = clone->tech_pvt; 02960 clone->tech_pvt = t_pvt; 02961 02962 /* Swap the readq's */ 02963 cur = original->readq; 02964 original->readq = clone->readq; 02965 clone->readq = cur; 02966 02967 /* Swap the alertpipes */ 02968 for (i = 0; i < 2; i++) { 02969 x = original->alertpipe[i]; 02970 original->alertpipe[i] = clone->alertpipe[i]; 02971 clone->alertpipe[i] = x; 02972 } 02973 02974 /* Swap the raw formats */ 02975 x = original->rawreadformat; 02976 original->rawreadformat = clone->rawreadformat; 02977 clone->rawreadformat = x; 02978 x = original->rawwriteformat; 02979 original->rawwriteformat = clone->rawwriteformat; 02980 clone->rawwriteformat = x; 02981 02982 /* Save any pending frames on both sides. Start by counting 02983 * how many we're going to need... */ 02984 prev = NULL; 02985 cur = clone->readq; 02986 x = 0; 02987 while(cur) { 02988 x++; 02989 prev = cur; 02990 cur = cur->next; 02991 } 02992 /* If we had any, prepend them to the ones already in the queue, and 02993 * load up the alertpipe */ 02994 if (prev) { 02995 prev->next = original->readq; 02996 original->readq = clone->readq; 02997 clone->readq = NULL; 02998 if (original->alertpipe[1] > -1) { 02999 for (i = 0; i < x; i++) 03000 write(original->alertpipe[1], &x, sizeof(x)); 03001 } 03002 } 03003 clone->_softhangup = AST_SOFTHANGUP_DEV; 03004 03005 03006 /* And of course, so does our current state. Note we need not 03007 call ast_setstate since the event manager doesn't really consider 03008 these separate. We do this early so that the clone has the proper 03009 state of the original channel. */ 03010 origstate = original->_state; 03011 original->_state = clone->_state; 03012 clone->_state = origstate; 03013 03014 if (clone->tech->fixup){ 03015 res = clone->tech->fixup(original, clone); 03016 if (res) 03017 ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name); 03018 } 03019 03020 /* Start by disconnecting the original's physical side */ 03021 if (clone->tech->hangup) 03022 res = clone->tech->hangup(clone); 03023 if (res) { 03024 ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n"); 03025 ast_mutex_unlock(&clone->lock); 03026 return -1; 03027 } 03028 03029 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig); 03030 /* Mangle the name of the clone channel */ 03031 ast_copy_string(clone->name, zombn, sizeof(clone->name)); 03032 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", masqn, zombn, clone->uniqueid); 03033 03034 /* Update the type. */ 03035 original->type = clone->type; 03036 t_pvt = original->monitor; 03037 original->monitor = clone->monitor; 03038 clone->monitor = t_pvt; 03039 03040 /* Keep the same language. */ 03041 ast_copy_string(original->language, clone->language, sizeof(original->language)); 03042 /* Copy the FD's */ 03043 for (x = 0; x < AST_MAX_FDS; x++) { 03044 original->fds[x] = clone->fds[x]; 03045 } 03046 clone_variables(original, clone); 03047 AST_LIST_HEAD_INIT_NOLOCK(&clone->varshead); 03048 /* Presense of ADSI capable CPE follows clone */ 03049 original->adsicpe = clone->adsicpe; 03050 /* Bridge remains the same */ 03051 /* CDR fields remain the same */ 03052 /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */ 03053 /* Application and data remain the same */ 03054 /* Clone exception becomes real one, as with fdno */ 03055 ast_copy_flags(original, clone, AST_FLAG_EXCEPTION); 03056 original->fdno = clone->fdno; 03057 /* Schedule context remains the same */ 03058 /* Stream stuff stays the same */ 03059 /* Keep the original state. The fixup code will need to work with it most likely */ 03060 03061 /* Just swap the whole structures, nevermind the allocations, they'll work themselves 03062 out. */ 03063 tmpcid = original->cid; 03064 original->cid = clone->cid; 03065 clone->cid = tmpcid; 03066 03067 /* Restore original timing file descriptor */ 03068 original->fds[AST_MAX_FDS - 2] = original->timingfd; 03069 03070 /* Our native formats are different now */ 03071 original->nativeformats = clone->nativeformats; 03072 03073 /* Context, extension, priority, app data, jump table, remain the same */ 03074 /* pvt switches. pbx stays the same, as does next */ 03075 03076 /* Set the write format */ 03077 ast_set_write_format(original, wformat); 03078 03079 /* Set the read format */ 03080 ast_set_read_format(original, rformat); 03081 03082 /* Copy the music class */ 03083 ast_copy_string(original->musicclass, clone->musicclass, sizeof(original->musicclass)); 03084 03085 ast_log(LOG_DEBUG, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat); 03086 03087 /* Okay. Last thing is to let the channel driver know about all this mess, so he 03088 can fix up everything as best as possible */ 03089 if (original->tech->fixup) { 03090 res = original->tech->fixup(clone, original); 03091 if (res) { 03092 ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n", 03093 original->type, original->name); 03094 ast_mutex_unlock(&clone->lock); 03095 return -1; 03096 } 03097 } else 03098 ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)! Bad things may happen.\n", 03099 original->type, original->name); 03100 03101 /* Now, at this point, the "clone" channel is totally F'd up. We mark it as 03102 a zombie so nothing tries to touch it. If it's already been marked as a 03103 zombie, then free it now (since it already is considered invalid). */ 03104 if (ast_test_flag(clone, AST_FLAG_ZOMBIE)) { 03105 ast_log(LOG_DEBUG, "Destroying channel clone '%s'\n", clone->name); 03106 ast_mutex_unlock(&clone->lock); 03107 manager_event(EVENT_FLAG_CALL, "Hangup", 03108 "Channel: %s\r\n" 03109 "Uniqueid: %s\r\n" 03110 "Cause: %d\r\n" 03111 "Cause-txt: %s\r\n", 03112 clone->name, 03113 clone->uniqueid, 03114 clone->hangupcause, 03115 ast_cause2str(clone->hangupcause) 03116 ); 03117 ast_channel_free(clone); 03118 } else { 03119 struct ast_frame null_frame = { AST_FRAME_NULL, }; 03120 ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name); 03121 ast_set_flag(clone, AST_FLAG_ZOMBIE); 03122 ast_queue_frame(clone, &null_frame); 03123 ast_mutex_unlock(&clone->lock); 03124 } 03125 03126 /* Signal any blocker */ 03127 if (ast_test_flag(original, AST_FLAG_BLOCKING)) 03128 pthread_kill(original->blocker, SIGURG); 03129 ast_log(LOG_DEBUG, "Done Masquerading %s (%d)\n", original->name, original->_state); 03130 return 0; 03131 }
|
|
Definition at line 1109 of file channel.h. References pollfd::revents. Referenced by ast_waitfor_n_fd(), ast_waitfor_nandfds(), and do_monitor(). 01110 { 01111 int x; 01112 for (x=start ? *start : 0;x<max;x++) 01113 if (pfds[x].fd == fd) { 01114 if (start) { 01115 if (x==*start) 01116 (*start)++; 01117 } 01118 return pfds[x].revents; 01119 } 01120 return 0; 01121 }
|
|
Definition at line 818 of file channel.c. References channel_find_locked(). Referenced by pickup_exec(). 00819 { 00820 return channel_find_locked(NULL, NULL, 0, context, exten); 00821 }
|
|
Get channel by name (locks channel) Definition at line 800 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(), manager_play_dtmf(), pbx_builtin_importvar(), pickup_exec(), start_monitor_action(), and stop_monitor_action(). 00801 { 00802 return channel_find_locked(NULL, name, 0, NULL, NULL); 00803 }
|
|
Get channel by name prefix (locks channel) Definition at line 806 of file channel.c. References channel_find_locked(). Referenced by ast_parse_device_state(), and mixmonitor_cli(). 00807 { 00808 return channel_find_locked(NULL, name, namelen, NULL, NULL); 00809 }
|
|
Get a channel technology structure by name.
Definition at line 385 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(). 00386 { 00387 struct chanlist *chanls; 00388 00389 if (ast_mutex_lock(&chlock)) { 00390 ast_log(LOG_WARNING, "Unable to lock channel tech list\n"); 00391 return NULL; 00392 } 00393 00394 for (chanls = backends; chanls; chanls = chanls->next) { 00395 if (strcasecmp(name, chanls->tech->type)) 00396 continue; 00397 00398 ast_mutex_unlock(&chlock); 00399 return chanls->tech; 00400 } 00401 00402 ast_mutex_unlock(&chlock); 00403 return NULL; 00404 }
|
|
Definition at line 3747 of file channel.c. References ast_log(), ast_strdupa, copy(), group, LOG_ERROR, LOG_WARNING, and strsep(). Referenced by build_device(), build_gateway(), build_peer(), build_port_config(), build_user(), load_module(), read_agent_config(), and setup_zap(). 03748 { 03749 char *copy; 03750 char *piece; 03751 char *c=NULL; 03752 int start=0, finish=0, x; 03753 ast_group_t group = 0; 03754 03755 copy = ast_strdupa(s); 03756 if (!copy) { 03757 ast_log(LOG_ERROR, "Out of memory\n"); 03758 return 0; 03759 } 03760 c = copy; 03761 03762 while((piece = strsep(&c, ","))) { 03763 if (sscanf(piece, "%d-%d", &start, &finish) == 2) { 03764 /* Range */ 03765 } else if (sscanf(piece, "%d", &start)) { 03766 /* Just one */ 03767 finish = start; 03768 } else { 03769 ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece); 03770 continue; 03771 } 03772 for (x = start; x <= finish; x++) { 03773 if ((x > 63) || (x < 0)) { 03774 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x); 03775 } else 03776 group |= ((ast_group_t) 1 << x); 03777 } 03778 } 03779 return group; 03780 }
|
|
Hang up a channel.
Definition at line 1282 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(), cb_events(), 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(), 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(), release_chan(), 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(). 01283 { 01284 int res = 0; 01285 01286 /* Don't actually hang up a channel that will masquerade as someone else, or 01287 if someone is going to masquerade as us */ 01288 ast_mutex_lock(&chan->lock); 01289 01290 detach_spies(chan); /* get rid of spies */ 01291 01292 if (chan->masq) { 01293 if (ast_do_masquerade(chan)) 01294 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 01295 } 01296 01297 if (chan->masq) { 01298 ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name); 01299 ast_mutex_unlock(&chan->lock); 01300 return 0; 01301 } 01302 /* If this channel is one which will be masqueraded into something, 01303 mark it as a zombie already, so we know to free it later */ 01304 if (chan->masqr) { 01305 ast_set_flag(chan, AST_FLAG_ZOMBIE); 01306 ast_mutex_unlock(&chan->lock); 01307 return 0; 01308 } 01309 free_translation(chan); 01310 if (chan->stream) /* Close audio stream */ 01311 ast_closestream(chan->stream); 01312 if (chan->vstream) /* Close video stream */ 01313 ast_closestream(chan->vstream); 01314 if (chan->sched) { 01315 sched_context_destroy(chan->sched); 01316 chan->sched = NULL; 01317 } 01318 01319 if (chan->generatordata) /* Clear any tone stuff remaining */ 01320 chan->generator->release(chan, chan->generatordata); 01321 chan->generatordata = NULL; 01322 chan->generator = NULL; 01323 if (chan->cdr) { /* End the CDR if it hasn't already */ 01324 ast_cdr_end(chan->cdr); 01325 ast_cdr_detach(chan->cdr); /* Post and Free the CDR */ 01326 chan->cdr = NULL; 01327 } 01328 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) { 01329 ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd " 01330 "is blocked by thread %ld in procedure %s! Expect a failure\n", 01331 (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc); 01332 CRASH; 01333 } 01334 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) { 01335 if (option_debug) 01336 ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name); 01337 if (chan->tech->hangup) 01338 res = chan->tech->hangup(chan); 01339 } else { 01340 if (option_debug) 01341 ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name); 01342 } 01343 01344 ast_mutex_unlock(&chan->lock); 01345 manager_event(EVENT_FLAG_CALL, "Hangup", 01346 "Channel: %s\r\n" 01347 "Uniqueid: %s\r\n" 01348 "Cause: %d\r\n" 01349 "Cause-txt: %s\r\n", 01350 chan->name, 01351 chan->uniqueid, 01352 chan->hangupcause, 01353 ast_cause2str(chan->hangupcause) 01354 ); 01355 ast_channel_free(chan); 01356 return res; 01357 }
|
|
Indicates condition of channel.
Definition at line 2017 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 agent_indicate(), 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(). 02018 { 02019 int res = -1; 02020 02021 ast_mutex_lock(&chan->lock); 02022 /* Stop if we're a zombie or need a soft hangup */ 02023 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 02024 ast_mutex_unlock(&chan->lock); 02025 return -1; 02026 } 02027 if (chan->tech->indicate) 02028 res = chan->tech->indicate(chan, condition); 02029 ast_mutex_unlock(&chan->lock); 02030 if (!chan->tech->indicate || res) { 02031 /* 02032 * Device does not support (that) indication, lets fake 02033 * it by doing our own tone generation. (PM2002) 02034 */ 02035 if (condition >= 0) { 02036 const struct tone_zone_sound *ts = NULL; 02037 switch (condition) { 02038 case AST_CONTROL_RINGING: 02039 ts = ast_get_indication_tone(chan->zone, "ring"); 02040 break; 02041 case AST_CONTROL_BUSY: 02042 ts = ast_get_indication_tone(chan->zone, "busy"); 02043 break; 02044 case AST_CONTROL_CONGESTION: 02045 ts = ast_get_indication_tone(chan->zone, "congestion"); 02046 break; 02047 } 02048 if (ts && ts->data[0]) { 02049 ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition); 02050 ast_playtones_start(chan,0,ts->data, 1); 02051 res = 0; 02052 } else if (condition == AST_CONTROL_PROGRESS) { 02053 /* ast_playtones_stop(chan); */ 02054 } else if (condition == AST_CONTROL_PROCEEDING) { 02055 /* Do nothing, really */ 02056 } else if (condition == AST_CONTROL_HOLD) { 02057 /* Do nothing.... */ 02058 } else if (condition == AST_CONTROL_UNHOLD) { 02059 /* Do nothing.... */ 02060 } else if (condition == AST_CONTROL_VIDUPDATE) { 02061 /* Do nothing.... */ 02062 } else { 02063 /* not handled */ 02064 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name); 02065 res = -1; 02066 } 02067 } 02068 else ast_playtones_stop(chan); 02069 } 02070 return res; 02071 }
|
|
Definition at line 3835 of file channel.c. Referenced by ast_serialize_showchan(), misdn_new(), and print_group(). 03836 { 03837 unsigned int i; 03838 int first=1; 03839 char num[3]; 03840 03841 buf[0] = '\0'; 03842 03843 if (!group) /* Return empty string if no group */ 03844 return(buf); 03845 03846 for (i=0; i<=63; i++) { /* Max group is 63 */ 03847 if (group & ((ast_group_t) 1 << i)) { 03848 if (!first) { 03849 strncat(buf, ", ", buflen); 03850 } else { 03851 first=0; 03852 } 03853 snprintf(num, sizeof(num), "%u", i); 03854 strncat(buf, num, buflen); 03855 } 03856 } 03857 return(buf); 03858 }
|
|
Definition at line 2173 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(). 02174 { 02175 struct ast_frame a = { AST_FRAME_VOICE }; 02176 char nothing[128]; 02177 02178 /* Send an empty audio frame to get things moving */ 02179 if (chan->_state != AST_STATE_UP) { 02180 ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name); 02181 a.subclass = chan->rawwriteformat; 02182 a.data = nothing + AST_FRIENDLY_OFFSET; 02183 a.src = "ast_prod"; 02184 if (ast_write(chan, &a)) 02185 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name); 02186 } 02187 return 0; 02188 }
|
|
Queue a control frame.
Definition at line 682 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(). 00683 { 00684 struct ast_frame f = { AST_FRAME_CONTROL, }; 00685 f.subclass = control; 00686 return ast_queue_frame(chan, &f); 00687 }
|
|
Queue an outgoing frame.
Definition at line 611 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(), misdn_tx2ast_frm(), monitor_handle_owned(), oss_call(), process_sdp(), receive_message(), send_digit(), wakeup_sub(), and zap_queue_frame(). 00612 { 00613 struct ast_frame *f; 00614 struct ast_frame *prev, *cur; 00615 int blah = 1; 00616 int qlen = 0; 00617 00618 /* Build us a copy and free the original one */ 00619 f = ast_frdup(fin); 00620 if (!f) { 00621 ast_log(LOG_WARNING, "Unable to duplicate frame\n"); 00622 return -1; 00623 } 00624 ast_mutex_lock(&chan->lock); 00625 prev = NULL; 00626 cur = chan->readq; 00627 while(cur) { 00628 if ((cur->frametype == AST_FRAME_CONTROL) && (cur->subclass == AST_CONTROL_HANGUP)) { 00629 /* Don't bother actually queueing anything after a hangup */ 00630 ast_frfree(f); 00631 ast_mutex_unlock(&chan->lock); 00632 return 0; 00633 } 00634 prev = cur; 00635 cur = cur->next; 00636 qlen++; 00637 } 00638 /* Allow up to 96 voice frames outstanding, and up to 128 total frames */ 00639 if (((fin->frametype == AST_FRAME_VOICE) && (qlen > 96)) || (qlen > 128)) { 00640 if (fin->frametype != AST_FRAME_VOICE) { 00641 ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name); 00642 CRASH; 00643 } else { 00644 ast_log(LOG_DEBUG, "Dropping voice to exceptionally long queue on %s\n", chan->name); 00645 ast_frfree(f); 00646 ast_mutex_unlock(&chan->lock); 00647 return 0; 00648 } 00649 } 00650 if (prev) 00651 prev->next = f; 00652 else 00653 chan->readq = f; 00654 if (chan->alertpipe[1] > -1) { 00655 if (write(chan->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah)) 00656 ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d (qlen = %d): %s!\n", 00657 chan->name, f->frametype, f->subclass, qlen, strerror(errno)); 00658 #ifdef ZAPTEL_OPTIMIZATIONS 00659 } else if (chan->timingfd > -1) { 00660 ioctl(chan->timingfd, ZT_TIMERPING, &blah); 00661 #endif 00662 } else if (ast_test_flag(chan, AST_FLAG_BLOCKING)) { 00663 pthread_kill(chan->blocker, SIGURG); 00664 } 00665 ast_mutex_unlock(&chan->lock); 00666 return 0; 00667 }
|
|
Queue a hangup frame.
Definition at line 670 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(), hangup_connection(), iax2_destroy(), iax2_predestroy(), mgcp_queue_hangup(), misdn_answer(), release_chan(), retrans_pkt(), and zt_handle_event(). 00671 { 00672 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP }; 00673 /* Yeah, let's not change a lock-critical value without locking */ 00674 if (!ast_mutex_trylock(&chan->lock)) { 00675 chan->_softhangup |= AST_SOFTHANGUP_DEV; 00676 ast_mutex_unlock(&chan->lock); 00677 } 00678 return ast_queue_frame(chan, &f); 00679 }
|
|
Definition at line 1790 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::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(). 01791 { 01792 struct ast_frame *f = NULL; 01793 int blah; 01794 int prestate; 01795 #ifdef ZAPTEL_OPTIMIZATIONS 01796 int (*func)(void *); 01797 void *data; 01798 int res; 01799 #endif 01800 static struct ast_frame null_frame = { 01801 AST_FRAME_NULL, 01802 }; 01803 01804 ast_mutex_lock(&chan->lock); 01805 if (chan->masq) { 01806 if (ast_do_masquerade(chan)) { 01807 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 01808 f = NULL; 01809 } else 01810 f = &null_frame; 01811 ast_mutex_unlock(&chan->lock); 01812 return f; 01813 } 01814 01815 /* Stop if we're a zombie or need a soft hangup */ 01816 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 01817 if (chan->generator) 01818 ast_deactivate_generator(chan); 01819 ast_mutex_unlock(&chan->lock); 01820 return NULL; 01821 } 01822 prestate = chan->_state; 01823 01824 if (!ast_test_flag(chan, AST_FLAG_DEFER_DTMF) && !ast_strlen_zero(chan->dtmfq)) { 01825 /* We have DTMF that has been deferred. Return it now */ 01826 chan->dtmff.frametype = AST_FRAME_DTMF; 01827 chan->dtmff.subclass = chan->dtmfq[0]; 01828 /* Drop first digit */ 01829 memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1); 01830 ast_mutex_unlock(&chan->lock); 01831 return &chan->dtmff; 01832 } 01833 01834 /* Read and ignore anything on the alertpipe, but read only 01835 one sizeof(blah) per frame that we send from it */ 01836 if (chan->alertpipe[0] > -1) { 01837 read(chan->alertpipe[0], &blah, sizeof(blah)); 01838 } 01839 #ifdef ZAPTEL_OPTIMIZATIONS 01840 if ((chan->timingfd > -1) && (chan->fdno == AST_MAX_FDS - 2) && ast_test_flag(chan, AST_FLAG_EXCEPTION)) { 01841 ast_clear_flag(chan, AST_FLAG_EXCEPTION); 01842 blah = -1; 01843 /* IF we can't get event, assume it's an expired as-per the old interface */ 01844 res = ioctl(chan->timingfd, ZT_GETEVENT, &blah); 01845 if (res) 01846 blah = ZT_EVENT_TIMER_EXPIRED; 01847 01848 if (blah == ZT_EVENT_TIMER_PING) { 01849 #if 0 01850 ast_log(LOG_NOTICE, "Oooh, there's a PING!\n"); 01851 #endif 01852 if (!chan->readq || !chan->readq->next) { 01853 /* Acknowledge PONG unless we need it again */ 01854 #if 0 01855 ast_log(LOG_NOTICE, "Sending a PONG!\n"); 01856 #endif 01857 if (ioctl(chan->timingfd, ZT_TIMERPONG, &blah)) { 01858 ast_log(LOG_WARNING, "Failed to pong timer on '%s': %s\n", chan->name, strerror(errno)); 01859 } 01860 } 01861 } else if (blah == ZT_EVENT_TIMER_EXPIRED) { 01862 ioctl(chan->timingfd, ZT_TIMERACK, &blah); 01863 func = chan->timingfunc; 01864 data = chan->timingdata; 01865 ast_mutex_unlock(&chan->lock); 01866 if (func) { 01867 #if 0 01868 ast_log(LOG_DEBUG, "Calling private function\n"); 01869 #endif 01870 func(data); 01871 } else { 01872 blah = 0; 01873 ast_mutex_lock(&chan->lock); 01874 ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah); 01875 chan->timingdata = NULL; 01876 ast_mutex_unlock(&chan->lock); 01877 } 01878 f = &null_frame; 01879 return f; 01880 } else 01881 ast_log(LOG_NOTICE, "No/unknown event '%d' on timer for '%s'?\n", blah, chan->name); 01882 } 01883 #endif 01884 /* Check for pending read queue */ 01885 if (chan->readq) { 01886 f = chan->readq; 01887 chan->readq = f->next; 01888 /* Interpret hangup and return NULL */ 01889 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) { 01890 ast_frfree(f); 01891 f = NULL; 01892 } 01893 } else { 01894 chan->blocker = pthread_self(); 01895 if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) { 01896 if (chan->tech->exception) 01897 f = chan->tech->exception(chan); 01898 else { 01899 ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name); 01900 f = &null_frame; 01901 } 01902 /* Clear the exception flag */ 01903 ast_clear_flag(chan, AST_FLAG_EXCEPTION); 01904 } else { 01905 if (chan->tech->read) 01906 f = chan->tech->read(chan); 01907 else 01908 ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name); 01909 } 01910 } 01911 01912 01913 if (f && (f->frametype == AST_FRAME_VOICE)) { 01914 if (!(f->subclass & chan->nativeformats)) { 01915 /* This frame can't be from the current native formats -- drop it on the 01916 floor */ 01917 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)); 01918 ast_frfree(f); 01919 f = &null_frame; 01920 } else { 01921 if (chan->spies) 01922 queue_frame_to_spies(chan, f, SPY_READ); 01923 01924 if (chan->monitor && chan->monitor->read_stream ) { 01925 #ifndef MONITOR_CONSTANT_DELAY 01926 int jump = chan->outsmpl - chan->insmpl - 4 * f->samples; 01927 if (jump >= 0) { 01928 if (ast_seekstream(chan->monitor->read_stream, jump + f->samples, SEEK_FORCECUR) == -1) 01929 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 01930 chan->insmpl += jump + 4 * f->samples; 01931 } else 01932 chan->insmpl+= f->samples; 01933 #else 01934 int jump = chan->outsmpl - chan->insmpl; 01935 if (jump - MONITOR_DELAY >= 0) { 01936 if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1) 01937 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 01938 chan->insmpl += jump; 01939 } else 01940 chan->insmpl += f->samples; 01941 #endif 01942 if (ast_writestream(chan->monitor->read_stream, f) < 0) 01943 ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n"); 01944 } 01945 if (chan->readtrans) { 01946 f = ast_translate(chan->readtrans, f, 1); 01947 if (!f) 01948 f = &null_frame; 01949 } 01950 } 01951 } 01952 01953 /* Make sure we always return NULL in the future */ 01954 if (!f) { 01955 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01956 if (chan->generator) 01957 ast_deactivate_generator(chan); 01958 /* End the CDR if appropriate */ 01959 if (chan->cdr) 01960 ast_cdr_end(chan->cdr); 01961 } else if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF) && f->frametype == AST_FRAME_DTMF) { 01962 if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2) 01963 chan->dtmfq[strlen(chan->dtmfq)] = f->subclass; 01964 else 01965 ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name); 01966 ast_frfree(f); 01967 f = &null_frame; 01968 } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_ANSWER)) { 01969 if (prestate == AST_STATE_UP) { 01970 ast_log(LOG_DEBUG, "Dropping duplicate answer!\n"); 01971 ast_frfree(f); 01972 f = &null_frame; 01973 } 01974 /* Answer the CDR */ 01975 ast_setstate(chan, AST_STATE_UP); 01976 ast_cdr_answer(chan->cdr); 01977 } 01978 01979 /* Run any generator sitting on the line */ 01980 if (f && (f->frametype == AST_FRAME_VOICE) && chan->generatordata) { 01981 /* Mask generator data temporarily and apply. If there is a timing function, it 01982 will be calling the generator instead */ 01983 void *tmp; 01984 int res; 01985 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples); 01986 01987 if (chan->timingfunc) { 01988 ast_log(LOG_DEBUG, "Generator got voice, switching to phase locked mode\n"); 01989 ast_settimeout(chan, 0, NULL, NULL); 01990 } 01991 tmp = chan->generatordata; 01992 chan->generatordata = NULL; 01993 generate = chan->generator->generate; 01994 res = generate(chan, tmp, f->datalen, f->samples); 01995 chan->generatordata = tmp; 01996 if (res) { 01997 ast_log(LOG_DEBUG, "Auto-deactivating generator\n"); 01998 ast_deactivate_generator(chan); 01999 } 02000 } else if (f && (f->frametype == AST_FRAME_CNG)) { 02001 if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) { 02002 ast_log(LOG_DEBUG, "Generator got CNG, switching to zap timed mode\n"); 02003 ast_settimeout(chan, 160, generator_force, chan); 02004 } 02005 } 02006 /* High bit prints debugging */ 02007 if (chan->fin & 0x80000000) 02008 ast_frame_dump(chan->name, f, "<<"); 02009 if ((chan->fin & 0x7fffffff) == 0x7fffffff) 02010 chan->fin &= 0x80000000; 02011 else 02012 chan->fin++; 02013 ast_mutex_unlock(&chan->lock); 02014 return f; 02015 }
|
|
Definition at line 2593 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(). 02594 { 02595 int pos=0; 02596 int to = ftimeout; 02597 int d; 02598 02599 /* XXX Merge with full version? XXX */ 02600 /* Stop if we're a zombie or need a soft hangup */ 02601 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 02602 return -1; 02603 if (!len) 02604 return -1; 02605 do { 02606 if (c->stream) { 02607 d = ast_waitstream(c, AST_DIGIT_ANY); 02608 ast_stopstream(c); 02609 usleep(1000); 02610 if (!d) 02611 d = ast_waitfordigit(c, to); 02612 } else { 02613 d = ast_waitfordigit(c, to); 02614 } 02615 if (d < 0) 02616 return -1; 02617 if (d == 0) { 02618 s[pos]='\0'; 02619 return 1; 02620 } 02621 if (!strchr(enders, d)) 02622 s[pos++] = d; 02623 if (strchr(enders, d) || (pos >= len)) { 02624 s[pos]='\0'; 02625 return 0; 02626 } 02627 to = timeout; 02628 } while(1); 02629 /* Never reached */ 02630 return 0; 02631 }
|
|
Definition at line 2633 of file channel.c. References ast_check_hangup(), AST_DIGIT_ANY, AST_FLAG_ZOMBIE, ast_stopstream(), ast_test_flag, ast_waitfordigit_full(), and ast_waitstream_full(). Referenced by ast_app_getdata_full(). 02634 { 02635 int pos=0; 02636 int to = ftimeout; 02637 int d; 02638 02639 /* Stop if we're a zombie or need a soft hangup */ 02640 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 02641 return -1; 02642 if (!len) 02643 return -1; 02644 do { 02645 if (c->stream) { 02646 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd); 02647 ast_stopstream(c); 02648 usleep(1000); 02649 if (!d) 02650 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 02651 } else { 02652 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 02653 } 02654 if (d < 0) 02655 return -1; 02656 if (d == 0) { 02657 s[pos]='\0'; 02658 return 1; 02659 } 02660 if (d == 1) { 02661 s[pos]='\0'; 02662 return 2; 02663 } 02664 if (!strchr(enders, d)) 02665 s[pos++] = d; 02666 if (strchr(enders, d) || (pos >= len)) { 02667 s[pos]='\0'; 02668 return 0; 02669 } 02670 to = timeout; 02671 } while(1); 02672 /* Never reached */ 02673 return 0; 02674 }
|
|
Definition at line 2073 of file channel.c. References ast_recvtext(), and free. Referenced by handle_recvchar(). 02074 { 02075 int c; 02076 char *buf = ast_recvtext(chan, timeout); 02077 if (buf == NULL) 02078 return -1; /* error or timeout */ 02079 c = *(unsigned char *)buf; 02080 free(buf); 02081 return c; 02082 }
|
|
Definition at line 2084 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(). 02085 { 02086 int res, done = 0; 02087 char *buf = NULL; 02088 02089 while (!done) { 02090 struct ast_frame *f; 02091 if (ast_check_hangup(chan)) 02092 break; 02093 res = ast_waitfor(chan, timeout); 02094 if (res <= 0) /* timeout or error */ 02095 break; 02096 timeout = res; /* update timeout */ 02097 f = ast_read(chan); 02098 if (f == NULL) 02099 break; /* no frame */ 02100 if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP) 02101 done = 1; /* force a break */ 02102 else if (f->frametype == AST_FRAME_TEXT) { /* what we want */ 02103 buf = strndup((char *) f->data, f->datalen); /* dup and break */ 02104 done = 1; 02105 } 02106 ast_frfree(f); 02107 } 02108 return buf; 02109 }
|
|
Requests a channel.
Definition at line 2499 of file channel.c. References ast_channel::_state, AST_CAUSE_NOSUCHDRIVER, AST_CAUSE_NOTDEFINED, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), 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(), dial_exec_full(), features_alloc(), function_ilink(), ring_entry(), rpt(), rpt_call(), rpt_exec(), rpt_tele_thread(), and wait_for_answer(). 02500 { 02501 struct chanlist *chan; 02502 struct ast_channel *c; 02503 int capabilities; 02504 int fmt; 02505 int res; 02506 int foo; 02507 02508 if (!cause) 02509 cause = &foo; 02510 *cause = AST_CAUSE_NOTDEFINED; 02511 02512 if (ast_mutex_lock(&chlock)) { 02513 ast_log(LOG_WARNING, "Unable to lock channel list\n"); 02514 return NULL; 02515 } 02516 02517 for (chan = backends; chan; chan = chan->next) { 02518 if (strcasecmp(type, chan->tech->type)) 02519 continue; 02520 02521 capabilities = chan->tech->capabilities; 02522 fmt = format; 02523 res = ast_translator_best_choice(&fmt, &capabilities); 02524 if (res < 0) { 02525 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->tech->capabilities, format); 02526 ast_mutex_unlock(&chlock); 02527 return NULL; 02528 } 02529 ast_mutex_unlock(&chlock); 02530 if (!chan->tech->requester) 02531 return NULL; 02532 02533 if (!(c = chan->tech->requester(type, capabilities, data, cause))) 02534 return NULL; 02535 02536 if (c->_state == AST_STATE_DOWN) { 02537 manager_event(EVENT_FLAG_CALL, "Newchannel", 02538 "Channel: %s\r\n" 02539 "State: %s\r\n" 02540 "CallerID: %s\r\n" 02541 "CallerIDName: %s\r\n" 02542 "Uniqueid: %s\r\n", 02543 c->name, ast_state2str(c->_state), 02544 c->cid.cid_num ? c->cid.cid_num : "<unknown>", 02545 c->cid.cid_name ? c->cid.cid_name : "<unknown>", 02546 c->uniqueid); 02547 } 02548 return c; 02549 } 02550 02551 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type); 02552 *cause = AST_CAUSE_NOSUCHDRIVER; 02553 ast_mutex_unlock(&chlock); 02554 02555 return NULL; 02556 }
|
|
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.
Definition at line 2494 of file channel.c. References __ast_request_and_dial(). Referenced by ast_pbx_outgoing_exten(). 02495 { 02496 return __ast_request_and_dial(type, format, data, timeout, outstate, cidnum, cidname, NULL); 02497 }
|
|
Wait for a specied amount of time, looking for hangups.
Definition at line 846 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(). 00847 { 00848 struct ast_frame *f; 00849 while(ms > 0) { 00850 ms = ast_waitfor(chan, ms); 00851 if (ms <0) 00852 return -1; 00853 if (ms > 0) { 00854 f = ast_read(chan); 00855 if (!f) 00856 return -1; 00857 ast_frfree(f); 00858 } 00859 } 00860 return 0; 00861 }
|
|
Wait for a specied amount of time, looking for hangups and a condition argument.
Definition at line 824 of file channel.c. References ast_frfree(), ast_read(), and ast_waitfor(). Referenced by __login_exec(). 00826 { 00827 struct ast_frame *f; 00828 00829 while(ms > 0) { 00830 if( cond && ((*cond)(data) == 0 ) ) 00831 return 0; 00832 ms = ast_waitfor(chan, ms); 00833 if (ms <0) 00834 return -1; 00835 if (ms > 0) { 00836 f = ast_read(chan); 00837 if (!f) 00838 return -1; 00839 ast_frfree(f); 00840 } 00841 } 00842 return 0; 00843 }
|
|
Waits for activity on a group of channels.
Definition at line 1146 of file channel.h. Referenced by do_monitor(), do_parking_thread(), and sound_thread(). 01147 { 01148 #ifdef __linux__ 01149 return select(nfds, rfds, wfds, efds, tvp); 01150 #else 01151 if (tvp) { 01152 struct timeval tv, tvstart, tvend, tvlen; 01153 int res; 01154 01155 tv = *tvp; 01156 gettimeofday(&tvstart, NULL); 01157 res = select(nfds, rfds, wfds, efds, tvp); 01158 gettimeofday(&tvend, NULL); 01159 timersub(&tvend, &tvstart, &tvlen); 01160 timersub(&tv, &tvlen, tvp); 01161 if (tvp->tv_sec < 0 || (tvp->tv_sec == 0 && tvp->tv_usec < 0)) { 01162 tvp->tv_sec = 0; 01163 tvp->tv_usec = 0; 01164 } 01165 return res; 01166 } 01167 else 01168 return select(nfds, rfds, wfds, efds, NULL); 01169 #endif 01170 }
|
|
Definition at line 2168 of file channel.c. References do_senddigit(). Referenced by dial_exec_full(), features_digit(), and manager_play_dtmf(). 02169 { 02170 return do_senddigit(chan, digit); 02171 }
|
|
Definition at line 2111 of file channel.c. References ast_check_hangup(), ast_clear_flag, AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_test_flag, and CHECK_BLOCKING. Referenced by agent_sendtext(), handle_sendtext(), and sendtext_exec(). 02112 { 02113 int res = 0; 02114 /* Stop if we're a zombie or need a soft hangup */ 02115 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) 02116 return -1; 02117 CHECK_BLOCKING(chan); 02118 if (chan->tech->send_text) 02119 res = chan->tech->send_text(chan, text); 02120 ast_clear_flag(chan, AST_FLAG_BLOCKING); 02121 return res; 02122 }
|
|
Definition at line 3133 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(), __oh323_new(), agent_call(), ast_feature_request_and_dial(), ast_iax2_new(), ast_modem_new(), callerid_write(), dial_exec_full(), disa_exec(), features_call(), get_callerid(), handle_setcallerid(), local_call(), lookupcidname_exec(), mgcp_new(), mgcp_ss(), misdn_new(), monitor_handle_notowned(), phone_new(), privacy_exec(), rpt_exec(), setcallerid_exec(), sip_new(), skinny_new(), skinny_ss(), ss_thread(), vpb_new(), wait_for_answer(), zt_new(), and zt_read(). 03134 { 03135 if (callerid) { 03136 if (chan->cid.cid_num) 03137 free(chan->cid.cid_num); 03138 if (ast_strlen_zero(callerid)) 03139 chan->cid.cid_num = NULL; 03140 else 03141 chan->cid.cid_num = strdup(callerid); 03142 } 03143 if (calleridname) { 03144 if (chan->cid.cid_name) 03145 free(chan->cid.cid_name); 03146 if (ast_strlen_zero(calleridname)) 03147 chan->cid.cid_name = NULL; 03148 else 03149 chan->cid.cid_name = strdup(calleridname); 03150 } 03151 if (ani) { 03152 if (chan->cid.cid_ani) 03153 free(chan->cid.cid_ani); 03154 if (ast_strlen_zero(ani)) 03155 chan->cid.cid_ani = NULL; 03156 else 03157 chan->cid.cid_ani = strdup(ani); 03158 } 03159 if (chan->cdr) 03160 ast_cdr_setcid(chan->cdr, chan); 03161 manager_event(EVENT_FLAG_CALL, "Newcallerid", 03162 "Channel: %s\r\n" 03163 "CallerID: %s\r\n" 03164 "CallerIDName: %s\r\n" 03165 "Uniqueid: %s\r\n" 03166 "CID-CallingPres: %d (%s)\r\n", 03167 chan->name, chan->cid.cid_num ? 03168 chan->cid.cid_num : "<Unknown>", 03169 chan->cid.cid_name ? 03170 chan->cid.cid_name : "<Unknown>", 03171 chan->uniqueid, 03172 chan->cid.cid_pres, 03173 ast_describe_caller_presentation(chan->cid.cid_pres) 03174 ); 03175 }
|
|
Definition at line 2368 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(). 02369 { 02370 return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat, 02371 &chan->readtrans, 0); 02372 }
|
|
adds a list of channel variables to a channel
Definition at line 3860 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(). 03861 { 03862 struct ast_variable *cur; 03863 03864 for (cur = vars; cur; cur = cur->next) 03865 pbx_builtin_setvar_helper(chan, cur->name, cur->value); 03866 }
|
|
Definition at line 2374 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(). 02375 { 02376 return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat, 02377 &chan->writetrans, 1); 02378 }
|
|
Change the state of a channel.
Definition at line 3177 of file channel.c. References ast_channel::_state, ast_device_state_changed_literal(), ast_state2str(), AST_STATE_DOWN, 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(). 03178 { 03179 int oldstate = chan->_state; 03180 03181 if (oldstate == state) 03182 return 0; 03183 03184 chan->_state = state; 03185 ast_device_state_changed_literal(chan->name); 03186 manager_event(EVENT_FLAG_CALL, 03187 (oldstate == AST_STATE_DOWN) ? "Newchannel" : "Newstate", 03188 "Channel: %s\r\n" 03189 "State: %s\r\n" 03190 "CallerID: %s\r\n" 03191 "CallerIDName: %s\r\n" 03192 "Uniqueid: %s\r\n", 03193 chan->name, ast_state2str(chan->_state), 03194 chan->cid.cid_num ? chan->cid.cid_num : "<unknown>", 03195 chan->cid.cid_name ? chan->cid.cid_name : "<unknown>", 03196 chan->uniqueid); 03197 03198 return 0; 03199 }
|
|
Definition at line 1715 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(). 01716 { 01717 int res = -1; 01718 #ifdef ZAPTEL_OPTIMIZATIONS 01719 if (c->timingfd > -1) { 01720 if (!func) { 01721 samples = 0; 01722 data = 0; 01723 } 01724 ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples); 01725 res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples); 01726 c->timingfunc = func; 01727 c->timingdata = data; 01728 } 01729 #endif 01730 return res; 01731 }
|
|
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 }
|
|
Softly hangup up a channel.
Definition at line 1130 of file channel.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_softhangup_nolock(), and ast_channel::lock. Referenced by __unload_module(), action_hangup(), agent_hangup(), agent_logoff(), ast_begin_shutdown(), do_monitor(), 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(). 01131 { 01132 int res; 01133 ast_mutex_lock(&chan->lock); 01134 res = ast_softhangup_nolock(chan, cause); 01135 ast_mutex_unlock(&chan->lock); 01136 return res; 01137 }
|
|
Softly hangup up a channel (no channel lock).
Definition at line 1114 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(), oh323_indicate(), sip_indicate(), and skinny_indicate(). 01115 { 01116 int res = 0; 01117 struct ast_frame f = { AST_FRAME_NULL }; 01118 if (option_debug) 01119 ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name); 01120 /* Inform channel driver that we need to be hung up, if it cares */ 01121 chan->_softhangup |= cause; 01122 ast_queue_frame(chan, &f); 01123 /* Interrupt any poll call or such */ 01124 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) 01125 pthread_kill(chan->blocker, SIGURG); 01126 return res; 01127 }
|
|
Definition at line 419 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(). 00420 { 00421 /* XXX Not reentrant XXX */ 00422 static char localtmp[256]; 00423 switch(state) { 00424 case AST_STATE_DOWN: 00425 return "Down"; 00426 case AST_STATE_RESERVED: 00427 return "Rsrvd"; 00428 case AST_STATE_OFFHOOK: 00429 return "OffHook"; 00430 case AST_STATE_DIALING: 00431 return "Dialing"; 00432 case AST_STATE_RING: 00433 return "Ring"; 00434 case AST_STATE_RINGING: 00435 return "Ringing"; 00436 case AST_STATE_UP: 00437 return "Up"; 00438 case AST_STATE_BUSY: 00439 return "Busy"; 00440 default: 00441 snprintf(localtmp, sizeof(localtmp), "Unknown (%d)\n", state); 00442 return localtmp; 00443 } 00444 }
|
|
Play a tone pair for a given amount of time Definition at line 3728 of file channel.c. References ast_frfree(), ast_read(), ast_tonepair_start(), ast_waitfor(), and ast_channel::generatordata. Referenced by zapateller_exec(). 03729 { 03730 struct ast_frame *f; 03731 int res; 03732 03733 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol))) 03734 return res; 03735 03736 /* Give us some wiggle room */ 03737 while(chan->generatordata && (ast_waitfor(chan, 100) >= 0)) { 03738 f = ast_read(chan); 03739 if (f) 03740 ast_frfree(f); 03741 else 03742 return -1; 03743 } 03744 return 0; 03745 }
|
|
Start a tone going Definition at line 3707 of file channel.c. References ast_activate_generator(), tonepair_def::duration, tonepair_def::freq1, tonepair_def::freq2, and tonepair_def::vol. Referenced by ast_tonepair(), play_dialtone(), play_tone_pair(), rpt_tele_thread(), and sendnoise(). 03708 { 03709 struct tonepair_def d = { 0, }; 03710 03711 d.freq1 = freq1; 03712 d.freq2 = freq2; 03713 d.duration = duration; 03714 if (vol < 1) 03715 d.vol = 8192; 03716 else 03717 d.vol = vol; 03718 if (ast_activate_generator(chan, &tonepair, &d)) 03719 return -1; 03720 return 0; 03721 }
|
|
Stop a tone from playing Definition at line 3723 of file channel.c. References ast_deactivate_generator(). Referenced by sendnoise(). 03724 { 03725 ast_deactivate_generator(chan); 03726 }
|
|
Transfer a channel (if supported). Returns -1 on error, 0 if not supported and 1 if supported and requested.
Definition at line 2575 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(). 02576 { 02577 int res = -1; 02578 02579 /* Stop if we're a zombie or need a soft hangup */ 02580 ast_mutex_lock(&chan->lock); 02581 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) { 02582 if (chan->tech->transfer) { 02583 res = chan->tech->transfer(chan, dest); 02584 if (!res) 02585 res = 1; 02586 } else 02587 res = 0; 02588 } 02589 ast_mutex_unlock(&chan->lock); 02590 return res; 02591 }
|
|
Definition at line 447 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(). 00448 { 00449 switch(transfercapability) { 00450 case AST_TRANS_CAP_SPEECH: 00451 return "SPEECH"; 00452 case AST_TRANS_CAP_DIGITAL: 00453 return "DIGITAL"; 00454 case AST_TRANS_CAP_RESTRICTED_DIGITAL: 00455 return "RESTRICTED_DIGITAL"; 00456 case AST_TRANS_CAP_3_1K_AUDIO: 00457 return "3K1AUDIO"; 00458 case AST_TRANS_CAP_DIGITAL_W_TONES: 00459 return "DIGITAL_W_TONES"; 00460 case AST_TRANS_CAP_VIDEO: 00461 return "VIDEO"; 00462 default: 00463 return "UNKNOWN"; 00464 } 00465 }
|
|
Wait for input on a channel.
Definition at line 1671 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(). 01672 { 01673 struct ast_channel *chan; 01674 int oldms = ms; 01675 01676 chan = ast_waitfor_n(&c, 1, &ms); 01677 if (ms < 0) { 01678 if (oldms < 0) 01679 return 0; 01680 else 01681 return -1; 01682 } 01683 return ms; 01684 }
|
|
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 1666 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(). 01667 { 01668 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms); 01669 }
|
|
This version works on fd's only. Be careful with it. Definition at line 1452 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(). 01453 { 01454 struct timeval start = { 0 , 0 }; 01455 int res; 01456 int x, y; 01457 int winner = -1; 01458 int spoint; 01459 struct pollfd *pfds; 01460 01461 pfds = alloca(sizeof(struct pollfd) * n); 01462 if (!pfds) { 01463 ast_log(LOG_ERROR, "Out of memory\n"); 01464 return -1; 01465 } 01466 if (*ms > 0) 01467 start = ast_tvnow(); 01468 y = 0; 01469 for (x=0; x < n; x++) { 01470 if (fds[x] > -1) { 01471 pfds[y].fd = fds[x]; 01472 pfds[y].events = POLLIN | POLLPRI; 01473 y++; 01474 } 01475 } 01476 res = poll(pfds, y, *ms); 01477 if (res < 0) { 01478 /* Simulate a timeout if we were interrupted */ 01479 if (errno != EINTR) 01480 *ms = -1; 01481 else 01482 *ms = 0; 01483 return -1; 01484 } 01485 spoint = 0; 01486 for (x=0; x < n; x++) { 01487 if (fds[x] > -1) { 01488 if ((res = ast_fdisset(pfds, fds[x], y, &spoint))) { 01489 winner = fds[x]; 01490 if (exception) { 01491 if (res & POLLPRI) 01492 *exception = -1; 01493 else 01494 *exception = 0; 01495 } 01496 } 01497 } 01498 } 01499 if (*ms > 0) { 01500 *ms -= ast_tvdiff_ms(ast_tvnow(), start); 01501 if (*ms < 0) 01502 *ms = 0; 01503 } 01504 return winner; 01505 }
|
|
Waits for activity on a group of channels.
Definition at line 1508 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(). 01510 { 01511 struct timeval start = { 0 , 0 }; 01512 struct pollfd *pfds; 01513 int res; 01514 long rms; 01515 int x, y, max; 01516 int spoint; 01517 time_t now = 0; 01518 long whentohangup = 0, havewhen = 0, diff; 01519 struct ast_channel *winner = NULL; 01520 01521 pfds = alloca(sizeof(struct pollfd) * (n * AST_MAX_FDS + nfds)); 01522 if (!pfds) { 01523 ast_log(LOG_ERROR, "Out of memory\n"); 01524 *outfd = -1; 01525 return NULL; 01526 } 01527 01528 if (outfd) 01529 *outfd = -99999; 01530 if (exception) 01531 *exception = 0; 01532 01533 /* Perform any pending masquerades */ 01534 for (x=0; x < n; x++) { 01535 ast_mutex_lock(&c[x]->lock); 01536 if (c[x]->whentohangup) { 01537 if (!havewhen) 01538 time(&now); 01539 diff = c[x]->whentohangup - now; 01540 if (!havewhen || (diff < whentohangup)) { 01541 havewhen++; 01542 whentohangup = diff; 01543 } 01544 } 01545 if (c[x]->masq) { 01546 if (ast_do_masquerade(c[x])) { 01547 ast_log(LOG_WARNING, "Masquerade failed\n"); 01548 *ms = -1; 01549 ast_mutex_unlock(&c[x]->lock); 01550 return NULL; 01551 } 01552 } 01553 ast_mutex_unlock(&c[x]->lock); 01554 } 01555 01556 rms = *ms; 01557 01558 if (havewhen) { 01559 if ((*ms < 0) || (whentohangup * 1000 < *ms)) { 01560 rms = whentohangup * 1000; 01561 } 01562 } 01563 max = 0; 01564 for (x=0; x < n; x++) { 01565 for (y=0; y< AST_MAX_FDS; y++) { 01566 if (c[x]->fds[y] > -1) { 01567 pfds[max].fd = c[x]->fds[y]; 01568 pfds[max].events = POLLIN | POLLPRI; 01569 pfds[max].revents = 0; 01570 max++; 01571 } 01572 } 01573 CHECK_BLOCKING(c[x]); 01574 } 01575 for (x=0; x < nfds; x++) { 01576 if (fds[x] > -1) { 01577 pfds[max].fd = fds[x]; 01578 pfds[max].events = POLLIN | POLLPRI; 01579 pfds[max].revents = 0; 01580 max++; 01581 } 01582 } 01583 if (*ms > 0) 01584 start = ast_tvnow(); 01585 01586 if (sizeof(int) == 4) { 01587 do { 01588 int kbrms = rms; 01589 if (kbrms > 600000) 01590 kbrms = 600000; 01591 res = poll(pfds, max, kbrms); 01592 if (!res) 01593 rms -= kbrms; 01594 } while (!res && (rms > 0)); 01595 } else { 01596 res = poll(pfds, max, rms); 01597 } 01598 01599 if (res < 0) { 01600 for (x=0; x < n; x++) 01601 ast_clear_flag(c[x], AST_FLAG_BLOCKING); 01602 /* Simulate a timeout if we were interrupted */ 01603 if (errno != EINTR) 01604 *ms = -1; 01605 else { 01606 /* Just an interrupt */ 01607 #if 0 01608 *ms = 0; 01609 #endif 01610 } 01611 return NULL; 01612 } else { 01613 /* If no fds signalled, then timeout. So set ms = 0 01614 since we may not have an exact timeout. 01615 */ 01616 if (res == 0) 01617 *ms = 0; 01618 } 01619 01620 if (havewhen) 01621 time(&now); 01622 spoint = 0; 01623 for (x=0; x < n; x++) { 01624 ast_clear_flag(c[x], AST_FLAG_BLOCKING); 01625 if (havewhen && c[x]->whentohangup && (now > c[x]->whentohangup)) { 01626 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 01627 if (!winner) 01628 winner = c[x]; 01629 } 01630 for (y=0; y < AST_MAX_FDS; y++) { 01631 if (c[x]->fds[y] > -1) { 01632 if ((res = ast_fdisset(pfds, c[x]->fds[y], max, &spoint))) { 01633 if (res & POLLPRI) 01634 ast_set_flag(c[x], AST_FLAG_EXCEPTION); 01635 else 01636 ast_clear_flag(c[x], AST_FLAG_EXCEPTION); 01637 c[x]->fdno = y; 01638 winner = c[x]; 01639 } 01640 } 01641 } 01642 } 01643 for (x=0; x < nfds; x++) { 01644 if (fds[x] > -1) { 01645 if ((res = ast_fdisset(pfds, fds[x], max, &spoint))) { 01646 if (outfd) 01647 *outfd = fds[x]; 01648 if (exception) { 01649 if (res & POLLPRI) 01650 *exception = -1; 01651 else 01652 *exception = 0; 01653 } 01654 winner = NULL; 01655 } 01656 } 01657 } 01658 if (*ms > 0) { 01659 *ms -= ast_tvdiff_ms(ast_tvnow(), start); 01660 if (*ms < 0) 01661 *ms = 0; 01662 } 01663 return winner; 01664 }
|
|
Definition at line 1686 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(). 01687 { 01688 /* XXX Should I be merged with waitfordigit_full XXX */ 01689 struct ast_frame *f; 01690 int result = 0; 01691 01692 /* Stop if we're a zombie or need a soft hangup */ 01693 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 01694 return -1; 01695 01696 /* Wait for a digit, no more than ms milliseconds total. */ 01697 while(ms && !result) { 01698 ms = ast_waitfor(c, ms); 01699 if (ms < 0) /* Error */ 01700 result = -1; 01701 else if (ms > 0) { 01702 /* Read something */ 01703 f = ast_read(c); 01704 if (f) { 01705 if (f->frametype == AST_FRAME_DTMF) 01706 result = f->subclass; 01707 ast_frfree(f); 01708 } else 01709 result = -1; 01710 } 01711 } 01712 return result; 01713 }
|
|
Definition at line 1733 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(). 01734 { 01735 struct ast_frame *f; 01736 struct ast_channel *rchan; 01737 int outfd; 01738 int res; 01739 01740 /* Stop if we're a zombie or need a soft hangup */ 01741 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 01742 return -1; 01743 /* Wait for a digit, no more than ms milliseconds total. */ 01744 while(ms) { 01745 errno = 0; 01746 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 01747 if ((!rchan) && (outfd < 0) && (ms)) { 01748 if (errno == 0 || errno == EINTR) 01749 continue; 01750 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 01751 return -1; 01752 } else if (outfd > -1) { 01753 /* The FD we were watching has something waiting */ 01754 return 1; 01755 } else if (rchan) { 01756 f = ast_read(c); 01757 if(!f) { 01758 return -1; 01759 } 01760 01761 switch(f->frametype) { 01762 case AST_FRAME_DTMF: 01763 res = f->subclass; 01764 ast_frfree(f); 01765 return res; 01766 case AST_FRAME_CONTROL: 01767 switch(f->subclass) { 01768 case AST_CONTROL_HANGUP: 01769 ast_frfree(f); 01770 return -1; 01771 case AST_CONTROL_RINGING: 01772 case AST_CONTROL_ANSWER: 01773 /* Unimportant */ 01774 break; 01775 default: 01776 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass); 01777 } 01778 case AST_FRAME_VOICE: 01779 /* Write audio if appropriate */ 01780 if (audiofd > -1) 01781 write(audiofd, f->data, f->datalen); 01782 } 01783 /* Ignore */ 01784 ast_frfree(f); 01785 } 01786 } 01787 return 0; /* Time is up */ 01788 }
|
|
Get channel by name prefix (locks channel) Definition at line 812 of file channel.c. References channel_find_locked(). 00813 { 00814 return channel_find_locked(chan, name, namelen, NULL, NULL); 00815 }
|
|
Definition at line 2201 of file channel.c. References 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_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_frame::frametype, LOG_DTMF, LOG_WARNING, queue_frame_to_spies(), ast_frame::samples, SEEK_FORCECUR, SPY_WRITE, and ast_frame::subclass. 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(). 02202 { 02203 int res = -1; 02204 struct ast_frame *f = NULL; 02205 /* Stop if we're a zombie or need a soft hangup */ 02206 ast_mutex_lock(&chan->lock); 02207 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 02208 ast_mutex_unlock(&chan->lock); 02209 return -1; 02210 } 02211 /* Handle any pending masquerades */ 02212 if (chan->masq) { 02213 if (ast_do_masquerade(chan)) { 02214 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 02215 ast_mutex_unlock(&chan->lock); 02216 return -1; 02217 } 02218 } 02219 if (chan->masqr) { 02220 ast_mutex_unlock(&chan->lock); 02221 return 0; 02222 } 02223 if (chan->generatordata) { 02224 if (ast_test_flag(chan, AST_FLAG_WRITE_INT)) 02225 ast_deactivate_generator(chan); 02226 else { 02227 ast_mutex_unlock(&chan->lock); 02228 return 0; 02229 } 02230 } 02231 /* High bit prints debugging */ 02232 if (chan->fout & 0x80000000) 02233 ast_frame_dump(chan->name, fr, ">>"); 02234 CHECK_BLOCKING(chan); 02235 switch(fr->frametype) { 02236 case AST_FRAME_CONTROL: 02237 /* XXX Interpret control frames XXX */ 02238 ast_log(LOG_WARNING, "Don't know how to handle control frames yet\n"); 02239 break; 02240 case AST_FRAME_DTMF: 02241 ast_clear_flag(chan, AST_FLAG_BLOCKING); 02242 ast_mutex_unlock(&chan->lock); 02243 res = do_senddigit(chan,fr->subclass); 02244 ast_mutex_lock(&chan->lock); 02245 CHECK_BLOCKING(chan); 02246 break; 02247 case AST_FRAME_TEXT: 02248 if (chan->tech->send_text) 02249 res = chan->tech->send_text(chan, (char *) fr->data); 02250 else 02251 res = 0; 02252 break; 02253 case AST_FRAME_HTML: 02254 if (chan->tech->send_html) 02255 res = chan->tech->send_html(chan, fr->subclass, (char *) fr->data, fr->datalen); 02256 else 02257 res = 0; 02258 break; 02259 case AST_FRAME_VIDEO: 02260 /* XXX Handle translation of video codecs one day XXX */ 02261 if (chan->tech->write_video) 02262 res = chan->tech->write_video(chan, fr); 02263 else 02264 res = 0; 02265 break; 02266 default: 02267 if (chan->tech->write) { 02268 f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr; 02269 if (f) { 02270 if (f->frametype == AST_FRAME_VOICE && chan->spies) 02271 queue_frame_to_spies(chan, f, SPY_WRITE); 02272 02273 if( chan->monitor && chan->monitor->write_stream && 02274 f && ( f->frametype == AST_FRAME_VOICE ) ) { 02275 #ifndef MONITOR_CONSTANT_DELAY 02276 int jump = chan->insmpl - chan->outsmpl - 4 * f->samples; 02277 if (jump >= 0) { 02278 if (ast_seekstream(chan->monitor->write_stream, jump + f->samples, SEEK_FORCECUR) == -1) 02279 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 02280 chan->outsmpl += jump + 4 * f->samples; 02281 } else 02282 chan->outsmpl += f->samples; 02283 #else 02284 int jump = chan->insmpl - chan->outsmpl; 02285 if (jump - MONITOR_DELAY >= 0) { 02286 if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1) 02287 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 02288 chan->outsmpl += jump; 02289 } else 02290 chan->outsmpl += f->samples; 02291 #endif 02292 if (ast_writestream(chan->monitor->write_stream, f) < 0) 02293 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n"); 02294 } 02295 02296 res = chan->tech->write(chan, f); 02297 } else 02298 res = 0; 02299 } 02300 } 02301 02302 /* It's possible this is a translated frame */ 02303 if (f && f->frametype == AST_FRAME_DTMF) { 02304 ast_log(LOG_DTMF, "%s : %c\n", chan->name, f->subclass); 02305 } else if (fr->frametype == AST_FRAME_DTMF) { 02306 ast_log(LOG_DTMF, "%s : %c\n", chan->name, fr->subclass); 02307 } 02308 02309 if (f && (f != fr)) 02310 ast_frfree(f); 02311 ast_clear_flag(chan, AST_FLAG_BLOCKING); 02312 /* Consider a write failure to force a soft hangup */ 02313 if (res < 0) 02314 chan->_softhangup |= AST_SOFTHANGUP_DEV; 02315 else { 02316 if ((chan->fout & 0x7fffffff) == 0x7fffffff) 02317 chan->fout &= 0x80000000; 02318 else 02319 chan->fout++; 02320 } 02321 ast_mutex_unlock(&chan->lock); 02322 return res; 02323 }
|
|
Definition at line 2190 of file channel.c. References ast_write(), ast_channel::tech, and ast_channel_tech::write_video. 02191 { 02192 int res; 02193 if (!chan->tech->write_video) 02194 return 0; 02195 res = ast_write(chan, fr); 02196 if (!res) 02197 res = 1; 02198 return res; 02199 }
|