#include <unistd.h>
#include <setjmp.h>
#include <sys/poll.h>
#include "asterisk/compat.h"
#include "asterisk/frame.h"
#include "asterisk/sched.h"
#include "asterisk/chanvars.h"
#include "asterisk/config.h"
#include "asterisk/lock.h"
#include "asterisk/cdr.h"
#include "asterisk/utils.h"
#include "asterisk/linkedlists.h"
Go to the source code of this file.
Data Structures | |
struct | ast_bridge_config |
struct | ast_callerid |
struct | ast_channel |
struct | ast_channel_tech |
struct | ast_generator |
struct | outgoing_helper |
Defines | |
#define | AST_ADSI_AVAILABLE (1) |
#define | AST_ADSI_OFFHOOKONLY (3) |
#define | AST_ADSI_UNAVAILABLE (2) |
#define | AST_ADSI_UNKNOWN (0) |
#define | AST_BRIDGE_DTMF_CHANNEL_0 (1 << 0) |
#define | AST_BRIDGE_DTMF_CHANNEL_1 (1 << 1) |
#define | AST_BRIDGE_IGNORE_SIGS (1 << 4) |
#define | AST_BRIDGE_REC_CHANNEL_0 (1 << 2) |
#define | AST_BRIDGE_REC_CHANNEL_1 (1 << 3) |
#define | AST_CDR_CALLWAIT (1 << 2) |
#define | AST_CDR_CONFERENCE (1 << 3) |
#define | AST_CDR_FORWARD (1 << 1) |
#define | AST_CDR_TRANSFER (1 << 0) |
#define | AST_CHANNEL_NAME 80 |
#define | AST_FEATURE_ATXFER (1 << 3) |
#define | AST_FEATURE_AUTOMON (1 << 4) |
#define | AST_FEATURE_DISCONNECT (1 << 2) |
#define | AST_FEATURE_FLAG_CALLEE (1 << 1) |
#define | AST_FEATURE_FLAG_CALLER (1 << 2) |
#define | AST_FEATURE_FLAG_NEEDSDTMF (1 << 0) |
#define | AST_FEATURE_PLAY_WARNING (1 << 0) |
#define | AST_FEATURE_REDIRECT (1 << 1) |
#define | AST_MAX_CONTEXT 80 |
#define | AST_MAX_EXTENSION 80 |
#define | AST_MAX_FDS 8 |
#define | AST_SOFTHANGUP_APPUNLOAD (1 << 4) |
#define | AST_SOFTHANGUP_ASYNCGOTO (1 << 1) |
#define | AST_SOFTHANGUP_DEV (1 << 0) |
#define | AST_SOFTHANGUP_EXPLICIT (1 << 5) |
#define | AST_SOFTHANGUP_SHUTDOWN (1 << 2) |
#define | AST_SOFTHANGUP_TIMEOUT (1 << 3) |
#define | AST_SOFTHANGUP_UNBRIDGE (1 << 6) |
#define | AST_STATE_BUSY 7 |
#define | AST_STATE_DIALING 3 |
#define | AST_STATE_DIALING_OFFHOOK 8 |
#define | AST_STATE_DOWN 0 |
#define | AST_STATE_MUTE (1 << 16) |
#define | AST_STATE_OFFHOOK 2 |
#define | AST_STATE_PRERING 9 |
#define | AST_STATE_RESERVED 1 |
#define | AST_STATE_RING 4 |
#define | AST_STATE_RINGING 5 |
#define | AST_STATE_UP 6 |
#define | ast_strdupa(s) |
#define | CHECK_BLOCKING(c) |
#define | CRASH do { } while(0) |
#define | LOAD_OH(oh) |
#define | MAX_LANGUAGE 20 |
#define | MAX_MUSICCLASS 20 |
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. | |
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. | |
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.
|
|
|
|
|
|
|
|
|
Report DTMF on channel 0 Definition at line 870 of file channel.h. Referenced by ast_rtp_bridge(), iax2_bridge(), set_config_flags(), and zt_bridge(). |
|
Report DTMF on channel 1 Definition at line 872 of file channel.h. Referenced by set_config_flags(). |
|
Ignore all signal frames except NULL |
|
Return all voice frames on channel 0 |
|
Return all voice frames on channel 1 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Definition at line 443 of file channel.h. Referenced by dial_exec_full(), and try_calling(). |
|
Definition at line 441 of file channel.h. Referenced by builtin_atxfer(), dial_exec_full(), and try_calling(). |
|
Definition at line 446 of file channel.h. Referenced by feature_exec_app(), load_config(), and set_config_flags(). |
|
Definition at line 447 of file channel.h. Referenced by load_config(), and set_config_flags(). |
|
Definition at line 445 of file channel.h. Referenced by load_config(), and set_config_flags(). |
|
Definition at line 439 of file channel.h. Referenced by ast_bridge_call(), ast_channel_bridge(), and dial_exec_full(). |
|
Definition at line 440 of file channel.h. Referenced by dial_exec_full(), park_exec(), and try_calling(). |
|
if we are blocking Definition at line 427 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 425 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 429 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 433 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 430 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 432 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 431 of file channel.h. Referenced by chanspy_exec(). |
|
if write should be interrupt generator Definition at line 426 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 428 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(). |
|
|
|
Max length of an extension Definition at line 102 of file channel.h. Referenced by fillin_process(), find_conf(), gosub_exec(), mgcp_ss(), monitor_handle_notowned(), phone_check_exception(), realtime_switch_common(), skinny_ss(), and ss_thread(). |
|
Definition at line 122 of file channel.h. Referenced by agent_read(), ast_channel_alloc(), ast_do_masquerade(), ast_read(), ast_waitfor_nandfds(), and restore_channel(). |
|
Definition at line 502 of file channel.h. Referenced by __unload_module(), and unload_module(). |
|
Soft hangup for async goto Definition at line 499 of file channel.h. Referenced by ast_async_goto(). |
|
Soft hangup by device Definition at line 498 of file channel.h. Referenced by attempt_transfer(), do_monitor(), function_ilink(), handle_link_data(), oh323_indicate(), rpt(), rpt_call(), sip_indicate(), and skinny_indicate(). |
|
Definition at line 503 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 500 of file channel.h. Referenced by ast_begin_shutdown(). |
|
|
|
Definition at line 504 of file channel.h. Referenced by ast_channel_bridge(), ast_generic_bridge(), start_spying(), and startmon(). |
|
|
Definition at line 1188 of file channel.h. Referenced by ast_sendtext(), ast_waitfor_nandfds(), ast_write(), phone_read(), and zt_read(). |
|
|
|
Definition at line 466 of file channel.h. Referenced by ast_pbx_outgoing_exten(). |
|
|
|
|
|
Definition at line 131 of file channel.h. Referenced by agent_devicestate(), agent_request(), ast_get_group(), build_port_config(), get_group(), load_module(), misdn_new(), and modem_request(). |
|
Definition at line 124 of file channel.h. Referenced by ast_channel_bridge(), ast_generic_bridge(), ast_rtp_bridge(), iax2_bridge(), misdn_bridge(), vpb_bridge(), and zt_bridge(). 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 2372 of file channel.c. References ast_channel::_state, outgoing_helper::account, ast_call(), AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, ast_cdr_alloc(), ast_cdr_disposition(), ast_cdr_end(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_setapp(), ast_cdr_start(), ast_cdr_update(), ast_channel_inherit_variables(), ast_frfree(), ast_hangup(), ast_log(), ast_read(), ast_request(), ast_set_callerid(), ast_set_variables(), ast_waitfor(), ast_channel::cdr, outgoing_helper::cid_name, outgoing_helper::cid_num, ast_channel::context, outgoing_helper::context, ast_channel::exten, outgoing_helper::exten, ast_frame::frametype, ast_channel::hangupcause, LOG_NOTICE, LOG_WARNING, outgoing_helper::parent_channel, ast_channel::priority, outgoing_helper::priority, ast_frame::subclass, type, and outgoing_helper::vars. Referenced by ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_request_and_dial(), and parkandannounce_exec(). 02373 { 02374 int state = 0; 02375 int cause = 0; 02376 struct ast_channel *chan; 02377 struct ast_frame *f; 02378 int res = 0; 02379 02380 chan = ast_request(type, format, data, &cause); 02381 if (chan) { 02382 if (oh) { 02383 if (oh->vars) 02384 ast_set_variables(chan, oh->vars); 02385 if (oh->cid_num && *oh->cid_num && oh->cid_name && *oh->cid_name) 02386 ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num); 02387 if (oh->parent_channel) 02388 ast_channel_inherit_variables(oh->parent_channel, chan); 02389 if (oh->account) 02390 ast_cdr_setaccount(chan, oh->account); 02391 } 02392 ast_set_callerid(chan, cid_num, cid_name, cid_num); 02393 02394 if (!ast_call(chan, data, 0)) { 02395 res = 1; /* in case chan->_state is already AST_STATE_UP */ 02396 while (timeout && (chan->_state != AST_STATE_UP)) { 02397 res = ast_waitfor(chan, timeout); 02398 if (res < 0) { 02399 /* Something not cool, or timed out */ 02400 break; 02401 } 02402 /* If done, break out */ 02403 if (!res) 02404 break; 02405 if (timeout > -1) 02406 timeout = res; 02407 f = ast_read(chan); 02408 if (!f) { 02409 state = AST_CONTROL_HANGUP; 02410 res = 0; 02411 break; 02412 } 02413 if (f->frametype == AST_FRAME_CONTROL) { 02414 if (f->subclass == AST_CONTROL_RINGING) 02415 state = AST_CONTROL_RINGING; 02416 else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) { 02417 state = f->subclass; 02418 ast_frfree(f); 02419 break; 02420 } else if (f->subclass == AST_CONTROL_ANSWER) { 02421 state = f->subclass; 02422 ast_frfree(f); 02423 break; 02424 } else if (f->subclass == AST_CONTROL_PROGRESS) { 02425 /* Ignore */ 02426 } else if (f->subclass == -1) { 02427 /* Ignore -- just stopping indications */ 02428 } else { 02429 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass); 02430 } 02431 } 02432 ast_frfree(f); 02433 } 02434 } else 02435 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data); 02436 } else { 02437 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data); 02438 switch(cause) { 02439 case AST_CAUSE_BUSY: 02440 state = AST_CONTROL_BUSY; 02441 break; 02442 case AST_CAUSE_CONGESTION: 02443 state = AST_CONTROL_CONGESTION; 02444 break; 02445 } 02446 } 02447 if (chan) { 02448 /* Final fixups */ 02449 if (oh) { 02450 if (oh->context && *oh->context) 02451 ast_copy_string(chan->context, oh->context, sizeof(chan->context)); 02452 if (oh->exten && *oh->exten) 02453 ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten)); 02454 if (oh->priority) 02455 chan->priority = oh->priority; 02456 } 02457 if (chan->_state == AST_STATE_UP) 02458 state = AST_CONTROL_ANSWER; 02459 } 02460 if (outstate) 02461 *outstate = state; 02462 if (chan && res <= 0) { 02463 if (!chan->cdr) { 02464 chan->cdr = ast_cdr_alloc(); 02465 if (chan->cdr) 02466 ast_cdr_init(chan->cdr, chan); 02467 } 02468 if (chan->cdr) { 02469 char tmp[256]; 02470 snprintf(tmp, 256, "%s/%s", type, (char *)data); 02471 ast_cdr_setapp(chan->cdr,"Dial",tmp); 02472 ast_cdr_update(chan); 02473 ast_cdr_start(chan->cdr); 02474 ast_cdr_end(chan->cdr); 02475 /* If the cause wasn't handled properly */ 02476 if (ast_cdr_disposition(chan->cdr,chan->hangupcause)) 02477 ast_cdr_failed(chan->cdr); 02478 } else 02479 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 02480 ast_hangup(chan); 02481 chan = NULL; 02482 } 02483 return chan; 02484 }
|
|
Activate a given generator Definition at line 1417 of file channel.c. References ast_generator::alloc, ast_mutex_lock(), ast_mutex_unlock(), ast_prod(), ast_settimeout(), ast_channel::generator, generator_force(), ast_channel::generatordata, ast_channel::lock, and ast_generator::release. Referenced by app_exec(), ast_channel_start_silence_generator(), ast_linear_stream(), ast_playtones_start(), ast_tonepair_start(), channel_spy(), local_ast_moh_start(), milliwatt_exec(), and sms_exec(). 01418 { 01419 int res = 0; 01420 01421 ast_mutex_lock(&chan->lock); 01422 01423 if (chan->generatordata) { 01424 if (chan->generator && chan->generator->release) 01425 chan->generator->release(chan, chan->generatordata); 01426 chan->generatordata = NULL; 01427 } 01428 01429 ast_prod(chan); 01430 if (gen->alloc) { 01431 if (!(chan->generatordata = gen->alloc(chan, params))) 01432 res = -1; 01433 } 01434 01435 if (!res) { 01436 ast_settimeout(chan, 160, generator_force, chan); 01437 chan->generator = gen; 01438 } 01439 01440 ast_mutex_unlock(&chan->lock); 01441 01442 return res; 01443 }
|
|
Returns number of active/allocated channels Definition at line 250 of file channel.c. References ast_mutex_lock(), ast_mutex_unlock(), 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 aslist, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, asthread, autoservice_run(), asent::chan, free, LOG_WARNING, malloc, and asent::next. Referenced by ast_dtmf_stream(), ast_get_enum(), ast_get_srv(), ast_get_txt(), ast_osp_lookup(), bridge_playfile(), builtin_atxfer(), builtin_automonitor(), builtin_blindtransfer(), conf_play(), dial_exec_full(), and try_calling(). 00104 { 00105 int res = -1; 00106 struct asent *as; 00107 int needstart; 00108 ast_mutex_lock(&autolock); 00109 needstart = (asthread == AST_PTHREADT_NULL) ? 1 : 0 /* aslist ? 0 : 1 */; 00110 as = aslist; 00111 while(as) { 00112 if (as->chan == chan) 00113 break; 00114 as = as->next; 00115 } 00116 if (!as) { 00117 as = malloc(sizeof(struct asent)); 00118 if (as) { 00119 memset(as, 0, sizeof(struct asent)); 00120 as->chan = chan; 00121 as->next = aslist; 00122 aslist = as; 00123 res = 0; 00124 if (needstart) { 00125 if (ast_pthread_create(&asthread, NULL, autoservice_run, NULL)) { 00126 ast_log(LOG_WARNING, "Unable to create autoservice thread :(\n"); 00127 free(aslist); 00128 aslist = NULL; 00129 res = -1; 00130 } else 00131 pthread_kill(asthread, SIGURG); 00132 } 00133 } 00134 } 00135 ast_mutex_unlock(&autolock); 00136 return res; 00137 }
|
|
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, aslist, AST_FLAG_BLOCKING, ast_mutex_lock(), ast_mutex_unlock(), 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, 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_log(), and LOG_WARNING. 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 3166 of file channel.c. References ast_channel::_bridge, ast_channel_tech::bridged_channel, and ast_channel::tech. Referenced by __zt_exception(), agents_show(), 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(). 03167 { 03168 struct ast_channel *bridged; 03169 bridged = chan->_bridge; 03170 if (bridged && bridged->tech->bridged_channel) 03171 bridged = bridged->tech->bridged_channel(chan, bridged); 03172 return bridged; 03173 }
|
|
Make a call.
Definition at line 2550 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(). 02551 { 02552 /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 02553 If the remote end does not answer within the timeout, then do NOT hang up, but 02554 return anyway. */ 02555 int res = -1; 02556 /* Stop if we're a zombie or need a soft hangup */ 02557 ast_mutex_lock(&chan->lock); 02558 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) 02559 if (chan->tech->call) 02560 res = chan->tech->call(chan, addr, timeout); 02561 ast_mutex_unlock(&chan->lock); 02562 return res; 02563 }
|
|
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 ast_cause::cause, causes, and ast_cause::desc. 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 2775 of file channel.c. References EVENT_FLAG_CALL, manager_event(), ast_channel::name, and ast_channel::uniqueid. 02776 { 02777 char tmp[256]; 02778 ast_copy_string(tmp, chan->name, sizeof(tmp)); 02779 ast_copy_string(chan->name, newname, sizeof(chan->name)); 02780 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", tmp, chan->name, chan->uniqueid); 02781 }
|
|
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_LIST_HEAD_INIT_NOLOCK, ast_log(), AST_MAX_FDS, ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), channels, ast_channel::context, ast_channel::data, defaultlanguage, ast_channel::exten, ast_channel::fds, ast_channel::fin, ast_channel::fout, free, ast_channel::language, ast_channel::lock, LOG_WARNING, malloc, ast_channel::name, ast_channel::next, ast_channel::priority, ast_channel::sched, sched_context_create(), ast_channel::streamid, ast_channel::tech, ast_channel::timingfd, ast_channel::uniqueid, uniqueint, and ast_channel::varshead. Referenced by __oh323_new(), agent_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_masq_park_call(), ast_modem_new(), ast_pbx_outgoing_cdr_failed(), ast_pbx_outgoing_exten(), builtin_atxfer(), check_goto_on_transfer(), features_new(), iax_park(), local_new(), mgcp_new(), misdn_new(), nbs_new(), oss_new(), phone_new(), sendmail(), sendpage(), sip_new(), sip_park(), skinny_new(), vpb_new(), and zt_new(). 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 3327 of file channel.c. References ast_channel::_bridge, ast_channel::_softhangup, AST_BRIDGE_FAILED_NOWARN, ast_bridge_result, AST_BRIDGE_RETRY, ast_channel_make_compatible(), ast_check_hangup(), ast_check_hangup_locked(), ast_clear_flag, AST_FEATURE_PLAY_WARNING, 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(). 03329 { 03330 struct ast_channel *who = NULL; 03331 enum ast_bridge_result res = AST_BRIDGE_COMPLETE; 03332 int nativefailed=0; 03333 int firstpass; 03334 int o0nativeformats; 03335 int o1nativeformats; 03336 long time_left_ms=0; 03337 struct timeval nexteventts = { 0, }; 03338 char caller_warning = 0; 03339 char callee_warning = 0; 03340 int to; 03341 03342 if (c0->_bridge) { 03343 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 03344 c0->name, c0->_bridge->name); 03345 return -1; 03346 } 03347 if (c1->_bridge) { 03348 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 03349 c1->name, c1->_bridge->name); 03350 return -1; 03351 } 03352 03353 /* Stop if we're a zombie or need a soft hangup */ 03354 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 03355 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) 03356 return -1; 03357 03358 *fo = NULL; 03359 firstpass = config->firstpass; 03360 config->firstpass = 0; 03361 03362 if (ast_tvzero(config->start_time)) 03363 config->start_time = ast_tvnow(); 03364 time_left_ms = config->timelimit; 03365 03366 caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING); 03367 callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING); 03368 03369 if (config->start_sound && firstpass) { 03370 if (caller_warning) 03371 bridge_playfile(c0, c1, config->start_sound, time_left_ms / 1000); 03372 if (callee_warning) 03373 bridge_playfile(c1, c0, config->start_sound, time_left_ms / 1000); 03374 } 03375 03376 /* Keep track of bridge */ 03377 c0->_bridge = c1; 03378 c1->_bridge = c0; 03379 03380 manager_event(EVENT_FLAG_CALL, "Link", 03381 "Channel1: %s\r\n" 03382 "Channel2: %s\r\n" 03383 "Uniqueid1: %s\r\n" 03384 "Uniqueid2: %s\r\n" 03385 "CallerID1: %s\r\n" 03386 "CallerID2: %s\r\n", 03387 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 03388 03389 o0nativeformats = c0->nativeformats; 03390 o1nativeformats = c1->nativeformats; 03391 03392 if (config->timelimit) { 03393 nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 03394 if (caller_warning || callee_warning) 03395 nexteventts = ast_tvsub(nexteventts, ast_samp2tv(config->play_warning, 1000)); 03396 } 03397 03398 for (/* ever */;;) { 03399 to = -1; 03400 if (config->timelimit) { 03401 struct timeval now; 03402 now = ast_tvnow(); 03403 to = ast_tvdiff_ms(nexteventts, now); 03404 if (to < 0) 03405 to = 0; 03406 time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time); 03407 if (time_left_ms < to) 03408 to = time_left_ms; 03409 03410 if (time_left_ms <= 0) { 03411 if (caller_warning && config->end_sound) 03412 bridge_playfile(c0, c1, config->end_sound, 0); 03413 if (callee_warning && config->end_sound) 03414 bridge_playfile(c1, c0, config->end_sound, 0); 03415 *fo = NULL; 03416 if (who) 03417 *rc = who; 03418 res = 0; 03419 break; 03420 } 03421 03422 if (!to) { 03423 if (time_left_ms >= 5000) { 03424 /* force the time left to round up if appropriate */ 03425 if (caller_warning && config->warning_sound && config->play_warning) 03426 bridge_playfile(c0, c1, config->warning_sound, 03427 (time_left_ms + 500) / 1000); 03428 if (callee_warning && config->warning_sound && config->play_warning) 03429 bridge_playfile(c1, c0, config->warning_sound, 03430 (time_left_ms + 500) / 1000); 03431 } 03432 if (config->warning_freq) { 03433 nexteventts = ast_tvadd(nexteventts, ast_samp2tv(config->warning_freq, 1000)); 03434 } else 03435 nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 03436 } 03437 } 03438 03439 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) { 03440 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 03441 c0->_softhangup = 0; 03442 if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 03443 c1->_softhangup = 0; 03444 c0->_bridge = c1; 03445 c1->_bridge = c0; 03446 ast_log(LOG_DEBUG, "Unbridge signal received. Ending native bridge.\n"); 03447 continue; 03448 } 03449 03450 /* Stop if we're a zombie or need a soft hangup */ 03451 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 03452 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) { 03453 *fo = NULL; 03454 if (who) 03455 *rc = who; 03456 res = 0; 03457 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", 03458 c0->name, c1->name, 03459 ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No", 03460 ast_check_hangup(c0) ? "Yes" : "No", 03461 ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No", 03462 ast_check_hangup(c1) ? "Yes" : "No"); 03463 break; 03464 } 03465 03466 if (c0->tech->bridge && 03467 (config->timelimit == 0) && 03468 (c0->tech->bridge == c1->tech->bridge) && 03469 !nativefailed && !c0->monitor && !c1->monitor && 03470 !c0->spies && !c1->spies) { 03471 /* Looks like they share a bridge method and nothing else is in the way */ 03472 if (option_verbose > 2) 03473 ast_verbose(VERBOSE_PREFIX_3 "Attempting native bridge of %s and %s\n", c0->name, c1->name); 03474 ast_set_flag(c0, AST_FLAG_NBRIDGE); 03475 ast_set_flag(c1, AST_FLAG_NBRIDGE); 03476 if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, to)) == AST_BRIDGE_COMPLETE) { 03477 manager_event(EVENT_FLAG_CALL, "Unlink", 03478 "Channel1: %s\r\n" 03479 "Channel2: %s\r\n" 03480 "Uniqueid1: %s\r\n" 03481 "Uniqueid2: %s\r\n" 03482 "CallerID1: %s\r\n" 03483 "CallerID2: %s\r\n", 03484 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 03485 ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name); 03486 03487 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 03488 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 03489 03490 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 03491 continue; 03492 03493 c0->_bridge = NULL; 03494 c1->_bridge = NULL; 03495 03496 return res; 03497 } else { 03498 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 03499 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 03500 } 03501 switch (res) { 03502 case AST_BRIDGE_RETRY: 03503 continue; 03504 default: 03505 ast_log(LOG_WARNING, "Private bridge between %s and %s failed\n", c0->name, c1->name); 03506 /* fallthrough */ 03507 case AST_BRIDGE_FAILED_NOWARN: 03508 nativefailed++; 03509 break; 03510 } 03511 } 03512 03513 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) || 03514 (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) && 03515 !(c0->generator || c1->generator)) { 03516 if (ast_channel_make_compatible(c0, c1)) { 03517 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name); 03518 manager_event(EVENT_FLAG_CALL, "Unlink", 03519 "Channel1: %s\r\n" 03520 "Channel2: %s\r\n" 03521 "Uniqueid1: %s\r\n" 03522 "Uniqueid2: %s\r\n" 03523 "CallerID1: %s\r\n" 03524 "CallerID2: %s\r\n", 03525 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 03526 return AST_BRIDGE_FAILED; 03527 } 03528 o0nativeformats = c0->nativeformats; 03529 o1nativeformats = c1->nativeformats; 03530 } 03531 res = ast_generic_bridge(c0, c1, config, fo, rc, nexteventts); 03532 if (res != AST_BRIDGE_RETRY) 03533 break; 03534 } 03535 03536 c0->_bridge = NULL; 03537 c1->_bridge = NULL; 03538 03539 manager_event(EVENT_FLAG_CALL, "Unlink", 03540 "Channel1: %s\r\n" 03541 "Channel2: %s\r\n" 03542 "Uniqueid1: %s\r\n" 03543 "Uniqueid2: %s\r\n" 03544 "CallerID1: %s\r\n" 03545 "CallerID2: %s\r\n", 03546 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 03547 ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name); 03548 03549 return res; 03550 }
|
|
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_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(), 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 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 2783 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, and ast_channel::varshead. Referenced by __ast_request_and_dial(), agent_call(), ast_feature_request_and_dial(), dial_exec_full(), and ring_entry(). 02784 { 02785 struct ast_var_t *current, *newvar; 02786 char *varname; 02787 02788 AST_LIST_TRAVERSE(&parent->varshead, current, entries) { 02789 int vartype = 0; 02790 02791 varname = ast_var_full_name(current); 02792 if (!varname) 02793 continue; 02794 02795 if (varname[0] == '_') { 02796 vartype = 1; 02797 if (varname[1] == '_') 02798 vartype = 2; 02799 } 02800 02801 switch (vartype) { 02802 case 1: 02803 newvar = ast_var_assign(&varname[1], ast_var_value(current)); 02804 if (newvar) { 02805 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 02806 if (option_debug) 02807 ast_log(LOG_DEBUG, "Copying soft-transferable variable %s.\n", ast_var_name(newvar)); 02808 } 02809 break; 02810 case 2: 02811 newvar = ast_var_assign(ast_var_full_name(current), ast_var_value(current)); 02812 if (newvar) { 02813 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 02814 if (option_debug) 02815 ast_log(LOG_DEBUG, "Copying hard-transferable variable %s.\n", ast_var_name(newvar)); 02816 } 02817 break; 02818 default: 02819 if (option_debug) 02820 ast_log(LOG_DEBUG, "Not copying variable %s.\n", ast_var_name(current)); 02821 break; 02822 } 02823 } 02824 }
|
|
Definition at line 2689 of file channel.c. References ast_log(), ast_set_read_format(), ast_set_write_format(), ast_translator_best_choice(), LOG_WARNING, ast_channel::name, and ast_channel::nativeformats. Referenced by ast_channel_bridge(), builtin_atxfer(), dial_exec_full(), park_exec(), try_calling(), and wait_for_answer(). 02690 { 02691 int src; 02692 int dst; 02693 02694 /* Set up translation from the chan to the peer */ 02695 src = chan->nativeformats; 02696 dst = peer->nativeformats; 02697 if (ast_translator_best_choice(&dst, &src) < 0) { 02698 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, src, peer->name, dst); 02699 return -1; 02700 } 02701 02702 /* if the best path is not 'pass through', then 02703 transcoding is needed; if desired, force transcode path 02704 to use SLINEAR between channels */ 02705 if ((src != dst) && option_transcode_slin) 02706 dst = AST_FORMAT_SLINEAR; 02707 if (ast_set_read_format(chan, dst) < 0) { 02708 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, dst); 02709 return -1; 02710 } 02711 if (ast_set_write_format(peer, dst) < 0) { 02712 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, dst); 02713 return -1; 02714 } 02715 02716 /* Set up translation from the peer to the chan */ 02717 src = peer->nativeformats; 02718 dst = chan->nativeformats; 02719 if (ast_translator_best_choice(&dst, &src) < 0) { 02720 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, src, chan->name, dst); 02721 return -1; 02722 } 02723 /* if the best path is not 'pass through', then 02724 transcoding is needed; if desired, force transcode path 02725 to use SLINEAR between channels */ 02726 if ((src != dst) && option_transcode_slin) 02727 dst = AST_FORMAT_SLINEAR; 02728 if (ast_set_read_format(peer, dst) < 0) { 02729 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, dst); 02730 return -1; 02731 } 02732 if (ast_set_write_format(chan, dst) < 0) { 02733 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, dst); 02734 return -1; 02735 } 02736 return 0; 02737 }
|
|
Definition at line 2739 of file channel.c. References 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(). 02740 { 02741 struct ast_frame null = { AST_FRAME_NULL, }; 02742 int res = -1; 02743 02744 if (original == clone) { 02745 ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name); 02746 return -1; 02747 } 02748 ast_mutex_lock(&original->lock); 02749 while(ast_mutex_trylock(&clone->lock)) { 02750 ast_mutex_unlock(&original->lock); 02751 usleep(1); 02752 ast_mutex_lock(&original->lock); 02753 } 02754 ast_log(LOG_DEBUG, "Planning to masquerade channel %s into the structure of %s\n", 02755 clone->name, original->name); 02756 if (original->masq) { 02757 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 02758 original->masq->name, original->name); 02759 } else if (clone->masqr) { 02760 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 02761 clone->name, clone->masqr->name); 02762 } else { 02763 original->masq = clone; 02764 clone->masqr = original; 02765 ast_queue_frame(original, &null); 02766 ast_queue_frame(clone, &null); 02767 ast_log(LOG_DEBUG, "Done planning to masquerade channel %s into the structure of %s\n", clone->name, original->name); 02768 res = 0; 02769 } 02770 ast_mutex_unlock(&clone->lock); 02771 ast_mutex_unlock(&original->lock); 02772 return res; 02773 }
|
|
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_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 2675 of file channel.c. References ast_channel_tech::send_html, and ast_channel::tech. Referenced by agent_sendhtml(), and wait_for_answer(). 02676 { 02677 if (chan->tech->send_html) 02678 return chan->tech->send_html(chan, subclass, data, datalen); 02679 return -1; 02680 }
|
|
Send URL on link. Returns 0 on success or -1 on failure Definition at line 2682 of file channel.c. References AST_HTML_URL, ast_channel_tech::send_html, and ast_channel::tech. Referenced by dial_exec_full(), sendurl_exec(), and try_calling(). 02683 { 02684 if (chan->tech->send_html) 02685 return chan->tech->send_html(chan, AST_HTML_URL, url, strlen(url) + 1); 02686 return -1; 02687 }
|
|
Definition at line 3553 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(). 03554 { 03555 int res; 03556 03557 if (chan->tech->setoption) { 03558 res = chan->tech->setoption(chan, option, data, datalen); 03559 if (res < 0) 03560 return res; 03561 } else { 03562 errno = ENOSYS; 03563 return -1; 03564 } 03565 if (block) { 03566 /* XXX Implement blocking -- just wait for our option frame reply, discarding 03567 intermediate packets. XXX */ 03568 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 03569 return -1; 03570 } 03571 return 0; 03572 }
|
|
Set when to hang a channel up.
Definition at line 277 of file channel.c. References 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 4020 of file channel.c. References ast_activate_generator(), AST_FORMAT_SLINEAR, ast_log(), ast_set_write_format(), calloc, free, LOG_DEBUG, LOG_ERROR, LOG_WARNING, ast_channel::name, ast_silence_generator::old_write_format, silence_generator, and ast_channel::writeformat. Referenced by ast_play_and_record(), and record_exec(). 04021 { 04022 struct ast_silence_generator *state; 04023 04024 if (!(state = calloc(1, sizeof(*state)))) { 04025 ast_log(LOG_WARNING, "Could not allocate state structure\n"); 04026 return NULL; 04027 } 04028 04029 state->old_write_format = chan->writeformat; 04030 04031 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) { 04032 ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n"); 04033 free(state); 04034 return NULL; 04035 } 04036 04037 ast_activate_generator(chan, &silence_generator, state); 04038 04039 if (option_debug) 04040 ast_log(LOG_DEBUG, "Started silence generator on '%s'\n", chan->name); 04041 04042 return state; 04043 }
|
|
Stops a previously-started silence generator on the given channel.
Definition at line 4045 of file channel.c. References ast_deactivate_generator(), ast_log(), ast_set_write_format(), free, LOG_DEBUG, LOG_ERROR, ast_channel::name, and ast_silence_generator::old_write_format. Referenced by ast_play_and_record(), and record_exec(). 04046 { 04047 if (!state) 04048 return; 04049 04050 ast_deactivate_generator(chan); 04051 04052 if (option_debug) 04053 ast_log(LOG_DEBUG, "Stopped silence generator on '%s'\n", chan->name); 04054 04055 if (ast_set_write_format(chan, state->old_write_format) < 0) 04056 ast_log(LOG_ERROR, "Could not return write format to its original state\n"); 04057 04058 free(state); 04059 }
|
|
Returns 0 if channel does not support HTML or non-zero if it does Definition at line 2668 of file channel.c. References ast_channel_tech::send_html, and ast_channel::tech. Referenced by dial_exec_full(), sendurl_exec(), and try_calling(). 02669 { 02670 if (chan->tech->send_html) 02671 return 1; 02672 return 0; 02673 }
|
|
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, LOG_DEBUG, chanlist::next, 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_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(), mixmonitor_thread(), 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 1384 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(). 01385 { 01386 ast_mutex_lock(&chan->lock); 01387 if (chan->generatordata) { 01388 if (chan->generator && chan->generator->release) 01389 chan->generator->release(chan, chan->generatordata); 01390 chan->generatordata = NULL; 01391 chan->generator = NULL; 01392 ast_clear_flag(chan, AST_FLAG_WRITE_INT); 01393 ast_settimeout(chan, 0, NULL, NULL); 01394 } 01395 ast_mutex_unlock(&chan->lock); 01396 }
|
|
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 2859 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_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_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_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::readq, 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(). 02860 { 02861 int x,i; 02862 int res=0; 02863 int origstate; 02864 struct ast_frame *cur, *prev; 02865 const struct ast_channel_tech *t; 02866 void *t_pvt; 02867 struct ast_callerid tmpcid; 02868 struct ast_channel *clone = original->masq; 02869 int rformat = original->readformat; 02870 int wformat = original->writeformat; 02871 char newn[100]; 02872 char orig[100]; 02873 char masqn[100]; 02874 char zombn[100]; 02875 02876 if (option_debug > 3) 02877 ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n", 02878 clone->name, clone->_state, original->name, original->_state); 02879 02880 /* XXX This is a seriously wacked out operation. We're essentially putting the guts of 02881 the clone channel into the original channel. Start by killing off the original 02882 channel's backend. I'm not sure we're going to keep this function, because 02883 while the features are nice, the cost is very high in terms of pure nastiness. XXX */ 02884 02885 /* We need the clone's lock, too */ 02886 ast_mutex_lock(&clone->lock); 02887 02888 ast_log(LOG_DEBUG, "Got clone lock for masquerade on '%s' at %p\n", clone->name, &clone->lock); 02889 02890 /* Having remembered the original read/write formats, we turn off any translation on either 02891 one */ 02892 free_translation(clone); 02893 free_translation(original); 02894 02895 02896 /* Unlink the masquerade */ 02897 original->masq = NULL; 02898 clone->masqr = NULL; 02899 02900 /* Save the original name */ 02901 ast_copy_string(orig, original->name, sizeof(orig)); 02902 /* Save the new name */ 02903 ast_copy_string(newn, clone->name, sizeof(newn)); 02904 /* Create the masq name */ 02905 snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn); 02906 02907 /* Copy the name from the clone channel */ 02908 ast_copy_string(original->name, newn, sizeof(original->name)); 02909 02910 /* Mangle the name of the clone channel */ 02911 ast_copy_string(clone->name, masqn, sizeof(clone->name)); 02912 02913 /* Notify any managers of the change, first the masq then the other */ 02914 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", newn, masqn, clone->uniqueid); 02915 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", orig, newn, original->uniqueid); 02916 02917 /* Swap the technlogies */ 02918 t = original->tech; 02919 original->tech = clone->tech; 02920 clone->tech = t; 02921 02922 t_pvt = original->tech_pvt; 02923 original->tech_pvt = clone->tech_pvt; 02924 clone->tech_pvt = t_pvt; 02925 02926 /* Swap the readq's */ 02927 cur = original->readq; 02928 original->readq = clone->readq; 02929 clone->readq = cur; 02930 02931 /* Swap the alertpipes */ 02932 for (i = 0; i < 2; i++) { 02933 x = original->alertpipe[i]; 02934 original->alertpipe[i] = clone->alertpipe[i]; 02935 clone->alertpipe[i] = x; 02936 } 02937 02938 /* Swap the raw formats */ 02939 x = original->rawreadformat; 02940 original->rawreadformat = clone->rawreadformat; 02941 clone->rawreadformat = x; 02942 x = original->rawwriteformat; 02943 original->rawwriteformat = clone->rawwriteformat; 02944 clone->rawwriteformat = x; 02945 02946 /* Save any pending frames on both sides. Start by counting 02947 * how many we're going to need... */ 02948 prev = NULL; 02949 cur = clone->readq; 02950 x = 0; 02951 while(cur) { 02952 x++; 02953 prev = cur; 02954 cur = cur->next; 02955 } 02956 /* If we had any, prepend them to the ones already in the queue, and 02957 * load up the alertpipe */ 02958 if (prev) { 02959 prev->next = original->readq; 02960 original->readq = clone->readq; 02961 clone->readq = NULL; 02962 if (original->alertpipe[1] > -1) { 02963 for (i = 0; i < x; i++) 02964 write(original->alertpipe[1], &x, sizeof(x)); 02965 } 02966 } 02967 clone->_softhangup = AST_SOFTHANGUP_DEV; 02968 02969 02970 /* And of course, so does our current state. Note we need not 02971 call ast_setstate since the event manager doesn't really consider 02972 these separate. We do this early so that the clone has the proper 02973 state of the original channel. */ 02974 origstate = original->_state; 02975 original->_state = clone->_state; 02976 clone->_state = origstate; 02977 02978 if (clone->tech->fixup){ 02979 res = clone->tech->fixup(original, clone); 02980 if (res) 02981 ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name); 02982 } 02983 02984 /* Start by disconnecting the original's physical side */ 02985 if (clone->tech->hangup) 02986 res = clone->tech->hangup(clone); 02987 if (res) { 02988 ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n"); 02989 ast_mutex_unlock(&clone->lock); 02990 return -1; 02991 } 02992 02993 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig); 02994 /* Mangle the name of the clone channel */ 02995 ast_copy_string(clone->name, zombn, sizeof(clone->name)); 02996 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", masqn, zombn, clone->uniqueid); 02997 02998 /* Update the type. */ 02999 original->type = clone->type; 03000 t_pvt = original->monitor; 03001 original->monitor = clone->monitor; 03002 clone->monitor = t_pvt; 03003 03004 /* Keep the same language. */ 03005 ast_copy_string(original->language, clone->language, sizeof(original->language)); 03006 /* Copy the FD's */ 03007 for (x = 0; x < AST_MAX_FDS; x++) { 03008 original->fds[x] = clone->fds[x]; 03009 } 03010 clone_variables(original, clone); 03011 AST_LIST_HEAD_INIT_NOLOCK(&clone->varshead); 03012 /* Presense of ADSI capable CPE follows clone */ 03013 original->adsicpe = clone->adsicpe; 03014 /* Bridge remains the same */ 03015 /* CDR fields remain the same */ 03016 /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */ 03017 /* Application and data remain the same */ 03018 /* Clone exception becomes real one, as with fdno */ 03019 ast_copy_flags(original, clone, AST_FLAG_EXCEPTION); 03020 original->fdno = clone->fdno; 03021 /* Schedule context remains the same */ 03022 /* Stream stuff stays the same */ 03023 /* Keep the original state. The fixup code will need to work with it most likely */ 03024 03025 /* Just swap the whole structures, nevermind the allocations, they'll work themselves 03026 out. */ 03027 tmpcid = original->cid; 03028 original->cid = clone->cid; 03029 clone->cid = tmpcid; 03030 03031 /* Restore original timing file descriptor */ 03032 original->fds[AST_MAX_FDS - 2] = original->timingfd; 03033 03034 /* Our native formats are different now */ 03035 original->nativeformats = clone->nativeformats; 03036 03037 /* Context, extension, priority, app data, jump table, remain the same */ 03038 /* pvt switches. pbx stays the same, as does next */ 03039 03040 /* Set the write format */ 03041 ast_set_write_format(original, wformat); 03042 03043 /* Set the read format */ 03044 ast_set_read_format(original, rformat); 03045 03046 /* Copy the music class */ 03047 ast_copy_string(original->musicclass, clone->musicclass, sizeof(original->musicclass)); 03048 03049 ast_log(LOG_DEBUG, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat); 03050 03051 /* Okay. Last thing is to let the channel driver know about all this mess, so he 03052 can fix up everything as best as possible */ 03053 if (original->tech->fixup) { 03054 res = original->tech->fixup(clone, original); 03055 if (res) { 03056 ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n", 03057 original->type, original->name); 03058 ast_mutex_unlock(&clone->lock); 03059 return -1; 03060 } 03061 } else 03062 ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)! Bad things may happen.\n", 03063 original->type, original->name); 03064 03065 /* Now, at this point, the "clone" channel is totally F'd up. We mark it as 03066 a zombie so nothing tries to touch it. If it's already been marked as a 03067 zombie, then free it now (since it already is considered invalid). */ 03068 if (ast_test_flag(clone, AST_FLAG_ZOMBIE)) { 03069 ast_log(LOG_DEBUG, "Destroying channel clone '%s'\n", clone->name); 03070 ast_mutex_unlock(&clone->lock); 03071 manager_event(EVENT_FLAG_CALL, "Hangup", 03072 "Channel: %s\r\n" 03073 "Uniqueid: %s\r\n" 03074 "Cause: %d\r\n" 03075 "Cause-txt: %s\r\n", 03076 clone->name, 03077 clone->uniqueid, 03078 clone->hangupcause, 03079 ast_cause2str(clone->hangupcause) 03080 ); 03081 ast_channel_free(clone); 03082 } else { 03083 struct ast_frame null_frame = { AST_FRAME_NULL, }; 03084 ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name); 03085 ast_set_flag(clone, AST_FLAG_ZOMBIE); 03086 ast_queue_frame(clone, &null_frame); 03087 ast_mutex_unlock(&clone->lock); 03088 } 03089 03090 /* Signal any blocker */ 03091 if (ast_test_flag(original, AST_FLAG_BLOCKING)) 03092 pthread_kill(original->blocker, SIGURG); 03093 ast_log(LOG_DEBUG, "Done Masquerading %s (%d)\n", original->name, original->_state); 03094 return 0; 03095 }
|
|
Definition at line 1108 of file channel.h. References pollfd::fd, and pollfd::revents. Referenced by ast_waitfor_n_fd(), ast_waitfor_nandfds(), and do_monitor(). 01109 { 01110 int x; 01111 for (x=start ? *start : 0;x<max;x++) 01112 if (pfds[x].fd == fd) { 01113 if (start) { 01114 if (x==*start) 01115 (*start)++; 01116 } 01117 return pfds[x].revents; 01118 } 01119 return 0; 01120 }
|
|
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(), and name. Referenced by action_getvar(), action_hangup(), action_redirect(), action_setcdruserfield(), action_setvar(), action_status(), action_timeout(), ast_async_goto_by_name(), change_monitor_action(), get_zap_channel_locked(), handle_channelstatus(), handle_debugchan(), handle_getvariablefull(), handle_hangup(), handle_nodebugchan(), handle_showchan(), handle_softhangup(), pbx_builtin_importvar(), pickup_exec(), start_monitor_action(), and stop_monitor_action(). 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(), and name. 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(), LOG_WARNING, name, 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 3710 of file channel.c. References ast_group_t, ast_log(), ast_strdupa, LOG_ERROR, LOG_WARNING, s, and strsep(). Referenced by build_device(), build_gateway(), build_peer(), build_port_config(), build_user(), load_module(), read_agent_config(), and setup_zap(). 03711 { 03712 char *copy; 03713 char *piece; 03714 char *c=NULL; 03715 int start=0, finish=0, x; 03716 ast_group_t group = 0; 03717 03718 copy = ast_strdupa(s); 03719 if (!copy) { 03720 ast_log(LOG_ERROR, "Out of memory\n"); 03721 return 0; 03722 } 03723 c = copy; 03724 03725 while((piece = strsep(&c, ","))) { 03726 if (sscanf(piece, "%d-%d", &start, &finish) == 2) { 03727 /* Range */ 03728 } else if (sscanf(piece, "%d", &start)) { 03729 /* Just one */ 03730 finish = start; 03731 } else { 03732 ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece); 03733 continue; 03734 } 03735 for (x = start; x <= finish; x++) { 03736 if ((x > 63) || (x < 0)) { 03737 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x); 03738 } else 03739 group |= ((ast_group_t) 1 << x); 03740 } 03741 } 03742 return group; 03743 }
|
|
Hang up a channel.
Definition at line 1276 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, 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, 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(). 01277 { 01278 int res = 0; 01279 01280 /* Don't actually hang up a channel that will masquerade as someone else, or 01281 if someone is going to masquerade as us */ 01282 ast_mutex_lock(&chan->lock); 01283 01284 detach_spies(chan); /* get rid of spies */ 01285 01286 if (chan->masq) { 01287 if (ast_do_masquerade(chan)) 01288 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 01289 } 01290 01291 if (chan->masq) { 01292 ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name); 01293 ast_mutex_unlock(&chan->lock); 01294 return 0; 01295 } 01296 /* If this channel is one which will be masqueraded into something, 01297 mark it as a zombie already, so we know to free it later */ 01298 if (chan->masqr) { 01299 ast_set_flag(chan, AST_FLAG_ZOMBIE); 01300 ast_mutex_unlock(&chan->lock); 01301 return 0; 01302 } 01303 free_translation(chan); 01304 if (chan->stream) /* Close audio stream */ 01305 ast_closestream(chan->stream); 01306 if (chan->vstream) /* Close video stream */ 01307 ast_closestream(chan->vstream); 01308 if (chan->sched) { 01309 sched_context_destroy(chan->sched); 01310 chan->sched = NULL; 01311 } 01312 01313 if (chan->generatordata) /* Clear any tone stuff remaining */ 01314 chan->generator->release(chan, chan->generatordata); 01315 chan->generatordata = NULL; 01316 chan->generator = NULL; 01317 if (chan->cdr) { /* End the CDR if it hasn't already */ 01318 ast_cdr_end(chan->cdr); 01319 ast_cdr_detach(chan->cdr); /* Post and Free the CDR */ 01320 chan->cdr = NULL; 01321 } 01322 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) { 01323 ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd " 01324 "is blocked by thread %ld in procedure %s! Expect a failure\n", 01325 (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc); 01326 CRASH; 01327 } 01328 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) { 01329 if (option_debug) 01330 ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name); 01331 if (chan->tech->hangup) 01332 res = chan->tech->hangup(chan); 01333 } else { 01334 if (option_debug) 01335 ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name); 01336 } 01337 01338 ast_mutex_unlock(&chan->lock); 01339 manager_event(EVENT_FLAG_CALL, "Hangup", 01340 "Channel: %s\r\n" 01341 "Uniqueid: %s\r\n" 01342 "Cause: %d\r\n" 01343 "Cause-txt: %s\r\n", 01344 chan->name, 01345 chan->uniqueid, 01346 chan->hangupcause, 01347 ast_cause2str(chan->hangupcause) 01348 ); 01349 ast_channel_free(chan); 01350 return res; 01351 }
|
|
Indicates condition of channel.
Definition at line 2009 of file channel.c. References ast_check_hangup(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_RINGING, 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(), ast_rtp_bridge(), attempt_transfer(), builtin_atxfer(), builtin_blindtransfer(), conf_run(), dial_exec_full(), disa_exec(), do_parking_thread(), features_indicate(), function_remote(), 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(). 02010 { 02011 int res = -1; 02012 02013 ast_mutex_lock(&chan->lock); 02014 /* Stop if we're a zombie or need a soft hangup */ 02015 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 02016 ast_mutex_unlock(&chan->lock); 02017 return -1; 02018 } 02019 if (chan->tech->indicate) 02020 res = chan->tech->indicate(chan, condition); 02021 ast_mutex_unlock(&chan->lock); 02022 if (!chan->tech->indicate || res) { 02023 /* 02024 * Device does not support (that) indication, lets fake 02025 * it by doing our own tone generation. (PM2002) 02026 */ 02027 if (condition >= 0) { 02028 const struct tone_zone_sound *ts = NULL; 02029 switch (condition) { 02030 case AST_CONTROL_RINGING: 02031 ts = ast_get_indication_tone(chan->zone, "ring"); 02032 break; 02033 case AST_CONTROL_BUSY: 02034 ts = ast_get_indication_tone(chan->zone, "busy"); 02035 break; 02036 case AST_CONTROL_CONGESTION: 02037 ts = ast_get_indication_tone(chan->zone, "congestion"); 02038 break; 02039 } 02040 if (ts && ts->data[0]) { 02041 ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition); 02042 ast_playtones_start(chan,0,ts->data, 1); 02043 res = 0; 02044 } else if (condition == AST_CONTROL_PROGRESS) { 02045 /* ast_playtones_stop(chan); */ 02046 } else if (condition == AST_CONTROL_PROCEEDING) { 02047 /* Do nothing, really */ 02048 } else if (condition == AST_CONTROL_HOLD) { 02049 /* Do nothing.... */ 02050 } else if (condition == AST_CONTROL_UNHOLD) { 02051 /* Do nothing.... */ 02052 } else if (condition == AST_CONTROL_VIDUPDATE) { 02053 /* Do nothing.... */ 02054 } else { 02055 /* not handled */ 02056 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name); 02057 res = -1; 02058 } 02059 } 02060 else ast_playtones_stop(chan); 02061 } 02062 return res; 02063 }
|
|
Definition at line 3798 of file channel.c. Referenced by ast_serialize_showchan(), misdn_new(), and print_group(). 03799 { 03800 unsigned int i; 03801 int first=1; 03802 char num[3]; 03803 03804 buf[0] = '\0'; 03805 03806 if (!group) /* Return empty string if no group */ 03807 return(buf); 03808 03809 for (i=0; i<=63; i++) { /* Max group is 63 */ 03810 if (group & ((ast_group_t) 1 << i)) { 03811 if (!first) { 03812 strncat(buf, ", ", buflen); 03813 } else { 03814 first=0; 03815 } 03816 snprintf(num, sizeof(num), "%u", i); 03817 strncat(buf, num, buflen); 03818 } 03819 } 03820 return(buf); 03821 }
|
|
Definition at line 2165 of file channel.c. References ast_channel::_state, AST_FRAME_VOICE, ast_log(), 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(). 02166 { 02167 struct ast_frame a = { AST_FRAME_VOICE }; 02168 char nothing[128]; 02169 02170 /* Send an empty audio frame to get things moving */ 02171 if (chan->_state != AST_STATE_UP) { 02172 ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name); 02173 a.subclass = chan->rawwriteformat; 02174 a.data = nothing + AST_FRIENDLY_OFFSET; 02175 a.src = "ast_prod"; 02176 if (ast_write(chan, &a)) 02177 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name); 02178 } 02179 return 0; 02180 }
|
|
Queue a control frame.
Definition at line 682 of file channel.c. References 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_FLAG_BLOCKING, ast_frdup(), ast_frfree(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_channel::blocker, ast_frame::frametype, ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_frame::next, 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_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), 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 1784 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_deactivate_generator(), ast_do_masquerade(), AST_FLAG_DEFER_DTMF, AST_FLAG_EXCEPTION, AST_FLAG_ZOMBIE, ast_frame_dump(), ast_frfree(), ast_getformatname(), ast_log(), AST_MAX_FDS, ast_mutex_lock(), ast_mutex_unlock(), ast_seekstream(), ast_setstate(), ast_settimeout(), AST_STATE_UP, ast_strlen_zero(), ast_test_flag, ast_translate(), ast_writestream(), ast_channel::blocker, ast_channel::cdr, ast_frame::datalen, ast_channel::dtmff, ast_channel::dtmfq, ast_channel_tech::exception, ast_channel::fdno, ast_channel::fin, ast_frame::frametype, ast_generator::generate, ast_channel::generator, generator_force(), ast_channel::generatordata, ast_channel::insmpl, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::masq, ast_channel::monitor, ast_channel::name, ast_channel::nativeformats, ast_frame::next, ast_channel::outsmpl, queue_frame_to_spies(), ast_channel_tech::read, ast_channel_monitor::read_stream, ast_channel::readq, ast_channel::readtrans, ast_frame::samples, SEEK_FORCECUR, ast_channel::spies, SPY_READ, ast_frame::subclass, ast_channel::tech, ast_channel::timingdata, ast_channel::timingfd, and ast_channel::timingfunc. Referenced by __adsi_transmit_messages(), __ast_request_and_dial(), adsi_careful_send(), agent_ack_sleep(), agent_read(), app_exec(), ast_app_getvoice(), ast_feature_request_and_dial(), ast_generic_bridge(), ast_masq_park_call(), ast_play_and_prepend(), ast_play_and_record(), 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(). 01785 { 01786 struct ast_frame *f = NULL; 01787 int blah; 01788 int prestate; 01789 #ifdef ZAPTEL_OPTIMIZATIONS 01790 int (*func)(void *); 01791 void *data; 01792 int res; 01793 #endif 01794 static struct ast_frame null_frame = { 01795 AST_FRAME_NULL, 01796 }; 01797 01798 ast_mutex_lock(&chan->lock); 01799 if (chan->masq) { 01800 if (ast_do_masquerade(chan)) { 01801 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 01802 f = NULL; 01803 } else 01804 f = &null_frame; 01805 ast_mutex_unlock(&chan->lock); 01806 return f; 01807 } 01808 01809 /* Stop if we're a zombie or need a soft hangup */ 01810 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 01811 if (chan->generator) 01812 ast_deactivate_generator(chan); 01813 ast_mutex_unlock(&chan->lock); 01814 return NULL; 01815 } 01816 prestate = chan->_state; 01817 01818 if (!ast_test_flag(chan, AST_FLAG_DEFER_DTMF) && !ast_strlen_zero(chan->dtmfq)) { 01819 /* We have DTMF that has been deferred. Return it now */ 01820 chan->dtmff.frametype = AST_FRAME_DTMF; 01821 chan->dtmff.subclass = chan->dtmfq[0]; 01822 /* Drop first digit */ 01823 memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1); 01824 ast_mutex_unlock(&chan->lock); 01825 return &chan->dtmff; 01826 } 01827 01828 /* Read and ignore anything on the alertpipe, but read only 01829 one sizeof(blah) per frame that we send from it */ 01830 if (chan->alertpipe[0] > -1) { 01831 read(chan->alertpipe[0], &blah, sizeof(blah)); 01832 } 01833 #ifdef ZAPTEL_OPTIMIZATIONS 01834 if ((chan->timingfd > -1) && (chan->fdno == AST_MAX_FDS - 2) && ast_test_flag(chan, AST_FLAG_EXCEPTION)) { 01835 ast_clear_flag(chan, AST_FLAG_EXCEPTION); 01836 blah = -1; 01837 /* IF we can't get event, assume it's an expired as-per the old interface */ 01838 res = ioctl(chan->timingfd, ZT_GETEVENT, &blah); 01839 if (res) 01840 blah = ZT_EVENT_TIMER_EXPIRED; 01841 01842 if (blah == ZT_EVENT_TIMER_PING) { 01843 #if 0 01844 ast_log(LOG_NOTICE, "Oooh, there's a PING!\n"); 01845 #endif 01846 if (!chan->readq || !chan->readq->next) { 01847 /* Acknowledge PONG unless we need it again */ 01848 #if 0 01849 ast_log(LOG_NOTICE, "Sending a PONG!\n"); 01850 #endif 01851 if (ioctl(chan->timingfd, ZT_TIMERPONG, &blah)) { 01852 ast_log(LOG_WARNING, "Failed to pong timer on '%s': %s\n", chan->name, strerror(errno)); 01853 } 01854 } 01855 } else if (blah == ZT_EVENT_TIMER_EXPIRED) { 01856 ioctl(chan->timingfd, ZT_TIMERACK, &blah); 01857 func = chan->timingfunc; 01858 data = chan->timingdata; 01859 ast_mutex_unlock(&chan->lock); 01860 if (func) { 01861 #if 0 01862 ast_log(LOG_DEBUG, "Calling private function\n"); 01863 #endif 01864 func(data); 01865 } else { 01866 blah = 0; 01867 ast_mutex_lock(&chan->lock); 01868 ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah); 01869 chan->timingdata = NULL; 01870 ast_mutex_unlock(&chan->lock); 01871 } 01872 f = &null_frame; 01873 return f; 01874 } else 01875 ast_log(LOG_NOTICE, "No/unknown event '%d' on timer for '%s'?\n", blah, chan->name); 01876 } 01877 #endif 01878 /* Check for pending read queue */ 01879 if (chan->readq) { 01880 f = chan->readq; 01881 chan->readq = f->next; 01882 /* Interpret hangup and return NULL */ 01883 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) { 01884 ast_frfree(f); 01885 f = NULL; 01886 } 01887 } else { 01888 chan->blocker = pthread_self(); 01889 if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) { 01890 if (chan->tech->exception) 01891 f = chan->tech->exception(chan); 01892 else { 01893 ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name); 01894 f = &null_frame; 01895 } 01896 /* Clear the exception flag */ 01897 ast_clear_flag(chan, AST_FLAG_EXCEPTION); 01898 } else { 01899 if (chan->tech->read) 01900 f = chan->tech->read(chan); 01901 else 01902 ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name); 01903 } 01904 } 01905 01906 01907 if (f && (f->frametype == AST_FRAME_VOICE)) { 01908 if (!(f->subclass & chan->nativeformats)) { 01909 /* This frame can't be from the current native formats -- drop it on the 01910 floor */ 01911 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)); 01912 ast_frfree(f); 01913 f = &null_frame; 01914 } else { 01915 if (chan->spies) 01916 queue_frame_to_spies(chan, f, SPY_READ); 01917 01918 if (chan->monitor && chan->monitor->read_stream ) { 01919 #ifndef MONITOR_CONSTANT_DELAY 01920 int jump = chan->outsmpl - chan->insmpl - 4 * f->samples; 01921 if (jump >= 0) { 01922 if (ast_seekstream(chan->monitor->read_stream, jump + f->samples, SEEK_FORCECUR) == -1) 01923 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 01924 chan->insmpl += jump + 4 * f->samples; 01925 } else 01926 chan->insmpl+= f->samples; 01927 #else 01928 int jump = chan->outsmpl - chan->insmpl; 01929 if (jump - MONITOR_DELAY >= 0) { 01930 if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1) 01931 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 01932 chan->insmpl += jump; 01933 } else 01934 chan->insmpl += f->samples; 01935 #endif 01936 if (ast_writestream(chan->monitor->read_stream, f) < 0) 01937 ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n"); 01938 } 01939 if (chan->readtrans) { 01940 f = ast_translate(chan->readtrans, f, 1); 01941 if (!f) 01942 f = &null_frame; 01943 } 01944 } 01945 } 01946 01947 /* Make sure we always return NULL in the future */ 01948 if (!f) { 01949 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01950 if (chan->generator) 01951 ast_deactivate_generator(chan); 01952 /* End the CDR if appropriate */ 01953 if (chan->cdr) 01954 ast_cdr_end(chan->cdr); 01955 } else if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF) && f->frametype == AST_FRAME_DTMF) { 01956 if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2) 01957 chan->dtmfq[strlen(chan->dtmfq)] = f->subclass; 01958 else 01959 ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name); 01960 f = &null_frame; 01961 } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_ANSWER)) { 01962 if (prestate == AST_STATE_UP) { 01963 ast_log(LOG_DEBUG, "Dropping duplicate answer!\n"); 01964 f = &null_frame; 01965 } 01966 /* Answer the CDR */ 01967 ast_setstate(chan, AST_STATE_UP); 01968 ast_cdr_answer(chan->cdr); 01969 } 01970 01971 /* Run any generator sitting on the line */ 01972 if (f && (f->frametype == AST_FRAME_VOICE) && chan->generatordata) { 01973 /* Mask generator data temporarily and apply. If there is a timing function, it 01974 will be calling the generator instead */ 01975 void *tmp; 01976 int res; 01977 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples); 01978 01979 if (chan->timingfunc) { 01980 ast_log(LOG_DEBUG, "Generator got voice, switching to phase locked mode\n"); 01981 ast_settimeout(chan, 0, NULL, NULL); 01982 } 01983 tmp = chan->generatordata; 01984 chan->generatordata = NULL; 01985 generate = chan->generator->generate; 01986 res = generate(chan, tmp, f->datalen, f->samples); 01987 chan->generatordata = tmp; 01988 if (res) { 01989 ast_log(LOG_DEBUG, "Auto-deactivating generator\n"); 01990 ast_deactivate_generator(chan); 01991 } 01992 } else if (f && (f->frametype == AST_FRAME_CNG)) { 01993 if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) { 01994 ast_log(LOG_DEBUG, "Generator got CNG, switching to zap timed mode\n"); 01995 ast_settimeout(chan, 160, generator_force, chan); 01996 } 01997 } 01998 /* High bit prints debugging */ 01999 if (chan->fin & 0x80000000) 02000 ast_frame_dump(chan->name, f, "<<"); 02001 if ((chan->fin & 0x7fffffff) == 0x7fffffff) 02002 chan->fin &= 0x80000000; 02003 else 02004 chan->fin++; 02005 ast_mutex_unlock(&chan->lock); 02006 return f; 02007 }
|
|
Definition at line 2585 of file channel.c. References ast_check_hangup(), AST_DIGIT_ANY, AST_FLAG_ZOMBIE, ast_stopstream(), ast_test_flag, ast_waitfordigit(), ast_waitstream(), s, 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(). 02586 { 02587 int pos=0; 02588 int to = ftimeout; 02589 int d; 02590 02591 /* XXX Merge with full version? XXX */ 02592 /* Stop if we're a zombie or need a soft hangup */ 02593 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 02594 return -1; 02595 if (!len) 02596 return -1; 02597 do { 02598 if (c->stream) { 02599 d = ast_waitstream(c, AST_DIGIT_ANY); 02600 ast_stopstream(c); 02601 usleep(1000); 02602 if (!d) 02603 d = ast_waitfordigit(c, to); 02604 } else { 02605 d = ast_waitfordigit(c, to); 02606 } 02607 if (d < 0) 02608 return -1; 02609 if (d == 0) { 02610 s[pos]='\0'; 02611 return 1; 02612 } 02613 if (!strchr(enders, d)) 02614 s[pos++] = d; 02615 if (strchr(enders, d) || (pos >= len)) { 02616 s[pos]='\0'; 02617 return 0; 02618 } 02619 to = timeout; 02620 } while(1); 02621 /* Never reached */ 02622 return 0; 02623 }
|
|
Definition at line 2625 of file channel.c. References ast_check_hangup(), AST_DIGIT_ANY, AST_FLAG_ZOMBIE, ast_stopstream(), ast_test_flag, ast_waitfordigit_full(), ast_waitstream_full(), s, and ast_channel::stream. Referenced by ast_app_getdata_full(). 02626 { 02627 int pos=0; 02628 int to = ftimeout; 02629 int d; 02630 02631 /* Stop if we're a zombie or need a soft hangup */ 02632 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 02633 return -1; 02634 if (!len) 02635 return -1; 02636 do { 02637 if (c->stream) { 02638 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd); 02639 ast_stopstream(c); 02640 usleep(1000); 02641 if (!d) 02642 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 02643 } else { 02644 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 02645 } 02646 if (d < 0) 02647 return -1; 02648 if (d == 0) { 02649 s[pos]='\0'; 02650 return 1; 02651 } 02652 if (d == 1) { 02653 s[pos]='\0'; 02654 return 2; 02655 } 02656 if (!strchr(enders, d)) 02657 s[pos++] = d; 02658 if (strchr(enders, d) || (pos >= len)) { 02659 s[pos]='\0'; 02660 return 0; 02661 } 02662 to = timeout; 02663 } while(1); 02664 /* Never reached */ 02665 return 0; 02666 }
|
|
Definition at line 2065 of file channel.c. References ast_recvtext(), and free. Referenced by handle_recvchar(). 02066 { 02067 int c; 02068 char *buf = ast_recvtext(chan, timeout); 02069 if (buf == NULL) 02070 return -1; /* error or timeout */ 02071 c = *(unsigned char *)buf; 02072 free(buf); 02073 return c; 02074 }
|
|
Definition at line 2076 of file channel.c. References ast_check_hangup(), AST_FRAME_CONTROL, 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(). 02077 { 02078 int res, done = 0; 02079 char *buf = NULL; 02080 02081 while (!done) { 02082 struct ast_frame *f; 02083 if (ast_check_hangup(chan)) 02084 break; 02085 res = ast_waitfor(chan, timeout); 02086 if (res <= 0) /* timeout or error */ 02087 break; 02088 timeout = res; /* update timeout */ 02089 f = ast_read(chan); 02090 if (f == NULL) 02091 break; /* no frame */ 02092 if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP) 02093 done = 1; /* force a break */ 02094 else if (f->frametype == AST_FRAME_TEXT) { /* what we want */ 02095 buf = strndup((char *) f->data, f->datalen); /* dup and break */ 02096 done = 1; 02097 } 02098 ast_frfree(f); 02099 } 02100 return buf; 02101 }
|
|
Requests a channel.
Definition at line 2491 of file channel.c. References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_state2str(), ast_translator_best_choice(), 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, type, and ast_channel::uniqueid. Referenced by __ast_request_and_dial(), agent_request(), ast_feature_request_and_dial(), attempt_reconnect(), build_conf(), chanavail_exec(), dial_exec_full(), features_alloc(), function_ilink(), ring_entry(), rpt(), rpt_call(), rpt_exec(), rpt_tele_thread(), and wait_for_answer(). 02492 { 02493 struct chanlist *chan; 02494 struct ast_channel *c; 02495 int capabilities; 02496 int fmt; 02497 int res; 02498 int foo; 02499 02500 if (!cause) 02501 cause = &foo; 02502 *cause = AST_CAUSE_NOTDEFINED; 02503 02504 if (ast_mutex_lock(&chlock)) { 02505 ast_log(LOG_WARNING, "Unable to lock channel list\n"); 02506 return NULL; 02507 } 02508 02509 for (chan = backends; chan; chan = chan->next) { 02510 if (strcasecmp(type, chan->tech->type)) 02511 continue; 02512 02513 capabilities = chan->tech->capabilities; 02514 fmt = format; 02515 res = ast_translator_best_choice(&fmt, &capabilities); 02516 if (res < 0) { 02517 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->tech->capabilities, format); 02518 ast_mutex_unlock(&chlock); 02519 return NULL; 02520 } 02521 ast_mutex_unlock(&chlock); 02522 if (!chan->tech->requester) 02523 return NULL; 02524 02525 if (!(c = chan->tech->requester(type, capabilities, data, cause))) 02526 return NULL; 02527 02528 if (c->_state == AST_STATE_DOWN) { 02529 manager_event(EVENT_FLAG_CALL, "Newchannel", 02530 "Channel: %s\r\n" 02531 "State: %s\r\n" 02532 "CallerID: %s\r\n" 02533 "CallerIDName: %s\r\n" 02534 "Uniqueid: %s\r\n", 02535 c->name, ast_state2str(c->_state), 02536 c->cid.cid_num ? c->cid.cid_num : "<unknown>", 02537 c->cid.cid_name ? c->cid.cid_name : "<unknown>", 02538 c->uniqueid); 02539 } 02540 return c; 02541 } 02542 02543 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type); 02544 *cause = AST_CAUSE_NOSUCHDRIVER; 02545 ast_mutex_unlock(&chlock); 02546 02547 return NULL; 02548 }
|
|
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 2486 of file channel.c. References __ast_request_and_dial(), and type. Referenced by ast_pbx_outgoing_exten(). 02487 { 02488 return __ast_request_and_dial(type, format, data, timeout, outstate, cidnum, cidname, NULL); 02489 }
|
|
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 1145 of file channel.h. References tv. Referenced by do_monitor(), do_parking_thread(), and sound_thread(). 01146 { 01147 #ifdef __linux__ 01148 return select(nfds, rfds, wfds, efds, tvp); 01149 #else 01150 if (tvp) { 01151 struct timeval tv, tvstart, tvend, tvlen; 01152 int res; 01153 01154 tv = *tvp; 01155 gettimeofday(&tvstart, NULL); 01156 res = select(nfds, rfds, wfds, efds, tvp); 01157 gettimeofday(&tvend, NULL); 01158 timersub(&tvend, &tvstart, &tvlen); 01159 timersub(&tv, &tvlen, tvp); 01160 if (tvp->tv_sec < 0 || (tvp->tv_sec == 0 && tvp->tv_usec < 0)) { 01161 tvp->tv_sec = 0; 01162 tvp->tv_usec = 0; 01163 } 01164 return res; 01165 } 01166 else 01167 return select(nfds, rfds, wfds, efds, NULL); 01168 #endif 01169 }
|
|
Definition at line 2160 of file channel.c. References do_senddigit(). Referenced by dial_exec_full(), and features_digit(). 02161 { 02162 return do_senddigit(chan, digit); 02163 }
|
|
Definition at line 2103 of file channel.c. References ast_check_hangup(), ast_clear_flag, AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_test_flag, CHECK_BLOCKING, ast_channel_tech::send_text, ast_channel::tech, and text. Referenced by agent_sendtext(), handle_sendtext(), and sendtext_exec(). 02104 { 02105 int res = 0; 02106 /* Stop if we're a zombie or need a soft hangup */ 02107 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) 02108 return -1; 02109 CHECK_BLOCKING(chan); 02110 if (chan->tech->send_text) 02111 res = chan->tech->send_text(chan, text); 02112 ast_clear_flag(chan, AST_FLAG_BLOCKING); 02113 return res; 02114 }
|
|
Definition at line 3097 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(), ast_feature_request_and_dial(), callerid_write(), dial_exec_full(), disa_exec(), get_callerid(), handle_setcallerid(), lookupcidname_exec(), monitor_handle_notowned(), privacy_exec(), rpt_exec(), setcallerid_exec(), ss_thread(), vpb_new(), wait_for_answer(), zt_new(), and zt_read(). 03098 { 03099 if (callerid) { 03100 if (chan->cid.cid_num) 03101 free(chan->cid.cid_num); 03102 if (ast_strlen_zero(callerid)) 03103 chan->cid.cid_num = NULL; 03104 else 03105 chan->cid.cid_num = strdup(callerid); 03106 } 03107 if (calleridname) { 03108 if (chan->cid.cid_name) 03109 free(chan->cid.cid_name); 03110 if (ast_strlen_zero(calleridname)) 03111 chan->cid.cid_name = NULL; 03112 else 03113 chan->cid.cid_name = strdup(calleridname); 03114 } 03115 if (ani) { 03116 if (chan->cid.cid_ani) 03117 free(chan->cid.cid_ani); 03118 if (ast_strlen_zero(ani)) 03119 chan->cid.cid_ani = NULL; 03120 else 03121 chan->cid.cid_ani = strdup(ani); 03122 } 03123 if (chan->cdr) 03124 ast_cdr_setcid(chan->cdr, chan); 03125 manager_event(EVENT_FLAG_CALL, "Newcallerid", 03126 "Channel: %s\r\n" 03127 "CallerID: %s\r\n" 03128 "CallerIDName: %s\r\n" 03129 "Uniqueid: %s\r\n" 03130 "CID-CallingPres: %d (%s)\r\n", 03131 chan->name, chan->cid.cid_num ? 03132 chan->cid.cid_num : "<Unknown>", 03133 chan->cid.cid_name ? 03134 chan->cid.cid_name : "<Unknown>", 03135 chan->uniqueid, 03136 chan->cid.cid_pres, 03137 ast_describe_caller_presentation(chan->cid.cid_pres) 03138 ); 03139 }
|
|
Definition at line 2360 of file channel.c. References fmt, 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(), 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(). 02361 { 02362 return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat, 02363 &chan->readtrans, 0); 02364 }
|
|
adds a list of channel variables to a channel
Definition at line 3823 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(). 03824 { 03825 struct ast_variable *cur; 03826 03827 for (cur = vars; cur; cur = cur->next) 03828 pbx_builtin_setvar_helper(chan, cur->name, cur->value); 03829 }
|
|
Definition at line 2366 of file channel.c. References fmt, 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_moh_files_next(), 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_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(). 02367 { 02368 return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat, 02369 &chan->writetrans, 1); 02370 }
|
|
Change the state of a channel.
Definition at line 3141 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(). 03142 { 03143 int oldstate = chan->_state; 03144 03145 if (oldstate == state) 03146 return 0; 03147 03148 chan->_state = state; 03149 ast_device_state_changed_literal(chan->name); 03150 manager_event(EVENT_FLAG_CALL, 03151 (oldstate == AST_STATE_DOWN) ? "Newchannel" : "Newstate", 03152 "Channel: %s\r\n" 03153 "State: %s\r\n" 03154 "CallerID: %s\r\n" 03155 "CallerIDName: %s\r\n" 03156 "Uniqueid: %s\r\n", 03157 chan->name, ast_state2str(chan->_state), 03158 chan->cid.cid_num ? chan->cid.cid_num : "<unknown>", 03159 chan->cid.cid_name ? chan->cid.cid_name : "<unknown>", 03160 chan->uniqueid); 03161 03162 return 0; 03163 }
|
|
Definition at line 1709 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(). 01710 { 01711 int res = -1; 01712 #ifdef ZAPTEL_OPTIMIZATIONS 01713 if (c->timingfd > -1) { 01714 if (!func) { 01715 samples = 0; 01716 data = 0; 01717 } 01718 ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples); 01719 res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples); 01720 c->timingfunc = func; 01721 c->timingdata = data; 01722 } 01723 #endif 01724 return res; 01725 }
|
|
Returns non-zero if Asterisk is being shut down Definition at line 271 of file channel.c. 00272 {
00273 return shutting_down;
00274 }
|
|
Softly hangup up a channel.
Definition at line 1117 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(). 01118 { 01119 int res; 01120 ast_mutex_lock(&chan->lock); 01121 res = ast_softhangup_nolock(chan, cause); 01122 ast_mutex_unlock(&chan->lock); 01123 return res; 01124 }
|
|
Softly hangup up a channel (no channel lock).
Definition at line 1101 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, and ast_channel::name. Referenced by ast_async_goto(), ast_softhangup(), attempt_transfer(), oh323_indicate(), sip_indicate(), and skinny_indicate(). 01102 { 01103 int res = 0; 01104 struct ast_frame f = { AST_FRAME_NULL }; 01105 if (option_debug) 01106 ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name); 01107 /* Inform channel driver that we need to be hung up, if it cares */ 01108 chan->_softhangup |= cause; 01109 ast_queue_frame(chan, &f); 01110 /* Interrupt any poll call or such */ 01111 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) 01112 pthread_kill(chan->blocker, SIGURG); 01113 return res; 01114 }
|
|
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 3691 of file channel.c. References ast_frfree(), ast_read(), ast_tonepair_start(), ast_waitfor(), and ast_channel::generatordata. Referenced by zapateller_exec(). 03692 { 03693 struct ast_frame *f; 03694 int res; 03695 03696 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol))) 03697 return res; 03698 03699 /* Give us some wiggle room */ 03700 while(chan->generatordata && (ast_waitfor(chan, 100) >= 0)) { 03701 f = ast_read(chan); 03702 if (f) 03703 ast_frfree(f); 03704 else 03705 return -1; 03706 } 03707 return 0; 03708 }
|
|
Start a tone going Definition at line 3670 of file channel.c. References ast_activate_generator(), tonepair_def::duration, tonepair_def::freq1, tonepair_def::freq2, tonepair, and tonepair_def::vol. Referenced by ast_tonepair(), play_dialtone(), play_tone_pair(), rpt_tele_thread(), and sendnoise(). 03671 { 03672 struct tonepair_def d = { 0, }; 03673 03674 d.freq1 = freq1; 03675 d.freq2 = freq2; 03676 d.duration = duration; 03677 if (vol < 1) 03678 d.vol = 8192; 03679 else 03680 d.vol = vol; 03681 if (ast_activate_generator(chan, &tonepair, &d)) 03682 return -1; 03683 return 0; 03684 }
|
|
Stop a tone from playing Definition at line 3686 of file channel.c. References ast_deactivate_generator(). Referenced by sendnoise(). 03687 { 03688 ast_deactivate_generator(chan); 03689 }
|
|
Transfer a channel (if supported). Returns -1 on error, 0 if not supported and 1 if supported and requested.
Definition at line 2567 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(). 02568 { 02569 int res = -1; 02570 02571 /* Stop if we're a zombie or need a soft hangup */ 02572 ast_mutex_lock(&chan->lock); 02573 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) { 02574 if (chan->tech->transfer) { 02575 res = chan->tech->transfer(chan, dest); 02576 if (!res) 02577 res = 1; 02578 } else 02579 res = 0; 02580 } 02581 ast_mutex_unlock(&chan->lock); 02582 return res; 02583 }
|
|
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 1665 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(), 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(). 01666 { 01667 struct ast_channel *chan; 01668 int oldms = ms; 01669 01670 chan = ast_waitfor_n(&c, 1, &ms); 01671 if (ms < 0) { 01672 if (oldms < 0) 01673 return 0; 01674 else 01675 return -1; 01676 } 01677 return ms; 01678 }
|
|
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 1660 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(). 01661 { 01662 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms); 01663 }
|
|
This version works on fd's only. Be careful with it. Definition at line 1446 of file channel.c. References ast_fdisset(), ast_log(), pollfd::events, pollfd::fd, LOG_ERROR, poll(), and POLLIN. Referenced by ast_modem_expect(), ast_modem_read_response(), bestdata_read(), dundi_lookup_internal(), and dundi_precache_internal(). 01447 { 01448 struct timeval start = { 0 , 0 }; 01449 int res; 01450 int x, y; 01451 int winner = -1; 01452 int spoint; 01453 struct pollfd *pfds; 01454 01455 pfds = alloca(sizeof(struct pollfd) * n); 01456 if (!pfds) { 01457 ast_log(LOG_ERROR, "Out of memory\n"); 01458 return -1; 01459 } 01460 if (*ms > 0) 01461 start = ast_tvnow(); 01462 y = 0; 01463 for (x=0; x < n; x++) { 01464 if (fds[x] > -1) { 01465 pfds[y].fd = fds[x]; 01466 pfds[y].events = POLLIN | POLLPRI; 01467 y++; 01468 } 01469 } 01470 res = poll(pfds, y, *ms); 01471 if (res < 0) { 01472 /* Simulate a timeout if we were interrupted */ 01473 if (errno != EINTR) 01474 *ms = -1; 01475 else 01476 *ms = 0; 01477 return -1; 01478 } 01479 spoint = 0; 01480 for (x=0; x < n; x++) { 01481 if (fds[x] > -1) { 01482 if ((res = ast_fdisset(pfds, fds[x], y, &spoint))) { 01483 winner = fds[x]; 01484 if (exception) { 01485 if (res & POLLPRI) 01486 *exception = -1; 01487 else 01488 *exception = 0; 01489 } 01490 } 01491 } 01492 } 01493 if (*ms > 0) { 01494 *ms -= ast_tvdiff_ms(ast_tvnow(), start); 01495 if (*ms < 0) 01496 *ms = 0; 01497 } 01498 return winner; 01499 }
|
|
Waits for activity on a group of channels.
Definition at line 1502 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, CHECK_BLOCKING, pollfd::events, pollfd::fd, ast_channel::fdno, ast_channel::fds, lock, LOG_ERROR, LOG_WARNING, ast_channel::masq, poll(), POLLIN, 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(). 01504 { 01505 struct timeval start = { 0 , 0 }; 01506 struct pollfd *pfds; 01507 int res; 01508 long rms; 01509 int x, y, max; 01510 int spoint; 01511 time_t now = 0; 01512 long whentohangup = 0, havewhen = 0, diff; 01513 struct ast_channel *winner = NULL; 01514 01515 pfds = alloca(sizeof(struct pollfd) * (n * AST_MAX_FDS + nfds)); 01516 if (!pfds) { 01517 ast_log(LOG_ERROR, "Out of memory\n"); 01518 *outfd = -1; 01519 return NULL; 01520 } 01521 01522 if (outfd) 01523 *outfd = -99999; 01524 if (exception) 01525 *exception = 0; 01526 01527 /* Perform any pending masquerades */ 01528 for (x=0; x < n; x++) { 01529 ast_mutex_lock(&c[x]->lock); 01530 if (c[x]->whentohangup) { 01531 if (!havewhen) 01532 time(&now); 01533 diff = c[x]->whentohangup - now; 01534 if (!havewhen || (diff < whentohangup)) { 01535 havewhen++; 01536 whentohangup = diff; 01537 } 01538 } 01539 if (c[x]->masq) { 01540 if (ast_do_masquerade(c[x])) { 01541 ast_log(LOG_WARNING, "Masquerade failed\n"); 01542 *ms = -1; 01543 ast_mutex_unlock(&c[x]->lock); 01544 return NULL; 01545 } 01546 } 01547 ast_mutex_unlock(&c[x]->lock); 01548 } 01549 01550 rms = *ms; 01551 01552 if (havewhen) { 01553 if ((*ms < 0) || (whentohangup * 1000 < *ms)) { 01554 rms = whentohangup * 1000; 01555 } 01556 } 01557 max = 0; 01558 for (x=0; x < n; x++) { 01559 for (y=0; y< AST_MAX_FDS; y++) { 01560 if (c[x]->fds[y] > -1) { 01561 pfds[max].fd = c[x]->fds[y]; 01562 pfds[max].events = POLLIN | POLLPRI; 01563 pfds[max].revents = 0; 01564 max++; 01565 } 01566 } 01567 CHECK_BLOCKING(c[x]); 01568 } 01569 for (x=0; x < nfds; x++) { 01570 if (fds[x] > -1) { 01571 pfds[max].fd = fds[x]; 01572 pfds[max].events = POLLIN | POLLPRI; 01573 pfds[max].revents = 0; 01574 max++; 01575 } 01576 } 01577 if (*ms > 0) 01578 start = ast_tvnow(); 01579 01580 if (sizeof(int) == 4) { 01581 do { 01582 int kbrms = rms; 01583 if (kbrms > 600000) 01584 kbrms = 600000; 01585 res = poll(pfds, max, kbrms); 01586 if (!res) 01587 rms -= kbrms; 01588 } while (!res && (rms > 0)); 01589 } else { 01590 res = poll(pfds, max, rms); 01591 } 01592 01593 if (res < 0) { 01594 for (x=0; x < n; x++) 01595 ast_clear_flag(c[x], AST_FLAG_BLOCKING); 01596 /* Simulate a timeout if we were interrupted */ 01597 if (errno != EINTR) 01598 *ms = -1; 01599 else { 01600 /* Just an interrupt */ 01601 #if 0 01602 *ms = 0; 01603 #endif 01604 } 01605 return NULL; 01606 } else { 01607 /* If no fds signalled, then timeout. So set ms = 0 01608 since we may not have an exact timeout. 01609 */ 01610 if (res == 0) 01611 *ms = 0; 01612 } 01613 01614 if (havewhen) 01615 time(&now); 01616 spoint = 0; 01617 for (x=0; x < n; x++) { 01618 ast_clear_flag(c[x], AST_FLAG_BLOCKING); 01619 if (havewhen && c[x]->whentohangup && (now > c[x]->whentohangup)) { 01620 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 01621 if (!winner) 01622 winner = c[x]; 01623 } 01624 for (y=0; y < AST_MAX_FDS; y++) { 01625 if (c[x]->fds[y] > -1) { 01626 if ((res = ast_fdisset(pfds, c[x]->fds[y], max, &spoint))) { 01627 if (res & POLLPRI) 01628 ast_set_flag(c[x], AST_FLAG_EXCEPTION); 01629 else 01630 ast_clear_flag(c[x], AST_FLAG_EXCEPTION); 01631 c[x]->fdno = y; 01632 winner = c[x]; 01633 } 01634 } 01635 } 01636 } 01637 for (x=0; x < nfds; x++) { 01638 if (fds[x] > -1) { 01639 if ((res = ast_fdisset(pfds, fds[x], max, &spoint))) { 01640 if (outfd) 01641 *outfd = fds[x]; 01642 if (exception) { 01643 if (res & POLLPRI) 01644 *exception = -1; 01645 else 01646 *exception = 0; 01647 } 01648 winner = NULL; 01649 } 01650 } 01651 } 01652 if (*ms > 0) { 01653 *ms -= ast_tvdiff_ms(ast_tvnow(), start); 01654 if (*ms < 0) 01655 *ms = 0; 01656 } 01657 return winner; 01658 }
|
|
Definition at line 1680 of file channel.c. References ast_check_hangup(), AST_FLAG_ZOMBIE, 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(). 01681 { 01682 /* XXX Should I be merged with waitfordigit_full XXX */ 01683 struct ast_frame *f; 01684 int result = 0; 01685 01686 /* Stop if we're a zombie or need a soft hangup */ 01687 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 01688 return -1; 01689 01690 /* Wait for a digit, no more than ms milliseconds total. */ 01691 while(ms && !result) { 01692 ms = ast_waitfor(c, ms); 01693 if (ms < 0) /* Error */ 01694 result = -1; 01695 else if (ms > 0) { 01696 /* Read something */ 01697 f = ast_read(c); 01698 if (f) { 01699 if (f->frametype == AST_FRAME_DTMF) 01700 result = f->subclass; 01701 ast_frfree(f); 01702 } else 01703 result = -1; 01704 } 01705 } 01706 return result; 01707 }
|
|
Definition at line 1727 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(). 01728 { 01729 struct ast_frame *f; 01730 struct ast_channel *rchan; 01731 int outfd; 01732 int res; 01733 01734 /* Stop if we're a zombie or need a soft hangup */ 01735 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 01736 return -1; 01737 /* Wait for a digit, no more than ms milliseconds total. */ 01738 while(ms) { 01739 errno = 0; 01740 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 01741 if ((!rchan) && (outfd < 0) && (ms)) { 01742 if (errno == 0 || errno == EINTR) 01743 continue; 01744 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 01745 return -1; 01746 } else if (outfd > -1) { 01747 /* The FD we were watching has something waiting */ 01748 return 1; 01749 } else if (rchan) { 01750 f = ast_read(c); 01751 if(!f) { 01752 return -1; 01753 } 01754 01755 switch(f->frametype) { 01756 case AST_FRAME_DTMF: 01757 res = f->subclass; 01758 ast_frfree(f); 01759 return res; 01760 case AST_FRAME_CONTROL: 01761 switch(f->subclass) { 01762 case AST_CONTROL_HANGUP: 01763 ast_frfree(f); 01764 return -1; 01765 case AST_CONTROL_RINGING: 01766 case AST_CONTROL_ANSWER: 01767 /* Unimportant */ 01768 break; 01769 default: 01770 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass); 01771 } 01772 case AST_FRAME_VOICE: 01773 /* Write audio if appropriate */ 01774 if (audiofd > -1) 01775 write(audiofd, f->data, f->datalen); 01776 } 01777 /* Ignore */ 01778 ast_frfree(f); 01779 } 01780 } 01781 return 0; /* Time is up */ 01782 }
|
|
Get channel by name prefix (locks channel) Definition at line 812 of file channel.c. References channel_find_locked(), and name. 00813 { 00814 return channel_find_locked(chan, name, namelen, NULL, NULL); 00815 }
|
|
Definition at line 2193 of file channel.c. References ast_channel::_softhangup, ast_check_hangup(), ast_clear_flag, ast_deactivate_generator(), ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_WRITE_INT, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frame_dump(), AST_FRAME_HTML, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_seekstream(), ast_test_flag, ast_translate(), ast_writestream(), CHECK_BLOCKING, ast_frame::data, ast_frame::datalen, do_senddigit(), ast_channel::fout, ast_frame::frametype, ast_channel::generatordata, ast_channel::insmpl, ast_channel::lock, LOG_DTMF, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::name, ast_channel::outsmpl, queue_frame_to_spies(), ast_frame::samples, SEEK_FORCECUR, ast_channel_tech::send_html, ast_channel_tech::send_text, ast_channel::spies, SPY_WRITE, ast_frame::subclass, ast_channel::tech, ast_channel_tech::write, ast_channel_monitor::write_stream, ast_channel_tech::write_video, and ast_channel::writetrans. Referenced by adsi_careful_send(), agent_write(), ast_dtmf_stream(), ast_generic_bridge(), ast_prod(), ast_readaudio_callback(), ast_readvideo_callback(), ast_rtp_bridge(), ast_write_video(), conf_run(), dictate_exec(), echo_exec(), features_write(), function_ilink(), gen_generate(), handle_link_data(), iax2_bridge(), linear_generator(), milliwatt_generate(), misdn_bridge(), moh_files_generator(), moh_generate(), mp3_exec(), NBScat_exec(), playtones_generator(), rpt(), rpt_call(), rpt_exec(), send_link_dtmf(), send_tone_burst(), send_waveform_to_channel(), silence_generator_generate(), sms_generate(), spy_generate(), tonepair_generator(), wait_for_answer(), and zt_bridge(). 02194 { 02195 int res = -1; 02196 struct ast_frame *f = NULL; 02197 /* Stop if we're a zombie or need a soft hangup */ 02198 ast_mutex_lock(&chan->lock); 02199 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 02200 ast_mutex_unlock(&chan->lock); 02201 return -1; 02202 } 02203 /* Handle any pending masquerades */ 02204 if (chan->masq) { 02205 if (ast_do_masquerade(chan)) { 02206 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 02207 ast_mutex_unlock(&chan->lock); 02208 return -1; 02209 } 02210 } 02211 if (chan->masqr) { 02212 ast_mutex_unlock(&chan->lock); 02213 return 0; 02214 } 02215 if (chan->generatordata) { 02216 if (ast_test_flag(chan, AST_FLAG_WRITE_INT)) 02217 ast_deactivate_generator(chan); 02218 else { 02219 ast_mutex_unlock(&chan->lock); 02220 return 0; 02221 } 02222 } 02223 /* High bit prints debugging */ 02224 if (chan->fout & 0x80000000) 02225 ast_frame_dump(chan->name, fr, ">>"); 02226 CHECK_BLOCKING(chan); 02227 switch(fr->frametype) { 02228 case AST_FRAME_CONTROL: 02229 /* XXX Interpret control frames XXX */ 02230 ast_log(LOG_WARNING, "Don't know how to handle control frames yet\n"); 02231 break; 02232 case AST_FRAME_DTMF: 02233 ast_clear_flag(chan, AST_FLAG_BLOCKING); 02234 ast_mutex_unlock(&chan->lock); 02235 res = do_senddigit(chan,fr->subclass); 02236 ast_mutex_lock(&chan->lock); 02237 CHECK_BLOCKING(chan); 02238 break; 02239 case AST_FRAME_TEXT: 02240 if (chan->tech->send_text) 02241 res = chan->tech->send_text(chan, (char *) fr->data); 02242 else 02243 res = 0; 02244 break; 02245 case AST_FRAME_HTML: 02246 if (chan->tech->send_html) 02247 res = chan->tech->send_html(chan, fr->subclass, (char *) fr->data, fr->datalen); 02248 else 02249 res = 0; 02250 break; 02251 case AST_FRAME_VIDEO: 02252 /* XXX Handle translation of video codecs one day XXX */ 02253 if (chan->tech->write_video) 02254 res = chan->tech->write_video(chan, fr); 02255 else 02256 res = 0; 02257 break; 02258 default: 02259 if (chan->tech->write) { 02260 f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr; 02261 if (f) { 02262 if (f->frametype == AST_FRAME_VOICE && chan->spies) 02263 queue_frame_to_spies(chan, f, SPY_WRITE); 02264 02265 if( chan->monitor && chan->monitor->write_stream && 02266 f && ( f->frametype == AST_FRAME_VOICE ) ) { 02267 #ifndef MONITOR_CONSTANT_DELAY 02268 int jump = chan->insmpl - chan->outsmpl - 4 * f->samples; 02269 if (jump >= 0) { 02270 if (ast_seekstream(chan->monitor->write_stream, jump + f->samples, SEEK_FORCECUR) == -1) 02271 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 02272 chan->outsmpl += jump + 4 * f->samples; 02273 } else 02274 chan->outsmpl += f->samples; 02275 #else 02276 int jump = chan->insmpl - chan->outsmpl; 02277 if (jump - MONITOR_DELAY >= 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; 02281 } else 02282 chan->outsmpl += f->samples; 02283 #endif 02284 if (ast_writestream(chan->monitor->write_stream, f) < 0) 02285 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n"); 02286 } 02287 02288 res = chan->tech->write(chan, f); 02289 } else 02290 res = 0; 02291 } 02292 } 02293 02294 /* It's possible this is a translated frame */ 02295 if (f && f->frametype == AST_FRAME_DTMF) { 02296 ast_log(LOG_DTMF, "%s : %c\n", chan->name, f->subclass); 02297 } else if (fr->frametype == AST_FRAME_DTMF) { 02298 ast_log(LOG_DTMF, "%s : %c\n", chan->name, fr->subclass); 02299 } 02300 02301 if (f && (f != fr)) 02302 ast_frfree(f); 02303 ast_clear_flag(chan, AST_FLAG_BLOCKING); 02304 /* Consider a write failure to force a soft hangup */ 02305 if (res < 0) 02306 chan->_softhangup |= AST_SOFTHANGUP_DEV; 02307 else { 02308 if ((chan->fout & 0x7fffffff) == 0x7fffffff) 02309 chan->fout &= 0x80000000; 02310 else 02311 chan->fout++; 02312 } 02313 ast_mutex_unlock(&chan->lock); 02314 return res; 02315 }
|
|
Definition at line 2182 of file channel.c. References ast_write(), ast_channel::tech, and ast_channel_tech::write_video. 02183 { 02184 int res; 02185 if (!chan->tech->write_video) 02186 return 0; 02187 res = ast_write(chan, fr); 02188 if (!res) 02189 res = 1; 02190 return res; 02191 }
|