00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <stdio.h>
00015 #include <stdlib.h>
00016 #include <pthread.h>
00017 #include <string.h>
00018 #include <sys/time.h>
00019 #include <signal.h>
00020 #include <errno.h>
00021 #include <unistd.h>
00022 #include <math.h>
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/file.h>
00031 #include <asterisk/translate.h>
00032 #include <asterisk/manager.h>
00033 #include <asterisk/chanvars.h>
00034 #include <asterisk/linkedlists.h>
00035 #include <asterisk/indications.h>
00036 #include <asterisk/monitor.h>
00037 #include <asterisk/causes.h>
00038 #ifdef ZAPTEL_OPTIMIZATIONS
00039 #include <sys/ioctl.h>
00040 #include <linux/zaptel.h>
00041 #endif
00042
00043
00044 #if 0
00045 #define MONITOR_CONSTANT_DELAY
00046 #define MONITOR_DELAY 150 * 8
00047 #endif
00048
00049 static int shutting_down = 0;
00050 static int uniqueint = 0;
00051
00052
00053
00054 struct chanlist {
00055 char type[80];
00056 char description[80];
00057 int capabilities;
00058 struct ast_channel * (*requester)(char *type, int format, void *data);
00059 int (*devicestate)(void *data);
00060 struct chanlist *next;
00061 } *backends = NULL;
00062 struct ast_channel *channels = NULL;
00063
00064
00065
00066
00067 static ast_mutex_t chlock = AST_MUTEX_INITIALIZER;
00068
00069 int ast_check_hangup(struct ast_channel *chan)
00070 {
00071 time_t myt;
00072
00073
00074 if (chan->_softhangup) return 1;
00075
00076 if (!chan->pvt->pvt) return 1;
00077
00078 if (!chan->whentohangup) return 0;
00079 time(&myt);
00080
00081 if (chan->whentohangup > myt) return 0;
00082 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
00083 return 1;
00084 }
00085
00086 static int ast_check_hangup_locked(struct ast_channel *chan)
00087 {
00088 int res;
00089 ast_mutex_lock(&chan->lock);
00090 res = ast_check_hangup(chan);
00091 ast_mutex_unlock(&chan->lock);
00092 return res;
00093 }
00094
00095 void ast_begin_shutdown(int hangup)
00096 {
00097 struct ast_channel *c;
00098 shutting_down = 1;
00099 if (hangup) {
00100 ast_mutex_lock(&chlock);
00101 c = channels;
00102 while(c) {
00103 ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN);
00104 c = c->next;
00105 }
00106 ast_mutex_unlock(&chlock);
00107 }
00108 }
00109
00110 int ast_active_channels(void)
00111 {
00112 struct ast_channel *c;
00113 int cnt = 0;
00114 ast_mutex_lock(&chlock);
00115 c = channels;
00116 while(c) {
00117 cnt++;
00118 c = c->next;
00119 }
00120 ast_mutex_unlock(&chlock);
00121 return cnt;
00122 }
00123
00124 void ast_cancel_shutdown(void)
00125 {
00126 shutting_down = 0;
00127 }
00128
00129 int ast_shutting_down(void)
00130 {
00131 return shutting_down;
00132 }
00133
00134 void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset)
00135 {
00136 time_t myt;
00137
00138 time(&myt);
00139 if (offset)
00140 chan->whentohangup = myt + offset;
00141 else
00142 chan->whentohangup = 0;
00143 return;
00144 }
00145
00146 int ast_channel_register(char *type, char *description, int capabilities,
00147 struct ast_channel *(*requester)(char *type, int format, void *data))
00148 {
00149 return ast_channel_register_ex(type, description, capabilities, requester, NULL);
00150 }
00151
00152 int ast_channel_register_ex(char *type, char *description, int capabilities,
00153 struct ast_channel *(*requester)(char *type, int format, void *data),
00154 int (*devicestate)(void *data))
00155 {
00156 struct chanlist *chan, *last=NULL;
00157 if (ast_mutex_lock(&chlock)) {
00158 ast_log(LOG_WARNING, "Unable to lock channel list\n");
00159 return -1;
00160 }
00161 chan = backends;
00162 while(chan) {
00163 if (!strcasecmp(type, chan->type)) {
00164 ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", type);
00165 ast_mutex_unlock(&chlock);
00166 return -1;
00167 }
00168 last = chan;
00169 chan = chan->next;
00170 }
00171 chan = malloc(sizeof(struct chanlist));
00172 if (!chan) {
00173 ast_log(LOG_WARNING, "Out of memory\n");
00174 ast_mutex_unlock(&chlock);
00175 return -1;
00176 }
00177 strncpy(chan->type, type, sizeof(chan->type)-1);
00178 strncpy(chan->description, description, sizeof(chan->description)-1);
00179 chan->capabilities = capabilities;
00180 chan->requester = requester;
00181 chan->devicestate = devicestate;
00182 chan->next = NULL;
00183 if (last)
00184 last->next = chan;
00185 else
00186 backends = chan;
00187 if (option_debug)
00188 ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->type, chan->description);
00189 else if (option_verbose > 1)
00190 ast_verbose( VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->type, chan->description);
00191 ast_mutex_unlock(&chlock);
00192 return 0;
00193 }
00194
00195 char *ast_state2str(int state)
00196 {
00197
00198 static char localtmp[256];
00199 switch(state) {
00200 case AST_STATE_DOWN:
00201 return "Down";
00202 case AST_STATE_RESERVED:
00203 return "Rsrvd";
00204 case AST_STATE_OFFHOOK:
00205 return "OffHook";
00206 case AST_STATE_DIALING:
00207 return "Dialing";
00208 case AST_STATE_RING:
00209 return "Ring";
00210 case AST_STATE_RINGING:
00211 return "Ringing";
00212 case AST_STATE_UP:
00213 return "Up";
00214 case AST_STATE_BUSY:
00215 return "Busy";
00216 default:
00217 snprintf(localtmp, sizeof(localtmp), "Unknown (%d)\n", state);
00218 return localtmp;
00219 }
00220 }
00221
00222
00223 int ast_best_codec(int fmts)
00224 {
00225
00226
00227 int x;
00228 static int prefs[] =
00229 {
00230
00231 AST_FORMAT_ULAW,
00232
00233 AST_FORMAT_ALAW,
00234
00235 AST_FORMAT_SLINEAR,
00236
00237 AST_FORMAT_G726,
00238
00239 AST_FORMAT_ADPCM,
00240
00241
00242 AST_FORMAT_GSM,
00243
00244 AST_FORMAT_ILBC,
00245
00246 AST_FORMAT_SPEEX,
00247
00248
00249 AST_FORMAT_LPC10,
00250
00251 AST_FORMAT_G729A,
00252
00253 AST_FORMAT_G723_1,
00254 };
00255
00256
00257 for (x=0;x<sizeof(prefs) / sizeof(prefs[0]); x++)
00258 if (fmts & prefs[x])
00259 return prefs[x];
00260 ast_log(LOG_WARNING, "Don't know any of 0x%x formats\n", fmts);
00261 return 0;
00262 }
00263
00264 struct ast_channel *ast_channel_alloc(int needqueue)
00265 {
00266 struct ast_channel *tmp;
00267 struct ast_channel_pvt *pvt;
00268 int x;
00269 int flags;
00270 struct varshead *headp;
00271
00272
00273
00274 if (shutting_down)
00275 return NULL;
00276 ast_mutex_lock(&chlock);
00277 tmp = malloc(sizeof(struct ast_channel));
00278 if (tmp) {
00279 memset(tmp, 0, sizeof(struct ast_channel));
00280 pvt = malloc(sizeof(struct ast_channel_pvt));
00281 if (pvt) {
00282 memset(pvt, 0, sizeof(struct ast_channel_pvt));
00283 tmp->sched = sched_context_create();
00284 if (tmp->sched) {
00285 for (x=0;x<AST_MAX_FDS - 1;x++)
00286 tmp->fds[x] = -1;
00287 if (needqueue &&
00288 pipe(pvt->alertpipe)) {
00289 ast_log(LOG_WARNING, "Alert pipe creation failed!\n");
00290 free(pvt);
00291 free(tmp);
00292 tmp = NULL;
00293 pvt = NULL;
00294 } else {
00295
00296 if (needqueue) {
00297 flags = fcntl(pvt->alertpipe[0], F_GETFL);
00298 fcntl(pvt->alertpipe[0], F_SETFL, flags | O_NONBLOCK);
00299 flags = fcntl(pvt->alertpipe[1], F_GETFL);
00300 fcntl(pvt->alertpipe[1], F_SETFL, flags | O_NONBLOCK);
00301 } else
00302 pvt->alertpipe[0] = pvt->alertpipe[1] = -1;
00303 #ifdef ZAPTEL_OPTIMIZATIONS
00304 tmp->timingfd = open("/dev/zap/timer", O_RDWR);
00305 #else
00306 tmp->timingfd = -1;
00307 #endif
00308
00309 tmp->fds[AST_MAX_FDS-1] = pvt->alertpipe[0];
00310
00311 tmp->fds[AST_MAX_FDS-2] = tmp->timingfd;
00312 strncpy(tmp->name, "**Unknown**", sizeof(tmp->name)-1);
00313 tmp->pvt = pvt;
00314
00315 tmp->_state = AST_STATE_DOWN;
00316 tmp->stack = -1;
00317 tmp->streamid = -1;
00318 tmp->appl = NULL;
00319 tmp->data = NULL;
00320 tmp->fin = 0;
00321 tmp->fout = 0;
00322 snprintf(tmp->uniqueid, sizeof(tmp->uniqueid), "%li.%d", (long)time(NULL), uniqueint++);
00323 headp=&tmp->varshead;
00324 ast_mutex_init(&tmp->lock);
00325 AST_LIST_HEAD_INIT(headp);
00326 tmp->vars=ast_var_assign("tempvar","tempval");
00327 AST_LIST_INSERT_HEAD(headp,tmp->vars,entries);
00328 strncpy(tmp->context, "default", sizeof(tmp->context)-1);
00329 strncpy(tmp->language, defaultlanguage, sizeof(tmp->language)-1);
00330 strncpy(tmp->exten, "s", sizeof(tmp->exten)-1);
00331 tmp->priority=1;
00332 tmp->amaflags = ast_default_amaflags;
00333 strncpy(tmp->accountcode, ast_default_accountcode, sizeof(tmp->accountcode)-1);
00334 tmp->next = channels;
00335 channels= tmp;
00336 }
00337 } else {
00338 ast_log(LOG_WARNING, "Unable to create schedule context\n");
00339 free(tmp);
00340 tmp = NULL;
00341 }
00342 } else {
00343 ast_log(LOG_WARNING, "Out of memory\n");
00344 free(tmp);
00345 tmp = NULL;
00346 }
00347 } else
00348 ast_log(LOG_WARNING, "Out of memory\n");
00349 ast_mutex_unlock(&chlock);
00350 return tmp;
00351 }
00352
00353 int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin, int lock)
00354 {
00355 struct ast_frame *f;
00356 struct ast_frame *prev, *cur;
00357 int blah = 1;
00358 int qlen = 0;
00359
00360 f = ast_frdup(fin);
00361 if (!f) {
00362 ast_log(LOG_WARNING, "Unable to duplicate frame\n");
00363 return -1;
00364 }
00365 if (lock)
00366 ast_mutex_lock(&chan->lock);
00367 prev = NULL;
00368 cur = chan->pvt->readq;
00369 while(cur) {
00370 prev = cur;
00371 cur = cur->next;
00372 qlen++;
00373 }
00374
00375 if (((fin->frametype == AST_FRAME_VOICE) && (qlen > 96)) || (qlen > 128)) {
00376 if (fin->frametype != AST_FRAME_VOICE) {
00377 ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name);
00378 CRASH;
00379 } else {
00380 ast_log(LOG_DEBUG, "Dropping voice to exceptionally long queue on %s\n", chan->name);
00381 ast_frfree(f);
00382 if (lock)
00383 ast_mutex_unlock(&chan->lock);
00384 return 0;
00385 }
00386 }
00387 if (prev)
00388 prev->next = f;
00389 else
00390 chan->pvt->readq = f;
00391 if (chan->pvt->alertpipe[1] > -1) {
00392 if (write(chan->pvt->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah))
00393 ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d (qlen = %d): %s!\n",
00394 chan->name, f->frametype, f->subclass, qlen, strerror(errno));
00395 } else if (chan->blocking) {
00396 pthread_kill(chan->blocker, SIGURG);
00397 }
00398 if (lock)
00399 ast_mutex_unlock(&chan->lock);
00400 return 0;
00401 }
00402
00403 int ast_queue_hangup(struct ast_channel *chan, int lock)
00404 {
00405 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
00406 chan->_softhangup |= AST_SOFTHANGUP_DEV;
00407 return ast_queue_frame(chan, &f, lock);
00408 }
00409
00410 int ast_queue_control(struct ast_channel *chan, int control, int lock)
00411 {
00412 struct ast_frame f = { AST_FRAME_CONTROL, };
00413 f.subclass = control;
00414 return ast_queue_frame(chan, &f, lock);
00415 }
00416
00417 int ast_channel_defer_dtmf(struct ast_channel *chan)
00418 {
00419 int pre = 0;
00420 if (chan) {
00421 pre = chan->deferdtmf;
00422 chan->deferdtmf = 1;
00423 }
00424 return pre;
00425 }
00426
00427 void ast_channel_undefer_dtmf(struct ast_channel *chan)
00428 {
00429 if (chan)
00430 chan->deferdtmf = 0;
00431 }
00432
00433 struct ast_channel *ast_channel_walk(struct ast_channel *prev)
00434 {
00435 struct ast_channel *l, *ret=NULL;
00436 ast_mutex_lock(&chlock);
00437 l = channels;
00438 if (!prev) {
00439 ast_mutex_unlock(&chlock);
00440 return l;
00441 }
00442 while(l) {
00443 if (l == prev)
00444 ret = l->next;
00445 l = l->next;
00446 }
00447 ast_mutex_unlock(&chlock);
00448 return ret;
00449
00450 }
00451
00452 int ast_safe_sleep_conditional( struct ast_channel *chan, int ms,
00453 int (*cond)(void*), void *data )
00454 {
00455 struct ast_frame *f;
00456
00457 while(ms > 0) {
00458 if( cond && ((*cond)(data) == 0 ) )
00459 return 0;
00460 ms = ast_waitfor(chan, ms);
00461 if (ms <0)
00462 return -1;
00463 if (ms > 0) {
00464 f = ast_read(chan);
00465 if (!f)
00466 return -1;
00467 ast_frfree(f);
00468 }
00469 }
00470 return 0;
00471 }
00472
00473 int ast_safe_sleep(struct ast_channel *chan, int ms)
00474 {
00475 struct ast_frame *f;
00476 while(ms > 0) {
00477 ms = ast_waitfor(chan, ms);
00478 if (ms <0)
00479 return -1;
00480 if (ms > 0) {
00481 f = ast_read(chan);
00482 if (!f)
00483 return -1;
00484 ast_frfree(f);
00485 }
00486 }
00487 return 0;
00488 }
00489
00490 void ast_channel_free(struct ast_channel *chan)
00491 {
00492 struct ast_channel *last=NULL, *cur;
00493 int fd;
00494 struct ast_var_t *vardata;
00495 struct ast_frame *f, *fp;
00496 struct varshead *headp;
00497 char name[AST_CHANNEL_NAME];
00498
00499 headp=&chan->varshead;
00500
00501 ast_mutex_lock(&chlock);
00502 cur = channels;
00503 while(cur) {
00504 if (cur == chan) {
00505 if (last)
00506 last->next = cur->next;
00507 else
00508 channels = cur->next;
00509 break;
00510 }
00511 last = cur;
00512 cur = cur->next;
00513 }
00514 if (!cur)
00515 ast_log(LOG_WARNING, "Unable to find channel in list\n");
00516 if (chan->pvt->pvt)
00517 ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
00518
00519 strncpy(name, chan->name, sizeof(name)-1);
00520
00521
00522 if (chan->monitor) {
00523 chan->monitor->stop( chan, 0 );
00524 }
00525
00526
00527 if (chan->pvt->readtrans)
00528 ast_translator_free_path(chan->pvt->readtrans);
00529 if (chan->pvt->writetrans)
00530 ast_translator_free_path(chan->pvt->writetrans);
00531 if (chan->pbx)
00532 ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
00533 if (chan->dnid)
00534 free(chan->dnid);
00535 if (chan->callerid)
00536 free(chan->callerid);
00537 if (chan->ani)
00538 free(chan->ani);
00539 if (chan->rdnis)
00540 free(chan->rdnis);
00541 ast_mutex_destroy(&chan->lock);
00542
00543 if ((fd = chan->pvt->alertpipe[0]) > -1)
00544 close(fd);
00545 if ((fd = chan->pvt->alertpipe[1]) > -1)
00546 close(fd);
00547 if ((fd = chan->timingfd) > -1)
00548 close(fd);
00549 f = chan->pvt->readq;
00550 chan->pvt->readq = NULL;
00551 while(f) {
00552 fp = f;
00553 f = f->next;
00554 ast_frfree(fp);
00555 }
00556
00557
00558
00559
00560 while (!AST_LIST_EMPTY(headp)) {
00561 vardata = AST_LIST_FIRST(headp);
00562 AST_LIST_REMOVE_HEAD(headp, entries);
00563
00564 ast_var_delete(vardata);
00565 }
00566
00567
00568 free(chan->pvt);
00569 chan->pvt = NULL;
00570 free(chan);
00571 ast_mutex_unlock(&chlock);
00572
00573 ast_device_state_changed(name);
00574 }
00575
00576 int ast_softhangup_nolock(struct ast_channel *chan, int cause)
00577 {
00578 int res = 0;
00579 struct ast_frame f = { AST_FRAME_NULL };
00580 if (option_debug)
00581 ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name);
00582
00583 chan->_softhangup |= cause;
00584 ast_queue_frame(chan, &f, 0);
00585
00586 if (chan->blocking)
00587 pthread_kill(chan->blocker, SIGURG);
00588 return res;
00589 }
00590
00591 int ast_softhangup(struct ast_channel *chan, int cause)
00592 {
00593 int res;
00594 ast_mutex_lock(&chan->lock);
00595 res = ast_softhangup_nolock(chan, cause);
00596 ast_mutex_unlock(&chan->lock);
00597 return res;
00598 }
00599
00600 static int ast_do_masquerade(struct ast_channel *original);
00601
00602 static void free_translation(struct ast_channel *clone)
00603 {
00604 if (clone->pvt->writetrans)
00605 ast_translator_free_path(clone->pvt->writetrans);
00606 if (clone->pvt->readtrans)
00607 ast_translator_free_path(clone->pvt->readtrans);
00608 clone->pvt->writetrans = NULL;
00609 clone->pvt->readtrans = NULL;
00610 clone->pvt->rawwriteformat = clone->nativeformats;
00611 clone->pvt->rawreadformat = clone->nativeformats;
00612 }
00613
00614 int ast_hangup(struct ast_channel *chan)
00615 {
00616 int res = 0;
00617
00618
00619 ast_mutex_lock(&chan->lock);
00620 if (chan->masq) {
00621 if (ast_do_masquerade(chan))
00622 ast_log(LOG_WARNING, "Failed to perform masquerade\n");
00623 }
00624
00625 if (chan->masq) {
00626 ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name);
00627 ast_mutex_unlock(&chan->lock);
00628 return 0;
00629 }
00630
00631
00632 if (chan->masqr) {
00633 ast_mutex_unlock(&chan->lock);
00634 chan->zombie=1;
00635 return 0;
00636 }
00637 free_translation(chan);
00638 if (chan->stream)
00639 ast_stopstream(chan);
00640 if (chan->sched)
00641 sched_context_destroy(chan->sched);
00642
00643 if (chan->generatordata)
00644 chan->generator->release(chan, chan->generatordata);
00645 chan->generatordata = NULL;
00646 chan->generator = NULL;
00647 if (chan->cdr) {
00648
00649 ast_cdr_end(chan->cdr);
00650
00651 ast_cdr_post(chan->cdr);
00652 ast_cdr_free(chan->cdr);
00653 }
00654 if (chan->blocking) {
00655 ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
00656 "is blocked by thread %ld in procedure %s! Expect a failure\n",
00657 (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc);
00658 CRASH;
00659 }
00660 if (!chan->zombie) {
00661 if (option_debug)
00662 ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name);
00663 if (chan->pvt->hangup)
00664 res = chan->pvt->hangup(chan);
00665 } else
00666 if (option_debug)
00667 ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name);
00668
00669 ast_mutex_unlock(&chan->lock);
00670 manager_event(EVENT_FLAG_CALL, "Hangup",
00671 "Channel: %s\r\n"
00672 "Uniqueid: %s\r\n",
00673 chan->name, chan->uniqueid);
00674 ast_channel_free(chan);
00675 return res;
00676 }
00677
00678 void ast_channel_unregister(char *type)
00679 {
00680 struct chanlist *chan, *last=NULL;
00681 if (option_debug)
00682 ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", type);
00683 if (ast_mutex_lock(&chlock)) {
00684 ast_log(LOG_WARNING, "Unable to lock channel list\n");
00685 return;
00686 }
00687 if (option_verbose > 1)
00688 ast_verbose( VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", type);
00689
00690 chan = backends;
00691 while(chan) {
00692 if (!strcasecmp(chan->type, type)) {
00693 if (last)
00694 last->next = chan->next;
00695 else
00696 backends = backends->next;
00697 free(chan);
00698 ast_mutex_unlock(&chlock);
00699 return;
00700 }
00701 last = chan;
00702 chan = chan->next;
00703 }
00704 ast_mutex_unlock(&chlock);
00705 }
00706
00707 int ast_answer(struct ast_channel *chan)
00708 {
00709 int res = 0;
00710
00711 if (chan->zombie || ast_check_hangup(chan))
00712 return -1;
00713 switch(chan->_state) {
00714 case AST_STATE_RINGING:
00715 case AST_STATE_RING:
00716 ast_mutex_lock(&chan->lock);
00717 if (chan->pvt->answer)
00718 res = chan->pvt->answer(chan);
00719 ast_mutex_unlock(&chan->lock);
00720 ast_setstate(chan, AST_STATE_UP);
00721 if (chan->cdr)
00722 ast_cdr_answer(chan->cdr);
00723 return res;
00724 break;
00725 case AST_STATE_UP:
00726 if (chan->cdr)
00727 ast_cdr_answer(chan->cdr);
00728 break;
00729 }
00730 return 0;
00731 }
00732
00733 void ast_deactivate_generator(struct ast_channel *chan)
00734 {
00735 if (chan->generatordata) {
00736 chan->generator->release(chan, chan->generatordata);
00737 chan->generatordata = NULL;
00738 chan->generator = NULL;
00739 chan->writeinterrupt = 0;
00740 }
00741 }
00742
00743 int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, void *params)
00744 {
00745 if (chan->generatordata) {
00746 chan->generator->release(chan, chan->generatordata);
00747 chan->generatordata = NULL;
00748 }
00749 ast_prod(chan);
00750 if ((chan->generatordata = gen->alloc(chan, params))) {
00751 chan->generator = gen;
00752 } else {
00753 return -1;
00754 }
00755 return 0;
00756 }
00757
00758 int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception)
00759 {
00760
00761 struct timeval tv;
00762 fd_set rfds, efds;
00763 int res;
00764 int x, max=-1;
00765 int winner = -1;
00766
00767 tv.tv_sec = *ms / 1000;
00768 tv.tv_usec = (*ms % 1000) * 1000;
00769 FD_ZERO(&rfds);
00770 FD_ZERO(&efds);
00771 for (x=0;x<n;x++) {
00772 if (fds[x] > -1) {
00773 FD_SET(fds[x], &rfds);
00774 FD_SET(fds[x], &efds);
00775 if (fds[x] > max)
00776 max = fds[x];
00777 }
00778 }
00779 if (*ms >= 0)
00780 res = ast_select(max + 1, &rfds, NULL, &efds, &tv);
00781 else
00782 res = ast_select(max + 1, &rfds, NULL, &efds, NULL);
00783
00784 if (res < 0) {
00785
00786 if (errno != EINTR)
00787 *ms = -1;
00788 else
00789 *ms = 0;
00790 return -1;
00791 }
00792
00793 for (x=0;x<n;x++) {
00794 if ((fds[x] > -1) && (FD_ISSET(fds[x], &rfds) || FD_ISSET(fds[x], &efds)) && (winner < 0)) {
00795 if (exception)
00796 *exception = FD_ISSET(fds[x], &efds);
00797 winner = fds[x];
00798 }
00799 }
00800 *ms = tv.tv_sec * 1000 + tv.tv_usec / 1000;
00801 return winner;
00802 }
00803
00804 struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds, int nfds,
00805 int *exception, int *outfd, int *ms)
00806 {
00807
00808 struct timeval tv;
00809 fd_set rfds, efds;
00810 int res;
00811 int x, y, max=-1;
00812 struct ast_channel *winner = NULL;
00813 if (outfd)
00814 *outfd = -1;
00815 if (exception)
00816 *exception = 0;
00817
00818
00819 for (x=0;x<n;x++) {
00820 ast_mutex_lock(&c[x]->lock);
00821 if (c[x]->masq) {
00822 if (ast_do_masquerade(c[x])) {
00823 ast_log(LOG_WARNING, "Masquerade failed\n");
00824 *ms = -1;
00825 ast_mutex_unlock(&c[x]->lock);
00826 return NULL;
00827 }
00828 }
00829 ast_mutex_unlock(&c[x]->lock);
00830 }
00831
00832 tv.tv_sec = *ms / 1000;
00833 tv.tv_usec = (*ms % 1000) * 1000;
00834 FD_ZERO(&rfds);
00835 FD_ZERO(&efds);
00836
00837 for (x=0;x<n;x++) {
00838 for (y=0;y<AST_MAX_FDS;y++) {
00839 if (c[x]->fds[y] > -1) {
00840 FD_SET(c[x]->fds[y], &rfds);
00841 FD_SET(c[x]->fds[y], &efds);
00842 if (c[x]->fds[y] > max)
00843 max = c[x]->fds[y];
00844 }
00845 }
00846 CHECK_BLOCKING(c[x]);
00847 }
00848 for (x=0;x<nfds; x++) {
00849 FD_SET(fds[x], &rfds);
00850 FD_SET(fds[x], &efds);
00851 if (fds[x] > max)
00852 max = fds[x];
00853 }
00854 if (*ms >= 0)
00855 res = ast_select(max + 1, &rfds, NULL, &efds, &tv);
00856 else
00857 res = ast_select(max + 1, &rfds, NULL, &efds, NULL);
00858
00859 if (res < 0) {
00860 for (x=0;x<n;x++)
00861 c[x]->blocking = 0;
00862
00863 if (errno != EINTR)
00864 *ms = -1;
00865 else {
00866
00867 #if 0
00868 *ms = 0;
00869 #endif
00870 }
00871 return NULL;
00872 }
00873
00874 for (x=0;x<n;x++) {
00875 c[x]->blocking = 0;
00876 for (y=0;y<AST_MAX_FDS;y++) {
00877 if (c[x]->fds[y] > -1) {
00878 if ((FD_ISSET(c[x]->fds[y], &rfds) || FD_ISSET(c[x]->fds[y], &efds)) && !winner) {
00879
00880 if (FD_ISSET(c[x]->fds[y], &efds))
00881 c[x]->exception = 1;
00882 c[x]->fdno = y;
00883 winner = c[x];
00884 }
00885 }
00886 }
00887 }
00888 for (x=0;x<nfds;x++) {
00889 if ((FD_ISSET(fds[x], &rfds) || FD_ISSET(fds[x], &efds)) && !winner) {
00890 if (outfd)
00891 *outfd = fds[x];
00892 if (FD_ISSET(fds[x], &efds) && exception)
00893 *exception = 1;
00894 winner = NULL;
00895 }
00896 }
00897 *ms = tv.tv_sec * 1000 + tv.tv_usec / 1000;
00898 return winner;
00899 }
00900
00901 struct ast_channel *ast_waitfor_n(struct ast_channel **c, int n, int *ms)
00902 {
00903 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
00904 }
00905
00906 int ast_waitfor(struct ast_channel *c, int ms)
00907 {
00908 struct ast_channel *chan;
00909 int oldms = ms;
00910 chan = ast_waitfor_n(&c, 1, &ms);
00911 if (ms < 0) {
00912 if (oldms < 0)
00913 return 0;
00914 else
00915 return -1;
00916 }
00917 return ms;
00918 }
00919
00920 char ast_waitfordigit(struct ast_channel *c, int ms)
00921 {
00922
00923 struct ast_frame *f;
00924 char result = 0;
00925
00926 if (c->zombie || ast_check_hangup(c))
00927 return -1;
00928
00929 while(ms && !result) {
00930 ms = ast_waitfor(c, ms);
00931 if (ms < 0)
00932 result = -1;
00933 else if (ms > 0) {
00934
00935 f = ast_read(c);
00936 if (f) {
00937 if (f->frametype == AST_FRAME_DTMF)
00938 result = f->subclass;
00939 ast_frfree(f);
00940 } else
00941 result = -1;
00942 }
00943 }
00944 return result;
00945 }
00946
00947 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
00948 {
00949 int res = -1;
00950 #ifdef ZAPTEL_OPTIMIZATIONS
00951 if (c->timingfd > -1) {
00952 if (!func) {
00953 samples = 0;
00954 data = 0;
00955 }
00956 ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
00957 res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
00958 c->timingfunc = func;
00959 c->timingdata = data;
00960 }
00961 #endif
00962 return res;
00963 }
00964 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audio, int ctrl)
00965 {
00966 struct ast_frame *f;
00967 char result = 0;
00968 struct ast_channel *rchan;
00969 int outfd;
00970
00971 if (c->zombie || ast_check_hangup(c))
00972 return -1;
00973
00974 while(ms && !result) {
00975 rchan = ast_waitfor_nandfds(&c, 1, &audio, (audio > -1) ? 1 : 0, NULL, &outfd, &ms);
00976 if ((!rchan) && (outfd < 0) && (ms))
00977 result = -1;
00978 else if (outfd > -1) {
00979 result = 1;
00980 } else if (rchan) {
00981
00982 f = ast_read(c);
00983 if (f) {
00984 if (f->frametype == AST_FRAME_DTMF)
00985 result = f->subclass;
00986 ast_frfree(f);
00987 } else
00988 result = -1;
00989 }
00990 }
00991 return result;
00992 }
00993
00994 struct ast_frame *ast_read(struct ast_channel *chan)
00995 {
00996 struct ast_frame *f = NULL;
00997 int blah;
00998 #ifdef ZAPTEL_OPTIMIZATIONS
00999 int (*func)(void *);
01000 void *data;
01001 #endif
01002 static struct ast_frame null_frame =
01003 {
01004 AST_FRAME_NULL,
01005 };
01006
01007 ast_mutex_lock(&chan->lock);
01008 if (chan->masq) {
01009 if (ast_do_masquerade(chan)) {
01010 ast_log(LOG_WARNING, "Failed to perform masquerade\n");
01011 f = NULL;
01012 } else
01013 f = &null_frame;
01014 ast_mutex_unlock(&chan->lock);
01015 return f;
01016 }
01017
01018
01019 if (chan->zombie || ast_check_hangup(chan)) {
01020 if (chan->generator)
01021 ast_deactivate_generator(chan);
01022 ast_mutex_unlock(&chan->lock);
01023 return NULL;
01024 }
01025
01026 if (!chan->deferdtmf && strlen(chan->dtmfq)) {
01027
01028 chan->dtmff.frametype = AST_FRAME_DTMF;
01029 chan->dtmff.subclass = chan->dtmfq[0];
01030
01031 memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1);
01032 ast_mutex_unlock(&chan->lock);
01033 return &chan->dtmff;
01034 }
01035
01036
01037
01038 if (chan->pvt->alertpipe[0] > -1) {
01039 read(chan->pvt->alertpipe[0], &blah, sizeof(blah));
01040 }
01041 #ifdef ZAPTEL_OPTIMIZATIONS
01042 if ((chan->timingfd > -1) && (chan->fdno == AST_MAX_FDS - 2) && chan->exception) {
01043 chan->exception = 0;
01044 blah = -1;
01045 ioctl(chan->timingfd, ZT_TIMERACK, &blah);
01046 func = chan->timingfunc;
01047 data = chan->timingdata;
01048 ast_mutex_unlock(&chan->lock);
01049 if (func) {
01050 #if 0
01051 ast_log(LOG_DEBUG, "Calling private function\n");
01052 #endif
01053 func(data);
01054 } else {
01055 blah = 0;
01056 ast_mutex_lock(&chan->lock);
01057 ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah);
01058 chan->timingdata = NULL;
01059 ast_mutex_unlock(&chan->lock);
01060 }
01061 f = &null_frame;
01062 return f;
01063 }
01064 #endif
01065
01066 if (chan->pvt->readq) {
01067 f = chan->pvt->readq;
01068 chan->pvt->readq = f->next;
01069
01070 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) {
01071 ast_frfree(f);
01072 f = NULL;
01073 }
01074 } else {
01075 chan->blocker = pthread_self();
01076 if (chan->exception) {
01077 if (chan->pvt->exception)
01078 f = chan->pvt->exception(chan);
01079 else {
01080 ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name);
01081 f = &null_frame;
01082 }
01083
01084 chan->exception = 0;
01085 } else
01086 if (chan->pvt->read)
01087 f = chan->pvt->read(chan);
01088 else
01089 ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
01090 }
01091
01092
01093 if (f && (f->frametype == AST_FRAME_VOICE)) {
01094 if (!(f->subclass & chan->nativeformats)) {
01095
01096
01097 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));
01098 ast_frfree(f);
01099 f = &null_frame;
01100 } else {
01101 if (chan->monitor && chan->monitor->read_stream ) {
01102 #ifndef MONITOR_CONSTANT_DELAY
01103 int jump = chan->outsmpl - chan->insmpl - 2 * f->samples;
01104 if (jump >= 0) {
01105 if (ast_seekstream(chan->monitor->read_stream, jump + f->samples, SEEK_FORCECUR) == -1)
01106 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
01107 chan->insmpl += jump + 2 * f->samples;
01108 } else
01109 chan->insmpl+= f->samples;
01110 #else
01111 int jump = chan->outsmpl - chan->insmpl;
01112 if (jump - MONITOR_DELAY >= 0) {
01113 if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
01114 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
01115 chan->insmpl += jump;
01116 } else
01117 chan->insmpl += f->samples;
01118 #endif
01119 if (ast_writestream(chan->monitor->read_stream, f) < 0)
01120 ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
01121 }
01122 if (chan->pvt->readtrans) {
01123 f = ast_translate(chan->pvt->readtrans, f, 1);
01124 if (!f)
01125 f = &null_frame;
01126 }
01127 }
01128 }
01129
01130
01131 if (!f) {
01132 chan->_softhangup |= AST_SOFTHANGUP_DEV;
01133 if (chan->generator)
01134 ast_deactivate_generator(chan);
01135
01136 if (chan->cdr)
01137 ast_cdr_end(chan->cdr);
01138 } else if (chan->deferdtmf && f->frametype == AST_FRAME_DTMF) {
01139 if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2)
01140 chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
01141 else
01142 ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
01143 f = &null_frame;
01144 } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_ANSWER)) {
01145
01146 ast_setstate(chan, AST_STATE_UP);
01147 ast_cdr_answer(chan->cdr);
01148 }
01149 ast_mutex_unlock(&chan->lock);
01150
01151
01152 if (f && (f->frametype == AST_FRAME_VOICE) && chan->generatordata) {
01153
01154 void *tmp;
01155 int res;
01156 tmp = chan->generatordata;
01157 chan->generatordata = NULL;
01158 res = chan->generator->generate(chan, tmp, f->datalen, f->samples);
01159 chan->generatordata = tmp;
01160 if (res) {
01161 ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
01162 ast_deactivate_generator(chan);
01163 }
01164 }
01165 if (chan->fin & 0x80000000)
01166 ast_frame_dump(chan->name, f, "<<");
01167 if ((chan->fin & 0x7fffffff) == 0x7fffffff)
01168 chan->fin &= 0x80000000;
01169 else
01170 chan->fin++;
01171 return f;
01172 }
01173
01174 int ast_indicate(struct ast_channel *chan, int condition)
01175 {
01176 int res = -1;
01177
01178 if (chan->zombie || ast_check_hangup(chan))
01179 return -1;
01180 ast_mutex_lock(&chan->lock);
01181 if (chan->pvt->indicate)
01182 res = chan->pvt->indicate(chan, condition);
01183 ast_mutex_unlock(&chan->lock);
01184 if (!chan->pvt->indicate || res) {
01185
01186
01187
01188
01189 if (condition >= 0) {
01190 const struct tone_zone_sound *ts = NULL;
01191 switch (condition) {
01192 case AST_CONTROL_RINGING:
01193 ts = ast_get_indication_tone(chan->zone, "ring");
01194 break;
01195 case AST_CONTROL_BUSY:
01196 ts = ast_get_indication_tone(chan->zone, "busy");
01197 break;
01198 case AST_CONTROL_CONGESTION:
01199 ts = ast_get_indication_tone(chan->zone, "congestion");
01200 break;
01201 }
01202 if (ts && ts->data[0]) {
01203 ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
01204 ast_playtones_start(chan,0,ts->data, 1);
01205 res = 0;
01206 } else if (condition == AST_CONTROL_PROGRESS) {
01207
01208 } else {
01209
01210 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
01211 res = -1;
01212 }
01213 }
01214 else ast_playtones_stop(chan);
01215 }
01216 return res;
01217 }
01218
01219 int ast_recvchar(struct ast_channel *chan, int timeout)
01220 {
01221 int res,ourto,c;
01222 struct ast_frame *f;
01223
01224 ourto = timeout;
01225 for(;;)
01226 {
01227 if (ast_check_hangup(chan)) return -1;
01228 res = ast_waitfor(chan,ourto);
01229 if (res <= 0)
01230 {
01231 return 0;
01232 }
01233 ourto = res;
01234 f = ast_read(chan);
01235 if (f == NULL) return -1;
01236 if ((f->frametype == AST_FRAME_CONTROL) &&
01237 (f->subclass == AST_CONTROL_HANGUP)) return -1;
01238 if (f->frametype == AST_FRAME_TEXT)
01239 {
01240 c = *((char *)f->data);
01241 ast_frfree(f);
01242 return(c);
01243 }
01244 ast_frfree(f);
01245 }
01246 }
01247
01248 int ast_sendtext(struct ast_channel *chan, char *text)
01249 {
01250 int res = 0;
01251
01252 if (chan->zombie || ast_check_hangup(chan))
01253 return -1;
01254 CHECK_BLOCKING(chan);
01255 if (chan->pvt->send_text)
01256 res = chan->pvt->send_text(chan, text);
01257 chan->blocking = 0;
01258 return res;
01259 }
01260
01261 static int do_senddigit(struct ast_channel *chan, char digit)
01262 {
01263 int res = -1;
01264
01265 if (chan->pvt->send_digit)
01266 res = chan->pvt->send_digit(chan, digit);
01267 if (!chan->pvt->send_digit || res) {
01268
01269
01270
01271
01272 static const char* dtmf_tones[] = {
01273 "!941+1336/50,!0/50",
01274 "!697+1209/50,!0/50",
01275 "!697+1336/50,!0/50",
01276 "!697+1477/50,!0/50",
01277 "!770+1209/50,!0/50",
01278 "!770+1336/50,!0/50",
01279 "!770+1477/50,!0/50",
01280 "!852+1209/50,!0/50",
01281 "!852+1336/50,!0/50",
01282 "!852+1477/50,!0/50",
01283 "!697+1633/50,!0/50",
01284 "!770+1633/50,!0/50",
01285 "!852+1633/50,!0/50",
01286 "!941+1633/50,!0/50",
01287 "!941+1209/50,!0/50",
01288 "!941+1477/50,!0/50" };
01289 if (digit >= '0' && digit <='9')
01290 ast_playtones_start(chan,0,dtmf_tones[digit-'0'], 0);
01291 else if (digit >= 'A' && digit <= 'D')
01292 ast_playtones_start(chan,0,dtmf_tones[digit-'A'+10], 0);
01293 else if (digit == '*')
01294 ast_playtones_start(chan,0,dtmf_tones[14], 0);
01295 else if (digit == '#')
01296 ast_playtones_start(chan,0,dtmf_tones[15], 0);
01297 else {
01298
01299 ast_log(LOG_WARNING, "Unable to handle DTMF tone '%c' for '%s'\n", digit, chan->name);
01300 return -1;
01301 }
01302 }
01303 return 0;
01304 }
01305
01306 int ast_prod(struct ast_channel *chan)
01307 {
01308 struct ast_frame a = { AST_FRAME_VOICE };
01309 char nothing[128];
01310
01311 if (chan->_state != AST_STATE_UP) {
01312 ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name);
01313 a.subclass = chan->pvt->rawwriteformat;
01314 a.data = nothing + AST_FRIENDLY_OFFSET;
01315 if (ast_write(chan, &a))
01316 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name);
01317 }
01318 return 0;
01319 }
01320
01321 int ast_write_video(struct ast_channel *chan, struct ast_frame *fr)
01322 {
01323 int res;
01324 if (!chan->pvt->write_video)
01325 return 0;
01326 res = ast_write(chan, fr);
01327 if (!res)
01328 res = 1;
01329 return res;
01330 }
01331
01332 int ast_write(struct ast_channel *chan, struct ast_frame *fr)
01333 {
01334 int res = -1;
01335 struct ast_frame *f = NULL;
01336
01337 ast_mutex_lock(&chan->lock);
01338 if (chan->zombie || ast_check_hangup(chan)) {
01339 ast_mutex_unlock(&chan->lock);
01340 return -1;
01341 }
01342
01343 if (chan->masq) {
01344 if (ast_do_masquerade(chan)) {
01345 ast_log(LOG_WARNING, "Failed to perform masquerade\n");
01346 ast_mutex_unlock(&chan->lock);
01347 return -1;
01348 }
01349 }
01350 if (chan->masqr) {
01351 ast_mutex_unlock(&chan->lock);
01352 return 0;
01353 }
01354 if (chan->generatordata) {
01355 if (chan->writeinterrupt)
01356 ast_deactivate_generator(chan);
01357 else {
01358 ast_mutex_unlock(&chan->lock);
01359 return 0;
01360 }
01361 }
01362 if (chan->fout & 0x80000000)
01363 ast_frame_dump(chan->name, fr, ">>");
01364 CHECK_BLOCKING(chan);
01365 switch(fr->frametype) {
01366 case AST_FRAME_CONTROL:
01367
01368 ast_log(LOG_WARNING, "Don't know how to handle control frames yet\n");
01369 break;
01370 case AST_FRAME_DTMF:
01371 chan->blocking = 0;
01372 ast_mutex_unlock(&chan->lock);
01373 res = do_senddigit(chan,fr->subclass);
01374 ast_mutex_lock(&chan->lock);
01375 CHECK_BLOCKING(chan);
01376 break;
01377 case AST_FRAME_TEXT:
01378 if (chan->pvt->send_text)
01379 res = chan->pvt->send_text(chan, (char *) fr->data);
01380 break;
01381 case AST_FRAME_VIDEO:
01382
01383 if (chan->pvt->write_video)
01384 res = chan->pvt->write_video(chan, fr);
01385 else
01386 res = 0;
01387 break;
01388 default:
01389 if (chan->pvt->write) {
01390 if (chan->pvt->writetrans) {
01391 f = ast_translate(chan->pvt->writetrans, fr, 0);
01392 } else
01393 f = fr;
01394 if (f) {
01395 res = chan->pvt->write(chan, f);
01396 if( chan->monitor &&
01397 chan->monitor->write_stream &&
01398 f && ( f->frametype == AST_FRAME_VOICE ) ) {
01399 #ifndef MONITOR_CONSTANT_DELAY
01400 int jump = chan->insmpl - chan->outsmpl - 2 * f->samples;
01401 if (jump >= 0) {
01402 if (ast_seekstream(chan->monitor->write_stream, jump + f->samples, SEEK_FORCECUR) == -1)
01403 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
01404 chan->outsmpl += jump + 2 * f->samples;
01405 } else
01406 chan->outsmpl += f->samples;
01407 #else
01408 int jump = chan->insmpl - chan->outsmpl;
01409 if (jump - MONITOR_DELAY >= 0) {
01410 if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1)
01411 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
01412 chan->outsmpl += jump;
01413 } else
01414 chan->outsmpl += f->samples;
01415 #endif
01416 if (ast_writestream(chan->monitor->write_stream, f) < 0)
01417 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
01418 }
01419 } else
01420 res = 0;
01421 }
01422 }
01423 if (f && (f != fr))
01424 ast_frfree(f);
01425 chan->blocking = 0;
01426
01427 if (res < 0)
01428 chan->_softhangup |= AST_SOFTHANGUP_DEV;
01429 else {
01430 if ((chan->fout & 0x7fffffff) == 0x7fffffff)
01431 chan->fout &= 0x80000000;
01432 else
01433 chan->fout++;
01434 chan->fout++;
01435 }
01436 ast_mutex_unlock(&chan->lock);
01437 return res;
01438 }
01439
01440 int ast_set_write_format(struct ast_channel *chan, int fmts)
01441 {
01442 int fmt;
01443 int native;
01444 int res;
01445
01446 native = chan->nativeformats;
01447 fmt = fmts;
01448
01449 res = ast_translator_best_choice(&native, &fmt);
01450 if (res < 0) {
01451 ast_log(LOG_NOTICE, "Unable to find a path from %s to %s\n",
01452 ast_getformatname(fmts), ast_getformatname(chan->nativeformats));
01453 return -1;
01454 }
01455
01456
01457 chan->pvt->rawwriteformat = native;
01458
01459 chan->writeformat = fmt;
01460
01461 if (chan->pvt->writetrans)
01462 ast_translator_free_path(chan->pvt->writetrans);
01463
01464 chan->pvt->writetrans = ast_translator_build_path(chan->pvt->rawwriteformat, chan->writeformat);
01465 if (option_debug)
01466 ast_log(LOG_DEBUG, "Set channel %s to write format %s\n", chan->name, ast_getformatname(chan->writeformat));
01467 return 0;
01468 }
01469
01470 int ast_set_read_format(struct ast_channel *chan, int fmts)
01471 {
01472 int fmt;
01473 int native;
01474 int res;
01475
01476 native = chan->nativeformats;
01477 fmt = fmts;
01478
01479 res = ast_translator_best_choice(&fmt, &native);
01480 if (res < 0) {
01481 ast_log(LOG_NOTICE, "Unable to find a path from %s to %s\n",
01482 ast_getformatname(chan->nativeformats), ast_getformatname(fmts));
01483 return -1;
01484 }
01485
01486
01487 chan->pvt->rawreadformat = native;
01488
01489 chan->readformat = fmt;
01490
01491 if (chan->pvt->readtrans)
01492 ast_translator_free_path(chan->pvt->readtrans);
01493
01494 chan->pvt->readtrans = ast_translator_build_path(chan->readformat, chan->pvt->rawreadformat);
01495 if (option_debug)
01496 ast_log(LOG_DEBUG, "Set channel %s to read format %s\n",
01497 chan->name, ast_getformatname(chan->readformat));
01498 return 0;
01499 }
01500
01501 struct ast_channel *__ast_request_and_dial(char *type, int format, void *data, int timeout, int *outstate, char *callerid, struct outgoing_helper *oh)
01502 {
01503 int state = 0;
01504 struct ast_channel *chan;
01505 struct ast_frame *f;
01506 int res = 0;
01507 chan = ast_request(type, format, data);
01508 if (chan) {
01509 if (oh) {
01510 char *tmp, *var;
01511
01512 tmp = oh->variable;
01513
01514 while( (var = strtok_r(NULL, "|", &tmp)) ) {
01515 pbx_builtin_setvar( chan, var );
01516 }
01517 if (oh->callerid && *oh->callerid)
01518 ast_set_callerid(chan, oh->callerid, 1);
01519 if (oh->account && *oh->account)
01520 ast_cdr_setaccount(chan, oh->account);
01521 }
01522 if (callerid && strlen(callerid))
01523 ast_set_callerid(chan, callerid, 1);
01524
01525 if (!ast_call(chan, data, 0)) {
01526 while(timeout && (chan->_state != AST_STATE_UP)) {
01527 res = ast_waitfor(chan, timeout);
01528 if (res < 0) {
01529
01530 break;
01531 }
01532
01533 if (!res)
01534 break;
01535 if (timeout > -1)
01536 timeout = res;
01537 f = ast_read(chan);
01538 if (!f) {
01539 state = AST_CONTROL_HANGUP;
01540 res = 0;
01541 break;
01542 }
01543 if (f->frametype == AST_FRAME_CONTROL) {
01544 if (f->subclass == AST_CONTROL_RINGING)
01545 state = AST_CONTROL_RINGING;
01546 else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) {
01547 state = f->subclass;
01548 ast_frfree(f);
01549 break;
01550 } else if (f->subclass == AST_CONTROL_ANSWER) {
01551 state = f->subclass;
01552 ast_frfree(f);
01553 break;
01554 } else {
01555 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
01556 }
01557 }
01558 ast_frfree(f);
01559 }
01560 } else
01561 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
01562 } else
01563 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
01564 if (chan) {
01565
01566 if (oh) {
01567 if (oh->context && *oh->context)
01568 strncpy(chan->context, oh->context, sizeof(chan->context) - 1);
01569 if (oh->exten && *oh->exten)
01570 strncpy(chan->exten, oh->exten, sizeof(chan->exten) - 1);
01571 chan->priority = oh->priority;
01572 }
01573 if (chan->_state == AST_STATE_UP)
01574 state = AST_CONTROL_ANSWER;
01575 }
01576 if (outstate)
01577 *outstate = state;
01578 if (chan && res <= 0) {
01579 if (!chan->cdr) {
01580 chan->cdr = ast_cdr_alloc();
01581 if (chan->cdr)
01582 ast_cdr_init(chan->cdr, chan);
01583 }
01584 if (chan->cdr) {
01585 char tmp[256];
01586 sprintf(tmp, "%s/%s",type,(char *)data);
01587 ast_cdr_setapp(chan->cdr,"Dial",tmp);
01588 ast_cdr_update(chan);
01589 ast_cdr_start(chan->cdr);
01590 ast_cdr_end(chan->cdr);
01591
01592 if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
01593 ast_cdr_failed(chan->cdr);
01594 } else
01595 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
01596 ast_hangup(chan);
01597 chan = NULL;
01598 }
01599 return chan;
01600 }
01601
01602 struct ast_channel *ast_request_and_dial(char *type, int format, void *data, int timeout, int *outstate, char *callerid)
01603 {
01604 return __ast_request_and_dial(type, format, data, timeout, outstate, callerid, NULL);
01605 }
01606
01607 struct ast_channel *ast_request(char *type, int format, void *data)
01608 {
01609 struct chanlist *chan;
01610 struct ast_channel *c = NULL;
01611 int capabilities;
01612 int fmt;
01613 int res;
01614 if (ast_mutex_lock(&chlock)) {
01615 ast_log(LOG_WARNING, "Unable to lock channel list\n");
01616 return NULL;
01617 }
01618 chan = backends;
01619 while(chan) {
01620 if (!strcasecmp(type, chan->type)) {
01621 capabilities = chan->capabilities;
01622 fmt = format;
01623 res = ast_translator_best_choice(&fmt, &capabilities);
01624 if (res < 0) {
01625 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->capabilities, format);
01626 ast_mutex_unlock(&chlock);
01627 return NULL;
01628 }
01629 ast_mutex_unlock(&chlock);
01630 if (chan->requester)
01631 c = chan->requester(type, capabilities, data);
01632 if (c) {
01633 if (c->_state == AST_STATE_DOWN) {
01634 manager_event(EVENT_FLAG_CALL, "Newchannel",
01635 "Channel: %s\r\n"
01636 "State: %s\r\n"
01637 "Callerid: %s\r\n"
01638 "Uniqueid: %s\r\n",
01639 c->name, ast_state2str(c->_state), c->callerid ? c->callerid : "<unknown>", c->uniqueid);
01640 }
01641 }
01642 return c;
01643 }
01644 chan = chan->next;
01645 }
01646 if (!chan)
01647 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
01648 ast_mutex_unlock(&chlock);
01649 return c;
01650 }
01651
01652 int ast_parse_device_state(char *device)
01653 {
01654 char name[AST_CHANNEL_NAME] = "";
01655 char *cut;
01656 struct ast_channel *chan;
01657
01658 chan = ast_channel_walk(NULL);
01659 while (chan) {
01660 strncpy(name, chan->name, sizeof(name)-1);
01661 cut = strchr(name,'-');
01662 if (cut)
01663 *cut = 0;
01664 if (!strcmp(name, device))
01665 return AST_DEVICE_INUSE;
01666 chan = ast_channel_walk(chan);
01667 }
01668 return AST_DEVICE_UNKNOWN;
01669 }
01670
01671 int ast_device_state(char *device)
01672 {
01673 char tech[AST_MAX_EXTENSION] = "";
01674 char *number;
01675 struct chanlist *chanls;
01676 int res = 0;
01677
01678 strncpy(tech, device, sizeof(tech)-1);
01679 number = strchr(tech, '/');
01680 if (!number) {
01681 return AST_DEVICE_INVALID;
01682 }
01683 *number = 0;
01684 number++;
01685
01686 if (ast_mutex_lock(&chlock)) {
01687 ast_log(LOG_WARNING, "Unable to lock channel list\n");
01688 return -1;
01689 }
01690 chanls = backends;
01691 while(chanls) {
01692 if (!strcasecmp(tech, chanls->type)) {
01693 ast_mutex_unlock(&chlock);
01694 if (!chanls->devicestate)
01695 return ast_parse_device_state(device);
01696 else {
01697 res = chanls->devicestate(number);
01698 if (res == AST_DEVICE_UNKNOWN)
01699 return ast_parse_device_state(device);
01700 else
01701 return res;
01702 }
01703 }
01704 chanls = chanls->next;
01705 }
01706 ast_mutex_unlock(&chlock);
01707 return AST_DEVICE_INVALID;
01708 }
01709
01710 int ast_call(struct ast_channel *chan, char *addr, int timeout)
01711 {
01712
01713
01714
01715 int res = -1;
01716
01717 ast_mutex_lock(&chan->lock);
01718 if (!chan->zombie && !ast_check_hangup(chan))
01719 if (chan->pvt->call)
01720 res = chan->pvt->call(chan, addr, timeout);
01721 ast_mutex_unlock(&chan->lock);
01722 return res;
01723 }
01724
01725 int ast_transfer(struct ast_channel *chan, char *dest)
01726 {
01727
01728
01729
01730 int res = -1;
01731
01732 ast_mutex_lock(&chan->lock);
01733 if (!chan->zombie && !ast_check_hangup(chan)) {
01734 if (chan->pvt->transfer) {
01735 res = chan->pvt->transfer(chan, dest);
01736 if (!res)
01737 res = 1;
01738 } else
01739 res = 0;
01740 }
01741 ast_mutex_unlock(&chan->lock);
01742 return res;
01743 }
01744
01745 int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders)
01746 {
01747 int pos=0;
01748 int to = ftimeout;
01749 char d;
01750
01751
01752 if (c->zombie || ast_check_hangup(c))
01753 return -1;
01754 if (!len)
01755 return -1;
01756 do {
01757 if (c->stream) {
01758 d = ast_waitstream(c, AST_DIGIT_ANY);
01759 ast_stopstream(c);
01760 usleep(1000);
01761 if (!d)
01762 d = ast_waitfordigit(c, to);
01763 } else {
01764 d = ast_waitfordigit(c, to);
01765 }
01766 if (d < 0)
01767 return -1;
01768 if (d == 0) {
01769 s[pos]='\0';
01770 return 1;
01771 }
01772 if (!strchr(enders, d))
01773 s[pos++] = d;
01774 if (strchr(enders, d) || (pos >= len)) {
01775 s[pos]='\0';
01776 return 0;
01777 }
01778 to = timeout;
01779 } while(1);
01780
01781 return 0;
01782 }
01783
01784 int ast_readstring_full(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders, int audiofd, int ctrlfd)
01785 {
01786 int pos=0;
01787 int to = ftimeout;
01788 char d;
01789
01790 if (c->zombie || ast_check_hangup(c))
01791 return -1;
01792 if (!len)
01793 return -1;
01794 do {
01795 if (c->stream) {
01796 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
01797 ast_stopstream(c);
01798 usleep(1000);
01799 if (!d)
01800 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
01801 } else {
01802 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
01803 }
01804 if (d < 0)
01805 return -1;
01806 if (d == 0) {
01807 s[pos]='\0';
01808 return 1;
01809 }
01810 if (d == 1) {
01811 s[pos]='\0';
01812 return 2;
01813 }
01814 if (!strchr(enders, d))
01815 s[pos++] = d;
01816 if (strchr(enders, d) || (pos >= len)) {
01817 s[pos]='\0';
01818 return 0;
01819 }
01820 to = timeout;
01821 } while(1);
01822
01823 return 0;
01824 }
01825
01826 int ast_channel_supports_html(struct ast_channel *chan)
01827 {
01828 if (chan->pvt->send_html)
01829 return 1;
01830 return 0;
01831 }
01832
01833 int ast_channel_sendhtml(struct ast_channel *chan, int subclass, char *data, int datalen)
01834 {
01835 if (chan->pvt->send_html)
01836 return chan->pvt->send_html(chan, subclass, data, datalen);
01837 return -1;
01838 }
01839
01840 int ast_channel_sendurl(struct ast_channel *chan, char *url)
01841 {
01842 if (chan->pvt->send_html)
01843 return chan->pvt->send_html(chan, AST_HTML_URL, url, strlen(url) + 1);
01844 return -1;
01845 }
01846
01847 int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
01848 {
01849 int peerf;
01850 int chanf;
01851 int res;
01852 peerf = peer->nativeformats;
01853 chanf = chan->nativeformats;
01854 res = ast_translator_best_choice(&peerf, &chanf);
01855 if (res < 0) {
01856 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, chan->nativeformats, peer->name, peer->nativeformats);
01857 return -1;
01858 }
01859
01860 res = ast_set_read_format(chan, peerf);
01861 if (res < 0) {
01862 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, chanf);
01863 return -1;
01864 }
01865
01866 res = ast_set_write_format(peer, peerf);
01867 if (res < 0) {
01868 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, peerf);
01869 return -1;
01870 }
01871
01872 peerf = peer->nativeformats;
01873 chanf = chan->nativeformats;
01874 res = ast_translator_best_choice(&chanf, &peerf);
01875 if (res < 0) {
01876 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, peer->nativeformats, chan->name, chan->nativeformats);
01877 return -1;
01878 }
01879
01880 res = ast_set_write_format(chan, chanf);
01881 if (res < 0) {
01882 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, chanf);
01883 return -1;
01884 }
01885
01886 res = ast_set_read_format(peer, chanf);
01887 if (res < 0) {
01888 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, peerf);
01889 return -1;
01890 }
01891 return 0;
01892 }
01893
01894 int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone)
01895 {
01896 struct ast_frame null = { AST_FRAME_NULL, };
01897 ast_log(LOG_DEBUG, "Planning to masquerade %s into the structure of %s\n",
01898 clone->name, original->name);
01899 if (original->masq) {
01900 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
01901 original->masq->name, original->name);
01902 return -1;
01903 }
01904 if (clone->masqr) {
01905 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
01906 clone->name, clone->masqr->name);
01907 return -1;
01908 }
01909 original->masq = clone;
01910 clone->masqr = original;
01911
01912
01913 ast_queue_frame(original, &null, 0);
01914 ast_queue_frame(clone, &null, 0);
01915 ast_log(LOG_DEBUG, "Done planning to masquerade %s into the structure of %s\n", original->name, clone->name);
01916 return 0;
01917 }
01918
01919 void ast_change_name(struct ast_channel *chan, char *newname)
01920 {
01921 char tmp[256];
01922 strncpy(tmp, chan->name, 256);
01923 strncpy(chan->name, newname, sizeof(chan->name) - 1);
01924 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", tmp, chan->name, chan->uniqueid);
01925 }
01926
01927 static int ast_do_masquerade(struct ast_channel *original)
01928 {
01929 int x,i;
01930 int res=0;
01931 char *tmp;
01932 struct ast_var_t *varptr;
01933 struct ast_frame *cur, *prev;
01934 struct ast_channel_pvt *p;
01935 struct ast_channel *clone = original->masq;
01936 int rformat = original->readformat;
01937 int wformat = original->writeformat;
01938 char newn[100];
01939 char orig[100];
01940 char masqn[100];
01941 char zombn[100];
01942
01943 #if 1
01944 ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",
01945 clone->name, clone->_state, original->name, original->_state);
01946 #endif
01947
01948
01949
01950
01951
01952
01953 ast_mutex_lock(&clone->lock);
01954
01955 ast_log(LOG_DEBUG, "Got clone lock on '%s' at %p\n", clone->name, &clone->lock);
01956
01957
01958
01959 free_translation(clone);
01960 free_translation(original);
01961
01962
01963
01964 original->masq = NULL;
01965 clone->masqr = NULL;
01966
01967
01968 strncpy(orig, original->name, sizeof(orig) - 1);
01969
01970 strncpy(newn, clone->name, sizeof(newn) - 1);
01971
01972 snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn);
01973
01974
01975 strncpy(original->name, newn, sizeof(original->name)-1);
01976
01977
01978 strncpy(clone->name, masqn, sizeof(clone->name) - 1);
01979
01980
01981 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\n", newn, masqn);
01982 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\n", orig, newn);
01983
01984
01985 p = original->pvt;
01986 original->pvt = clone->pvt;
01987 clone->pvt = p;
01988
01989
01990
01991 prev = NULL;
01992 cur = clone->pvt->readq;
01993 x = 0;
01994 while(cur) {
01995 x++;
01996 prev = cur;
01997 cur = cur->next;
01998 }
01999
02000
02001 if (prev) {
02002 prev->next = original->pvt->readq;
02003 original->pvt->readq = clone->pvt->readq;
02004 clone->pvt->readq = NULL;
02005 if (original->pvt->alertpipe[1] > -1) {
02006 for (i=0;i<x;i++)
02007 write(original->pvt->alertpipe[1], &x, sizeof(x));
02008 }
02009 }
02010 clone->_softhangup = AST_SOFTHANGUP_DEV;
02011
02012
02013 if (clone->pvt->fixup){
02014 res = clone->pvt->fixup(original, clone);
02015 if (res)
02016 ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name);
02017 }
02018
02019
02020 if (clone->pvt->hangup)
02021 res = clone->pvt->hangup(clone);
02022 if (res) {
02023 ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n");
02024 ast_mutex_unlock(&clone->lock);
02025 return -1;
02026 }
02027
02028 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig);
02029
02030 strncpy(clone->name, zombn, sizeof(clone->name) - 1);
02031 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\n", masqn, zombn);
02032
02033
02034
02035 original->type = clone->type;
02036
02037 for (x=0;x<AST_MAX_FDS;x++) {
02038 original->fds[x] = clone->fds[x];
02039 }
02040
02041
02042 varptr = original->varshead.first;
02043 if (varptr) {
02044 while(varptr->entries.next) {
02045 varptr = varptr->entries.next;
02046 }
02047 varptr->entries.next = clone->varshead.first;
02048 } else {
02049 original->varshead.first = clone->varshead.first;
02050 }
02051 clone->varshead.first = NULL;
02052
02053 original->adsicpe = clone->adsicpe;
02054
02055
02056
02057
02058
02059 original->exception = clone->exception;
02060 original->fdno = clone->fdno;
02061
02062
02063
02064
02065
02066
02067
02068 tmp = original->dnid;
02069 original->dnid = clone->dnid;
02070 clone->dnid = tmp;
02071
02072 tmp = original->callerid;
02073 original->callerid = clone->callerid;
02074 clone->callerid = tmp;
02075
02076
02077 original->fds[AST_MAX_FDS - 2] = original->timingfd;
02078
02079
02080 original->nativeformats = clone->nativeformats;
02081
02082
02083
02084
02085 original->_state = clone->_state;
02086
02087
02088
02089
02090
02091
02092
02093 if (clone->zombie) {
02094 ast_log(LOG_DEBUG, "Destroying clone '%s'\n", clone->name);
02095 ast_mutex_unlock(&clone->lock);
02096 ast_channel_free(clone);
02097 manager_event(EVENT_FLAG_CALL, "Hangup", "Channel: %s\r\n", zombn);
02098 } else {
02099 ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name);
02100 clone->zombie=1;
02101 ast_mutex_unlock(&clone->lock);
02102 }
02103
02104 ast_set_write_format(original, wformat);
02105
02106
02107 ast_set_read_format(original, rformat);
02108
02109 ast_log(LOG_DEBUG, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat);
02110
02111
02112
02113 if (original->pvt->fixup) {
02114 res = original->pvt->fixup(clone, original);
02115 if (res) {
02116 ast_log(LOG_WARNING, "Driver for '%s' could not fixup channel %s\n",
02117 original->type, original->name);
02118 return -1;
02119 }
02120 } else
02121 ast_log(LOG_WARNING, "Driver '%s' does not have a fixup routine (for %s)! Bad things may happen.\n",
02122 original->type, original->name);
02123
02124 if (original->blocking)
02125 pthread_kill(original->blocker, SIGURG);
02126 ast_log(LOG_DEBUG, "Done Masquerading %s (%d)\n",
02127 original->name, original->_state);
02128 return 0;
02129 }
02130
02131 void ast_set_callerid(struct ast_channel *chan, char *callerid, int anitoo)
02132 {
02133 if (chan->callerid)
02134 free(chan->callerid);
02135 if (anitoo && chan->ani)
02136 free(chan->ani);
02137 if (callerid) {
02138 chan->callerid = strdup(callerid);
02139 if (anitoo)
02140 chan->ani = strdup(callerid);
02141 } else {
02142 chan->callerid = NULL;
02143 if (anitoo)
02144 chan->ani = NULL;
02145 }
02146 if (chan->cdr)
02147 ast_cdr_setcid(chan->cdr, chan);
02148 manager_event(EVENT_FLAG_CALL, "Newcallerid",
02149 "Channel: %s\r\n"
02150 "Callerid: %s\r\n"
02151 "Uniqueid: %s\r\n",
02152 chan->name, chan->callerid ?
02153 chan->callerid : "<Unknown>",
02154 chan->uniqueid);
02155 }
02156
02157 int ast_setstate(struct ast_channel *chan, int state)
02158 {
02159 if (chan->_state != state) {
02160 int oldstate = chan->_state;
02161 chan->_state = state;
02162 if (oldstate == AST_STATE_DOWN) {
02163 ast_device_state_changed(chan->name);
02164 manager_event(EVENT_FLAG_CALL, "Newchannel",
02165 "Channel: %s\r\n"
02166 "State: %s\r\n"
02167 "Callerid: %s\r\n"
02168 "Uniqueid: %s\r\n",
02169 chan->name, ast_state2str(chan->_state), chan->callerid ? chan->callerid : "<unknown>", chan->uniqueid);
02170 } else {
02171 manager_event(EVENT_FLAG_CALL, "Newstate",
02172 "Channel: %s\r\n"
02173 "State: %s\r\n"
02174 "Callerid: %s\r\n"
02175 "Uniqueid: %s\r\n",
02176 chan->name, ast_state2str(chan->_state), chan->callerid ? chan->callerid : "<unknown>", chan->uniqueid);
02177 }
02178 }
02179 return 0;
02180 }
02181
02182 int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc)
02183 {
02184
02185
02186 struct ast_channel *cs[3];
02187 int to = -1;
02188 struct ast_frame *f;
02189 struct ast_channel *who = NULL;
02190 int res;
02191 int nativefailed=0;
02192
02193
02194 if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1))
02195 return -1;
02196 if (c0->bridge) {
02197 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
02198 c0->name, c0->bridge->name);
02199 return -1;
02200 }
02201 if (c1->bridge) {
02202 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
02203 c1->name, c1->bridge->name);
02204 return -1;
02205 }
02206
02207
02208 c0->bridge = c1;
02209 c1->bridge = c0;
02210 cs[0] = c0;
02211 cs[1] = c1;
02212
02213 manager_event(EVENT_FLAG_CALL, "Link",
02214 "Channel1: %s\r\n"
02215 "Channel2: %s\r\n",
02216 c0->name, c1->name);
02217
02218 for (;;) {
02219
02220 if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1)) {
02221 *fo = NULL;
02222 if (who) *rc = who;
02223 res = 0;
02224 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");
02225 break;
02226 }
02227 if (c0->pvt->bridge &&
02228 (c0->pvt->bridge == c1->pvt->bridge) && !nativefailed && !c0->monitor && !c1->monitor) {
02229
02230 if (option_verbose > 2)
02231 ast_verbose(VERBOSE_PREFIX_3 "Attempting native bridge of %s and %s\n", c0->name, c1->name);
02232 if (!(res = c0->pvt->bridge(c0, c1, flags, fo, rc))) {
02233 c0->bridge = NULL;
02234 c1->bridge = NULL;
02235 manager_event(EVENT_FLAG_CALL, "Unlink",
02236 "Channel1: %s\r\n"
02237 "Channel2: %s\r\n",
02238 c0->name, c1->name);
02239 ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n",c0->name ,c1->name);
02240 return 0;
02241 }
02242
02243
02244 if ((res != -2) && (res != -3))
02245 ast_log(LOG_WARNING, "Private bridge between %s and %s failed\n", c0->name, c1->name);
02246 if (res != -3) nativefailed++;
02247 }
02248
02249
02250 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat)) &&
02251 !(c0->generator || c1->generator)) {
02252 if (ast_channel_make_compatible(c0, c1)) {
02253 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
02254 manager_event(EVENT_FLAG_CALL, "Unlink",
02255 "Channel1: %s\r\n"
02256 "Channel2: %s\r\n",
02257 c0->name, c1->name);
02258 return -1;
02259 }
02260 }
02261 who = ast_waitfor_n(cs, 2, &to);
02262 if (!who) {
02263 ast_log(LOG_DEBUG, "Nobody there, continuing...\n");
02264 continue;
02265 }
02266 f = ast_read(who);
02267 if (!f) {
02268 *fo = NULL;
02269 *rc = who;
02270 res = 0;
02271 ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name);
02272 break;
02273 }
02274
02275 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
02276 *fo = f;
02277 *rc = who;
02278 res = 0;
02279 ast_log(LOG_DEBUG, "Got a FRAME_CONTROL frame on channel %s\n",who->name);
02280 break;
02281 }
02282 if ((f->frametype == AST_FRAME_VOICE) ||
02283 (f->frametype == AST_FRAME_TEXT) ||
02284 (f->frametype == AST_FRAME_VIDEO) ||
02285 (f->frametype == AST_FRAME_IMAGE) ||
02286 (f->frametype == AST_FRAME_DTMF)) {
02287 if ((f->frametype == AST_FRAME_DTMF) &&
02288 (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
02289 if ((who == c0)) {
02290 if ((flags & AST_BRIDGE_DTMF_CHANNEL_0)) {
02291 *rc = c0;
02292 *fo = f;
02293
02294 res = 0;
02295 ast_log(LOG_DEBUG, "Got AST_BRIDGE_DTMF_CHANNEL_0 on c0 (%s)\n",c0->name);
02296 break;
02297 } else
02298 goto tackygoto;
02299 } else
02300 if ((who == c1)) {
02301 if (flags & AST_BRIDGE_DTMF_CHANNEL_1) {
02302 *rc = c1;
02303 *fo = f;
02304 res = 0;
02305 ast_log(LOG_DEBUG, "Got AST_BRIDGE_DTMF_CHANNEL_1 on c1 (%s)\n",c1->name);
02306 break;
02307 } else
02308 goto tackygoto;
02309 }
02310 } else {
02311 #if 0
02312 ast_log(LOG_DEBUG, "Read from %s\n", who->name);
02313 if (who == last)
02314 ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name);
02315 last = who;
02316 #endif
02317 tackygoto:
02318
02319
02320 if (who == c0)
02321 ast_write(c1, f);
02322 else
02323 ast_write(c0, f);
02324 }
02325 ast_frfree(f);
02326 } else
02327 ast_frfree(f);
02328
02329 cs[2] = cs[0];
02330 cs[0] = cs[1];
02331 cs[1] = cs[2];
02332 }
02333 c0->bridge = NULL;
02334 c1->bridge = NULL;
02335 manager_event(EVENT_FLAG_CALL, "Unlink",
02336 "Channel1: %s\r\n"
02337 "Channel2: %s\r\n",
02338 c0->name, c1->name);
02339 ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n",c0->name,c1->name);
02340 return res;
02341 }
02342
02343 int ast_channel_setoption(struct ast_channel *chan, int option, void *data, int datalen, int block)
02344 {
02345 int res;
02346 if (chan->pvt->setoption) {
02347 res = chan->pvt->setoption(chan, option, data, datalen);
02348 if (res < 0)
02349 return res;
02350 } else {
02351 errno = ENOSYS;
02352 return -1;
02353 }
02354 if (block) {
02355
02356
02357 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
02358 return -1;
02359 }
02360 return 0;
02361 }
02362
02363 struct tonepair_def {
02364 int freq1;
02365 int freq2;
02366 int duration;
02367 int vol;
02368 };
02369
02370 struct tonepair_state {
02371 float freq1;
02372 float freq2;
02373 float vol;
02374 int duration;
02375 int pos;
02376 int origwfmt;
02377 struct ast_frame f;
02378 unsigned char offset[AST_FRIENDLY_OFFSET];
02379 short data[4000];
02380 };
02381
02382 static void tonepair_release(struct ast_channel *chan, void *params)
02383 {
02384 struct tonepair_state *ts = params;
02385 if (chan) {
02386 ast_set_write_format(chan, ts->origwfmt);
02387 }
02388 free(ts);
02389 }
02390
02391 static void * tonepair_alloc(struct ast_channel *chan, void *params)
02392 {
02393 struct tonepair_state *ts;
02394 struct tonepair_def *td = params;
02395 ts = malloc(sizeof(struct tonepair_state));
02396 if (!ts)
02397 return NULL;
02398 memset(ts, 0, sizeof(struct tonepair_state));
02399 ts->origwfmt = chan->writeformat;
02400 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
02401 ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
02402 tonepair_release(NULL, ts);
02403 ts = NULL;
02404 } else {
02405 ts->freq1 = td->freq1;
02406 ts->freq2 = td->freq2;
02407 ts->duration = td->duration;
02408 ts->vol = td->vol;
02409 }
02410
02411 chan->writeinterrupt = 1;
02412 return ts;
02413 }
02414
02415 static int tonepair_generator(struct ast_channel *chan, void *data, int len, int samples)
02416 {
02417 struct tonepair_state *ts = data;
02418 int x;
02419
02420
02421
02422
02423 len = samples * 2;
02424
02425 if (len > sizeof(ts->data) / 2 - 1) {
02426 ast_log(LOG_WARNING, "Can't generate that much data!\n");
02427 return -1;
02428 }
02429 memset(&ts->f, 0, sizeof(ts->f));
02430 for (x=0;x<len/2;x++) {
02431 ts->data[x] = ts->vol * (
02432 sin((ts->freq1 * 2.0 * M_PI / 8000.0) * (ts->pos + x)) +
02433 sin((ts->freq2 * 2.0 * M_PI / 8000.0) * (ts->pos + x))
02434 );
02435 }
02436 ts->f.frametype = AST_FRAME_VOICE;
02437 ts->f.subclass = AST_FORMAT_SLINEAR;
02438 ts->f.datalen = len;
02439 ts->f.samples = samples;
02440 ts->f.offset = AST_FRIENDLY_OFFSET;
02441 ts->f.data = ts->data;
02442 ast_write(chan, &ts->f);
02443 ts->pos += x;
02444 if (ts->duration > 0) {
02445 if (ts->pos >= ts->duration * 8)
02446 return -1;
02447 }
02448 return 0;
02449 }
02450
02451 static struct ast_generator tonepair = {
02452 alloc: tonepair_alloc,
02453 release: tonepair_release,
02454 generate: tonepair_generator,
02455 };
02456
02457 int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
02458 {
02459 struct tonepair_def d = { 0, };
02460 d.freq1 = freq1;
02461 d.freq2 = freq2;
02462 d.duration = duration;
02463 if (vol < 1)
02464 d.vol = 8192;
02465 else
02466 d.vol = vol;
02467 if (ast_activate_generator(chan, &tonepair, &d))
02468 return -1;
02469 return 0;
02470 }
02471
02472 void ast_tonepair_stop(struct ast_channel *chan)
02473 {
02474 ast_deactivate_generator(chan);
02475 }
02476
02477 int ast_tonepair(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
02478 {
02479 struct ast_frame *f;
02480 int res;
02481 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
02482 return res;
02483
02484
02485 while(chan->generatordata && (ast_waitfor(chan, 100) >= 0)) {
02486 f = ast_read(chan);
02487 if (f)
02488 ast_frfree(f);
02489 else
02490 return -1;
02491 }
02492 return 0;
02493 }
02494