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 chan->zombie=1;
00634 ast_mutex_unlock(&chan->lock);
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 if (chan->generator && chan->generator->release)
00737 chan->generator->release(chan, chan->generatordata);
00738 chan->generatordata = NULL;
00739 chan->generator = NULL;
00740 chan->writeinterrupt = 0;
00741 }
00742 }
00743
00744 int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, void *params)
00745 {
00746 if (chan->generatordata) {
00747 if (chan->generator && chan->generator->release)
00748 chan->generator->release(chan, chan->generatordata);
00749 chan->generatordata = NULL;
00750 }
00751 ast_prod(chan);
00752 if ((chan->generatordata = gen->alloc(chan, params))) {
00753 chan->generator = gen;
00754 } else {
00755 return -1;
00756 }
00757 return 0;
00758 }
00759
00760 int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception)
00761 {
00762
00763 struct timeval tv;
00764 fd_set rfds, efds;
00765 int res;
00766 int x, max=-1;
00767 int winner = -1;
00768
00769 tv.tv_sec = *ms / 1000;
00770 tv.tv_usec = (*ms % 1000) * 1000;
00771 FD_ZERO(&rfds);
00772 FD_ZERO(&efds);
00773 for (x=0;x<n;x++) {
00774 if (fds[x] > -1) {
00775 FD_SET(fds[x], &rfds);
00776 FD_SET(fds[x], &efds);
00777 if (fds[x] > max)
00778 max = fds[x];
00779 }
00780 }
00781 if (*ms >= 0)
00782 res = ast_select(max + 1, &rfds, NULL, &efds, &tv);
00783 else
00784 res = ast_select(max + 1, &rfds, NULL, &efds, NULL);
00785
00786 if (res < 0) {
00787
00788 if (errno != EINTR)
00789 *ms = -1;
00790 else
00791 *ms = 0;
00792 return -1;
00793 }
00794
00795 for (x=0;x<n;x++) {
00796 if ((fds[x] > -1) && (FD_ISSET(fds[x], &rfds) || FD_ISSET(fds[x], &efds)) && (winner < 0)) {
00797 if (exception)
00798 *exception = FD_ISSET(fds[x], &efds);
00799 winner = fds[x];
00800 }
00801 }
00802 *ms = tv.tv_sec * 1000 + tv.tv_usec / 1000;
00803 return winner;
00804 }
00805
00806 struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds, int nfds,
00807 int *exception, int *outfd, int *ms)
00808 {
00809
00810 struct timeval tv;
00811 fd_set rfds, efds;
00812 int res;
00813 int x, y, max=-1;
00814 time_t now = 0;
00815 long whentohangup = 0, havewhen = 0, diff;
00816 struct ast_channel *winner = NULL;
00817 if (outfd)
00818 *outfd = -99999;
00819 if (exception)
00820 *exception = 0;
00821
00822
00823 for (x=0;x<n;x++) {
00824 ast_mutex_lock(&c[x]->lock);
00825 if (c[x]->whentohangup) {
00826 if (!havewhen)
00827 time(&now);
00828 diff = c[x]->whentohangup - now;
00829 if (!havewhen || (diff < whentohangup)) {
00830 havewhen++;
00831 whentohangup = diff;
00832 }
00833 }
00834 if (c[x]->masq) {
00835 if (ast_do_masquerade(c[x])) {
00836 ast_log(LOG_WARNING, "Masquerade failed\n");
00837 *ms = -1;
00838 ast_mutex_unlock(&c[x]->lock);
00839 return NULL;
00840 }
00841 }
00842 ast_mutex_unlock(&c[x]->lock);
00843 }
00844
00845 tv.tv_sec = *ms / 1000;
00846 tv.tv_usec = (*ms % 1000) * 1000;
00847
00848 if (havewhen) {
00849 if ((*ms < 0) || (whentohangup * 1000 < *ms)) {
00850 tv.tv_sec = whentohangup;
00851 tv.tv_usec = 0;
00852 }
00853 }
00854 FD_ZERO(&rfds);
00855 FD_ZERO(&efds);
00856
00857 for (x=0;x<n;x++) {
00858 for (y=0;y<AST_MAX_FDS;y++) {
00859 if (c[x]->fds[y] > -1) {
00860 FD_SET(c[x]->fds[y], &rfds);
00861 FD_SET(c[x]->fds[y], &efds);
00862 if (c[x]->fds[y] > max)
00863 max = c[x]->fds[y];
00864 }
00865 }
00866 CHECK_BLOCKING(c[x]);
00867 }
00868 for (x=0;x<nfds; x++) {
00869 FD_SET(fds[x], &rfds);
00870 FD_SET(fds[x], &efds);
00871 if (fds[x] > max)
00872 max = fds[x];
00873 }
00874 if ((*ms >= 0) || (havewhen))
00875 res = ast_select(max + 1, &rfds, NULL, &efds, &tv);
00876 else
00877 res = ast_select(max + 1, &rfds, NULL, &efds, NULL);
00878
00879 if (res < 0) {
00880 for (x=0;x<n;x++)
00881 c[x]->blocking = 0;
00882
00883 if (errno != EINTR)
00884 *ms = -1;
00885 else {
00886
00887 #if 0
00888 *ms = 0;
00889 #endif
00890 }
00891 return NULL;
00892 }
00893
00894 if (havewhen)
00895 time(&now);
00896 for (x=0;x<n;x++) {
00897 c[x]->blocking = 0;
00898 if (havewhen && c[x]->whentohangup && (now > c[x]->whentohangup)) {
00899 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
00900 if (!winner)
00901 winner = c[x];
00902 }
00903 for (y=0;y<AST_MAX_FDS;y++) {
00904 if (c[x]->fds[y] > -1) {
00905 if ((FD_ISSET(c[x]->fds[y], &rfds) || FD_ISSET(c[x]->fds[y], &efds)) && !winner) {
00906
00907 if (FD_ISSET(c[x]->fds[y], &efds))
00908 c[x]->exception = 1;
00909 c[x]->fdno = y;
00910 winner = c[x];
00911 }
00912 }
00913 }
00914 }
00915 for (x=0;x<nfds;x++) {
00916 if ((FD_ISSET(fds[x], &rfds) || FD_ISSET(fds[x], &efds)) && !winner) {
00917 if (outfd)
00918 *outfd = fds[x];
00919 if (FD_ISSET(fds[x], &efds) && exception)
00920 *exception = 1;
00921 winner = NULL;
00922 }
00923 }
00924 *ms = tv.tv_sec * 1000 + tv.tv_usec / 1000;
00925 return winner;
00926 }
00927
00928 struct ast_channel *ast_waitfor_n(struct ast_channel **c, int n, int *ms)
00929 {
00930 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
00931 }
00932
00933 int ast_waitfor(struct ast_channel *c, int ms)
00934 {
00935 struct ast_channel *chan;
00936 int oldms = ms;
00937 chan = ast_waitfor_n(&c, 1, &ms);
00938 if (ms < 0) {
00939 if (oldms < 0)
00940 return 0;
00941 else
00942 return -1;
00943 }
00944 return ms;
00945 }
00946
00947 char ast_waitfordigit(struct ast_channel *c, int ms)
00948 {
00949
00950 struct ast_frame *f;
00951 char result = 0;
00952
00953 if (c->zombie || ast_check_hangup(c))
00954 return -1;
00955
00956 while(ms && !result) {
00957 ms = ast_waitfor(c, ms);
00958 if (ms < 0)
00959 result = -1;
00960 else if (ms > 0) {
00961
00962 f = ast_read(c);
00963 if (f) {
00964 if (f->frametype == AST_FRAME_DTMF)
00965 result = f->subclass;
00966 ast_frfree(f);
00967 } else
00968 result = -1;
00969 }
00970 }
00971 return result;
00972 }
00973
00974 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
00975 {
00976 int res = -1;
00977 #ifdef ZAPTEL_OPTIMIZATIONS
00978 if (c->timingfd > -1) {
00979 if (!func) {
00980 samples = 0;
00981 data = 0;
00982 }
00983 ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
00984 res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
00985 c->timingfunc = func;
00986 c->timingdata = data;
00987 }
00988 #endif
00989 return res;
00990 }
00991 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audio, int ctrl)
00992 {
00993 struct ast_frame *f;
00994 char result = 0;
00995 struct ast_channel *rchan;
00996 int outfd;
00997
00998 if (c->zombie || ast_check_hangup(c))
00999 return -1;
01000
01001 while(ms && !result) {
01002 rchan = ast_waitfor_nandfds(&c, 1, &audio, (audio > -1) ? 1 : 0, NULL, &outfd, &ms);
01003 if ((!rchan) && (outfd < 0) && (ms))
01004 result = -1;
01005 else if (outfd > -1) {
01006 result = 1;
01007 } else if (rchan) {
01008
01009 f = ast_read(c);
01010 if (f) {
01011 if (f->frametype == AST_FRAME_DTMF)
01012 result = f->subclass;
01013 ast_frfree(f);
01014 } else
01015 result = -1;
01016 }
01017 }
01018 return result;
01019 }
01020
01021 struct ast_frame *ast_read(struct ast_channel *chan)
01022 {
01023 struct ast_frame *f = NULL;
01024 int blah;
01025 #ifdef ZAPTEL_OPTIMIZATIONS
01026 int (*func)(void *);
01027 void *data;
01028 #endif
01029 static struct ast_frame null_frame =
01030 {
01031 AST_FRAME_NULL,
01032 };
01033
01034 ast_mutex_lock(&chan->lock);
01035 if (chan->masq) {
01036 if (ast_do_masquerade(chan)) {
01037 ast_log(LOG_WARNING, "Failed to perform masquerade\n");
01038 f = NULL;
01039 } else
01040 f = &null_frame;
01041 ast_mutex_unlock(&chan->lock);
01042 return f;
01043 }
01044
01045
01046 if (chan->zombie || ast_check_hangup(chan)) {
01047 if (chan->generator)
01048 ast_deactivate_generator(chan);
01049 ast_mutex_unlock(&chan->lock);
01050 return NULL;
01051 }
01052
01053 if (!chan->deferdtmf && strlen(chan->dtmfq)) {
01054
01055 chan->dtmff.frametype = AST_FRAME_DTMF;
01056 chan->dtmff.subclass = chan->dtmfq[0];
01057
01058 memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1);
01059 ast_mutex_unlock(&chan->lock);
01060 return &chan->dtmff;
01061 }
01062
01063
01064
01065 if (chan->pvt->alertpipe[0] > -1) {
01066 read(chan->pvt->alertpipe[0], &blah, sizeof(blah));
01067 }
01068 #ifdef ZAPTEL_OPTIMIZATIONS
01069 if ((chan->timingfd > -1) && (chan->fdno == AST_MAX_FDS - 2) && chan->exception) {
01070 chan->exception = 0;
01071 blah = -1;
01072 ioctl(chan->timingfd, ZT_TIMERACK, &blah);
01073 func = chan->timingfunc;
01074 data = chan->timingdata;
01075 ast_mutex_unlock(&chan->lock);
01076 if (func) {
01077 #if 0
01078 ast_log(LOG_DEBUG, "Calling private function\n");
01079 #endif
01080 func(data);
01081 } else {
01082 blah = 0;
01083 ast_mutex_lock(&chan->lock);
01084 ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah);
01085 chan->timingdata = NULL;
01086 ast_mutex_unlock(&chan->lock);
01087 }
01088 f = &null_frame;
01089 return f;
01090 }
01091 #endif
01092
01093 if (chan->pvt->readq) {
01094 f = chan->pvt->readq;
01095 chan->pvt->readq = f->next;
01096
01097 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) {
01098 ast_frfree(f);
01099 f = NULL;
01100 }
01101 } else {
01102 chan->blocker = pthread_self();
01103 if (chan->exception) {
01104 if (chan->pvt->exception)
01105 f = chan->pvt->exception(chan);
01106 else {
01107 ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name);
01108 f = &null_frame;
01109 }
01110
01111 chan->exception = 0;
01112 } else
01113 if (chan->pvt->read)
01114 f = chan->pvt->read(chan);
01115 else
01116 ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
01117 }
01118
01119
01120 if (f && (f->frametype == AST_FRAME_VOICE)) {
01121 if (!(f->subclass & chan->nativeformats)) {
01122
01123
01124 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));
01125 ast_frfree(f);
01126 f = &null_frame;
01127 } else {
01128 if (chan->monitor && chan->monitor->read_stream ) {
01129 #ifndef MONITOR_CONSTANT_DELAY
01130 int jump = chan->outsmpl - chan->insmpl - 2 * f->samples;
01131 if (jump >= 0) {
01132 if (ast_seekstream(chan->monitor->read_stream, jump + f->samples, SEEK_FORCECUR) == -1)
01133 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
01134 chan->insmpl += jump + 2 * f->samples;
01135 } else
01136 chan->insmpl+= f->samples;
01137 #else
01138 int jump = chan->outsmpl - chan->insmpl;
01139 if (jump - MONITOR_DELAY >= 0) {
01140 if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
01141 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
01142 chan->insmpl += jump;
01143 } else
01144 chan->insmpl += f->samples;
01145 #endif
01146 if (ast_writestream(chan->monitor->read_stream, f) < 0)
01147 ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
01148 }
01149 if (chan->pvt->readtrans) {
01150 f = ast_translate(chan->pvt->readtrans, f, 1);
01151 if (!f)
01152 f = &null_frame;
01153 }
01154 }
01155 }
01156
01157
01158 if (!f) {
01159 chan->_softhangup |= AST_SOFTHANGUP_DEV;
01160 if (chan->generator)
01161 ast_deactivate_generator(chan);
01162
01163 if (chan->cdr)
01164 ast_cdr_end(chan->cdr);
01165 } else if (chan->deferdtmf && f->frametype == AST_FRAME_DTMF) {
01166 if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2)
01167 chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
01168 else
01169 ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
01170 f = &null_frame;
01171 } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_ANSWER)) {
01172
01173 ast_setstate(chan, AST_STATE_UP);
01174 ast_cdr_answer(chan->cdr);
01175 }
01176 ast_mutex_unlock(&chan->lock);
01177
01178
01179 if (f && (f->frametype == AST_FRAME_VOICE) && chan->generatordata) {
01180
01181 void *tmp;
01182 int res;
01183 tmp = chan->generatordata;
01184 chan->generatordata = NULL;
01185 res = chan->generator->generate(chan, tmp, f->datalen, f->samples);
01186 chan->generatordata = tmp;
01187 if (res) {
01188 ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
01189 ast_deactivate_generator(chan);
01190 }
01191 }
01192 if (chan->fin & 0x80000000)
01193 ast_frame_dump(chan->name, f, "<<");
01194 if ((chan->fin & 0x7fffffff) == 0x7fffffff)
01195 chan->fin &= 0x80000000;
01196 else
01197 chan->fin++;
01198 return f;
01199 }
01200
01201 int ast_indicate(struct ast_channel *chan, int condition)
01202 {
01203 int res = -1;
01204
01205 if (chan->zombie || ast_check_hangup(chan))
01206 return -1;
01207 ast_mutex_lock(&chan->lock);
01208 if (chan->pvt->indicate)
01209 res = chan->pvt->indicate(chan, condition);
01210 ast_mutex_unlock(&chan->lock);
01211 if (!chan->pvt->indicate || res) {
01212
01213
01214
01215
01216 if (condition >= 0) {
01217 const struct tone_zone_sound *ts = NULL;
01218 switch (condition) {
01219 case AST_CONTROL_RINGING:
01220 ts = ast_get_indication_tone(chan->zone, "ring");
01221 break;
01222 case AST_CONTROL_BUSY:
01223 ts = ast_get_indication_tone(chan->zone, "busy");
01224 break;
01225 case AST_CONTROL_CONGESTION:
01226 ts = ast_get_indication_tone(chan->zone, "congestion");
01227 break;
01228 }
01229 if (ts && ts->data[0]) {
01230 ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
01231 ast_playtones_start(chan,0,ts->data, 1);
01232 res = 0;
01233 } else if (condition == AST_CONTROL_PROGRESS) {
01234
01235 } else {
01236
01237 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
01238 res = -1;
01239 }
01240 }
01241 else ast_playtones_stop(chan);
01242 }
01243 return res;
01244 }
01245
01246 int ast_recvchar(struct ast_channel *chan, int timeout)
01247 {
01248 int res,ourto,c;
01249 struct ast_frame *f;
01250
01251 ourto = timeout;
01252 for(;;)
01253 {
01254 if (ast_check_hangup(chan)) return -1;
01255 res = ast_waitfor(chan,ourto);
01256 if (res <= 0)
01257 {
01258 return 0;
01259 }
01260 ourto = res;
01261 f = ast_read(chan);
01262 if (f == NULL) return -1;
01263 if ((f->frametype == AST_FRAME_CONTROL) &&
01264 (f->subclass == AST_CONTROL_HANGUP)) return -1;
01265 if (f->frametype == AST_FRAME_TEXT)
01266 {
01267 c = *((char *)f->data);
01268 ast_frfree(f);
01269 return(c);
01270 }
01271 ast_frfree(f);
01272 }
01273 }
01274
01275 int ast_sendtext(struct ast_channel *chan, char *text)
01276 {
01277 int res = 0;
01278
01279 if (chan->zombie || ast_check_hangup(chan))
01280 return -1;
01281 CHECK_BLOCKING(chan);
01282 if (chan->pvt->send_text)
01283 res = chan->pvt->send_text(chan, text);
01284 chan->blocking = 0;
01285 return res;
01286 }
01287
01288 static int do_senddigit(struct ast_channel *chan, char digit)
01289 {
01290 int res = -1;
01291
01292 if (chan->pvt->send_digit)
01293 res = chan->pvt->send_digit(chan, digit);
01294 if (!chan->pvt->send_digit || res) {
01295
01296
01297
01298
01299 static const char* dtmf_tones[] = {
01300 "!941+1336/50,!0/50",
01301 "!697+1209/50,!0/50",
01302 "!697+1336/50,!0/50",
01303 "!697+1477/50,!0/50",
01304 "!770+1209/50,!0/50",
01305 "!770+1336/50,!0/50",
01306 "!770+1477/50,!0/50",
01307 "!852+1209/50,!0/50",
01308 "!852+1336/50,!0/50",
01309 "!852+1477/50,!0/50",
01310 "!697+1633/50,!0/50",
01311 "!770+1633/50,!0/50",
01312 "!852+1633/50,!0/50",
01313 "!941+1633/50,!0/50",
01314 "!941+1209/50,!0/50",
01315 "!941+1477/50,!0/50" };
01316 if (digit >= '0' && digit <='9')
01317 ast_playtones_start(chan,0,dtmf_tones[digit-'0'], 0);
01318 else if (digit >= 'A' && digit <= 'D')
01319 ast_playtones_start(chan,0,dtmf_tones[digit-'A'+10], 0);
01320 else if (digit == '*')
01321 ast_playtones_start(chan,0,dtmf_tones[14], 0);
01322 else if (digit == '#')
01323 ast_playtones_start(chan,0,dtmf_tones[15], 0);
01324 else {
01325
01326 ast_log(LOG_WARNING, "Unable to handle DTMF tone '%c' for '%s'\n", digit, chan->name);
01327 return -1;
01328 }
01329 }
01330 return 0;
01331 }
01332
01333 int ast_prod(struct ast_channel *chan)
01334 {
01335 struct ast_frame a = { AST_FRAME_VOICE };
01336 char nothing[128];
01337
01338 if (chan->_state != AST_STATE_UP) {
01339 ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name);
01340 a.subclass = chan->pvt->rawwriteformat;
01341 a.data = nothing + AST_FRIENDLY_OFFSET;
01342 if (ast_write(chan, &a))
01343 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name);
01344 }
01345 return 0;
01346 }
01347
01348 int ast_write_video(struct ast_channel *chan, struct ast_frame *fr)
01349 {
01350 int res;
01351 if (!chan->pvt->write_video)
01352 return 0;
01353 res = ast_write(chan, fr);
01354 if (!res)
01355 res = 1;
01356 return res;
01357 }
01358
01359 int ast_write(struct ast_channel *chan, struct ast_frame *fr)
01360 {
01361 int res = -1;
01362 struct ast_frame *f = NULL;
01363
01364 ast_mutex_lock(&chan->lock);
01365 if (chan->zombie || ast_check_hangup(chan)) {
01366 ast_mutex_unlock(&chan->lock);
01367 return -1;
01368 }
01369
01370 if (chan->masq) {
01371 if (ast_do_masquerade(chan)) {
01372 ast_log(LOG_WARNING, "Failed to perform masquerade\n");
01373 ast_mutex_unlock(&chan->lock);
01374 return -1;
01375 }
01376 }
01377 if (chan->masqr) {
01378 ast_mutex_unlock(&chan->lock);
01379 return 0;
01380 }
01381 if (chan->generatordata) {
01382 if (chan->writeinterrupt)
01383 ast_deactivate_generator(chan);
01384 else {
01385 ast_mutex_unlock(&chan->lock);
01386 return 0;
01387 }
01388 }
01389 if (chan->fout & 0x80000000)
01390 ast_frame_dump(chan->name, fr, ">>");
01391 CHECK_BLOCKING(chan);
01392 switch(fr->frametype) {
01393 case AST_FRAME_CONTROL:
01394
01395 ast_log(LOG_WARNING, "Don't know how to handle control frames yet\n");
01396 break;
01397 case AST_FRAME_DTMF:
01398 chan->blocking = 0;
01399 ast_mutex_unlock(&chan->lock);
01400 res = do_senddigit(chan,fr->subclass);
01401 ast_mutex_lock(&chan->lock);
01402 CHECK_BLOCKING(chan);
01403 break;
01404 case AST_FRAME_TEXT:
01405 if (chan->pvt->send_text)
01406 res = chan->pvt->send_text(chan, (char *) fr->data);
01407 break;
01408 case AST_FRAME_VIDEO:
01409
01410 if (chan->pvt->write_video)
01411 res = chan->pvt->write_video(chan, fr);
01412 else
01413 res = 0;
01414 break;
01415 default:
01416 if (chan->pvt->write) {
01417 if (chan->pvt->writetrans) {
01418 f = ast_translate(chan->pvt->writetrans, fr, 0);
01419 } else
01420 f = fr;
01421 if (f) {
01422 res = chan->pvt->write(chan, f);
01423 if( chan->monitor &&
01424 chan->monitor->write_stream &&
01425 f && ( f->frametype == AST_FRAME_VOICE ) ) {
01426 #ifndef MONITOR_CONSTANT_DELAY
01427 int jump = chan->insmpl - chan->outsmpl - 2 * f->samples;
01428 if (jump >= 0) {
01429 if (ast_seekstream(chan->monitor->write_stream, jump + f->samples, SEEK_FORCECUR) == -1)
01430 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
01431 chan->outsmpl += jump + 2 * f->samples;
01432 } else
01433 chan->outsmpl += f->samples;
01434 #else
01435 int jump = chan->insmpl - chan->outsmpl;
01436 if (jump - MONITOR_DELAY >= 0) {
01437 if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1)
01438 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
01439 chan->outsmpl += jump;
01440 } else
01441 chan->outsmpl += f->samples;
01442 #endif
01443 if (ast_writestream(chan->monitor->write_stream, f) < 0)
01444 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
01445 }
01446 } else
01447 res = 0;
01448 }
01449 }
01450 if (f && (f != fr))
01451 ast_frfree(f);
01452 chan->blocking = 0;
01453
01454 if (res < 0)
01455 chan->_softhangup |= AST_SOFTHANGUP_DEV;
01456 else {
01457 if ((chan->fout & 0x7fffffff) == 0x7fffffff)
01458 chan->fout &= 0x80000000;
01459 else
01460 chan->fout++;
01461 chan->fout++;
01462 }
01463 ast_mutex_unlock(&chan->lock);
01464 return res;
01465 }
01466
01467 int ast_set_write_format(struct ast_channel *chan, int fmts)
01468 {
01469 int fmt;
01470 int native;
01471 int res;
01472
01473 native = chan->nativeformats;
01474 fmt = fmts;
01475
01476 res = ast_translator_best_choice(&native, &fmt);
01477 if (res < 0) {
01478 ast_log(LOG_NOTICE, "Unable to find a path from %s to %s\n",
01479 ast_getformatname(fmts), ast_getformatname(chan->nativeformats));
01480 return -1;
01481 }
01482
01483
01484 chan->pvt->rawwriteformat = native;
01485
01486 chan->writeformat = fmt;
01487
01488 if (chan->pvt->writetrans)
01489 ast_translator_free_path(chan->pvt->writetrans);
01490
01491 chan->pvt->writetrans = ast_translator_build_path(chan->pvt->rawwriteformat, chan->writeformat);
01492 if (option_debug)
01493 ast_log(LOG_DEBUG, "Set channel %s to write format %s\n", chan->name, ast_getformatname(chan->writeformat));
01494 return 0;
01495 }
01496
01497 int ast_set_read_format(struct ast_channel *chan, int fmts)
01498 {
01499 int fmt;
01500 int native;
01501 int res;
01502
01503 native = chan->nativeformats;
01504 fmt = fmts;
01505
01506 res = ast_translator_best_choice(&fmt, &native);
01507 if (res < 0) {
01508 ast_log(LOG_NOTICE, "Unable to find a path from %s to %s\n",
01509 ast_getformatname(chan->nativeformats), ast_getformatname(fmts));
01510 return -1;
01511 }
01512
01513
01514 chan->pvt->rawreadformat = native;
01515
01516 chan->readformat = fmt;
01517
01518 if (chan->pvt->readtrans)
01519 ast_translator_free_path(chan->pvt->readtrans);
01520
01521 chan->pvt->readtrans = ast_translator_build_path(chan->readformat, chan->pvt->rawreadformat);
01522 if (option_debug)
01523 ast_log(LOG_DEBUG, "Set channel %s to read format %s\n",
01524 chan->name, ast_getformatname(chan->readformat));
01525 return 0;
01526 }
01527
01528 struct ast_channel *__ast_request_and_dial(char *type, int format, void *data, int timeout, int *outstate, char *callerid, struct outgoing_helper *oh)
01529 {
01530 int state = 0;
01531 struct ast_channel *chan;
01532 struct ast_frame *f;
01533 int res = 0;
01534 chan = ast_request(type, format, data);
01535 if (chan) {
01536 if (oh) {
01537 char *tmp, *var;
01538
01539 tmp = oh->variable;
01540
01541 while( (var = strtok_r(NULL, "|", &tmp)) ) {
01542 pbx_builtin_setvar( chan, var );
01543 }
01544 if (oh->callerid && *oh->callerid)
01545 ast_set_callerid(chan, oh->callerid, 1);
01546 if (oh->account && *oh->account)
01547 ast_cdr_setaccount(chan, oh->account);
01548 }
01549 if (callerid && strlen(callerid))
01550 ast_set_callerid(chan, callerid, 1);
01551
01552 if (!ast_call(chan, data, 0)) {
01553 while(timeout && (chan->_state != AST_STATE_UP)) {
01554 res = ast_waitfor(chan, timeout);
01555 if (res < 0) {
01556
01557 break;
01558 }
01559
01560 if (!res)
01561 break;
01562 if (timeout > -1)
01563 timeout = res;
01564 f = ast_read(chan);
01565 if (!f) {
01566 state = AST_CONTROL_HANGUP;
01567 res = 0;
01568 break;
01569 }
01570 if (f->frametype == AST_FRAME_CONTROL) {
01571 if (f->subclass == AST_CONTROL_RINGING)
01572 state = AST_CONTROL_RINGING;
01573 else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) {
01574 state = f->subclass;
01575 ast_frfree(f);
01576 break;
01577 } else if (f->subclass == AST_CONTROL_ANSWER) {
01578 state = f->subclass;
01579 ast_frfree(f);
01580 break;
01581 } else if (f->subclass == -1) {
01582
01583 } else {
01584 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
01585 }
01586 }
01587 ast_frfree(f);
01588 }
01589 } else
01590 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
01591 } else
01592 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
01593 if (chan) {
01594
01595 if (oh) {
01596 if (oh->context && *oh->context)
01597 strncpy(chan->context, oh->context, sizeof(chan->context) - 1);
01598 if (oh->exten && *oh->exten)
01599 strncpy(chan->exten, oh->exten, sizeof(chan->exten) - 1);
01600 chan->priority = oh->priority;
01601 }
01602 if (chan->_state == AST_STATE_UP)
01603 state = AST_CONTROL_ANSWER;
01604 }
01605 if (outstate)
01606 *outstate = state;
01607 if (chan && res <= 0) {
01608 if (!chan->cdr) {
01609 chan->cdr = ast_cdr_alloc();
01610 if (chan->cdr)
01611 ast_cdr_init(chan->cdr, chan);
01612 }
01613 if (chan->cdr) {
01614 char tmp[256];
01615 sprintf(tmp, "%s/%s",type,(char *)data);
01616 ast_cdr_setapp(chan->cdr,"Dial",tmp);
01617 ast_cdr_update(chan);
01618 ast_cdr_start(chan->cdr);
01619 ast_cdr_end(chan->cdr);
01620
01621 if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
01622 ast_cdr_failed(chan->cdr);
01623 } else
01624 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
01625 ast_hangup(chan);
01626 chan = NULL;
01627 }
01628 return chan;
01629 }
01630
01631 struct ast_channel *ast_request_and_dial(char *type, int format, void *data, int timeout, int *outstate, char *callerid)
01632 {
01633 return __ast_request_and_dial(type, format, data, timeout, outstate, callerid, NULL);
01634 }
01635
01636 struct ast_channel *ast_request(char *type, int format, void *data)
01637 {
01638 struct chanlist *chan;
01639 struct ast_channel *c = NULL;
01640 int capabilities;
01641 int fmt;
01642 int res;
01643 if (ast_mutex_lock(&chlock)) {
01644 ast_log(LOG_WARNING, "Unable to lock channel list\n");
01645 return NULL;
01646 }
01647 chan = backends;
01648 while(chan) {
01649 if (!strcasecmp(type, chan->type)) {
01650 capabilities = chan->capabilities;
01651 fmt = format;
01652 res = ast_translator_best_choice(&fmt, &capabilities);
01653 if (res < 0) {
01654 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->capabilities, format);
01655 ast_mutex_unlock(&chlock);
01656 return NULL;
01657 }
01658 ast_mutex_unlock(&chlock);
01659 if (chan->requester)
01660 c = chan->requester(type, capabilities, data);
01661 if (c) {
01662 if (c->_state == AST_STATE_DOWN) {
01663 manager_event(EVENT_FLAG_CALL, "Newchannel",
01664 "Channel: %s\r\n"
01665 "State: %s\r\n"
01666 "Callerid: %s\r\n"
01667 "Uniqueid: %s\r\n",
01668 c->name, ast_state2str(c->_state), c->callerid ? c->callerid : "<unknown>", c->uniqueid);
01669 }
01670 }
01671 return c;
01672 }
01673 chan = chan->next;
01674 }
01675 if (!chan)
01676 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
01677 ast_mutex_unlock(&chlock);
01678 return c;
01679 }
01680
01681 int ast_parse_device_state(char *device)
01682 {
01683 char name[AST_CHANNEL_NAME] = "";
01684 char *cut;
01685 struct ast_channel *chan;
01686
01687 chan = ast_channel_walk(NULL);
01688 while (chan) {
01689 strncpy(name, chan->name, sizeof(name)-1);
01690 cut = strchr(name,'-');
01691 if (cut)
01692 *cut = 0;
01693 if (!strcmp(name, device))
01694 return AST_DEVICE_INUSE;
01695 chan = ast_channel_walk(chan);
01696 }
01697 return AST_DEVICE_UNKNOWN;
01698 }
01699
01700 int ast_device_state(char *device)
01701 {
01702 char tech[AST_MAX_EXTENSION] = "";
01703 char *number;
01704 struct chanlist *chanls;
01705 int res = 0;
01706
01707 strncpy(tech, device, sizeof(tech)-1);
01708 number = strchr(tech, '/');
01709 if (!number) {
01710 return AST_DEVICE_INVALID;
01711 }
01712 *number = 0;
01713 number++;
01714
01715 if (ast_mutex_lock(&chlock)) {
01716 ast_log(LOG_WARNING, "Unable to lock channel list\n");
01717 return -1;
01718 }
01719 chanls = backends;
01720 while(chanls) {
01721 if (!strcasecmp(tech, chanls->type)) {
01722 ast_mutex_unlock(&chlock);
01723 if (!chanls->devicestate)
01724 return ast_parse_device_state(device);
01725 else {
01726 res = chanls->devicestate(number);
01727 if (res == AST_DEVICE_UNKNOWN)
01728 return ast_parse_device_state(device);
01729 else
01730 return res;
01731 }
01732 }
01733 chanls = chanls->next;
01734 }
01735 ast_mutex_unlock(&chlock);
01736 return AST_DEVICE_INVALID;
01737 }
01738
01739 int ast_call(struct ast_channel *chan, char *addr, int timeout)
01740 {
01741
01742
01743
01744 int res = -1;
01745
01746 ast_mutex_lock(&chan->lock);
01747 if (!chan->zombie && !ast_check_hangup(chan))
01748 if (chan->pvt->call)
01749 res = chan->pvt->call(chan, addr, timeout);
01750 ast_mutex_unlock(&chan->lock);
01751 return res;
01752 }
01753
01754 int ast_transfer(struct ast_channel *chan, char *dest)
01755 {
01756
01757
01758
01759 int res = -1;
01760
01761 ast_mutex_lock(&chan->lock);
01762 if (!chan->zombie && !ast_check_hangup(chan)) {
01763 if (chan->pvt->transfer) {
01764 res = chan->pvt->transfer(chan, dest);
01765 if (!res)
01766 res = 1;
01767 } else
01768 res = 0;
01769 }
01770 ast_mutex_unlock(&chan->lock);
01771 return res;
01772 }
01773
01774 int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders)
01775 {
01776 int pos=0;
01777 int to = ftimeout;
01778 char d;
01779
01780
01781 if (c->zombie || ast_check_hangup(c))
01782 return -1;
01783 if (!len)
01784 return -1;
01785 do {
01786 if (c->stream) {
01787 d = ast_waitstream(c, AST_DIGIT_ANY);
01788 ast_stopstream(c);
01789 usleep(1000);
01790 if (!d)
01791 d = ast_waitfordigit(c, to);
01792 } else {
01793 d = ast_waitfordigit(c, to);
01794 }
01795 if (d < 0)
01796 return -1;
01797 if (d == 0) {
01798 s[pos]='\0';
01799 return 1;
01800 }
01801 if (!strchr(enders, d))
01802 s[pos++] = d;
01803 if (strchr(enders, d) || (pos >= len)) {
01804 s[pos]='\0';
01805 return 0;
01806 }
01807 to = timeout;
01808 } while(1);
01809
01810 return 0;
01811 }
01812
01813 int ast_readstring_full(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders, int audiofd, int ctrlfd)
01814 {
01815 int pos=0;
01816 int to = ftimeout;
01817 char d;
01818
01819 if (c->zombie || ast_check_hangup(c))
01820 return -1;
01821 if (!len)
01822 return -1;
01823 do {
01824 if (c->stream) {
01825 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
01826 ast_stopstream(c);
01827 usleep(1000);
01828 if (!d)
01829 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
01830 } else {
01831 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
01832 }
01833 if (d < 0)
01834 return -1;
01835 if (d == 0) {
01836 s[pos]='\0';
01837 return 1;
01838 }
01839 if (d == 1) {
01840 s[pos]='\0';
01841 return 2;
01842 }
01843 if (!strchr(enders, d))
01844 s[pos++] = d;
01845 if (strchr(enders, d) || (pos >= len)) {
01846 s[pos]='\0';
01847 return 0;
01848 }
01849 to = timeout;
01850 } while(1);
01851
01852 return 0;
01853 }
01854
01855 int ast_channel_supports_html(struct ast_channel *chan)
01856 {
01857 if (chan->pvt->send_html)
01858 return 1;
01859 return 0;
01860 }
01861
01862 int ast_channel_sendhtml(struct ast_channel *chan, int subclass, char *data, int datalen)
01863 {
01864 if (chan->pvt->send_html)
01865 return chan->pvt->send_html(chan, subclass, data, datalen);
01866 return -1;
01867 }
01868
01869 int ast_channel_sendurl(struct ast_channel *chan, char *url)
01870 {
01871 if (chan->pvt->send_html)
01872 return chan->pvt->send_html(chan, AST_HTML_URL, url, strlen(url) + 1);
01873 return -1;
01874 }
01875
01876 int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
01877 {
01878 int peerf;
01879 int chanf;
01880 int res;
01881 peerf = peer->nativeformats;
01882 chanf = chan->nativeformats;
01883 res = ast_translator_best_choice(&peerf, &chanf);
01884 if (res < 0) {
01885 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, chan->nativeformats, peer->name, peer->nativeformats);
01886 return -1;
01887 }
01888
01889 res = ast_set_read_format(chan, peerf);
01890 if (res < 0) {
01891 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, chanf);
01892 return -1;
01893 }
01894
01895 res = ast_set_write_format(peer, peerf);
01896 if (res < 0) {
01897 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, peerf);
01898 return -1;
01899 }
01900
01901 peerf = peer->nativeformats;
01902 chanf = chan->nativeformats;
01903 res = ast_translator_best_choice(&chanf, &peerf);
01904 if (res < 0) {
01905 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, peer->nativeformats, chan->name, chan->nativeformats);
01906 return -1;
01907 }
01908
01909 res = ast_set_write_format(chan, chanf);
01910 if (res < 0) {
01911 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, chanf);
01912 return -1;
01913 }
01914
01915 res = ast_set_read_format(peer, chanf);
01916 if (res < 0) {
01917 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, peerf);
01918 return -1;
01919 }
01920 return 0;
01921 }
01922
01923 int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone)
01924 {
01925 struct ast_frame null = { AST_FRAME_NULL, };
01926 ast_log(LOG_DEBUG, "Planning to masquerade %s into the structure of %s\n",
01927 clone->name, original->name);
01928 if (original->masq) {
01929 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
01930 original->masq->name, original->name);
01931 return -1;
01932 }
01933 if (clone->masqr) {
01934 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
01935 clone->name, clone->masqr->name);
01936 return -1;
01937 }
01938 original->masq = clone;
01939 clone->masqr = original;
01940
01941
01942 ast_queue_frame(original, &null, 0);
01943 ast_queue_frame(clone, &null, 0);
01944 ast_log(LOG_DEBUG, "Done planning to masquerade %s into the structure of %s\n", original->name, clone->name);
01945 return 0;
01946 }
01947
01948 void ast_change_name(struct ast_channel *chan, char *newname)
01949 {
01950 char tmp[256];
01951 strncpy(tmp, chan->name, 256);
01952 strncpy(chan->name, newname, sizeof(chan->name) - 1);
01953 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", tmp, chan->name, chan->uniqueid);
01954 }
01955
01956 static int ast_do_masquerade(struct ast_channel *original)
01957 {
01958 int x,i;
01959 int res=0;
01960 char *tmp;
01961 struct ast_var_t *varptr;
01962 struct ast_frame *cur, *prev;
01963 struct ast_channel_pvt *p;
01964 struct ast_channel *clone = original->masq;
01965 int rformat = original->readformat;
01966 int wformat = original->writeformat;
01967 char newn[100];
01968 char orig[100];
01969 char masqn[100];
01970 char zombn[100];
01971
01972 #if 1
01973 ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",
01974 clone->name, clone->_state, original->name, original->_state);
01975 #endif
01976
01977
01978
01979
01980
01981
01982 ast_mutex_lock(&clone->lock);
01983
01984 ast_log(LOG_DEBUG, "Got clone lock on '%s' at %p\n", clone->name, &clone->lock);
01985
01986
01987
01988 free_translation(clone);
01989 free_translation(original);
01990
01991
01992
01993 original->masq = NULL;
01994 clone->masqr = NULL;
01995
01996
01997 strncpy(orig, original->name, sizeof(orig) - 1);
01998
01999 strncpy(newn, clone->name, sizeof(newn) - 1);
02000
02001 snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn);
02002
02003
02004 strncpy(original->name, newn, sizeof(original->name)-1);
02005
02006
02007 strncpy(clone->name, masqn, sizeof(clone->name) - 1);
02008
02009
02010 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\n", newn, masqn);
02011 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\n", orig, newn);
02012
02013
02014 p = original->pvt;
02015 original->pvt = clone->pvt;
02016 clone->pvt = p;
02017
02018
02019
02020 prev = NULL;
02021 cur = clone->pvt->readq;
02022 x = 0;
02023 while(cur) {
02024 x++;
02025 prev = cur;
02026 cur = cur->next;
02027 }
02028
02029
02030 if (prev) {
02031 prev->next = original->pvt->readq;
02032 original->pvt->readq = clone->pvt->readq;
02033 clone->pvt->readq = NULL;
02034 if (original->pvt->alertpipe[1] > -1) {
02035 for (i=0;i<x;i++)
02036 write(original->pvt->alertpipe[1], &x, sizeof(x));
02037 }
02038 }
02039 clone->_softhangup = AST_SOFTHANGUP_DEV;
02040
02041
02042 if (clone->pvt->fixup){
02043 res = clone->pvt->fixup(original, clone);
02044 if (res)
02045 ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name);
02046 }
02047
02048
02049 if (clone->pvt->hangup)
02050 res = clone->pvt->hangup(clone);
02051 if (res) {
02052 ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n");
02053 ast_mutex_unlock(&clone->lock);
02054 return -1;
02055 }
02056
02057 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig);
02058
02059 strncpy(clone->name, zombn, sizeof(clone->name) - 1);
02060 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\n", masqn, zombn);
02061
02062
02063
02064 original->type = clone->type;
02065
02066 for (x=0;x<AST_MAX_FDS;x++) {
02067 original->fds[x] = clone->fds[x];
02068 }
02069
02070
02071 varptr = original->varshead.first;
02072 if (varptr) {
02073 while(varptr->entries.next) {
02074 varptr = varptr->entries.next;
02075 }
02076 varptr->entries.next = clone->varshead.first;
02077 } else {
02078 original->varshead.first = clone->varshead.first;
02079 }
02080 clone->varshead.first = NULL;
02081
02082 original->adsicpe = clone->adsicpe;
02083
02084
02085
02086
02087
02088 original->exception = clone->exception;
02089 original->fdno = clone->fdno;
02090
02091
02092
02093
02094
02095
02096
02097 tmp = original->dnid;
02098 original->dnid = clone->dnid;
02099 clone->dnid = tmp;
02100
02101 tmp = original->callerid;
02102 original->callerid = clone->callerid;
02103 clone->callerid = tmp;
02104
02105
02106 original->fds[AST_MAX_FDS - 2] = original->timingfd;
02107
02108
02109 original->nativeformats = clone->nativeformats;
02110
02111
02112
02113
02114 original->_state = clone->_state;
02115
02116
02117
02118
02119
02120 ast_set_write_format(original, wformat);
02121
02122
02123 ast_set_read_format(original, rformat);
02124
02125 ast_log(LOG_DEBUG, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat);
02126
02127
02128
02129 if (original->pvt->fixup) {
02130 res = original->pvt->fixup(clone, original);
02131 if (res) {
02132 ast_log(LOG_WARNING, "Driver for '%s' could not fixup channel %s\n",
02133 original->type, original->name);
02134 return -1;
02135 }
02136 } else
02137 ast_log(LOG_WARNING, "Driver '%s' does not have a fixup routine (for %s)! Bad things may happen.\n",
02138 original->type, original->name);
02139
02140
02141
02142
02143 if (clone->zombie) {
02144 ast_log(LOG_DEBUG, "Destroying clone '%s'\n", clone->name);
02145 ast_mutex_unlock(&clone->lock);
02146 ast_channel_free(clone);
02147 manager_event(EVENT_FLAG_CALL, "Hangup", "Channel: %s\r\n", zombn);
02148 } else {
02149 ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name);
02150 clone->zombie=1;
02151 ast_mutex_unlock(&clone->lock);
02152 }
02153
02154
02155 if (original->blocking)
02156 pthread_kill(original->blocker, SIGURG);
02157 ast_log(LOG_DEBUG, "Done Masquerading %s (%d)\n",
02158 original->name, original->_state);
02159 return 0;
02160 }
02161
02162 void ast_set_callerid(struct ast_channel *chan, char *callerid, int anitoo)
02163 {
02164 if (chan->callerid)
02165 free(chan->callerid);
02166 if (anitoo && chan->ani)
02167 free(chan->ani);
02168 if (callerid) {
02169 chan->callerid = strdup(callerid);
02170 if (anitoo)
02171 chan->ani = strdup(callerid);
02172 } else {
02173 chan->callerid = NULL;
02174 if (anitoo)
02175 chan->ani = NULL;
02176 }
02177 if (chan->cdr)
02178 ast_cdr_setcid(chan->cdr, chan);
02179 manager_event(EVENT_FLAG_CALL, "Newcallerid",
02180 "Channel: %s\r\n"
02181 "Callerid: %s\r\n"
02182 "Uniqueid: %s\r\n",
02183 chan->name, chan->callerid ?
02184 chan->callerid : "<Unknown>",
02185 chan->uniqueid);
02186 }
02187
02188 int ast_setstate(struct ast_channel *chan, int state)
02189 {
02190 if (chan->_state != state) {
02191 int oldstate = chan->_state;
02192 chan->_state = state;
02193 if (oldstate == AST_STATE_DOWN) {
02194 ast_device_state_changed(chan->name);
02195 manager_event(EVENT_FLAG_CALL, "Newchannel",
02196 "Channel: %s\r\n"
02197 "State: %s\r\n"
02198 "Callerid: %s\r\n"
02199 "Uniqueid: %s\r\n",
02200 chan->name, ast_state2str(chan->_state), chan->callerid ? chan->callerid : "<unknown>", chan->uniqueid);
02201 } else {
02202 manager_event(EVENT_FLAG_CALL, "Newstate",
02203 "Channel: %s\r\n"
02204 "State: %s\r\n"
02205 "Callerid: %s\r\n"
02206 "Uniqueid: %s\r\n",
02207 chan->name, ast_state2str(chan->_state), chan->callerid ? chan->callerid : "<unknown>", chan->uniqueid);
02208 }
02209 }
02210 return 0;
02211 }
02212
02213 int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc)
02214 {
02215
02216
02217 struct ast_channel *cs[3];
02218 int to = -1;
02219 struct ast_frame *f;
02220 struct ast_channel *who = NULL;
02221 int res;
02222 int nativefailed=0;
02223
02224
02225 if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1))
02226 return -1;
02227 if (c0->bridge) {
02228 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
02229 c0->name, c0->bridge->name);
02230 return -1;
02231 }
02232 if (c1->bridge) {
02233 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
02234 c1->name, c1->bridge->name);
02235 return -1;
02236 }
02237
02238
02239 c0->bridge = c1;
02240 c1->bridge = c0;
02241 cs[0] = c0;
02242 cs[1] = c1;
02243
02244 manager_event(EVENT_FLAG_CALL, "Link",
02245 "Channel1: %s\r\n"
02246 "Channel2: %s\r\n",
02247 c0->name, c1->name);
02248
02249 for (;;) {
02250
02251 if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1)) {
02252 *fo = NULL;
02253 if (who) *rc = who;
02254 res = 0;
02255 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");
02256 break;
02257 }
02258 if (c0->pvt->bridge &&
02259 (c0->pvt->bridge == c1->pvt->bridge) && !nativefailed && !c0->monitor && !c1->monitor) {
02260
02261 if (option_verbose > 2)
02262 ast_verbose(VERBOSE_PREFIX_3 "Attempting native bridge of %s and %s\n", c0->name, c1->name);
02263 if (!(res = c0->pvt->bridge(c0, c1, flags, fo, rc))) {
02264 c0->bridge = NULL;
02265 c1->bridge = NULL;
02266 manager_event(EVENT_FLAG_CALL, "Unlink",
02267 "Channel1: %s\r\n"
02268 "Channel2: %s\r\n",
02269 c0->name, c1->name);
02270 ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n",c0->name ,c1->name);
02271 return 0;
02272 }
02273
02274
02275 if ((res != -2) && (res != -3))
02276 ast_log(LOG_WARNING, "Private bridge between %s and %s failed\n", c0->name, c1->name);
02277 if (res != -3) nativefailed++;
02278 }
02279
02280
02281 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat)) &&
02282 !(c0->generator || c1->generator)) {
02283 if (ast_channel_make_compatible(c0, c1)) {
02284 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
02285 manager_event(EVENT_FLAG_CALL, "Unlink",
02286 "Channel1: %s\r\n"
02287 "Channel2: %s\r\n",
02288 c0->name, c1->name);
02289 return -1;
02290 }
02291 }
02292 who = ast_waitfor_n(cs, 2, &to);
02293 if (!who) {
02294 ast_log(LOG_DEBUG, "Nobody there, continuing...\n");
02295 continue;
02296 }
02297 f = ast_read(who);
02298 if (!f) {
02299 *fo = NULL;
02300 *rc = who;
02301 res = 0;
02302 ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name);
02303 break;
02304 }
02305
02306 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
02307 *fo = f;
02308 *rc = who;
02309 res = 0;
02310 ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name);
02311 break;
02312 }
02313 if ((f->frametype == AST_FRAME_VOICE) ||
02314 (f->frametype == AST_FRAME_TEXT) ||
02315 (f->frametype == AST_FRAME_VIDEO) ||
02316 (f->frametype == AST_FRAME_IMAGE) ||
02317 (f->frametype == AST_FRAME_DTMF)) {
02318 if ((f->frametype == AST_FRAME_DTMF) &&
02319 (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
02320 if ((who == c0)) {
02321 if ((flags & AST_BRIDGE_DTMF_CHANNEL_0)) {
02322 *rc = c0;
02323 *fo = f;
02324
02325 res = 0;
02326 ast_log(LOG_DEBUG, "Got AST_BRIDGE_DTMF_CHANNEL_0 on c0 (%s)\n",c0->name);
02327 break;
02328 } else
02329 goto tackygoto;
02330 } else
02331 if ((who == c1)) {
02332 if (flags & AST_BRIDGE_DTMF_CHANNEL_1) {
02333 *rc = c1;
02334 *fo = f;
02335 res = 0;
02336 ast_log(LOG_DEBUG, "Got AST_BRIDGE_DTMF_CHANNEL_1 on c1 (%s)\n",c1->name);
02337 break;
02338 } else
02339 goto tackygoto;
02340 }
02341 } else {
02342 #if 0
02343 ast_log(LOG_DEBUG, "Read from %s\n", who->name);
02344 if (who == last)
02345 ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name);
02346 last = who;
02347 #endif
02348 tackygoto:
02349
02350
02351 if (who == c0)
02352 ast_write(c1, f);
02353 else
02354 ast_write(c0, f);
02355 }
02356 ast_frfree(f);
02357 } else
02358 ast_frfree(f);
02359
02360 cs[2] = cs[0];
02361 cs[0] = cs[1];
02362 cs[1] = cs[2];
02363 }
02364 c0->bridge = NULL;
02365 c1->bridge = NULL;
02366 manager_event(EVENT_FLAG_CALL, "Unlink",
02367 "Channel1: %s\r\n"
02368 "Channel2: %s\r\n",
02369 c0->name, c1->name);
02370 ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n",c0->name,c1->name);
02371 return res;
02372 }
02373
02374 int ast_channel_setoption(struct ast_channel *chan, int option, void *data, int datalen, int block)
02375 {
02376 int res;
02377 if (chan->pvt->setoption) {
02378 res = chan->pvt->setoption(chan, option, data, datalen);
02379 if (res < 0)
02380 return res;
02381 } else {
02382 errno = ENOSYS;
02383 return -1;
02384 }
02385 if (block) {
02386
02387
02388 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
02389 return -1;
02390 }
02391 return 0;
02392 }
02393
02394 struct tonepair_def {
02395 int freq1;
02396 int freq2;
02397 int duration;
02398 int vol;
02399 };
02400
02401 struct tonepair_state {
02402 float freq1;
02403 float freq2;
02404 float vol;
02405 int duration;
02406 int pos;
02407 int origwfmt;
02408 struct ast_frame f;
02409 unsigned char offset[AST_FRIENDLY_OFFSET];
02410 short data[4000];
02411 };
02412
02413 static void tonepair_release(struct ast_channel *chan, void *params)
02414 {
02415 struct tonepair_state *ts = params;
02416 if (chan) {
02417 ast_set_write_format(chan, ts->origwfmt);
02418 }
02419 free(ts);
02420 }
02421
02422 static void * tonepair_alloc(struct ast_channel *chan, void *params)
02423 {
02424 struct tonepair_state *ts;
02425 struct tonepair_def *td = params;
02426 ts = malloc(sizeof(struct tonepair_state));
02427 if (!ts)
02428 return NULL;
02429 memset(ts, 0, sizeof(struct tonepair_state));
02430 ts->origwfmt = chan->writeformat;
02431 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
02432 ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
02433 tonepair_release(NULL, ts);
02434 ts = NULL;
02435 } else {
02436 ts->freq1 = td->freq1;
02437 ts->freq2 = td->freq2;
02438 ts->duration = td->duration;
02439 ts->vol = td->vol;
02440 }
02441
02442 chan->writeinterrupt = 1;
02443 return ts;
02444 }
02445
02446 static int tonepair_generator(struct ast_channel *chan, void *data, int len, int samples)
02447 {
02448 struct tonepair_state *ts = data;
02449 int x;
02450
02451
02452
02453
02454 len = samples * 2;
02455
02456 if (len > sizeof(ts->data) / 2 - 1) {
02457 ast_log(LOG_WARNING, "Can't generate that much data!\n");
02458 return -1;
02459 }
02460 memset(&ts->f, 0, sizeof(ts->f));
02461 for (x=0;x<len/2;x++) {
02462 ts->data[x] = ts->vol * (
02463 sin((ts->freq1 * 2.0 * M_PI / 8000.0) * (ts->pos + x)) +
02464 sin((ts->freq2 * 2.0 * M_PI / 8000.0) * (ts->pos + x))
02465 );
02466 }
02467 ts->f.frametype = AST_FRAME_VOICE;
02468 ts->f.subclass = AST_FORMAT_SLINEAR;
02469 ts->f.datalen = len;
02470 ts->f.samples = samples;
02471 ts->f.offset = AST_FRIENDLY_OFFSET;
02472 ts->f.data = ts->data;
02473 ast_write(chan, &ts->f);
02474 ts->pos += x;
02475 if (ts->duration > 0) {
02476 if (ts->pos >= ts->duration * 8)
02477 return -1;
02478 }
02479 return 0;
02480 }
02481
02482 static struct ast_generator tonepair = {
02483 alloc: tonepair_alloc,
02484 release: tonepair_release,
02485 generate: tonepair_generator,
02486 };
02487
02488 int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
02489 {
02490 struct tonepair_def d = { 0, };
02491 d.freq1 = freq1;
02492 d.freq2 = freq2;
02493 d.duration = duration;
02494 if (vol < 1)
02495 d.vol = 8192;
02496 else
02497 d.vol = vol;
02498 if (ast_activate_generator(chan, &tonepair, &d))
02499 return -1;
02500 return 0;
02501 }
02502
02503 void ast_tonepair_stop(struct ast_channel *chan)
02504 {
02505 ast_deactivate_generator(chan);
02506 }
02507
02508 int ast_tonepair(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
02509 {
02510 struct ast_frame *f;
02511 int res;
02512 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
02513 return res;
02514
02515
02516 while(chan->generatordata && (ast_waitfor(chan, 100) >= 0)) {
02517 f = ast_read(chan);
02518 if (f)
02519 ast_frfree(f);
02520 else
02521 return -1;
02522 }
02523 return 0;
02524 }
02525
02526 unsigned int ast_get_group(char *s)
02527 {
02528 char *copy;
02529 char *piece;
02530 char *c=NULL;
02531 int start=0, finish=0,x;
02532 unsigned int group = 0;
02533 copy = ast_strdupa(s);
02534 if (!copy) {
02535 ast_log(LOG_ERROR, "Out of memory\n");
02536 return 0;
02537 }
02538 c = copy;
02539
02540 while((piece = strsep(&c, ","))) {
02541 if (sscanf(piece, "%d-%d", &start, &finish) == 2) {
02542
02543 } else if (sscanf(piece, "%d", &start)) {
02544
02545 finish = start;
02546 } else {
02547 ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'. Using '0'\n", s,piece);
02548 return 0;
02549 }
02550 for (x=start;x<=finish;x++) {
02551 if ((x > 31) || (x < 0)) {
02552 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 31)\n", x);
02553 } else
02554 group |= (1 << x);
02555 }
02556 }
02557 return group;
02558 }