#include <asterisk/frame.h>
#include <asterisk/sched.h>
#include <asterisk/chanvars.h>
#include <unistd.h>
#include <setjmp.h>
#include <pthread.h>
#include <asterisk/lock.h>
#include <asterisk/cdr.h>
#include <asterisk/monitor.h>
Go to the source code of this file.
Data Structures | |
struct | ast_channel |
Main Channel structure associated with a channel. More... | |
struct | ast_generator |
struct | outgoing_helper |
Defines | |
#define | AST_MAX_EXTENSION 80 |
Max length of an extension. | |
#define | AST_CHANNEL_NAME 80 |
#define | AST_CHANNEL_MAX_STACK 32 |
#define | MAX_LANGUAGE 20 |
#define | AST_MAX_FDS 8 |
#define | AST_FLAG_DIGITAL 1 |
#define | LOAD_OH(oh) |
#define | AST_CDR_TRANSFER (1 << 0) |
#define | AST_CDR_FORWARD (1 << 1) |
#define | AST_CDR_CALLWAIT (1 << 2) |
#define | AST_CDR_CONFERENCE (1 << 3) |
#define | AST_ADSI_UNKNOWN (0) |
#define | AST_ADSI_AVAILABLE (1) |
#define | AST_ADSI_UNAVAILABLE (2) |
#define | AST_ADSI_OFFHOOKONLY (3) |
#define | AST_SOFTHANGUP_DEV (1 << 0) |
#define | AST_SOFTHANGUP_ASYNCGOTO (1 << 1) |
#define | AST_SOFTHANGUP_SHUTDOWN (1 << 2) |
#define | AST_SOFTHANGUP_TIMEOUT (1 << 3) |
#define | AST_SOFTHANGUP_APPUNLOAD (1 << 4) |
#define | AST_SOFTHANGUP_EXPLICIT (1 << 5) |
#define | AST_STATE_DOWN 0 |
#define | AST_STATE_RESERVED 1 |
#define | AST_STATE_OFFHOOK 2 |
#define | AST_STATE_DIALING 3 |
#define | AST_STATE_RING 4 |
#define | AST_STATE_RINGING 5 |
#define | AST_STATE_UP 6 |
#define | AST_STATE_BUSY 7 |
#define | AST_STATE_DIALING_OFFHOOK 8 |
#define | AST_STATE_MUTE (1 << 16) |
#define | AST_DEVICE_UNKNOWN 0 |
#define | AST_DEVICE_NOT_INUSE 1 |
#define | AST_DEVICE_INUSE 2 |
#define | AST_DEVICE_BUSY 3 |
#define | AST_DEVICE_INVALID 4 |
#define | AST_DEVICE_UNAVAILABLE 5 |
#define | AST_BRIDGE_DTMF_CHANNEL_0 (1 << 0) |
#define | AST_BRIDGE_DTMF_CHANNEL_1 (1 << 1) |
#define | AST_BRIDGE_REC_CHANNEL_0 (1 << 2) |
#define | AST_BRIDGE_REC_CHANNEL_1 (1 << 3) |
#define | AST_BRIDGE_IGNORE_SIGS (1 << 4) |
#define | CRASH do { } while(0) |
#define | CHECK_BLOCKING(c) |
Functions | |
ast_channel * | ast_request (char *type, int format, void *data) |
Requests a channel. | |
int | ast_parse_device_state (char *device) |
Search the Channels by Name. | |
int | ast_device_state (char *device) |
Asks a channel for device state. | |
ast_channel * | ast_request_and_dial (char *type, int format, void *data, int timeout, int *reason, char *callerid) |
ast_channel * | __ast_request_and_dial (char *type, int format, void *data, int timeout, int *reason, char *callerid, struct outgoing_helper *oh) |
int | ast_channel_register (char *type, char *description, int capabilities, struct ast_channel *(*requester)(char *type, int format, void *data)) |
Registers a channel. | |
int | ast_channel_register_ex (char *type, char *description, int capabilities, struct ast_channel *(*requester)(char *type, int format, void *data), int(*devicestate)(void *data)) |
void | ast_channel_unregister (char *type) |
Unregister a channel class. | |
int | ast_hangup (struct ast_channel *chan) |
Hang up a channel. | |
int | ast_softhangup (struct ast_channel *chan, int cause) |
Softly hangup up a channel. | |
int | ast_softhangup_nolock (struct ast_channel *chan, int cause) |
int | ast_check_hangup (struct ast_channel *chan) |
Check to see if a channel is needing hang up. | |
void | ast_channel_setwhentohangup (struct ast_channel *chan, time_t offset) |
Set when to hang a channel up. | |
int | ast_answer (struct ast_channel *chan) |
Answer a ringing call. | |
int | ast_call (struct ast_channel *chan, char *addr, int timeout) |
Make a call. | |
int | ast_indicate (struct ast_channel *chan, int condition) |
Indicates condition of channel. | |
int | ast_waitfor (struct ast_channel *chan, int ms) |
Wait for input on a channel. | |
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. | |
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. | |
ast_channel * | ast_waitfor_n (struct ast_channel **chan, int n, int *ms) |
Waits for input on a group of channels. | |
int | ast_waitfor_n_fd (int *fds, int n, int *ms, int *exception) |
Waits for input on an fd. | |
ast_frame * | ast_read (struct ast_channel *chan) |
Reads a frame. | |
int | ast_write (struct ast_channel *chan, struct ast_frame *frame) |
Write a frame to a channel. | |
int | ast_write_video (struct ast_channel *chan, struct ast_frame *frame) |
Write video frame to a channel. | |
int | ast_prod (struct ast_channel *chan) |
int | ast_set_read_format (struct ast_channel *chan, int format) |
Sets read format on channel chan. | |
int | ast_set_write_format (struct ast_channel *chan, int format) |
Sets write format on channel chan. | |
int | ast_sendtext (struct ast_channel *chan, char *text) |
Sends text to a channel. | |
int | ast_recvchar (struct ast_channel *chan, int timeout) |
Receives a text character from a channel. | |
ast_channel * | ast_channel_walk (struct ast_channel *prev) |
Browse channels in use. | |
char | ast_waitfordigit (struct ast_channel *c, int ms) |
Waits for a digit. | |
char | ast_waitfordigit_full (struct ast_channel *c, int ms, int audiofd, int ctrlfd) |
int | ast_readstring (struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders) |
Reads multiple digits. | |
int | ast_readstring_full (struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders, int audiofd, int ctrlfd) |
int | ast_channel_make_compatible (struct ast_channel *c0, struct ast_channel *c1) |
Makes two channel formats compatible. | |
int | ast_channel_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc) |
Bridge two channels together. | |
int | ast_channel_masquerade (struct ast_channel *original, struct ast_channel *clone) |
Weird function made for call transfers. | |
char * | ast_state2str (int state) |
Gives the string form of a given state. | |
int | ast_channel_setoption (struct ast_channel *channel, int option, void *data, int datalen, int block) |
Sets an option on a channel. | |
ast_frame * | ast_channel_queryoption (struct ast_channel *channel, int option, void *data, int *datalen, int block) |
Checks the value of an option. | |
int | ast_channel_supports_html (struct ast_channel *channel) |
Checks for HTML support on a channel. | |
int | ast_channel_sendhtml (struct ast_channel *channel, int subclass, char *data, int datalen) |
Sends HTML on given channel. | |
int | ast_channel_sendurl (struct ast_channel *channel, char *url) |
Sends a URL on a given link. | |
int | ast_channel_defer_dtmf (struct ast_channel *chan) |
Defers DTMF. | |
void | ast_channel_undefer_dtmf (struct ast_channel *chan) |
Undeos a defer. | |
void | ast_begin_shutdown (int hangup) |
void | ast_cancel_shutdown (void) |
int | ast_active_channels (void) |
int | ast_shutting_down (void) |
int | ast_activate_generator (struct ast_channel *chan, struct ast_generator *gen, void *params) |
void | ast_deactivate_generator (struct ast_channel *chan) |
void | ast_set_callerid (struct ast_channel *chan, char *callerid, int anitoo) |
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_tonepair (struct ast_channel *chan, int freq1, int freq2, int duration, int vol) |
int | ast_autoservice_start (struct ast_channel *chan) |
int | ast_autoservice_stop (struct ast_channel *chan) |
int | ast_settimeout (struct ast_channel *c, int samples, int(*func)(void *data), void *data) |
int | ast_transfer (struct ast_channel *chan, char *dest) |
|
|
|
|
|
|
|
|
|
Report DTMF on channel 0 Definition at line 640 of file channel.h. Referenced by ast_channel_bridge(), and ast_rtp_bridge(). |
|
Report DTMF on channel 1 Definition at line 642 of file channel.h. Referenced by ast_channel_bridge(), and ast_rtp_bridge(). |
|
Ignore all signal frames except NULL Definition at line 648 of file channel.h. Referenced by ast_channel_bridge(). |
|
Return all voice frames on channel 0 |
|
Return all voice frames on channel 1 |
|
|
|
|
|
|
|
|
|
Definition at line 38 of file channel.h. Referenced by pbx_exec(). |
|
Definition at line 37 of file channel.h. Referenced by ast_channel_free(), and ast_parse_device_state(). |
|
Device is busy |
|
Device is in use Definition at line 335 of file channel.h. Referenced by ast_parse_device_state(). |
|
Device is invalid Definition at line 339 of file channel.h. Referenced by ast_device_state(). |
|
Device is not used |
|
Device is unavailable |
|
Device is valid but channel didn't know state Definition at line 331 of file channel.h. Referenced by ast_device_state(), and ast_parse_device_state(). |
|
|
|
Max length of an extension.
Definition at line 31 of file channel.h. Referenced by ast_cdr_init(), ast_cdr_setcid(), ast_cdr_update(), ast_device_state(), and ast_device_state_changed(). |
|
Definition at line 43 of file channel.h. Referenced by ast_channel_alloc(), ast_read(), and ast_waitfor_nandfds(). |
|
|
|
Definition at line 300 of file channel.h. Referenced by ast_pbx_run(). |
|
Definition at line 299 of file channel.h. Referenced by ast_dsp_process(), ast_queue_hangup(), ast_read(), and ast_write(). |
|
|
|
Definition at line 301 of file channel.h. Referenced by ast_begin_shutdown(). |
|
Definition at line 302 of file channel.h. Referenced by ast_check_hangup(), and ast_pbx_run(). |
|
Line is busy Definition at line 322 of file channel.h. Referenced by ast_state2str(). |
|
Digits (or equivalent) have been dialed Definition at line 314 of file channel.h. Referenced by ast_state2str(). |
|
Digits (or equivalent) have been dialed while offhook |
|
Channel is down and available Definition at line 308 of file channel.h. Referenced by ast_channel_alloc(), ast_request(), ast_setstate(), and ast_state2str(). |
|
Do not transmit voice data |
|
Channel is off hook Definition at line 312 of file channel.h. Referenced by ast_state2str(). |
|
Channel is down, but reserved Definition at line 310 of file channel.h. Referenced by ast_state2str(). |
|
Line is ringing Definition at line 316 of file channel.h. Referenced by ast_answer(), and ast_state2str(). |
|
Remote end is ringing Definition at line 318 of file channel.h. Referenced by ast_answer(), and ast_state2str(). |
|
Line is up Definition at line 320 of file channel.h. Referenced by __ast_request_and_dial(), ast_answer(), ast_cdr_init(), ast_prod(), ast_read(), and ast_state2str(). |
|
Definition at line 836 of file channel.h. Referenced by ast_sendtext(), ast_waitfor_nandfds(), and ast_write(). |
|
Definition at line 833 of file channel.h. Referenced by ast_hangup(), ast_queue_frame(), ast_rtcp_read(), ast_rtp_read(), and ast_sched_del(). |
|
|
|
Definition at line 40 of file channel.h. Referenced by ast_fileexists(), and ast_openvstream(). |
|
Definition at line 1501 of file channel.c. References ast_channel::_state, outgoing_helper::account, ast_call(), 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_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, AST_FRAME_CONTROL, ast_frfree(), ast_hangup(), ast_log(), ast_read(), ast_request(), ast_set_callerid(), AST_STATE_UP, ast_waitfor(), outgoing_helper::callerid, ast_channel::cdr, ast_channel::context, outgoing_helper::context, ast_channel::exten, outgoing_helper::exten, ast_channel::hangupcause, LOG_NOTICE, LOG_WARNING, pbx_builtin_setvar(), outgoing_helper::priority, ast_channel::priority, type, and outgoing_helper::variable. Referenced by ast_request_and_dial().
01502 { 01503 int state = 0; 01504 struct ast_channel *chan; 01505 struct ast_frame *f; 01506 int res = 0; 01507 chan = ast_request(type, format, data); 01508 if (chan) { 01509 if (oh) { 01510 char *tmp, *var; 01511 /* JDG chanvar */ 01512 tmp = oh->variable; 01513 /* FIXME replace this call with strsep NOT*/ 01514 while( (var = strtok_r(NULL, "|", &tmp)) ) { 01515 pbx_builtin_setvar( chan, var ); 01516 } /* /JDG */ 01517 if (oh->callerid && *oh->callerid) 01518 ast_set_callerid(chan, oh->callerid, 1); 01519 if (oh->account && *oh->account) 01520 ast_cdr_setaccount(chan, oh->account); 01521 } 01522 if (callerid && strlen(callerid)) 01523 ast_set_callerid(chan, callerid, 1); 01524 01525 if (!ast_call(chan, data, 0)) { 01526 while(timeout && (chan->_state != AST_STATE_UP)) { 01527 res = ast_waitfor(chan, timeout); 01528 if (res < 0) { 01529 /* Something not cool, or timed out */ 01530 break; 01531 } 01532 /* If done, break out */ 01533 if (!res) 01534 break; 01535 if (timeout > -1) 01536 timeout = res; 01537 f = ast_read(chan); 01538 if (!f) { 01539 state = AST_CONTROL_HANGUP; 01540 res = 0; 01541 break; 01542 } 01543 if (f->frametype == AST_FRAME_CONTROL) { 01544 if (f->subclass == AST_CONTROL_RINGING) 01545 state = AST_CONTROL_RINGING; 01546 else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) { 01547 state = f->subclass; 01548 ast_frfree(f); 01549 break; 01550 } else if (f->subclass == AST_CONTROL_ANSWER) { 01551 state = f->subclass; 01552 ast_frfree(f); 01553 break; 01554 } else { 01555 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass); 01556 } 01557 } 01558 ast_frfree(f); 01559 } 01560 } else 01561 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data); 01562 } else 01563 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data); 01564 if (chan) { 01565 /* Final fixups */ 01566 if (oh) { 01567 if (oh->context && *oh->context) 01568 strncpy(chan->context, oh->context, sizeof(chan->context) - 1); 01569 if (oh->exten && *oh->exten) 01570 strncpy(chan->exten, oh->exten, sizeof(chan->exten) - 1); 01571 chan->priority = oh->priority; 01572 } 01573 if (chan->_state == AST_STATE_UP) 01574 state = AST_CONTROL_ANSWER; 01575 } 01576 if (outstate) 01577 *outstate = state; 01578 if (chan && res <= 0) { 01579 if (!chan->cdr) { 01580 chan->cdr = ast_cdr_alloc(); 01581 if (chan->cdr) 01582 ast_cdr_init(chan->cdr, chan); 01583 } 01584 if (chan->cdr) { 01585 char tmp[256]; 01586 sprintf(tmp, "%s/%s",type,(char *)data); 01587 ast_cdr_setapp(chan->cdr,"Dial",tmp); 01588 ast_cdr_update(chan); 01589 ast_cdr_start(chan->cdr); 01590 ast_cdr_end(chan->cdr); 01591 /* If the cause wasn't handled properly */ 01592 if (ast_cdr_disposition(chan->cdr,chan->hangupcause)) 01593 ast_cdr_failed(chan->cdr); 01594 } else 01595 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 01596 ast_hangup(chan); 01597 chan = NULL; 01598 } 01599 return chan; 01600 } |
|
Activate a given generator Definition at line 743 of file channel.c. References ast_generator::alloc, ast_prod(), ast_channel::generator, ast_channel::generatordata, and ast_generator::release. Referenced by ast_playtones_start(), and ast_tonepair_start().
00744 { 00745 if (chan->generatordata) { 00746 chan->generator->release(chan, chan->generatordata); 00747 chan->generatordata = NULL; 00748 } 00749 ast_prod(chan); 00750 if ((chan->generatordata = gen->alloc(chan, params))) { 00751 chan->generator = gen; 00752 } else { 00753 return -1; 00754 } 00755 return 0; 00756 } |
|
Returns number of active/allocated channels Definition at line 110 of file channel.c. References ast_mutex_lock, ast_mutex_unlock, channels, and ast_channel::next.
00111 { 00112 struct ast_channel *c; 00113 int cnt = 0; 00114 ast_mutex_lock(&chlock); 00115 c = channels; 00116 while(c) { 00117 cnt++; 00118 c = c->next; 00119 } 00120 ast_mutex_unlock(&chlock); 00121 return cnt; 00122 } |
|
Answer a ringing call.
Definition at line 707 of file channel.c. References ast_channel::_state, ast_channel_pvt::answer, ast_cdr_answer(), ast_check_hangup(), ast_mutex_lock, ast_mutex_unlock, ast_setstate(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_channel::cdr, ast_channel::lock, ast_channel::pvt, and ast_channel::zombie.
00708 { 00709 int res = 0; 00710 /* Stop if we're a zombie or need a soft hangup */ 00711 if (chan->zombie || ast_check_hangup(chan)) 00712 return -1; 00713 switch(chan->_state) { 00714 case AST_STATE_RINGING: 00715 case AST_STATE_RING: 00716 ast_mutex_lock(&chan->lock); 00717 if (chan->pvt->answer) 00718 res = chan->pvt->answer(chan); 00719 ast_mutex_unlock(&chan->lock); 00720 ast_setstate(chan, AST_STATE_UP); 00721 if (chan->cdr) 00722 ast_cdr_answer(chan->cdr); 00723 return res; 00724 break; 00725 case AST_STATE_UP: 00726 if (chan->cdr) 00727 ast_cdr_answer(chan->cdr); 00728 break; 00729 } 00730 return 0; 00731 } |
|
Automatically service a channel for us... Definition at line 87 of file autoservice.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, free, LOG_WARNING, malloc, ast_channel::next, and asent::next. Referenced by ast_get_enum(), ast_get_srv(), and ast_rtp_bridge().
00088 { 00089 int res = -1; 00090 struct asent *as; 00091 int needstart; 00092 ast_mutex_lock(&autolock); 00093 needstart = (asthread == (pthread_t) -1) ? 1 : 0 /* aslist ? 0 : 1 */; 00094 as = aslist; 00095 while(as) { 00096 if (as->chan == chan) 00097 break; 00098 as = as->next; 00099 } 00100 if (!as) { 00101 as = malloc(sizeof(struct asent)); 00102 if (as) { 00103 memset(as, 0, sizeof(struct asent)); 00104 as->chan = chan; 00105 as->next = aslist; 00106 aslist = as; 00107 res = 0; 00108 if (needstart) { 00109 if (pthread_create(&asthread, NULL, autoservice_run, NULL)) { 00110 ast_log(LOG_WARNING, "Unable to create autoservice thread :(\n"); 00111 free(aslist); 00112 aslist = NULL; 00113 res = -1; 00114 } else 00115 pthread_kill(asthread, SIGURG); 00116 } 00117 } 00118 } 00119 ast_mutex_unlock(&autolock); 00120 return res; 00121 } |
|
Stop servicing a channel for us... Returns -1 on error or if channel has been hungup Definition at line 123 of file autoservice.c. References ast_channel::_softhangup, ast_mutex_lock, ast_mutex_unlock, ast_channel::blocking, free, and asent::next. Referenced by ast_get_enum(), ast_get_srv(), and ast_rtp_bridge().
00124 { 00125 int res = -1; 00126 struct asent *as, *prev; 00127 ast_mutex_lock(&autolock); 00128 as = aslist; 00129 prev = NULL; 00130 while(as) { 00131 if (as->chan == chan) 00132 break; 00133 prev = as; 00134 as = as->next; 00135 } 00136 if (as) { 00137 if (prev) 00138 prev->next = as->next; 00139 else 00140 aslist = as->next; 00141 free(as); 00142 if (!chan->_softhangup) 00143 res = 0; 00144 } 00145 if (asthread != (pthread_t) -1) 00146 pthread_kill(asthread, SIGURG); 00147 ast_mutex_unlock(&autolock); 00148 /* Wait for it to un-block */ 00149 while(chan->blocking) 00150 usleep(1000); 00151 return res; 00152 } |
|
Initiate system shutdown -- prevents new channels from being allocated. If "hangup" is non-zero, all existing channels will receive soft hangups Definition at line 95 of file channel.c. References ast_mutex_lock, ast_mutex_unlock, ast_softhangup(), AST_SOFTHANGUP_SHUTDOWN, and channels.
00096 { 00097 struct ast_channel *c; 00098 shutting_down = 1; 00099 if (hangup) { 00100 ast_mutex_lock(&chlock); 00101 c = channels; 00102 while(c) { 00103 ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN); 00104 c = c->next; 00105 } 00106 ast_mutex_unlock(&chlock); 00107 } 00108 } |
|
Make a call.
Definition at line 1710 of file channel.c. References ast_check_hangup(), ast_mutex_lock, ast_mutex_unlock, ast_channel_pvt::call, ast_channel::lock, ast_channel::pvt, and ast_channel::zombie. Referenced by __ast_request_and_dial().
01711 { 01712 /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 01713 If the remote end does not answer within the timeout, then do NOT hang up, but 01714 return anyway. */ 01715 int res = -1; 01716 /* Stop if we're a zombie or need a soft hangup */ 01717 ast_mutex_lock(&chan->lock); 01718 if (!chan->zombie && !ast_check_hangup(chan)) 01719 if (chan->pvt->call) 01720 res = chan->pvt->call(chan, addr, timeout); 01721 ast_mutex_unlock(&chan->lock); 01722 return res; 01723 } |
|
Cancels an existing shutdown and returns to normal operation Definition at line 124 of file channel.c.
00125 { 00126 shutting_down = 0; 00127 } |
|
Bridge two channels together.
Definition at line 2182 of file channel.c. References AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_IGNORE_SIGS, ast_channel_make_compatible(), ast_check_hangup(), AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_IMAGE, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree(), ast_log(), ast_read(), ast_verbose(), ast_waitfor_n(), ast_write(), ast_channel::bridge, EVENT_FLAG_CALL, LOG_DEBUG, LOG_WARNING, manager_event(), ast_channel::name, option_verbose, VERBOSE_PREFIX_3, and ast_channel::zombie.
02183 { 02184 /* Copy voice back and forth between the two channels. Give the peer 02185 the ability to transfer calls with '#<extension' syntax. */ 02186 struct ast_channel *cs[3]; 02187 int to = -1; 02188 struct ast_frame *f; 02189 struct ast_channel *who = NULL; 02190 int res; 02191 int nativefailed=0; 02192 02193 /* Stop if we're a zombie or need a soft hangup */ 02194 if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1)) 02195 return -1; 02196 if (c0->bridge) { 02197 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 02198 c0->name, c0->bridge->name); 02199 return -1; 02200 } 02201 if (c1->bridge) { 02202 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 02203 c1->name, c1->bridge->name); 02204 return -1; 02205 } 02206 02207 /* Keep track of bridge */ 02208 c0->bridge = c1; 02209 c1->bridge = c0; 02210 cs[0] = c0; 02211 cs[1] = c1; 02212 02213 manager_event(EVENT_FLAG_CALL, "Link", 02214 "Channel1: %s\r\n" 02215 "Channel2: %s\r\n", 02216 c0->name, c1->name); 02217 02218 for (/* ever */;;) { 02219 /* Stop if we're a zombie or need a soft hangup */ 02220 if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1)) { 02221 *fo = NULL; 02222 if (who) *rc = who; 02223 res = 0; 02224 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",c0->name,c1->name,c0->zombie?"Yes":"No",ast_check_hangup(c0)?"Yes":"No",c1->zombie?"Yes":"No",ast_check_hangup(c1)?"Yes":"No"); 02225 break; 02226 } 02227 if (c0->pvt->bridge && 02228 (c0->pvt->bridge == c1->pvt->bridge) && !nativefailed && !c0->monitor && !c1->monitor) { 02229 /* Looks like they share a bridge code */ 02230 if (option_verbose > 2) 02231 ast_verbose(VERBOSE_PREFIX_3 "Attempting native bridge of %s and %s\n", c0->name, c1->name); 02232 if (!(res = c0->pvt->bridge(c0, c1, flags, fo, rc))) { 02233 c0->bridge = NULL; 02234 c1->bridge = NULL; 02235 manager_event(EVENT_FLAG_CALL, "Unlink", 02236 "Channel1: %s\r\n" 02237 "Channel2: %s\r\n", 02238 c0->name, c1->name); 02239 ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n",c0->name ,c1->name); 02240 return 0; 02241 } 02242 /* If they return non-zero then continue on normally. Let "-2" mean don't worry about 02243 my not wanting to bridge */ 02244 if ((res != -2) && (res != -3)) 02245 ast_log(LOG_WARNING, "Private bridge between %s and %s failed\n", c0->name, c1->name); 02246 if (res != -3) nativefailed++; 02247 } 02248 02249 02250 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat)) && 02251 !(c0->generator || c1->generator)) { 02252 if (ast_channel_make_compatible(c0, c1)) { 02253 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name); 02254 manager_event(EVENT_FLAG_CALL, "Unlink", 02255 "Channel1: %s\r\n" 02256 "Channel2: %s\r\n", 02257 c0->name, c1->name); 02258 return -1; 02259 } 02260 } 02261 who = ast_waitfor_n(cs, 2, &to); 02262 if (!who) { 02263 ast_log(LOG_DEBUG, "Nobody there, continuing...\n"); 02264 continue; 02265 } 02266 f = ast_read(who); 02267 if (!f) { 02268 *fo = NULL; 02269 *rc = who; 02270 res = 0; 02271 ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name); 02272 break; 02273 } 02274 02275 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) { 02276 *fo = f; 02277 *rc = who; 02278 res = 0; 02279 ast_log(LOG_DEBUG, "Got a FRAME_CONTROL frame on channel %s\n",who->name); 02280 break; 02281 } 02282 if ((f->frametype == AST_FRAME_VOICE) || 02283 (f->frametype == AST_FRAME_TEXT) || 02284 (f->frametype == AST_FRAME_VIDEO) || 02285 (f->frametype == AST_FRAME_IMAGE) || 02286 (f->frametype == AST_FRAME_DTMF)) { 02287 if ((f->frametype == AST_FRAME_DTMF) && 02288 (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) { 02289 if ((who == c0)) { 02290 if ((flags & AST_BRIDGE_DTMF_CHANNEL_0)) { 02291 *rc = c0; 02292 *fo = f; 02293 /* Take out of conference mode */ 02294 res = 0; 02295 ast_log(LOG_DEBUG, "Got AST_BRIDGE_DTMF_CHANNEL_0 on c0 (%s)\n",c0->name); 02296 break; 02297 } else 02298 goto tackygoto; 02299 } else 02300 if ((who == c1)) { 02301 if (flags & AST_BRIDGE_DTMF_CHANNEL_1) { 02302 *rc = c1; 02303 *fo = f; 02304 res = 0; 02305 ast_log(LOG_DEBUG, "Got AST_BRIDGE_DTMF_CHANNEL_1 on c1 (%s)\n",c1->name); 02306 break; 02307 } else 02308 goto tackygoto; 02309 } 02310 } else { 02311 #if 0 02312 ast_log(LOG_DEBUG, "Read from %s\n", who->name); 02313 if (who == last) 02314 ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name); 02315 last = who; 02316 #endif 02317 tackygoto: 02318 /* Don't copy packets if there is a generator on either one, since they're 02319 not supposed to be listening anyway */ 02320 if (who == c0) 02321 ast_write(c1, f); 02322 else 02323 ast_write(c0, f); 02324 } 02325 ast_frfree(f); 02326 } else 02327 ast_frfree(f); 02328 /* Swap who gets priority */ 02329 cs[2] = cs[0]; 02330 cs[0] = cs[1]; 02331 cs[1] = cs[2]; 02332 } 02333 c0->bridge = NULL; 02334 c1->bridge = NULL; 02335 manager_event(EVENT_FLAG_CALL, "Unlink", 02336 "Channel1: %s\r\n" 02337 "Channel2: %s\r\n", 02338 c0->name, c1->name); 02339 ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n",c0->name,c1->name); 02340 return res; 02341 } |
|
Defers DTMF. Defer DTMF so that you only read things like hangups and audio. Returns non-zero if channel was already DTMF-deferred or 0 if channel is just now being DTMF-deferred Definition at line 417 of file channel.c. References ast_channel::deferdtmf.
|
|
Makes two channel formats compatible.
Definition at line 1847 of file channel.c. References ast_log(), ast_set_read_format(), ast_set_write_format(), ast_translator_best_choice(), LOG_WARNING, ast_channel::name, and ast_channel::nativeformats. Referenced by ast_channel_bridge().
01848 { 01849 int peerf; 01850 int chanf; 01851 int res; 01852 peerf = peer->nativeformats; 01853 chanf = chan->nativeformats; 01854 res = ast_translator_best_choice(&peerf, &chanf); 01855 if (res < 0) { 01856 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, chan->nativeformats, peer->name, peer->nativeformats); 01857 return -1; 01858 } 01859 /* Set read format on channel */ 01860 res = ast_set_read_format(chan, peerf); 01861 if (res < 0) { 01862 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, chanf); 01863 return -1; 01864 } 01865 /* Set write format on peer channel */ 01866 res = ast_set_write_format(peer, peerf); 01867 if (res < 0) { 01868 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, peerf); 01869 return -1; 01870 } 01871 /* Now we go the other way */ 01872 peerf = peer->nativeformats; 01873 chanf = chan->nativeformats; 01874 res = ast_translator_best_choice(&chanf, &peerf); 01875 if (res < 0) { 01876 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, peer->nativeformats, chan->name, chan->nativeformats); 01877 return -1; 01878 } 01879 /* Set writeformat on channel */ 01880 res = ast_set_write_format(chan, chanf); 01881 if (res < 0) { 01882 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, chanf); 01883 return -1; 01884 } 01885 /* Set read format on peer channel */ 01886 res = ast_set_read_format(peer, chanf); 01887 if (res < 0) { 01888 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, peerf); 01889 return -1; 01890 } 01891 return 0; 01892 } |
|
Weird function made for call transfers.
Definition at line 1894 of file channel.c. References AST_FRAME_NULL, ast_log(), ast_queue_frame(), LOG_DEBUG, LOG_WARNING, ast_channel::masq, ast_channel::masqr, and ast_channel::name.
01895 { 01896 struct ast_frame null = { AST_FRAME_NULL, }; 01897 ast_log(LOG_DEBUG, "Planning to masquerade %s into the structure of %s\n", 01898 clone->name, original->name); 01899 if (original->masq) { 01900 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 01901 original->masq->name, original->name); 01902 return -1; 01903 } 01904 if (clone->masqr) { 01905 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 01906 clone->name, clone->masqr->name); 01907 return -1; 01908 } 01909 original->masq = clone; 01910 clone->masqr = original; 01911 /* XXX can't really hold the lock here, but at the same time, it' s 01912 not really safe not to XXX */ 01913 ast_queue_frame(original, &null, 0); 01914 ast_queue_frame(clone, &null, 0); 01915 ast_log(LOG_DEBUG, "Done planning to masquerade %s into the structure of %s\n", original->name, clone->name); 01916 return 0; 01917 } |
|
Checks the value of an option. Query the value of an option, optionally blocking until a reply is received Works similarly to setoption except only reads the options. |
|
Registers a channel.
Definition at line 146 of file channel.c. References ast_channel_register_ex(), description(), and type.
00148 { 00149 return ast_channel_register_ex(type, description, capabilities, requester, NULL); 00150 } |
|
Definition at line 152 of file channel.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_verbose(), backends, description(), LOG_DEBUG, LOG_WARNING, malloc, option_debug, option_verbose, type, and VERBOSE_PREFIX_2. Referenced by ast_channel_register().
00155 { 00156 struct chanlist *chan, *last=NULL; 00157 if (ast_mutex_lock(&chlock)) { 00158 ast_log(LOG_WARNING, "Unable to lock channel list\n"); 00159 return -1; 00160 } 00161 chan = backends; 00162 while(chan) { 00163 if (!strcasecmp(type, chan->type)) { 00164 ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", type); 00165 ast_mutex_unlock(&chlock); 00166 return -1; 00167 } 00168 last = chan; 00169 chan = chan->next; 00170 } 00171 chan = malloc(sizeof(struct chanlist)); 00172 if (!chan) { 00173 ast_log(LOG_WARNING, "Out of memory\n"); 00174 ast_mutex_unlock(&chlock); 00175 return -1; 00176 } 00177 strncpy(chan->type, type, sizeof(chan->type)-1); 00178 strncpy(chan->description, description, sizeof(chan->description)-1); 00179 chan->capabilities = capabilities; 00180 chan->requester = requester; 00181 chan->devicestate = devicestate; 00182 chan->next = NULL; 00183 if (last) 00184 last->next = chan; 00185 else 00186 backends = chan; 00187 if (option_debug) 00188 ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->type, chan->description); 00189 else if (option_verbose > 1) 00190 ast_verbose( VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->type, chan->description); 00191 ast_mutex_unlock(&chlock); 00192 return 0; 00193 } |
|
Sends HTML on given channel. Send HTML or URL on link. Returns 0 on success or -1 on failure Definition at line 1833 of file channel.c. References ast_channel::pvt, and ast_channel_pvt::send_html.
01834 { 01835 if (chan->pvt->send_html) 01836 return chan->pvt->send_html(chan, subclass, data, datalen); 01837 return -1; 01838 } |
|
Sends a URL on a given link. Send URL on link. Returns 0 on success or -1 on failure Definition at line 1840 of file channel.c. References AST_HTML_URL, ast_channel::pvt, and ast_channel_pvt::send_html.
01841 { 01842 if (chan->pvt->send_html) 01843 return chan->pvt->send_html(chan, AST_HTML_URL, url, strlen(url) + 1); 01844 return -1; 01845 } |
|
Sets an option on a channel.
Definition at line 2343 of file channel.c. References ast_log(), LOG_ERROR, ast_channel::pvt, and ast_channel_pvt::setoption.
02344 { 02345 int res; 02346 if (chan->pvt->setoption) { 02347 res = chan->pvt->setoption(chan, option, data, datalen); 02348 if (res < 0) 02349 return res; 02350 } else { 02351 errno = ENOSYS; 02352 return -1; 02353 } 02354 if (block) { 02355 /* XXX Implement blocking -- just wait for our option frame reply, discarding 02356 intermediate packets. XXX */ 02357 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 02358 return -1; 02359 } 02360 return 0; 02361 } |
|
Set when to hang a channel up.
Definition at line 134 of file channel.c. References ast_channel::whentohangup.
00135 { 00136 time_t myt; 00137 00138 time(&myt); 00139 if (offset) 00140 chan->whentohangup = myt + offset; 00141 else 00142 chan->whentohangup = 0; 00143 return; 00144 } |
|
Checks for HTML support on a channel. Returns 0 if channel does not support HTML or non-zero if it does Definition at line 1826 of file channel.c. References ast_channel::pvt, and ast_channel_pvt::send_html.
01827 { 01828 if (chan->pvt->send_html) 01829 return 1; 01830 return 0; 01831 } |
|
Undeos a defer. Undo defer. ast_read will return any dtmf characters that were queued Definition at line 427 of file channel.c. References ast_channel::deferdtmf.
00428 { 00429 if (chan) 00430 chan->deferdtmf = 0; 00431 } |
|
Unregister a channel class.
Definition at line 678 of file channel.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_verbose(), backends, free, LOG_DEBUG, LOG_WARNING, ast_channel::next, chanlist::next, option_debug, option_verbose, ast_channel::type, type, and VERBOSE_PREFIX_2.
00679 { 00680 struct chanlist *chan, *last=NULL; 00681 if (option_debug) 00682 ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", type); 00683 if (ast_mutex_lock(&chlock)) { 00684 ast_log(LOG_WARNING, "Unable to lock channel list\n"); 00685 return; 00686 } 00687 if (option_verbose > 1) 00688 ast_verbose( VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", type); 00689 00690 chan = backends; 00691 while(chan) { 00692 if (!strcasecmp(chan->type, type)) { 00693 if (last) 00694 last->next = chan->next; 00695 else 00696 backends = backends->next; 00697 free(chan); 00698 ast_mutex_unlock(&chlock); 00699 return; 00700 } 00701 last = chan; 00702 chan = chan->next; 00703 } 00704 ast_mutex_unlock(&chlock); 00705 } |
|
Browse channels in use.
Definition at line 433 of file channel.c. References ast_mutex_lock, ast_mutex_unlock, and channels. Referenced by ast_parse_device_state().
00434 { 00435 struct ast_channel *l, *ret=NULL; 00436 ast_mutex_lock(&chlock); 00437 l = channels; 00438 if (!prev) { 00439 ast_mutex_unlock(&chlock); 00440 return l; 00441 } 00442 while(l) { 00443 if (l == prev) 00444 ret = l->next; 00445 l = l->next; 00446 } 00447 ast_mutex_unlock(&chlock); 00448 return ret; 00449 00450 } |
|
Check to see if a channel is needing hang up.
Definition at line 69 of file channel.c. References ast_channel::_softhangup, AST_SOFTHANGUP_TIMEOUT, ast_channel_pvt::pvt, ast_channel::pvt, and ast_channel::whentohangup. Referenced by ast_answer(), ast_call(), ast_channel_bridge(), ast_indicate(), ast_read(), ast_readstring(), ast_readstring_full(), ast_recvchar(), ast_rtp_bridge(), ast_sendtext(), ast_transfer(), ast_waitfordigit(), ast_waitfordigit_full(), and ast_write().
00070 { 00071 time_t myt; 00072 00073 /* if soft hangup flag, return true */ 00074 if (chan->_softhangup) return 1; 00075 /* if no private structure, return true */ 00076 if (!chan->pvt->pvt) return 1; 00077 /* if no hangup scheduled, just return here */ 00078 if (!chan->whentohangup) return 0; 00079 time(&myt); /* get current time */ 00080 /* return, if not yet */ 00081 if (chan->whentohangup > myt) return 0; 00082 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 00083 return 1; 00084 } |
|
Deactive an active generator Definition at line 733 of file channel.c. References ast_channel::generator, ast_channel::generatordata, ast_generator::release, and ast_channel::writeinterrupt. Referenced by ast_openstream(), ast_playtones_stop(), ast_read(), ast_tonepair_stop(), and ast_write().
00734 { 00735 if (chan->generatordata) { 00736 chan->generator->release(chan, chan->generatordata); 00737 chan->generatordata = NULL; 00738 chan->generator = NULL; 00739 chan->writeinterrupt = 0; 00740 } 00741 } |
|
Asks a channel for device state.
Definition at line 1671 of file channel.c. References AST_DEVICE_INVALID, AST_DEVICE_UNKNOWN, ast_log(), AST_MAX_EXTENSION, ast_mutex_lock, ast_mutex_unlock, ast_parse_device_state(), backends, and LOG_WARNING.
01672 { 01673 char tech[AST_MAX_EXTENSION] = ""; 01674 char *number; 01675 struct chanlist *chanls; 01676 int res = 0; 01677 01678 strncpy(tech, device, sizeof(tech)-1); 01679 number = strchr(tech, '/'); 01680 if (!number) { 01681 return AST_DEVICE_INVALID; 01682 } 01683 *number = 0; 01684 number++; 01685 01686 if (ast_mutex_lock(&chlock)) { 01687 ast_log(LOG_WARNING, "Unable to lock channel list\n"); 01688 return -1; 01689 } 01690 chanls = backends; 01691 while(chanls) { 01692 if (!strcasecmp(tech, chanls->type)) { 01693 ast_mutex_unlock(&chlock); 01694 if (!chanls->devicestate) 01695 return ast_parse_device_state(device); 01696 else { 01697 res = chanls->devicestate(number); 01698 if (res == AST_DEVICE_UNKNOWN) 01699 return ast_parse_device_state(device); 01700 else 01701 return res; 01702 } 01703 } 01704 chanls = chanls->next; 01705 } 01706 ast_mutex_unlock(&chlock); 01707 return AST_DEVICE_INVALID; 01708 } |
|
Hang up a channel.
Definition at line 614 of file channel.c. References ast_cdr_end(), ast_cdr_free(), ast_cdr_post(), ast_channel_free(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_stopstream(), ast_channel::blocker, ast_channel::blocking, ast_channel::blockproc, ast_channel::cdr, CRASH, EVENT_FLAG_CALL, ast_channel::generator, ast_channel::generatordata, ast_channel_pvt::hangup, ast_channel::lock, LOG_DEBUG, LOG_WARNING, manager_event(), ast_channel::masq, ast_channel::masqr, ast_channel::name, option_debug, ast_channel::pvt, ast_generator::release, ast_channel::sched, sched_context_destroy(), ast_channel::stream, ast_channel::uniqueid, and ast_channel::zombie. Referenced by __ast_request_and_dial(), and ast_pbx_run().
00615 { 00616 int res = 0; 00617 /* Don't actually hang up a channel that will masquerade as someone else, or 00618 if someone is going to masquerade as us */ 00619 ast_mutex_lock(&chan->lock); 00620 if (chan->masq) { 00621 if (ast_do_masquerade(chan)) 00622 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 00623 } 00624 00625 if (chan->masq) { 00626 ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name); 00627 ast_mutex_unlock(&chan->lock); 00628 return 0; 00629 } 00630 /* If this channel is one which will be masqueraded into something, 00631 mark it as a zombie already, so we know to free it later */ 00632 if (chan->masqr) { 00633 ast_mutex_unlock(&chan->lock); 00634 chan->zombie=1; 00635 return 0; 00636 } 00637 free_translation(chan); 00638 if (chan->stream) 00639 ast_stopstream(chan); 00640 if (chan->sched) 00641 sched_context_destroy(chan->sched); 00642 /* Clear any tone stuff remaining */ 00643 if (chan->generatordata) 00644 chan->generator->release(chan, chan->generatordata); 00645 chan->generatordata = NULL; 00646 chan->generator = NULL; 00647 if (chan->cdr) { 00648 /* End the CDR if it hasn't already */ 00649 ast_cdr_end(chan->cdr); 00650 /* Post and Free the CDR */ 00651 ast_cdr_post(chan->cdr); 00652 ast_cdr_free(chan->cdr); 00653 } 00654 if (chan->blocking) { 00655 ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd " 00656 "is blocked by thread %ld in procedure %s! Expect a failure\n", 00657 (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc); 00658 CRASH; 00659 } 00660 if (!chan->zombie) { 00661 if (option_debug) 00662 ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name); 00663 if (chan->pvt->hangup) 00664 res = chan->pvt->hangup(chan); 00665 } else 00666 if (option_debug) 00667 ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name); 00668 00669 ast_mutex_unlock(&chan->lock); 00670 manager_event(EVENT_FLAG_CALL, "Hangup", 00671 "Channel: %s\r\n" 00672 "Uniqueid: %s\r\n", 00673 chan->name, chan->uniqueid); 00674 ast_channel_free(chan); 00675 return res; 00676 } |
|
Indicates condition of channel.
Definition at line 1174 of file channel.c. References ast_check_hangup(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_get_indication_tone(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_playtones_start(), ast_playtones_stop(), ast_channel::data, ast_channel_pvt::indicate, ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_channel::pvt, ast_channel::zombie, and ast_channel::zone.
01175 { 01176 int res = -1; 01177 /* Stop if we're a zombie or need a soft hangup */ 01178 if (chan->zombie || ast_check_hangup(chan)) 01179 return -1; 01180 ast_mutex_lock(&chan->lock); 01181 if (chan->pvt->indicate) 01182 res = chan->pvt->indicate(chan, condition); 01183 ast_mutex_unlock(&chan->lock); 01184 if (!chan->pvt->indicate || res) { 01185 /* 01186 * Device does not support (that) indication, lets fake 01187 * it by doing our own tone generation. (PM2002) 01188 */ 01189 if (condition >= 0) { 01190 const struct tone_zone_sound *ts = NULL; 01191 switch (condition) { 01192 case AST_CONTROL_RINGING: 01193 ts = ast_get_indication_tone(chan->zone, "ring"); 01194 break; 01195 case AST_CONTROL_BUSY: 01196 ts = ast_get_indication_tone(chan->zone, "busy"); 01197 break; 01198 case AST_CONTROL_CONGESTION: 01199 ts = ast_get_indication_tone(chan->zone, "congestion"); 01200 break; 01201 } 01202 if (ts && ts->data[0]) { 01203 ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition); 01204 ast_playtones_start(chan,0,ts->data, 1); 01205 res = 0; 01206 } else if (condition == AST_CONTROL_PROGRESS) { 01207 /* ast_playtones_stop(chan); */ 01208 } else { 01209 /* not handled */ 01210 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name); 01211 res = -1; 01212 } 01213 } 01214 else ast_playtones_stop(chan); 01215 } 01216 return res; 01217 } |
|
Search the Channels by Name.
Definition at line 1652 of file channel.c. References AST_CHANNEL_NAME, ast_channel_walk(), AST_DEVICE_INUSE, AST_DEVICE_UNKNOWN, and ast_channel::name. Referenced by ast_device_state().
01653 { 01654 char name[AST_CHANNEL_NAME] = ""; 01655 char *cut; 01656 struct ast_channel *chan; 01657 01658 chan = ast_channel_walk(NULL); 01659 while (chan) { 01660 strncpy(name, chan->name, sizeof(name)-1); 01661 cut = strchr(name,'-'); 01662 if (cut) 01663 *cut = 0; 01664 if (!strcmp(name, device)) 01665 return AST_DEVICE_INUSE; 01666 chan = ast_channel_walk(chan); 01667 } 01668 return AST_DEVICE_UNKNOWN; 01669 } |
|
Definition at line 1306 of file channel.c. References ast_channel::_state, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), AST_STATE_UP, ast_write(), ast_frame::data, LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_channel::pvt, ast_channel_pvt::rawwriteformat, and ast_frame::subclass. Referenced by ast_activate_generator().
01307 { 01308 struct ast_frame a = { AST_FRAME_VOICE }; 01309 char nothing[128]; 01310 /* Send an empty audio frame to get things moving */ 01311 if (chan->_state != AST_STATE_UP) { 01312 ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name); 01313 a.subclass = chan->pvt->rawwriteformat; 01314 a.data = nothing + AST_FRIENDLY_OFFSET; 01315 if (ast_write(chan, &a)) 01316 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name); 01317 } 01318 return 0; 01319 } |
|
Reads a frame.
Definition at line 994 of file channel.c. References ast_channel::_softhangup, ast_channel_pvt::alertpipe, ast_cdr_answer(), ast_cdr_end(), ast_check_hangup(), AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, ast_deactivate_generator(), AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frame_dump(), AST_FRAME_NULL, AST_FRAME_VOICE, ast_frfree(), ast_getformatname(), ast_log(), AST_MAX_FDS, ast_mutex_lock, ast_mutex_unlock, ast_seekstream(), ast_setstate(), AST_SOFTHANGUP_DEV, AST_STATE_UP, ast_translate(), ast_writestream(), ast_channel::blocker, ast_channel::cdr, ast_channel::deferdtmf, ast_channel::dtmff, ast_channel::dtmfq, ast_channel_pvt::exception, ast_channel::exception, ast_channel::fdno, ast_channel::fin, ast_frame::frametype, ast_generator::generate, ast_channel::generator, ast_channel::generatordata, ast_channel::insmpl, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::masq, ast_channel::monitor, ast_channel::name, ast_channel::nativeformats, ast_frame::next, ast_channel::outsmpl, ast_channel::pvt, ast_channel_pvt::read, ast_channel_monitor::read_stream, ast_channel_pvt::readq, ast_channel_pvt::readtrans, SEEK_FORCECUR, ast_frame::subclass, ast_channel::timingdata, ast_channel::timingfd, ast_channel::timingfunc, and ast_channel::zombie. Referenced by __ast_request_and_dial(), ast_app_getvoice(), ast_channel_bridge(), ast_recvchar(), ast_rtp_bridge(), ast_safe_sleep(), ast_safe_sleep_conditional(), ast_tonepair(), ast_waitfordigit(), ast_waitfordigit_full(), ast_waitstream(), ast_waitstream_fr(), and ast_waitstream_full().
00995 { 00996 struct ast_frame *f = NULL; 00997 int blah; 00998 #ifdef ZAPTEL_OPTIMIZATIONS 00999 int (*func)(void *); 01000 void *data; 01001 #endif 01002 static struct ast_frame null_frame = 01003 { 01004 AST_FRAME_NULL, 01005 }; 01006 01007 ast_mutex_lock(&chan->lock); 01008 if (chan->masq) { 01009 if (ast_do_masquerade(chan)) { 01010 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 01011 f = NULL; 01012 } else 01013 f = &null_frame; 01014 ast_mutex_unlock(&chan->lock); 01015 return f; 01016 } 01017 01018 /* Stop if we're a zombie or need a soft hangup */ 01019 if (chan->zombie || ast_check_hangup(chan)) { 01020 if (chan->generator) 01021 ast_deactivate_generator(chan); 01022 ast_mutex_unlock(&chan->lock); 01023 return NULL; 01024 } 01025 01026 if (!chan->deferdtmf && strlen(chan->dtmfq)) { 01027 /* We have DTMF that has been deferred. Return it now */ 01028 chan->dtmff.frametype = AST_FRAME_DTMF; 01029 chan->dtmff.subclass = chan->dtmfq[0]; 01030 /* Drop first digit */ 01031 memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1); 01032 ast_mutex_unlock(&chan->lock); 01033 return &chan->dtmff; 01034 } 01035 01036 /* Read and ignore anything on the alertpipe, but read only 01037 one sizeof(blah) per frame that we send from it */ 01038 if (chan->pvt->alertpipe[0] > -1) { 01039 read(chan->pvt->alertpipe[0], &blah, sizeof(blah)); 01040 } 01041 #ifdef ZAPTEL_OPTIMIZATIONS 01042 if ((chan->timingfd > -1) && (chan->fdno == AST_MAX_FDS - 2) && chan->exception) { 01043 chan->exception = 0; 01044 blah = -1; 01045 ioctl(chan->timingfd, ZT_TIMERACK, &blah); 01046 func = chan->timingfunc; 01047 data = chan->timingdata; 01048 ast_mutex_unlock(&chan->lock); 01049 if (func) { 01050 #if 0 01051 ast_log(LOG_DEBUG, "Calling private function\n"); 01052 #endif 01053 func(data); 01054 } else { 01055 blah = 0; 01056 ast_mutex_lock(&chan->lock); 01057 ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah); 01058 chan->timingdata = NULL; 01059 ast_mutex_unlock(&chan->lock); 01060 } 01061 f = &null_frame; 01062 return f; 01063 } 01064 #endif 01065 /* Check for pending read queue */ 01066 if (chan->pvt->readq) { 01067 f = chan->pvt->readq; 01068 chan->pvt->readq = f->next; 01069 /* Interpret hangup and return NULL */ 01070 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) { 01071 ast_frfree(f); 01072 f = NULL; 01073 } 01074 } else { 01075 chan->blocker = pthread_self(); 01076 if (chan->exception) { 01077 if (chan->pvt->exception) 01078 f = chan->pvt->exception(chan); 01079 else { 01080 ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name); 01081 f = &null_frame; 01082 } 01083 /* Clear the exception flag */ 01084 chan->exception = 0; 01085 } else 01086 if (chan->pvt->read) 01087 f = chan->pvt->read(chan); 01088 else 01089 ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name); 01090 } 01091 01092 01093 if (f && (f->frametype == AST_FRAME_VOICE)) { 01094 if (!(f->subclass & chan->nativeformats)) { 01095 /* This frame can't be from the current native formats -- drop it on the 01096 floor */ 01097 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)); 01098 ast_frfree(f); 01099 f = &null_frame; 01100 } else { 01101 if (chan->monitor && chan->monitor->read_stream ) { 01102 #ifndef MONITOR_CONSTANT_DELAY 01103 int jump = chan->outsmpl - chan->insmpl - 2 * f->samples; 01104 if (jump >= 0) { 01105 if (ast_seekstream(chan->monitor->read_stream, jump + f->samples, SEEK_FORCECUR) == -1) 01106 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 01107 chan->insmpl += jump + 2 * f->samples; 01108 } else 01109 chan->insmpl+= f->samples; 01110 #else 01111 int jump = chan->outsmpl - chan->insmpl; 01112 if (jump - MONITOR_DELAY >= 0) { 01113 if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1) 01114 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 01115 chan->insmpl += jump; 01116 } else 01117 chan->insmpl += f->samples; 01118 #endif 01119 if (ast_writestream(chan->monitor->read_stream, f) < 0) 01120 ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n"); 01121 } 01122 if (chan->pvt->readtrans) { 01123 f = ast_translate(chan->pvt->readtrans, f, 1); 01124 if (!f) 01125 f = &null_frame; 01126 } 01127 } 01128 } 01129 01130 /* Make sure we always return NULL in the future */ 01131 if (!f) { 01132 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01133 if (chan->generator) 01134 ast_deactivate_generator(chan); 01135 /* End the CDR if appropriate */ 01136 if (chan->cdr) 01137 ast_cdr_end(chan->cdr); 01138 } else if (chan->deferdtmf && f->frametype == AST_FRAME_DTMF) { 01139 if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2) 01140 chan->dtmfq[strlen(chan->dtmfq)] = f->subclass; 01141 else 01142 ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name); 01143 f = &null_frame; 01144 } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_ANSWER)) { 01145 /* Answer the CDR */ 01146 ast_setstate(chan, AST_STATE_UP); 01147 ast_cdr_answer(chan->cdr); 01148 } 01149 ast_mutex_unlock(&chan->lock); 01150 01151 /* Run any generator sitting on the line */ 01152 if (f && (f->frametype == AST_FRAME_VOICE) && chan->generatordata) { 01153 /* Mask generator data temporarily */ 01154 void *tmp; 01155 int res; 01156 tmp = chan->generatordata; 01157 chan->generatordata = NULL; 01158 res = chan->generator->generate(chan, tmp, f->datalen, f->samples); 01159 chan->generatordata = tmp; 01160 if (res) { 01161 ast_log(LOG_DEBUG, "Auto-deactivating generator\n"); 01162 ast_deactivate_generator(chan); 01163 } 01164 } 01165 if (chan->fin & 0x80000000) 01166 ast_frame_dump(chan->name, f, "<<"); 01167 if ((chan->fin & 0x7fffffff) == 0x7fffffff) 01168 chan->fin &= 0x80000000; 01169 else 01170 chan->fin++; 01171 return f; 01172 } |
|
Reads multiple digits.
Definition at line 1745 of file channel.c. References ast_check_hangup(), AST_DIGIT_ANY, ast_stopstream(), ast_waitfordigit(), ast_waitstream(), s, ast_channel::stream, and ast_channel::zombie. Referenced by ast_app_getdata().
01746 { 01747 int pos=0; 01748 int to = ftimeout; 01749 char d; 01750 /* XXX Merge with full version? XXX */ 01751 /* Stop if we're a zombie or need a soft hangup */ 01752 if (c->zombie || ast_check_hangup(c)) 01753 return -1; 01754 if (!len) 01755 return -1; 01756 do { 01757 if (c->stream) { 01758 d = ast_waitstream(c, AST_DIGIT_ANY); 01759 ast_stopstream(c); 01760 usleep(1000); 01761 if (!d) 01762 d = ast_waitfordigit(c, to); 01763 } else { 01764 d = ast_waitfordigit(c, to); 01765 } 01766 if (d < 0) 01767 return -1; 01768 if (d == 0) { 01769 s[pos]='\0'; 01770 return 1; 01771 } 01772 if (!strchr(enders, d)) 01773 s[pos++] = d; 01774 if (strchr(enders, d) || (pos >= len)) { 01775 s[pos]='\0'; 01776 return 0; 01777 } 01778 to = timeout; 01779 } while(1); 01780 /* Never reached */ 01781 return 0; 01782 } |
|
Definition at line 1784 of file channel.c. References ast_check_hangup(), AST_DIGIT_ANY, ast_stopstream(), ast_waitfordigit_full(), ast_waitstream_full(), s, ast_channel::stream, and ast_channel::zombie. Referenced by ast_app_getdata_full().
01785 { 01786 int pos=0; 01787 int to = ftimeout; 01788 char d; 01789 /* Stop if we're a zombie or need a soft hangup */ 01790 if (c->zombie || ast_check_hangup(c)) 01791 return -1; 01792 if (!len) 01793 return -1; 01794 do { 01795 if (c->stream) { 01796 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd); 01797 ast_stopstream(c); 01798 usleep(1000); 01799 if (!d) 01800 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 01801 } else { 01802 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 01803 } 01804 if (d < 0) 01805 return -1; 01806 if (d == 0) { 01807 s[pos]='\0'; 01808 return 1; 01809 } 01810 if (d == 1) { 01811 s[pos]='\0'; 01812 return 2; 01813 } 01814 if (!strchr(enders, d)) 01815 s[pos++] = d; 01816 if (strchr(enders, d) || (pos >= len)) { 01817 s[pos]='\0'; 01818 return 0; 01819 } 01820 to = timeout; 01821 } while(1); 01822 /* Never reached */ 01823 return 0; 01824 } |
|
Receives a text character from a channel.
Definition at line 1219 of file channel.c. References ast_check_hangup(), AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_TEXT, ast_frfree(), ast_read(), and ast_waitfor().
01220 { 01221 int res,ourto,c; 01222 struct ast_frame *f; 01223 01224 ourto = timeout; 01225 for(;;) 01226 { 01227 if (ast_check_hangup(chan)) return -1; 01228 res = ast_waitfor(chan,ourto); 01229 if (res <= 0) /* if timeout */ 01230 { 01231 return 0; 01232 } 01233 ourto = res; 01234 f = ast_read(chan); 01235 if (f == NULL) return -1; /* if hangup */ 01236 if ((f->frametype == AST_FRAME_CONTROL) && 01237 (f->subclass == AST_CONTROL_HANGUP)) return -1; /* if hangup */ 01238 if (f->frametype == AST_FRAME_TEXT) /* if a text frame */ 01239 { 01240 c = *((char *)f->data); /* get the data */ 01241 ast_frfree(f); 01242 return(c); 01243 } 01244 ast_frfree(f); 01245 } 01246 } |
|
Requests a channel.
Definition at line 1607 of file channel.c. References ast_channel::_state, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_state2str(), AST_STATE_DOWN, ast_translator_best_choice(), backends, ast_channel::callerid, EVENT_FLAG_CALL, LOG_WARNING, manager_event(), ast_channel::name, ast_channel::next, ast_channel::type, type, and ast_channel::uniqueid. Referenced by __ast_request_and_dial().
01608 { 01609 struct chanlist *chan; 01610 struct ast_channel *c = NULL; 01611 int capabilities; 01612 int fmt; 01613 int res; 01614 if (ast_mutex_lock(&chlock)) { 01615 ast_log(LOG_WARNING, "Unable to lock channel list\n"); 01616 return NULL; 01617 } 01618 chan = backends; 01619 while(chan) { 01620 if (!strcasecmp(type, chan->type)) { 01621 capabilities = chan->capabilities; 01622 fmt = format; 01623 res = ast_translator_best_choice(&fmt, &capabilities); 01624 if (res < 0) { 01625 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->capabilities, format); 01626 ast_mutex_unlock(&chlock); 01627 return NULL; 01628 } 01629 ast_mutex_unlock(&chlock); 01630 if (chan->requester) 01631 c = chan->requester(type, capabilities, data); 01632 if (c) { 01633 if (c->_state == AST_STATE_DOWN) { 01634 manager_event(EVENT_FLAG_CALL, "Newchannel", 01635 "Channel: %s\r\n" 01636 "State: %s\r\n" 01637 "Callerid: %s\r\n" 01638 "Uniqueid: %s\r\n", 01639 c->name, ast_state2str(c->_state), c->callerid ? c->callerid : "<unknown>", c->uniqueid); 01640 } 01641 } 01642 return c; 01643 } 01644 chan = chan->next; 01645 } 01646 if (!chan) 01647 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type); 01648 ast_mutex_unlock(&chlock); 01649 return c; 01650 } |
|
Definition at line 1602 of file channel.c. References __ast_request_and_dial(), and type.
01603 { 01604 return __ast_request_and_dial(type, format, data, timeout, outstate, callerid, NULL); 01605 } |
|
Wait for a specied amount of time, looking for hangups.
Definition at line 473 of file channel.c. References ast_frfree(), ast_read(), and ast_waitfor().
00474 { 00475 struct ast_frame *f; 00476 while(ms > 0) { 00477 ms = ast_waitfor(chan, ms); 00478 if (ms <0) 00479 return -1; 00480 if (ms > 0) { 00481 f = ast_read(chan); 00482 if (!f) 00483 return -1; 00484 ast_frfree(f); 00485 } 00486 } 00487 return 0; 00488 } |
|
Wait for a specied amount of time, looking for hangups and a condition argument.
Definition at line 452 of file channel.c. References ast_frfree(), ast_read(), and ast_waitfor().
00454 { 00455 struct ast_frame *f; 00456 00457 while(ms > 0) { 00458 if( cond && ((*cond)(data) == 0 ) ) 00459 return 0; 00460 ms = ast_waitfor(chan, ms); 00461 if (ms <0) 00462 return -1; 00463 if (ms > 0) { 00464 f = ast_read(chan); 00465 if (!f) 00466 return -1; 00467 ast_frfree(f); 00468 } 00469 } 00470 return 0; 00471 } |
|
Sends text to a channel.
Definition at line 1248 of file channel.c. References ast_check_hangup(), ast_channel::blocking, CHECK_BLOCKING, ast_channel::pvt, ast_channel_pvt::send_text, and ast_channel::zombie.
01249 { 01250 int res = 0; 01251 /* Stop if we're a zombie or need a soft hangup */ 01252 if (chan->zombie || ast_check_hangup(chan)) 01253 return -1; 01254 CHECK_BLOCKING(chan); 01255 if (chan->pvt->send_text) 01256 res = chan->pvt->send_text(chan, text); 01257 chan->blocking = 0; 01258 return res; 01259 } |
|
Definition at line 2131 of file channel.c. References ast_channel::ani, ast_cdr_setcid(), ast_channel::callerid, ast_channel::cdr, EVENT_FLAG_CALL, free, manager_event(), ast_channel::name, strdup, and ast_channel::uniqueid. Referenced by __ast_request_and_dial().
02132 { 02133 if (chan->callerid) 02134 free(chan->callerid); 02135 if (anitoo && chan->ani) 02136 free(chan->ani); 02137 if (callerid) { 02138 chan->callerid = strdup(callerid); 02139 if (anitoo) 02140 chan->ani = strdup(callerid); 02141 } else { 02142 chan->callerid = NULL; 02143 if (anitoo) 02144 chan->ani = NULL; 02145 } 02146 if (chan->cdr) 02147 ast_cdr_setcid(chan->cdr, chan); 02148 manager_event(EVENT_FLAG_CALL, "Newcallerid", 02149 "Channel: %s\r\n" 02150 "Callerid: %s\r\n" 02151 "Uniqueid: %s\r\n", 02152 chan->name, chan->callerid ? 02153 chan->callerid : "<Unknown>", 02154 chan->uniqueid); 02155 } |
|
Sets read format on channel chan.
Definition at line 1470 of file channel.c. References ast_getformatname(), ast_log(), ast_translator_best_choice(), ast_translator_build_path(), ast_translator_free_path(), LOG_DEBUG, LOG_NOTICE, ast_channel::name, ast_channel::nativeformats, option_debug, ast_channel::pvt, ast_channel_pvt::rawreadformat, ast_channel::readformat, and ast_channel_pvt::readtrans. Referenced by ast_app_getvoice(), and ast_channel_make_compatible().
01471 { 01472 int fmt; 01473 int native; 01474 int res; 01475 01476 native = chan->nativeformats; 01477 fmt = fmts; 01478 /* Find a translation path from the native read format to one of the user's read formats */ 01479 res = ast_translator_best_choice(&fmt, &native); 01480 if (res < 0) { 01481 ast_log(LOG_NOTICE, "Unable to find a path from %s to %s\n", 01482 ast_getformatname(chan->nativeformats), ast_getformatname(fmts)); 01483 return -1; 01484 } 01485 01486 /* Now we have a good choice for both. We'll write using our native format. */ 01487 chan->pvt->rawreadformat = native; 01488 /* User perspective is fmt */ 01489 chan->readformat = fmt; 01490 /* Free any read translation we have right now */ 01491 if (chan->pvt->readtrans) 01492 ast_translator_free_path(chan->pvt->readtrans); 01493 /* Build a translation path from the raw read format to the user reading format */ 01494 chan->pvt->readtrans = ast_translator_build_path(chan->readformat, chan->pvt->rawreadformat); 01495 if (option_debug) 01496 ast_log(LOG_DEBUG, "Set channel %s to read format %s\n", 01497 chan->name, ast_getformatname(chan->readformat)); 01498 return 0; 01499 } |
|
Sets write format on channel chan.
Definition at line 1440 of file channel.c. References ast_getformatname(), ast_log(), ast_translator_best_choice(), ast_translator_build_path(), ast_translator_free_path(), LOG_DEBUG, LOG_NOTICE, ast_channel::name, ast_channel::nativeformats, option_debug, ast_channel::pvt, ast_channel_pvt::rawwriteformat, ast_channel::writeformat, and ast_channel_pvt::writetrans. Referenced by ast_channel_make_compatible(), ast_openstream(), and ast_stopstream().
01441 { 01442 int fmt; 01443 int native; 01444 int res; 01445 01446 native = chan->nativeformats; 01447 fmt = fmts; 01448 01449 res = ast_translator_best_choice(&native, &fmt); 01450 if (res < 0) { 01451 ast_log(LOG_NOTICE, "Unable to find a path from %s to %s\n", 01452 ast_getformatname(fmts), ast_getformatname(chan->nativeformats)); 01453 return -1; 01454 } 01455 01456 /* Now we have a good choice for both. We'll write using our native format. */ 01457 chan->pvt->rawwriteformat = native; 01458 /* User perspective is fmt */ 01459 chan->writeformat = fmt; 01460 /* Free any write translation we have right now */ 01461 if (chan->pvt->writetrans) 01462 ast_translator_free_path(chan->pvt->writetrans); 01463 /* Build a translation path from the user write format to the raw writing format */ 01464 chan->pvt->writetrans = ast_translator_build_path(chan->pvt->rawwriteformat, chan->writeformat); 01465 if (option_debug) 01466 ast_log(LOG_DEBUG, "Set channel %s to write format %s\n", chan->name, ast_getformatname(chan->writeformat)); 01467 return 0; 01468 } |
|
Definition at line 947 of file channel.c. References ast_log(), LOG_DEBUG, ast_channel::timingdata, ast_channel::timingfd, and ast_channel::timingfunc. Referenced by ast_closestream().
00948 { 00949 int res = -1; 00950 #ifdef ZAPTEL_OPTIMIZATIONS 00951 if (c->timingfd > -1) { 00952 if (!func) { 00953 samples = 0; 00954 data = 0; 00955 } 00956 ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples); 00957 res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples); 00958 c->timingfunc = func; 00959 c->timingdata = data; 00960 } 00961 #endif 00962 return res; 00963 } |
|
Returns non-zero if Asterisk is being shut down Definition at line 129 of file channel.c.
00130 {
00131 return shutting_down;
00132 }
|
|
Softly hangup up a channel.
Definition at line 591 of file channel.c. References ast_mutex_lock, ast_mutex_unlock, ast_softhangup_nolock(), and ast_channel::lock. Referenced by ast_begin_shutdown().
00592 { 00593 int res; 00594 ast_mutex_lock(&chan->lock); 00595 res = ast_softhangup_nolock(chan, cause); 00596 ast_mutex_unlock(&chan->lock); 00597 return res; 00598 } |
|
Definition at line 576 of file channel.c. References ast_channel::_softhangup, AST_FRAME_NULL, ast_log(), ast_queue_frame(), ast_channel::blocker, ast_channel::blocking, LOG_DEBUG, ast_channel::name, and option_debug. Referenced by ast_softhangup().
00577 { 00578 int res = 0; 00579 struct ast_frame f = { AST_FRAME_NULL }; 00580 if (option_debug) 00581 ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name); 00582 /* Inform channel driver that we need to be hung up, if it cares */ 00583 chan->_softhangup |= cause; 00584 ast_queue_frame(chan, &f, 0); 00585 /* Interrupt any select call or such */ 00586 if (chan->blocking) 00587 pthread_kill(chan->blocker, SIGURG); 00588 return res; 00589 } |
|
Gives the string form of a given state.
Definition at line 195 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 ast_request(), and ast_setstate().
00196 { 00197 /* XXX Not reentrant XXX */ 00198 static char localtmp[256]; 00199 switch(state) { 00200 case AST_STATE_DOWN: 00201 return "Down"; 00202 case AST_STATE_RESERVED: 00203 return "Rsrvd"; 00204 case AST_STATE_OFFHOOK: 00205 return "OffHook"; 00206 case AST_STATE_DIALING: 00207 return "Dialing"; 00208 case AST_STATE_RING: 00209 return "Ring"; 00210 case AST_STATE_RINGING: 00211 return "Ringing"; 00212 case AST_STATE_UP: 00213 return "Up"; 00214 case AST_STATE_BUSY: 00215 return "Busy"; 00216 default: 00217 snprintf(localtmp, sizeof(localtmp), "Unknown (%d)\n", state); 00218 return localtmp; 00219 } 00220 } |
|
Play a tone pair for a given amount of time Definition at line 2477 of file channel.c. References ast_frfree(), ast_read(), ast_tonepair_start(), ast_waitfor(), and ast_channel::generatordata.
02478 { 02479 struct ast_frame *f; 02480 int res; 02481 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol))) 02482 return res; 02483 02484 /* Give us some wiggle room */ 02485 while(chan->generatordata && (ast_waitfor(chan, 100) >= 0)) { 02486 f = ast_read(chan); 02487 if (f) 02488 ast_frfree(f); 02489 else 02490 return -1; 02491 } 02492 return 0; 02493 } |
|
Start a tone going Definition at line 2457 of file channel.c. References ast_activate_generator(), tonepair_def::duration, tonepair_def::freq1, tonepair_def::freq2, and tonepair_def::vol. Referenced by ast_tonepair().
02458 { 02459 struct tonepair_def d = { 0, }; 02460 d.freq1 = freq1; 02461 d.freq2 = freq2; 02462 d.duration = duration; 02463 if (vol < 1) 02464 d.vol = 8192; 02465 else 02466 d.vol = vol; 02467 if (ast_activate_generator(chan, &tonepair, &d)) 02468 return -1; 02469 return 0; 02470 } |
|
Stop a tone from playing Definition at line 2472 of file channel.c. References ast_deactivate_generator().
02473 { 02474 ast_deactivate_generator(chan); 02475 } |
|
Definition at line 1725 of file channel.c. References ast_check_hangup(), ast_mutex_lock, ast_mutex_unlock, ast_channel::lock, ast_channel::pvt, ast_channel_pvt::transfer, and ast_channel::zombie.
01726 { 01727 /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 01728 If the remote end does not answer within the timeout, then do NOT hang up, but 01729 return anyway. */ 01730 int res = -1; 01731 /* Stop if we're a zombie or need a soft hangup */ 01732 ast_mutex_lock(&chan->lock); 01733 if (!chan->zombie && !ast_check_hangup(chan)) { 01734 if (chan->pvt->transfer) { 01735 res = chan->pvt->transfer(chan, dest); 01736 if (!res) 01737 res = 1; 01738 } else 01739 res = 0; 01740 } 01741 ast_mutex_unlock(&chan->lock); 01742 return res; 01743 } |
|
Wait for input on a channel.
Definition at line 906 of file channel.c. References ast_waitfor_n(). Referenced by __ast_request_and_dial(), ast_app_getvoice(), ast_recvchar(), ast_safe_sleep(), ast_safe_sleep_conditional(), ast_tonepair(), ast_waitfordigit(), ast_waitstream(), and ast_waitstream_fr().
00907 { 00908 struct ast_channel *chan; 00909 int oldms = ms; 00910 chan = ast_waitfor_n(&c, 1, &ms); 00911 if (ms < 0) { 00912 if (oldms < 0) 00913 return 0; 00914 else 00915 return -1; 00916 } 00917 return ms; 00918 } |
|
Waits for input on a group of channels. Wait for input on an array of channels for a given # of milliseconds. Return channel with activity, or NULL if none has activity. time "ms" is modified in-place, if applicable Definition at line 901 of file channel.c. References ast_waitfor_nandfds(). Referenced by ast_channel_bridge(), ast_rtp_bridge(), and ast_waitfor().
00902 { 00903 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms); 00904 } |
|
Waits for input on an fd. This version works on fd's only. Be careful with it. Definition at line 758 of file channel.c.
00759 { 00760 /* Wait for x amount of time on a file descriptor to have input. */ 00761 struct timeval tv; 00762 fd_set rfds, efds; 00763 int res; 00764 int x, max=-1; 00765 int winner = -1; 00766 00767 tv.tv_sec = *ms / 1000; 00768 tv.tv_usec = (*ms % 1000) * 1000; 00769 FD_ZERO(&rfds); 00770 FD_ZERO(&efds); 00771 for (x=0;x<n;x++) { 00772 if (fds[x] > -1) { 00773 FD_SET(fds[x], &rfds); 00774 FD_SET(fds[x], &efds); 00775 if (fds[x] > max) 00776 max = fds[x]; 00777 } 00778 } 00779 if (*ms >= 0) 00780 res = ast_select(max + 1, &rfds, NULL, &efds, &tv); 00781 else 00782 res = ast_select(max + 1, &rfds, NULL, &efds, NULL); 00783 00784 if (res < 0) { 00785 /* Simulate a timeout if we were interrupted */ 00786 if (errno != EINTR) 00787 *ms = -1; 00788 else 00789 *ms = 0; 00790 return -1; 00791 } 00792 00793 for (x=0;x<n;x++) { 00794 if ((fds[x] > -1) && (FD_ISSET(fds[x], &rfds) || FD_ISSET(fds[x], &efds)) && (winner < 0)) { 00795 if (exception) 00796 *exception = FD_ISSET(fds[x], &efds); 00797 winner = fds[x]; 00798 } 00799 } 00800 *ms = tv.tv_sec * 1000 + tv.tv_usec / 1000; 00801 return winner; 00802 } |
|
Waits for activity on a group of channels.
Definition at line 804 of file channel.c. References ast_log(), AST_MAX_FDS, ast_mutex_lock, ast_mutex_unlock, ast_channel::blocking, CHECK_BLOCKING, ast_channel::exception, ast_channel::fdno, ast_channel::fds, LOG_WARNING, and ast_channel::masq. Referenced by ast_waitfor_n(), ast_waitfordigit_full(), and ast_waitstream_full().
00806 { 00807 /* Wait for x amount of time on a file descriptor to have input. */ 00808 struct timeval tv; 00809 fd_set rfds, efds; 00810 int res; 00811 int x, y, max=-1; 00812 struct ast_channel *winner = NULL; 00813 if (outfd) 00814 *outfd = -1; 00815 if (exception) 00816 *exception = 0; 00817 00818 /* Perform any pending masquerades */ 00819 for (x=0;x<n;x++) { 00820 ast_mutex_lock(&c[x]->lock); 00821 if (c[x]->masq) { 00822 if (ast_do_masquerade(c[x])) { 00823 ast_log(LOG_WARNING, "Masquerade failed\n"); 00824 *ms = -1; 00825 ast_mutex_unlock(&c[x]->lock); 00826 return NULL; 00827 } 00828 } 00829 ast_mutex_unlock(&c[x]->lock); 00830 } 00831 00832 tv.tv_sec = *ms / 1000; 00833 tv.tv_usec = (*ms % 1000) * 1000; 00834 FD_ZERO(&rfds); 00835 FD_ZERO(&efds); 00836 00837 for (x=0;x<n;x++) { 00838 for (y=0;y<AST_MAX_FDS;y++) { 00839 if (c[x]->fds[y] > -1) { 00840 FD_SET(c[x]->fds[y], &rfds); 00841 FD_SET(c[x]->fds[y], &efds); 00842 if (c[x]->fds[y] > max) 00843 max = c[x]->fds[y]; 00844 } 00845 } 00846 CHECK_BLOCKING(c[x]); 00847 } 00848 for (x=0;x<nfds; x++) { 00849 FD_SET(fds[x], &rfds); 00850 FD_SET(fds[x], &efds); 00851 if (fds[x] > max) 00852 max = fds[x]; 00853 } 00854 if (*ms >= 0) 00855 res = ast_select(max + 1, &rfds, NULL, &efds, &tv); 00856 else 00857 res = ast_select(max + 1, &rfds, NULL, &efds, NULL); 00858 00859 if (res < 0) { 00860 for (x=0;x<n;x++) 00861 c[x]->blocking = 0; 00862 /* Simulate a timeout if we were interrupted */ 00863 if (errno != EINTR) 00864 *ms = -1; 00865 else { 00866 /* Just an interrupt */ 00867 #if 0 00868 *ms = 0; 00869 #endif 00870 } 00871 return NULL; 00872 } 00873 00874 for (x=0;x<n;x++) { 00875 c[x]->blocking = 0; 00876 for (y=0;y<AST_MAX_FDS;y++) { 00877 if (c[x]->fds[y] > -1) { 00878 if ((FD_ISSET(c[x]->fds[y], &rfds) || FD_ISSET(c[x]->fds[y], &efds)) && !winner) { 00879 /* Set exception flag if appropriate */ 00880 if (FD_ISSET(c[x]->fds[y], &efds)) 00881 c[x]->exception = 1; 00882 c[x]->fdno = y; 00883 winner = c[x]; 00884 } 00885 } 00886 } 00887 } 00888 for (x=0;x<nfds;x++) { 00889 if ((FD_ISSET(fds[x], &rfds) || FD_ISSET(fds[x], &efds)) && !winner) { 00890 if (outfd) 00891 *outfd = fds[x]; 00892 if (FD_ISSET(fds[x], &efds) && exception) 00893 *exception = 1; 00894 winner = NULL; 00895 } 00896 } 00897 *ms = tv.tv_sec * 1000 + tv.tv_usec / 1000; 00898 return winner; 00899 } |
|
Waits for a digit.
Definition at line 920 of file channel.c. References ast_check_hangup(), AST_FRAME_DTMF, ast_frfree(), ast_read(), ast_waitfor(), and ast_channel::zombie. Referenced by ast_pbx_run(), and ast_readstring().
00921 { 00922 /* XXX Should I be merged with waitfordigit_full XXX */ 00923 struct ast_frame *f; 00924 char result = 0; 00925 /* Stop if we're a zombie or need a soft hangup */ 00926 if (c->zombie || ast_check_hangup(c)) 00927 return -1; 00928 /* Wait for a digit, no more than ms milliseconds total. */ 00929 while(ms && !result) { 00930 ms = ast_waitfor(c, ms); 00931 if (ms < 0) /* Error */ 00932 result = -1; 00933 else if (ms > 0) { 00934 /* Read something */ 00935 f = ast_read(c); 00936 if (f) { 00937 if (f->frametype == AST_FRAME_DTMF) 00938 result = f->subclass; 00939 ast_frfree(f); 00940 } else 00941 result = -1; 00942 } 00943 } 00944 return result; 00945 } |
|
Definition at line 964 of file channel.c. References ast_check_hangup(), AST_FRAME_DTMF, ast_frfree(), ast_read(), ast_waitfor_nandfds(), and ast_channel::zombie. Referenced by ast_readstring_full().
00965 { 00966 struct ast_frame *f; 00967 char result = 0; 00968 struct ast_channel *rchan; 00969 int outfd; 00970 /* Stop if we're a zombie or need a soft hangup */ 00971 if (c->zombie || ast_check_hangup(c)) 00972 return -1; 00973 /* Wait for a digit, no more than ms milliseconds total. */ 00974 while(ms && !result) { 00975 rchan = ast_waitfor_nandfds(&c, 1, &audio, (audio > -1) ? 1 : 0, NULL, &outfd, &ms); 00976 if ((!rchan) && (outfd < 0) && (ms)) /* Error */ 00977 result = -1; 00978 else if (outfd > -1) { 00979 result = 1; 00980 } else if (rchan) { 00981 /* Read something */ 00982 f = ast_read(c); 00983 if (f) { 00984 if (f->frametype == AST_FRAME_DTMF) 00985 result = f->subclass; 00986 ast_frfree(f); 00987 } else 00988 result = -1; 00989 } 00990 } 00991 return result; 00992 } |
|
Write a frame to a channel.
Definition at line 1332 of file channel.c. References ast_channel::_softhangup, ast_check_hangup(), ast_deactivate_generator(), AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frame_dump(), 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_translate(), ast_writestream(), ast_channel::blocking, CHECK_BLOCKING, ast_frame::data, ast_channel::fout, ast_frame::frametype, ast_channel::generatordata, ast_channel::insmpl, ast_channel::lock, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::name, ast_channel::outsmpl, ast_channel::pvt, SEEK_FORCECUR, ast_channel_pvt::send_text, ast_frame::subclass, ast_channel_pvt::write, ast_channel_monitor::write_stream, ast_channel_pvt::write_video, ast_channel::writeinterrupt, ast_channel_pvt::writetrans, and ast_channel::zombie. Referenced by ast_channel_bridge(), ast_prod(), ast_rtp_bridge(), and ast_write_video().
01333 { 01334 int res = -1; 01335 struct ast_frame *f = NULL; 01336 /* Stop if we're a zombie or need a soft hangup */ 01337 ast_mutex_lock(&chan->lock); 01338 if (chan->zombie || ast_check_hangup(chan)) { 01339 ast_mutex_unlock(&chan->lock); 01340 return -1; 01341 } 01342 /* Handle any pending masquerades */ 01343 if (chan->masq) { 01344 if (ast_do_masquerade(chan)) { 01345 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 01346 ast_mutex_unlock(&chan->lock); 01347 return -1; 01348 } 01349 } 01350 if (chan->masqr) { 01351 ast_mutex_unlock(&chan->lock); 01352 return 0; 01353 } 01354 if (chan->generatordata) { 01355 if (chan->writeinterrupt) 01356 ast_deactivate_generator(chan); 01357 else { 01358 ast_mutex_unlock(&chan->lock); 01359 return 0; 01360 } 01361 } 01362 if (chan->fout & 0x80000000) 01363 ast_frame_dump(chan->name, fr, ">>"); 01364 CHECK_BLOCKING(chan); 01365 switch(fr->frametype) { 01366 case AST_FRAME_CONTROL: 01367 /* XXX Interpret control frames XXX */ 01368 ast_log(LOG_WARNING, "Don't know how to handle control frames yet\n"); 01369 break; 01370 case AST_FRAME_DTMF: 01371 chan->blocking = 0; 01372 ast_mutex_unlock(&chan->lock); 01373 res = do_senddigit(chan,fr->subclass); 01374 ast_mutex_lock(&chan->lock); 01375 CHECK_BLOCKING(chan); 01376 break; 01377 case AST_FRAME_TEXT: 01378 if (chan->pvt->send_text) 01379 res = chan->pvt->send_text(chan, (char *) fr->data); 01380 break; 01381 case AST_FRAME_VIDEO: 01382 /* XXX Handle translation of video codecs one day XXX */ 01383 if (chan->pvt->write_video) 01384 res = chan->pvt->write_video(chan, fr); 01385 else 01386 res = 0; 01387 break; 01388 default: 01389 if (chan->pvt->write) { 01390 if (chan->pvt->writetrans) { 01391 f = ast_translate(chan->pvt->writetrans, fr, 0); 01392 } else 01393 f = fr; 01394 if (f) { 01395 res = chan->pvt->write(chan, f); 01396 if( chan->monitor && 01397 chan->monitor->write_stream && 01398 f && ( f->frametype == AST_FRAME_VOICE ) ) { 01399 #ifndef MONITOR_CONSTANT_DELAY 01400 int jump = chan->insmpl - chan->outsmpl - 2 * f->samples; 01401 if (jump >= 0) { 01402 if (ast_seekstream(chan->monitor->write_stream, jump + f->samples, SEEK_FORCECUR) == -1) 01403 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 01404 chan->outsmpl += jump + 2 * f->samples; 01405 } else 01406 chan->outsmpl += f->samples; 01407 #else 01408 int jump = chan->insmpl - chan->outsmpl; 01409 if (jump - MONITOR_DELAY >= 0) { 01410 if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1) 01411 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 01412 chan->outsmpl += jump; 01413 } else 01414 chan->outsmpl += f->samples; 01415 #endif 01416 if (ast_writestream(chan->monitor->write_stream, f) < 0) 01417 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n"); 01418 } 01419 } else 01420 res = 0; 01421 } 01422 } 01423 if (f && (f != fr)) 01424 ast_frfree(f); 01425 chan->blocking = 0; 01426 /* Consider a write failure to force a soft hangup */ 01427 if (res < 0) 01428 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01429 else { 01430 if ((chan->fout & 0x7fffffff) == 0x7fffffff) 01431 chan->fout &= 0x80000000; 01432 else 01433 chan->fout++; 01434 chan->fout++; 01435 } 01436 ast_mutex_unlock(&chan->lock); 01437 return res; 01438 } |
|
Write video frame to a channel.
Definition at line 1321 of file channel.c. References ast_write(), ast_channel::pvt, and ast_channel_pvt::write_video.
01322 { 01323 int res; 01324 if (!chan->pvt->write_video) 01325 return 0; 01326 res = ast_write(chan, fr); 01327 if (!res) 01328 res = 1; 01329 return res; 01330 } |