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