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