#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_generator |
struct | ast_channel |
Main Channel structure associated with a channel. More... | |
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 /* if the call is a digital ISDN call */ |
#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) /* Soft hangup by device */ |
#define | AST_SOFTHANGUP_ASYNCGOTO (1 << 1) /* Soft hangup for async goto */ |
#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) |
unsigned int | ast_get_group (char *s) |
|
|
|
|
|
|
|
|
|
Report DTMF on channel 0 Definition at line 643 of file channel.h. Referenced by ast_channel_bridge(), and ast_rtp_bridge(). |
|
Report DTMF on channel 1 Definition at line 645 of file channel.h. Referenced by ast_channel_bridge(), and ast_rtp_bridge(). |
|
Ignore all signal frames except NULL Definition at line 651 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 338 of file channel.h. Referenced by ast_parse_device_state(). |
|
Device is invalid Definition at line 342 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 334 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 302 of file channel.h. Referenced by ast_pbx_run(). |
|
Definition at line 300 of file channel.h. Referenced by ast_queue_hangup(), ast_read(), and ast_write(). |
|
|
|
Definition at line 304 of file channel.h. Referenced by ast_begin_shutdown(). |
|
Definition at line 305 of file channel.h. Referenced by ast_check_hangup(), ast_pbx_run(), and ast_waitfor_nandfds(). |
|
Line is busy Definition at line 325 of file channel.h. Referenced by ast_state2str(). |
|
Digits (or equivalent) have been dialed Definition at line 317 of file channel.h. Referenced by ast_state2str(). |
|
Digits (or equivalent) have been dialed while offhook |
|
Channel is down and available Definition at line 311 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 315 of file channel.h. Referenced by ast_state2str(). |
|
Channel is down, but reserved Definition at line 313 of file channel.h. Referenced by ast_state2str(). |
|
Line is ringing Definition at line 319 of file channel.h. Referenced by ast_answer(), and ast_state2str(). |
|
Remote end is ringing Definition at line 321 of file channel.h. Referenced by ast_answer(), and ast_state2str(). |
|
Line is up Definition at line 323 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 839 of file channel.h. Referenced by ast_sendtext(), ast_waitfor_nandfds(), and ast_write(). |
|
Definition at line 836 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 1528 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, and outgoing_helper::variable. Referenced by ast_request_and_dial().
01529 { 01530 int state = 0; 01531 struct ast_channel *chan; 01532 struct ast_frame *f; 01533 int res = 0; 01534 chan = ast_request(type, format, data); 01535 if (chan) { 01536 if (oh) { 01537 char *tmp, *var; 01538 /* JDG chanvar */ 01539 tmp = oh->variable; 01540 /* FIXME replace this call with strsep NOT*/ 01541 while( (var = strtok_r(NULL, "|", &tmp)) ) { 01542 pbx_builtin_setvar( chan, var ); 01543 } /* /JDG */ 01544 if (oh->callerid && *oh->callerid) 01545 ast_set_callerid(chan, oh->callerid, 1); 01546 if (oh->account && *oh->account) 01547 ast_cdr_setaccount(chan, oh->account); 01548 } 01549 if (callerid && strlen(callerid)) 01550 ast_set_callerid(chan, callerid, 1); 01551 01552 if (!ast_call(chan, data, 0)) { 01553 while(timeout && (chan->_state != AST_STATE_UP)) { 01554 res = ast_waitfor(chan, timeout); 01555 if (res < 0) { 01556 /* Something not cool, or timed out */ 01557 break; 01558 } 01559 /* If done, break out */ 01560 if (!res) 01561 break; 01562 if (timeout > -1) 01563 timeout = res; 01564 f = ast_read(chan); 01565 if (!f) { 01566 state = AST_CONTROL_HANGUP; 01567 res = 0; 01568 break; 01569 } 01570 if (f->frametype == AST_FRAME_CONTROL) { 01571 if (f->subclass == AST_CONTROL_RINGING) 01572 state = AST_CONTROL_RINGING; 01573 else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) { 01574 state = f->subclass; 01575 ast_frfree(f); 01576 break; 01577 } else if (f->subclass == AST_CONTROL_ANSWER) { 01578 state = f->subclass; 01579 ast_frfree(f); 01580 break; 01581 } else if (f->subclass == -1) { 01582 /* Ignore -- just stopping indications */ 01583 } else { 01584 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass); 01585 } 01586 } 01587 ast_frfree(f); 01588 } 01589 } else 01590 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data); 01591 } else 01592 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data); 01593 if (chan) { 01594 /* Final fixups */ 01595 if (oh) { 01596 if (oh->context && *oh->context) 01597 strncpy(chan->context, oh->context, sizeof(chan->context) - 1); 01598 if (oh->exten && *oh->exten) 01599 strncpy(chan->exten, oh->exten, sizeof(chan->exten) - 1); 01600 chan->priority = oh->priority; 01601 } 01602 if (chan->_state == AST_STATE_UP) 01603 state = AST_CONTROL_ANSWER; 01604 } 01605 if (outstate) 01606 *outstate = state; 01607 if (chan && res <= 0) { 01608 if (!chan->cdr) { 01609 chan->cdr = ast_cdr_alloc(); 01610 if (chan->cdr) 01611 ast_cdr_init(chan->cdr, chan); 01612 } 01613 if (chan->cdr) { 01614 char tmp[256]; 01615 sprintf(tmp, "%s/%s",type,(char *)data); 01616 ast_cdr_setapp(chan->cdr,"Dial",tmp); 01617 ast_cdr_update(chan); 01618 ast_cdr_start(chan->cdr); 01619 ast_cdr_end(chan->cdr); 01620 /* If the cause wasn't handled properly */ 01621 if (ast_cdr_disposition(chan->cdr,chan->hangupcause)) 01622 ast_cdr_failed(chan->cdr); 01623 } else 01624 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 01625 ast_hangup(chan); 01626 chan = NULL; 01627 } 01628 return chan; 01629 } |
|
Activate a given generator Definition at line 744 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().
00745 { 00746 if (chan->generatordata) { 00747 if (chan->generator && chan->generator->release) 00748 chan->generator->release(chan, chan->generatordata); 00749 chan->generatordata = NULL; 00750 } 00751 ast_prod(chan); 00752 if ((chan->generatordata = gen->alloc(chan, params))) { 00753 chan->generator = gen; 00754 } else { 00755 return -1; 00756 } 00757 return 0; 00758 } |
|
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, AST_PTHREADT_NULL, 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 == AST_PTHREADT_NULL) ? 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_PTHREADT_NULL, 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 != AST_PTHREADT_NULL) 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 1739 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().
01740 { 01741 /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 01742 If the remote end does not answer within the timeout, then do NOT hang up, but 01743 return anyway. */ 01744 int res = -1; 01745 /* Stop if we're a zombie or need a soft hangup */ 01746 ast_mutex_lock(&chan->lock); 01747 if (!chan->zombie && !ast_check_hangup(chan)) 01748 if (chan->pvt->call) 01749 res = chan->pvt->call(chan, addr, timeout); 01750 ast_mutex_unlock(&chan->lock); 01751 return res; 01752 } |
|
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 2213 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.
02214 { 02215 /* Copy voice back and forth between the two channels. Give the peer 02216 the ability to transfer calls with '#<extension' syntax. */ 02217 struct ast_channel *cs[3]; 02218 int to = -1; 02219 struct ast_frame *f; 02220 struct ast_channel *who = NULL; 02221 int res; 02222 int nativefailed=0; 02223 02224 /* Stop if we're a zombie or need a soft hangup */ 02225 if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1)) 02226 return -1; 02227 if (c0->bridge) { 02228 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 02229 c0->name, c0->bridge->name); 02230 return -1; 02231 } 02232 if (c1->bridge) { 02233 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 02234 c1->name, c1->bridge->name); 02235 return -1; 02236 } 02237 02238 /* Keep track of bridge */ 02239 c0->bridge = c1; 02240 c1->bridge = c0; 02241 cs[0] = c0; 02242 cs[1] = c1; 02243 02244 manager_event(EVENT_FLAG_CALL, "Link", 02245 "Channel1: %s\r\n" 02246 "Channel2: %s\r\n", 02247 c0->name, c1->name); 02248 02249 for (/* ever */;;) { 02250 /* Stop if we're a zombie or need a soft hangup */ 02251 if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1)) { 02252 *fo = NULL; 02253 if (who) *rc = who; 02254 res = 0; 02255 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"); 02256 break; 02257 } 02258 if (c0->pvt->bridge && 02259 (c0->pvt->bridge == c1->pvt->bridge) && !nativefailed && !c0->monitor && !c1->monitor) { 02260 /* Looks like they share a bridge code */ 02261 if (option_verbose > 2) 02262 ast_verbose(VERBOSE_PREFIX_3 "Attempting native bridge of %s and %s\n", c0->name, c1->name); 02263 if (!(res = c0->pvt->bridge(c0, c1, flags, fo, rc))) { 02264 c0->bridge = NULL; 02265 c1->bridge = NULL; 02266 manager_event(EVENT_FLAG_CALL, "Unlink", 02267 "Channel1: %s\r\n" 02268 "Channel2: %s\r\n", 02269 c0->name, c1->name); 02270 ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n",c0->name ,c1->name); 02271 return 0; 02272 } 02273 /* If they return non-zero then continue on normally. Let "-2" mean don't worry about 02274 my not wanting to bridge */ 02275 if ((res != -2) && (res != -3)) 02276 ast_log(LOG_WARNING, "Private bridge between %s and %s failed\n", c0->name, c1->name); 02277 if (res != -3) nativefailed++; 02278 } 02279 02280 02281 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat)) && 02282 !(c0->generator || c1->generator)) { 02283 if (ast_channel_make_compatible(c0, c1)) { 02284 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name); 02285 manager_event(EVENT_FLAG_CALL, "Unlink", 02286 "Channel1: %s\r\n" 02287 "Channel2: %s\r\n", 02288 c0->name, c1->name); 02289 return -1; 02290 } 02291 } 02292 who = ast_waitfor_n(cs, 2, &to); 02293 if (!who) { 02294 ast_log(LOG_DEBUG, "Nobody there, continuing...\n"); 02295 continue; 02296 } 02297 f = ast_read(who); 02298 if (!f) { 02299 *fo = NULL; 02300 *rc = who; 02301 res = 0; 02302 ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name); 02303 break; 02304 } 02305 02306 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) { 02307 *fo = f; 02308 *rc = who; 02309 res = 0; 02310 ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name); 02311 break; 02312 } 02313 if ((f->frametype == AST_FRAME_VOICE) || 02314 (f->frametype == AST_FRAME_TEXT) || 02315 (f->frametype == AST_FRAME_VIDEO) || 02316 (f->frametype == AST_FRAME_IMAGE) || 02317 (f->frametype == AST_FRAME_DTMF)) { 02318 if ((f->frametype == AST_FRAME_DTMF) && 02319 (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) { 02320 if ((who == c0)) { 02321 if ((flags & AST_BRIDGE_DTMF_CHANNEL_0)) { 02322 *rc = c0; 02323 *fo = f; 02324 /* Take out of conference mode */ 02325 res = 0; 02326 ast_log(LOG_DEBUG, "Got AST_BRIDGE_DTMF_CHANNEL_0 on c0 (%s)\n",c0->name); 02327 break; 02328 } else 02329 goto tackygoto; 02330 } else 02331 if ((who == c1)) { 02332 if (flags & AST_BRIDGE_DTMF_CHANNEL_1) { 02333 *rc = c1; 02334 *fo = f; 02335 res = 0; 02336 ast_log(LOG_DEBUG, "Got AST_BRIDGE_DTMF_CHANNEL_1 on c1 (%s)\n",c1->name); 02337 break; 02338 } else 02339 goto tackygoto; 02340 } 02341 } else { 02342 #if 0 02343 ast_log(LOG_DEBUG, "Read from %s\n", who->name); 02344 if (who == last) 02345 ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name); 02346 last = who; 02347 #endif 02348 tackygoto: 02349 /* Don't copy packets if there is a generator on either one, since they're 02350 not supposed to be listening anyway */ 02351 if (who == c0) 02352 ast_write(c1, f); 02353 else 02354 ast_write(c0, f); 02355 } 02356 ast_frfree(f); 02357 } else 02358 ast_frfree(f); 02359 /* Swap who gets priority */ 02360 cs[2] = cs[0]; 02361 cs[0] = cs[1]; 02362 cs[1] = cs[2]; 02363 } 02364 c0->bridge = NULL; 02365 c1->bridge = NULL; 02366 manager_event(EVENT_FLAG_CALL, "Unlink", 02367 "Channel1: %s\r\n" 02368 "Channel2: %s\r\n", 02369 c0->name, c1->name); 02370 ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n",c0->name,c1->name); 02371 return res; 02372 } |
|
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 1876 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().
01877 { 01878 int peerf; 01879 int chanf; 01880 int res; 01881 peerf = peer->nativeformats; 01882 chanf = chan->nativeformats; 01883 res = ast_translator_best_choice(&peerf, &chanf); 01884 if (res < 0) { 01885 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, chan->nativeformats, peer->name, peer->nativeformats); 01886 return -1; 01887 } 01888 /* Set read format on channel */ 01889 res = ast_set_read_format(chan, peerf); 01890 if (res < 0) { 01891 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, chanf); 01892 return -1; 01893 } 01894 /* Set write format on peer channel */ 01895 res = ast_set_write_format(peer, peerf); 01896 if (res < 0) { 01897 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, peerf); 01898 return -1; 01899 } 01900 /* Now we go the other way */ 01901 peerf = peer->nativeformats; 01902 chanf = chan->nativeformats; 01903 res = ast_translator_best_choice(&chanf, &peerf); 01904 if (res < 0) { 01905 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, peer->nativeformats, chan->name, chan->nativeformats); 01906 return -1; 01907 } 01908 /* Set writeformat on channel */ 01909 res = ast_set_write_format(chan, chanf); 01910 if (res < 0) { 01911 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, chanf); 01912 return -1; 01913 } 01914 /* Set read format on peer channel */ 01915 res = ast_set_read_format(peer, chanf); 01916 if (res < 0) { 01917 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, peerf); 01918 return -1; 01919 } 01920 return 0; 01921 } |
|
Weird function made for call transfers.
Definition at line 1923 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.
01924 { 01925 struct ast_frame null = { AST_FRAME_NULL, }; 01926 ast_log(LOG_DEBUG, "Planning to masquerade %s into the structure of %s\n", 01927 clone->name, original->name); 01928 if (original->masq) { 01929 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 01930 original->masq->name, original->name); 01931 return -1; 01932 } 01933 if (clone->masqr) { 01934 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 01935 clone->name, clone->masqr->name); 01936 return -1; 01937 } 01938 original->masq = clone; 01939 clone->masqr = original; 01940 /* XXX can't really hold the lock here, but at the same time, it' s 01941 not really safe not to XXX */ 01942 ast_queue_frame(original, &null, 0); 01943 ast_queue_frame(clone, &null, 0); 01944 ast_log(LOG_DEBUG, "Done planning to masquerade %s into the structure of %s\n", original->name, clone->name); 01945 return 0; 01946 } |
|
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().
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, LOG_DEBUG, LOG_WARNING, malloc, ast_channel::next, option_debug, option_verbose, 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 1862 of file channel.c. References ast_channel::pvt, and ast_channel_pvt::send_html.
01863 { 01864 if (chan->pvt->send_html) 01865 return chan->pvt->send_html(chan, subclass, data, datalen); 01866 return -1; 01867 } |
|
Sends a URL on a given link. Send URL on link. Returns 0 on success or -1 on failure Definition at line 1869 of file channel.c. References AST_HTML_URL, ast_channel::pvt, and ast_channel_pvt::send_html.
01870 { 01871 if (chan->pvt->send_html) 01872 return chan->pvt->send_html(chan, AST_HTML_URL, url, strlen(url) + 1); 01873 return -1; 01874 } |
|
Sets an option on a channel.
Definition at line 2374 of file channel.c. References ast_log(), LOG_ERROR, ast_channel::pvt, and ast_channel_pvt::setoption.
02375 { 02376 int res; 02377 if (chan->pvt->setoption) { 02378 res = chan->pvt->setoption(chan, option, data, datalen); 02379 if (res < 0) 02380 return res; 02381 } else { 02382 errno = ENOSYS; 02383 return -1; 02384 } 02385 if (block) { 02386 /* XXX Implement blocking -- just wait for our option frame reply, discarding 02387 intermediate packets. XXX */ 02388 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 02389 return -1; 02390 } 02391 return 0; 02392 } |
|
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 1855 of file channel.c. References ast_channel::pvt, and ast_channel_pvt::send_html.
01856 { 01857 if (chan->pvt->send_html) 01858 return 1; 01859 return 0; 01860 } |
|
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, 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 if (chan->generator && chan->generator->release) 00737 chan->generator->release(chan, chan->generatordata); 00738 chan->generatordata = NULL; 00739 chan->generator = NULL; 00740 chan->writeinterrupt = 0; 00741 } 00742 } |
|
Asks a channel for device state.
Definition at line 1700 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.
01701 { 01702 char tech[AST_MAX_EXTENSION] = ""; 01703 char *number; 01704 struct chanlist *chanls; 01705 int res = 0; 01706 01707 strncpy(tech, device, sizeof(tech)-1); 01708 number = strchr(tech, '/'); 01709 if (!number) { 01710 return AST_DEVICE_INVALID; 01711 } 01712 *number = 0; 01713 number++; 01714 01715 if (ast_mutex_lock(&chlock)) { 01716 ast_log(LOG_WARNING, "Unable to lock channel list\n"); 01717 return -1; 01718 } 01719 chanls = backends; 01720 while(chanls) { 01721 if (!strcasecmp(tech, chanls->type)) { 01722 ast_mutex_unlock(&chlock); 01723 if (!chanls->devicestate) 01724 return ast_parse_device_state(device); 01725 else { 01726 res = chanls->devicestate(number); 01727 if (res == AST_DEVICE_UNKNOWN) 01728 return ast_parse_device_state(device); 01729 else 01730 return res; 01731 } 01732 } 01733 chanls = chanls->next; 01734 } 01735 ast_mutex_unlock(&chlock); 01736 return AST_DEVICE_INVALID; 01737 } |
|
Definition at line 2526 of file channel.c. References ast_log(), LOG_ERROR, LOG_WARNING, and s.
02527 { 02528 char *copy; 02529 char *piece; 02530 char *c=NULL; 02531 int start=0, finish=0,x; 02532 unsigned int group = 0; 02533 copy = ast_strdupa(s); 02534 if (!copy) { 02535 ast_log(LOG_ERROR, "Out of memory\n"); 02536 return 0; 02537 } 02538 c = copy; 02539 02540 while((piece = strsep(&c, ","))) { 02541 if (sscanf(piece, "%d-%d", &start, &finish) == 2) { 02542 /* Range */ 02543 } else if (sscanf(piece, "%d", &start)) { 02544 /* Just one */ 02545 finish = start; 02546 } else { 02547 ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'. Using '0'\n", s,piece); 02548 return 0; 02549 } 02550 for (x=start;x<=finish;x++) { 02551 if ((x > 31) || (x < 0)) { 02552 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 31)\n", x); 02553 } else 02554 group |= (1 << x); 02555 } 02556 } 02557 return group; 02558 } |
|
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 chan->zombie=1; 00634 ast_mutex_unlock(&chan->lock); 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 1201 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.
01202 { 01203 int res = -1; 01204 /* Stop if we're a zombie or need a soft hangup */ 01205 if (chan->zombie || ast_check_hangup(chan)) 01206 return -1; 01207 ast_mutex_lock(&chan->lock); 01208 if (chan->pvt->indicate) 01209 res = chan->pvt->indicate(chan, condition); 01210 ast_mutex_unlock(&chan->lock); 01211 if (!chan->pvt->indicate || res) { 01212 /* 01213 * Device does not support (that) indication, lets fake 01214 * it by doing our own tone generation. (PM2002) 01215 */ 01216 if (condition >= 0) { 01217 const struct tone_zone_sound *ts = NULL; 01218 switch (condition) { 01219 case AST_CONTROL_RINGING: 01220 ts = ast_get_indication_tone(chan->zone, "ring"); 01221 break; 01222 case AST_CONTROL_BUSY: 01223 ts = ast_get_indication_tone(chan->zone, "busy"); 01224 break; 01225 case AST_CONTROL_CONGESTION: 01226 ts = ast_get_indication_tone(chan->zone, "congestion"); 01227 break; 01228 } 01229 if (ts && ts->data[0]) { 01230 ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition); 01231 ast_playtones_start(chan,0,ts->data, 1); 01232 res = 0; 01233 } else if (condition == AST_CONTROL_PROGRESS) { 01234 /* ast_playtones_stop(chan); */ 01235 } else { 01236 /* not handled */ 01237 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name); 01238 res = -1; 01239 } 01240 } 01241 else ast_playtones_stop(chan); 01242 } 01243 return res; 01244 } |
|
Search the Channels by Name.
Definition at line 1681 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().
01682 { 01683 char name[AST_CHANNEL_NAME] = ""; 01684 char *cut; 01685 struct ast_channel *chan; 01686 01687 chan = ast_channel_walk(NULL); 01688 while (chan) { 01689 strncpy(name, chan->name, sizeof(name)-1); 01690 cut = strchr(name,'-'); 01691 if (cut) 01692 *cut = 0; 01693 if (!strcmp(name, device)) 01694 return AST_DEVICE_INUSE; 01695 chan = ast_channel_walk(chan); 01696 } 01697 return AST_DEVICE_UNKNOWN; 01698 } |
|
Definition at line 1333 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().
01334 { 01335 struct ast_frame a = { AST_FRAME_VOICE }; 01336 char nothing[128]; 01337 /* Send an empty audio frame to get things moving */ 01338 if (chan->_state != AST_STATE_UP) { 01339 ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name); 01340 a.subclass = chan->pvt->rawwriteformat; 01341 a.data = nothing + AST_FRIENDLY_OFFSET; 01342 if (ast_write(chan, &a)) 01343 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name); 01344 } 01345 return 0; 01346 } |
|
Reads a frame.
Definition at line 1021 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().
01022 { 01023 struct ast_frame *f = NULL; 01024 int blah; 01025 #ifdef ZAPTEL_OPTIMIZATIONS 01026 int (*func)(void *); 01027 void *data; 01028 #endif 01029 static struct ast_frame null_frame = 01030 { 01031 AST_FRAME_NULL, 01032 }; 01033 01034 ast_mutex_lock(&chan->lock); 01035 if (chan->masq) { 01036 if (ast_do_masquerade(chan)) { 01037 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 01038 f = NULL; 01039 } else 01040 f = &null_frame; 01041 ast_mutex_unlock(&chan->lock); 01042 return f; 01043 } 01044 01045 /* Stop if we're a zombie or need a soft hangup */ 01046 if (chan->zombie || ast_check_hangup(chan)) { 01047 if (chan->generator) 01048 ast_deactivate_generator(chan); 01049 ast_mutex_unlock(&chan->lock); 01050 return NULL; 01051 } 01052 01053 if (!chan->deferdtmf && strlen(chan->dtmfq)) { 01054 /* We have DTMF that has been deferred. Return it now */ 01055 chan->dtmff.frametype = AST_FRAME_DTMF; 01056 chan->dtmff.subclass = chan->dtmfq[0]; 01057 /* Drop first digit */ 01058 memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1); 01059 ast_mutex_unlock(&chan->lock); 01060 return &chan->dtmff; 01061 } 01062 01063 /* Read and ignore anything on the alertpipe, but read only 01064 one sizeof(blah) per frame that we send from it */ 01065 if (chan->pvt->alertpipe[0] > -1) { 01066 read(chan->pvt->alertpipe[0], &blah, sizeof(blah)); 01067 } 01068 #ifdef ZAPTEL_OPTIMIZATIONS 01069 if ((chan->timingfd > -1) && (chan->fdno == AST_MAX_FDS - 2) && chan->exception) { 01070 chan->exception = 0; 01071 blah = -1; 01072 ioctl(chan->timingfd, ZT_TIMERACK, &blah); 01073 func = chan->timingfunc; 01074 data = chan->timingdata; 01075 ast_mutex_unlock(&chan->lock); 01076 if (func) { 01077 #if 0 01078 ast_log(LOG_DEBUG, "Calling private function\n"); 01079 #endif 01080 func(data); 01081 } else { 01082 blah = 0; 01083 ast_mutex_lock(&chan->lock); 01084 ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah); 01085 chan->timingdata = NULL; 01086 ast_mutex_unlock(&chan->lock); 01087 } 01088 f = &null_frame; 01089 return f; 01090 } 01091 #endif 01092 /* Check for pending read queue */ 01093 if (chan->pvt->readq) { 01094 f = chan->pvt->readq; 01095 chan->pvt->readq = f->next; 01096 /* Interpret hangup and return NULL */ 01097 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) { 01098 ast_frfree(f); 01099 f = NULL; 01100 } 01101 } else { 01102 chan->blocker = pthread_self(); 01103 if (chan->exception) { 01104 if (chan->pvt->exception) 01105 f = chan->pvt->exception(chan); 01106 else { 01107 ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name); 01108 f = &null_frame; 01109 } 01110 /* Clear the exception flag */ 01111 chan->exception = 0; 01112 } else 01113 if (chan->pvt->read) 01114 f = chan->pvt->read(chan); 01115 else 01116 ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name); 01117 } 01118 01119 01120 if (f && (f->frametype == AST_FRAME_VOICE)) { 01121 if (!(f->subclass & chan->nativeformats)) { 01122 /* This frame can't be from the current native formats -- drop it on the 01123 floor */ 01124 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)); 01125 ast_frfree(f); 01126 f = &null_frame; 01127 } else { 01128 if (chan->monitor && chan->monitor->read_stream ) { 01129 #ifndef MONITOR_CONSTANT_DELAY 01130 int jump = chan->outsmpl - chan->insmpl - 2 * f->samples; 01131 if (jump >= 0) { 01132 if (ast_seekstream(chan->monitor->read_stream, jump + f->samples, SEEK_FORCECUR) == -1) 01133 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 01134 chan->insmpl += jump + 2 * f->samples; 01135 } else 01136 chan->insmpl+= f->samples; 01137 #else 01138 int jump = chan->outsmpl - chan->insmpl; 01139 if (jump - MONITOR_DELAY >= 0) { 01140 if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1) 01141 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 01142 chan->insmpl += jump; 01143 } else 01144 chan->insmpl += f->samples; 01145 #endif 01146 if (ast_writestream(chan->monitor->read_stream, f) < 0) 01147 ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n"); 01148 } 01149 if (chan->pvt->readtrans) { 01150 f = ast_translate(chan->pvt->readtrans, f, 1); 01151 if (!f) 01152 f = &null_frame; 01153 } 01154 } 01155 } 01156 01157 /* Make sure we always return NULL in the future */ 01158 if (!f) { 01159 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01160 if (chan->generator) 01161 ast_deactivate_generator(chan); 01162 /* End the CDR if appropriate */ 01163 if (chan->cdr) 01164 ast_cdr_end(chan->cdr); 01165 } else if (chan->deferdtmf && f->frametype == AST_FRAME_DTMF) { 01166 if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2) 01167 chan->dtmfq[strlen(chan->dtmfq)] = f->subclass; 01168 else 01169 ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name); 01170 f = &null_frame; 01171 } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_ANSWER)) { 01172 /* Answer the CDR */ 01173 ast_setstate(chan, AST_STATE_UP); 01174 ast_cdr_answer(chan->cdr); 01175 } 01176 ast_mutex_unlock(&chan->lock); 01177 01178 /* Run any generator sitting on the line */ 01179 if (f && (f->frametype == AST_FRAME_VOICE) && chan->generatordata) { 01180 /* Mask generator data temporarily */ 01181 void *tmp; 01182 int res; 01183 tmp = chan->generatordata; 01184 chan->generatordata = NULL; 01185 res = chan->generator->generate(chan, tmp, f->datalen, f->samples); 01186 chan->generatordata = tmp; 01187 if (res) { 01188 ast_log(LOG_DEBUG, "Auto-deactivating generator\n"); 01189 ast_deactivate_generator(chan); 01190 } 01191 } 01192 if (chan->fin & 0x80000000) 01193 ast_frame_dump(chan->name, f, "<<"); 01194 if ((chan->fin & 0x7fffffff) == 0x7fffffff) 01195 chan->fin &= 0x80000000; 01196 else 01197 chan->fin++; 01198 return f; 01199 } |
|
Reads multiple digits.
Definition at line 1774 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().
01775 { 01776 int pos=0; 01777 int to = ftimeout; 01778 char d; 01779 /* XXX Merge with full version? XXX */ 01780 /* Stop if we're a zombie or need a soft hangup */ 01781 if (c->zombie || ast_check_hangup(c)) 01782 return -1; 01783 if (!len) 01784 return -1; 01785 do { 01786 if (c->stream) { 01787 d = ast_waitstream(c, AST_DIGIT_ANY); 01788 ast_stopstream(c); 01789 usleep(1000); 01790 if (!d) 01791 d = ast_waitfordigit(c, to); 01792 } else { 01793 d = ast_waitfordigit(c, to); 01794 } 01795 if (d < 0) 01796 return -1; 01797 if (d == 0) { 01798 s[pos]='\0'; 01799 return 1; 01800 } 01801 if (!strchr(enders, d)) 01802 s[pos++] = d; 01803 if (strchr(enders, d) || (pos >= len)) { 01804 s[pos]='\0'; 01805 return 0; 01806 } 01807 to = timeout; 01808 } while(1); 01809 /* Never reached */ 01810 return 0; 01811 } |
|
Definition at line 1813 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().
01814 { 01815 int pos=0; 01816 int to = ftimeout; 01817 char d; 01818 /* Stop if we're a zombie or need a soft hangup */ 01819 if (c->zombie || ast_check_hangup(c)) 01820 return -1; 01821 if (!len) 01822 return -1; 01823 do { 01824 if (c->stream) { 01825 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd); 01826 ast_stopstream(c); 01827 usleep(1000); 01828 if (!d) 01829 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 01830 } else { 01831 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 01832 } 01833 if (d < 0) 01834 return -1; 01835 if (d == 0) { 01836 s[pos]='\0'; 01837 return 1; 01838 } 01839 if (d == 1) { 01840 s[pos]='\0'; 01841 return 2; 01842 } 01843 if (!strchr(enders, d)) 01844 s[pos++] = d; 01845 if (strchr(enders, d) || (pos >= len)) { 01846 s[pos]='\0'; 01847 return 0; 01848 } 01849 to = timeout; 01850 } while(1); 01851 /* Never reached */ 01852 return 0; 01853 } |
|
Receives a text character from a channel.
Definition at line 1246 of file channel.c. References ast_check_hangup(), AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_TEXT, ast_frfree(), ast_read(), and ast_waitfor().
01247 { 01248 int res,ourto,c; 01249 struct ast_frame *f; 01250 01251 ourto = timeout; 01252 for(;;) 01253 { 01254 if (ast_check_hangup(chan)) return -1; 01255 res = ast_waitfor(chan,ourto); 01256 if (res <= 0) /* if timeout */ 01257 { 01258 return 0; 01259 } 01260 ourto = res; 01261 f = ast_read(chan); 01262 if (f == NULL) return -1; /* if hangup */ 01263 if ((f->frametype == AST_FRAME_CONTROL) && 01264 (f->subclass == AST_CONTROL_HANGUP)) return -1; /* if hangup */ 01265 if (f->frametype == AST_FRAME_TEXT) /* if a text frame */ 01266 { 01267 c = *((char *)f->data); /* get the data */ 01268 ast_frfree(f); 01269 return(c); 01270 } 01271 ast_frfree(f); 01272 } 01273 } |
|
Requests a channel.
Definition at line 1636 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, and ast_channel::uniqueid. Referenced by __ast_request_and_dial().
01637 { 01638 struct chanlist *chan; 01639 struct ast_channel *c = NULL; 01640 int capabilities; 01641 int fmt; 01642 int res; 01643 if (ast_mutex_lock(&chlock)) { 01644 ast_log(LOG_WARNING, "Unable to lock channel list\n"); 01645 return NULL; 01646 } 01647 chan = backends; 01648 while(chan) { 01649 if (!strcasecmp(type, chan->type)) { 01650 capabilities = chan->capabilities; 01651 fmt = format; 01652 res = ast_translator_best_choice(&fmt, &capabilities); 01653 if (res < 0) { 01654 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->capabilities, format); 01655 ast_mutex_unlock(&chlock); 01656 return NULL; 01657 } 01658 ast_mutex_unlock(&chlock); 01659 if (chan->requester) 01660 c = chan->requester(type, capabilities, data); 01661 if (c) { 01662 if (c->_state == AST_STATE_DOWN) { 01663 manager_event(EVENT_FLAG_CALL, "Newchannel", 01664 "Channel: %s\r\n" 01665 "State: %s\r\n" 01666 "Callerid: %s\r\n" 01667 "Uniqueid: %s\r\n", 01668 c->name, ast_state2str(c->_state), c->callerid ? c->callerid : "<unknown>", c->uniqueid); 01669 } 01670 } 01671 return c; 01672 } 01673 chan = chan->next; 01674 } 01675 if (!chan) 01676 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type); 01677 ast_mutex_unlock(&chlock); 01678 return c; 01679 } |
|
Definition at line 1631 of file channel.c. References __ast_request_and_dial().
01632 { 01633 return __ast_request_and_dial(type, format, data, timeout, outstate, callerid, NULL); 01634 } |
|
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 1275 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.
01276 { 01277 int res = 0; 01278 /* Stop if we're a zombie or need a soft hangup */ 01279 if (chan->zombie || ast_check_hangup(chan)) 01280 return -1; 01281 CHECK_BLOCKING(chan); 01282 if (chan->pvt->send_text) 01283 res = chan->pvt->send_text(chan, text); 01284 chan->blocking = 0; 01285 return res; 01286 } |
|
Definition at line 2162 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().
02163 { 02164 if (chan->callerid) 02165 free(chan->callerid); 02166 if (anitoo && chan->ani) 02167 free(chan->ani); 02168 if (callerid) { 02169 chan->callerid = strdup(callerid); 02170 if (anitoo) 02171 chan->ani = strdup(callerid); 02172 } else { 02173 chan->callerid = NULL; 02174 if (anitoo) 02175 chan->ani = NULL; 02176 } 02177 if (chan->cdr) 02178 ast_cdr_setcid(chan->cdr, chan); 02179 manager_event(EVENT_FLAG_CALL, "Newcallerid", 02180 "Channel: %s\r\n" 02181 "Callerid: %s\r\n" 02182 "Uniqueid: %s\r\n", 02183 chan->name, chan->callerid ? 02184 chan->callerid : "<Unknown>", 02185 chan->uniqueid); 02186 } |
|
Sets read format on channel chan.
Definition at line 1497 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().
01498 { 01499 int fmt; 01500 int native; 01501 int res; 01502 01503 native = chan->nativeformats; 01504 fmt = fmts; 01505 /* Find a translation path from the native read format to one of the user's read formats */ 01506 res = ast_translator_best_choice(&fmt, &native); 01507 if (res < 0) { 01508 ast_log(LOG_NOTICE, "Unable to find a path from %s to %s\n", 01509 ast_getformatname(chan->nativeformats), ast_getformatname(fmts)); 01510 return -1; 01511 } 01512 01513 /* Now we have a good choice for both. We'll write using our native format. */ 01514 chan->pvt->rawreadformat = native; 01515 /* User perspective is fmt */ 01516 chan->readformat = fmt; 01517 /* Free any read translation we have right now */ 01518 if (chan->pvt->readtrans) 01519 ast_translator_free_path(chan->pvt->readtrans); 01520 /* Build a translation path from the raw read format to the user reading format */ 01521 chan->pvt->readtrans = ast_translator_build_path(chan->readformat, chan->pvt->rawreadformat); 01522 if (option_debug) 01523 ast_log(LOG_DEBUG, "Set channel %s to read format %s\n", 01524 chan->name, ast_getformatname(chan->readformat)); 01525 return 0; 01526 } |
|
Sets write format on channel chan.
Definition at line 1467 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().
01468 { 01469 int fmt; 01470 int native; 01471 int res; 01472 01473 native = chan->nativeformats; 01474 fmt = fmts; 01475 01476 res = ast_translator_best_choice(&native, &fmt); 01477 if (res < 0) { 01478 ast_log(LOG_NOTICE, "Unable to find a path from %s to %s\n", 01479 ast_getformatname(fmts), ast_getformatname(chan->nativeformats)); 01480 return -1; 01481 } 01482 01483 /* Now we have a good choice for both. We'll write using our native format. */ 01484 chan->pvt->rawwriteformat = native; 01485 /* User perspective is fmt */ 01486 chan->writeformat = fmt; 01487 /* Free any write translation we have right now */ 01488 if (chan->pvt->writetrans) 01489 ast_translator_free_path(chan->pvt->writetrans); 01490 /* Build a translation path from the user write format to the raw writing format */ 01491 chan->pvt->writetrans = ast_translator_build_path(chan->pvt->rawwriteformat, chan->writeformat); 01492 if (option_debug) 01493 ast_log(LOG_DEBUG, "Set channel %s to write format %s\n", chan->name, ast_getformatname(chan->writeformat)); 01494 return 0; 01495 } |
|
Definition at line 974 of file channel.c. References ast_log(), LOG_DEBUG, ast_channel::timingdata, ast_channel::timingfd, and ast_channel::timingfunc. Referenced by ast_closestream().
00975 { 00976 int res = -1; 00977 #ifdef ZAPTEL_OPTIMIZATIONS 00978 if (c->timingfd > -1) { 00979 if (!func) { 00980 samples = 0; 00981 data = 0; 00982 } 00983 ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples); 00984 res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples); 00985 c->timingfunc = func; 00986 c->timingdata = data; 00987 } 00988 #endif 00989 return res; 00990 } |
|
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 2508 of file channel.c. References ast_frfree(), ast_read(), ast_tonepair_start(), ast_waitfor(), and ast_channel::generatordata.
02509 { 02510 struct ast_frame *f; 02511 int res; 02512 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol))) 02513 return res; 02514 02515 /* Give us some wiggle room */ 02516 while(chan->generatordata && (ast_waitfor(chan, 100) >= 0)) { 02517 f = ast_read(chan); 02518 if (f) 02519 ast_frfree(f); 02520 else 02521 return -1; 02522 } 02523 return 0; 02524 } |
|
Start a tone going Definition at line 2488 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().
02489 { 02490 struct tonepair_def d = { 0, }; 02491 d.freq1 = freq1; 02492 d.freq2 = freq2; 02493 d.duration = duration; 02494 if (vol < 1) 02495 d.vol = 8192; 02496 else 02497 d.vol = vol; 02498 if (ast_activate_generator(chan, &tonepair, &d)) 02499 return -1; 02500 return 0; 02501 } |
|
Stop a tone from playing Definition at line 2503 of file channel.c. References ast_deactivate_generator().
02504 { 02505 ast_deactivate_generator(chan); 02506 } |
|
Definition at line 1754 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.
01755 { 01756 /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 01757 If the remote end does not answer within the timeout, then do NOT hang up, but 01758 return anyway. */ 01759 int res = -1; 01760 /* Stop if we're a zombie or need a soft hangup */ 01761 ast_mutex_lock(&chan->lock); 01762 if (!chan->zombie && !ast_check_hangup(chan)) { 01763 if (chan->pvt->transfer) { 01764 res = chan->pvt->transfer(chan, dest); 01765 if (!res) 01766 res = 1; 01767 } else 01768 res = 0; 01769 } 01770 ast_mutex_unlock(&chan->lock); 01771 return res; 01772 } |
|
Wait for input on a channel.
Definition at line 933 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().
00934 { 00935 struct ast_channel *chan; 00936 int oldms = ms; 00937 chan = ast_waitfor_n(&c, 1, &ms); 00938 if (ms < 0) { 00939 if (oldms < 0) 00940 return 0; 00941 else 00942 return -1; 00943 } 00944 return ms; 00945 } |
|
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 928 of file channel.c. References ast_waitfor_nandfds(). Referenced by ast_channel_bridge(), ast_rtp_bridge(), and ast_waitfor().
00929 { 00930 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms); 00931 } |
|
Waits for input on an fd. This version works on fd's only. Be careful with it. Definition at line 760 of file channel.c.
00761 { 00762 /* Wait for x amount of time on a file descriptor to have input. */ 00763 struct timeval tv; 00764 fd_set rfds, efds; 00765 int res; 00766 int x, max=-1; 00767 int winner = -1; 00768 00769 tv.tv_sec = *ms / 1000; 00770 tv.tv_usec = (*ms % 1000) * 1000; 00771 FD_ZERO(&rfds); 00772 FD_ZERO(&efds); 00773 for (x=0;x<n;x++) { 00774 if (fds[x] > -1) { 00775 FD_SET(fds[x], &rfds); 00776 FD_SET(fds[x], &efds); 00777 if (fds[x] > max) 00778 max = fds[x]; 00779 } 00780 } 00781 if (*ms >= 0) 00782 res = ast_select(max + 1, &rfds, NULL, &efds, &tv); 00783 else 00784 res = ast_select(max + 1, &rfds, NULL, &efds, NULL); 00785 00786 if (res < 0) { 00787 /* Simulate a timeout if we were interrupted */ 00788 if (errno != EINTR) 00789 *ms = -1; 00790 else 00791 *ms = 0; 00792 return -1; 00793 } 00794 00795 for (x=0;x<n;x++) { 00796 if ((fds[x] > -1) && (FD_ISSET(fds[x], &rfds) || FD_ISSET(fds[x], &efds)) && (winner < 0)) { 00797 if (exception) 00798 *exception = FD_ISSET(fds[x], &efds); 00799 winner = fds[x]; 00800 } 00801 } 00802 *ms = tv.tv_sec * 1000 + tv.tv_usec / 1000; 00803 return winner; 00804 } |
|
Waits for activity on a group of channels.
Definition at line 806 of file channel.c. References ast_log(), AST_MAX_FDS, ast_mutex_lock, ast_mutex_unlock, AST_SOFTHANGUP_TIMEOUT, ast_channel::blocking, CHECK_BLOCKING, ast_channel::fds, LOG_WARNING, ast_channel::masq, and ast_channel::whentohangup. Referenced by ast_waitfor_n(), ast_waitfordigit_full(), and ast_waitstream_full().
00808 { 00809 /* Wait for x amount of time on a file descriptor to have input. */ 00810 struct timeval tv; 00811 fd_set rfds, efds; 00812 int res; 00813 int x, y, max=-1; 00814 time_t now = 0; 00815 long whentohangup = 0, havewhen = 0, diff; 00816 struct ast_channel *winner = NULL; 00817 if (outfd) 00818 *outfd = -99999; 00819 if (exception) 00820 *exception = 0; 00821 00822 /* Perform any pending masquerades */ 00823 for (x=0;x<n;x++) { 00824 ast_mutex_lock(&c[x]->lock); 00825 if (c[x]->whentohangup) { 00826 if (!havewhen) 00827 time(&now); 00828 diff = c[x]->whentohangup - now; 00829 if (!havewhen || (diff < whentohangup)) { 00830 havewhen++; 00831 whentohangup = diff; 00832 } 00833 } 00834 if (c[x]->masq) { 00835 if (ast_do_masquerade(c[x])) { 00836 ast_log(LOG_WARNING, "Masquerade failed\n"); 00837 *ms = -1; 00838 ast_mutex_unlock(&c[x]->lock); 00839 return NULL; 00840 } 00841 } 00842 ast_mutex_unlock(&c[x]->lock); 00843 } 00844 00845 tv.tv_sec = *ms / 1000; 00846 tv.tv_usec = (*ms % 1000) * 1000; 00847 00848 if (havewhen) { 00849 if ((*ms < 0) || (whentohangup * 1000 < *ms)) { 00850 tv.tv_sec = whentohangup; 00851 tv.tv_usec = 0; 00852 } 00853 } 00854 FD_ZERO(&rfds); 00855 FD_ZERO(&efds); 00856 00857 for (x=0;x<n;x++) { 00858 for (y=0;y<AST_MAX_FDS;y++) { 00859 if (c[x]->fds[y] > -1) { 00860 FD_SET(c[x]->fds[y], &rfds); 00861 FD_SET(c[x]->fds[y], &efds); 00862 if (c[x]->fds[y] > max) 00863 max = c[x]->fds[y]; 00864 } 00865 } 00866 CHECK_BLOCKING(c[x]); 00867 } 00868 for (x=0;x<nfds; x++) { 00869 FD_SET(fds[x], &rfds); 00870 FD_SET(fds[x], &efds); 00871 if (fds[x] > max) 00872 max = fds[x]; 00873 } 00874 if ((*ms >= 0) || (havewhen)) 00875 res = ast_select(max + 1, &rfds, NULL, &efds, &tv); 00876 else 00877 res = ast_select(max + 1, &rfds, NULL, &efds, NULL); 00878 00879 if (res < 0) { 00880 for (x=0;x<n;x++) 00881 c[x]->blocking = 0; 00882 /* Simulate a timeout if we were interrupted */ 00883 if (errno != EINTR) 00884 *ms = -1; 00885 else { 00886 /* Just an interrupt */ 00887 #if 0 00888 *ms = 0; 00889 #endif 00890 } 00891 return NULL; 00892 } 00893 00894 if (havewhen) 00895 time(&now); 00896 for (x=0;x<n;x++) { 00897 c[x]->blocking = 0; 00898 if (havewhen && c[x]->whentohangup && (now > c[x]->whentohangup)) { 00899 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 00900 if (!winner) 00901 winner = c[x]; 00902 } 00903 for (y=0;y<AST_MAX_FDS;y++) { 00904 if (c[x]->fds[y] > -1) { 00905 if ((FD_ISSET(c[x]->fds[y], &rfds) || FD_ISSET(c[x]->fds[y], &efds)) && !winner) { 00906 /* Set exception flag if appropriate */ 00907 if (FD_ISSET(c[x]->fds[y], &efds)) 00908 c[x]->exception = 1; 00909 c[x]->fdno = y; 00910 winner = c[x]; 00911 } 00912 } 00913 } 00914 } 00915 for (x=0;x<nfds;x++) { 00916 if ((FD_ISSET(fds[x], &rfds) || FD_ISSET(fds[x], &efds)) && !winner) { 00917 if (outfd) 00918 *outfd = fds[x]; 00919 if (FD_ISSET(fds[x], &efds) && exception) 00920 *exception = 1; 00921 winner = NULL; 00922 } 00923 } 00924 *ms = tv.tv_sec * 1000 + tv.tv_usec / 1000; 00925 return winner; 00926 } |
|
Waits for a digit.
Definition at line 947 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().
00948 { 00949 /* XXX Should I be merged with waitfordigit_full XXX */ 00950 struct ast_frame *f; 00951 char result = 0; 00952 /* Stop if we're a zombie or need a soft hangup */ 00953 if (c->zombie || ast_check_hangup(c)) 00954 return -1; 00955 /* Wait for a digit, no more than ms milliseconds total. */ 00956 while(ms && !result) { 00957 ms = ast_waitfor(c, ms); 00958 if (ms < 0) /* Error */ 00959 result = -1; 00960 else if (ms > 0) { 00961 /* Read something */ 00962 f = ast_read(c); 00963 if (f) { 00964 if (f->frametype == AST_FRAME_DTMF) 00965 result = f->subclass; 00966 ast_frfree(f); 00967 } else 00968 result = -1; 00969 } 00970 } 00971 return result; 00972 } |
|
Definition at line 991 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().
00992 { 00993 struct ast_frame *f; 00994 char result = 0; 00995 struct ast_channel *rchan; 00996 int outfd; 00997 /* Stop if we're a zombie or need a soft hangup */ 00998 if (c->zombie || ast_check_hangup(c)) 00999 return -1; 01000 /* Wait for a digit, no more than ms milliseconds total. */ 01001 while(ms && !result) { 01002 rchan = ast_waitfor_nandfds(&c, 1, &audio, (audio > -1) ? 1 : 0, NULL, &outfd, &ms); 01003 if ((!rchan) && (outfd < 0) && (ms)) /* Error */ 01004 result = -1; 01005 else if (outfd > -1) { 01006 result = 1; 01007 } else if (rchan) { 01008 /* Read something */ 01009 f = ast_read(c); 01010 if (f) { 01011 if (f->frametype == AST_FRAME_DTMF) 01012 result = f->subclass; 01013 ast_frfree(f); 01014 } else 01015 result = -1; 01016 } 01017 } 01018 return result; 01019 } |
|
Write a frame to a channel.
Definition at line 1359 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().
01360 { 01361 int res = -1; 01362 struct ast_frame *f = NULL; 01363 /* Stop if we're a zombie or need a soft hangup */ 01364 ast_mutex_lock(&chan->lock); 01365 if (chan->zombie || ast_check_hangup(chan)) { 01366 ast_mutex_unlock(&chan->lock); 01367 return -1; 01368 } 01369 /* Handle any pending masquerades */ 01370 if (chan->masq) { 01371 if (ast_do_masquerade(chan)) { 01372 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 01373 ast_mutex_unlock(&chan->lock); 01374 return -1; 01375 } 01376 } 01377 if (chan->masqr) { 01378 ast_mutex_unlock(&chan->lock); 01379 return 0; 01380 } 01381 if (chan->generatordata) { 01382 if (chan->writeinterrupt) 01383 ast_deactivate_generator(chan); 01384 else { 01385 ast_mutex_unlock(&chan->lock); 01386 return 0; 01387 } 01388 } 01389 if (chan->fout & 0x80000000) 01390 ast_frame_dump(chan->name, fr, ">>"); 01391 CHECK_BLOCKING(chan); 01392 switch(fr->frametype) { 01393 case AST_FRAME_CONTROL: 01394 /* XXX Interpret control frames XXX */ 01395 ast_log(LOG_WARNING, "Don't know how to handle control frames yet\n"); 01396 break; 01397 case AST_FRAME_DTMF: 01398 chan->blocking = 0; 01399 ast_mutex_unlock(&chan->lock); 01400 res = do_senddigit(chan,fr->subclass); 01401 ast_mutex_lock(&chan->lock); 01402 CHECK_BLOCKING(chan); 01403 break; 01404 case AST_FRAME_TEXT: 01405 if (chan->pvt->send_text) 01406 res = chan->pvt->send_text(chan, (char *) fr->data); 01407 break; 01408 case AST_FRAME_VIDEO: 01409 /* XXX Handle translation of video codecs one day XXX */ 01410 if (chan->pvt->write_video) 01411 res = chan->pvt->write_video(chan, fr); 01412 else 01413 res = 0; 01414 break; 01415 default: 01416 if (chan->pvt->write) { 01417 if (chan->pvt->writetrans) { 01418 f = ast_translate(chan->pvt->writetrans, fr, 0); 01419 } else 01420 f = fr; 01421 if (f) { 01422 res = chan->pvt->write(chan, f); 01423 if( chan->monitor && 01424 chan->monitor->write_stream && 01425 f && ( f->frametype == AST_FRAME_VOICE ) ) { 01426 #ifndef MONITOR_CONSTANT_DELAY 01427 int jump = chan->insmpl - chan->outsmpl - 2 * f->samples; 01428 if (jump >= 0) { 01429 if (ast_seekstream(chan->monitor->write_stream, jump + f->samples, SEEK_FORCECUR) == -1) 01430 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 01431 chan->outsmpl += jump + 2 * f->samples; 01432 } else 01433 chan->outsmpl += f->samples; 01434 #else 01435 int jump = chan->insmpl - chan->outsmpl; 01436 if (jump - MONITOR_DELAY >= 0) { 01437 if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1) 01438 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 01439 chan->outsmpl += jump; 01440 } else 01441 chan->outsmpl += f->samples; 01442 #endif 01443 if (ast_writestream(chan->monitor->write_stream, f) < 0) 01444 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n"); 01445 } 01446 } else 01447 res = 0; 01448 } 01449 } 01450 if (f && (f != fr)) 01451 ast_frfree(f); 01452 chan->blocking = 0; 01453 /* Consider a write failure to force a soft hangup */ 01454 if (res < 0) 01455 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01456 else { 01457 if ((chan->fout & 0x7fffffff) == 0x7fffffff) 01458 chan->fout &= 0x80000000; 01459 else 01460 chan->fout++; 01461 chan->fout++; 01462 } 01463 ast_mutex_unlock(&chan->lock); 01464 return res; 01465 } |
|
Write video frame to a channel.
Definition at line 1348 of file channel.c. References ast_write(), ast_channel::pvt, and ast_channel_pvt::write_video.
01349 { 01350 int res; 01351 if (!chan->pvt->write_video) 01352 return 0; 01353 res = ast_write(chan, fr); 01354 if (!res) 01355 res = 1; 01356 return res; 01357 } |