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

Generated on Tue Aug 17 16:13:52 2004 for Asterisk by doxygen 1.3.8