Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

channel.c

Go to the documentation of this file.
00001 /* 00002 * Asterisk -- A telephony toolkit for Linux. 00003 * 00004 * Channel Management 00005 * 00006 * Copyright (C) 1999, Mark Spencer 00007 * 00008 * Mark Spencer <markster@linux-support.net> 00009 * 00010 * This program is free software, distributed under the terms of 00011 * the GNU General Public License 00012 */ 00013 00014 #include <stdio.h> 00015 #include <stdlib.h> 00016 #include <pthread.h> 00017 #include <string.h> 00018 #include <sys/time.h> 00019 #include <signal.h> 00020 #include <errno.h> 00021 #include <unistd.h> 00022 #include <math.h> /* For PI */ 00023 #include <sys/poll.h> 00024 #include <asterisk/pbx.h> 00025 #include <asterisk/frame.h> 00026 #include <asterisk/sched.h> 00027 #include <asterisk/options.h> 00028 #include <asterisk/channel.h> 00029 #include <asterisk/channel_pvt.h> 00030 #include <asterisk/logger.h> 00031 #include <asterisk/say.h> 00032 #include <asterisk/file.h> 00033 #include <asterisk/translate.h> 00034 #include <asterisk/manager.h> 00035 #include <asterisk/chanvars.h> 00036 #include <asterisk/linkedlists.h> 00037 #include <asterisk/indications.h> 00038 #include <asterisk/monitor.h> 00039 #include <asterisk/causes.h> 00040 #include <asterisk/utils.h> 00041 #ifdef ZAPTEL_OPTIMIZATIONS 00042 #include <sys/ioctl.h> 00043 #ifdef __linux__ 00044 #include <linux/zaptel.h> 00045 #else 00046 #include <zaptel.h> 00047 #endif /* __linux__ */ 00048 #ifndef ZT_TIMERPING 00049 #error "You need newer zaptel! Please cvs update zaptel" 00050 #endif 00051 #endif 00052 00053 /* uncomment if you have problems with 'monitoring' synchronized files */ 00054 #if 0 00055 #define MONITOR_CONSTANT_DELAY 00056 #define MONITOR_DELAY 150 * 8 /* 150 ms of MONITORING DELAY */ 00057 #endif 00058 00059 static int shutting_down = 0; 00060 static int uniqueint = 0; 00061 00062 /* XXX Lock appropriately in more functions XXX */ 00063 00064 struct chanlist { 00065 char type[80]; 00066 char description[80]; 00067 int capabilities; 00068 struct ast_channel * (*requester)(char *type, int format, void *data); 00069 int (*devicestate)(void *data); 00070 struct chanlist *next; 00071 } *backends = NULL; 00072 struct ast_channel *channels = NULL; 00073 00074 /* Protect the channel list (highly unlikely that two things would change 00075 it at the same time, but still! */ 00076 00077 AST_MUTEX_DEFINE_STATIC(chlock); 00078 00079 int ast_check_hangup(struct ast_channel *chan) 00080 { 00081 time_t myt; 00082 00083 /* if soft hangup flag, return true */ 00084 if (chan->_softhangup) return 1; 00085 /* if no private structure, return true */ 00086 if (!chan->pvt->pvt) return 1; 00087 /* if no hangup scheduled, just return here */ 00088 if (!chan->whentohangup) return 0; 00089 time(&myt); /* get current time */ 00090 /* return, if not yet */ 00091 if (chan->whentohangup > myt) return 0; 00092 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 00093 return 1; 00094 } 00095 00096 static int ast_check_hangup_locked(struct ast_channel *chan) 00097 { 00098 int res; 00099 ast_mutex_lock(&chan->lock); 00100 res = ast_check_hangup(chan); 00101 ast_mutex_unlock(&chan->lock); 00102 return res; 00103 } 00104 00105 void ast_begin_shutdown(int hangup) 00106 { 00107 struct ast_channel *c; 00108 shutting_down = 1; 00109 if (hangup) { 00110 ast_mutex_lock(&chlock); 00111 c = channels; 00112 while(c) { 00113 ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN); 00114 c = c->next; 00115 } 00116 ast_mutex_unlock(&chlock); 00117 } 00118 } 00119 00120 int ast_active_channels(void) 00121 { 00122 struct ast_channel *c; 00123 int cnt = 0; 00124 ast_mutex_lock(&chlock); 00125 c = channels; 00126 while(c) { 00127 cnt++; 00128 c = c->next; 00129 } 00130 ast_mutex_unlock(&chlock); 00131 return cnt; 00132 } 00133 00134 void ast_cancel_shutdown(void) 00135 { 00136 shutting_down = 0; 00137 } 00138 00139 int ast_shutting_down(void) 00140 { 00141 return shutting_down; 00142 } 00143 00144 void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset) 00145 { 00146 time_t myt; 00147 00148 time(&myt); 00149 if (offset) 00150 chan->whentohangup = myt + offset; 00151 else 00152 chan->whentohangup = 0; 00153 return; 00154 } 00155 00156 int ast_channel_register(char *type, char *description, int capabilities, 00157 struct ast_channel *(*requester)(char *type, int format, void *data)) 00158 { 00159 return ast_channel_register_ex(type, description, capabilities, requester, NULL); 00160 } 00161 00162 int ast_channel_register_ex(char *type, char *description, int capabilities, 00163 struct ast_channel *(*requester)(char *type, int format, void *data), 00164 int (*devicestate)(void *data)) 00165 { 00166 struct chanlist *chan, *last=NULL; 00167 if (ast_mutex_lock(&chlock)) { 00168 ast_log(LOG_WARNING, "Unable to lock channel list\n"); 00169 return -1; 00170 } 00171 chan = backends; 00172 while(chan) { 00173 if (!strcasecmp(type, chan->type)) { 00174 ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", type); 00175 ast_mutex_unlock(&chlock); 00176 return -1; 00177 } 00178 last = chan; 00179 chan = chan->next; 00180 } 00181 chan = malloc(sizeof(struct chanlist)); 00182 if (!chan) { 00183 ast_log(LOG_WARNING, "Out of memory\n"); 00184 ast_mutex_unlock(&chlock); 00185 return -1; 00186 } 00187 strncpy(chan->type, type, sizeof(chan->type)-1); 00188 strncpy(chan->description, description, sizeof(chan->description)-1); 00189 chan->capabilities = capabilities; 00190 chan->requester = requester; 00191 chan->devicestate = devicestate; 00192 chan->next = NULL; 00193 if (last) 00194 last->next = chan; 00195 else 00196 backends = chan; 00197 if (option_debug) 00198 ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->type, chan->description); 00199 else if (option_verbose > 1) 00200 ast_verbose( VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->type, chan->description); 00201 ast_mutex_unlock(&chlock); 00202 return 0; 00203 } 00204 00205 char *ast_state2str(int state) 00206 { 00207 /* XXX Not reentrant XXX */ 00208 static char localtmp[256]; 00209 switch(state) { 00210 case AST_STATE_DOWN: 00211 return "Down"; 00212 case AST_STATE_RESERVED: 00213 return "Rsrvd"; 00214 case AST_STATE_OFFHOOK: 00215 return "OffHook"; 00216 case AST_STATE_DIALING: 00217 return "Dialing"; 00218 case AST_STATE_RING: 00219 return "Ring"; 00220 case AST_STATE_RINGING: 00221 return "Ringing"; 00222 case AST_STATE_UP: 00223 return "Up"; 00224 case AST_STATE_BUSY: 00225 return "Busy"; 00226 default: 00227 snprintf(localtmp, sizeof(localtmp), "Unknown (%d)\n", state); 00228 return localtmp; 00229 } 00230 } 00231 00232 00233 int ast_best_codec(int fmts) 00234 { 00235 /* This just our opinion, expressed in code. We are asked to choose 00236 the best codec to use, given no information */ 00237 int x; 00238 static int prefs[] = 00239 { 00240 /* Okay, ulaw is used by all telephony equipment, so start with it */ 00241 AST_FORMAT_ULAW, 00242 /* Unless of course, you're a silly European, so then prefer ALAW */ 00243 AST_FORMAT_ALAW, 00244 /* Okay, well, signed linear is easy to translate into other stuff */ 00245 AST_FORMAT_SLINEAR, 00246 /* G.726 is standard ADPCM */ 00247 AST_FORMAT_G726, 00248 /* ADPCM has great sound quality and is still pretty easy to translate */ 00249 AST_FORMAT_ADPCM, 00250 /* Okay, we're down to vocoders now, so pick GSM because it's small and easier to 00251 translate and sounds pretty good */ 00252 AST_FORMAT_GSM, 00253 /* iLBC is not too bad */ 00254 AST_FORMAT_ILBC, 00255 /* Speex is free, but computationally more expensive than GSM */ 00256 AST_FORMAT_SPEEX, 00257 /* Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough 00258 to use it */ 00259 AST_FORMAT_LPC10, 00260 /* G.729a is faster than 723 and slightly less expensive */ 00261 AST_FORMAT_G729A, 00262 /* Down to G.723.1 which is proprietary but at least designed for voice */ 00263 AST_FORMAT_G723_1, 00264 }; 00265 00266 00267 for (x=0;x<sizeof(prefs) / sizeof(prefs[0]); x++) 00268 if (fmts & prefs[x]) 00269 return prefs[x]; 00270 ast_log(LOG_WARNING, "Don't know any of 0x%x formats\n", fmts); 00271 return 0; 00272 } 00273 00274 struct ast_channel *ast_channel_alloc(int needqueue) 00275 { 00276 struct ast_channel *tmp; 00277 struct ast_channel_pvt *pvt; 00278 int x; 00279 int flags; 00280 struct varshead *headp; 00281 00282 00283 /* If shutting down, don't allocate any new channels */ 00284 if (shutting_down) 00285 return NULL; 00286 ast_mutex_lock(&chlock); 00287 tmp = malloc(sizeof(struct ast_channel)); 00288 if (tmp) { 00289 memset(tmp, 0, sizeof(struct ast_channel)); 00290 pvt = malloc(sizeof(struct ast_channel_pvt)); 00291 if (pvt) { 00292 memset(pvt, 0, sizeof(struct ast_channel_pvt)); 00293 tmp->sched = sched_context_create(); 00294 if (tmp->sched) { 00295 for (x=0;x<AST_MAX_FDS - 1;x++) 00296 tmp->fds[x] = -1; 00297 #ifdef ZAPTEL_OPTIMIZATIONS 00298 tmp->timingfd = open("/dev/zap/timer", O_RDWR); 00299 if (tmp->timingfd > -1) { 00300 /* Check if timing interface supports new 00301 ping/pong scheme */ 00302 flags = 1; 00303 if (!ioctl(tmp->timingfd, ZT_TIMERPONG, &flags)) 00304 needqueue = 0; 00305 } 00306 #else 00307 tmp->timingfd = -1; 00308 #endif 00309 if (needqueue && 00310 pipe(pvt->alertpipe)) { 00311 ast_log(LOG_WARNING, "Alert pipe creation failed!\n"); 00312 free(pvt); 00313 free(tmp); 00314 tmp = NULL; 00315 pvt = NULL; 00316 } else { 00317 if (needqueue) { 00318 flags = fcntl(pvt->alertpipe[0], F_GETFL); 00319 fcntl(pvt->alertpipe[0], F_SETFL, flags | O_NONBLOCK); 00320 flags = fcntl(pvt->alertpipe[1], F_GETFL); 00321 fcntl(pvt->alertpipe[1], F_SETFL, flags | O_NONBLOCK); 00322 } else 00323 /* Make sure we've got it done right if they don't */ 00324 pvt->alertpipe[0] = pvt->alertpipe[1] = -1; 00325 /* Always watch the alertpipe */ 00326 tmp->fds[AST_MAX_FDS-1] = pvt->alertpipe[0]; 00327 /* And timing pipe */ 00328 tmp->fds[AST_MAX_FDS-2] = tmp->timingfd; 00329 strncpy(tmp->name, "**Unknown**", sizeof(tmp->name)-1); 00330 tmp->pvt = pvt; 00331 /* Initial state */ 00332 tmp->_state = AST_STATE_DOWN; 00333 tmp->stack = -1; 00334 tmp->streamid = -1; 00335 tmp->appl = NULL; 00336 tmp->data = NULL; 00337 tmp->fin = 0; 00338 tmp->fout = 0; 00339 snprintf(tmp->uniqueid, sizeof(tmp->uniqueid), "%li.%d", (long)time(NULL), uniqueint++); 00340 headp=&tmp->varshead; 00341 ast_mutex_init(&tmp->lock); 00342 AST_LIST_HEAD_INIT(headp); 00343 tmp->vars=ast_var_assign("tempvar","tempval"); 00344 AST_LIST_INSERT_HEAD(headp,tmp->vars,entries); 00345 strncpy(tmp->context, "default", sizeof(tmp->context)-1); 00346 strncpy(tmp->language, defaultlanguage, sizeof(tmp->language)-1); 00347 strncpy(tmp->exten, "s", sizeof(tmp->exten)-1); 00348 tmp->priority=1; 00349 tmp->amaflags = ast_default_amaflags; 00350 strncpy(tmp->accountcode, ast_default_accountcode, sizeof(tmp->accountcode)-1); 00351 tmp->next = channels; 00352 channels= tmp; 00353 } 00354 } else { 00355 ast_log(LOG_WARNING, "Unable to create schedule context\n"); 00356 free(tmp); 00357 tmp = NULL; 00358 } 00359 } else { 00360 ast_log(LOG_WARNING, "Out of memory\n"); 00361 free(tmp); 00362 tmp = NULL; 00363 } 00364 } else 00365 ast_log(LOG_WARNING, "Out of memory\n"); 00366 ast_mutex_unlock(&chlock); 00367 return tmp; 00368 } 00369 00370 int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin) 00371 { 00372 struct ast_frame *f; 00373 struct ast_frame *prev, *cur; 00374 int blah = 1; 00375 int qlen = 0; 00376 /* Build us a copy and free the original one */ 00377 f = ast_frdup(fin); 00378 if (!f) { 00379 ast_log(LOG_WARNING, "Unable to duplicate frame\n"); 00380 return -1; 00381 } 00382 ast_mutex_lock(&chan->lock); 00383 prev = NULL; 00384 cur = chan->pvt->readq; 00385 while(cur) { 00386 prev = cur; 00387 cur = cur->next; 00388 qlen++; 00389 } 00390 /* Allow up to 96 voice frames outstanding, and up to 128 total frames */ 00391 if (((fin->frametype == AST_FRAME_VOICE) && (qlen > 96)) || (qlen > 128)) { 00392 if (fin->frametype != AST_FRAME_VOICE) { 00393 ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name); 00394 CRASH; 00395 } else { 00396 ast_log(LOG_DEBUG, "Dropping voice to exceptionally long queue on %s\n", chan->name); 00397 ast_frfree(f); 00398 ast_mutex_unlock(&chan->lock); 00399 return 0; 00400 } 00401 } 00402 if (prev) 00403 prev->next = f; 00404 else 00405 chan->pvt->readq = f; 00406 if (chan->pvt->alertpipe[1] > -1) { 00407 if (write(chan->pvt->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah)) 00408 ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d (qlen = %d): %s!\n", 00409 chan->name, f->frametype, f->subclass, qlen, strerror(errno)); 00410 #ifdef ZAPTEL_OPTIMIZATIONS 00411 } else if (chan->timingfd > -1) { 00412 ioctl(chan->timingfd, ZT_TIMERPING, &blah); 00413 #endif 00414 } else if (chan->blocking) { 00415 pthread_kill(chan->blocker, SIGURG); 00416 } 00417 ast_mutex_unlock(&chan->lock); 00418 return 0; 00419 } 00420 00421 int ast_queue_hangup(struct ast_channel *chan) 00422 { 00423 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP }; 00424 chan->_softhangup |= AST_SOFTHANGUP_DEV; 00425 return ast_queue_frame(chan, &f); 00426 } 00427 00428 int ast_queue_control(struct ast_channel *chan, int control) 00429 { 00430 struct ast_frame f = { AST_FRAME_CONTROL, }; 00431 f.subclass = control; 00432 return ast_queue_frame(chan, &f); 00433 } 00434 00435 int ast_channel_defer_dtmf(struct ast_channel *chan) 00436 { 00437 int pre = 0; 00438 if (chan) { 00439 pre = chan->deferdtmf; 00440 chan->deferdtmf = 1; 00441 } 00442 return pre; 00443 } 00444 00445 void ast_channel_undefer_dtmf(struct ast_channel *chan) 00446 { 00447 if (chan) 00448 chan->deferdtmf = 0; 00449 } 00450 00451 struct ast_channel *ast_channel_walk_locked(struct ast_channel *prev) 00452 { 00453 /* Returns next channel (locked) */ 00454 struct ast_channel *l, *ret=NULL; 00455 ast_mutex_lock(&chlock); 00456 l = channels; 00457 if (!prev) { 00458 if (l) 00459 ast_mutex_lock(&l->lock); 00460 ast_mutex_unlock(&chlock); 00461 return l; 00462 } 00463 while(l) { 00464 if (l == prev) 00465 ret = l->next; 00466 l = l->next; 00467 } 00468 if (ret) 00469 ast_mutex_lock(&ret->lock); 00470 ast_mutex_unlock(&chlock); 00471 return ret; 00472 00473 } 00474 00475 struct ast_channel *ast_get_channel_by_name_locked(char *channame) 00476 { 00477 struct ast_channel *chan; 00478 chan = ast_channel_walk_locked(NULL); 00479 while(chan) { 00480 if (!strcasecmp(chan->name, channame)) 00481 return chan; 00482 ast_mutex_unlock(&chan->lock); 00483 chan = ast_channel_walk_locked(chan); 00484 } 00485 return NULL; 00486 } 00487 00488 int ast_safe_sleep_conditional( struct ast_channel *chan, int ms, 00489 int (*cond)(void*), void *data ) 00490 { 00491 struct ast_frame *f; 00492 00493 while(ms > 0) { 00494 if( cond && ((*cond)(data) == 0 ) ) 00495 return 0; 00496 ms = ast_waitfor(chan, ms); 00497 if (ms <0) 00498 return -1; 00499 if (ms > 0) { 00500 f = ast_read(chan); 00501 if (!f) 00502 return -1; 00503 ast_frfree(f); 00504 } 00505 } 00506 return 0; 00507 } 00508 00509 int ast_safe_sleep(struct ast_channel *chan, int ms) 00510 { 00511 struct ast_frame *f; 00512 while(ms > 0) { 00513 ms = ast_waitfor(chan, ms); 00514 if (ms <0) 00515 return -1; 00516 if (ms > 0) { 00517 f = ast_read(chan); 00518 if (!f) 00519 return -1; 00520 ast_frfree(f); 00521 } 00522 } 00523 return 0; 00524 } 00525 00526 void ast_channel_free(struct ast_channel *chan) 00527 { 00528 struct ast_channel *last=NULL, *cur; 00529 int fd; 00530 struct ast_var_t *vardata; 00531 struct ast_frame *f, *fp; 00532 struct varshead *headp; 00533 char name[AST_CHANNEL_NAME]; 00534 00535 headp=&chan->varshead; 00536 00537 ast_mutex_lock(&chlock); 00538 cur = channels; 00539 while(cur) { 00540 if (cur == chan) { 00541 if (last) 00542 last->next = cur->next; 00543 else 00544 channels = cur->next; 00545 break; 00546 } 00547 last = cur; 00548 cur = cur->next; 00549 } 00550 if (!cur) 00551 ast_log(LOG_WARNING, "Unable to find channel in list\n"); 00552 else { 00553 /* Lock and unlock the channel just to be sure nobody 00554 has it locked still */ 00555 ast_mutex_lock(&cur->lock); 00556 ast_mutex_unlock(&cur->lock); 00557 } 00558 if (chan->pvt->pvt) 00559 ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name); 00560 00561 strncpy(name, chan->name, sizeof(name)-1); 00562 00563 /* Stop monitoring */ 00564 if (chan->monitor) { 00565 chan->monitor->stop( chan, 0 ); 00566 } 00567 00568 /* Free translatosr */ 00569 if (chan->pvt->readtrans) 00570 ast_translator_free_path(chan->pvt->readtrans); 00571 if (chan->pvt->writetrans) 00572 ast_translator_free_path(chan->pvt->writetrans); 00573 if (chan->pbx) 00574 ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name); 00575 if (chan->dnid) 00576 free(chan->dnid); 00577 if (chan->callerid) 00578 free(chan->callerid); 00579 if (chan->ani) 00580 free(chan->ani); 00581 if (chan->rdnis) 00582 free(chan->rdnis); 00583 ast_mutex_destroy(&chan->lock); 00584 /* Close pipes if appropriate */ 00585 if ((fd = chan->pvt->alertpipe[0]) > -1) 00586 close(fd); 00587 if ((fd = chan->pvt->alertpipe[1]) > -1) 00588 close(fd); 00589 if ((fd = chan->timingfd) > -1) 00590 close(fd); 00591 f = chan->pvt->readq; 00592 chan->pvt->readq = NULL; 00593 while(f) { 00594 fp = f; 00595 f = f->next; 00596 ast_frfree(fp); 00597 } 00598 00599 /* loop over the variables list, freeing all data and deleting list items */ 00600 /* no need to lock the list, as the channel is already locked */ 00601 00602 while (!AST_LIST_EMPTY(headp)) { /* List Deletion. */ 00603 vardata = AST_LIST_FIRST(headp); 00604 AST_LIST_REMOVE_HEAD(headp, entries); 00605 // printf("deleting var %s=%s\n",ast_var_name(vardata),ast_var_value(vardata)); 00606 ast_var_delete(vardata); 00607 } 00608 00609 00610 free(chan->pvt); 00611 chan->pvt = NULL; 00612 free(chan); 00613 ast_mutex_unlock(&chlock); 00614 00615 ast_device_state_changed(name); 00616 } 00617 00618 int ast_softhangup_nolock(struct ast_channel *chan, int cause) 00619 { 00620 int res = 0; 00621 struct ast_frame f = { AST_FRAME_NULL }; 00622 if (option_debug) 00623 ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name); 00624 /* Inform channel driver that we need to be hung up, if it cares */ 00625 chan->_softhangup |= cause; 00626 ast_queue_frame(chan, &f); 00627 /* Interrupt any poll call or such */ 00628 if (chan->blocking) 00629 pthread_kill(chan->blocker, SIGURG); 00630 return res; 00631 } 00632 00633 int ast_softhangup(struct ast_channel *chan, int cause) 00634 { 00635 int res; 00636 ast_mutex_lock(&chan->lock); 00637 res = ast_softhangup_nolock(chan, cause); 00638 ast_mutex_unlock(&chan->lock); 00639 return res; 00640 } 00641 00642 static void free_translation(struct ast_channel *clone) 00643 { 00644 if (clone->pvt->writetrans) 00645 ast_translator_free_path(clone->pvt->writetrans); 00646 if (clone->pvt->readtrans) 00647 ast_translator_free_path(clone->pvt->readtrans); 00648 clone->pvt->writetrans = NULL; 00649 clone->pvt->readtrans = NULL; 00650 clone->pvt->rawwriteformat = clone->nativeformats; 00651 clone->pvt->rawreadformat = clone->nativeformats; 00652 } 00653 00654 int ast_hangup(struct ast_channel *chan) 00655 { 00656 int res = 0; 00657 /* Don't actually hang up a channel that will masquerade as someone else, or 00658 if someone is going to masquerade as us */ 00659 ast_mutex_lock(&chan->lock); 00660 if (chan->masq) { 00661 if (ast_do_masquerade(chan)) 00662 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 00663 } 00664 00665 if (chan->masq) { 00666 ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name); 00667 ast_mutex_unlock(&chan->lock); 00668 return 0; 00669 } 00670 /* If this channel is one which will be masqueraded into something, 00671 mark it as a zombie already, so we know to free it later */ 00672 if (chan->masqr) { 00673 chan->zombie=1; 00674 ast_mutex_unlock(&chan->lock); 00675 return 0; 00676 } 00677 free_translation(chan); 00678 if (chan->stream) 00679 ast_closestream(chan->stream); 00680 if (chan->vstream) 00681 ast_closestream(chan->vstream); 00682 if (chan->sched) 00683 sched_context_destroy(chan->sched); 00684 /* Clear any tone stuff remaining */ 00685 if (chan->generatordata) 00686 chan->generator->release(chan, chan->generatordata); 00687 chan->generatordata = NULL; 00688 chan->generator = NULL; 00689 if (chan->cdr) { 00690 /* End the CDR if it hasn't already */ 00691 ast_cdr_end(chan->cdr); 00692 /* Post and Free the CDR */ 00693 ast_cdr_post(chan->cdr); 00694 ast_cdr_free(chan->cdr); 00695 } 00696 if (chan->blocking) { 00697 ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd " 00698 "is blocked by thread %ld in procedure %s! Expect a failure\n", 00699 (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc); 00700 CRASH; 00701 } 00702 if (!chan->zombie) { 00703 if (option_debug) 00704 ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name); 00705 if (chan->pvt->hangup) 00706 res = chan->pvt->hangup(chan); 00707 } else 00708 if (option_debug) 00709 ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name); 00710 00711 ast_mutex_unlock(&chan->lock); 00712 manager_event(EVENT_FLAG_CALL, "Hangup", 00713 "Channel: %s\r\n" 00714 "Uniqueid: %s\r\n" 00715 "Cause: %i\r\n", 00716 chan->name, chan->uniqueid, chan->hangupcause); 00717 ast_channel_free(chan); 00718 return res; 00719 } 00720 00721 void ast_channel_unregister(char *type) 00722 { 00723 struct chanlist *chan, *last=NULL; 00724 if (option_debug) 00725 ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", type); 00726 if (ast_mutex_lock(&chlock)) { 00727 ast_log(LOG_WARNING, "Unable to lock channel list\n"); 00728 return; 00729 } 00730 if (option_verbose > 1) 00731 ast_verbose( VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", type); 00732 00733 chan = backends; 00734 while(chan) { 00735 if (!strcasecmp(chan->type, type)) { 00736 if (last) 00737 last->next = chan->next; 00738 else 00739 backends = backends->next; 00740 free(chan); 00741 ast_mutex_unlock(&chlock); 00742 return; 00743 } 00744 last = chan; 00745 chan = chan->next; 00746 } 00747 ast_mutex_unlock(&chlock); 00748 } 00749 00750 int ast_answer(struct ast_channel *chan) 00751 { 00752 int res = 0; 00753 /* Stop if we're a zombie or need a soft hangup */ 00754 if (chan->zombie || ast_check_hangup(chan)) 00755 return -1; 00756 switch(chan->_state) { 00757 case AST_STATE_RINGING: 00758 case AST_STATE_RING: 00759 ast_mutex_lock(&chan->lock); 00760 if (chan->pvt->answer) 00761 res = chan->pvt->answer(chan); 00762 ast_mutex_unlock(&chan->lock); 00763 ast_setstate(chan, AST_STATE_UP); 00764 if (chan->cdr) 00765 ast_cdr_answer(chan->cdr); 00766 return res; 00767 break; 00768 case AST_STATE_UP: 00769 if (chan->cdr) 00770 ast_cdr_answer(chan->cdr); 00771 break; 00772 } 00773 return 0; 00774 } 00775 00776 00777 00778 void ast_deactivate_generator(struct ast_channel *chan) 00779 { 00780 ast_mutex_lock(&chan->lock); 00781 if (chan->generatordata) { 00782 if (chan->generator && chan->generator->release) 00783 chan->generator->release(chan, chan->generatordata); 00784 chan->generatordata = NULL; 00785 chan->generator = NULL; 00786 chan->writeinterrupt = 0; 00787 } 00788 ast_mutex_unlock(&chan->lock); 00789 } 00790 00791 int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, void *params) 00792 { 00793 int res = 0; 00794 ast_mutex_lock(&chan->lock); 00795 if (chan->generatordata) { 00796 if (chan->generator && chan->generator->release) 00797 chan->generator->release(chan, chan->generatordata); 00798 chan->generatordata = NULL; 00799 } 00800 ast_prod(chan); 00801 if ((chan->generatordata = gen->alloc(chan, params))) { 00802 chan->generator = gen; 00803 } else { 00804 res = -1; 00805 } 00806 ast_mutex_unlock(&chan->lock); 00807 return res; 00808 } 00809 00810 int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception) 00811 { 00812 /* Wait for x amount of time on a file descriptor to have input. */ 00813 struct timeval start, now; 00814 int res; 00815 int x, y; 00816 int winner = -1; 00817 int spoint; 00818 struct pollfd *pfds; 00819 00820 pfds = alloca(sizeof(struct pollfd) * n); 00821 if (!pfds) { 00822 ast_log(LOG_WARNING, "alloca failed! bad things will happen.\n"); 00823 return -1; 00824 } 00825 if (*ms > 0) 00826 gettimeofday(&start, NULL); 00827 y = 0; 00828 for (x=0;x<n;x++) { 00829 if (fds[x] > -1) { 00830 pfds[y].fd = fds[x]; 00831 pfds[y].events = POLLIN | POLLPRI; 00832 y++; 00833 } 00834 } 00835 res = poll(pfds, y, *ms); 00836 if (res < 0) { 00837 /* Simulate a timeout if we were interrupted */ 00838 if (errno != EINTR) 00839 *ms = -1; 00840 else 00841 *ms = 0; 00842 return -1; 00843 } 00844 spoint = 0; 00845 for (x=0;x<n;x++) { 00846 if (fds[x] > -1) { 00847 if ((res = ast_fdisset(pfds, fds[x], y, &spoint))) { 00848 winner = fds[x]; 00849 if (exception) { 00850 if (res & POLLPRI) 00851 *exception = -1; 00852 else 00853 *exception = 0; 00854 } 00855 } 00856 } 00857 } 00858 if (*ms > 0) { 00859 long passed; 00860 gettimeofday(&now, NULL); 00861 passed = (now.tv_sec - start.tv_sec) * 1000; 00862 passed += (now.tv_usec - start.tv_usec) / 1000; 00863 if (passed <= *ms) 00864 *ms -= passed; 00865 else 00866 *ms = 0; 00867 } 00868 return winner; 00869 } 00870 00871 struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds, int nfds, 00872 int *exception, int *outfd, int *ms) 00873 { 00874 /* Wait for x amount of time on a file descriptor to have input. */ 00875 struct timeval start, end; 00876 struct pollfd *pfds; 00877 int res; 00878 long rms; 00879 int x, y, max; 00880 int spoint; 00881 time_t now = 0; 00882 long whentohangup = 0, havewhen = 0, diff; 00883 struct ast_channel *winner = NULL; 00884 00885 pfds = alloca(sizeof(struct pollfd) * (n * AST_MAX_FDS + nfds)); 00886 if (!pfds) { 00887 ast_log(LOG_WARNING, "alloca failed! bad things will happen.\n"); 00888 *outfd = -1; 00889 return NULL; 00890 } 00891 00892 if (outfd) 00893 *outfd = -99999; 00894 if (exception) 00895 *exception = 0; 00896 00897 /* Perform any pending masquerades */ 00898 for (x=0;x<n;x++) { 00899 ast_mutex_lock(&c[x]->lock); 00900 if (c[x]->whentohangup) { 00901 if (!havewhen) 00902 time(&now); 00903 diff = c[x]->whentohangup - now; 00904 if (!havewhen || (diff < whentohangup)) { 00905 havewhen++; 00906 whentohangup = diff; 00907 } 00908 } 00909 if (c[x]->masq) { 00910 if (ast_do_masquerade(c[x])) { 00911 ast_log(LOG_WARNING, "Masquerade failed\n"); 00912 *ms = -1; 00913 ast_mutex_unlock(&c[x]->lock); 00914 return NULL; 00915 } 00916 } 00917 ast_mutex_unlock(&c[x]->lock); 00918 } 00919 00920 rms = *ms; 00921 00922 if (havewhen) { 00923 if ((*ms < 0) || (whentohangup * 1000 < *ms)) { 00924 rms = whentohangup * 1000; 00925 } 00926 } 00927 max = 0; 00928 for (x=0;x<n;x++) { 00929 for (y=0;y<AST_MAX_FDS;y++) { 00930 if (c[x]->fds[y] > -1) { 00931 pfds[max].fd = c[x]->fds[y]; 00932 pfds[max].events = POLLIN | POLLPRI; 00933 max++; 00934 } 00935 } 00936 CHECK_BLOCKING(c[x]); 00937 } 00938 for (x=0;x<nfds; x++) { 00939 if (fds[x] > -1) { 00940 pfds[max].fd = fds[x]; 00941 pfds[max].events = POLLIN | POLLPRI; 00942 max++; 00943 } 00944 } 00945 if (*ms > 0) 00946 gettimeofday(&start, NULL); 00947 res = poll(pfds, max, rms); 00948 if (res < 0) { 00949 for (x=0;x<n;x++) 00950 c[x]->blocking = 0; 00951 /* Simulate a timeout if we were interrupted */ 00952 if (errno != EINTR) 00953 *ms = -1; 00954 else { 00955 /* Just an interrupt */ 00956 #if 0 00957 *ms = 0; 00958 #endif 00959 } 00960 return NULL; 00961 } 00962 00963 if (havewhen) 00964 time(&now); 00965 spoint = 0; 00966 for (x=0;x<n;x++) { 00967 c[x]->blocking = 0; 00968 if (havewhen && c[x]->whentohangup && (now > c[x]->whentohangup)) { 00969 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 00970 if (!winner) 00971 winner = c[x]; 00972 } 00973 for (y=0;y<AST_MAX_FDS;y++) { 00974 if (c[x]->fds[y] > -1) { 00975 if ((res = ast_fdisset(pfds, c[x]->fds[y], max, &spoint))) { 00976 if (res & POLLPRI) 00977 c[x]->exception = -1; 00978 else 00979 c[x]->exception = 0; 00980 c[x]->fdno = y; 00981 winner = c[x]; 00982 } 00983 } 00984 } 00985 } 00986 for (x=0;x<nfds;x++) { 00987 if (fds[x] > -1) { 00988 if ((res = ast_fdisset(pfds, fds[x], max, &spoint))) { 00989 if (outfd) 00990 *outfd = fds[x]; 00991 if (exception) { 00992 if (res & POLLPRI) 00993 *exception = -1; 00994 else 00995 *exception = 0; 00996 } 00997 winner = NULL; 00998 } 00999 } 01000 } 01001 if (*ms > 0) { 01002 long diff; 01003 gettimeofday(&end, NULL); 01004 diff = (end.tv_sec - start.tv_sec) * 1000; 01005 diff += (end.tv_usec - start.tv_usec) / 1000; 01006 if (diff < *ms) 01007 *ms -= diff; 01008 else 01009 *ms = 0; 01010 } 01011 return winner; 01012 } 01013 01014 struct ast_channel *ast_waitfor_n(struct ast_channel **c, int n, int *ms) 01015 { 01016 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms); 01017 } 01018 01019 int ast_waitfor(struct ast_channel *c, int ms) 01020 { 01021 struct ast_channel *chan; 01022 int oldms = ms; 01023 chan = ast_waitfor_n(&c, 1, &ms); 01024 if (ms < 0) { 01025 if (oldms < 0) 01026 return 0; 01027 else 01028 return -1; 01029 } 01030 return ms; 01031 } 01032 01033 char ast_waitfordigit(struct ast_channel *c, int ms) 01034 { 01035 /* XXX Should I be merged with waitfordigit_full XXX */ 01036 struct ast_frame *f; 01037 char result = 0; 01038 /* Stop if we're a zombie or need a soft hangup */ 01039 if (c->zombie || ast_check_hangup(c)) 01040 return -1; 01041 /* Wait for a digit, no more than ms milliseconds total. */ 01042 while(ms && !result) { 01043 ms = ast_waitfor(c, ms); 01044 if (ms < 0) /* Error */ 01045 result = -1; 01046 else if (ms > 0) { 01047 /* Read something */ 01048 f = ast_read(c); 01049 if (f) { 01050 if (f->frametype == AST_FRAME_DTMF) 01051 result = f->subclass; 01052 ast_frfree(f); 01053 } else 01054 result = -1; 01055 } 01056 } 01057 return result; 01058 } 01059 01060 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data) 01061 { 01062 int res = -1; 01063 #ifdef ZAPTEL_OPTIMIZATIONS 01064 if (c->timingfd > -1) { 01065 if (!func) { 01066 samples = 0; 01067 data = 0; 01068 } 01069 ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples); 01070 res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples); 01071 c->timingfunc = func; 01072 c->timingdata = data; 01073 } 01074 #endif 01075 return res; 01076 } 01077 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd) 01078 { 01079 struct ast_frame *f; 01080 struct ast_channel *rchan; 01081 int outfd; 01082 int res; 01083 /* Stop if we're a zombie or need a soft hangup */ 01084 if (c->zombie || ast_check_hangup(c)) 01085 return -1; 01086 /* Wait for a digit, no more than ms milliseconds total. */ 01087 while(ms) { 01088 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 01089 if ((!rchan) && (outfd < 0) && (ms)) { 01090 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 01091 return -1; 01092 } else if (outfd > -1) { 01093 /* The FD we were watching has something waiting */ 01094 return 1; 01095 } else if (rchan) { 01096 f = ast_read(c); 01097 if(!f) { 01098 return -1; 01099 } 01100 01101 switch(f->frametype) { 01102 case AST_FRAME_DTMF: 01103 res = f->subclass; 01104 ast_frfree(f); 01105 return res; 01106 case AST_FRAME_CONTROL: 01107 switch(f->subclass) { 01108 case AST_CONTROL_HANGUP: 01109 ast_frfree(f); 01110 return -1; 01111 case AST_CONTROL_RINGING: 01112 case AST_CONTROL_ANSWER: 01113 /* Unimportant */ 01114 break; 01115 default: 01116 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass); 01117 } 01118 case AST_FRAME_VOICE: 01119 /* Write audio if appropriate */ 01120 if (audiofd > -1) 01121 write(audiofd, f->data, f->datalen); 01122 } 01123 /* Ignore */ 01124 ast_frfree(f); 01125 } 01126 } 01127 return 0; // Time is up 01128 } 01129 01130 struct ast_frame *ast_read(struct ast_channel *chan) 01131 { 01132 struct ast_frame *f = NULL; 01133 int blah; 01134 #ifdef ZAPTEL_OPTIMIZATIONS 01135 int (*func)(void *); 01136 void *data; 01137 int res; 01138 #endif 01139 static struct ast_frame null_frame = 01140 { 01141 AST_FRAME_NULL, 01142 }; 01143 01144 ast_mutex_lock(&chan->lock); 01145 if (chan->masq) { 01146 if (ast_do_masquerade(chan)) { 01147 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 01148 f = NULL; 01149 } else 01150 f = &null_frame; 01151 ast_mutex_unlock(&chan->lock); 01152 return f; 01153 } 01154 01155 /* Stop if we're a zombie or need a soft hangup */ 01156 if (chan->zombie || ast_check_hangup(chan)) { 01157 if (chan->generator) 01158 ast_deactivate_generator(chan); 01159 ast_mutex_unlock(&chan->lock); 01160 return NULL; 01161 } 01162 01163 if (!chan->deferdtmf && !ast_strlen_zero(chan->dtmfq)) { 01164 /* We have DTMF that has been deferred. Return it now */ 01165 chan->dtmff.frametype = AST_FRAME_DTMF; 01166 chan->dtmff.subclass = chan->dtmfq[0]; 01167 /* Drop first digit */ 01168 memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1); 01169 ast_mutex_unlock(&chan->lock); 01170 return &chan->dtmff; 01171 } 01172 01173 /* Read and ignore anything on the alertpipe, but read only 01174 one sizeof(blah) per frame that we send from it */ 01175 if (chan->pvt->alertpipe[0] > -1) { 01176 read(chan->pvt->alertpipe[0], &blah, sizeof(blah)); 01177 } 01178 #ifdef ZAPTEL_OPTIMIZATIONS 01179 if ((chan->timingfd > -1) && (chan->fdno == AST_MAX_FDS - 2) && chan->exception) { 01180 chan->exception = 0; 01181 blah = -1; 01182 /* IF we can't get event, assume it's an expired as-per the old interface */ 01183 res = ioctl(chan->timingfd, ZT_GETEVENT, &blah); 01184 if (res) 01185 blah = ZT_EVENT_TIMER_EXPIRED; 01186 01187 if (blah == ZT_EVENT_TIMER_PING) { 01188 #if 0 01189 ast_log(LOG_NOTICE, "Oooh, there's a PING!\n"); 01190 #endif 01191 if (!chan->pvt->readq || !chan->pvt->readq->next) { 01192 /* Acknowledge PONG unless we need it again */ 01193 #if 0 01194 ast_log(LOG_NOTICE, "Sending a PONG!\n"); 01195 #endif 01196 if (ioctl(chan->timingfd, ZT_TIMERPONG, &blah)) { 01197 ast_log(LOG_WARNING, "Failed to pong timer on '%s': %s\n", chan->name, strerror(errno)); 01198 } 01199 } 01200 } else if (blah == ZT_EVENT_TIMER_EXPIRED) { 01201 ioctl(chan->timingfd, ZT_TIMERACK, &blah); 01202 func = chan->timingfunc; 01203 data = chan->timingdata; 01204 ast_mutex_unlock(&chan->lock); 01205 if (func) { 01206 #if 0 01207 ast_log(LOG_DEBUG, "Calling private function\n"); 01208 #endif 01209 func(data); 01210 } else { 01211 blah = 0; 01212 ast_mutex_lock(&chan->lock); 01213 ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah); 01214 chan->timingdata = NULL; 01215 ast_mutex_unlock(&chan->lock); 01216 } 01217 f = &null_frame; 01218 return f; 01219 } else 01220 ast_log(LOG_NOTICE, "No/unknown event '%d' on timer for '%s'?\n", blah, chan->name); 01221 } 01222 #endif 01223 /* Check for pending read queue */ 01224 if (chan->pvt->readq) { 01225 f = chan->pvt->readq; 01226 chan->pvt->readq = f->next; 01227 /* Interpret hangup and return NULL */ 01228 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) { 01229 ast_frfree(f); 01230 f = NULL; 01231 } 01232 } else { 01233 chan->blocker = pthread_self(); 01234 if (chan->exception) { 01235 if (chan->pvt->exception) 01236 f = chan->pvt->exception(chan); 01237 else { 01238 ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name); 01239 f = &null_frame; 01240 } 01241 /* Clear the exception flag */ 01242 chan->exception = 0; 01243 } else 01244 if (chan->pvt->read) 01245 f = chan->pvt->read(chan); 01246 else 01247 ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name); 01248 } 01249 01250 01251 if (f && (f->frametype == AST_FRAME_VOICE)) { 01252 if (!(f->subclass & chan->nativeformats)) { 01253 /* This frame can't be from the current native formats -- drop it on the 01254 floor */ 01255 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)); 01256 ast_frfree(f); 01257 f = &null_frame; 01258 } else { 01259 if (chan->monitor && chan->monitor->read_stream ) { 01260 #ifndef MONITOR_CONSTANT_DELAY 01261 int jump = chan->outsmpl - chan->insmpl - 2 * f->samples; 01262 if (jump >= 0) { 01263 if (ast_seekstream(chan->monitor->read_stream, jump + f->samples, SEEK_FORCECUR) == -1) 01264 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 01265 chan->insmpl += jump + 2 * f->samples; 01266 } else 01267 chan->insmpl+= f->samples; 01268 #else 01269 int jump = chan->outsmpl - chan->insmpl; 01270 if (jump - MONITOR_DELAY >= 0) { 01271 if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1) 01272 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 01273 chan->insmpl += jump; 01274 } else 01275 chan->insmpl += f->samples; 01276 #endif 01277 if (ast_writestream(chan->monitor->read_stream, f) < 0) 01278 ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n"); 01279 } 01280 if (chan->pvt->readtrans) { 01281 f = ast_translate(chan->pvt->readtrans, f, 1); 01282 if (!f) 01283 f = &null_frame; 01284 } 01285 } 01286 } 01287 01288 /* Make sure we always return NULL in the future */ 01289 if (!f) { 01290 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01291 if (chan->generator) 01292 ast_deactivate_generator(chan); 01293 /* End the CDR if appropriate */ 01294 if (chan->cdr) 01295 ast_cdr_end(chan->cdr); 01296 } else if (chan->deferdtmf && f->frametype == AST_FRAME_DTMF) { 01297 if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2) 01298 chan->dtmfq[strlen(chan->dtmfq)] = f->subclass; 01299 else 01300 ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name); 01301 f = &null_frame; 01302 } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_ANSWER)) { 01303 /* Answer the CDR */ 01304 ast_setstate(chan, AST_STATE_UP); 01305 ast_cdr_answer(chan->cdr); 01306 } 01307 01308 /* Run any generator sitting on the line */ 01309 if (f && (f->frametype == AST_FRAME_VOICE) && chan->generatordata) { 01310 /* Mask generator data temporarily */ 01311 void *tmp; 01312 int res; 01313 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples); 01314 tmp = chan->generatordata; 01315 chan->generatordata = NULL; 01316 generate = chan->generator->generate; 01317 res = generate(chan, tmp, f->datalen, f->samples); 01318 chan->generatordata = tmp; 01319 if (res) { 01320 ast_log(LOG_DEBUG, "Auto-deactivating generator\n"); 01321 ast_deactivate_generator(chan); 01322 } 01323 } 01324 if (chan->fin & 0x80000000) 01325 ast_frame_dump(chan->name, f, "<<"); 01326 if ((chan->fin & 0x7fffffff) == 0x7fffffff) 01327 chan->fin &= 0x80000000; 01328 else 01329 chan->fin++; 01330 ast_mutex_unlock(&chan->lock); 01331 return f; 01332 } 01333 01334 int ast_indicate(struct ast_channel *chan, int condition) 01335 { 01336 int res = -1; 01337 /* Stop if we're a zombie or need a soft hangup */ 01338 if (chan->zombie || ast_check_hangup(chan)) 01339 return -1; 01340 ast_mutex_lock(&chan->lock); 01341 if (chan->pvt->indicate) 01342 res = chan->pvt->indicate(chan, condition); 01343 ast_mutex_unlock(&chan->lock); 01344 if (!chan->pvt->indicate || res) { 01345 /* 01346 * Device does not support (that) indication, lets fake 01347 * it by doing our own tone generation. (PM2002) 01348 */ 01349 if (condition >= 0) { 01350 const struct tone_zone_sound *ts = NULL; 01351 switch (condition) { 01352 case AST_CONTROL_RINGING: 01353 ts = ast_get_indication_tone(chan->zone, "ring"); 01354 break; 01355 case AST_CONTROL_BUSY: 01356 ts = ast_get_indication_tone(chan->zone, "busy"); 01357 break; 01358 case AST_CONTROL_CONGESTION: 01359 ts = ast_get_indication_tone(chan->zone, "congestion"); 01360 break; 01361 } 01362 if (ts && ts->data[0]) { 01363 ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition); 01364 ast_playtones_start(chan,0,ts->data, 1); 01365 res = 0; 01366 } else if (condition == AST_CONTROL_PROGRESS) { 01367 /* ast_playtones_stop(chan); */ 01368 } else { 01369 /* not handled */ 01370 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name); 01371 res = -1; 01372 } 01373 } 01374 else ast_playtones_stop(chan); 01375 } 01376 return res; 01377 } 01378 01379 int ast_recvchar(struct ast_channel *chan, int timeout) 01380 { 01381 int res,ourto,c; 01382 struct ast_frame *f; 01383 01384 ourto = timeout; 01385 for(;;) 01386 { 01387 if (ast_check_hangup(chan)) return -1; 01388 res = ast_waitfor(chan,ourto); 01389 if (res <= 0) /* if timeout */ 01390 { 01391 return 0; 01392 } 01393 ourto = res; 01394 f = ast_read(chan); 01395 if (f == NULL) return -1; /* if hangup */ 01396 if ((f->frametype == AST_FRAME_CONTROL) && 01397 (f->subclass == AST_CONTROL_HANGUP)) return -1; /* if hangup */ 01398 if (f->frametype == AST_FRAME_TEXT) /* if a text frame */ 01399 { 01400 c = *((char *)f->data); /* get the data */ 01401 ast_frfree(f); 01402 return(c); 01403 } 01404 ast_frfree(f); 01405 } 01406 } 01407 01408 int ast_sendtext(struct ast_channel *chan, char *text) 01409 { 01410 int res = 0; 01411 /* Stop if we're a zombie or need a soft hangup */ 01412 if (chan->zombie || ast_check_hangup(chan)) 01413 return -1; 01414 CHECK_BLOCKING(chan); 01415 if (chan->pvt->send_text) 01416 res = chan->pvt->send_text(chan, text); 01417 chan->blocking = 0; 01418 return res; 01419 } 01420 01421 static int do_senddigit(struct ast_channel *chan, char digit) 01422 { 01423 int res = -1; 01424 01425 if (chan->pvt->send_digit) 01426 res = chan->pvt->send_digit(chan, digit); 01427 if (!chan->pvt->send_digit || res) { 01428 /* 01429 * Device does not support DTMF tones, lets fake 01430 * it by doing our own generation. (PM2002) 01431 */ 01432 static const char* dtmf_tones[] = { 01433 "!941+1336/100,!0/100", /* 0 */ 01434 "!697+1209/100,!0/100", /* 1 */ 01435 "!697+1336/100,!0/100", /* 2 */ 01436 "!697+1477/100,!0/100", /* 3 */ 01437 "!770+1209/100,!0/100", /* 4 */ 01438 "!770+1336/100,!0/100", /* 5 */ 01439 "!770+1477/100,!0/100", /* 6 */ 01440 "!852+1209/100,!0/100", /* 7 */ 01441 "!852+1336/100,!0/100", /* 8 */ 01442 "!852+1477/100,!0/100", /* 9 */ 01443 "!697+1633/100,!0/100", /* A */ 01444 "!770+1633/100,!0/100", /* B */ 01445 "!852+1633/100,!0/100", /* C */ 01446 "!941+1633/100,!0/100", /* D */ 01447 "!941+1209/100,!0/100", /* * */ 01448 "!941+1477/100,!0/100" }; /* # */ 01449 if (digit >= '0' && digit <='9') 01450 ast_playtones_start(chan,0,dtmf_tones[digit-'0'], 0); 01451 else if (digit >= 'A' && digit <= 'D') 01452 ast_playtones_start(chan,0,dtmf_tones[digit-'A'+10], 0); 01453 else if (digit == '*') 01454 ast_playtones_start(chan,0,dtmf_tones[14], 0); 01455 else if (digit == '#') 01456 ast_playtones_start(chan,0,dtmf_tones[15], 0); 01457 else { 01458 /* not handled */ 01459 ast_log(LOG_DEBUG, "Unable to handle DTMF tone '%c' for '%s'\n", digit, chan->name); 01460 } 01461 } 01462 return 0; 01463 } 01464 01465 int ast_senddigit(struct ast_channel *chan, char digit) 01466 { 01467 return do_senddigit(chan, digit); 01468 } 01469 01470 int ast_prod(struct ast_channel *chan) 01471 { 01472 struct ast_frame a = { AST_FRAME_VOICE }; 01473 char nothing[128]; 01474 /* Send an empty audio frame to get things moving */ 01475 if (chan->_state != AST_STATE_UP) { 01476 ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name); 01477 a.subclass = chan->pvt->rawwriteformat; 01478 a.data = nothing + AST_FRIENDLY_OFFSET; 01479 if (ast_write(chan, &a)) 01480 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name); 01481 } 01482 return 0; 01483 } 01484 01485 int ast_write_video(struct ast_channel *chan, struct ast_frame *fr) 01486 { 01487 int res; 01488 if (!chan->pvt->write_video) 01489 return 0; 01490 res = ast_write(chan, fr); 01491 if (!res) 01492 res = 1; 01493 return res; 01494 } 01495 01496 int ast_write(struct ast_channel *chan, struct ast_frame *fr) 01497 { 01498 int res = -1; 01499 struct ast_frame *f = NULL; 01500 /* Stop if we're a zombie or need a soft hangup */ 01501 ast_mutex_lock(&chan->lock); 01502 if (chan->zombie || ast_check_hangup(chan)) { 01503 ast_mutex_unlock(&chan->lock); 01504 return -1; 01505 } 01506 /* Handle any pending masquerades */ 01507 if (chan->masq) { 01508 if (ast_do_masquerade(chan)) { 01509 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 01510 ast_mutex_unlock(&chan->lock); 01511 return -1; 01512 } 01513 } 01514 if (chan->masqr) { 01515 ast_mutex_unlock(&chan->lock); 01516 return 0; 01517 } 01518 if (chan->generatordata) { 01519 if (chan->writeinterrupt) 01520 ast_deactivate_generator(chan); 01521 else { 01522 ast_mutex_unlock(&chan->lock); 01523 return 0; 01524 } 01525 } 01526 if (chan->fout & 0x80000000) 01527 ast_frame_dump(chan->name, fr, ">>"); 01528 CHECK_BLOCKING(chan); 01529 switch(fr->frametype) { 01530 case AST_FRAME_CONTROL: 01531 /* XXX Interpret control frames XXX */ 01532 ast_log(LOG_WARNING, "Don't know how to handle control frames yet\n"); 01533 break; 01534 case AST_FRAME_DTMF: 01535 chan->blocking = 0; 01536 ast_mutex_unlock(&chan->lock); 01537 res = do_senddigit(chan,fr->subclass); 01538 ast_mutex_lock(&chan->lock); 01539 CHECK_BLOCKING(chan); 01540 break; 01541 case AST_FRAME_TEXT: 01542 if (chan->pvt->send_text) 01543 res = chan->pvt->send_text(chan, (char *) fr->data); 01544 break; 01545 case AST_FRAME_VIDEO: 01546 /* XXX Handle translation of video codecs one day XXX */ 01547 if (chan->pvt->write_video) 01548 res = chan->pvt->write_video(chan, fr); 01549 else 01550 res = 0; 01551 break; 01552 default: 01553 if (chan->pvt->write) { 01554 if (chan->pvt->writetrans) { 01555 f = ast_translate(chan->pvt->writetrans, fr, 0); 01556 } else 01557 f = fr; 01558 if (f) { 01559 res = chan->pvt->write(chan, f); 01560 if( chan->monitor && 01561 chan->monitor->write_stream && 01562 f && ( f->frametype == AST_FRAME_VOICE ) ) { 01563 #ifndef MONITOR_CONSTANT_DELAY 01564 int jump = chan->insmpl - chan->outsmpl - 2 * f->samples; 01565 if (jump >= 0) { 01566 if (ast_seekstream(chan->monitor->write_stream, jump + f->samples, SEEK_FORCECUR) == -1) 01567 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 01568 chan->outsmpl += jump + 2 * f->samples; 01569 } else 01570 chan->outsmpl += f->samples; 01571 #else 01572 int jump = chan->insmpl - chan->outsmpl; 01573 if (jump - MONITOR_DELAY >= 0) { 01574 if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1) 01575 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 01576 chan->outsmpl += jump; 01577 } else 01578 chan->outsmpl += f->samples; 01579 #endif 01580 if (ast_writestream(chan->monitor->write_stream, f) < 0) 01581 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n"); 01582 } 01583 } else 01584 res = 0; 01585 } 01586 } 01587 if (f && (f != fr)) 01588 ast_frfree(f); 01589 chan->blocking = 0; 01590 /* Consider a write failure to force a soft hangup */ 01591 if (res < 0) 01592 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01593 else { 01594 if ((chan->fout & 0x7fffffff) == 0x7fffffff) 01595 chan->fout &= 0x80000000; 01596 else 01597 chan->fout++; 01598 chan->fout++; 01599 } 01600 ast_mutex_unlock(&chan->lock); 01601 return res; 01602 } 01603 01604 int ast_set_write_format(struct ast_channel *chan, int fmts) 01605 { 01606 int fmt; 01607 int native; 01608 int res; 01609 01610 ast_mutex_lock(&chan->lock); 01611 native = chan->nativeformats; 01612 fmt = fmts; 01613 01614 res = ast_translator_best_choice(&native, &fmt); 01615 if (res < 0) { 01616 ast_log(LOG_NOTICE, "Unable to find a path from %s to %s\n", 01617 ast_getformatname(fmts), ast_getformatname(chan->nativeformats)); 01618 ast_mutex_unlock(&chan->lock); 01619 return -1; 01620 } 01621 01622 /* Now we have a good choice for both. We'll write using our native format. */ 01623 chan->pvt->rawwriteformat = native; 01624 /* User perspective is fmt */ 01625 chan->writeformat = fmt; 01626 /* Free any write translation we have right now */ 01627 if (chan->pvt->writetrans) 01628 ast_translator_free_path(chan->pvt->writetrans); 01629 /* Build a translation path from the user write format to the raw writing format */ 01630 chan->pvt->writetrans = ast_translator_build_path(chan->pvt->rawwriteformat, chan->writeformat); 01631 if (option_debug) 01632 ast_log(LOG_DEBUG, "Set channel %s to write format %s\n", chan->name, ast_getformatname(chan->writeformat)); 01633 ast_mutex_unlock(&chan->lock); 01634 return 0; 01635 } 01636 01637 int ast_set_read_format(struct ast_channel *chan, int fmts) 01638 { 01639 int fmt; 01640 int native; 01641 int res; 01642 01643 ast_mutex_lock(&chan->lock); 01644 native = chan->nativeformats; 01645 fmt = fmts; 01646 /* Find a translation path from the native read format to one of the user's read formats */ 01647 res = ast_translator_best_choice(&fmt, &native); 01648 if (res < 0) { 01649 ast_log(LOG_NOTICE, "Unable to find a path from %s to %s\n", 01650 ast_getformatname(chan->nativeformats), ast_getformatname(fmts)); 01651 ast_mutex_unlock(&chan->lock); 01652 return -1; 01653 } 01654 01655 /* Now we have a good choice for both. We'll write using our native format. */ 01656 chan->pvt->rawreadformat = native; 01657 /* User perspective is fmt */ 01658 chan->readformat = fmt; 01659 /* Free any read translation we have right now */ 01660 if (chan->pvt->readtrans) 01661 ast_translator_free_path(chan->pvt->readtrans); 01662 /* Build a translation path from the raw read format to the user reading format */ 01663 chan->pvt->readtrans = ast_translator_build_path(chan->readformat, chan->pvt->rawreadformat); 01664 if (option_debug) 01665 ast_log(LOG_DEBUG, "Set channel %s to read format %s\n", 01666 chan->name, ast_getformatname(chan->readformat)); 01667 ast_mutex_unlock(&chan->lock); 01668 return 0; 01669 } 01670 01671 struct ast_channel *__ast_request_and_dial(char *type, int format, void *data, int timeout, int *outstate, char *callerid, struct outgoing_helper *oh) 01672 { 01673 int state = 0; 01674 struct ast_channel *chan; 01675 struct ast_frame *f; 01676 int res = 0; 01677 char *variable; 01678 chan = ast_request(type, format, data); 01679 if (chan) { 01680 if (oh) { 01681 char *tmp, *var; 01682 /* JDG chanvar */ 01683 if (oh->variable) 01684 variable = ast_strdupa(oh->variable); 01685 else 01686 variable = NULL; 01687 tmp = variable; 01688 /* FIXME replace this call with strsep NOT*/ 01689 while( (var = strtok_r(NULL, "|", &tmp)) ) { 01690 pbx_builtin_setvar( chan, var ); 01691 } /* /JDG */ 01692 if (oh->callerid && *oh->callerid) 01693 ast_set_callerid(chan, oh->callerid, 1); 01694 if (oh->account && *oh->account) 01695 ast_cdr_setaccount(chan, oh->account); 01696 } 01697 if (callerid && !ast_strlen_zero(callerid)) 01698 ast_set_callerid(chan, callerid, 1); 01699 01700 if (!ast_call(chan, data, 0)) { 01701 while(timeout && (chan->_state != AST_STATE_UP)) { 01702 res = ast_waitfor(chan, timeout); 01703 if (res < 0) { 01704 /* Something not cool, or timed out */ 01705 break; 01706 } 01707 /* If done, break out */ 01708 if (!res) 01709 break; 01710 if (timeout > -1) 01711 timeout = res; 01712 f = ast_read(chan); 01713 if (!f) { 01714 state = AST_CONTROL_HANGUP; 01715 res = 0; 01716 break; 01717 } 01718 if (f->frametype == AST_FRAME_CONTROL) { 01719 if (f->subclass == AST_CONTROL_RINGING) 01720 state = AST_CONTROL_RINGING; 01721 else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) { 01722 state = f->subclass; 01723 ast_frfree(f); 01724 break; 01725 } else if (f->subclass == AST_CONTROL_ANSWER) { 01726 state = f->subclass; 01727 ast_frfree(f); 01728 break; 01729 } else if (f->subclass == AST_CONTROL_PROGRESS) { 01730 /* Ignore */ 01731 } else if (f->subclass == -1) { 01732 /* Ignore -- just stopping indications */ 01733 } else { 01734 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass); 01735 } 01736 } 01737 ast_frfree(f); 01738 } 01739 } else 01740 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data); 01741 } else 01742 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data); 01743 if (chan) { 01744 /* Final fixups */ 01745 if (oh) { 01746 if (oh->context && *oh->context) 01747 strncpy(chan->context, oh->context, sizeof(chan->context) - 1); 01748 if (oh->exten && *oh->exten) 01749 strncpy(chan->exten, oh->exten, sizeof(chan->exten) - 1); 01750 chan->priority = oh->priority; 01751 } 01752 if (chan->_state == AST_STATE_UP) 01753 state = AST_CONTROL_ANSWER; 01754 } 01755 if (outstate) 01756 *outstate = state; 01757 if (chan && res <= 0) { 01758 if (!chan->cdr) { 01759 chan->cdr = ast_cdr_alloc(); 01760 if (chan->cdr) 01761 ast_cdr_init(chan->cdr, chan); 01762 } 01763 if (chan->cdr) { 01764 char tmp[256]; 01765 sprintf(tmp, "%s/%s",type,(char *)data); 01766 ast_cdr_setapp(chan->cdr,"Dial",tmp); 01767 ast_cdr_update(chan); 01768 ast_cdr_start(chan->cdr); 01769 ast_cdr_end(chan->cdr); 01770 /* If the cause wasn't handled properly */ 01771 if (ast_cdr_disposition(chan->cdr,chan->hangupcause)) 01772 ast_cdr_failed(chan->cdr); 01773 } else 01774 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 01775 ast_hangup(chan); 01776 chan = NULL; 01777 } 01778 return chan; 01779 } 01780 01781 struct ast_channel *ast_request_and_dial(char *type, int format, void *data, int timeout, int *outstate, char *callerid) 01782 { 01783 return __ast_request_and_dial(type, format, data, timeout, outstate, callerid, NULL); 01784 } 01785 01786 struct ast_channel *ast_request(char *type, int format, void *data) 01787 { 01788 struct chanlist *chan; 01789 struct ast_channel *c = NULL; 01790 int capabilities; 01791 int fmt; 01792 int res; 01793 if (ast_mutex_lock(&chlock)) { 01794 ast_log(LOG_WARNING, "Unable to lock channel list\n"); 01795 return NULL; 01796 } 01797 chan = backends; 01798 while(chan) { 01799 if (!strcasecmp(type, chan->type)) { 01800 capabilities = chan->capabilities; 01801 fmt = format; 01802 res = ast_translator_best_choice(&fmt, &capabilities); 01803 if (res < 0) { 01804 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->capabilities, format); 01805 ast_mutex_unlock(&chlock); 01806 return NULL; 01807 } 01808 ast_mutex_unlock(&chlock); 01809 if (chan->requester) 01810 c = chan->requester(type, capabilities, data); 01811 if (c) { 01812 if (c->_state == AST_STATE_DOWN) { 01813 manager_event(EVENT_FLAG_CALL, "Newchannel", 01814 "Channel: %s\r\n" 01815 "State: %s\r\n" 01816 "Callerid: %s\r\n" 01817 "Uniqueid: %s\r\n", 01818 c->name, ast_state2str(c->_state), c->callerid ? c->callerid : "<unknown>", c->uniqueid); 01819 } 01820 } 01821 return c; 01822 } 01823 chan = chan->next; 01824 } 01825 if (!chan) 01826 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type); 01827 ast_mutex_unlock(&chlock); 01828 return c; 01829 } 01830 01831 int ast_parse_device_state(char *device) 01832 { 01833 char name[AST_CHANNEL_NAME] = ""; 01834 char *cut; 01835 struct ast_channel *chan; 01836 01837 chan = ast_channel_walk_locked(NULL); 01838 while (chan) { 01839 strncpy(name, chan->name, sizeof(name)-1); 01840 ast_mutex_unlock(&chan->lock); 01841 cut = strchr(name,'-'); 01842 if (cut) 01843 *cut = 0; 01844 if (!strcmp(name, device)) 01845 return AST_DEVICE_INUSE; 01846 chan = ast_channel_walk_locked(chan); 01847 } 01848 return AST_DEVICE_UNKNOWN; 01849 } 01850 01851 int ast_device_state(char *device) 01852 { 01853 char tech[AST_MAX_EXTENSION] = ""; 01854 char *number; 01855 struct chanlist *chanls; 01856 int res = 0; 01857 01858 strncpy(tech, device, sizeof(tech)-1); 01859 number = strchr(tech, '/'); 01860 if (!number) { 01861 return AST_DEVICE_INVALID; 01862 } 01863 *number = 0; 01864 number++; 01865 01866 if (ast_mutex_lock(&chlock)) { 01867 ast_log(LOG_WARNING, "Unable to lock channel list\n"); 01868 return -1; 01869 } 01870 chanls = backends; 01871 while(chanls) { 01872 if (!strcasecmp(tech, chanls->type)) { 01873 ast_mutex_unlock(&chlock); 01874 if (!chanls->devicestate) 01875 return ast_parse_device_state(device); 01876 else { 01877 res = chanls->devicestate(number); 01878 if (res == AST_DEVICE_UNKNOWN) 01879 return ast_parse_device_state(device); 01880 else 01881 return res; 01882 } 01883 } 01884 chanls = chanls->next; 01885 } 01886 ast_mutex_unlock(&chlock); 01887 return AST_DEVICE_INVALID; 01888 } 01889 01890 int ast_call(struct ast_channel *chan, char *addr, int timeout) 01891 { 01892 /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 01893 If the remote end does not answer within the timeout, then do NOT hang up, but 01894 return anyway. */ 01895 int res = -1; 01896 /* Stop if we're a zombie or need a soft hangup */ 01897 ast_mutex_lock(&chan->lock); 01898 if (!chan->zombie && !ast_check_hangup(chan)) 01899 if (chan->pvt->call) 01900 res = chan->pvt->call(chan, addr, timeout); 01901 ast_mutex_unlock(&chan->lock); 01902 return res; 01903 } 01904 01905 int ast_transfer(struct ast_channel *chan, char *dest) 01906 { 01907 /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 01908 If the remote end does not answer within the timeout, then do NOT hang up, but 01909 return anyway. */ 01910 int res = -1; 01911 /* Stop if we're a zombie or need a soft hangup */ 01912 ast_mutex_lock(&chan->lock); 01913 if (!chan->zombie && !ast_check_hangup(chan)) { 01914 if (chan->pvt->transfer) { 01915 res = chan->pvt->transfer(chan, dest); 01916 if (!res) 01917 res = 1; 01918 } else 01919 res = 0; 01920 } 01921 ast_mutex_unlock(&chan->lock); 01922 return res; 01923 } 01924 01925 int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders) 01926 { 01927 int pos=0; 01928 int to = ftimeout; 01929 char d; 01930 /* XXX Merge with full version? XXX */ 01931 /* Stop if we're a zombie or need a soft hangup */ 01932 if (c->zombie || ast_check_hangup(c)) 01933 return -1; 01934 if (!len) 01935 return -1; 01936 do { 01937 if (c->stream) { 01938 d = ast_waitstream(c, AST_DIGIT_ANY); 01939 ast_stopstream(c); 01940 usleep(1000); 01941 if (!d) 01942 d = ast_waitfordigit(c, to); 01943 } else { 01944 d = ast_waitfordigit(c, to); 01945 } 01946 if (d < 0) 01947 return -1; 01948 if (d == 0) { 01949 s[pos]='\0'; 01950 return 1; 01951 } 01952 if (!strchr(enders, d)) 01953 s[pos++] = d; 01954 if (strchr(enders, d) || (pos >= len)) { 01955 s[pos]='\0'; 01956 return 0; 01957 } 01958 to = timeout; 01959 } while(1); 01960 /* Never reached */ 01961 return 0; 01962 } 01963 01964 int ast_readstring_full(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders, int audiofd, int ctrlfd) 01965 { 01966 int pos=0; 01967 int to = ftimeout; 01968 char d; 01969 /* Stop if we're a zombie or need a soft hangup */ 01970 if (c->zombie || ast_check_hangup(c)) 01971 return -1; 01972 if (!len) 01973 return -1; 01974 do { 01975 if (c->stream) { 01976 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd); 01977 ast_stopstream(c); 01978 usleep(1000); 01979 if (!d) 01980 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 01981 } else { 01982 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 01983 } 01984 if (d < 0) 01985 return -1; 01986 if (d == 0) { 01987 s[pos]='\0'; 01988 return 1; 01989 } 01990 if (d == 1) { 01991 s[pos]='\0'; 01992 return 2; 01993 } 01994 if (!strchr(enders, d)) 01995 s[pos++] = d; 01996 if (strchr(enders, d) || (pos >= len)) { 01997 s[pos]='\0'; 01998 return 0; 01999 } 02000 to = timeout; 02001 } while(1); 02002 /* Never reached */ 02003 return 0; 02004 } 02005 02006 int ast_channel_supports_html(struct ast_channel *chan) 02007 { 02008 if (chan->pvt->send_html) 02009 return 1; 02010 return 0; 02011 } 02012 02013 int ast_channel_sendhtml(struct ast_channel *chan, int subclass, char *data, int datalen) 02014 { 02015 if (chan->pvt->send_html) 02016 return chan->pvt->send_html(chan, subclass, data, datalen); 02017 return -1; 02018 } 02019 02020 int ast_channel_sendurl(struct ast_channel *chan, char *url) 02021 { 02022 if (chan->pvt->send_html) 02023 return chan->pvt->send_html(chan, AST_HTML_URL, url, strlen(url) + 1); 02024 return -1; 02025 } 02026 02027 int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer) 02028 { 02029 int peerf; 02030 int chanf; 02031 int res; 02032 ast_mutex_lock(&peer->lock); 02033 peerf = peer->nativeformats; 02034 ast_mutex_unlock(&peer->lock); 02035 ast_mutex_lock(&chan->lock); 02036 chanf = chan->nativeformats; 02037 ast_mutex_unlock(&chan->lock); 02038 res = ast_translator_best_choice(&peerf, &chanf); 02039 if (res < 0) { 02040 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, chan->nativeformats, peer->name, peer->nativeformats); 02041 return -1; 02042 } 02043 /* Set read format on channel */ 02044 res = ast_set_read_format(chan, peerf); 02045 if (res < 0) { 02046 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, chanf); 02047 return -1; 02048 } 02049 /* Set write format on peer channel */ 02050 res = ast_set_write_format(peer, peerf); 02051 if (res < 0) { 02052 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, peerf); 02053 return -1; 02054 } 02055 /* Now we go the other way */ 02056 peerf = peer->nativeformats; 02057 chanf = chan->nativeformats; 02058 res = ast_translator_best_choice(&chanf, &peerf); 02059 if (res < 0) { 02060 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, peer->nativeformats, chan->name, chan->nativeformats); 02061 return -1; 02062 } 02063 /* Set writeformat on channel */ 02064 res = ast_set_write_format(chan, chanf); 02065 if (res < 0) { 02066 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, chanf); 02067 return -1; 02068 } 02069 /* Set read format on peer channel */ 02070 res = ast_set_read_format(peer, chanf); 02071 if (res < 0) { 02072 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, peerf); 02073 return -1; 02074 } 02075 return 0; 02076 } 02077 02078 int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone) 02079 { 02080 struct ast_frame null = { AST_FRAME_NULL, }; 02081 int res = -1; 02082 ast_mutex_lock(&original->lock); 02083 while(ast_mutex_trylock(&clone->lock)) { 02084 ast_mutex_unlock(&original->lock); 02085 usleep(1); 02086 ast_mutex_lock(&original->lock); 02087 } 02088 ast_log(LOG_DEBUG, "Planning to masquerade %s into the structure of %s\n", 02089 clone->name, original->name); 02090 if (original->masq) { 02091 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 02092 original->masq->name, original->name); 02093 } else if (clone->masqr) { 02094 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 02095 clone->name, clone->masqr->name); 02096 } else { 02097 original->masq = clone; 02098 clone->masqr = original; 02099 ast_queue_frame(original, &null); 02100 ast_queue_frame(clone, &null); 02101 ast_log(LOG_DEBUG, "Done planning to masquerade %s into the structure of %s\n", original->name, clone->name); 02102 res = 0; 02103 } 02104 ast_mutex_unlock(&clone->lock); 02105 ast_mutex_unlock(&original->lock); 02106 return res; 02107 } 02108 02109 void ast_change_name(struct ast_channel *chan, char *newname) 02110 { 02111 char tmp[256]; 02112 strncpy(tmp, chan->name, 256); 02113 strncpy(chan->name, newname, sizeof(chan->name) - 1); 02114 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", tmp, chan->name, chan->uniqueid); 02115 } 02116 02117 int ast_do_masquerade(struct ast_channel *original) 02118 { 02119 int x,i; 02120 int res=0; 02121 char *tmp; 02122 struct ast_var_t *varptr; 02123 struct ast_frame *cur, *prev; 02124 struct ast_channel_pvt *p; 02125 struct ast_channel *clone = original->masq; 02126 int rformat = original->readformat; 02127 int wformat = original->writeformat; 02128 char newn[100]; 02129 char orig[100]; 02130 char masqn[100]; 02131 char zombn[100]; 02132 02133 #if 1 02134 ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n", 02135 clone->name, clone->_state, original->name, original->_state); 02136 #endif 02137 /* XXX This is a seriously wacked out operation. We're essentially putting the guts of 02138 the clone channel into the original channel. Start by killing off the original 02139 channel's backend. I'm not sure we're going to keep this function, because 02140 while the features are nice, the cost is very high in terms of pure nastiness. XXX */ 02141 02142 /* We need the clone's lock, too */ 02143 ast_mutex_lock(&clone->lock); 02144 02145 ast_log(LOG_DEBUG, "Got clone lock on '%s' at %p\n", clone->name, &clone->lock); 02146 02147 /* Having remembered the original read/write formats, we turn off any translation on either 02148 one */ 02149 free_translation(clone); 02150 free_translation(original); 02151 02152 02153 /* Unlink the masquerade */ 02154 original->masq = NULL; 02155 clone->masqr = NULL; 02156 02157 /* Save the original name */ 02158 strncpy(orig, original->name, sizeof(orig) - 1); 02159 /* Save the new name */ 02160 strncpy(newn, clone->name, sizeof(newn) - 1); 02161 /* Create the masq name */ 02162 snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn); 02163 02164 /* Copy the name from the clone channel */ 02165 strncpy(original->name, newn, sizeof(original->name)-1); 02166 02167 /* Mangle the name of the clone channel */ 02168 strncpy(clone->name, masqn, sizeof(clone->name) - 1); 02169 02170 /* Notify any managers of the change, first the masq then the other */ 02171 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\n", newn, masqn); 02172 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\n", orig, newn); 02173 02174 /* Swap the guts */ 02175 p = original->pvt; 02176 original->pvt = clone->pvt; 02177 clone->pvt = p; 02178 02179 /* Save any pending frames on both sides. Start by counting 02180 * how many we're going to need... */ 02181 prev = NULL; 02182 cur = clone->pvt->readq; 02183 x = 0; 02184 while(cur) { 02185 x++; 02186 prev = cur; 02187 cur = cur->next; 02188 } 02189 /* If we had any, prepend them to the ones already in the queue, and 02190 * load up the alertpipe */ 02191 if (prev) { 02192 prev->next = original->pvt->readq; 02193 original->pvt->readq = clone->pvt->readq; 02194 clone->pvt->readq = NULL; 02195 if (original->pvt->alertpipe[1] > -1) { 02196 for (i=0;i<x;i++) 02197 write(original->pvt->alertpipe[1], &x, sizeof(x)); 02198 } 02199 } 02200 clone->_softhangup = AST_SOFTHANGUP_DEV; 02201 02202 02203 if (clone->pvt->fixup){ 02204 res = clone->pvt->fixup(original, clone); 02205 if (res) 02206 ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name); 02207 } 02208 02209 /* Start by disconnecting the original's physical side */ 02210 if (clone->pvt->hangup) 02211 res = clone->pvt->hangup(clone); 02212 if (res) { 02213 ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n"); 02214 ast_mutex_unlock(&clone->lock); 02215 return -1; 02216 } 02217 02218 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig); 02219 /* Mangle the name of the clone channel */ 02220 strncpy(clone->name, zombn, sizeof(clone->name) - 1); 02221 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\n", masqn, zombn); 02222 02223 /* Keep the same language. */ 02224 /* Update the type. */ 02225 original->type = clone->type; 02226 /* Copy the FD's */ 02227 for (x=0;x<AST_MAX_FDS;x++) { 02228 original->fds[x] = clone->fds[x]; 02229 } 02230 /* Append variables from clone channel into original channel */ 02231 /* XXX Is this always correct? We have to in order to keep MACROS working XXX */ 02232 varptr = original->varshead.first; 02233 if (varptr) { 02234 while(varptr->entries.next) { 02235 varptr = varptr->entries.next; 02236 } 02237 varptr->entries.next = clone->varshead.first; 02238 } else { 02239 original->varshead.first = clone->varshead.first; 02240 } 02241 clone->varshead.first = NULL; 02242 /* Presense of ADSI capable CPE follows clone */ 02243 original->adsicpe = clone->adsicpe; 02244 /* Bridge remains the same */ 02245 /* CDR fields remain the same */ 02246 /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */ 02247 /* Application and data remain the same */ 02248 /* Clone exception becomes real one, as with fdno */ 02249 original->exception = clone->exception; 02250 original->fdno = clone->fdno; 02251 /* Schedule context remains the same */ 02252 /* Stream stuff stays the same */ 02253 /* Keep the original state. The fixup code will need to work with it most likely */ 02254 02255 /* dnid and callerid change to become the new, HOWEVER, we also link the original's 02256 fields back into the defunct 'clone' so that they will be freed when 02257 ast_frfree is eventually called */ 02258 tmp = original->dnid; 02259 original->dnid = clone->dnid; 02260 clone->dnid = tmp; 02261 02262 tmp = original->callerid; 02263 original->callerid = clone->callerid; 02264 clone->callerid = tmp; 02265 02266 /* Restore original timing file descriptor */ 02267 original->fds[AST_MAX_FDS - 2] = original->timingfd; 02268 02269 /* Our native formats are different now */ 02270 original->nativeformats = clone->nativeformats; 02271 02272 /* And of course, so does our current state. Note we need not 02273 call ast_setstate since the event manager doesn't really consider 02274 these separate */ 02275 original->_state = clone->_state; 02276 02277 /* Context, extension, priority, app data, jump table, remain the same */ 02278 /* pvt switches. pbx stays the same, as does next */ 02279 02280 /* Set the write format */ 02281 ast_set_write_format(original, wformat); 02282 02283 /* Set the read format */ 02284 ast_set_read_format(original, rformat); 02285 02286 ast_log(LOG_DEBUG, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat); 02287 02288 /* Okay. Last thing is to let the channel driver know about all this mess, so he 02289 can fix up everything as best as possible */ 02290 if (original->pvt->fixup) { 02291 res = original->pvt->fixup(clone, original); 02292 if (res) { 02293 ast_log(LOG_WARNING, "Driver for '%s' could not fixup channel %s\n", 02294 original->type, original->name); 02295 ast_mutex_unlock(&clone->lock); 02296 return -1; 02297 } 02298 } else 02299 ast_log(LOG_WARNING, "Driver '%s' does not have a fixup routine (for %s)! Bad things may happen.\n", 02300 original->type, original->name); 02301 02302 /* Now, at this point, the "clone" channel is totally F'd up. We mark it as 02303 a zombie so nothing tries to touch it. If it's already been marked as a 02304 zombie, then free it now (since it already is considered invalid). */ 02305 if (clone->zombie) { 02306 ast_log(LOG_DEBUG, "Destroying clone '%s'\n", clone->name); 02307 ast_mutex_unlock(&clone->lock); 02308 ast_channel_free(clone); 02309 manager_event(EVENT_FLAG_CALL, "Hangup", "Channel: %s\r\n", zombn); 02310 } else { 02311 ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name); 02312 clone->zombie=1; 02313 ast_mutex_unlock(&clone->lock); 02314 } 02315 02316 /* Signal any blocker */ 02317 if (original->blocking) 02318 pthread_kill(original->blocker, SIGURG); 02319 ast_log(LOG_DEBUG, "Done Masquerading %s (%d)\n", 02320 original->name, original->_state); 02321 return 0; 02322 } 02323 02324 void ast_set_callerid(struct ast_channel *chan, char *callerid, int anitoo) 02325 { 02326 if (chan->callerid) 02327 free(chan->callerid); 02328 if (anitoo && chan->ani) 02329 free(chan->ani); 02330 if (callerid) { 02331 chan->callerid = strdup(callerid); 02332 if (anitoo) 02333 chan->ani = strdup(callerid); 02334 } else { 02335 chan->callerid = NULL; 02336 if (anitoo) 02337 chan->ani = NULL; 02338 } 02339 if (chan->cdr) 02340 ast_cdr_setcid(chan->cdr, chan); 02341 manager_event(EVENT_FLAG_CALL, "Newcallerid", 02342 "Channel: %s\r\n" 02343 "Callerid: %s\r\n" 02344 "Uniqueid: %s\r\n", 02345 chan->name, chan->callerid ? 02346 chan->callerid : "<Unknown>", 02347 chan->uniqueid); 02348 } 02349 02350 int ast_setstate(struct ast_channel *chan, int state) 02351 { 02352 if (chan->_state != state) { 02353 int oldstate = chan->_state; 02354 chan->_state = state; 02355 if (oldstate == AST_STATE_DOWN) { 02356 ast_device_state_changed(chan->name); 02357 manager_event(EVENT_FLAG_CALL, "Newchannel", 02358 "Channel: %s\r\n" 02359 "State: %s\r\n" 02360 "Callerid: %s\r\n" 02361 "Uniqueid: %s\r\n", 02362 chan->name, ast_state2str(chan->_state), chan->callerid ? chan->callerid : "<unknown>", chan->uniqueid); 02363 } else { 02364 manager_event(EVENT_FLAG_CALL, "Newstate", 02365 "Channel: %s\r\n" 02366 "State: %s\r\n" 02367 "Callerid: %s\r\n" 02368 "Uniqueid: %s\r\n", 02369 chan->name, ast_state2str(chan->_state), chan->callerid ? chan->callerid : "<unknown>", chan->uniqueid); 02370 } 02371 } 02372 return 0; 02373 } 02374 02375 static long tvdiff(struct timeval *now, struct timeval *then) 02376 { 02377 return (((now->tv_sec * 1000) + now->tv_usec / 1000) - ((then->tv_sec * 1000) + then->tv_usec / 1000)); 02378 } 02379 02380 static void bridge_playfile(struct ast_channel *chan, struct ast_channel *peer, char *sound, int remain) 02381 { 02382 int res=0, min=0, sec=0,check=0; 02383 02384 check = ast_autoservice_start(peer); 02385 if(check) 02386 return; 02387 02388 if (remain > 0) { 02389 if (remain / 60 > 1) { 02390 min = remain / 60; 02391 sec = remain % 60; 02392 } else { 02393 sec = remain; 02394 } 02395 } 02396 02397 if (!strcmp(sound,"timeleft")) { 02398 res = ast_streamfile(chan, "vm-youhave", chan->language); 02399 res = ast_waitstream(chan, ""); 02400 if (min) { 02401 res = ast_say_number(chan, min, AST_DIGIT_ANY, chan->language, (char *) NULL); 02402 res = ast_streamfile(chan, "minutes", chan->language); 02403 res = ast_waitstream(chan, ""); 02404 } 02405 if (sec) { 02406 res = ast_say_number(chan, sec, AST_DIGIT_ANY, chan->language, (char *) NULL); 02407 res = ast_streamfile(chan, "seconds", chan->language); 02408 res = ast_waitstream(chan, ""); 02409 } 02410 } else { 02411 res = ast_streamfile(chan, sound, chan->language); 02412 res = ast_waitstream(chan, ""); 02413 } 02414 02415 check = ast_autoservice_stop(peer); 02416 } 02417 02418 int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc) 02419 { 02420 /* Copy voice back and forth between the two channels. Give the peer 02421 the ability to transfer calls with '#<extension' syntax. */ 02422 int flags; 02423 struct ast_channel *cs[3]; 02424 int to = -1; 02425 struct ast_frame *f; 02426 struct ast_channel *who = NULL; 02427 int res=0; 02428 int nativefailed=0; 02429 struct timeval start_time,precise_now; 02430 long elapsed_ms=0, time_left_ms=0; 02431 int playit=0, playitagain=1, first_time=1; 02432 02433 flags = (config->allowdisconnect||config->allowredirect_out ? AST_BRIDGE_DTMF_CHANNEL_0 : 0) + (config->allowredirect_in ? AST_BRIDGE_DTMF_CHANNEL_1 : 0); 02434 02435 /* timestamp */ 02436 gettimeofday(&start_time,NULL); 02437 time_left_ms = config->timelimit; 02438 02439 if (config->play_to_caller && config->start_sound) 02440 bridge_playfile(c0,c1,config->start_sound,time_left_ms / 1000); 02441 if (config->play_to_callee && config->start_sound) 02442 bridge_playfile(c1,c0,config->start_sound,time_left_ms / 1000); 02443 02444 /* Stop if we're a zombie or need a soft hangup */ 02445 if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1)) 02446 return -1; 02447 if (c0->bridge) { 02448 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 02449 c0->name, c0->bridge->name); 02450 return -1; 02451 } 02452 if (c1->bridge) { 02453 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 02454 c1->name, c1->bridge->name); 02455 return -1; 02456 } 02457 02458 /* Keep track of bridge */ 02459 c0->bridge = c1; 02460 c1->bridge = c0; 02461 cs[0] = c0; 02462 cs[1] = c1; 02463 02464 manager_event(EVENT_FLAG_CALL, "Link", 02465 "Channel1: %s\r\n" 02466 "Channel2: %s\r\n" 02467 "Uniqueid1: %s\r\n" 02468 "Uniqueid2: %s\r\n", 02469 c0->name, c1->name, c0->uniqueid, c1->uniqueid); 02470 02471 for (/* ever */;;) { 02472 /* timestamp */ 02473 if (config->timelimit) { 02474 gettimeofday(&precise_now,NULL); 02475 elapsed_ms = tvdiff(&precise_now,&start_time); 02476 time_left_ms = config->timelimit - elapsed_ms; 02477 02478 if (playitagain && (config->play_to_caller || config->play_to_callee) && (config->play_warning && time_left_ms <= config->play_warning)) { 02479 /* narrowing down to the end */ 02480 if (config->warning_freq == 0) { 02481 playit = 1; 02482 first_time=0; 02483 playitagain=0; 02484 } else if (first_time) { 02485 playit = 1; 02486 first_time=0; 02487 } else { 02488 if ((time_left_ms % config->warning_freq) <= 50) { 02489 playit = 1; 02490 } 02491 } 02492 } 02493 if (time_left_ms <= 0) { 02494 if (config->play_to_caller && config->end_sound) 02495 bridge_playfile(c0,c1,config->end_sound,0); 02496 if (config->play_to_callee && config->end_sound) 02497 bridge_playfile(c1,c0,config->end_sound,0); 02498 *fo = NULL; 02499 if (who) *rc = who; 02500 res = 0; 02501 break; 02502 } 02503 if (time_left_ms >= 5000 && playit) { 02504 if (config->play_to_caller && config->warning_sound && config->play_warning) 02505 bridge_playfile(c0,c1,config->warning_sound,time_left_ms / 1000); 02506 if (config->play_to_callee && config->warning_sound && config->play_warning) 02507 bridge_playfile(c1,c0,config->warning_sound,time_left_ms / 1000); 02508 playit = 0; 02509 } 02510 02511 } 02512 /* Stop if we're a zombie or need a soft hangup */ 02513 if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1)) { 02514 *fo = NULL; 02515 if (who) *rc = who; 02516 res = 0; 02517 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"); 02518 break; 02519 } 02520 if (c0->pvt->bridge && config->timelimit==0 && 02521 (c0->pvt->bridge == c1->pvt->bridge) && !nativefailed && !c0->monitor && !c1->monitor) { 02522 /* Looks like they share a bridge code */ 02523 if (option_verbose > 2) 02524 ast_verbose(VERBOSE_PREFIX_3 "Attempting native bridge of %s and %s\n", c0->name, c1->name); 02525 if (!(res = c0->pvt->bridge(c0, c1, flags, fo, rc))) { 02526 c0->bridge = NULL; 02527 c1->bridge = NULL; 02528 manager_event(EVENT_FLAG_CALL, "Unlink", 02529 "Channel1: %s\r\n" 02530 "Channel2: %s\r\n" 02531 "Uniqueid1: %s\r\n" 02532 "Uniqueid2: %s\r\n", 02533 c0->name, c1->name, c0->uniqueid, c1->uniqueid); 02534 ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n",c0->name ,c1->name); 02535 return 0; 02536 } 02537 /* If they return non-zero then continue on normally. Let "-2" mean don't worry about 02538 my not wanting to bridge */ 02539 if ((res != -2) && (res != -3)) 02540 ast_log(LOG_WARNING, "Private bridge between %s and %s failed\n", c0->name, c1->name); 02541 if (res != -3) nativefailed++; 02542 } 02543 02544 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat)) && 02545 !(c0->generator || c1->generator)) { 02546 if (ast_channel_make_compatible(c0, c1)) { 02547 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name); 02548 manager_event(EVENT_FLAG_CALL, "Unlink", 02549 "Channel1: %s\r\n" 02550 "Channel2: %s\r\n" 02551 "Uniqueid1: %s\r\n" 02552 "Uniqueid2: %s\r\n", 02553 c0->name, c1->name, c0->uniqueid, c1->uniqueid); 02554 return -1; 02555 } 02556 } 02557 who = ast_waitfor_n(cs, 2, &to); 02558 if (!who) { 02559 ast_log(LOG_DEBUG, "Nobody there, continuing...\n"); 02560 continue; 02561 } 02562 f = ast_read(who); 02563 if (!f) { 02564 *fo = NULL; 02565 *rc = who; 02566 res = 0; 02567 ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name); 02568 break; 02569 } 02570 02571 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) { 02572 *fo = f; 02573 *rc = who; 02574 res = 0; 02575 ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name); 02576 break; 02577 } 02578 if ((f->frametype == AST_FRAME_VOICE) || 02579 (f->frametype == AST_FRAME_TEXT) || 02580 (f->frametype == AST_FRAME_VIDEO) || 02581 (f->frametype == AST_FRAME_IMAGE) || 02582 (f->frametype == AST_FRAME_DTMF)) { 02583 if ((f->frametype == AST_FRAME_DTMF) && 02584 (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) { 02585 if ((who == c0)) { 02586 if ((flags & AST_BRIDGE_DTMF_CHANNEL_0)) { 02587 *rc = c0; 02588 *fo = f; 02589 /* Take out of conference mode */ 02590 res = 0; 02591 ast_log(LOG_DEBUG, "Got AST_BRIDGE_DTMF_CHANNEL_0 on c0 (%s)\n",c0->name); 02592 break; 02593 } else 02594 goto tackygoto; 02595 } else 02596 if ((who == c1)) { 02597 if (flags & AST_BRIDGE_DTMF_CHANNEL_1) { 02598 *rc = c1; 02599 *fo = f; 02600 res = 0; 02601 ast_log(LOG_DEBUG, "Got AST_BRIDGE_DTMF_CHANNEL_1 on c1 (%s)\n",c1->name); 02602 break; 02603 } else 02604 goto tackygoto; 02605 } 02606 } else { 02607 #if 0 02608 ast_log(LOG_DEBUG, "Read from %s\n", who->name); 02609 if (who == last) 02610 ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name); 02611 last = who; 02612 #endif 02613 tackygoto: 02614 /* Don't copy packets if there is a generator on either one, since they're 02615 not supposed to be listening anyway */ 02616 if (who == c0) 02617 ast_write(c1, f); 02618 else 02619 ast_write(c0, f); 02620 } 02621 ast_frfree(f); 02622 } else 02623 ast_frfree(f); 02624 /* Swap who gets priority */ 02625 cs[2] = cs[0]; 02626 cs[0] = cs[1]; 02627 cs[1] = cs[2]; 02628 } 02629 c0->bridge = NULL; 02630 c1->bridge = NULL; 02631 manager_event(EVENT_FLAG_CALL, "Unlink", 02632 "Channel1: %s\r\n" 02633 "Channel2: %s\r\n" 02634 "Uniqueid1: %s\r\n" 02635 "Uniqueid2: %s\r\n", 02636 c0->name, c1->name, c0->uniqueid, c1->uniqueid); 02637 ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n",c0->name,c1->name); 02638 return res; 02639 } 02640 02641 int ast_channel_setoption(struct ast_channel *chan, int option, void *data, int datalen, int block) 02642 { 02643 int res; 02644 if (chan->pvt->setoption) { 02645 res = chan->pvt->setoption(chan, option, data, datalen); 02646 if (res < 0) 02647 return res; 02648 } else { 02649 errno = ENOSYS; 02650 return -1; 02651 } 02652 if (block) { 02653 /* XXX Implement blocking -- just wait for our option frame reply, discarding 02654 intermediate packets. XXX */ 02655 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 02656 return -1; 02657 } 02658 return 0; 02659 } 02660 02661 struct tonepair_def { 02662 int freq1; 02663 int freq2; 02664 int duration; 02665 int vol; 02666 }; 02667 02668 struct tonepair_state { 02669 float freq1; 02670 float freq2; 02671 float vol; 02672 int duration; 02673 int pos; 02674 int origwfmt; 02675 struct ast_frame f; 02676 unsigned char offset[AST_FRIENDLY_OFFSET]; 02677 short data[4000]; 02678 }; 02679 02680 static void tonepair_release(struct ast_channel *chan, void *params) 02681 { 02682 struct tonepair_state *ts = params; 02683 if (chan) { 02684 ast_set_write_format(chan, ts->origwfmt); 02685 } 02686 free(ts); 02687 } 02688 02689 static void * tonepair_alloc(struct ast_channel *chan, void *params) 02690 { 02691 struct tonepair_state *ts; 02692 struct tonepair_def *td = params; 02693 ts = malloc(sizeof(struct tonepair_state)); 02694 if (!ts) 02695 return NULL; 02696 memset(ts, 0, sizeof(struct tonepair_state)); 02697 ts->origwfmt = chan->writeformat; 02698 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) { 02699 ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name); 02700 tonepair_release(NULL, ts); 02701 ts = NULL; 02702 } else { 02703 ts->freq1 = td->freq1; 02704 ts->freq2 = td->freq2; 02705 ts->duration = td->duration; 02706 ts->vol = td->vol; 02707 } 02708 /* Let interrupts interrupt :) */ 02709 chan->writeinterrupt = 1; 02710 return ts; 02711 } 02712 02713 static int tonepair_generator(struct ast_channel *chan, void *data, int len, int samples) 02714 { 02715 struct tonepair_state *ts = data; 02716 int x; 02717 02718 /* we need to prepare a frame with 16 * timelen samples as we're 02719 * generating SLIN audio 02720 */ 02721 len = samples * 2; 02722 02723 if (len > sizeof(ts->data) / 2 - 1) { 02724 ast_log(LOG_WARNING, "Can't generate that much data!\n"); 02725 return -1; 02726 } 02727 memset(&ts->f, 0, sizeof(ts->f)); 02728 for (x=0;x<len/2;x++) { 02729 ts->data[x] = ts->vol * ( 02730 sin((ts->freq1 * 2.0 * M_PI / 8000.0) * (ts->pos + x)) + 02731 sin((ts->freq2 * 2.0 * M_PI / 8000.0) * (ts->pos + x)) 02732 ); 02733 } 02734 ts->f.frametype = AST_FRAME_VOICE; 02735 ts->f.subclass = AST_FORMAT_SLINEAR; 02736 ts->f.datalen = len; 02737 ts->f.samples = samples; 02738 ts->f.offset = AST_FRIENDLY_OFFSET; 02739 ts->f.data = ts->data; 02740 ast_write(chan, &ts->f); 02741 ts->pos += x; 02742 if (ts->duration > 0) { 02743 if (ts->pos >= ts->duration * 8) 02744 return -1; 02745 } 02746 return 0; 02747 } 02748 02749 static struct ast_generator tonepair = { 02750 alloc: tonepair_alloc, 02751 release: tonepair_release, 02752 generate: tonepair_generator, 02753 }; 02754 02755 int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol) 02756 { 02757 struct tonepair_def d = { 0, }; 02758 d.freq1 = freq1; 02759 d.freq2 = freq2; 02760 d.duration = duration; 02761 if (vol < 1) 02762 d.vol = 8192; 02763 else 02764 d.vol = vol; 02765 if (ast_activate_generator(chan, &tonepair, &d)) 02766 return -1; 02767 return 0; 02768 } 02769 02770 void ast_tonepair_stop(struct ast_channel *chan) 02771 { 02772 ast_deactivate_generator(chan); 02773 } 02774 02775 int ast_tonepair(struct ast_channel *chan, int freq1, int freq2, int duration, int vol) 02776 { 02777 struct ast_frame *f; 02778 int res; 02779 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol))) 02780 return res; 02781 02782 /* Give us some wiggle room */ 02783 while(chan->generatordata && (ast_waitfor(chan, 100) >= 0)) { 02784 f = ast_read(chan); 02785 if (f) 02786 ast_frfree(f); 02787 else 02788 return -1; 02789 } 02790 return 0; 02791 } 02792 02793 unsigned int ast_get_group(char *s) 02794 { 02795 char *copy; 02796 char *piece; 02797 char *c=NULL; 02798 int start=0, finish=0,x; 02799 unsigned int group = 0; 02800 copy = ast_strdupa(s); 02801 if (!copy) { 02802 ast_log(LOG_ERROR, "Out of memory\n"); 02803 return 0; 02804 } 02805 c = copy; 02806 02807 while((piece = strsep(&c, ","))) { 02808 if (sscanf(piece, "%d-%d", &start, &finish) == 2) { 02809 /* Range */ 02810 } else if (sscanf(piece, "%d", &start)) { 02811 /* Just one */ 02812 finish = start; 02813 } else { 02814 ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'. Using '0'\n", s,piece); 02815 return 0; 02816 } 02817 for (x=start;x<=finish;x++) { 02818 if ((x > 31) || (x < 0)) { 02819 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 31)\n", x); 02820 } else 02821 group |= (1 << x); 02822 } 02823 } 02824 return group; 02825 }

Generated on Sat Jun 12 16:40:57 2004 for Asterisk by doxygen 1.3.7