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

Generated on Fri Sep 24 21:03:46 2004 for Asterisk by doxygen 1.3.8