#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 |
#define | AST_CHAN_TP_WANTSJITTER (1 << 0) |
#define | AST_FLAG_BLOCKING (1 << 3) |
#define | AST_FLAG_DEFER_DTMF (1 << 1) |
#define | AST_FLAG_EXCEPTION (1 << 5) |
#define | AST_FLAG_IN_AUTOLOOP (1 << 9) |
#define | AST_FLAG_MOH (1 << 6) |
#define | AST_FLAG_NBRIDGE (1 << 8) |
#define | AST_FLAG_SPYING (1 << 7) |
#define | AST_FLAG_WRITE_INT (1 << 2) |
#define | AST_FLAG_ZOMBIE (1 << 4) |
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. | |
static int | ast_fdisset (struct pollfd *pfds, int fd, int max, int *start) |
ast_channel * | ast_get_channel_by_exten_locked (const char *exten, const char *context) |
ast_channel * | ast_get_channel_by_name_locked (const char *chan) |
ast_channel * | ast_get_channel_by_name_prefix_locked (const char *name, const int namelen) |
const struct ast_channel_tech * | ast_get_channel_tech (const char *name) |
Get a channel technology structure by name. | |
ast_group_t | ast_get_group (char *s) |
int | ast_hangup (struct ast_channel *chan) |
Hang up a channel. | |
int | ast_indicate (struct ast_channel *chan, int condition) |
Indicates condition of channel. | |
char * | ast_print_group (char *buf, int buflen, ast_group_t group) |
int | ast_prod (struct ast_channel *chan) |
int | ast_queue_control (struct ast_channel *chan, int control) |
Queue a control frame. | |
int | ast_queue_frame (struct ast_channel *chan, struct ast_frame *f) |
Queue an outgoing frame. | |
int | ast_queue_hangup (struct ast_channel *chan) |
Queue a hangup frame. | |
ast_frame * | ast_read (struct ast_channel *chan) |
int | ast_readstring (struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders) |
int | ast_readstring_full (struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders, int audiofd, int ctrlfd) |
int | ast_recvchar (struct ast_channel *chan, int timeout) |
char * | ast_recvtext (struct ast_channel *chan, int timeout) |
ast_channel * | ast_request (const char *type, int format, void *data, int *status) |
Requests a channel. | |
ast_channel * | ast_request_and_dial (const char *type, int format, void *data, int timeout, int *reason, const char *cidnum, const char *cidname) |
Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it. | |
int | ast_safe_sleep (struct ast_channel *chan, int ms) |
Wait for a specied amount of time, looking for hangups. | |
int | ast_safe_sleep_conditional (struct ast_channel *chan, int ms, int(*cond)(void *), void *data) |
Wait for a specied amount of time, looking for hangups and a condition argument. | |
static int | ast_select (int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tvp) |
Waits for activity on a group of channels. | |
int | ast_senddigit (struct ast_channel *chan, char digit) |
int | ast_sendtext (struct ast_channel *chan, const char *text) |
void | ast_set_callerid (struct ast_channel *chan, const char *cidnum, const char *cidname, const char *ani) |
int | ast_set_read_format (struct ast_channel *chan, int format) |
void | ast_set_variables (struct ast_channel *chan, struct ast_variable *vars) |
adds a list of channel variables to a channel | |
int | ast_set_write_format (struct ast_channel *chan, int format) |
int | ast_setstate (struct ast_channel *chan, int state) |
Change the state of a channel. | |
int | ast_settimeout (struct ast_channel *c, int samples, int(*func)(void *data), void *data) |
int | ast_shutting_down (void) |
int | ast_softhangup (struct ast_channel *chan, int cause) |
Softly hangup up a channel. | |
int | ast_softhangup_nolock (struct ast_channel *chan, int cause) |
Softly hangup up a channel (no channel lock). | |
char * | ast_state2str (int state) |
int | ast_tonepair (struct ast_channel *chan, int freq1, int freq2, int duration, int vol) |
int | ast_tonepair_start (struct ast_channel *chan, int freq1, int freq2, int duration, int vol) |
void | ast_tonepair_stop (struct ast_channel *chan) |
int | ast_transfer (struct ast_channel *chan, char *dest) |
Transfer a channel (if supported). Returns -1 on error, 0 if not supported and 1 if supported and requested. | |
char * | ast_transfercapability2str (int transfercapability) |
int | ast_waitfor (struct ast_channel *chan, int ms) |
Wait for input on a channel. | |
ast_channel * | ast_waitfor_n (struct ast_channel **chan, int n, int *ms) |
int | ast_waitfor_n_fd (int *fds, int n, int *ms, int *exception) |
ast_channel * | ast_waitfor_nandfds (struct ast_channel **chan, int n, int *fds, int nfds, int *exception, int *outfd, int *ms) |
Waits for activity on a group of channels. | |
int | ast_waitfordigit (struct ast_channel *c, int ms) |
int | ast_waitfordigit_full (struct ast_channel *c, int ms, int audiofd, int ctrlfd) |
ast_channel * | ast_walk_channel_by_name_prefix_locked (struct ast_channel *chan, const char *name, const int namelen) |
int | ast_write (struct ast_channel *chan, struct ast_frame *frame) |
int | ast_write_video (struct ast_channel *chan, struct ast_frame *frame) |
Definition in file channel.h.
|
Definition at line 495 of file channel.h. Referenced by __adsi_transmit_messages(), and adsi_available(). |
|
|
|
Definition at line 496 of file channel.h. Referenced by __adsi_transmit_messages(), mgcp_new(), sip_new(), skinny_new(), and zt_new(). |
|
Definition at line 494 of file channel.h. Referenced by adsi_available(). |
|
Report DTMF on channel 0 Definition at line 871 of file channel.h. Referenced by ast_generic_bridge(), ast_rtp_bridge(), iax2_bridge(), misdn_bridge(), set_config_flags(), and zt_bridge(). |
|
Report DTMF on channel 1 Definition at line 873 of file channel.h. Referenced by ast_generic_bridge(), ast_rtp_bridge(), iax2_bridge(), misdn_bridge(), set_config_flags(), and zt_bridge(). |
|
Ignore all signal frames except NULL Definition at line 879 of file channel.h. Referenced by monitor_handle_owned(). |
|
Return all voice frames on channel 0 Definition at line 875 of file channel.h. Referenced by do_chanreads(). |
|
Return all voice frames on channel 1 Definition at line 877 of file channel.h. Referenced by do_chanreads(). |
|
|
|
|
|
|
|
|
|
|
|
Definition at line 106 of file channel.h. Referenced by ast_channel_free(), ast_parse_device_state(), page_exec(), and softhangup_exec(). |
|
|
|
Definition at line 444 of file channel.h. Referenced by try_calling(). |
|
Definition at line 442 of file channel.h. Referenced by builtin_atxfer(), and try_calling(). |
|
Definition at line 447 of file channel.h. Referenced by feature_exec_app(), and load_config(). |
|
Definition at line 448 of file channel.h. Referenced by load_config(). |
|
Definition at line 446 of file channel.h. Referenced by load_config(), and set_config_flags(). |
|
Definition at line 440 of file channel.h. Referenced by ast_channel_bridge(). |
|
Definition at line 441 of file channel.h. Referenced by park_exec(), and try_calling(). |
|
if we are blocking Definition at line 428 of file channel.h. Referenced by agent_new(), ast_autoservice_stop(), ast_hangup(), ast_queue_frame(), ast_sendtext(), ast_serialize_showchan(), ast_softhangup_nolock(), ast_write(), handle_showchan(), phone_read(), and zt_read(). |
|
if dtmf should be deferred Definition at line 426 of file channel.h. Referenced by ast_channel_defer_dtmf(), ast_channel_undefer_dtmf(), and ast_read(). |
|
if there is a pending exception Definition at line 430 of file channel.h. Referenced by agent_read(), ast_read(), do_parking_thread(), and zt_read(). |
|
the channel is in an auto-incrementing dialplan processor, so when ->priority is set, it will get incremented before finding the next priority to run Definition at line 434 of file channel.h. Referenced by __ast_pbx_run(), ast_explicit_goto(), and macro_exec(). |
|
XXX anthm promises me this will disappear XXX listening to moh Definition at line 431 of file channel.h. Referenced by local_ast_moh_start(), local_ast_moh_stop(), moh_on_off(), and retrydial_exec(). |
|
is it in a native bridge Definition at line 433 of file channel.h. Referenced by start_spying(), and startmon(). |
|
XXX might also go away XXX is spying on someone Definition at line 432 of file channel.h. Referenced by chanspy_exec(). |
|
if write should be interrupt generator Definition at line 427 of file channel.h. Referenced by ast_deactivate_generator(), ast_write(), linear_alloc(), playtones_alloc(), and tonepair_alloc(). |
|
if we are a zombie Definition at line 429 of file channel.h. Referenced by app_exec(), ast_answer(), ast_call(), ast_channel_bridge(), ast_hangup(), ast_indicate(), ast_read(), ast_readstring(), ast_readstring_full(), ast_sendtext(), ast_transfer(), ast_waitfordigit(), ast_waitfordigit_full(), ast_write(), and check_availability(). |
|
Definition at line 104 of file channel.h. Referenced by conf_run(), macro_exec(), and try_calling(). |
|
|
Definition at line 122 of file channel.h. Referenced by agent_read(), ast_channel_alloc(), ast_waitfor_nandfds(), do_parking_thread(), restore_channel(), and update_features(). |
|
Definition at line 503 of file channel.h. Referenced by __unload_module(), and unload_module(). |
|
Soft hangup for async goto Definition at line 500 of file channel.h. Referenced by ast_async_goto(). |
|
Soft hangup by device Definition at line 499 of file channel.h. Referenced by __oh323_update_info(), ast_dsp_process(), ast_queue_hangup(), ast_read(), ast_write(), attempt_transfer(), cleanup_connection(), do_monitor(), function_ilink(), handle_link_data(), hangup_connection(), iax2_destroy(), iax2_predestroy(), oh323_indicate(), rpt(), rpt_call(), sip_indicate(), skinny_indicate(), zt_handle_event(), and zt_indicate(). |
|
Definition at line 504 of file channel.h. Referenced by action_hangup(), agent_hangup(), agent_logoff(), handle_hangup(), handle_softhangup(), read_agent_config(), softhangup_exec(), and zt_handle_event(). |
|
Definition at line 501 of file channel.h. Referenced by ast_begin_shutdown(). |
|
Definition at line 502 of file channel.h. Referenced by ast_check_hangup(). |
|
Definition at line 505 of file channel.h. Referenced by start_spying(), and startmon(). |
|
|
Definition at line 1189 of file channel.h. Referenced by ast_sendtext(), ast_write(), phone_read(), and zt_read(). |
|
Definition at line 1186 of file channel.h. Referenced by agent_new(), ast_hangup(), ast_queue_frame(), ast_rtcp_read(), ast_rtp_read(), ast_sched_del(), and oss_read(). |
|
Definition at line 467 of file channel.h. Referenced by ast_pbx_outgoing_exten(). |
|
Definition at line 118 of file channel.h. Referenced by ast_fileexists(), and ast_openvstream(). |
|
|
|
|
|
Definition at line 124 of file channel.h. 00124 { 00125 AST_BRIDGE_COMPLETE = 0, 00126 AST_BRIDGE_FAILED = -1, 00127 AST_BRIDGE_FAILED_NOWARN = -2, 00128 AST_BRIDGE_RETRY = -3, 00129 };
|
|
Definition at line 2426 of file channel.c. References ast_channel::_state, ast_call(), AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, ast_cdr_alloc(), ast_cdr_disposition(), ast_cdr_end(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_setapp(), ast_cdr_start(), ast_cdr_update(), ast_channel_inherit_variables(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_FRAME_CONTROL, ast_frfree(), ast_hangup(), ast_log(), ast_read(), ast_request(), ast_set_callerid(), ast_set_variables(), AST_STATE_UP, ast_waitfor(), ast_channel::cdr, ast_channel::context, ast_channel::exten, ast_frame::frametype, ast_channel::hangupcause, LOG_NOTICE, LOG_WARNING, ast_channel::priority, and ast_frame::subclass. Referenced by ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_request_and_dial(), and parkandannounce_exec(). 02427 { 02428 int state = 0; 02429 int cause = 0; 02430 struct ast_channel *chan; 02431 struct ast_frame *f; 02432 int res = 0; 02433 02434 chan = ast_request(type, format, data, &cause); 02435 if (chan) { 02436 if (oh) { 02437 if (oh->vars) 02438 ast_set_variables(chan, oh->vars); 02439 if (oh->cid_num && *oh->cid_num && oh->cid_name && *oh->cid_name) 02440 ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num); 02441 if (oh->parent_channel) 02442 ast_channel_inherit_variables(oh->parent_channel, chan); 02443 if (oh->account) 02444 ast_cdr_setaccount(chan, oh->account); 02445 } 02446 ast_set_callerid(chan, cid_num, cid_name, cid_num); 02447 02448 if (!ast_call(chan, data, 0)) { 02449 res = 1; /* in case chan->_state is already AST_STATE_UP */ 02450 while (timeout && (chan->_state != AST_STATE_UP)) { 02451 res = ast_waitfor(chan, timeout); 02452 if (res < 0) { 02453 /* Something not cool, or timed out */ 02454 break; 02455 } 02456 /* If done, break out */ 02457 if (!res) 02458 break; 02459 if (timeout > -1) 02460 timeout = res; 02461 f = ast_read(chan); 02462 if (!f) { 02463 state = AST_CONTROL_HANGUP; 02464 res = 0; 02465 break; 02466 } 02467 if (f->frametype == AST_FRAME_CONTROL) { 02468 if (f->subclass == AST_CONTROL_RINGING) 02469 state = AST_CONTROL_RINGING; 02470 else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) { 02471 state = f->subclass; 02472 ast_frfree(f); 02473 break; 02474 } else if (f->subclass == AST_CONTROL_ANSWER) { 02475 state = f->subclass; 02476 ast_frfree(f); 02477 break; 02478 } else if (f->subclass == AST_CONTROL_PROGRESS) { 02479 /* Ignore */ 02480 } else if (f->subclass == -1) { 02481 /* Ignore -- just stopping indications */ 02482 } else { 02483 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass); 02484 } 02485 } 02486 ast_frfree(f); 02487 } 02488 } else 02489 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data); 02490 } else { 02491 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data); 02492 switch(cause) { 02493 case AST_CAUSE_BUSY: 02494 state = AST_CONTROL_BUSY; 02495 break; 02496 case AST_CAUSE_CONGESTION: 02497 state = AST_CONTROL_CONGESTION; 02498 break; 02499 } 02500 } 02501 if (chan) { 02502 /* Final fixups */ 02503 if (oh) { 02504 if (oh->context && *oh->context) 02505 ast_copy_string(chan->context, oh->context, sizeof(chan->context)); 02506 if (oh->exten && *oh->exten) 02507 ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten)); 02508 if (oh->priority) 02509 chan->priority = oh->priority; 02510 } 02511 if (chan->_state == AST_STATE_UP) 02512 state = AST_CONTROL_ANSWER; 02513 } 02514 if (outstate) 02515 *outstate = state; 02516 if (chan && res <= 0) { 02517 if (!chan->cdr) { 02518 chan->cdr = ast_cdr_alloc(); 02519 if (chan->cdr) 02520 ast_cdr_init(chan->cdr, chan); 02521 } 02522 if (chan->cdr) { 02523 char tmp[256]; 02524 snprintf(tmp, 256, "%s/%s", type, (char *)data); 02525 ast_cdr_setapp(chan->cdr,"Dial",tmp); 02526 ast_cdr_update(chan); 02527 ast_cdr_start(chan->cdr); 02528 ast_cdr_end(chan->cdr); 02529 /* If the cause wasn't handled properly */ 02530 if (ast_cdr_disposition(chan->cdr,chan->hangupcause)) 02531 ast_cdr_failed(chan->cdr); 02532 } else 02533 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 02534 ast_hangup(chan); 02535 chan = NULL; 02536 } 02537 return chan; 02538 }
|
|
|
Returns number of active/allocated channels Definition at line 250 of file channel.c. References ast_mutex_lock(), ast_mutex_unlock(), channels, and ast_channel::next. Referenced by quit_handler(). 00251 { 00252 struct ast_channel *c; 00253 int cnt = 0; 00254 ast_mutex_lock(&chlock); 00255 c = channels; 00256 while(c) { 00257 cnt++; 00258 c = c->next; 00259 } 00260 ast_mutex_unlock(&chlock); 00261 return cnt; 00262 }
|
|
|
Automatically service a channel for us... Definition at line 103 of file autoservice.c. References aslist, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, AST_PTHREADT_NULL, asthread, autoservice_run(), asent::chan, free, LOG_WARNING, malloc, ast_channel::next, and asent::next. Referenced by ast_dtmf_stream(), ast_get_enum(), ast_get_srv(), ast_get_txt(), ast_osp_lookup(), bridge_playfile(), builtin_atxfer(), builtin_automonitor(), builtin_blindtransfer(), and conf_play(). 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_PTHREADT_NULL, ast_test_flag, asthread, asent::chan, free, and asent::next. Referenced by ast_get_srv(), ast_osp_lookup(), bridge_playfile(), builtin_atxfer(), builtin_automonitor(), builtin_blindtransfer(), and conf_play(). 00140 { 00141 int res = -1; 00142 struct asent *as, *prev; 00143 ast_mutex_lock(&autolock); 00144 as = aslist; 00145 prev = NULL; 00146 while(as) { 00147 if (as->chan == chan) 00148 break; 00149 prev = as; 00150 as = as->next; 00151 } 00152 if (as) { 00153 if (prev) 00154 prev->next = as->next; 00155 else 00156 aslist = as->next; 00157 free(as); 00158 if (!chan->_softhangup) 00159 res = 0; 00160 } 00161 if (asthread != AST_PTHREADT_NULL) 00162 pthread_kill(asthread, SIGURG); 00163 ast_mutex_unlock(&autolock); 00164 /* Wait for it to un-block */ 00165 while(ast_test_flag(chan, AST_FLAG_BLOCKING)) 00166 usleep(1000); 00167 return res; 00168 }
|
|
Initiate system shutdown -- prevents new channels from being allocated. If "hangup" is non-zero, all existing channels will receive soft hangups Definition at line 234 of file channel.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_softhangup(), AST_SOFTHANGUP_SHUTDOWN, channels, and shutting_down. Referenced by quit_handler(). 00235 { 00236 struct ast_channel *c; 00237 shutting_down = 1; 00238 if (hangup) { 00239 ast_mutex_lock(&chlock); 00240 c = channels; 00241 while(c) { 00242 ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN); 00243 c = c->next; 00244 } 00245 ast_mutex_unlock(&chlock); 00246 } 00247 }
|
|
Pick the best codec Definition at line 468 of file channel.c. References AST_FORMAT_ADPCM, AST_FORMAT_ALAW, AST_FORMAT_G723_1, AST_FORMAT_G726, AST_FORMAT_G729A, AST_FORMAT_GSM, AST_FORMAT_ILBC, AST_FORMAT_LPC10, AST_FORMAT_SLINEAR, AST_FORMAT_SPEEX, AST_FORMAT_ULAW, ast_log(), LOG_WARNING, and prefs. Referenced by __login_exec(), __oh323_new(), agent_call(), ast_iax2_new(), builtin_atxfer(), echo_exec(), iax2_request(), local_new(), 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 3271 of file channel.c. References ast_channel::_bridge, ast_channel_tech::bridged_channel, and ast_channel::tech. Referenced by __zt_exception(), agents_show(), ast_channel_masquerade(), attempt_transfer(), 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(), skinny_ss(), socket_read(), ss_thread(), start_spying(), startmon(), zt_handle_event(), and zt_hangup(). 03272 { 03273 struct ast_channel *bridged; 03274 bridged = chan->_bridge; 03275 if (bridged && bridged->tech->bridged_channel) 03276 bridged = bridged->tech->bridged_channel(chan, bridged); 03277 return bridged; 03278 }
|
|
Make a call.
Definition at line 2604 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(), features_call(), function_ilink(), ring_entry(), rpt(), and wait_for_answer(). 02605 { 02606 /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 02607 If the remote end does not answer within the timeout, then do NOT hang up, but 02608 return anyway. */ 02609 int res = -1; 02610 /* Stop if we're a zombie or need a soft hangup */ 02611 ast_mutex_lock(&chan->lock); 02612 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) 02613 if (chan->tech->call) 02614 res = chan->tech->call(chan, addr, timeout); 02615 ast_mutex_unlock(&chan->lock); 02616 return res; 02617 }
|
|
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. Referenced by __transmit_response(), ast_hangup(), 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 2857 of file channel.c. References EVENT_FLAG_CALL, manager_event(), ast_channel::name, and ast_channel::uniqueid. 02858 { 02859 char tmp[256]; 02860 ast_copy_string(tmp, chan->name, sizeof(tmp)); 02861 ast_copy_string(chan->name, newname, sizeof(chan->name)); 02862 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", tmp, chan->name, chan->uniqueid); 02863 }
|
|
Create a channel structure.
Definition at line 516 of file channel.c. References ast_log(), AST_MAX_FDS, ast_channel::fds, ast_channel::flags, free, LOG_WARNING, malloc, ast_channel::sched, sched_context_create(), shutting_down, and ast_channel::timingfd. 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 3432 of file channel.c. References ast_channel::_bridge, AST_BRIDGE_COMPLETE, ast_check_hangup_locked(), AST_FEATURE_PLAY_WARNING, AST_FLAG_ZOMBIE, ast_log(), ast_test_flag, ast_tvadd(), ast_tvsub(), bridge_playfile(), ast_channel::cid, ast_callerid::cid_num, config, EVENT_FLAG_CALL, LOG_WARNING, manager_event(), ast_channel::name, ast_channel::nativeformats, and ast_channel::uniqueid. Referenced by ast_bridge_call(). 03434 { 03435 struct ast_channel *who = NULL; 03436 enum ast_bridge_result res = AST_BRIDGE_COMPLETE; 03437 int nativefailed=0; 03438 int firstpass; 03439 int o0nativeformats; 03440 int o1nativeformats; 03441 long time_left_ms=0; 03442 struct timeval nexteventts = { 0, }; 03443 char caller_warning = 0; 03444 char callee_warning = 0; 03445 03446 if (c0->_bridge) { 03447 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 03448 c0->name, c0->_bridge->name); 03449 return -1; 03450 } 03451 if (c1->_bridge) { 03452 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 03453 c1->name, c1->_bridge->name); 03454 return -1; 03455 } 03456 03457 /* Stop if we're a zombie or need a soft hangup */ 03458 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 03459 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) 03460 return -1; 03461 03462 *fo = NULL; 03463 firstpass = config->firstpass; 03464 config->firstpass = 0; 03465 03466 if (ast_tvzero(config->start_time)) 03467 config->start_time = ast_tvnow(); 03468 time_left_ms = config->timelimit; 03469 03470 caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING); 03471 callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING); 03472 03473 if (config->start_sound && firstpass) { 03474 if (caller_warning) 03475 bridge_playfile(c0, c1, config->start_sound, time_left_ms / 1000); 03476 if (callee_warning) 03477 bridge_playfile(c1, c0, config->start_sound, time_left_ms / 1000); 03478 } 03479 03480 /* Keep track of bridge */ 03481 c0->_bridge = c1; 03482 c1->_bridge = c0; 03483 03484 manager_event(EVENT_FLAG_CALL, "Link", 03485 "Channel1: %s\r\n" 03486 "Channel2: %s\r\n" 03487 "Uniqueid1: %s\r\n" 03488 "Uniqueid2: %s\r\n" 03489 "CallerID1: %s\r\n" 03490 "CallerID2: %s\r\n", 03491 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 03492 03493 o0nativeformats = c0->nativeformats; 03494 o1nativeformats = c1->nativeformats; 03495 03496 if (config->feature_timer) { 03497 nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->feature_timer, 1000)); 03498 } else if (config->timelimit) { 03499 nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 03500 if (caller_warning || callee_warning) 03501 nexteventts = ast_tvsub(nexteventts, ast_samp2tv(config->play_warning, 1000)); 03502 } 03503 03504 for (/* ever */;;) { 03505 struct timeval now = { 0, }; 03506 int to; 03507 03508 to = -1; 03509 03510 if (!ast_tvzero(nexteventts)) { 03511 now = ast_tvnow(); 03512 to = ast_tvdiff_ms(nexteventts, now); 03513 if (to <= 0) { 03514 res = AST_BRIDGE_COMPLETE; 03515 break; 03516 } 03517 } 03518 03519 if (config->timelimit) { 03520 time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time); 03521 if (time_left_ms < to) 03522 to = time_left_ms; 03523 03524 if (time_left_ms <= 0) { 03525 if (caller_warning && config->end_sound) 03526 bridge_playfile(c0, c1, config->end_sound, 0); 03527 if (callee_warning && config->end_sound) 03528 bridge_playfile(c1, c0, config->end_sound, 0); 03529 *fo = NULL; 03530 if (who) 03531 *rc = who; 03532 res = 0; 03533 break; 03534 } 03535 03536 if (!to) { 03537 if (time_left_ms >= 5000) { 03538 /* force the time left to round up if appropriate */ 03539 if (caller_warning && config->warning_sound && config->play_warning) 03540 bridge_playfile(c0, c1, config->warning_sound, 03541 (time_left_ms + 500) / 1000); 03542 if (callee_warning && config->warning_sound && config->play_warning) 03543 bridge_playfile(c1, c0, config->warning_sound, 03544 (time_left_ms + 500) / 1000); 03545 } 03546 if (config->warning_freq) { 03547 nexteventts = ast_tvadd(nexteventts, ast_samp2tv(config->warning_freq, 1000)); 03548 } else 03549 nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 03550 } 03551 } 03552 03553 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) { 03554 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 03555 c0->_softhangup = 0; 03556 if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 03557 c1->_softhangup = 0; 03558 c0->_bridge = c1; 03559 c1->_bridge = c0; 03560 ast_log(LOG_DEBUG, "Unbridge signal received. Ending native bridge.\n"); 03561 continue; 03562 } 03563 03564 /* Stop if we're a zombie or need a soft hangup */ 03565 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 03566 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) { 03567 *fo = NULL; 03568 if (who) 03569 *rc = who; 03570 res = 0; 03571 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", 03572 c0->name, c1->name, 03573 ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No", 03574 ast_check_hangup(c0) ? "Yes" : "No", 03575 ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No", 03576 ast_check_hangup(c1) ? "Yes" : "No"); 03577 break; 03578 } 03579 03580 if (c0->tech->bridge && 03581 (config->timelimit == 0) && 03582 (c0->tech->bridge == c1->tech->bridge) && 03583 !nativefailed && !c0->monitor && !c1->monitor && 03584 !c0->spies && !c1->spies && !ast_test_flag(&(config->features_callee),AST_FEATURE_REDIRECT) && 03585 !ast_test_flag(&(config->features_caller),AST_FEATURE_REDIRECT) ) { 03586 /* Looks like they share a bridge method and nothing else is in the way */ 03587 if (option_verbose > 2) 03588 ast_verbose(VERBOSE_PREFIX_3 "Attempting native bridge of %s and %s\n", c0->name, c1->name); 03589 ast_set_flag(c0, AST_FLAG_NBRIDGE); 03590 ast_set_flag(c1, AST_FLAG_NBRIDGE); 03591 if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, to)) == AST_BRIDGE_COMPLETE) { 03592 manager_event(EVENT_FLAG_CALL, "Unlink", 03593 "Channel1: %s\r\n" 03594 "Channel2: %s\r\n" 03595 "Uniqueid1: %s\r\n" 03596 "Uniqueid2: %s\r\n" 03597 "CallerID1: %s\r\n" 03598 "CallerID2: %s\r\n", 03599 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 03600 ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name); 03601 03602 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 03603 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 03604 03605 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 03606 continue; 03607 03608 c0->_bridge = NULL; 03609 c1->_bridge = NULL; 03610 03611 return res; 03612 } else { 03613 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 03614 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 03615 } 03616 switch (res) { 03617 case AST_BRIDGE_RETRY: 03618 continue; 03619 default: 03620 ast_log(LOG_WARNING, "Private bridge between %s and %s failed\n", c0->name, c1->name); 03621 /* fallthrough */ 03622 case AST_BRIDGE_FAILED_NOWARN: 03623 nativefailed++; 03624 break; 03625 } 03626 } 03627 03628 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) || 03629 (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) && 03630 !(c0->generator || c1->generator)) { 03631 if (ast_channel_make_compatible(c0, c1)) { 03632 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name); 03633 manager_event(EVENT_FLAG_CALL, "Unlink", 03634 "Channel1: %s\r\n" 03635 "Channel2: %s\r\n" 03636 "Uniqueid1: %s\r\n" 03637 "Uniqueid2: %s\r\n" 03638 "CallerID1: %s\r\n" 03639 "CallerID2: %s\r\n", 03640 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 03641 return AST_BRIDGE_FAILED; 03642 } 03643 o0nativeformats = c0->nativeformats; 03644 o1nativeformats = c1->nativeformats; 03645 } 03646 res = ast_generic_bridge(c0, c1, config, fo, rc, nexteventts); 03647 if (res != AST_BRIDGE_RETRY) 03648 break; 03649 } 03650 03651 c0->_bridge = NULL; 03652 c1->_bridge = NULL; 03653 03654 manager_event(EVENT_FLAG_CALL, "Unlink", 03655 "Channel1: %s\r\n" 03656 "Channel2: %s\r\n" 03657 "Uniqueid1: %s\r\n" 03658 "Uniqueid2: %s\r\n" 03659 "CallerID1: %s\r\n" 03660 "CallerID2: %s\r\n", 03661 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 03662 ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name); 03663 03664 return res; 03665 }
|
|
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 find_cache(). 00691 { 00692 int pre = 0; 00693 00694 if (chan) { 00695 pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF); 00696 ast_set_flag(chan, AST_FLAG_DEFER_DTMF); 00697 } 00698 return pre; 00699 }
|
|
Free a channel structure.
Definition at line 878 of file channel.c. References ast_channel::alertpipe, AST_CHANNEL_NAME, ast_device_state_changed_literal(), ast_frfree(), AST_LIST_REMOVE_HEAD, ast_log(), ast_moh_cleanup(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_translator_free_path(), ast_var_delete(), channels, ast_channel::cid, free, free_cid(), last, ast_channel::lock, LOG_WARNING, ast_channel::monitor, ast_channel::music_state, ast_channel::name, name, ast_frame::next, msglist::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_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 2865 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(), option_debug, and ast_channel::varshead. Referenced by __ast_request_and_dial(), agent_call(), ast_feature_request_and_dial(), ring_entry(), and wait_for_answer(). 02866 { 02867 struct ast_var_t *current, *newvar; 02868 char *varname; 02869 02870 AST_LIST_TRAVERSE(&parent->varshead, current, entries) { 02871 int vartype = 0; 02872 02873 varname = ast_var_full_name(current); 02874 if (!varname) 02875 continue; 02876 02877 if (varname[0] == '_') { 02878 vartype = 1; 02879 if (varname[1] == '_') 02880 vartype = 2; 02881 } 02882 02883 switch (vartype) { 02884 case 1: 02885 newvar = ast_var_assign(&varname[1], ast_var_value(current)); 02886 if (newvar) { 02887 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 02888 if (option_debug) 02889 ast_log(LOG_DEBUG, "Copying soft-transferable variable %s.\n", ast_var_name(newvar)); 02890 } 02891 break; 02892 case 2: 02893 newvar = ast_var_assign(ast_var_full_name(current), ast_var_value(current)); 02894 if (newvar) { 02895 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 02896 if (option_debug) 02897 ast_log(LOG_DEBUG, "Copying hard-transferable variable %s.\n", ast_var_name(newvar)); 02898 } 02899 break; 02900 default: 02901 if (option_debug) 02902 ast_log(LOG_DEBUG, "Not copying variable %s.\n", ast_var_name(current)); 02903 break; 02904 } 02905 } 02906 }
|
|
Definition at line 2743 of file channel.c. References AST_FORMAT_SLINEAR, ast_log(), ast_set_read_format(), ast_set_write_format(), ast_translator_best_choice(), LOG_WARNING, ast_channel::name, ast_channel::nativeformats, and option_transcode_slin. Referenced by builtin_atxfer(), park_exec(), and wait_for_answer(). 02744 { 02745 int src; 02746 int dst; 02747 02748 /* Set up translation from the chan to the peer */ 02749 src = chan->nativeformats; 02750 dst = peer->nativeformats; 02751 if (ast_translator_best_choice(&dst, &src) < 0) { 02752 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, src, peer->name, dst); 02753 return -1; 02754 } 02755 02756 /* if the best path is not 'pass through', then 02757 transcoding is needed; if desired, force transcode path 02758 to use SLINEAR between channels */ 02759 if ((src != dst) && option_transcode_slin) 02760 dst = AST_FORMAT_SLINEAR; 02761 if (ast_set_read_format(chan, dst) < 0) { 02762 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, dst); 02763 return -1; 02764 } 02765 if (ast_set_write_format(peer, dst) < 0) { 02766 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, dst); 02767 return -1; 02768 } 02769 02770 /* Set up translation from the peer to the chan */ 02771 src = peer->nativeformats; 02772 dst = chan->nativeformats; 02773 if (ast_translator_best_choice(&dst, &src) < 0) { 02774 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, src, chan->name, dst); 02775 return -1; 02776 } 02777 /* if the best path is not 'pass through', then 02778 transcoding is needed; if desired, force transcode path 02779 to use SLINEAR between channels */ 02780 if ((src != dst) && option_transcode_slin) 02781 dst = AST_FORMAT_SLINEAR; 02782 if (ast_set_read_format(peer, dst) < 0) { 02783 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, dst); 02784 return -1; 02785 } 02786 if (ast_set_write_format(chan, dst) < 0) { 02787 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, dst); 02788 return -1; 02789 } 02790 return 0; 02791 }
|
|
Definition at line 2793 of file channel.c. References ast_channel::_bridge, ast_bridged_channel(), AST_FRAME_NULL, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), ast_channel::lock, LOG_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(). 02794 { 02795 struct ast_frame null = { AST_FRAME_NULL, }; 02796 int res = -1; 02797 struct ast_channel *final_orig = original, *final_clone = clone; 02798 02799 ast_mutex_lock(&original->lock); 02800 while(ast_mutex_trylock(&clone->lock)) { 02801 ast_mutex_unlock(&original->lock); 02802 usleep(1); 02803 ast_mutex_lock(&original->lock); 02804 } 02805 02806 /* each of these channels may be sitting behind a channel proxy (i.e. chan_agent) 02807 and if so, we don't really want to masquerade it, but its proxy */ 02808 if (original->_bridge && (original->_bridge != ast_bridged_channel(original))) 02809 final_orig = original->_bridge; 02810 02811 if (clone->_bridge && (clone->_bridge != ast_bridged_channel(clone))) 02812 final_clone = clone->_bridge; 02813 02814 if ((final_orig != original) || (final_clone != clone)) { 02815 ast_mutex_lock(&final_orig->lock); 02816 while(ast_mutex_trylock(&final_clone->lock)) { 02817 ast_mutex_unlock(&final_orig->lock); 02818 usleep(1); 02819 ast_mutex_lock(&final_orig->lock); 02820 } 02821 ast_mutex_unlock(&clone->lock); 02822 ast_mutex_unlock(&original->lock); 02823 original = final_orig; 02824 clone = final_clone; 02825 } 02826 02827 if (original == clone) { 02828 ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name); 02829 ast_mutex_unlock(&clone->lock); 02830 ast_mutex_unlock(&original->lock); 02831 return -1; 02832 } 02833 02834 ast_log(LOG_DEBUG, "Planning to masquerade channel %s into the structure of %s\n", 02835 clone->name, original->name); 02836 if (original->masq) { 02837 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 02838 original->masq->name, original->name); 02839 } else if (clone->masqr) { 02840 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 02841 clone->name, clone->masqr->name); 02842 } else { 02843 original->masq = clone; 02844 clone->masqr = original; 02845 ast_queue_frame(original, &null); 02846 ast_queue_frame(clone, &null); 02847 ast_log(LOG_DEBUG, "Done planning to masquerade channel %s into the structure of %s\n", clone->name, original->name); 02848 res = 0; 02849 } 02850 02851 ast_mutex_unlock(&clone->lock); 02852 ast_mutex_unlock(&original->lock); 02853 02854 return res; 02855 }
|
|
Query the value of an option, optionally blocking until a reply is received Works similarly to setoption except only reads the options. |
|
Register a channel technology (a new channel driver) Called by a channel module to register the kind of channels it supports.
Definition at line 317 of file channel.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), backends, LOG_DEBUG, LOG_WARNING, malloc, chanlist::next, option_debug, option_verbose, chanlist::tech, ast_channel_tech::type, and VERBOSE_PREFIX_2. Referenced by load_module(), and unload_module(). 00318 { 00319 struct chanlist *chan; 00320 00321 ast_mutex_lock(&chlock); 00322 00323 chan = backends; 00324 while (chan) { 00325 if (!strcasecmp(tech->type, chan->tech->type)) { 00326 ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type); 00327 ast_mutex_unlock(&chlock); 00328 return -1; 00329 } 00330 chan = chan->next; 00331 } 00332 00333 chan = malloc(sizeof(*chan)); 00334 if (!chan) { 00335 ast_log(LOG_WARNING, "Out of memory\n"); 00336 ast_mutex_unlock(&chlock); 00337 return -1; 00338 } 00339 chan->tech = tech; 00340 chan->next = backends; 00341 backends = chan; 00342 00343 if (option_debug) 00344 ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description); 00345 00346 if (option_verbose > 1) 00347 ast_verbose(VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->tech->type, 00348 chan->tech->description); 00349 00350 ast_mutex_unlock(&chlock); 00351 return 0; 00352 }
|
|
Send HTML or URL on link. Returns 0 on success or -1 on failure Definition at line 2729 of file channel.c. References ast_channel_tech::send_html, and ast_channel::tech. Referenced by agent_sendhtml(), and wait_for_answer(). 02730 { 02731 if (chan->tech->send_html) 02732 return chan->tech->send_html(chan, subclass, data, datalen); 02733 return -1; 02734 }
|
|
Send URL on link. Returns 0 on success or -1 on failure Definition at line 2736 of file channel.c. References AST_HTML_URL, ast_channel_tech::send_html, and ast_channel::tech. Referenced by sendurl_exec(). 02737 { 02738 if (chan->tech->send_html) 02739 return chan->tech->send_html(chan, AST_HTML_URL, url, strlen(url) + 1); 02740 return -1; 02741 }
|
|
Definition at line 3668 of file channel.c. References ast_log(), LOG_ERROR, ast_channel_tech::setoption, and ast_channel::tech. Referenced by conf_run(), handle_tddmode(), play_record_review(), reset_volumes(), rpt(), set_listen_volume(), set_talk_volume(), set_volume(), vm_forwardoptions(), and zt_hangup(). 03669 { 03670 int res; 03671 03672 if (chan->tech->setoption) { 03673 res = chan->tech->setoption(chan, option, data, datalen); 03674 if (res < 0) 03675 return res; 03676 } else { 03677 errno = ENOSYS; 03678 return -1; 03679 } 03680 if (block) { 03681 /* XXX Implement blocking -- just wait for our option frame reply, discarding 03682 intermediate packets. XXX */ 03683 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 03684 return -1; 03685 } 03686 return 0; 03687 }
|
|
Set when to hang a channel up.
Definition at line 277 of file channel.c. References AST_FRAME_NULL, ast_queue_frame(), and ast_channel::whentohangup. Referenced by action_timeout(), ast_osp_lookup(), builtin_function_timeout_write(), handle_request_invite(), and pbx_builtin_atimeout(). 00278 { 00279 time_t myt; 00280 struct ast_frame fr = { AST_FRAME_NULL, }; 00281 00282 time(&myt); 00283 if (offset) 00284 chan->whentohangup = myt + offset; 00285 else 00286 chan->whentohangup = 0; 00287 ast_queue_frame(chan, &fr); 00288 return; 00289 }
|
|
Starts a silence generator on the given channel.
The pointer returned by this function must be preserved and passed to ast_channel_stop_silence_generator when you wish to stop the silence generation. Definition at line 4135 of file channel.c. References ast_activate_generator(), AST_FORMAT_SLINEAR, ast_log(), ast_set_write_format(), calloc, free, LOG_ERROR, LOG_WARNING, ast_channel::name, option_debug, silence_generator, and ast_channel::writeformat. 04136 { 04137 struct ast_silence_generator *state; 04138 04139 if (!(state = calloc(1, sizeof(*state)))) { 04140 ast_log(LOG_WARNING, "Could not allocate state structure\n"); 04141 return NULL; 04142 } 04143 04144 state->old_write_format = chan->writeformat; 04145 04146 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) { 04147 ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n"); 04148 free(state); 04149 return NULL; 04150 } 04151 04152 ast_activate_generator(chan, &silence_generator, state); 04153 04154 if (option_debug) 04155 ast_log(LOG_DEBUG, "Started silence generator on '%s'\n", chan->name); 04156 04157 return state; 04158 }
|
|
Stops a previously-started silence generator on the given channel.
Definition at line 4160 of file channel.c. References ast_deactivate_generator(), ast_log(), ast_set_write_format(), free, LOG_ERROR, ast_channel::name, ast_silence_generator::old_write_format, and option_debug. 04161 { 04162 if (!state) 04163 return; 04164 04165 ast_deactivate_generator(chan); 04166 04167 if (option_debug) 04168 ast_log(LOG_DEBUG, "Stopped silence generator on '%s'\n", chan->name); 04169 04170 if (ast_set_write_format(chan, state->old_write_format) < 0) 04171 ast_log(LOG_ERROR, "Could not return write format to its original state\n"); 04172 04173 free(state); 04174 }
|
|
Returns 0 if channel does not support HTML or non-zero if it does Definition at line 2722 of file channel.c. References ast_channel_tech::send_html, and ast_channel::tech. Referenced by sendurl_exec().
|
|
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 find_cache(), and rpt_call(). 00703 { 00704 if (chan) 00705 ast_clear_flag(chan, AST_FLAG_DEFER_DTMF); 00706 }
|
|
Unregister a channel technology.
Definition at line 354 of file channel.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), backends, free, last, LOG_DEBUG, chanlist::next, option_debug, option_verbose, chanlist::tech, ast_channel_tech::type, and VERBOSE_PREFIX_2. Referenced by __unload_module(), and unload_module(). 00355 { 00356 struct chanlist *chan, *last=NULL; 00357 00358 if (option_debug) 00359 ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", tech->type); 00360 00361 ast_mutex_lock(&chlock); 00362 00363 chan = backends; 00364 while (chan) { 00365 if (chan->tech == tech) { 00366 if (last) 00367 last->next = chan->next; 00368 else 00369 backends = backends->next; 00370 free(chan); 00371 ast_mutex_unlock(&chlock); 00372 00373 if (option_verbose > 1) 00374 ast_verbose( VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", tech->type); 00375 00376 return; 00377 } 00378 last = chan; 00379 chan = chan->next; 00380 } 00381 00382 ast_mutex_unlock(&chlock); 00383 }
|
|
Definition at line 794 of file channel.c. References channel_find_locked(). Referenced by action_status(), ast_app_group_get_count(), ast_app_group_match_get_count(), ast_pickup_call(), complete_ch_helper(), conf_exec(), group_show_channels(), handle_chanlist(), handle_debugchan(), handle_nodebugchan(), local_channel_walk(), moh_on_off(), and softhangup_exec(). 00795 { 00796 return channel_find_locked(prev, NULL, 0, NULL, NULL); 00797 }
|
|
Check to see if a channel is needing hang up.
Definition at line 203 of file channel.c. References ast_channel::_softhangup, AST_SOFTHANGUP_TIMEOUT, ast_channel::tech_pvt, and ast_channel::whentohangup. Referenced by app_exec(), ast_answer(), ast_call(), ast_check_hangup_locked(), ast_feature_request_and_dial(), ast_indicate(), ast_read(), ast_readstring(), ast_readstring_full(), ast_recvtext(), ast_sendtext(), ast_transfer(), ast_waitfordigit(), ast_waitfordigit_full(), ast_write(), builtin_atxfer(), channel_spy(), handle_sendimage(), rpt(), 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 1427 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(), generator_force(), local_ast_moh_stop(), milliwatt_exec(), moh_on_off(), and wait_for_answer(). 01428 { 01429 ast_mutex_lock(&chan->lock); 01430 if (chan->generatordata) { 01431 if (chan->generator && chan->generator->release) 01432 chan->generator->release(chan, chan->generatordata); 01433 chan->generatordata = NULL; 01434 chan->generator = NULL; 01435 ast_clear_flag(chan, AST_FLAG_WRITE_INT); 01436 ast_settimeout(chan, 0, NULL, NULL); 01437 } 01438 ast_mutex_unlock(&chan->lock); 01439 }
|
|
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 2941 of file channel.c. References ast_channel::_state, ast_channel::alertpipe, ast_log(), ast_mutex_lock(), EVENT_FLAG_CALL, free_translation(), ast_channel::lock, manager_event(), ast_channel::masq, ast_channel::masqr, ast_channel::name, option_debug, ast_frame::prev, ast_channel::readformat, ast_channel::readq, t, ast_channel::tech, ast_channel::tech_pvt, ast_channel::uniqueid, and ast_channel::writeformat. Referenced by ast_async_goto(), ast_hangup(), ast_read(), ast_write(), iax_park(), sip_park(), and sip_park_thread(). 02942 { 02943 int x,i; 02944 int res=0; 02945 int origstate; 02946 struct ast_frame *cur, *prev; 02947 const struct ast_channel_tech *t; 02948 void *t_pvt; 02949 struct ast_callerid tmpcid; 02950 struct ast_channel *clone = original->masq; 02951 struct ast_channel_spy_list *spy_list; 02952 struct ast_channel_spy *spy = NULL; 02953 int rformat = original->readformat; 02954 int wformat = original->writeformat; 02955 char newn[100]; 02956 char orig[100]; 02957 char masqn[100]; 02958 char zombn[100]; 02959 02960 if (option_debug > 3) 02961 ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n", 02962 clone->name, clone->_state, original->name, original->_state); 02963 02964 /* XXX This is a seriously wacked out operation. We're essentially putting the guts of 02965 the clone channel into the original channel. Start by killing off the original 02966 channel's backend. I'm not sure we're going to keep this function, because 02967 while the features are nice, the cost is very high in terms of pure nastiness. XXX */ 02968 02969 /* We need the clone's lock, too */ 02970 ast_mutex_lock(&clone->lock); 02971 02972 ast_log(LOG_DEBUG, "Got clone lock for masquerade on '%s' at %p\n", clone->name, &clone->lock); 02973 02974 /* Having remembered the original read/write formats, we turn off any translation on either 02975 one */ 02976 free_translation(clone); 02977 free_translation(original); 02978 02979 02980 /* Unlink the masquerade */ 02981 original->masq = NULL; 02982 clone->masqr = NULL; 02983 02984 /* Save the original name */ 02985 ast_copy_string(orig, original->name, sizeof(orig)); 02986 /* Save the new name */ 02987 ast_copy_string(newn, clone->name, sizeof(newn)); 02988 /* Create the masq name */ 02989 snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn); 02990 02991 /* Copy the name from the clone channel */ 02992 ast_copy_string(original->name, newn, sizeof(original->name)); 02993 02994 /* Mangle the name of the clone channel */ 02995 ast_copy_string(clone->name, masqn, sizeof(clone->name)); 02996 02997 /* Notify any managers of the change, first the masq then the other */ 02998 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", newn, masqn, clone->uniqueid); 02999 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", orig, newn, original->uniqueid); 03000 03001 /* Swap the technlogies */ 03002 t = original->tech; 03003 original->tech = clone->tech; 03004 clone->tech = t; 03005 03006 t_pvt = original->tech_pvt; 03007 original->tech_pvt = clone->tech_pvt; 03008 clone->tech_pvt = t_pvt; 03009 03010 /* Swap the readq's */ 03011 cur = original->readq; 03012 original->readq = clone->readq; 03013 clone->readq = cur; 03014 03015 /* Swap the alertpipes */ 03016 for (i = 0; i < 2; i++) { 03017 x = original->alertpipe[i]; 03018 original->alertpipe[i] = clone->alertpipe[i]; 03019 clone->alertpipe[i] = x; 03020 } 03021 03022 /* Swap the raw formats */ 03023 x = original->rawreadformat; 03024 original->rawreadformat = clone->rawreadformat; 03025 clone->rawreadformat = x; 03026 x = original->rawwriteformat; 03027 original->rawwriteformat = clone->rawwriteformat; 03028 clone->rawwriteformat = x; 03029 03030 /* Swap the spies */ 03031 spy_list = original->spies; 03032 original->spies = clone->spies; 03033 clone->spies = spy_list; 03034 03035 /* Update channel on respective spy lists if present */ 03036 if (original->spies) { 03037 AST_LIST_TRAVERSE(&original->spies->list, spy, list) { 03038 ast_mutex_lock(&spy->lock); 03039 spy->chan = original; 03040 ast_mutex_unlock(&spy->lock); 03041 } 03042 } 03043 if (clone->spies) { 03044 AST_LIST_TRAVERSE(&clone->spies->list, spy, list) { 03045 ast_mutex_lock(&spy->lock); 03046 spy->chan = clone; 03047 ast_mutex_unlock(&spy->lock); 03048 } 03049 } 03050 03051 /* Save any pending frames on both sides. Start by counting 03052 * how many we're going to need... */ 03053 prev = NULL; 03054 cur = clone->readq; 03055 x = 0; 03056 while(cur) { 03057 x++; 03058 prev = cur; 03059 cur = cur->next; 03060 } 03061 /* If we had any, prepend them to the ones already in the queue, and 03062 * load up the alertpipe */ 03063 if (prev) { 03064 prev->next = original->readq; 03065 original->readq = clone->readq; 03066 clone->readq = NULL; 03067 if (original->alertpipe[1] > -1) { 03068 for (i = 0; i < x; i++) 03069 write(original->alertpipe[1], &x, sizeof(x)); 03070 } 03071 } 03072 clone->_softhangup = AST_SOFTHANGUP_DEV; 03073 03074 03075 /* And of course, so does our current state. Note we need not 03076 call ast_setstate since the event manager doesn't really consider 03077 these separate. We do this early so that the clone has the proper 03078 state of the original channel. */ 03079 origstate = original->_state; 03080 original->_state = clone->_state; 03081 clone->_state = origstate; 03082 03083 if (clone->tech->fixup){ 03084 res = clone->tech->fixup(original, clone); 03085 if (res) 03086 ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name); 03087 } 03088 03089 /* Start by disconnecting the original's physical side */ 03090 if (clone->tech->hangup) 03091 res = clone->tech->hangup(clone); 03092 if (res) { 03093 ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n"); 03094 ast_mutex_unlock(&clone->lock); 03095 return -1; 03096 } 03097 03098 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig); 03099 /* Mangle the name of the clone channel */ 03100 ast_copy_string(clone->name, zombn, sizeof(clone->name)); 03101 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", masqn, zombn, clone->uniqueid); 03102 03103 /* Update the type. */ 03104 original->type = clone->type; 03105 t_pvt = original->monitor; 03106 original->monitor = clone->monitor; 03107 clone->monitor = t_pvt; 03108 03109 /* Keep the same language. */ 03110 ast_copy_string(original->language, clone->language, sizeof(original->language)); 03111 /* Copy the FD's */ 03112 for (x = 0; x < AST_MAX_FDS; x++) { 03113 original->fds[x] = clone->fds[x]; 03114 } 03115 clone_variables(original, clone); 03116 AST_LIST_HEAD_INIT_NOLOCK(&clone->varshead); 03117 /* Presense of ADSI capable CPE follows clone */ 03118 original->adsicpe = clone->adsicpe; 03119 /* Bridge remains the same */ 03120 /* CDR fields remain the same */ 03121 /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */ 03122 /* Application and data remain the same */ 03123 /* Clone exception becomes real one, as with fdno */ 03124 ast_copy_flags(original, clone, AST_FLAG_EXCEPTION); 03125 original->fdno = clone->fdno; 03126 /* Schedule context remains the same */ 03127 /* Stream stuff stays the same */ 03128 /* Keep the original state. The fixup code will need to work with it most likely */ 03129 03130 /* Just swap the whole structures, nevermind the allocations, they'll work themselves 03131 out. */ 03132 tmpcid = original->cid; 03133 original->cid = clone->cid; 03134 clone->cid = tmpcid; 03135 03136 /* Restore original timing file descriptor */ 03137 original->fds[AST_MAX_FDS - 2] = original->timingfd; 03138 03139 /* Our native formats are different now */ 03140 original->nativeformats = clone->nativeformats; 03141 03142 /* Context, extension, priority, app data, jump table, remain the same */ 03143 /* pvt switches. pbx stays the same, as does next */ 03144 03145 /* Set the write format */ 03146 ast_set_write_format(original, wformat); 03147 03148 /* Set the read format */ 03149 ast_set_read_format(original, rformat); 03150 03151 /* Copy the music class */ 03152 ast_copy_string(original->musicclass, clone->musicclass, sizeof(original->musicclass)); 03153 03154 ast_log(LOG_DEBUG, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat); 03155 03156 /* Okay. Last thing is to let the channel driver know about all this mess, so he 03157 can fix up everything as best as possible */ 03158 if (original->tech->fixup) { 03159 res = original->tech->fixup(clone, original); 03160 if (res) { 03161 ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n", 03162 original->type, original->name); 03163 ast_mutex_unlock(&clone->lock); 03164 return -1; 03165 } 03166 } else 03167 ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)! Bad things may happen.\n", 03168 original->type, original->name); 03169 03170 /* Now, at this point, the "clone" channel is totally F'd up. We mark it as 03171 a zombie so nothing tries to touch it. If it's already been marked as a 03172 zombie, then free it now (since it already is considered invalid). */ 03173 if (ast_test_flag(clone, AST_FLAG_ZOMBIE)) { 03174 ast_log(LOG_DEBUG, "Destroying channel clone '%s'\n", clone->name); 03175 ast_mutex_unlock(&clone->lock); 03176 manager_event(EVENT_FLAG_CALL, "Hangup", 03177 "Channel: %s\r\n" 03178 "Uniqueid: %s\r\n" 03179 "Cause: %d\r\n" 03180 "Cause-txt: %s\r\n", 03181 clone->name, 03182 clone->uniqueid, 03183 clone->hangupcause, 03184 ast_cause2str(clone->hangupcause) 03185 ); 03186 ast_channel_free(clone); 03187 } else { 03188 struct ast_frame null_frame = { AST_FRAME_NULL, }; 03189 ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name); 03190 ast_set_flag(clone, AST_FLAG_ZOMBIE); 03191 ast_queue_frame(clone, &null_frame); 03192 ast_mutex_unlock(&clone->lock); 03193 } 03194 03195 /* Signal any blocker */ 03196 if (ast_test_flag(original, AST_FLAG_BLOCKING)) 03197 pthread_kill(original->blocker, SIGURG); 03198 ast_log(LOG_DEBUG, "Done Masquerading %s (%d)\n", original->name, original->_state); 03199 return 0; 03200 }
|
|
Definition at line 1109 of file channel.h. 01110 { 01111 int x; 01112 for (x=start ? *start : 0;x<max;x++) 01113 if (pfds[x].fd == fd) { 01114 if (start) { 01115 if (x==*start) 01116 (*start)++; 01117 } 01118 return pfds[x].revents; 01119 } 01120 return 0; 01121 }
|
|
Definition at line 818 of file channel.c. References channel_find_locked(). Referenced by pickup_exec(). 00819 { 00820 return channel_find_locked(NULL, NULL, 0, context, exten); 00821 }
|
|
Get channel by name (locks channel) Definition at line 800 of file channel.c. References channel_find_locked(). Referenced by action_getvar(), action_hangup(), action_redirect(), action_setcdruserfield(), action_setvar(), action_status(), action_timeout(), ast_async_goto_by_name(), change_monitor_action(), get_zap_channel_locked(), handle_channelstatus(), handle_debugchan(), handle_getvariablefull(), handle_hangup(), handle_nodebugchan(), handle_showchan(), handle_softhangup(), pbx_builtin_importvar(), pickup_exec(), start_monitor_action(), and stop_monitor_action(). 00801 { 00802 return channel_find_locked(NULL, name, 0, NULL, NULL); 00803 }
|
|
Get channel by name prefix (locks channel) Definition at line 806 of file channel.c. References channel_find_locked(). Referenced by ast_parse_device_state(), and mixmonitor_cli(). 00807 { 00808 return channel_find_locked(NULL, name, namelen, NULL, NULL); 00809 }
|
|
Get a channel technology structure by name.
Definition at line 385 of file channel.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), backends, LOG_WARNING, chanlist::next, chanlist::tech, and ast_channel_tech::type. Referenced by ast_device_state(). 00386 { 00387 struct chanlist *chanls; 00388 00389 if (ast_mutex_lock(&chlock)) { 00390 ast_log(LOG_WARNING, "Unable to lock channel tech list\n"); 00391 return NULL; 00392 } 00393 00394 for (chanls = backends; chanls; chanls = chanls->next) { 00395 if (strcasecmp(name, chanls->tech->type)) 00396 continue; 00397 00398 ast_mutex_unlock(&chlock); 00399 return chanls->tech; 00400 } 00401 00402 ast_mutex_unlock(&chlock); 00403 return NULL; 00404 }
|
|
Definition at line 3825 of file channel.c. References ast_log(), ast_strdupa, copy(), group, LOG_ERROR, LOG_WARNING, and strsep(). Referenced by _parse(), build_device(), build_gateway(), build_peer(), build_user(), load_module(), and read_agent_config(). 03826 { 03827 char *copy; 03828 char *piece; 03829 char *c=NULL; 03830 int start=0, finish=0, x; 03831 ast_group_t group = 0; 03832 03833 copy = ast_strdupa(s); 03834 if (!copy) { 03835 ast_log(LOG_ERROR, "Out of memory\n"); 03836 return 0; 03837 } 03838 c = copy; 03839 03840 while((piece = strsep(&c, ","))) { 03841 if (sscanf(piece, "%d-%d", &start, &finish) == 2) { 03842 /* Range */ 03843 } else if (sscanf(piece, "%d", &start)) { 03844 /* Just one */ 03845 finish = start; 03846 } else { 03847 ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece); 03848 continue; 03849 } 03850 for (x = start; x <= finish; x++) { 03851 if ((x > 63) || (x < 0)) { 03852 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x); 03853 } else 03854 group |= ((ast_group_t) 1 << x); 03855 } 03856 } 03857 return group; 03858 }
|
|
Hang up a channel.
Definition at line 1313 of file channel.c. References ast_cause2str(), ast_cdr_detach(), ast_cdr_end(), ast_channel_free(), ast_closestream(), ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_channel::blocker, ast_channel::blockproc, ast_channel::cdr, CRASH, detach_spies(), EVENT_FLAG_CALL, free_translation(), ast_channel::generator, ast_channel::generatordata, ast_channel_tech::hangup, ast_channel::hangupcause, ast_channel::lock, LOG_WARNING, manager_event(), ast_channel::masq, ast_channel::masqr, ast_channel::name, option_debug, ast_generator::release, ast_channel::sched, sched_context_destroy(), ast_channel::stream, ast_channel::tech, ast_channel::uniqueid, and ast_channel::vstream. Referenced by __ast_request_and_dial(), __oh323_new(), agent_hangup(), agent_read(), alsa_new(), ast_async_goto(), ast_bridge_call_thread(), ast_iax2_new(), ast_modem_new(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pbx_run_app(), async_wait(), builtin_atxfer(), chanavail_exec(), check_goto_on_transfer(), conf_free(), do_parking_thread(), features_hangup(), function_ilink(), handle_hd_hf(), handle_init_event(), handle_request_invite(), hangup_chan(), hangupcalls(), hanguptree(), iax2_request(), iax_park(), iax_park_thread(), local_hangup(), mgcp_new(), mgcp_ss(), nbs_new(), oss_new(), park_exec(), parkandannounce_exec(), phone_new(), ring_entry(), rpt(), rpt_call(), rpt_tele_thread(), sip_new(), sip_park(), sip_park_thread(), skinny_new(), skinny_ss(), ss_thread(), vpb_new(), wait_for_answer(), zt_handle_event(), and zt_new(). 01314 { 01315 int res = 0; 01316 01317 /* Don't actually hang up a channel that will masquerade as someone else, or 01318 if someone is going to masquerade as us */ 01319 ast_mutex_lock(&chan->lock); 01320 01321 detach_spies(chan); /* get rid of spies */ 01322 01323 if (chan->masq) { 01324 if (ast_do_masquerade(chan)) 01325 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 01326 } 01327 01328 if (chan->masq) { 01329 ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name); 01330 ast_mutex_unlock(&chan->lock); 01331 return 0; 01332 } 01333 /* If this channel is one which will be masqueraded into something, 01334 mark it as a zombie already, so we know to free it later */ 01335 if (chan->masqr) { 01336 ast_set_flag(chan, AST_FLAG_ZOMBIE); 01337 ast_mutex_unlock(&chan->lock); 01338 return 0; 01339 } 01340 free_translation(chan); 01341 /* Close audio stream */ 01342 if (chan->stream) { 01343 ast_closestream(chan->stream); 01344 chan->stream = NULL; 01345 } 01346 /* Close video stream */ 01347 if (chan->vstream) { 01348 ast_closestream(chan->vstream); 01349 chan->vstream = NULL; 01350 } 01351 if (chan->sched) { 01352 sched_context_destroy(chan->sched); 01353 chan->sched = NULL; 01354 } 01355 01356 if (chan->generatordata) /* Clear any tone stuff remaining */ 01357 chan->generator->release(chan, chan->generatordata); 01358 chan->generatordata = NULL; 01359 chan->generator = NULL; 01360 if (chan->cdr) { /* End the CDR if it hasn't already */ 01361 ast_cdr_end(chan->cdr); 01362 ast_cdr_detach(chan->cdr); /* Post and Free the CDR */ 01363 chan->cdr = NULL; 01364 } 01365 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) { 01366 ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd " 01367 "is blocked by thread %ld in procedure %s! Expect a failure\n", 01368 (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc); 01369 CRASH; 01370 } 01371 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) { 01372 if (option_debug) 01373 ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name); 01374 if (chan->tech->hangup) 01375 res = chan->tech->hangup(chan); 01376 } else { 01377 if (option_debug) 01378 ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name); 01379 } 01380 01381 ast_mutex_unlock(&chan->lock); 01382 manager_event(EVENT_FLAG_CALL, "Hangup", 01383 "Channel: %s\r\n" 01384 "Uniqueid: %s\r\n" 01385 "Cause: %d\r\n" 01386 "Cause-txt: %s\r\n", 01387 chan->name, 01388 chan->uniqueid, 01389 chan->hangupcause, 01390 ast_cause2str(chan->hangupcause) 01391 ); 01392 ast_channel_free(chan); 01393 return res; 01394 }
|
|
Indicates condition of channel.
Definition at line 2056 of file channel.c. References ast_check_hangup(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, AST_FLAG_ZOMBIE, ast_get_indication_tone(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_playtones_start(), ast_playtones_stop(), ast_test_flag, tone_zone_sound::data, ast_channel_tech::indicate, ast_channel::lock, LOG_WARNING, ast_channel::name, ast_channel::tech, and ast_channel::zone. Referenced by agent_indicate(), ast_feature_request_and_dial(), attempt_transfer(), builtin_atxfer(), builtin_blindtransfer(), conf_run(), do_parking_thread(), features_indicate(), handle_recordfile(), handle_remote_data(), handle_remote_phone_dtmf(), mgcp_ss(), park_exec(), pbx_builtin_busy(), pbx_builtin_congestion(), pbx_builtin_progress(), pbx_builtin_ringing(), queue_exec(), rmt_telem_finish(), rmt_telem_start(), rpt(), send_waveform_to_channel(), skinny_ss(), vpb_fixup(), and wait_for_answer(). 02057 { 02058 int res = -1; 02059 02060 ast_mutex_lock(&chan->lock); 02061 /* Stop if we're a zombie or need a soft hangup */ 02062 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 02063 ast_mutex_unlock(&chan->lock); 02064 return -1; 02065 } 02066 if (chan->tech->indicate) 02067 res = chan->tech->indicate(chan, condition); 02068 ast_mutex_unlock(&chan->lock); 02069 if (!chan->tech->indicate || res) { 02070 /* 02071 * Device does not support (that) indication, lets fake 02072 * it by doing our own tone generation. (PM2002) 02073 */ 02074 if (condition >= 0) { 02075 const struct tone_zone_sound *ts = NULL; 02076 switch (condition) { 02077 case AST_CONTROL_RINGING: 02078 ts = ast_get_indication_tone(chan->zone, "ring"); 02079 break; 02080 case AST_CONTROL_BUSY: 02081 ts = ast_get_indication_tone(chan->zone, "busy"); 02082 break; 02083 case AST_CONTROL_CONGESTION: 02084 ts = ast_get_indication_tone(chan->zone, "congestion"); 02085 break; 02086 } 02087 if (ts && ts->data[0]) { 02088 ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition); 02089 ast_playtones_start(chan,0,ts->data, 1); 02090 res = 0; 02091 } else if (condition == AST_CONTROL_PROGRESS) { 02092 /* ast_playtones_stop(chan); */ 02093 } else if (condition == AST_CONTROL_PROCEEDING) { 02094 /* Do nothing, really */ 02095 } else if (condition == AST_CONTROL_HOLD) { 02096 /* Do nothing.... */ 02097 } else if (condition == AST_CONTROL_UNHOLD) { 02098 /* Do nothing.... */ 02099 } else if (condition == AST_CONTROL_VIDUPDATE) { 02100 /* Do nothing.... */ 02101 } else { 02102 /* not handled */ 02103 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name); 02104 res = -1; 02105 } 02106 } 02107 else ast_playtones_stop(chan); 02108 } 02109 return res; 02110 }
|
|
Definition at line 3913 of file channel.c. Referenced by ast_serialize_showchan(), misdn_cfg_get_config_string(), print_group(), and read_config(). 03914 { 03915 unsigned int i; 03916 int first=1; 03917 char num[3]; 03918 03919 buf[0] = '\0'; 03920 03921 if (!group) /* Return empty string if no group */ 03922 return(buf); 03923 03924 for (i=0; i<=63; i++) { /* Max group is 63 */ 03925 if (group & ((ast_group_t) 1 << i)) { 03926 if (!first) { 03927 strncat(buf, ", ", buflen); 03928 } else { 03929 first=0; 03930 } 03931 snprintf(num, sizeof(num), "%u", i); 03932 strncat(buf, num, buflen); 03933 } 03934 } 03935 return(buf); 03936 }
|
|
Definition at line 2212 of file channel.c. References ast_channel::_state, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), AST_STATE_UP, ast_write(), ast_frame::data, LOG_WARNING, ast_channel::name, ast_channel::rawwriteformat, ast_frame::src, and ast_frame::subclass. Referenced by ast_activate_generator(). 02213 { 02214 struct ast_frame a = { AST_FRAME_VOICE }; 02215 char nothing[128]; 02216 02217 /* Send an empty audio frame to get things moving */ 02218 if (chan->_state != AST_STATE_UP) { 02219 ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name); 02220 a.subclass = chan->rawwriteformat; 02221 a.data = nothing + AST_FRIENDLY_OFFSET; 02222 a.src = "ast_prod"; 02223 if (ast_write(chan, &a)) 02224 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name); 02225 } 02226 return 0; 02227 }
|
|
Queue a control frame.
Definition at line 682 of file channel.c. References AST_FRAME_CONTROL, ast_queue_frame(), and ast_frame::subclass. Referenced by __oh323_update_info(), ast_pickup_call(), auto_congest(), handle_request_info(), handle_response(), handle_response_invite(), mgcp_call(), nbs_call(), phone_call(), pickup_exec(), send_cause2ast(), setup_rtp_connection(), skinny_call(), and update_state(). 00683 { 00684 struct ast_frame f = { AST_FRAME_CONTROL, }; 00685 f.subclass = control; 00686 return ast_queue_frame(chan, &f); 00687 }
|
|
Queue an outgoing frame.
Definition at line 611 of file channel.c. References ast_channel::alertpipe, AST_CONTROL_HANGUP, AST_FLAG_BLOCKING, AST_FRAME_CONTROL, AST_FRAME_VOICE, ast_frdup(), ast_frfree(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_channel::blocker, CRASH, ast_frame::frametype, ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_frame::next, ast_frame::prev, ast_channel::readq, ast_frame::subclass, and ast_channel::timingfd. Referenced by agent_new(), alsa_call(), ast_channel_masquerade(), ast_channel_setwhentohangup(), ast_dsp_process(), ast_queue_control(), ast_queue_hangup(), ast_softhangup_nolock(), cb_events(), console_answer(), console_dial(), console_flash(), console_sendtext(), do_chanreads(), do_immediate_setup(), handle_request_info(), handle_request_invite(), handle_response_invite(), local_queue_frame(), mgcp_queue_frame(), monitor_handle_owned(), oss_call(), process_sdp(), receive_message(), and send_digit(). 00612 { 00613 struct ast_frame *f; 00614 struct ast_frame *prev, *cur; 00615 int blah = 1; 00616 int qlen = 0; 00617 00618 /* Build us a copy and free the original one */ 00619 f = ast_frdup(fin); 00620 if (!f) { 00621 ast_log(LOG_WARNING, "Unable to duplicate frame\n"); 00622 return -1; 00623 } 00624 ast_mutex_lock(&chan->lock); 00625 prev = NULL; 00626 cur = chan->readq; 00627 while(cur) { 00628 if ((cur->frametype == AST_FRAME_CONTROL) && (cur->subclass == AST_CONTROL_HANGUP)) { 00629 /* Don't bother actually queueing anything after a hangup */ 00630 ast_frfree(f); 00631 ast_mutex_unlock(&chan->lock); 00632 return 0; 00633 } 00634 prev = cur; 00635 cur = cur->next; 00636 qlen++; 00637 } 00638 /* Allow up to 96 voice frames outstanding, and up to 128 total frames */ 00639 if (((fin->frametype == AST_FRAME_VOICE) && (qlen > 96)) || (qlen > 128)) { 00640 if (fin->frametype != AST_FRAME_VOICE) { 00641 ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name); 00642 CRASH; 00643 } else { 00644 ast_log(LOG_DEBUG, "Dropping voice to exceptionally long queue on %s\n", chan->name); 00645 ast_frfree(f); 00646 ast_mutex_unlock(&chan->lock); 00647 return 0; 00648 } 00649 } 00650 if (prev) 00651 prev->next = f; 00652 else 00653 chan->readq = f; 00654 if (chan->alertpipe[1] > -1) { 00655 if (write(chan->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah)) 00656 ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d (qlen = %d): %s!\n", 00657 chan->name, f->frametype, f->subclass, qlen, strerror(errno)); 00658 #ifdef ZAPTEL_OPTIMIZATIONS 00659 } else if (chan->timingfd > -1) { 00660 ioctl(chan->timingfd, ZT_TIMERPING, &blah); 00661 #endif 00662 } else if (ast_test_flag(chan, AST_FLAG_BLOCKING)) { 00663 pthread_kill(chan->blocker, SIGURG); 00664 } 00665 ast_mutex_unlock(&chan->lock); 00666 return 0; 00667 }
|
|
Queue a hangup frame.
Definition at line 670 of file channel.c. References ast_channel::_softhangup, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), AST_SOFTHANGUP_DEV, and ast_channel::lock. Referenced by __oh323_update_info(), __sip_autodestruct(), cleanup_connection(), console_hangup(), handle_request_bye(), handle_request_cancel(), handle_request_refer(), handle_response(), hangup_chan(), hangup_connection(), iax2_destroy(), iax2_predestroy(), mgcp_queue_hangup(), misdn_answer(), 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 1829 of file channel.c. References ast_channel::_softhangup, ast_channel::_state, ast_channel::alertpipe, ast_cdr_answer(), ast_cdr_end(), ast_check_hangup(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, ast_deactivate_generator(), ast_do_masquerade(), AST_FLAG_DEFER_DTMF, AST_FLAG_EXCEPTION, AST_FLAG_ZOMBIE, AST_FRAME_CNG, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frame_dump(), AST_FRAME_NULL, AST_FRAME_VOICE, ast_frfree(), ast_getformatname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_seekstream(), ast_setstate(), ast_settimeout(), AST_SOFTHANGUP_DEV, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, ast_translate(), ast_writestream(), ast_channel::blocker, ast_channel::cdr, ast_frame::data, ast_frame::datalen, ast_channel::dtmff, ast_channel::dtmfq, ast_channel_tech::exception, ast_channel::fdno, ast_channel::fin, ast_frame::frametype, ast_generator::generate, ast_channel::generator, generator_force(), ast_channel::generatordata, ast_channel::insmpl, ast_channel::lock, LOG_NOTICE, LOG_WARNING, ast_channel::masq, ast_channel::monitor, ast_channel::name, ast_channel::nativeformats, ast_frame::next, ast_channel::outsmpl, queue_frame_to_spies(), ast_channel_tech::read, ast_channel_monitor::read_stream, ast_channel::readq, ast_channel::readtrans, ast_frame::samples, SEEK_FORCECUR, ast_channel::spies, SPY_READ, ast_frame::subclass, ast_channel::tech, ast_channel::timingfd, and ast_channel::timingfunc. Referenced by __adsi_transmit_messages(), __ast_request_and_dial(), adsi_careful_send(), agent_read(), app_exec(), ast_feature_request_and_dial(), ast_masq_park_call(), ast_recvtext(), 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(), do_parking_thread(), echo_exec(), features_read(), find_cache(), handle_recordfile(), iax_park_thread(), ices_exec(), measurenoise(), misdn_bridge(), recordthread(), rpt(), run_agi(), send_waveform_to_channel(), sendurl_exec(), ss_thread(), wait_for_answer(), wait_for_hangup(), waitforring_exec(), and zt_bridge(). 01830 { 01831 struct ast_frame *f = NULL; 01832 int blah; 01833 int prestate; 01834 #ifdef ZAPTEL_OPTIMIZATIONS 01835 int (*func)(void *); 01836 void *data; 01837 int res; 01838 #endif 01839 static struct ast_frame null_frame = { 01840 AST_FRAME_NULL, 01841 }; 01842 01843 ast_mutex_lock(&chan->lock); 01844 if (chan->masq) { 01845 if (ast_do_masquerade(chan)) { 01846 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 01847 f = NULL; 01848 } else 01849 f = &null_frame; 01850 ast_mutex_unlock(&chan->lock); 01851 return f; 01852 } 01853 01854 /* Stop if we're a zombie or need a soft hangup */ 01855 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 01856 if (chan->generator) 01857 ast_deactivate_generator(chan); 01858 ast_mutex_unlock(&chan->lock); 01859 return NULL; 01860 } 01861 prestate = chan->_state; 01862 01863 if (!ast_test_flag(chan, AST_FLAG_DEFER_DTMF) && !ast_strlen_zero(chan->dtmfq)) { 01864 /* We have DTMF that has been deferred. Return it now */ 01865 chan->dtmff.frametype = AST_FRAME_DTMF; 01866 chan->dtmff.subclass = chan->dtmfq[0]; 01867 /* Drop first digit */ 01868 memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1); 01869 ast_mutex_unlock(&chan->lock); 01870 return &chan->dtmff; 01871 } 01872 01873 /* Read and ignore anything on the alertpipe, but read only 01874 one sizeof(blah) per frame that we send from it */ 01875 if (chan->alertpipe[0] > -1) { 01876 read(chan->alertpipe[0], &blah, sizeof(blah)); 01877 } 01878 #ifdef ZAPTEL_OPTIMIZATIONS 01879 if ((chan->timingfd > -1) && (chan->fdno == AST_MAX_FDS - 2) && ast_test_flag(chan, AST_FLAG_EXCEPTION)) { 01880 ast_clear_flag(chan, AST_FLAG_EXCEPTION); 01881 blah = -1; 01882 /* IF we can't get event, assume it's an expired as-per the old interface */ 01883 res = ioctl(chan->timingfd, ZT_GETEVENT, &blah); 01884 if (res) 01885 blah = ZT_EVENT_TIMER_EXPIRED; 01886 01887 if (blah == ZT_EVENT_TIMER_PING) { 01888 #if 0 01889 ast_log(LOG_NOTICE, "Oooh, there's a PING!\n"); 01890 #endif 01891 if (!chan->readq || !chan->readq->next) { 01892 /* Acknowledge PONG unless we need it again */ 01893 #if 0 01894 ast_log(LOG_NOTICE, "Sending a PONG!\n"); 01895 #endif 01896 if (ioctl(chan->timingfd, ZT_TIMERPONG, &blah)) { 01897 ast_log(LOG_WARNING, "Failed to pong timer on '%s': %s\n", chan->name, strerror(errno)); 01898 } 01899 } 01900 } else if (blah == ZT_EVENT_TIMER_EXPIRED) { 01901 ioctl(chan->timingfd, ZT_TIMERACK, &blah); 01902 func = chan->timingfunc; 01903 data = chan->timingdata; 01904 ast_mutex_unlock(&chan->lock); 01905 if (func) { 01906 #if 0 01907 ast_log(LOG_DEBUG, "Calling private function\n"); 01908 #endif 01909 func(data); 01910 } else { 01911 blah = 0; 01912 ast_mutex_lock(&chan->lock); 01913 ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah); 01914 chan->timingdata = NULL; 01915 ast_mutex_unlock(&chan->lock); 01916 } 01917 f = &null_frame; 01918 return f; 01919 } else 01920 ast_log(LOG_NOTICE, "No/unknown event '%d' on timer for '%s'?\n", blah, chan->name); 01921 } 01922 #endif 01923 /* Check for pending read queue */ 01924 if (chan->readq) { 01925 f = chan->readq; 01926 chan->readq = f->next; 01927 /* Interpret hangup and return NULL */ 01928 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) { 01929 ast_frfree(f); 01930 f = NULL; 01931 } 01932 } else { 01933 chan->blocker = pthread_self(); 01934 if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) { 01935 if (chan->tech->exception) 01936 f = chan->tech->exception(chan); 01937 else { 01938 ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name); 01939 f = &null_frame; 01940 } 01941 /* Clear the exception flag */ 01942 ast_clear_flag(chan, AST_FLAG_EXCEPTION); 01943 } else { 01944 if (chan->tech->read) 01945 f = chan->tech->read(chan); 01946 else 01947 ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name); 01948 } 01949 } 01950 01951 01952 if (f && (f->frametype == AST_FRAME_VOICE)) { 01953 if (!(f->subclass & chan->nativeformats)) { 01954 /* This frame can't be from the current native formats -- drop it on the 01955 floor */ 01956 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)); 01957 ast_frfree(f); 01958 f = &null_frame; 01959 } else { 01960 if (chan->spies) 01961 queue_frame_to_spies(chan, f, SPY_READ); 01962 01963 if (chan->monitor && chan->monitor->read_stream ) { 01964 #ifndef MONITOR_CONSTANT_DELAY 01965 int jump = chan->outsmpl - chan->insmpl - 4 * f->samples; 01966 if (jump >= 0) { 01967 if (ast_seekstream(chan->monitor->read_stream, jump + f->samples, SEEK_FORCECUR) == -1) 01968 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 01969 chan->insmpl += jump + 4 * f->samples; 01970 } else 01971 chan->insmpl+= f->samples; 01972 #else 01973 int jump = chan->outsmpl - chan->insmpl; 01974 if (jump - MONITOR_DELAY >= 0) { 01975 if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1) 01976 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 01977 chan->insmpl += jump; 01978 } else 01979 chan->insmpl += f->samples; 01980 #endif 01981 if (ast_writestream(chan->monitor->read_stream, f) < 0) 01982 ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n"); 01983 } 01984 if (chan->readtrans) { 01985 f = ast_translate(chan->readtrans, f, 1); 01986 if (!f) 01987 f = &null_frame; 01988 } 01989 } 01990 } 01991 01992 /* Make sure we always return NULL in the future */ 01993 if (!f) { 01994 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01995 if (chan->generator) 01996 ast_deactivate_generator(chan); 01997 /* End the CDR if appropriate */ 01998 if (chan->cdr) 01999 ast_cdr_end(chan->cdr); 02000 } else if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF) && f->frametype == AST_FRAME_DTMF) { 02001 if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2) 02002 chan->dtmfq[strlen(chan->dtmfq)] = f->subclass; 02003 else 02004 ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name); 02005 ast_frfree(f); 02006 f = &null_frame; 02007 } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_ANSWER)) { 02008 if (prestate == AST_STATE_UP) { 02009 ast_log(LOG_DEBUG, "Dropping duplicate answer!\n"); 02010 ast_frfree(f); 02011 f = &null_frame; 02012 } 02013 /* Answer the CDR */ 02014 ast_setstate(chan, AST_STATE_UP); 02015 ast_cdr_answer(chan->cdr); 02016 } 02017 02018 /* Run any generator sitting on the line */ 02019 if (f && (f->frametype == AST_FRAME_VOICE) && chan->generatordata) { 02020 /* Mask generator data temporarily and apply. If there is a timing function, it 02021 will be calling the generator instead */ 02022 void *tmp; 02023 int res; 02024 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples); 02025 02026 if (chan->timingfunc) { 02027 ast_log(LOG_DEBUG, "Generator got voice, switching to phase locked mode\n"); 02028 ast_settimeout(chan, 0, NULL, NULL); 02029 } 02030 tmp = chan->generatordata; 02031 chan->generatordata = NULL; 02032 generate = chan->generator->generate; 02033 res = generate(chan, tmp, f->datalen, f->samples); 02034 chan->generatordata = tmp; 02035 if (res) { 02036 ast_log(LOG_DEBUG, "Auto-deactivating generator\n"); 02037 ast_deactivate_generator(chan); 02038 } 02039 } else if (f && (f->frametype == AST_FRAME_CNG)) { 02040 if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) { 02041 ast_log(LOG_DEBUG, "Generator got CNG, switching to zap timed mode\n"); 02042 ast_settimeout(chan, 160, generator_force, chan); 02043 } 02044 } 02045 /* High bit prints debugging */ 02046 if (chan->fin & 0x80000000) 02047 ast_frame_dump(chan->name, f, "<<"); 02048 if ((chan->fin & 0x7fffffff) == 0x7fffffff) 02049 chan->fin &= 0x80000000; 02050 else 02051 chan->fin++; 02052 ast_mutex_unlock(&chan->lock); 02053 return f; 02054 }
|
|
Definition at line 2639 of file channel.c. References ast_check_hangup(), AST_DIGIT_ANY, AST_FLAG_ZOMBIE, ast_stopstream(), ast_test_flag, ast_waitfordigit(), ast_waitstream(), and ast_channel::stream. Referenced by adsi_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(). 02640 { 02641 int pos=0; 02642 int to = ftimeout; 02643 int d; 02644 02645 /* XXX Merge with full version? XXX */ 02646 /* Stop if we're a zombie or need a soft hangup */ 02647 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 02648 return -1; 02649 if (!len) 02650 return -1; 02651 do { 02652 if (c->stream) { 02653 d = ast_waitstream(c, AST_DIGIT_ANY); 02654 ast_stopstream(c); 02655 usleep(1000); 02656 if (!d) 02657 d = ast_waitfordigit(c, to); 02658 } else { 02659 d = ast_waitfordigit(c, to); 02660 } 02661 if (d < 0) 02662 return -1; 02663 if (d == 0) { 02664 s[pos]='\0'; 02665 return 1; 02666 } 02667 if (!strchr(enders, d)) 02668 s[pos++] = d; 02669 if (strchr(enders, d) || (pos >= len)) { 02670 s[pos]='\0'; 02671 return 0; 02672 } 02673 to = timeout; 02674 } while(1); 02675 /* Never reached */ 02676 return 0; 02677 }
|
|
Definition at line 2679 of file channel.c. References ast_check_hangup(), AST_DIGIT_ANY, AST_FLAG_ZOMBIE, ast_stopstream(), ast_test_flag, ast_waitfordigit_full(), ast_waitstream_full(), and ast_channel::stream. Referenced by ast_app_getdata_full(). 02680 { 02681 int pos=0; 02682 int to = ftimeout; 02683 int d; 02684 02685 /* Stop if we're a zombie or need a soft hangup */ 02686 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 02687 return -1; 02688 if (!len) 02689 return -1; 02690 do { 02691 if (c->stream) { 02692 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd); 02693 ast_stopstream(c); 02694 usleep(1000); 02695 if (!d) 02696 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 02697 } else { 02698 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 02699 } 02700 if (d < 0) 02701 return -1; 02702 if (d == 0) { 02703 s[pos]='\0'; 02704 return 1; 02705 } 02706 if (d == 1) { 02707 s[pos]='\0'; 02708 return 2; 02709 } 02710 if (!strchr(enders, d)) 02711 s[pos++] = d; 02712 if (strchr(enders, d) || (pos >= len)) { 02713 s[pos]='\0'; 02714 return 0; 02715 } 02716 to = timeout; 02717 } while(1); 02718 /* Never reached */ 02719 return 0; 02720 }
|
|
Definition at line 2112 of file channel.c. References ast_recvtext(), and free. Referenced by handle_recvchar(). 02113 { 02114 int c; 02115 char *buf = ast_recvtext(chan, timeout); 02116 if (buf == NULL) 02117 return -1; /* error or timeout */ 02118 c = *(unsigned char *)buf; 02119 free(buf); 02120 return c; 02121 }
|
|
Definition at line 2123 of file channel.c. References ast_check_hangup(), AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_TEXT, ast_frfree(), ast_read(), ast_waitfor(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, strndup, and ast_frame::subclass. Referenced by ast_recvchar(), and handle_recvtext(). 02124 { 02125 int res, done = 0; 02126 char *buf = NULL; 02127 02128 while (!done) { 02129 struct ast_frame *f; 02130 if (ast_check_hangup(chan)) 02131 break; 02132 res = ast_waitfor(chan, timeout); 02133 if (res <= 0) /* timeout or error */ 02134 break; 02135 timeout = res; /* update timeout */ 02136 f = ast_read(chan); 02137 if (f == NULL) 02138 break; /* no frame */ 02139 if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP) 02140 done = 1; /* force a break */ 02141 else if (f->frametype == AST_FRAME_TEXT) { /* what we want */ 02142 buf = strndup((char *) f->data, f->datalen); /* dup and break */ 02143 done = 1; 02144 } 02145 ast_frfree(f); 02146 } 02147 return buf; 02148 }
|
|
Requests a channel.
Definition at line 2545 of file channel.c. References AST_CAUSE_NOTDEFINED, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_translator_best_choice(), backends, ast_channel_tech::capabilities, fmt, LOG_WARNING, chanlist::next, chanlist::tech, and ast_channel_tech::type. Referenced by __ast_request_and_dial(), agent_request(), ast_feature_request_and_dial(), attempt_reconnect(), chanavail_exec(), features_alloc(), function_ilink(), ring_entry(), rpt(), rpt_call(), rpt_tele_thread(), and wait_for_answer(). 02546 { 02547 struct chanlist *chan; 02548 struct ast_channel *c; 02549 int capabilities; 02550 int fmt; 02551 int res; 02552 int foo; 02553 02554 if (!cause) 02555 cause = &foo; 02556 *cause = AST_CAUSE_NOTDEFINED; 02557 02558 if (ast_mutex_lock(&chlock)) { 02559 ast_log(LOG_WARNING, "Unable to lock channel list\n"); 02560 return NULL; 02561 } 02562 02563 for (chan = backends; chan; chan = chan->next) { 02564 if (strcasecmp(type, chan->tech->type)) 02565 continue; 02566 02567 capabilities = chan->tech->capabilities; 02568 fmt = format; 02569 res = ast_translator_best_choice(&fmt, &capabilities); 02570 if (res < 0) { 02571 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->tech->capabilities, format); 02572 ast_mutex_unlock(&chlock); 02573 return NULL; 02574 } 02575 ast_mutex_unlock(&chlock); 02576 if (!chan->tech->requester) 02577 return NULL; 02578 02579 if (!(c = chan->tech->requester(type, capabilities, data, cause))) 02580 return NULL; 02581 02582 if (c->_state == AST_STATE_DOWN) { 02583 manager_event(EVENT_FLAG_CALL, "Newchannel", 02584 "Channel: %s\r\n" 02585 "State: %s\r\n" 02586 "CallerID: %s\r\n" 02587 "CallerIDName: %s\r\n" 02588 "Uniqueid: %s\r\n", 02589 c->name, ast_state2str(c->_state), 02590 c->cid.cid_num ? c->cid.cid_num : "<unknown>", 02591 c->cid.cid_name ? c->cid.cid_name : "<unknown>", 02592 c->uniqueid); 02593 } 02594 return c; 02595 } 02596 02597 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type); 02598 *cause = AST_CAUSE_NOSUCHDRIVER; 02599 ast_mutex_unlock(&chlock); 02600 02601 return NULL; 02602 }
|
|
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 2540 of file channel.c. References __ast_request_and_dial(). Referenced by ast_pbx_outgoing_exten(). 02541 { 02542 return __ast_request_and_dial(type, format, data, timeout, outstate, cidnum, cidname, NULL); 02543 }
|
|
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(), skinny_ss(), testclient_exec(), testserver_exec(), wait_for_hangup(), wait_interval(), and zapateller_exec(). 00847 { 00848 struct ast_frame *f; 00849 while(ms > 0) { 00850 ms = ast_waitfor(chan, ms); 00851 if (ms <0) 00852 return -1; 00853 if (ms > 0) { 00854 f = ast_read(chan); 00855 if (!f) 00856 return -1; 00857 ast_frfree(f); 00858 } 00859 } 00860 return 0; 00861 }
|
|
Wait for a specied amount of time, looking for hangups and a condition argument.
Definition at line 824 of file channel.c. References ast_frfree(), ast_read(), and ast_waitfor(). Referenced by __login_exec(). 00826 { 00827 struct ast_frame *f; 00828 00829 while(ms > 0) { 00830 if( cond && ((*cond)(data) == 0 ) ) 00831 return 0; 00832 ms = ast_waitfor(chan, ms); 00833 if (ms <0) 00834 return -1; 00835 if (ms > 0) { 00836 f = ast_read(chan); 00837 if (!f) 00838 return -1; 00839 ast_frfree(f); 00840 } 00841 } 00842 return 0; 00843 }
|
|
Waits for activity on a group of channels.
Definition at line 1146 of file channel.h. Referenced by sound_thread(). 01147 { 01148 #ifdef __linux__ 01149 return select(nfds, rfds, wfds, efds, tvp); 01150 #else 01151 if (tvp) { 01152 struct timeval tv, tvstart, tvend, tvlen; 01153 int res; 01154 01155 tv = *tvp; 01156 gettimeofday(&tvstart, NULL); 01157 res = select(nfds, rfds, wfds, efds, tvp); 01158 gettimeofday(&tvend, NULL); 01159 timersub(&tvend, &tvstart, &tvlen); 01160 timersub(&tv, &tvlen, tvp); 01161 if (tvp->tv_sec < 0 || (tvp->tv_sec == 0 && tvp->tv_usec < 0)) { 01162 tvp->tv_sec = 0; 01163 tvp->tv_usec = 0; 01164 } 01165 return res; 01166 } 01167 else 01168 return select(nfds, rfds, wfds, efds, NULL); 01169 #endif 01170 }
|
|
Definition at line 2207 of file channel.c. References do_senddigit(). Referenced by features_digit(). 02208 { 02209 return do_senddigit(chan, digit); 02210 }
|
|
Definition at line 2150 of file channel.c. References ast_check_hangup(), ast_clear_flag, AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_test_flag, CHECK_BLOCKING, ast_channel_tech::send_text, and ast_channel::tech. Referenced by agent_sendtext(), handle_sendtext(), and sendtext_exec(). 02151 { 02152 int res = 0; 02153 /* Stop if we're a zombie or need a soft hangup */ 02154 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) 02155 return -1; 02156 CHECK_BLOCKING(chan); 02157 if (chan->tech->send_text) 02158 res = chan->tech->send_text(chan, text); 02159 ast_clear_flag(chan, AST_FLAG_BLOCKING); 02160 return res; 02161 }
|
|
Definition at line 3202 of file channel.c. References ast_cdr_setcid(), ast_describe_caller_presentation(), ast_strlen_zero(), ast_channel::cdr, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, EVENT_FLAG_CALL, free, manager_event(), ast_channel::name, strdup, and ast_channel::uniqueid. Referenced by __ast_request_and_dial(), agent_call(), ast_feature_request_and_dial(), callerid_write(), get_callerid(), handle_setcallerid(), local_call(), lookupcidname_exec(), mgcp_ss(), monitor_handle_notowned(), privacy_exec(), read_config(), setcallerid_exec(), skinny_ss(), ss_thread(), wait_for_answer(), and zt_read(). 03203 { 03204 if (callerid) { 03205 if (chan->cid.cid_num) 03206 free(chan->cid.cid_num); 03207 if (ast_strlen_zero(callerid)) 03208 chan->cid.cid_num = NULL; 03209 else 03210 chan->cid.cid_num = strdup(callerid); 03211 } 03212 if (calleridname) { 03213 if (chan->cid.cid_name) 03214 free(chan->cid.cid_name); 03215 if (ast_strlen_zero(calleridname)) 03216 chan->cid.cid_name = NULL; 03217 else 03218 chan->cid.cid_name = strdup(calleridname); 03219 } 03220 if (ani) { 03221 if (chan->cid.cid_ani) 03222 free(chan->cid.cid_ani); 03223 if (ast_strlen_zero(ani)) 03224 chan->cid.cid_ani = NULL; 03225 else 03226 chan->cid.cid_ani = strdup(ani); 03227 } 03228 if (chan->cdr) 03229 ast_cdr_setcid(chan->cdr, chan); 03230 manager_event(EVENT_FLAG_CALL, "Newcallerid", 03231 "Channel: %s\r\n" 03232 "CallerID: %s\r\n" 03233 "CallerIDName: %s\r\n" 03234 "Uniqueid: %s\r\n" 03235 "CID-CallingPres: %d (%s)\r\n", 03236 chan->name, chan->cid.cid_num ? 03237 chan->cid.cid_num : "<Unknown>", 03238 chan->cid.cid_name ? 03239 chan->cid.cid_name : "<Unknown>", 03240 chan->uniqueid, 03241 chan->cid.cid_pres, 03242 ast_describe_caller_presentation(chan->cid.cid_pres) 03243 ); 03244 }
|
|
Definition at line 2414 of file channel.c. References ast_channel::rawreadformat, ast_channel::readformat, ast_channel::readtrans, and set_format(). Referenced by __login_exec(), __oh323_update_info(), adsi_transmit_message_full(), agent_call(), alarmreceiver_exec(), ast_app_getvoice(), ast_channel_make_compatible(), 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(), rpt(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_read(), and update_features(). 02415 { 02416 return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat, 02417 &chan->readtrans, 0); 02418 }
|
|
adds a list of channel variables to a channel
Definition at line 3938 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(). 03939 { 03940 struct ast_variable *cur; 03941 03942 for (cur = vars; cur; cur = cur->next) 03943 pbx_builtin_setvar_helper(chan, cur->name, cur->value); 03944 }
|
|
Definition at line 2420 of file channel.c. References ast_channel::rawwriteformat, set_format(), ast_channel::writeformat, and ast_channel::writetrans. Referenced by __login_exec(), __oh323_update_info(), adsi_transmit_message_full(), agent_call(), alarmreceiver_exec(), ast_channel_make_compatible(), ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_openstream_full(), ast_stopstream(), attempt_reconnect(), chanspy_exec(), conf_run(), disa_exec(), echo_exec(), function_ilink(), linear_alloc(), linear_release(), mgcp_rtp_read(), milliwatt_exec(), moh_alloc(), moh_files_release(), moh_release(), mp3_exec(), NBScat_exec(), oh323_rtp_read(), playtones_alloc(), playtones_release(), process_sdp(), rpt(), send_waveform_to_channel(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_read(), tonepair_alloc(), tonepair_release(), and update_features(). 02421 { 02422 return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat, 02423 &chan->writetrans, 1); 02424 }
|
|
Change the state of a channel.
Definition at line 3246 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(), 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_hangup(), vpb_new(), zt_answer(), zt_call(), zt_handle_event(), zt_indicate(), zt_new(), and zt_read(). 03247 { 03248 int oldstate = chan->_state; 03249 03250 if (oldstate == state) 03251 return 0; 03252 03253 chan->_state = state; 03254 ast_device_state_changed_literal(chan->name); 03255 manager_event(EVENT_FLAG_CALL, 03256 (oldstate == AST_STATE_DOWN) ? "Newchannel" : "Newstate", 03257 "Channel: %s\r\n" 03258 "State: %s\r\n" 03259 "CallerID: %s\r\n" 03260 "CallerIDName: %s\r\n" 03261 "Uniqueid: %s\r\n", 03262 chan->name, ast_state2str(chan->_state), 03263 chan->cid.cid_num ? chan->cid.cid_num : "<unknown>", 03264 chan->cid.cid_name ? chan->cid.cid_name : "<unknown>", 03265 chan->uniqueid); 03266 03267 return 0; 03268 }
|
|
Definition at line 1752 of file channel.c. References ast_log(), 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(). 01753 { 01754 int res = -1; 01755 #ifdef ZAPTEL_OPTIMIZATIONS 01756 if (c->timingfd > -1) { 01757 if (!func) { 01758 samples = 0; 01759 data = 0; 01760 } 01761 ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples); 01762 res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples); 01763 c->timingfunc = func; 01764 c->timingdata = data; 01765 } 01766 #endif 01767 return res; 01768 }
|
|
Returns non-zero if Asterisk is being shut down Definition at line 271 of file channel.c. References shutting_down. 00272 { 00273 return shutting_down; 00274 }
|
|
Softly hangup up a channel.
Definition at line 1161 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(), 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(). 01162 { 01163 int res; 01164 ast_mutex_lock(&chan->lock); 01165 res = ast_softhangup_nolock(chan, cause); 01166 ast_mutex_unlock(&chan->lock); 01167 return res; 01168 }
|
|
Softly hangup up a channel (no channel lock).
Definition at line 1145 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, ast_channel::name, and option_debug. Referenced by ast_async_goto(), ast_softhangup(), attempt_transfer(), do_monitor(), oh323_indicate(), sip_indicate(), and skinny_indicate(). 01146 { 01147 int res = 0; 01148 struct ast_frame f = { AST_FRAME_NULL }; 01149 if (option_debug) 01150 ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name); 01151 /* Inform channel driver that we need to be hung up, if it cares */ 01152 chan->_softhangup |= cause; 01153 ast_queue_frame(chan, &f); 01154 /* Interrupt any poll call or such */ 01155 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) 01156 pthread_kill(chan->blocker, SIGURG); 01157 return res; 01158 }
|
|
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_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 3806 of file channel.c. References ast_frfree(), ast_read(), ast_tonepair_start(), ast_waitfor(), and ast_channel::generatordata. Referenced by zapateller_exec(). 03807 { 03808 struct ast_frame *f; 03809 int res; 03810 03811 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol))) 03812 return res; 03813 03814 /* Give us some wiggle room */ 03815 while(chan->generatordata && (ast_waitfor(chan, 100) >= 0)) { 03816 f = ast_read(chan); 03817 if (f) 03818 ast_frfree(f); 03819 else 03820 return -1; 03821 } 03822 return 0; 03823 }
|
|
Start a tone going Definition at line 3785 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(), and sendnoise(). 03786 { 03787 struct tonepair_def d = { 0, }; 03788 03789 d.freq1 = freq1; 03790 d.freq2 = freq2; 03791 d.duration = duration; 03792 if (vol < 1) 03793 d.vol = 8192; 03794 else 03795 d.vol = vol; 03796 if (ast_activate_generator(chan, &tonepair, &d)) 03797 return -1; 03798 return 0; 03799 }
|
|
Stop a tone from playing Definition at line 3801 of file channel.c. References ast_deactivate_generator(). Referenced by sendnoise(). 03802 { 03803 ast_deactivate_generator(chan); 03804 }
|
|
Transfer a channel (if supported). Returns -1 on error, 0 if not supported and 1 if supported and requested.
Definition at line 2621 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(). 02622 { 02623 int res = -1; 02624 02625 /* Stop if we're a zombie or need a soft hangup */ 02626 ast_mutex_lock(&chan->lock); 02627 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) { 02628 if (chan->tech->transfer) { 02629 res = chan->tech->transfer(chan, dest); 02630 if (!res) 02631 res = 1; 02632 } else 02633 res = 0; 02634 } 02635 ast_mutex_unlock(&chan->lock); 02636 return res; 02637 }
|
|
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 1708 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_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(), do_waiting(), echo_exec(), handle_recordfile(), ices_exec(), measurenoise(), modem_call(), recordthread(), send_tone_burst(), send_waveform_to_channel(), sendurl_exec(), ss_thread(), wait_for_hangup(), and waitforring_exec(). 01709 { 01710 struct ast_channel *chan; 01711 int oldms = ms; 01712 01713 chan = ast_waitfor_n(&c, 1, &ms); 01714 if (ms < 0) { 01715 if (oldms < 0) 01716 return 0; 01717 else 01718 return -1; 01719 } 01720 return ms; 01721 }
|
|
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 1703 of file channel.c. References ast_waitfor_nandfds(). Referenced by ast_feature_request_and_dial(), ast_waitfor(), autoservice_run(), misdn_bridge(), rpt(), wait_for_answer(), and zt_bridge(). 01704 { 01705 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms); 01706 }
|
|
This version works on fd's only. Be careful with it. Definition at line 1489 of file channel.c. References ast_log(), pollfd::events, pollfd::fd, LOG_ERROR, POLLIN, and POLLPRI. Referenced by ast_modem_expect(), ast_modem_read_response(), bestdata_read(), dundi_lookup_internal(), and dundi_precache_internal(). 01490 { 01491 struct timeval start = { 0 , 0 }; 01492 int res; 01493 int x, y; 01494 int winner = -1; 01495 int spoint; 01496 struct pollfd *pfds; 01497 01498 pfds = alloca(sizeof(struct pollfd) * n); 01499 if (!pfds) { 01500 ast_log(LOG_ERROR, "Out of memory\n"); 01501 return -1; 01502 } 01503 if (*ms > 0) 01504 start = ast_tvnow(); 01505 y = 0; 01506 for (x=0; x < n; x++) { 01507 if (fds[x] > -1) { 01508 pfds[y].fd = fds[x]; 01509 pfds[y].events = POLLIN | POLLPRI; 01510 y++; 01511 } 01512 } 01513 res = poll(pfds, y, *ms); 01514 if (res < 0) { 01515 /* Simulate a timeout if we were interrupted */ 01516 if (errno != EINTR) 01517 *ms = -1; 01518 else 01519 *ms = 0; 01520 return -1; 01521 } 01522 spoint = 0; 01523 for (x=0; x < n; x++) { 01524 if (fds[x] > -1) { 01525 if ((res = ast_fdisset(pfds, fds[x], y, &spoint))) { 01526 winner = fds[x]; 01527 if (exception) { 01528 if (res & POLLPRI) 01529 *exception = -1; 01530 else 01531 *exception = 0; 01532 } 01533 } 01534 } 01535 } 01536 if (*ms > 0) { 01537 *ms -= ast_tvdiff_ms(ast_tvnow(), start); 01538 if (*ms < 0) 01539 *ms = 0; 01540 } 01541 return winner; 01542 }
|
|
Waits for activity on a group of channels.
Definition at line 1545 of file channel.c. References ast_log(), AST_MAX_FDS, ast_mutex_lock(), lock, LOG_ERROR, and ast_channel::whentohangup. Referenced by app_exec(), ast_waitfor_n(), ast_waitfordigit_full(), ast_waitstream_full(), conf_run(), find_cache(), and run_agi(). 01547 { 01548 struct timeval start = { 0 , 0 }; 01549 struct pollfd *pfds; 01550 int res; 01551 long rms; 01552 int x, y, max; 01553 int spoint; 01554 time_t now = 0; 01555 long whentohangup = 0, havewhen = 0, diff; 01556 struct ast_channel *winner = NULL; 01557 01558 pfds = alloca(sizeof(struct pollfd) * (n * AST_MAX_FDS + nfds)); 01559 if (!pfds) { 01560 ast_log(LOG_ERROR, "Out of memory\n"); 01561 *outfd = -1; 01562 return NULL; 01563 } 01564 01565 if (outfd) 01566 *outfd = -99999; 01567 if (exception) 01568 *exception = 0; 01569 01570 /* Perform any pending masquerades */ 01571 for (x=0; x < n; x++) { 01572 ast_mutex_lock(&c[x]->lock); 01573 if (c[x]->whentohangup) { 01574 if (!havewhen) 01575 time(&now); 01576 diff = c[x]->whentohangup - now; 01577 if (!havewhen || (diff < whentohangup)) { 01578 havewhen++; 01579 whentohangup = diff; 01580 } 01581 } 01582 if (c[x]->masq) { 01583 if (ast_do_masquerade(c[x])) { 01584 ast_log(LOG_WARNING, "Masquerade failed\n"); 01585 *ms = -1; 01586 ast_mutex_unlock(&c[x]->lock); 01587 return NULL; 01588 } 01589 } 01590 ast_mutex_unlock(&c[x]->lock); 01591 } 01592 01593 rms = *ms; 01594 01595 if (havewhen) { 01596 if ((*ms < 0) || (whentohangup * 1000 < *ms)) { 01597 rms = whentohangup * 1000; 01598 } 01599 } 01600 max = 0; 01601 for (x=0; x < n; x++) { 01602 for (y=0; y< AST_MAX_FDS; y++) { 01603 if (c[x]->fds[y] > -1) { 01604 pfds[max].fd = c[x]->fds[y]; 01605 pfds[max].events = POLLIN | POLLPRI; 01606 pfds[max].revents = 0; 01607 max++; 01608 } 01609 } 01610 CHECK_BLOCKING(c[x]); 01611 } 01612 for (x=0; x < nfds; x++) { 01613 if (fds[x] > -1) { 01614 pfds[max].fd = fds[x]; 01615 pfds[max].events = POLLIN | POLLPRI; 01616 pfds[max].revents = 0; 01617 max++; 01618 } 01619 } 01620 if (*ms > 0) 01621 start = ast_tvnow(); 01622 01623 if (sizeof(int) == 4) { 01624 do { 01625 int kbrms = rms; 01626 if (kbrms > 600000) 01627 kbrms = 600000; 01628 res = poll(pfds, max, kbrms); 01629 if (!res) 01630 rms -= kbrms; 01631 } while (!res && (rms > 0)); 01632 } else { 01633 res = poll(pfds, max, rms); 01634 } 01635 01636 if (res < 0) { 01637 for (x=0; x < n; x++) 01638 ast_clear_flag(c[x], AST_FLAG_BLOCKING); 01639 /* Simulate a timeout if we were interrupted */ 01640 if (errno != EINTR) 01641 *ms = -1; 01642 else { 01643 /* Just an interrupt */ 01644 #if 0 01645 *ms = 0; 01646 #endif 01647 } 01648 return NULL; 01649 } else { 01650 /* If no fds signalled, then timeout. So set ms = 0 01651 since we may not have an exact timeout. 01652 */ 01653 if (res == 0) 01654 *ms = 0; 01655 } 01656 01657 if (havewhen) 01658 time(&now); 01659 spoint = 0; 01660 for (x=0; x < n; x++) { 01661 ast_clear_flag(c[x], AST_FLAG_BLOCKING); 01662 if (havewhen && c[x]->whentohangup && (now > c[x]->whentohangup)) { 01663 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 01664 if (!winner) 01665 winner = c[x]; 01666 } 01667 for (y=0; y < AST_MAX_FDS; y++) { 01668 if (c[x]->fds[y] > -1) { 01669 if ((res = ast_fdisset(pfds, c[x]->fds[y], max, &spoint))) { 01670 if (res & POLLPRI) 01671 ast_set_flag(c[x], AST_FLAG_EXCEPTION); 01672 else 01673 ast_clear_flag(c[x], AST_FLAG_EXCEPTION); 01674 c[x]->fdno = y; 01675 winner = c[x]; 01676 } 01677 } 01678 } 01679 } 01680 for (x=0; x < nfds; x++) { 01681 if (fds[x] > -1) { 01682 if ((res = ast_fdisset(pfds, fds[x], max, &spoint))) { 01683 if (outfd) 01684 *outfd = fds[x]; 01685 if (exception) { 01686 if (res & POLLPRI) 01687 *exception = -1; 01688 else 01689 *exception = 0; 01690 } 01691 winner = NULL; 01692 } 01693 } 01694 } 01695 if (*ms > 0) { 01696 *ms -= ast_tvdiff_ms(ast_tvnow(), start); 01697 if (*ms < 0) 01698 *ms = 0; 01699 } 01700 return winner; 01701 }
|
|
Definition at line 1723 of file channel.c. References ast_check_hangup(), AST_FLAG_ZOMBIE, AST_FRAME_DTMF, ast_frfree(), ast_read(), ast_test_flag, ast_waitfor(), ast_frame::frametype, result, and ast_frame::subclass. Referenced by _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(), 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(), and wait_a_bit(). 01724 { 01725 /* XXX Should I be merged with waitfordigit_full XXX */ 01726 struct ast_frame *f; 01727 int result = 0; 01728 01729 /* Stop if we're a zombie or need a soft hangup */ 01730 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 01731 return -1; 01732 01733 /* Wait for a digit, no more than ms milliseconds total. */ 01734 while(ms && !result) { 01735 ms = ast_waitfor(c, ms); 01736 if (ms < 0) /* Error */ 01737 result = -1; 01738 else if (ms > 0) { 01739 /* Read something */ 01740 f = ast_read(c); 01741 if (f) { 01742 if (f->frametype == AST_FRAME_DTMF) 01743 result = f->subclass; 01744 ast_frfree(f); 01745 } else 01746 result = -1; 01747 } 01748 } 01749 return result; 01750 }
|
|
Definition at line 1770 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(). 01771 { 01772 struct ast_frame *f; 01773 struct ast_channel *rchan; 01774 int outfd; 01775 int res; 01776 01777 /* Stop if we're a zombie or need a soft hangup */ 01778 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 01779 return -1; 01780 /* Wait for a digit, no more than ms milliseconds total. */ 01781 while(ms) { 01782 errno = 0; 01783 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 01784 if ((!rchan) && (outfd < 0) && (ms)) { 01785 if (errno == 0 || errno == EINTR) 01786 continue; 01787 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 01788 return -1; 01789 } else if (outfd > -1) { 01790 /* The FD we were watching has something waiting */ 01791 return 1; 01792 } else if (rchan) { 01793 f = ast_read(c); 01794 if(!f) { 01795 return -1; 01796 } 01797 01798 switch(f->frametype) { 01799 case AST_FRAME_DTMF: 01800 res = f->subclass; 01801 ast_frfree(f); 01802 return res; 01803 case AST_FRAME_CONTROL: 01804 switch(f->subclass) { 01805 case AST_CONTROL_HANGUP: 01806 ast_frfree(f); 01807 return -1; 01808 case AST_CONTROL_RINGING: 01809 case AST_CONTROL_ANSWER: 01810 /* Unimportant */ 01811 break; 01812 default: 01813 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass); 01814 break; 01815 } 01816 break; 01817 case AST_FRAME_VOICE: 01818 /* Write audio if appropriate */ 01819 if (audiofd > -1) 01820 write(audiofd, f->data, f->datalen); 01821 } 01822 /* Ignore */ 01823 ast_frfree(f); 01824 } 01825 } 01826 return 0; /* Time is up */ 01827 }
|
|
Get channel by name prefix (locks channel) Definition at line 812 of file channel.c. References channel_find_locked(). 00813 { 00814 return channel_find_locked(chan, name, namelen, NULL, NULL); 00815 }
|
|
Definition at line 2240 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_SOFTHANGUP_DEV, ast_test_flag, ast_translate(), ast_writestream(), CHECK_BLOCKING, ast_frame::data, ast_frame::datalen, do_senddigit(), ast_channel::fout, ast_frame::frametype, ast_channel::generatordata, ast_channel::insmpl, ast_channel::lock, LOG_DTMF, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::name, ast_channel::outsmpl, queue_frame_to_spies(), ast_frame::samples, SEEK_FORCECUR, ast_channel_tech::send_html, ast_channel_tech::send_text, ast_channel::spies, SPY_WRITE, ast_frame::subclass, ast_channel::tech, ast_channel_tech::write, ast_channel_monitor::write_stream, ast_channel_tech::write_video, and ast_channel::writetrans. Referenced by adsi_careful_send(), agent_write(), ast_dtmf_stream(), ast_prod(), ast_readaudio_callback(), ast_readvideo_callback(), ast_write_video(), conf_run(), echo_exec(), features_write(), function_ilink(), gen_generate(), handle_link_data(), linear_generator(), misdn_bridge(), moh_files_generator(), moh_generate(), mp3_exec(), NBScat_exec(), rpt(), rpt_call(), send_link_dtmf(), send_waveform_to_channel(), silence_generator_generate(), spy_generate(), wait_for_answer(), and zt_bridge(). 02241 { 02242 int res = -1; 02243 struct ast_frame *f = NULL; 02244 /* Stop if we're a zombie or need a soft hangup */ 02245 ast_mutex_lock(&chan->lock); 02246 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 02247 ast_mutex_unlock(&chan->lock); 02248 return -1; 02249 } 02250 /* Handle any pending masquerades */ 02251 if (chan->masq) { 02252 if (ast_do_masquerade(chan)) { 02253 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 02254 ast_mutex_unlock(&chan->lock); 02255 return -1; 02256 } 02257 } 02258 if (chan->masqr) { 02259 ast_mutex_unlock(&chan->lock); 02260 return 0; 02261 } 02262 if (chan->generatordata) { 02263 if (ast_test_flag(chan, AST_FLAG_WRITE_INT)) 02264 ast_deactivate_generator(chan); 02265 else { 02266 ast_mutex_unlock(&chan->lock); 02267 return 0; 02268 } 02269 } 02270 /* High bit prints debugging */ 02271 if (chan->fout & 0x80000000) 02272 ast_frame_dump(chan->name, fr, ">>"); 02273 CHECK_BLOCKING(chan); 02274 switch(fr->frametype) { 02275 case AST_FRAME_CONTROL: 02276 /* XXX Interpret control frames XXX */ 02277 ast_log(LOG_WARNING, "Don't know how to handle control frames yet\n"); 02278 break; 02279 case AST_FRAME_DTMF: 02280 ast_clear_flag(chan, AST_FLAG_BLOCKING); 02281 ast_mutex_unlock(&chan->lock); 02282 res = do_senddigit(chan,fr->subclass); 02283 ast_mutex_lock(&chan->lock); 02284 CHECK_BLOCKING(chan); 02285 break; 02286 case AST_FRAME_TEXT: 02287 if (chan->tech->send_text) 02288 res = chan->tech->send_text(chan, (char *) fr->data); 02289 else 02290 res = 0; 02291 break; 02292 case AST_FRAME_HTML: 02293 if (chan->tech->send_html) 02294 res = chan->tech->send_html(chan, fr->subclass, (char *) fr->data, fr->datalen); 02295 else 02296 res = 0; 02297 break; 02298 case AST_FRAME_VIDEO: 02299 /* XXX Handle translation of video codecs one day XXX */ 02300 if (chan->tech->write_video) 02301 res = chan->tech->write_video(chan, fr); 02302 else 02303 res = 0; 02304 break; 02305 default: 02306 if (chan->tech->write) { 02307 f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr; 02308 if (f) { 02309 if (f->frametype == AST_FRAME_VOICE && chan->spies) 02310 queue_frame_to_spies(chan, f, SPY_WRITE); 02311 02312 if( chan->monitor && chan->monitor->write_stream && 02313 f && ( f->frametype == AST_FRAME_VOICE ) ) { 02314 #ifndef MONITOR_CONSTANT_DELAY 02315 int jump = chan->insmpl - chan->outsmpl - 4 * f->samples; 02316 if (jump >= 0) { 02317 if (ast_seekstream(chan->monitor->write_stream, jump + f->samples, SEEK_FORCECUR) == -1) 02318 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 02319 chan->outsmpl += jump + 4 * f->samples; 02320 } else 02321 chan->outsmpl += f->samples; 02322 #else 02323 int jump = chan->insmpl - chan->outsmpl; 02324 if (jump - MONITOR_DELAY >= 0) { 02325 if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1) 02326 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 02327 chan->outsmpl += jump; 02328 } else 02329 chan->outsmpl += f->samples; 02330 #endif 02331 if (ast_writestream(chan->monitor->write_stream, f) < 0) 02332 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n"); 02333 } 02334 02335 res = chan->tech->write(chan, f); 02336 } else 02337 res = 0; 02338 } 02339 } 02340 02341 /* It's possible this is a translated frame */ 02342 if (f && f->frametype == AST_FRAME_DTMF) { 02343 ast_log(LOG_DTMF, "%s : %c\n", chan->name, f->subclass); 02344 } else if (fr->frametype == AST_FRAME_DTMF) { 02345 ast_log(LOG_DTMF, "%s : %c\n", chan->name, fr->subclass); 02346 } 02347 02348 if (f && (f != fr)) 02349 ast_frfree(f); 02350 ast_clear_flag(chan, AST_FLAG_BLOCKING); 02351 /* Consider a write failure to force a soft hangup */ 02352 if (res < 0) 02353 chan->_softhangup |= AST_SOFTHANGUP_DEV; 02354 else { 02355 if ((chan->fout & 0x7fffffff) == 0x7fffffff) 02356 chan->fout &= 0x80000000; 02357 else 02358 chan->fout++; 02359 } 02360 ast_mutex_unlock(&chan->lock); 02361 return res; 02362 }
|
|
Definition at line 2229 of file channel.c. References ast_write(), ast_channel::tech, and ast_channel_tech::write_video. 02230 { 02231 int res; 02232 if (!chan->tech->write_video) 02233 return 0; 02234 res = ast_write(chan, fr); 02235 if (!res) 02236 res = 1; 02237 return res; 02238 }
|