#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <sys/time.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <math.h>
#include <asterisk/pbx.h>
#include <asterisk/frame.h>
#include <asterisk/sched.h>
#include <asterisk/options.h>
#include <asterisk/channel.h>
#include <asterisk/channel_pvt.h>
#include <asterisk/logger.h>
#include <asterisk/file.h>
#include <asterisk/translate.h>
#include <asterisk/manager.h>
#include <asterisk/chanvars.h>
#include <asterisk/linkedlists.h>
#include <asterisk/indications.h>
#include <asterisk/monitor.h>
Go to the source code of this file.
Data Structures | |
struct | chanlist |
struct | tonepair_def |
struct | tonepair_state |
Functions | |
int | ast_check_hangup (struct ast_channel *chan) |
Check to see if a channel is needing hang up. | |
void | ast_begin_shutdown (int hangup) |
int | ast_active_channels (void) |
void | ast_cancel_shutdown (void) |
int | ast_shutting_down (void) |
void | ast_channel_setwhentohangup (struct ast_channel *chan, time_t offset) |
Set when to hang a channel up. | |
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)) |
char * | ast_state2str (int state) |
Gives the string form of a given state. | |
int | ast_best_codec (int fmts) |
Pick the best codec. | |
ast_channel * | ast_channel_alloc (int needqueue) |
Create a channel structure. | |
int | ast_queue_frame (struct ast_channel *chan, struct ast_frame *fin, int lock) |
int | ast_queue_hangup (struct ast_channel *chan, int lock) |
int | ast_queue_control (struct ast_channel *chan, int control, int lock) |
int | ast_channel_defer_dtmf (struct ast_channel *chan) |
Defers DTMF. | |
void | ast_channel_undefer_dtmf (struct ast_channel *chan) |
Undeos a defer. | |
ast_channel * | ast_channel_walk (struct ast_channel *prev) |
Browse channels in use. | |
int | ast_safe_sleep_conditional (struct ast_channel *chan, int ms, int(*cond)(void *), void *data) |
Wait for a specied amount of time, looking for hangups and a condition argument. | |
int | ast_safe_sleep (struct ast_channel *chan, int ms) |
Wait for a specied amount of time, looking for hangups. | |
void | ast_channel_free (struct ast_channel *chan) |
Free a channel structure. | |
int | ast_softhangup_nolock (struct ast_channel *chan, int cause) |
int | ast_softhangup (struct ast_channel *chan, int cause) |
Softly hangup up a channel. | |
int | ast_hangup (struct ast_channel *chan) |
Hang up a channel. | |
void | ast_channel_unregister (char *type) |
Unregister a channel class. | |
int | ast_answer (struct ast_channel *chan) |
Answer a ringing call. | |
void | ast_deactivate_generator (struct ast_channel *chan) |
int | ast_activate_generator (struct ast_channel *chan, struct ast_generator *gen, void *params) |
int | ast_waitfor_n_fd (int *fds, int n, int *ms, int *exception) |
Waits for input on an fd. | |
ast_channel * | ast_waitfor_nandfds (struct ast_channel **c, 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 **c, int n, int *ms) |
Waits for input on a group of channels. | |
int | ast_waitfor (struct ast_channel *c, int ms) |
Wait for input on a channel. | |
char | ast_waitfordigit (struct ast_channel *c, int ms) |
Waits for a digit. | |
int | ast_settimeout (struct ast_channel *c, int samples, int(*func)(void *data), void *data) |
char | ast_waitfordigit_full (struct ast_channel *c, int ms, int audio, int ctrl) |
ast_frame * | ast_read (struct ast_channel *chan) |
Reads a frame. | |
int | ast_indicate (struct ast_channel *chan, int condition) |
Indicates condition of channel. | |
int | ast_recvchar (struct ast_channel *chan, int timeout) |
Receives a text character from a channel. | |
int | ast_sendtext (struct ast_channel *chan, char *text) |
Sends text to a channel. | |
int | ast_prod (struct ast_channel *chan) |
int | ast_write_video (struct ast_channel *chan, struct ast_frame *fr) |
Write video frame to a channel. | |
int | ast_write (struct ast_channel *chan, struct ast_frame *fr) |
Write a frame to a channel. | |
int | ast_set_write_format (struct ast_channel *chan, int fmts) |
Sets write format on channel chan. | |
int | ast_set_read_format (struct ast_channel *chan, int fmts) |
Sets read format on channel chan. | |
ast_channel * | ast_request_and_dial (char *type, int format, void *data, int timeout, int *outstate, char *callerid) |
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. | |
int | ast_call (struct ast_channel *chan, char *addr, int timeout) |
Make a call. | |
int | ast_transfer (struct ast_channel *chan, char *dest) |
int | ast_readstring (struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders) |
Reads multiple digits. | |
int | ast_readstring_full (struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders, int audiofd, int ctrlfd) |
int | ast_channel_supports_html (struct ast_channel *chan) |
Checks for HTML support on a channel. | |
int | ast_channel_sendhtml (struct ast_channel *chan, int subclass, char *data, int datalen) |
Sends HTML on given channel. | |
int | ast_channel_sendurl (struct ast_channel *chan, char *url) |
Sends a URL on a given link. | |
int | ast_channel_make_compatible (struct ast_channel *chan, struct ast_channel *peer) |
Makes two channel formats compatible. | |
int | ast_channel_masquerade (struct ast_channel *original, struct ast_channel *clone) |
Weird function made for call transfers. | |
void | ast_change_name (struct ast_channel *chan, char *newname) |
void | ast_set_callerid (struct ast_channel *chan, char *callerid, int anitoo) |
int | ast_setstate (struct ast_channel *chan, int state) |
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_setoption (struct ast_channel *chan, int option, void *data, int datalen, int block) |
Sets an option on a channel. | |
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) |
Variables | |
chanlist * | backends |
ast_channel * | channels = NULL |
|
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 } |
|
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 } |
|
Pick the best codec.
Definition at line 222 of file channel.c. References AST_FORMAT_ADPCM, AST_FORMAT_ALAW, AST_FORMAT_G723_1, AST_FORMAT_G729A, AST_FORMAT_GSM, AST_FORMAT_ILBC, AST_FORMAT_LPC10, AST_FORMAT_MP3, AST_FORMAT_SLINEAR, AST_FORMAT_SPEEX, AST_FORMAT_ULAW, ast_log(), and LOG_WARNING.
00223 { 00224 /* This just our opinion, expressed in code. We are asked to choose 00225 the best codec to use, given no information */ 00226 int x; 00227 static int prefs[] = 00228 { 00229 /* Okay, ulaw is used by all telephony equipment, so start with it */ 00230 AST_FORMAT_ULAW, 00231 /* Unless of course, you're a silly European, so then prefer ALAW */ 00232 AST_FORMAT_ALAW, 00233 /* Okay, well, signed linear is easy to translate into other stuff */ 00234 AST_FORMAT_SLINEAR, 00235 /* ADPCM has great sound quality and is still pretty easy to translate */ 00236 AST_FORMAT_ADPCM, 00237 /* Okay, we're down to vocoders now, so pick GSM because it's small and easier to 00238 translate and sounds pretty good */ 00239 AST_FORMAT_GSM, 00240 /* iLBC is not too bad */ 00241 AST_FORMAT_ILBC, 00242 /* Speex is free, but computationally more expensive than GSM */ 00243 AST_FORMAT_SPEEX, 00244 /* Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough 00245 to use it */ 00246 AST_FORMAT_LPC10, 00247 /* G.729a is faster than 723 and slightly less expensive */ 00248 AST_FORMAT_G729A, 00249 /* Down to G.723.1 which is proprietary but at least designed for voice */ 00250 AST_FORMAT_G723_1, 00251 /* Last and least, MP3 which was of course never designed for real-time voice */ 00252 AST_FORMAT_MP3, 00253 }; 00254 00255 00256 for (x=0;x<sizeof(prefs) / sizeof(prefs[0]); x++) 00257 if (fmts & prefs[x]) 00258 return prefs[x]; 00259 ast_log(LOG_WARNING, "Don't know any of 0x%x formats\n", fmts); 00260 return 0; 00261 } |
|
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 } |
|
Definition at line 1866 of file channel.c. References EVENT_FLAG_CALL, manager_event(), ast_channel::name, and ast_channel::uniqueid.
|
|
Create a channel structure. Returns NULL on failure to allocate Definition at line 263 of file channel.c. References ast_default_accountcode, ast_default_amaflags, AST_LIST_HEAD_INIT, AST_LIST_INSERT_HEAD, ast_log(), AST_MAX_FDS, ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, AST_STATE_DOWN, ast_var_assign(), channels, defaultlanguage, free, LOG_WARNING, malloc, and sched_context_create(). Referenced by ast_async_goto().
00264 { 00265 struct ast_channel *tmp; 00266 struct ast_channel_pvt *pvt; 00267 int x; 00268 int flags; 00269 struct varshead *headp; 00270 00271 00272 /* If shutting down, don't allocate any new channels */ 00273 if (shutting_down) 00274 return NULL; 00275 ast_mutex_lock(&chlock); 00276 tmp = malloc(sizeof(struct ast_channel)); 00277 if (tmp) { 00278 memset(tmp, 0, sizeof(struct ast_channel)); 00279 pvt = malloc(sizeof(struct ast_channel_pvt)); 00280 if (pvt) { 00281 memset(pvt, 0, sizeof(struct ast_channel_pvt)); 00282 tmp->sched = sched_context_create(); 00283 if (tmp->sched) { 00284 for (x=0;x<AST_MAX_FDS - 1;x++) 00285 tmp->fds[x] = -1; 00286 if (needqueue && 00287 pipe(pvt->alertpipe)) { 00288 ast_log(LOG_WARNING, "Alert pipe creation failed!\n"); 00289 free(pvt); 00290 free(tmp); 00291 tmp = NULL; 00292 pvt = NULL; 00293 } else { 00294 /* Make sure we've got it done right if they don't */ 00295 if (needqueue) { 00296 flags = fcntl(pvt->alertpipe[0], F_GETFL); 00297 fcntl(pvt->alertpipe[0], F_SETFL, flags | O_NONBLOCK); 00298 flags = fcntl(pvt->alertpipe[1], F_GETFL); 00299 fcntl(pvt->alertpipe[1], F_SETFL, flags | O_NONBLOCK); 00300 } else 00301 pvt->alertpipe[0] = pvt->alertpipe[1] = -1; 00302 #ifdef ZAPTEL_OPTIMIZATIONS 00303 tmp->timingfd = open("/dev/zap/timer", O_RDWR); 00304 #else 00305 tmp->timingfd = -1; 00306 #endif 00307 /* Always watch the alertpipe */ 00308 tmp->fds[AST_MAX_FDS-1] = pvt->alertpipe[0]; 00309 /* And timing pipe */ 00310 tmp->fds[AST_MAX_FDS-2] = tmp->timingfd; 00311 strncpy(tmp->name, "**Unknown**", sizeof(tmp->name)-1); 00312 tmp->pvt = pvt; 00313 /* Initial state */ 00314 tmp->_state = AST_STATE_DOWN; 00315 tmp->stack = -1; 00316 tmp->streamid = -1; 00317 tmp->appl = NULL; 00318 tmp->data = NULL; 00319 tmp->fin = 0; 00320 tmp->fout = 0; 00321 snprintf(tmp->uniqueid, sizeof(tmp->uniqueid), "%li.%d", (long)time(NULL), uniqueint++); 00322 headp=&tmp->varshead; 00323 ast_mutex_init(&tmp->lock); 00324 AST_LIST_HEAD_INIT(headp); 00325 tmp->vars=ast_var_assign("tempvar","tempval"); 00326 AST_LIST_INSERT_HEAD(headp,tmp->vars,entries); 00327 strncpy(tmp->context, "default", sizeof(tmp->context)-1); 00328 strncpy(tmp->language, defaultlanguage, sizeof(tmp->language)-1); 00329 strncpy(tmp->exten, "s", sizeof(tmp->exten)-1); 00330 tmp->priority=1; 00331 tmp->amaflags = ast_default_amaflags; 00332 strncpy(tmp->accountcode, ast_default_accountcode, sizeof(tmp->accountcode)-1); 00333 tmp->next = channels; 00334 channels= tmp; 00335 } 00336 } else { 00337 ast_log(LOG_WARNING, "Unable to create schedule context\n"); 00338 free(tmp); 00339 tmp = NULL; 00340 } 00341 } else { 00342 ast_log(LOG_WARNING, "Out of memory\n"); 00343 free(tmp); 00344 tmp = NULL; 00345 } 00346 } else 00347 ast_log(LOG_WARNING, "Out of memory\n"); 00348 ast_mutex_unlock(&chlock); 00349 return tmp; 00350 } |
|
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.
|
|
Free a channel structure.
Definition at line 489 of file channel.c. References ast_channel_pvt::alertpipe, ast_channel::ani, AST_CHANNEL_NAME, ast_device_state_changed(), ast_frfree(), AST_LIST_EMPTY, AST_LIST_FIRST, AST_LIST_REMOVE_HEAD, ast_log(), ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, ast_translator_free_path(), ast_var_delete(), ast_channel::callerid, channels, ast_channel::dnid, free, ast_channel::lock, LOG_WARNING, ast_channel::monitor, ast_channel::name, ast_channel::next, ast_frame::next, ast_channel::pbx, ast_channel::pvt, ast_channel_pvt::pvt, ast_channel::rdnis, ast_channel_pvt::readq, ast_channel_pvt::readtrans, ast_channel_monitor::stop, ast_channel::timingfd, and ast_channel_pvt::writetrans. Referenced by ast_hangup().
00490 { 00491 struct ast_channel *last=NULL, *cur; 00492 int fd; 00493 struct ast_var_t *vardata; 00494 struct ast_frame *f, *fp; 00495 struct varshead *headp; 00496 char name[AST_CHANNEL_NAME]; 00497 00498 headp=&chan->varshead; 00499 00500 ast_mutex_lock(&chlock); 00501 cur = channels; 00502 while(cur) { 00503 if (cur == chan) { 00504 if (last) 00505 last->next = cur->next; 00506 else 00507 channels = cur->next; 00508 break; 00509 } 00510 last = cur; 00511 cur = cur->next; 00512 } 00513 if (!cur) 00514 ast_log(LOG_WARNING, "Unable to find channel in list\n"); 00515 if (chan->pvt->pvt) 00516 ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name); 00517 00518 strncpy(name, chan->name, sizeof(name)-1); 00519 00520 /* Stop monitoring */ 00521 if (chan->monitor) { 00522 chan->monitor->stop( chan, 0 ); 00523 } 00524 00525 /* Free translatosr */ 00526 if (chan->pvt->readtrans) 00527 ast_translator_free_path(chan->pvt->readtrans); 00528 if (chan->pvt->writetrans) 00529 ast_translator_free_path(chan->pvt->writetrans); 00530 if (chan->pbx) 00531 ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name); 00532 if (chan->dnid) 00533 free(chan->dnid); 00534 if (chan->callerid) 00535 free(chan->callerid); 00536 if (chan->ani) 00537 free(chan->ani); 00538 if (chan->rdnis) 00539 free(chan->rdnis); 00540 ast_mutex_destroy(&chan->lock); 00541 /* Close pipes if appropriate */ 00542 if ((fd = chan->pvt->alertpipe[0]) > -1) 00543 close(fd); 00544 if ((fd = chan->pvt->alertpipe[1]) > -1) 00545 close(fd); 00546 if ((fd = chan->timingfd) > -1) 00547 close(fd); 00548 f = chan->pvt->readq; 00549 chan->pvt->readq = NULL; 00550 while(f) { 00551 fp = f; 00552 f = f->next; 00553 ast_frfree(fp); 00554 } 00555 00556 /* loop over the variables list, freeing all data and deleting list items */ 00557 /* no need to lock the list, as the channel is already locked */ 00558 00559 while (!AST_LIST_EMPTY(headp)) { /* List Deletion. */ 00560 vardata = AST_LIST_FIRST(headp); 00561 AST_LIST_REMOVE_HEAD(headp, entries); 00562 // printf("deleting var %s=%s\n",ast_var_name(vardata),ast_var_value(vardata)); 00563 ast_var_delete(vardata); 00564 } 00565 00566 00567 free(chan->pvt); 00568 chan->pvt = NULL; 00569 free(chan); 00570 ast_mutex_unlock(&chlock); 00571 00572 ast_device_state_changed(name); 00573 } |
|
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 } |
|
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, chanlist::next, ast_channel::next, option_debug, type, and ast_channel::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, ast_channel_pvt::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 } |
|
Definition at line 409 of file channel.c. References AST_FRAME_CONTROL, ast_queue_frame(), and ast_frame::subclass.
00410 { 00411 struct ast_frame f = { AST_FRAME_CONTROL, }; 00412 f.subclass = control; 00413 return ast_queue_frame(chan, &f, lock); 00414 } |
|
Queue an outgoing frame, locking if necessary Definition at line 352 of file channel.c. References ast_channel_pvt::alertpipe, AST_FRAME_VOICE, ast_frdup(), ast_frfree(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_channel::blocker, ast_channel::blocking, CRASH, ast_frame::frametype, ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_frame::next, ast_channel::pvt, and ast_channel_pvt::readq. Referenced by ast_channel_masquerade(), ast_dsp_process(), ast_queue_control(), ast_queue_hangup(), and ast_softhangup_nolock().
00353 { 00354 struct ast_frame *f; 00355 struct ast_frame *prev, *cur; 00356 int blah = 1; 00357 int qlen = 0; 00358 /* Build us a copy and free the original one */ 00359 f = ast_frdup(fin); 00360 if (!f) { 00361 ast_log(LOG_WARNING, "Unable to duplicate frame\n"); 00362 return -1; 00363 } 00364 if (lock) 00365 ast_mutex_lock(&chan->lock); 00366 prev = NULL; 00367 cur = chan->pvt->readq; 00368 while(cur) { 00369 prev = cur; 00370 cur = cur->next; 00371 qlen++; 00372 } 00373 /* Allow up to 96 voice frames outstanding, and up to 128 total frames */ 00374 if (((fin->frametype == AST_FRAME_VOICE) && (qlen > 96)) || (qlen > 128)) { 00375 if (fin->frametype != AST_FRAME_VOICE) { 00376 ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name); 00377 CRASH; 00378 } else { 00379 ast_log(LOG_DEBUG, "Dropping voice to exceptionally long queue on %s\n", chan->name); 00380 ast_frfree(f); 00381 if (lock) 00382 ast_mutex_unlock(&chan->lock); 00383 return 0; 00384 } 00385 } 00386 if (prev) 00387 prev->next = f; 00388 else 00389 chan->pvt->readq = f; 00390 if (chan->pvt->alertpipe[1] > -1) { 00391 if (write(chan->pvt->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah)) 00392 ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d (qlen = %d): %s!\n", 00393 chan->name, f->frametype, f->subclass, qlen, strerror(errno)); 00394 } else if (chan->blocking) { 00395 pthread_kill(chan->blocker, SIGURG); 00396 } 00397 if (lock) 00398 ast_mutex_unlock(&chan->lock); 00399 return 0; 00400 } |
|
Definition at line 402 of file channel.c. References ast_channel::_softhangup, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, ast_queue_frame(), and AST_SOFTHANGUP_DEV.
00403 { 00404 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP }; 00405 chan->_softhangup |= AST_SOFTHANGUP_DEV; 00406 return ast_queue_frame(chan, &f, lock); 00407 } |
|
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::exception, ast_channel_pvt::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, type, ast_channel::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 } |
|
Change the state of a channel Definition at line 2096 of file channel.c. References ast_channel::_state, ast_device_state_changed(), ast_state2str(), AST_STATE_DOWN, ast_channel::callerid, EVENT_FLAG_CALL, manager_event(), ast_channel::name, and ast_channel::uniqueid. Referenced by ast_answer(), ast_async_goto(), and ast_read().
02097 { 02098 if (chan->_state != state) { 02099 int oldstate = chan->_state; 02100 chan->_state = state; 02101 if (oldstate == AST_STATE_DOWN) { 02102 ast_device_state_changed(chan->name); 02103 manager_event(EVENT_FLAG_CALL, "Newchannel", 02104 "Channel: %s\r\n" 02105 "State: %s\r\n" 02106 "Callerid: %s\r\n" 02107 "Uniqueid: %s\r\n", 02108 chan->name, ast_state2str(chan->_state), chan->callerid ? chan->callerid : "<unknown>", chan->uniqueid); 02109 } else { 02110 manager_event(EVENT_FLAG_CALL, "Newstate", 02111 "Channel: %s\r\n" 02112 "State: %s\r\n" 02113 "Callerid: %s\r\n" 02114 "Uniqueid: %s\r\n", 02115 chan->name, ast_state2str(chan->_state), chan->callerid ? chan->callerid : "<unknown>", chan->uniqueid); 02116 } 02117 } 02118 return 0; 02119 } |
|
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 } |
|
Referenced by ast_channel_register_ex(), ast_channel_unregister(), ast_device_state(), and ast_request(). |
|
Definition at line 61 of file channel.c. Referenced by ast_active_channels(), ast_begin_shutdown(), ast_channel_alloc(), ast_channel_free(), and ast_channel_walk(). |