#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 |
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_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_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) |
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 577 of file channel.h. Referenced by ast_channel_bridge(), and ast_rtp_bridge(). |
|
Report DTMF on channel 1 Definition at line 579 of file channel.h. Referenced by ast_channel_bridge(), and ast_rtp_bridge(). |
|
Ignore all signal frames except NULL Definition at line 585 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 274 of file channel.h. Referenced by ast_parse_device_state(). |
|
Device is invalid Definition at line 278 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 270 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 241 of file channel.h. Referenced by ast_async_goto(), and ast_pbx_run(). |
|
Definition at line 240 of file channel.h. Referenced by ast_dsp_process(), ast_queue_hangup(), ast_read(), and ast_write(). |
|
|
|
Definition at line 242 of file channel.h. Referenced by ast_begin_shutdown(). |
|
Definition at line 243 of file channel.h. Referenced by ast_check_hangup(), and ast_pbx_run(). |
|
Line is busy Definition at line 263 of file channel.h. Referenced by ast_state2str(). |
|
Digits (or equivalent) have been dialed Definition at line 255 of file channel.h. Referenced by ast_state2str(). |
|
Channel is down and available Definition at line 249 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 253 of file channel.h. Referenced by ast_state2str(). |
|
Channel is down, but reserved Definition at line 251 of file channel.h. Referenced by ast_state2str(). |
|
Line is ringing Definition at line 257 of file channel.h. Referenced by ast_answer(), and ast_state2str(). |
|
Remote end is ringing Definition at line 259 of file channel.h. Referenced by ast_answer(), and ast_state2str(). |
|
Line is up Definition at line 261 of file channel.h. Referenced by ast_answer(), ast_cdr_init(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_prod(), ast_read(), ast_request_and_dial(), and ast_state2str(). |
|
Definition at line 773 of file channel.h. Referenced by ast_sendtext(), ast_waitfor_nandfds(), and ast_write(). |
|
Definition at line 770 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(), ast_openstream(), and ast_openvstream(). |
|
Activate a given generator Definition at line 739 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().
00740 { 00741 if (chan->generatordata) { 00742 chan->generator->release(chan, chan->generatordata); 00743 chan->generatordata = NULL; 00744 } 00745 ast_prod(chan); 00746 if ((chan->generatordata = gen->alloc(chan, params))) { 00747 chan->generator = gen; 00748 } else { 00749 return -1; 00750 } 00751 return 0; 00752 } |
|
Returns number of active/allocated channels Definition at line 109 of file channel.c. References ast_mutex_lock, ast_mutex_unlock, channels, and ast_channel::next.
00110 { 00111 struct ast_channel *c; 00112 int cnt = 0; 00113 ast_mutex_lock(&chlock); 00114 c = channels; 00115 while(c) { 00116 cnt++; 00117 c = c->next; 00118 } 00119 ast_mutex_unlock(&chlock); 00120 return cnt; 00121 } |
|
Answer a ringing call.
Definition at line 703 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.
00704 { 00705 int res = 0; 00706 /* Stop if we're a zombie or need a soft hangup */ 00707 if (chan->zombie || ast_check_hangup(chan)) 00708 return -1; 00709 switch(chan->_state) { 00710 case AST_STATE_RINGING: 00711 case AST_STATE_RING: 00712 ast_mutex_lock(&chan->lock); 00713 if (chan->pvt->answer) 00714 res = chan->pvt->answer(chan); 00715 ast_mutex_unlock(&chan->lock); 00716 ast_setstate(chan, AST_STATE_UP); 00717 if (chan->cdr) 00718 ast_cdr_answer(chan->cdr); 00719 return res; 00720 break; 00721 case AST_STATE_UP: 00722 if (chan->cdr) 00723 ast_cdr_answer(chan->cdr); 00724 break; 00725 } 00726 return 0; 00727 } |
|
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 94 of file channel.c. References ast_mutex_lock, ast_mutex_unlock, ast_softhangup(), AST_SOFTHANGUP_SHUTDOWN, and channels.
00095 { 00096 struct ast_channel *c; 00097 shutting_down = 1; 00098 if (hangup) { 00099 ast_mutex_lock(&chlock); 00100 c = channels; 00101 while(c) { 00102 ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN); 00103 c = c->next; 00104 } 00105 ast_mutex_unlock(&chlock); 00106 } 00107 } |
|
Make a call.
Definition at line 1657 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().
01658 { 01659 /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 01660 If the remote end does not answer within the timeout, then do NOT hang up, but 01661 return anyway. */ 01662 int res = -1; 01663 /* Stop if we're a zombie or need a soft hangup */ 01664 ast_mutex_lock(&chan->lock); 01665 if (!chan->zombie && !ast_check_hangup(chan)) 01666 if (chan->pvt->call) 01667 res = chan->pvt->call(chan, addr, timeout); 01668 ast_mutex_unlock(&chan->lock); 01669 return res; 01670 } |
|
Cancels an existing shutdown and returns to normal operation Definition at line 123 of file channel.c.
00124 { 00125 shutting_down = 0; 00126 } |
|
Bridge two channels together.
Definition at line 2121 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.
02122 { 02123 /* Copy voice back and forth between the two channels. Give the peer 02124 the ability to transfer calls with '#<extension' syntax. */ 02125 struct ast_channel *cs[3]; 02126 int to = -1; 02127 struct ast_frame *f; 02128 struct ast_channel *who = NULL; 02129 int res; 02130 int nativefailed=0; 02131 02132 /* Stop if we're a zombie or need a soft hangup */ 02133 if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1)) 02134 return -1; 02135 if (c0->bridge) { 02136 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 02137 c0->name, c0->bridge->name); 02138 return -1; 02139 } 02140 if (c1->bridge) { 02141 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 02142 c1->name, c1->bridge->name); 02143 return -1; 02144 } 02145 02146 /* Keep track of bridge */ 02147 c0->bridge = c1; 02148 c1->bridge = c0; 02149 cs[0] = c0; 02150 cs[1] = c1; 02151 02152 manager_event(EVENT_FLAG_CALL, "Link", 02153 "Channel1: %s\r\n" 02154 "Channel2: %s\r\n", 02155 c0->name, c1->name); 02156 02157 for (/* ever */;;) { 02158 /* Stop if we're a zombie or need a soft hangup */ 02159 if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1)) { 02160 *fo = NULL; 02161 if (who) *rc = who; 02162 res = 0; 02163 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"); 02164 break; 02165 } 02166 if (c0->pvt->bridge && 02167 (c0->pvt->bridge == c1->pvt->bridge) && !nativefailed && !c0->monitor && !c1->monitor) { 02168 /* Looks like they share a bridge code */ 02169 if (option_verbose > 2) 02170 ast_verbose(VERBOSE_PREFIX_3 "Attempting native bridge of %s and %s\n", c0->name, c1->name); 02171 if (!(res = c0->pvt->bridge(c0, c1, flags, fo, rc))) { 02172 c0->bridge = NULL; 02173 c1->bridge = NULL; 02174 manager_event(EVENT_FLAG_CALL, "Unlink", 02175 "Channel1: %s\r\n" 02176 "Channel2: %s\r\n", 02177 c0->name, c1->name); 02178 ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n",c0->name ,c1->name); 02179 return 0; 02180 } 02181 /* If they return non-zero then continue on normally. Let "-2" mean don't worry about 02182 my not wanting to bridge */ 02183 if ((res != -2) && (res != -3)) 02184 ast_log(LOG_WARNING, "Private bridge between %s and %s failed\n", c0->name, c1->name); 02185 if (res != -3) nativefailed++; 02186 } 02187 02188 02189 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat)) && 02190 !(c0->generator || c1->generator)) { 02191 if (ast_channel_make_compatible(c0, c1)) { 02192 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name); 02193 manager_event(EVENT_FLAG_CALL, "Unlink", 02194 "Channel1: %s\r\n" 02195 "Channel2: %s\r\n", 02196 c0->name, c1->name); 02197 return -1; 02198 } 02199 } 02200 who = ast_waitfor_n(cs, 2, &to); 02201 if (!who) { 02202 ast_log(LOG_DEBUG, "Nobody there, continuing...\n"); 02203 continue; 02204 } 02205 f = ast_read(who); 02206 if (!f) { 02207 *fo = NULL; 02208 *rc = who; 02209 res = 0; 02210 ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name); 02211 break; 02212 } 02213 02214 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) { 02215 *fo = f; 02216 *rc = who; 02217 res = 0; 02218 ast_log(LOG_DEBUG, "Got a FRAME_CONTROL frame on channel %s\n",who->name); 02219 break; 02220 } 02221 if ((f->frametype == AST_FRAME_VOICE) || 02222 (f->frametype == AST_FRAME_TEXT) || 02223 (f->frametype == AST_FRAME_VIDEO) || 02224 (f->frametype == AST_FRAME_IMAGE) || 02225 (f->frametype == AST_FRAME_DTMF)) { 02226 if ((f->frametype == AST_FRAME_DTMF) && 02227 (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) { 02228 if ((who == c0)) { 02229 if ((flags & AST_BRIDGE_DTMF_CHANNEL_0)) { 02230 *rc = c0; 02231 *fo = f; 02232 /* Take out of conference mode */ 02233 res = 0; 02234 ast_log(LOG_DEBUG, "Got AST_BRIDGE_DTMF_CHANNEL_0 on c0 (%s)\n",c0->name); 02235 break; 02236 } else 02237 goto tackygoto; 02238 } else 02239 if ((who == c1)) { 02240 if (flags & AST_BRIDGE_DTMF_CHANNEL_1) { 02241 *rc = c1; 02242 *fo = f; 02243 res = 0; 02244 ast_log(LOG_DEBUG, "Got AST_BRIDGE_DTMF_CHANNEL_1 on c1 (%s)\n",c1->name); 02245 break; 02246 } else 02247 goto tackygoto; 02248 } 02249 } else { 02250 #if 0 02251 ast_log(LOG_DEBUG, "Read from %s\n", who->name); 02252 if (who == last) 02253 ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name); 02254 last = who; 02255 #endif 02256 tackygoto: 02257 /* Don't copy packets if there is a generator on either one, since they're 02258 not supposed to be listening anyway */ 02259 if (who == c0) 02260 ast_write(c1, f); 02261 else 02262 ast_write(c0, f); 02263 } 02264 ast_frfree(f); 02265 } else 02266 ast_frfree(f); 02267 /* Swap who gets priority */ 02268 cs[2] = cs[0]; 02269 cs[0] = cs[1]; 02270 cs[1] = cs[2]; 02271 } 02272 c0->bridge = NULL; 02273 c1->bridge = NULL; 02274 manager_event(EVENT_FLAG_CALL, "Unlink", 02275 "Channel1: %s\r\n" 02276 "Channel2: %s\r\n", 02277 c0->name, c1->name); 02278 ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n",c0->name,c1->name); 02279 return res; 02280 } |
|
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 416 of file channel.c. References ast_channel::deferdtmf.
|
|
Makes two channel formats compatible.
Definition at line 1794 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().
01795 { 01796 int peerf; 01797 int chanf; 01798 int res; 01799 peerf = peer->nativeformats; 01800 chanf = chan->nativeformats; 01801 res = ast_translator_best_choice(&peerf, &chanf); 01802 if (res < 0) { 01803 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, chan->nativeformats, peer->name, peer->nativeformats); 01804 return -1; 01805 } 01806 /* Set read format on channel */ 01807 res = ast_set_read_format(chan, peerf); 01808 if (res < 0) { 01809 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, chanf); 01810 return -1; 01811 } 01812 /* Set write format on peer channel */ 01813 res = ast_set_write_format(peer, peerf); 01814 if (res < 0) { 01815 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, peerf); 01816 return -1; 01817 } 01818 /* Now we go the other way */ 01819 peerf = peer->nativeformats; 01820 chanf = chan->nativeformats; 01821 res = ast_translator_best_choice(&chanf, &peerf); 01822 if (res < 0) { 01823 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, peer->nativeformats, chan->name, chan->nativeformats); 01824 return -1; 01825 } 01826 /* Set writeformat on channel */ 01827 res = ast_set_write_format(chan, chanf); 01828 if (res < 0) { 01829 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, chanf); 01830 return -1; 01831 } 01832 /* Set read format on peer channel */ 01833 res = ast_set_read_format(peer, chanf); 01834 if (res < 0) { 01835 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, peerf); 01836 return -1; 01837 } 01838 return 0; 01839 } |
|
Weird function made for call transfers.
Definition at line 1841 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. Referenced by ast_async_goto().
01842 { 01843 struct ast_frame null = { AST_FRAME_NULL, }; 01844 ast_log(LOG_DEBUG, "Planning to masquerade %s into the structure of %s\n", 01845 clone->name, original->name); 01846 if (original->masq) { 01847 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 01848 original->masq->name, original->name); 01849 return -1; 01850 } 01851 if (clone->masqr) { 01852 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 01853 clone->name, clone->masqr->name); 01854 return -1; 01855 } 01856 original->masq = clone; 01857 clone->masqr = original; 01858 /* XXX can't really hold the lock here, but at the same time, it' s 01859 not really safe not to XXX */ 01860 ast_queue_frame(original, &null, 0); 01861 ast_queue_frame(clone, &null, 0); 01862 ast_log(LOG_DEBUG, "Done planning to masquerade %s into the structure of %s\n", original->name, clone->name); 01863 return 0; 01864 } |
|
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 145 of file channel.c. References ast_channel_register_ex(), description(), and type.
00147 { 00148 return ast_channel_register_ex(type, description, capabilities, requester, NULL); 00149 } |
|
Definition at line 151 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().
00154 { 00155 struct chanlist *chan, *last=NULL; 00156 if (ast_mutex_lock(&chlock)) { 00157 ast_log(LOG_WARNING, "Unable to lock channel list\n"); 00158 return -1; 00159 } 00160 chan = backends; 00161 while(chan) { 00162 if (!strcasecmp(type, chan->type)) { 00163 ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", type); 00164 ast_mutex_unlock(&chlock); 00165 return -1; 00166 } 00167 last = chan; 00168 chan = chan->next; 00169 } 00170 chan = malloc(sizeof(struct chanlist)); 00171 if (!chan) { 00172 ast_log(LOG_WARNING, "Out of memory\n"); 00173 ast_mutex_unlock(&chlock); 00174 return -1; 00175 } 00176 strncpy(chan->type, type, sizeof(chan->type)-1); 00177 strncpy(chan->description, description, sizeof(chan->description)-1); 00178 chan->capabilities = capabilities; 00179 chan->requester = requester; 00180 chan->devicestate = devicestate; 00181 chan->next = NULL; 00182 if (last) 00183 last->next = chan; 00184 else 00185 backends = chan; 00186 if (option_debug) 00187 ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->type, chan->description); 00188 else if (option_verbose > 1) 00189 ast_verbose( VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->type, chan->description); 00190 ast_mutex_unlock(&chlock); 00191 return 0; 00192 } |
|
Sends HTML on given channel. Send HTML or URL on link. Returns 0 on success or -1 on failure Definition at line 1780 of file channel.c. References ast_channel::pvt, and ast_channel_pvt::send_html.
|
|
Sends a URL on a given link. Send URL on link. Returns 0 on success or -1 on failure Definition at line 1787 of file channel.c. References AST_HTML_URL, ast_channel::pvt, and ast_channel_pvt::send_html.
|
|
Sets an option on a channel.
Definition at line 2282 of file channel.c. References ast_log(), LOG_ERROR, ast_channel::pvt, and ast_channel_pvt::setoption.
02283 { 02284 int res; 02285 if (chan->pvt->setoption) { 02286 res = chan->pvt->setoption(chan, option, data, datalen); 02287 if (res < 0) 02288 return res; 02289 } else { 02290 errno = ENOSYS; 02291 return -1; 02292 } 02293 if (block) { 02294 /* XXX Implement blocking -- just wait for our option frame reply, discarding 02295 intermediate packets. XXX */ 02296 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 02297 return -1; 02298 } 02299 return 0; 02300 } |
|
Set when to hang a channel up.
Definition at line 133 of file channel.c. References ast_channel::whentohangup.
00134 { 00135 time_t myt; 00136 00137 time(&myt); 00138 if (offset) 00139 chan->whentohangup = myt + offset; 00140 else 00141 chan->whentohangup = 0; 00142 return; 00143 } |
|
Checks for HTML support on a channel. Returns 0 if channel does not support HTML or non-zero if it does Definition at line 1773 of file channel.c. References ast_channel::pvt, and ast_channel_pvt::send_html.
|
|
Undeos a defer. Undo defer. ast_read will return any dtmf characters that were queued Definition at line 426 of file channel.c. References ast_channel::deferdtmf.
00427 { 00428 if (chan) 00429 chan->deferdtmf = 0; 00430 } |
|
Unregister a channel class.
Definition at line 677 of file channel.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, backends, free, LOG_DEBUG, LOG_WARNING, ast_channel::next, chanlist::next, option_debug, ast_channel::type, and type.
00678 { 00679 struct chanlist *chan, *last=NULL; 00680 if (option_debug) 00681 ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", type); 00682 if (ast_mutex_lock(&chlock)) { 00683 ast_log(LOG_WARNING, "Unable to lock channel list\n"); 00684 return; 00685 } 00686 chan = backends; 00687 while(chan) { 00688 if (!strcasecmp(chan->type, type)) { 00689 if (last) 00690 last->next = chan->next; 00691 else 00692 backends = backends->next; 00693 free(chan); 00694 ast_mutex_unlock(&chlock); 00695 return; 00696 } 00697 last = chan; 00698 chan = chan->next; 00699 } 00700 ast_mutex_unlock(&chlock); 00701 } |
|
Browse channels in use.
Definition at line 432 of file channel.c. References ast_mutex_lock, ast_mutex_unlock, and channels. Referenced by ast_async_goto_by_name(), and ast_parse_device_state().
00433 { 00434 struct ast_channel *l, *ret=NULL; 00435 ast_mutex_lock(&chlock); 00436 l = channels; 00437 if (!prev) { 00438 ast_mutex_unlock(&chlock); 00439 return l; 00440 } 00441 while(l) { 00442 if (l == prev) 00443 ret = l->next; 00444 l = l->next; 00445 } 00446 ast_mutex_unlock(&chlock); 00447 return ret; 00448 00449 } |
|
Check to see if a channel is needing hang up.
Definition at line 68 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_sendtext(), ast_transfer(), ast_waitfordigit(), ast_waitfordigit_full(), and ast_write().
00069 { 00070 time_t myt; 00071 00072 /* if soft hangup flag, return true */ 00073 if (chan->_softhangup) return 1; 00074 /* if no private structure, return true */ 00075 if (!chan->pvt->pvt) return 1; 00076 /* if no hangup scheduled, just return here */ 00077 if (!chan->whentohangup) return 0; 00078 time(&myt); /* get current time */ 00079 /* return, if not yet */ 00080 if (chan->whentohangup > myt) return 0; 00081 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 00082 return 1; 00083 } |
|
Deactive an active generator Definition at line 729 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().
00730 { 00731 if (chan->generatordata) { 00732 chan->generator->release(chan, chan->generatordata); 00733 chan->generatordata = NULL; 00734 chan->generator = NULL; 00735 chan->writeinterrupt = 0; 00736 } 00737 } |
|
Asks a channel for device state.
Definition at line 1618 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.
01619 { 01620 char tech[AST_MAX_EXTENSION] = ""; 01621 char *number; 01622 struct chanlist *chanls; 01623 int res = 0; 01624 01625 strncpy(tech, device, sizeof(tech)-1); 01626 number = strchr(tech, '/'); 01627 if (!number) { 01628 return AST_DEVICE_INVALID; 01629 } 01630 *number = 0; 01631 number++; 01632 01633 if (ast_mutex_lock(&chlock)) { 01634 ast_log(LOG_WARNING, "Unable to lock channel list\n"); 01635 return -1; 01636 } 01637 chanls = backends; 01638 while(chanls) { 01639 if (!strcasecmp(tech, chanls->type)) { 01640 ast_mutex_unlock(&chlock); 01641 if (!chanls->devicestate) 01642 return ast_parse_device_state(device); 01643 else { 01644 res = chanls->devicestate(number); 01645 if (res == AST_DEVICE_UNKNOWN) 01646 return ast_parse_device_state(device); 01647 else 01648 return res; 01649 } 01650 } 01651 chanls = chanls->next; 01652 } 01653 ast_mutex_unlock(&chlock); 01654 return AST_DEVICE_INVALID; 01655 } |
|
Hang up a channel.
Definition at line 613 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_async_goto(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pbx_run(), and ast_request_and_dial().
00614 { 00615 int res = 0; 00616 /* Don't actually hang up a channel that will masquerade as someone else, or 00617 if someone is going to masquerade as us */ 00618 ast_mutex_lock(&chan->lock); 00619 if (chan->masq) { 00620 if (ast_do_masquerade(chan)) 00621 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 00622 } 00623 00624 if (chan->masq) { 00625 ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name); 00626 ast_mutex_unlock(&chan->lock); 00627 return 0; 00628 } 00629 /* If this channel is one which will be masqueraded into something, 00630 mark it as a zombie already, so we know to free it later */ 00631 if (chan->masqr) { 00632 ast_mutex_unlock(&chan->lock); 00633 chan->zombie=1; 00634 return 0; 00635 } 00636 free_translation(chan); 00637 if (chan->stream) 00638 ast_stopstream(chan); 00639 if (chan->sched) 00640 sched_context_destroy(chan->sched); 00641 /* Clear any tone stuff remaining */ 00642 if (chan->generatordata) 00643 chan->generator->release(chan, chan->generatordata); 00644 chan->generatordata = NULL; 00645 chan->generator = NULL; 00646 if (chan->cdr) { 00647 /* End the CDR if it hasn't already */ 00648 ast_cdr_end(chan->cdr); 00649 /* Post and Free the CDR */ 00650 ast_cdr_post(chan->cdr); 00651 ast_cdr_free(chan->cdr); 00652 } 00653 if (chan->blocking) { 00654 ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd " 00655 "is blocked by thread %ld in procedure %s! Expect a failure\n", 00656 (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc); 00657 CRASH; 00658 } 00659 if (!chan->zombie) { 00660 if (option_debug) 00661 ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name); 00662 if (chan->pvt->hangup) 00663 res = chan->pvt->hangup(chan); 00664 } else 00665 if (option_debug) 00666 ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name); 00667 00668 ast_mutex_unlock(&chan->lock); 00669 manager_event(EVENT_FLAG_CALL, "Hangup", 00670 "Channel: %s\r\n" 00671 "Uniqueid: %s\r\n", 00672 chan->name, chan->uniqueid); 00673 ast_channel_free(chan); 00674 return res; 00675 } |
|
Indicates condition of channel.
Definition at line 1168 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.
01169 { 01170 int res = -1; 01171 /* Stop if we're a zombie or need a soft hangup */ 01172 if (chan->zombie || ast_check_hangup(chan)) 01173 return -1; 01174 ast_mutex_lock(&chan->lock); 01175 if (chan->pvt->indicate) 01176 res = chan->pvt->indicate(chan, condition); 01177 ast_mutex_unlock(&chan->lock); 01178 if (!chan->pvt->indicate || res) { 01179 /* 01180 * Device does not support (that) indication, lets fake 01181 * it by doing our own tone generation. (PM2002) 01182 */ 01183 if (condition >= 0) { 01184 const struct tone_zone_sound *ts = NULL; 01185 switch (condition) { 01186 case AST_CONTROL_RINGING: 01187 ts = ast_get_indication_tone(chan->zone, "ring"); 01188 break; 01189 case AST_CONTROL_BUSY: 01190 ts = ast_get_indication_tone(chan->zone, "busy"); 01191 break; 01192 case AST_CONTROL_CONGESTION: 01193 ts = ast_get_indication_tone(chan->zone, "congestion"); 01194 break; 01195 } 01196 if (ts && ts->data[0]) { 01197 ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition); 01198 ast_playtones_start(chan,0,ts->data, 1); 01199 res = 0; 01200 } else if (condition == AST_CONTROL_PROGRESS) { 01201 /* ast_playtones_stop(chan); */ 01202 } else { 01203 /* not handled */ 01204 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name); 01205 res = -1; 01206 } 01207 } 01208 else ast_playtones_stop(chan); 01209 } 01210 return res; 01211 } |
|
Search the Channels by Name.
Definition at line 1599 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().
01600 { 01601 char name[AST_CHANNEL_NAME] = ""; 01602 char *cut; 01603 struct ast_channel *chan; 01604 01605 chan = ast_channel_walk(NULL); 01606 while (chan) { 01607 strncpy(name, chan->name, sizeof(name)-1); 01608 cut = strchr(name,'-'); 01609 if (cut) 01610 *cut = 0; 01611 if (!strcmp(name, device)) 01612 return AST_DEVICE_INUSE; 01613 chan = ast_channel_walk(chan); 01614 } 01615 return AST_DEVICE_UNKNOWN; 01616 } |
|
Definition at line 1300 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().
01301 { 01302 struct ast_frame a = { AST_FRAME_VOICE }; 01303 char nothing[128]; 01304 /* Send an empty audio frame to get things moving */ 01305 if (chan->_state != AST_STATE_UP) { 01306 ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name); 01307 a.subclass = chan->pvt->rawwriteformat; 01308 a.data = nothing + AST_FRIENDLY_OFFSET; 01309 if (ast_write(chan, &a)) 01310 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name); 01311 } 01312 return 0; 01313 } |
|
Reads a frame.
Definition at line 990 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_app_getvoice(), ast_async_goto(), ast_channel_bridge(), ast_recvchar(), ast_request_and_dial(), 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().
00991 { 00992 struct ast_frame *f = NULL; 00993 int blah; 00994 #ifdef ZAPTEL_OPTIMIZATIONS 00995 int (*func)(void *); 00996 void *data; 00997 #endif 00998 static struct ast_frame null_frame = 00999 { 01000 AST_FRAME_NULL, 01001 }; 01002 01003 ast_mutex_lock(&chan->lock); 01004 if (chan->masq) { 01005 if (ast_do_masquerade(chan)) { 01006 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 01007 f = NULL; 01008 } else 01009 f = &null_frame; 01010 ast_mutex_unlock(&chan->lock); 01011 return f; 01012 } 01013 01014 /* Stop if we're a zombie or need a soft hangup */ 01015 if (chan->zombie || ast_check_hangup(chan)) { 01016 if (chan->generator) 01017 ast_deactivate_generator(chan); 01018 ast_mutex_unlock(&chan->lock); 01019 return NULL; 01020 } 01021 01022 if (!chan->deferdtmf && strlen(chan->dtmfq)) { 01023 /* We have DTMF that has been deferred. Return it now */ 01024 chan->dtmff.frametype = AST_FRAME_DTMF; 01025 chan->dtmff.subclass = chan->dtmfq[0]; 01026 /* Drop first digit */ 01027 memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1); 01028 ast_mutex_unlock(&chan->lock); 01029 return &chan->dtmff; 01030 } 01031 01032 /* Read and ignore anything on the alertpipe, but read only 01033 one sizeof(blah) per frame that we send from it */ 01034 if (chan->pvt->alertpipe[0] > -1) { 01035 read(chan->pvt->alertpipe[0], &blah, sizeof(blah)); 01036 } 01037 #ifdef ZAPTEL_OPTIMIZATIONS 01038 if ((chan->timingfd > -1) && (chan->fdno == AST_MAX_FDS - 2) && chan->exception) { 01039 chan->exception = 0; 01040 blah = -1; 01041 ioctl(chan->timingfd, ZT_TIMERACK, &blah); 01042 func = chan->timingfunc; 01043 data = chan->timingdata; 01044 ast_mutex_unlock(&chan->lock); 01045 if (func) { 01046 #if 0 01047 ast_log(LOG_DEBUG, "Calling private function\n"); 01048 #endif 01049 func(data); 01050 } else { 01051 blah = 0; 01052 ast_mutex_lock(&chan->lock); 01053 ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah); 01054 chan->timingdata = NULL; 01055 ast_mutex_unlock(&chan->lock); 01056 } 01057 f = &null_frame; 01058 return f; 01059 } 01060 #endif 01061 /* Check for pending read queue */ 01062 if (chan->pvt->readq) { 01063 f = chan->pvt->readq; 01064 chan->pvt->readq = f->next; 01065 /* Interpret hangup and return NULL */ 01066 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) 01067 f = NULL; 01068 } else { 01069 chan->blocker = pthread_self(); 01070 if (chan->exception) { 01071 if (chan->pvt->exception) 01072 f = chan->pvt->exception(chan); 01073 else { 01074 ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name); 01075 f = &null_frame; 01076 } 01077 /* Clear the exception flag */ 01078 chan->exception = 0; 01079 } else 01080 if (chan->pvt->read) 01081 f = chan->pvt->read(chan); 01082 else 01083 ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name); 01084 } 01085 01086 01087 if (f && (f->frametype == AST_FRAME_VOICE)) { 01088 if (!(f->subclass & chan->nativeformats)) { 01089 /* This frame can't be from the current native formats -- drop it on the 01090 floor */ 01091 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)); 01092 ast_frfree(f); 01093 f = &null_frame; 01094 } else { 01095 if (chan->monitor && chan->monitor->read_stream ) { 01096 #ifndef MONITOR_CONSTANT_DELAY 01097 int jump = chan->outsmpl - chan->insmpl - 2 * f->samples; 01098 if (jump >= 0) { 01099 if (ast_seekstream(chan->monitor->read_stream, jump + f->samples, SEEK_FORCECUR) == -1) 01100 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 01101 chan->insmpl += jump + 2 * f->samples; 01102 } else 01103 chan->insmpl+= f->samples; 01104 #else 01105 int jump = chan->outsmpl - chan->insmpl; 01106 if (jump - MONITOR_DELAY >= 0) { 01107 if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1) 01108 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 01109 chan->insmpl += jump; 01110 } else 01111 chan->insmpl += f->samples; 01112 #endif 01113 if (ast_writestream(chan->monitor->read_stream, f) < 0) 01114 ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n"); 01115 } 01116 if (chan->pvt->readtrans) { 01117 f = ast_translate(chan->pvt->readtrans, f, 1); 01118 if (!f) 01119 f = &null_frame; 01120 } 01121 } 01122 } 01123 01124 /* Make sure we always return NULL in the future */ 01125 if (!f) { 01126 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01127 if (chan->generator) 01128 ast_deactivate_generator(chan); 01129 /* End the CDR if appropriate */ 01130 if (chan->cdr) 01131 ast_cdr_end(chan->cdr); 01132 } else if (chan->deferdtmf && f->frametype == AST_FRAME_DTMF) { 01133 if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2) 01134 chan->dtmfq[strlen(chan->dtmfq)] = f->subclass; 01135 else 01136 ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name); 01137 f = &null_frame; 01138 } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_ANSWER)) { 01139 /* Answer the CDR */ 01140 ast_setstate(chan, AST_STATE_UP); 01141 ast_cdr_answer(chan->cdr); 01142 } 01143 ast_mutex_unlock(&chan->lock); 01144 01145 /* Run any generator sitting on the line */ 01146 if (f && (f->frametype == AST_FRAME_VOICE) && chan->generatordata) { 01147 /* Mask generator data temporarily */ 01148 void *tmp; 01149 int res; 01150 tmp = chan->generatordata; 01151 chan->generatordata = NULL; 01152 res = chan->generator->generate(chan, tmp, f->datalen, f->samples); 01153 chan->generatordata = tmp; 01154 if (res) { 01155 ast_log(LOG_DEBUG, "Auto-deactivating generator\n"); 01156 ast_deactivate_generator(chan); 01157 } 01158 } 01159 if (chan->fin & 0x80000000) 01160 ast_frame_dump(chan->name, f, "<<"); 01161 if ((chan->fin & 0x7fffffff) == 0x7fffffff) 01162 chan->fin &= 0x80000000; 01163 else 01164 chan->fin++; 01165 return f; 01166 } |
|
Reads multiple digits.
Definition at line 1692 of file channel.c. References ast_check_hangup(), AST_DIGIT_ANY, ast_stopstream(), ast_waitfordigit(), ast_waitstream(), ast_channel::stream, and ast_channel::zombie. Referenced by ast_app_getdata().
01693 { 01694 int pos=0; 01695 int to = ftimeout; 01696 char d; 01697 /* XXX Merge with full version? XXX */ 01698 /* Stop if we're a zombie or need a soft hangup */ 01699 if (c->zombie || ast_check_hangup(c)) 01700 return -1; 01701 if (!len) 01702 return -1; 01703 do { 01704 if (c->stream) { 01705 d = ast_waitstream(c, AST_DIGIT_ANY); 01706 ast_stopstream(c); 01707 usleep(1000); 01708 if (!d) 01709 d = ast_waitfordigit(c, to); 01710 } else { 01711 d = ast_waitfordigit(c, to); 01712 } 01713 if (d < 0) 01714 return -1; 01715 if (d == 0) { 01716 s[pos]='\0'; 01717 return 1; 01718 } 01719 if (!strchr(enders, d)) 01720 s[pos++] = d; 01721 if (strchr(enders, d) || (pos >= len)) { 01722 s[pos]='\0'; 01723 return 0; 01724 } 01725 to = timeout; 01726 } while(1); 01727 /* Never reached */ 01728 return 0; 01729 } |
|
Definition at line 1731 of file channel.c. References ast_check_hangup(), AST_DIGIT_ANY, ast_stopstream(), ast_waitfordigit_full(), ast_waitstream_full(), ast_channel::stream, and ast_channel::zombie. Referenced by ast_app_getdata_full().
01732 { 01733 int pos=0; 01734 int to = ftimeout; 01735 char d; 01736 /* Stop if we're a zombie or need a soft hangup */ 01737 if (c->zombie || ast_check_hangup(c)) 01738 return -1; 01739 if (!len) 01740 return -1; 01741 do { 01742 if (c->stream) { 01743 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd); 01744 ast_stopstream(c); 01745 usleep(1000); 01746 if (!d) 01747 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 01748 } else { 01749 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 01750 } 01751 if (d < 0) 01752 return -1; 01753 if (d == 0) { 01754 s[pos]='\0'; 01755 return 1; 01756 } 01757 if (d == 1) { 01758 s[pos]='\0'; 01759 return 2; 01760 } 01761 if (!strchr(enders, d)) 01762 s[pos++] = d; 01763 if (strchr(enders, d) || (pos >= len)) { 01764 s[pos]='\0'; 01765 return 0; 01766 } 01767 to = timeout; 01768 } while(1); 01769 /* Never reached */ 01770 return 0; 01771 } |
|
Receives a text character from a channel.
Definition at line 1213 of file channel.c. References ast_check_hangup(), AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_TEXT, ast_frfree(), ast_read(), and ast_waitfor().
01214 { 01215 int res,ourto,c; 01216 struct ast_frame *f; 01217 01218 ourto = timeout; 01219 for(;;) 01220 { 01221 if (ast_check_hangup(chan)) return -1; 01222 res = ast_waitfor(chan,ourto); 01223 if (res <= 0) /* if timeout */ 01224 { 01225 return 0; 01226 } 01227 ourto = res; 01228 f = ast_read(chan); 01229 if (f == NULL) return -1; /* if hangup */ 01230 if ((f->frametype == AST_FRAME_CONTROL) && 01231 (f->subclass == AST_CONTROL_HANGUP)) return -1; /* if hangup */ 01232 if (f->frametype == AST_FRAME_TEXT) /* if a text frame */ 01233 { 01234 c = *((char *)f->data); /* get the data */ 01235 ast_frfree(f); 01236 return(c); 01237 } 01238 ast_frfree(f); 01239 } 01240 } |
|
Requests a channel.
Definition at line 1554 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().
01555 { 01556 struct chanlist *chan; 01557 struct ast_channel *c = NULL; 01558 int capabilities; 01559 int fmt; 01560 int res; 01561 if (ast_mutex_lock(&chlock)) { 01562 ast_log(LOG_WARNING, "Unable to lock channel list\n"); 01563 return NULL; 01564 } 01565 chan = backends; 01566 while(chan) { 01567 if (!strcasecmp(type, chan->type)) { 01568 capabilities = chan->capabilities; 01569 fmt = format; 01570 res = ast_translator_best_choice(&fmt, &capabilities); 01571 if (res < 0) { 01572 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->capabilities, format); 01573 ast_mutex_unlock(&chlock); 01574 return NULL; 01575 } 01576 ast_mutex_unlock(&chlock); 01577 if (chan->requester) 01578 c = chan->requester(type, capabilities, data); 01579 if (c) { 01580 if (c->_state == AST_STATE_DOWN) { 01581 manager_event(EVENT_FLAG_CALL, "Newchannel", 01582 "Channel: %s\r\n" 01583 "State: %s\r\n" 01584 "Callerid: %s\r\n" 01585 "Uniqueid: %s\r\n", 01586 c->name, ast_state2str(c->_state), c->callerid ? c->callerid : "<unknown>", c->uniqueid); 01587 } 01588 } 01589 return c; 01590 } 01591 chan = chan->next; 01592 } 01593 if (!chan) 01594 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type); 01595 ast_mutex_unlock(&chlock); 01596 return c; 01597 } |
|
Definition at line 1491 of file channel.c. References ast_channel::_state, ast_call(), 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(), LOG_NOTICE, and type. Referenced by ast_pbx_outgoing_app(), and ast_pbx_outgoing_exten().
01492 { 01493 int state = 0; 01494 struct ast_channel *chan; 01495 struct ast_frame *f; 01496 int res; 01497 01498 chan = ast_request(type, format, data); 01499 if (chan) { 01500 if (callerid) 01501 ast_set_callerid(chan, callerid, 1); 01502 if (!ast_call(chan, data, 0)) { 01503 while(timeout && (chan->_state != AST_STATE_UP)) { 01504 res = ast_waitfor(chan, timeout); 01505 if (res < 0) { 01506 /* Something not cool, or timed out */ 01507 ast_hangup(chan); 01508 chan = NULL; 01509 break; 01510 } 01511 /* If done, break out */ 01512 if (!res) 01513 break; 01514 if (timeout > -1) 01515 timeout = res; 01516 f = ast_read(chan); 01517 if (!f) { 01518 state = AST_CONTROL_HANGUP; 01519 ast_hangup(chan); 01520 chan = NULL; 01521 break; 01522 } 01523 if (f->frametype == AST_FRAME_CONTROL) { 01524 if (f->subclass == AST_CONTROL_RINGING) 01525 state = AST_CONTROL_RINGING; 01526 else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) { 01527 state = f->subclass; 01528 ast_frfree(f); 01529 break; 01530 } else if (f->subclass == AST_CONTROL_ANSWER) { 01531 state = f->subclass; 01532 ast_frfree(f); 01533 break; 01534 } else { 01535 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass); 01536 } 01537 } 01538 ast_frfree(f); 01539 } 01540 } else { 01541 ast_hangup(chan); 01542 chan = NULL; 01543 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data); 01544 } 01545 } else 01546 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data); 01547 if (chan && (chan->_state == AST_STATE_UP)) 01548 state = AST_CONTROL_ANSWER; 01549 if (outstate) 01550 *outstate = state; 01551 return chan; 01552 } |
|
Wait for a specied amount of time, looking for hangups.
Definition at line 472 of file channel.c. References ast_frfree(), ast_read(), and ast_waitfor().
00473 { 00474 struct ast_frame *f; 00475 while(ms > 0) { 00476 ms = ast_waitfor(chan, ms); 00477 if (ms <0) 00478 return -1; 00479 if (ms > 0) { 00480 f = ast_read(chan); 00481 if (!f) 00482 return -1; 00483 ast_frfree(f); 00484 } 00485 } 00486 return 0; 00487 } |
|
Wait for a specied amount of time, looking for hangups and a condition argument.
Definition at line 451 of file channel.c. References ast_frfree(), ast_read(), and ast_waitfor().
00453 { 00454 struct ast_frame *f; 00455 00456 while(ms > 0) { 00457 if( cond && ((*cond)(data) == 0 ) ) 00458 return 0; 00459 ms = ast_waitfor(chan, ms); 00460 if (ms <0) 00461 return -1; 00462 if (ms > 0) { 00463 f = ast_read(chan); 00464 if (!f) 00465 return -1; 00466 ast_frfree(f); 00467 } 00468 } 00469 return 0; 00470 } |
|
Sends text to a channel.
Definition at line 1242 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.
01243 { 01244 int res = 0; 01245 /* Stop if we're a zombie or need a soft hangup */ 01246 if (chan->zombie || ast_check_hangup(chan)) 01247 return -1; 01248 CHECK_BLOCKING(chan); 01249 if (chan->pvt->send_text) 01250 res = chan->pvt->send_text(chan, text); 01251 chan->blocking = 0; 01252 return res; 01253 } |
|
Definition at line 2070 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().
02071 { 02072 if (chan->callerid) 02073 free(chan->callerid); 02074 if (anitoo && chan->ani) 02075 free(chan->ani); 02076 if (callerid) { 02077 chan->callerid = strdup(callerid); 02078 if (anitoo) 02079 chan->ani = strdup(callerid); 02080 } else { 02081 chan->callerid = NULL; 02082 if (anitoo) 02083 chan->ani = NULL; 02084 } 02085 if (chan->cdr) 02086 ast_cdr_setcid(chan->cdr, chan); 02087 manager_event(EVENT_FLAG_CALL, "Newcallerid", 02088 "Channel: %s\r\n" 02089 "Callerid: %s\r\n" 02090 "Uniqueid: %s\r\n", 02091 chan->name, chan->callerid ? 02092 chan->callerid : "<Unknown>", 02093 chan->uniqueid); 02094 } |
|
Sets read format on channel chan.
Definition at line 1460 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().
01461 { 01462 int fmt; 01463 int native; 01464 int res; 01465 01466 native = chan->nativeformats; 01467 fmt = fmts; 01468 /* Find a translation path from the native read format to one of the user's read formats */ 01469 res = ast_translator_best_choice(&fmt, &native); 01470 if (res < 0) { 01471 ast_log(LOG_NOTICE, "Unable to find a path from %s to %s\n", 01472 ast_getformatname(chan->nativeformats), ast_getformatname(fmts)); 01473 return -1; 01474 } 01475 01476 /* Now we have a good choice for both. We'll write using our native format. */ 01477 chan->pvt->rawreadformat = native; 01478 /* User perspective is fmt */ 01479 chan->readformat = fmt; 01480 /* Free any read translation we have right now */ 01481 if (chan->pvt->readtrans) 01482 ast_translator_free_path(chan->pvt->readtrans); 01483 /* Build a translation path from the raw read format to the user reading format */ 01484 chan->pvt->readtrans = ast_translator_build_path(chan->readformat, chan->pvt->rawreadformat); 01485 if (option_debug) 01486 ast_log(LOG_DEBUG, "Set channel %s to read format %s\n", 01487 chan->name, ast_getformatname(chan->readformat)); 01488 return 0; 01489 } |
|
Sets write format on channel chan.
Definition at line 1430 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().
01431 { 01432 int fmt; 01433 int native; 01434 int res; 01435 01436 native = chan->nativeformats; 01437 fmt = fmts; 01438 01439 res = ast_translator_best_choice(&native, &fmt); 01440 if (res < 0) { 01441 ast_log(LOG_NOTICE, "Unable to find a path from %s to %s\n", 01442 ast_getformatname(fmts), ast_getformatname(chan->nativeformats)); 01443 return -1; 01444 } 01445 01446 /* Now we have a good choice for both. We'll write using our native format. */ 01447 chan->pvt->rawwriteformat = native; 01448 /* User perspective is fmt */ 01449 chan->writeformat = fmt; 01450 /* Free any write translation we have right now */ 01451 if (chan->pvt->writetrans) 01452 ast_translator_free_path(chan->pvt->writetrans); 01453 /* Build a translation path from the user write format to the raw writing format */ 01454 chan->pvt->writetrans = ast_translator_build_path(chan->pvt->rawwriteformat, chan->writeformat); 01455 if (option_debug) 01456 ast_log(LOG_DEBUG, "Set channel %s to write format %s\n", chan->name, ast_getformatname(chan->writeformat)); 01457 return 0; 01458 } |
|
Definition at line 943 of file channel.c. References ast_log(), LOG_DEBUG, ast_channel::timingdata, ast_channel::timingfd, and ast_channel::timingfunc. Referenced by ast_closestream().
00944 { 00945 int res = -1; 00946 #ifdef ZAPTEL_OPTIMIZATIONS 00947 if (c->timingfd > -1) { 00948 if (!func) { 00949 samples = 0; 00950 data = 0; 00951 } 00952 ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples); 00953 res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples); 00954 c->timingfunc = func; 00955 c->timingdata = data; 00956 } 00957 #endif 00958 return res; 00959 } |
|
Returns non-zero if Asterisk is being shut down Definition at line 128 of file channel.c.
00129 {
00130 return shutting_down;
00131 }
|
|
Softly hangup up a channel.
Definition at line 590 of file channel.c. References ast_mutex_lock, ast_mutex_unlock, ast_softhangup_nolock(), and ast_channel::lock. Referenced by ast_begin_shutdown().
00591 { 00592 int res; 00593 ast_mutex_lock(&chan->lock); 00594 res = ast_softhangup_nolock(chan, cause); 00595 ast_mutex_unlock(&chan->lock); 00596 return res; 00597 } |
|
Definition at line 575 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_async_goto(), and ast_softhangup().
00576 { 00577 int res = 0; 00578 struct ast_frame f = { AST_FRAME_NULL }; 00579 if (option_debug) 00580 ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name); 00581 /* Inform channel driver that we need to be hung up, if it cares */ 00582 chan->_softhangup |= cause; 00583 ast_queue_frame(chan, &f, 0); 00584 /* Interrupt any select call or such */ 00585 if (chan->blocking) 00586 pthread_kill(chan->blocker, SIGURG); 00587 return res; 00588 } |
|
Gives the string form of a given state.
Definition at line 194 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().
00195 { 00196 /* XXX Not reentrant XXX */ 00197 static char localtmp[256]; 00198 switch(state) { 00199 case AST_STATE_DOWN: 00200 return "Down"; 00201 case AST_STATE_RESERVED: 00202 return "Rsrvd"; 00203 case AST_STATE_OFFHOOK: 00204 return "OffHook"; 00205 case AST_STATE_DIALING: 00206 return "Dialing"; 00207 case AST_STATE_RING: 00208 return "Ring"; 00209 case AST_STATE_RINGING: 00210 return "Ringing"; 00211 case AST_STATE_UP: 00212 return "Up"; 00213 case AST_STATE_BUSY: 00214 return "Busy"; 00215 default: 00216 snprintf(localtmp, sizeof(localtmp), "Unknown (%d)\n", state); 00217 return localtmp; 00218 } 00219 } |
|
Play a tone pair for a given amount of time Definition at line 2416 of file channel.c. References ast_frfree(), ast_read(), ast_tonepair_start(), ast_waitfor(), and ast_channel::generatordata.
02417 { 02418 struct ast_frame *f; 02419 int res; 02420 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol))) 02421 return res; 02422 02423 /* Give us some wiggle room */ 02424 while(chan->generatordata && (ast_waitfor(chan, 100) >= 0)) { 02425 f = ast_read(chan); 02426 if (f) 02427 ast_frfree(f); 02428 else 02429 return -1; 02430 } 02431 return 0; 02432 } |
|
Start a tone going Definition at line 2396 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().
02397 { 02398 struct tonepair_def d = { 0, }; 02399 d.freq1 = freq1; 02400 d.freq2 = freq2; 02401 d.duration = duration; 02402 if (vol < 1) 02403 d.vol = 8192; 02404 else 02405 d.vol = vol; 02406 if (ast_activate_generator(chan, &tonepair, &d)) 02407 return -1; 02408 return 0; 02409 } |
|
Stop a tone from playing Definition at line 2411 of file channel.c. References ast_deactivate_generator().
02412 { 02413 ast_deactivate_generator(chan); 02414 } |
|
Definition at line 1672 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.
01673 { 01674 /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 01675 If the remote end does not answer within the timeout, then do NOT hang up, but 01676 return anyway. */ 01677 int res = -1; 01678 /* Stop if we're a zombie or need a soft hangup */ 01679 ast_mutex_lock(&chan->lock); 01680 if (!chan->zombie && !ast_check_hangup(chan)) { 01681 if (chan->pvt->transfer) { 01682 res = chan->pvt->transfer(chan, dest); 01683 if (!res) 01684 res = 1; 01685 } else 01686 res = 0; 01687 } 01688 ast_mutex_unlock(&chan->lock); 01689 return res; 01690 } |
|
Wait for input on a channel.
Definition at line 902 of file channel.c. References ast_waitfor_n(). Referenced by ast_app_getvoice(), ast_recvchar(), ast_request_and_dial(), ast_safe_sleep(), ast_safe_sleep_conditional(), ast_tonepair(), ast_waitfordigit(), ast_waitstream(), and ast_waitstream_fr().
00903 { 00904 struct ast_channel *chan; 00905 int oldms = ms; 00906 chan = ast_waitfor_n(&c, 1, &ms); 00907 if (ms < 0) { 00908 if (oldms < 0) 00909 return 0; 00910 else 00911 return -1; 00912 } 00913 return ms; 00914 } |
|
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 897 of file channel.c. References ast_waitfor_nandfds(). Referenced by ast_channel_bridge(), ast_rtp_bridge(), and ast_waitfor().
00898 { 00899 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms); 00900 } |
|
Waits for input on an fd. This version works on fd's only. Be careful with it. Definition at line 754 of file channel.c.
00755 { 00756 /* Wait for x amount of time on a file descriptor to have input. */ 00757 struct timeval tv; 00758 fd_set rfds, efds; 00759 int res; 00760 int x, max=-1; 00761 int winner = -1; 00762 00763 tv.tv_sec = *ms / 1000; 00764 tv.tv_usec = (*ms % 1000) * 1000; 00765 FD_ZERO(&rfds); 00766 FD_ZERO(&efds); 00767 for (x=0;x<n;x++) { 00768 if (fds[x] > -1) { 00769 FD_SET(fds[x], &rfds); 00770 FD_SET(fds[x], &efds); 00771 if (fds[x] > max) 00772 max = fds[x]; 00773 } 00774 } 00775 if (*ms >= 0) 00776 res = ast_select(max + 1, &rfds, NULL, &efds, &tv); 00777 else 00778 res = ast_select(max + 1, &rfds, NULL, &efds, NULL); 00779 00780 if (res < 0) { 00781 /* Simulate a timeout if we were interrupted */ 00782 if (errno != EINTR) 00783 *ms = -1; 00784 else 00785 *ms = 0; 00786 return -1; 00787 } 00788 00789 for (x=0;x<n;x++) { 00790 if ((fds[x] > -1) && (FD_ISSET(fds[x], &rfds) || FD_ISSET(fds[x], &efds)) && (winner < 0)) { 00791 if (exception) 00792 *exception = FD_ISSET(fds[x], &efds); 00793 winner = fds[x]; 00794 } 00795 } 00796 *ms = tv.tv_sec * 1000 + tv.tv_usec / 1000; 00797 return winner; 00798 } |
|
Waits for activity on a group of channels.
Definition at line 800 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().
00802 { 00803 /* Wait for x amount of time on a file descriptor to have input. */ 00804 struct timeval tv; 00805 fd_set rfds, efds; 00806 int res; 00807 int x, y, max=-1; 00808 struct ast_channel *winner = NULL; 00809 if (outfd) 00810 *outfd = -1; 00811 if (exception) 00812 *exception = 0; 00813 00814 /* Perform any pending masquerades */ 00815 for (x=0;x<n;x++) { 00816 ast_mutex_lock(&c[x]->lock); 00817 if (c[x]->masq) { 00818 if (ast_do_masquerade(c[x])) { 00819 ast_log(LOG_WARNING, "Masquerade failed\n"); 00820 *ms = -1; 00821 ast_mutex_unlock(&c[x]->lock); 00822 return NULL; 00823 } 00824 } 00825 ast_mutex_unlock(&c[x]->lock); 00826 } 00827 00828 tv.tv_sec = *ms / 1000; 00829 tv.tv_usec = (*ms % 1000) * 1000; 00830 FD_ZERO(&rfds); 00831 FD_ZERO(&efds); 00832 00833 for (x=0;x<n;x++) { 00834 for (y=0;y<AST_MAX_FDS;y++) { 00835 if (c[x]->fds[y] > -1) { 00836 FD_SET(c[x]->fds[y], &rfds); 00837 FD_SET(c[x]->fds[y], &efds); 00838 if (c[x]->fds[y] > max) 00839 max = c[x]->fds[y]; 00840 } 00841 } 00842 CHECK_BLOCKING(c[x]); 00843 } 00844 for (x=0;x<nfds; x++) { 00845 FD_SET(fds[x], &rfds); 00846 FD_SET(fds[x], &efds); 00847 if (fds[x] > max) 00848 max = fds[x]; 00849 } 00850 if (*ms >= 0) 00851 res = ast_select(max + 1, &rfds, NULL, &efds, &tv); 00852 else 00853 res = ast_select(max + 1, &rfds, NULL, &efds, NULL); 00854 00855 if (res < 0) { 00856 for (x=0;x<n;x++) 00857 c[x]->blocking = 0; 00858 /* Simulate a timeout if we were interrupted */ 00859 if (errno != EINTR) 00860 *ms = -1; 00861 else { 00862 /* Just an interrupt */ 00863 #if 0 00864 *ms = 0; 00865 #endif 00866 } 00867 return NULL; 00868 } 00869 00870 for (x=0;x<n;x++) { 00871 c[x]->blocking = 0; 00872 for (y=0;y<AST_MAX_FDS;y++) { 00873 if (c[x]->fds[y] > -1) { 00874 if ((FD_ISSET(c[x]->fds[y], &rfds) || FD_ISSET(c[x]->fds[y], &efds)) && !winner) { 00875 /* Set exception flag if appropriate */ 00876 if (FD_ISSET(c[x]->fds[y], &efds)) 00877 c[x]->exception = 1; 00878 c[x]->fdno = y; 00879 winner = c[x]; 00880 } 00881 } 00882 } 00883 } 00884 for (x=0;x<nfds;x++) { 00885 if ((FD_ISSET(fds[x], &rfds) || FD_ISSET(fds[x], &efds)) && !winner) { 00886 if (outfd) 00887 *outfd = fds[x]; 00888 if (FD_ISSET(fds[x], &efds) && exception) 00889 *exception = 1; 00890 winner = NULL; 00891 } 00892 } 00893 *ms = tv.tv_sec * 1000 + tv.tv_usec / 1000; 00894 return winner; 00895 } |
|
Waits for a digit.
Definition at line 916 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().
00917 { 00918 /* XXX Should I be merged with waitfordigit_full XXX */ 00919 struct ast_frame *f; 00920 char result = 0; 00921 /* Stop if we're a zombie or need a soft hangup */ 00922 if (c->zombie || ast_check_hangup(c)) 00923 return -1; 00924 /* Wait for a digit, no more than ms milliseconds total. */ 00925 while(ms && !result) { 00926 ms = ast_waitfor(c, ms); 00927 if (ms < 0) /* Error */ 00928 result = -1; 00929 else if (ms > 0) { 00930 /* Read something */ 00931 f = ast_read(c); 00932 if (f) { 00933 if (f->frametype == AST_FRAME_DTMF) 00934 result = f->subclass; 00935 ast_frfree(f); 00936 } else 00937 result = -1; 00938 } 00939 } 00940 return result; 00941 } |
|
Definition at line 960 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().
00961 { 00962 struct ast_frame *f; 00963 char result = 0; 00964 struct ast_channel *rchan; 00965 int outfd; 00966 /* Stop if we're a zombie or need a soft hangup */ 00967 if (c->zombie || ast_check_hangup(c)) 00968 return -1; 00969 /* Wait for a digit, no more than ms milliseconds total. */ 00970 while(ms && !result) { 00971 rchan = ast_waitfor_nandfds(&c, 1, &audio, (audio > -1) ? 1 : 0, NULL, &outfd, &ms); 00972 if ((!rchan) && (outfd < 0) && (ms)) /* Error */ 00973 result = -1; 00974 else if (outfd > -1) { 00975 result = 1; 00976 } else if (rchan) { 00977 /* Read something */ 00978 f = ast_read(c); 00979 if (f) { 00980 if (f->frametype == AST_FRAME_DTMF) 00981 result = f->subclass; 00982 ast_frfree(f); 00983 } else 00984 result = -1; 00985 } 00986 } 00987 return result; 00988 } |
|
Write a frame to a channel.
Definition at line 1326 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().
01327 { 01328 int res = -1; 01329 struct ast_frame *f = NULL; 01330 /* Stop if we're a zombie or need a soft hangup */ 01331 ast_mutex_lock(&chan->lock); 01332 if (chan->zombie || ast_check_hangup(chan)) { 01333 ast_mutex_unlock(&chan->lock); 01334 return -1; 01335 } 01336 /* Handle any pending masquerades */ 01337 if (chan->masq) { 01338 if (ast_do_masquerade(chan)) { 01339 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 01340 ast_mutex_unlock(&chan->lock); 01341 return -1; 01342 } 01343 } 01344 if (chan->masqr) { 01345 ast_mutex_unlock(&chan->lock); 01346 return 0; 01347 } 01348 if (chan->generatordata) { 01349 if (chan->writeinterrupt) 01350 ast_deactivate_generator(chan); 01351 else { 01352 ast_mutex_unlock(&chan->lock); 01353 return 0; 01354 } 01355 } 01356 if (chan->fout & 0x80000000) 01357 ast_frame_dump(chan->name, fr, ">>"); 01358 CHECK_BLOCKING(chan); 01359 switch(fr->frametype) { 01360 case AST_FRAME_CONTROL: 01361 /* XXX Interpret control frames XXX */ 01362 ast_log(LOG_WARNING, "Don't know how to handle control frames yet\n"); 01363 break; 01364 case AST_FRAME_DTMF: 01365 res = do_senddigit(chan,fr->subclass); 01366 break; 01367 case AST_FRAME_TEXT: 01368 if (chan->pvt->send_text) 01369 res = chan->pvt->send_text(chan, (char *) fr->data); 01370 break; 01371 case AST_FRAME_VIDEO: 01372 /* XXX Handle translation of video codecs one day XXX */ 01373 if (chan->pvt->write_video) 01374 res = chan->pvt->write_video(chan, fr); 01375 else 01376 res = 0; 01377 break; 01378 default: 01379 if (chan->pvt->write) { 01380 if (chan->pvt->writetrans) { 01381 f = ast_translate(chan->pvt->writetrans, fr, 0); 01382 } else 01383 f = fr; 01384 if (f) { 01385 res = chan->pvt->write(chan, f); 01386 if( chan->monitor && 01387 chan->monitor->write_stream && 01388 f && ( f->frametype == AST_FRAME_VOICE ) ) { 01389 #ifndef MONITOR_CONSTANT_DELAY 01390 int jump = chan->insmpl - chan->outsmpl - 2 * f->samples; 01391 if (jump >= 0) { 01392 if (ast_seekstream(chan->monitor->write_stream, jump + f->samples, SEEK_FORCECUR) == -1) 01393 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 01394 chan->outsmpl += jump + 2 * f->samples; 01395 } else 01396 chan->outsmpl += f->samples; 01397 #else 01398 int jump = chan->insmpl - chan->outsmpl; 01399 if (jump - MONITOR_DELAY >= 0) { 01400 if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1) 01401 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 01402 chan->outsmpl += jump; 01403 } else 01404 chan->outsmpl += f->samples; 01405 #endif 01406 if (ast_writestream(chan->monitor->write_stream, f) < 0) 01407 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n"); 01408 } 01409 } else 01410 res = 0; 01411 } 01412 } 01413 if (f && (f != fr)) 01414 ast_frfree(f); 01415 chan->blocking = 0; 01416 /* Consider a write failure to force a soft hangup */ 01417 if (res < 0) 01418 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01419 else { 01420 if ((chan->fout & 0x7fffffff) == 0x7fffffff) 01421 chan->fout &= 0x80000000; 01422 else 01423 chan->fout++; 01424 chan->fout++; 01425 } 01426 ast_mutex_unlock(&chan->lock); 01427 return res; 01428 } |
|
Write video frame to a channel.
Definition at line 1315 of file channel.c. References ast_write(), ast_channel::pvt, and ast_channel_pvt::write_video.
01316 { 01317 int res; 01318 if (!chan->pvt->write_video) 01319 return 0; 01320 res = ast_write(chan, fr); 01321 if (!res) 01322 res = 1; 01323 return res; 01324 } |