00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include <string.h>
00028 #include <sys/time.h>
00029 #include <signal.h>
00030 #include <errno.h>
00031 #include <unistd.h>
00032 #include <math.h>
00033
00034 #ifdef ZAPTEL_OPTIMIZATIONS
00035 #include <sys/ioctl.h>
00036 #ifdef __linux__
00037 #include <linux/zaptel.h>
00038 #else
00039 #include <zaptel.h>
00040 #endif
00041 #ifndef ZT_TIMERPING
00042 #error "You need newer zaptel! Please svn update zaptel"
00043 #endif
00044 #endif
00045
00046 #include "asterisk.h"
00047
00048 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 73349 $")
00049
00050 #include "asterisk/pbx.h"
00051 #include "asterisk/frame.h"
00052 #include "asterisk/sched.h"
00053 #include "asterisk/options.h"
00054 #include "asterisk/channel.h"
00055 #include "asterisk/chanspy.h"
00056 #include "asterisk/musiconhold.h"
00057 #include "asterisk/logger.h"
00058 #include "asterisk/say.h"
00059 #include "asterisk/file.h"
00060 #include "asterisk/cli.h"
00061 #include "asterisk/translate.h"
00062 #include "asterisk/manager.h"
00063 #include "asterisk/chanvars.h"
00064 #include "asterisk/linkedlists.h"
00065 #include "asterisk/indications.h"
00066 #include "asterisk/monitor.h"
00067 #include "asterisk/causes.h"
00068 #include "asterisk/callerid.h"
00069 #include "asterisk/utils.h"
00070 #include "asterisk/lock.h"
00071 #include "asterisk/app.h"
00072 #include "asterisk/transcap.h"
00073 #include "asterisk/devicestate.h"
00074
00075 struct channel_spy_trans {
00076 int last_format;
00077 struct ast_trans_pvt *path;
00078 };
00079
00080 struct ast_channel_spy_list {
00081 struct channel_spy_trans read_translator;
00082 struct channel_spy_trans write_translator;
00083 AST_LIST_HEAD_NOLOCK(, ast_channel_spy) list;
00084 };
00085
00086
00087 #if 0
00088 #define MONITOR_CONSTANT_DELAY
00089 #define MONITOR_DELAY 150 * 8
00090 #endif
00091
00092
00093
00094
00095 static int shutting_down = 0;
00096
00097 AST_MUTEX_DEFINE_STATIC(uniquelock);
00098 static int uniqueint = 0;
00099
00100 unsigned long global_fin = 0, global_fout = 0;
00101
00102
00103
00104 struct chanlist {
00105 const struct ast_channel_tech *tech;
00106 struct chanlist *next;
00107 };
00108
00109 static struct chanlist *backends = NULL;
00110
00111
00112
00113
00114 static struct ast_channel *channels = NULL;
00115
00116
00117
00118 AST_MUTEX_DEFINE_STATIC(chlock);
00119
00120 const struct ast_cause {
00121 int cause;
00122 const char *desc;
00123 } causes[] = {
00124 { AST_CAUSE_UNALLOCATED, "Unallocated (unassigned) number" },
00125 { AST_CAUSE_NO_ROUTE_TRANSIT_NET, "No route to specified transmit network" },
00126 { AST_CAUSE_NO_ROUTE_DESTINATION, "No route to destination" },
00127 { AST_CAUSE_CHANNEL_UNACCEPTABLE, "Channel unacceptable" },
00128 { AST_CAUSE_CALL_AWARDED_DELIVERED, "Call awarded and being delivered in an established channel" },
00129 { AST_CAUSE_NORMAL_CLEARING, "Normal Clearing" },
00130 { AST_CAUSE_USER_BUSY, "User busy" },
00131 { AST_CAUSE_NO_USER_RESPONSE, "No user responding" },
00132 { AST_CAUSE_NO_ANSWER, "User alerting, no answer" },
00133 { AST_CAUSE_CALL_REJECTED, "Call Rejected" },
00134 { AST_CAUSE_NUMBER_CHANGED, "Number changed" },
00135 { AST_CAUSE_DESTINATION_OUT_OF_ORDER, "Destination out of order" },
00136 { AST_CAUSE_INVALID_NUMBER_FORMAT, "Invalid number format" },
00137 { AST_CAUSE_FACILITY_REJECTED, "Facility rejected" },
00138 { AST_CAUSE_RESPONSE_TO_STATUS_ENQUIRY, "Response to STATus ENQuiry" },
00139 { AST_CAUSE_NORMAL_UNSPECIFIED, "Normal, unspecified" },
00140 { AST_CAUSE_NORMAL_CIRCUIT_CONGESTION, "Circuit/channel congestion" },
00141 { AST_CAUSE_NETWORK_OUT_OF_ORDER, "Network out of order" },
00142 { AST_CAUSE_NORMAL_TEMPORARY_FAILURE, "Temporary failure" },
00143 { AST_CAUSE_SWITCH_CONGESTION, "Switching equipment congestion" },
00144 { AST_CAUSE_ACCESS_INFO_DISCARDED, "Access information discarded" },
00145 { AST_CAUSE_REQUESTED_CHAN_UNAVAIL, "Requested channel not available" },
00146 { AST_CAUSE_PRE_EMPTED, "Pre-empted" },
00147 { AST_CAUSE_FACILITY_NOT_SUBSCRIBED, "Facility not subscribed" },
00148 { AST_CAUSE_OUTGOING_CALL_BARRED, "Outgoing call barred" },
00149 { AST_CAUSE_INCOMING_CALL_BARRED, "Incoming call barred" },
00150 { AST_CAUSE_BEARERCAPABILITY_NOTAUTH, "Bearer capability not authorized" },
00151 { AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, "Bearer capability not available" },
00152 { AST_CAUSE_BEARERCAPABILITY_NOTIMPL, "Bearer capability not implemented" },
00153 { AST_CAUSE_CHAN_NOT_IMPLEMENTED, "Channel not implemented" },
00154 { AST_CAUSE_FACILITY_NOT_IMPLEMENTED, "Facility not implemented" },
00155 { AST_CAUSE_INVALID_CALL_REFERENCE, "Invalid call reference value" },
00156 { AST_CAUSE_INCOMPATIBLE_DESTINATION, "Incompatible destination" },
00157 { AST_CAUSE_INVALID_MSG_UNSPECIFIED, "Invalid message unspecified" },
00158 { AST_CAUSE_MANDATORY_IE_MISSING, "Mandatory information element is missing" },
00159 { AST_CAUSE_MESSAGE_TYPE_NONEXIST, "Message type nonexist." },
00160 { AST_CAUSE_WRONG_MESSAGE, "Wrong message" },
00161 { AST_CAUSE_IE_NONEXIST, "Info. element nonexist or not implemented" },
00162 { AST_CAUSE_INVALID_IE_CONTENTS, "Invalid information element contents" },
00163 { AST_CAUSE_WRONG_CALL_STATE, "Message not compatible with call state" },
00164 { AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, "Recover on timer expiry" },
00165 { AST_CAUSE_MANDATORY_IE_LENGTH_ERROR, "Mandatory IE length error" },
00166 { AST_CAUSE_PROTOCOL_ERROR, "Protocol error, unspecified" },
00167 { AST_CAUSE_INTERWORKING, "Interworking, unspecified" },
00168 };
00169
00170
00171 static int show_channeltypes(int fd, int argc, char *argv[])
00172 {
00173 #define FORMAT "%-10.10s %-30.30s %-12.12s %-12.12s %-12.12s\n"
00174 struct chanlist *cl = backends;
00175 ast_cli(fd, FORMAT, "Type", "Description", "Devicestate", "Indications", "Transfer");
00176 ast_cli(fd, FORMAT, "----------", "-----------", "-----------", "-----------", "--------");
00177 if (ast_mutex_lock(&chlock)) {
00178 ast_log(LOG_WARNING, "Unable to lock channel list\n");
00179 return -1;
00180 }
00181 while (cl) {
00182 ast_cli(fd, FORMAT, cl->tech->type, cl->tech->description,
00183 (cl->tech->devicestate) ? "yes" : "no",
00184 (cl->tech->indicate) ? "yes" : "no",
00185 (cl->tech->transfer) ? "yes" : "no");
00186 cl = cl->next;
00187 }
00188 ast_mutex_unlock(&chlock);
00189 return RESULT_SUCCESS;
00190
00191 #undef FORMAT
00192
00193 }
00194
00195 static char show_channeltypes_usage[] =
00196 "Usage: show channeltypes\n"
00197 " Shows available channel types registered in your Asterisk server.\n";
00198
00199 static struct ast_cli_entry cli_show_channeltypes =
00200 { { "show", "channeltypes", NULL }, show_channeltypes, "Show available channel types", show_channeltypes_usage };
00201
00202
00203 int ast_check_hangup(struct ast_channel *chan)
00204 {
00205 time_t myt;
00206
00207
00208 if (chan->_softhangup)
00209 return 1;
00210
00211 if (!chan->tech_pvt)
00212 return 1;
00213
00214 if (!chan->whentohangup)
00215 return 0;
00216 time(&myt);
00217
00218 if (chan->whentohangup > myt)
00219 return 0;
00220 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
00221 return 1;
00222 }
00223
00224 static int ast_check_hangup_locked(struct ast_channel *chan)
00225 {
00226 int res;
00227 ast_mutex_lock(&chan->lock);
00228 res = ast_check_hangup(chan);
00229 ast_mutex_unlock(&chan->lock);
00230 return res;
00231 }
00232
00233
00234 void ast_begin_shutdown(int hangup)
00235 {
00236 struct ast_channel *c;
00237 shutting_down = 1;
00238 if (hangup) {
00239 ast_mutex_lock(&chlock);
00240 c = channels;
00241 while(c) {
00242 ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN);
00243 c = c->next;
00244 }
00245 ast_mutex_unlock(&chlock);
00246 }
00247 }
00248
00249
00250 int ast_active_channels(void)
00251 {
00252 struct ast_channel *c;
00253 int cnt = 0;
00254 ast_mutex_lock(&chlock);
00255 c = channels;
00256 while(c) {
00257 cnt++;
00258 c = c->next;
00259 }
00260 ast_mutex_unlock(&chlock);
00261 return cnt;
00262 }
00263
00264
00265 void ast_cancel_shutdown(void)
00266 {
00267 shutting_down = 0;
00268 }
00269
00270
00271 int ast_shutting_down(void)
00272 {
00273 return shutting_down;
00274 }
00275
00276
00277 void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset)
00278 {
00279 time_t myt;
00280 struct ast_frame fr = { AST_FRAME_NULL, };
00281
00282 time(&myt);
00283 if (offset)
00284 chan->whentohangup = myt + offset;
00285 else
00286 chan->whentohangup = 0;
00287 ast_queue_frame(chan, &fr);
00288 return;
00289 }
00290
00291
00292 int ast_channel_cmpwhentohangup(struct ast_channel *chan, time_t offset)
00293 {
00294 time_t whentohangup;
00295
00296 if (chan->whentohangup == 0) {
00297 if (offset == 0)
00298 return (0);
00299 else
00300 return (-1);
00301 } else {
00302 if (offset == 0)
00303 return (1);
00304 else {
00305 whentohangup = offset + time (NULL);
00306 if (chan->whentohangup < whentohangup)
00307 return (1);
00308 else if (chan->whentohangup == whentohangup)
00309 return (0);
00310 else
00311 return (-1);
00312 }
00313 }
00314 }
00315
00316
00317 int ast_channel_register(const struct ast_channel_tech *tech)
00318 {
00319 struct chanlist *chan;
00320
00321 ast_mutex_lock(&chlock);
00322
00323 chan = backends;
00324 while (chan) {
00325 if (!strcasecmp(tech->type, chan->tech->type)) {
00326 ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type);
00327 ast_mutex_unlock(&chlock);
00328 return -1;
00329 }
00330 chan = chan->next;
00331 }
00332
00333 chan = malloc(sizeof(*chan));
00334 if (!chan) {
00335 ast_log(LOG_WARNING, "Out of memory\n");
00336 ast_mutex_unlock(&chlock);
00337 return -1;
00338 }
00339 chan->tech = tech;
00340 chan->next = backends;
00341 backends = chan;
00342
00343 if (option_debug)
00344 ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description);
00345
00346 if (option_verbose > 1)
00347 ast_verbose(VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->tech->type,
00348 chan->tech->description);
00349
00350 ast_mutex_unlock(&chlock);
00351 return 0;
00352 }
00353
00354 void ast_channel_unregister(const struct ast_channel_tech *tech)
00355 {
00356 struct chanlist *chan, *last=NULL;
00357
00358 if (option_debug && tech && tech->type )
00359 ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", tech->type);
00360 else if (option_debug)
00361 ast_log(LOG_DEBUG, "Unregistering channel, tech is NULL!!!\n");
00362
00363
00364 ast_mutex_lock(&chlock);
00365
00366 chan = backends;
00367 while (chan) {
00368 if (chan->tech == tech) {
00369 if (last)
00370 last->next = chan->next;
00371 else
00372 backends = backends->next;
00373 free(chan);
00374 ast_mutex_unlock(&chlock);
00375
00376 if (option_verbose > 1)
00377 ast_verbose( VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", tech->type);
00378
00379 return;
00380 }
00381 last = chan;
00382 chan = chan->next;
00383 }
00384
00385 ast_mutex_unlock(&chlock);
00386 }
00387
00388 const struct ast_channel_tech *ast_get_channel_tech(const char *name)
00389 {
00390 struct chanlist *chanls;
00391
00392 if (ast_mutex_lock(&chlock)) {
00393 ast_log(LOG_WARNING, "Unable to lock channel tech list\n");
00394 return NULL;
00395 }
00396
00397 for (chanls = backends; chanls; chanls = chanls->next) {
00398 if (strcasecmp(name, chanls->tech->type))
00399 continue;
00400
00401 ast_mutex_unlock(&chlock);
00402 return chanls->tech;
00403 }
00404
00405 ast_mutex_unlock(&chlock);
00406 return NULL;
00407 }
00408
00409
00410 const char *ast_cause2str(int cause)
00411 {
00412 int x;
00413
00414 for (x=0; x < sizeof(causes) / sizeof(causes[0]); x++)
00415 if (causes[x].cause == cause)
00416 return causes[x].desc;
00417
00418 return "Unknown";
00419 }
00420
00421
00422 char *ast_state2str(int state)
00423 {
00424
00425 static char localtmp[256];
00426 switch(state) {
00427 case AST_STATE_DOWN:
00428 return "Down";
00429 case AST_STATE_RESERVED:
00430 return "Rsrvd";
00431 case AST_STATE_OFFHOOK:
00432 return "OffHook";
00433 case AST_STATE_DIALING:
00434 return "Dialing";
00435 case AST_STATE_RING:
00436 return "Ring";
00437 case AST_STATE_RINGING:
00438 return "Ringing";
00439 case AST_STATE_UP:
00440 return "Up";
00441 case AST_STATE_BUSY:
00442 return "Busy";
00443 default:
00444 snprintf(localtmp, sizeof(localtmp), "Unknown (%d)\n", state);
00445 return localtmp;
00446 }
00447 }
00448
00449
00450 char *ast_transfercapability2str(int transfercapability)
00451 {
00452 switch(transfercapability) {
00453 case AST_TRANS_CAP_SPEECH:
00454 return "SPEECH";
00455 case AST_TRANS_CAP_DIGITAL:
00456 return "DIGITAL";
00457 case AST_TRANS_CAP_RESTRICTED_DIGITAL:
00458 return "RESTRICTED_DIGITAL";
00459 case AST_TRANS_CAP_3_1K_AUDIO:
00460 return "3K1AUDIO";
00461 case AST_TRANS_CAP_DIGITAL_W_TONES:
00462 return "DIGITAL_W_TONES";
00463 case AST_TRANS_CAP_VIDEO:
00464 return "VIDEO";
00465 default:
00466 return "UNKNOWN";
00467 }
00468 }
00469
00470
00471 int ast_best_codec(int fmts)
00472 {
00473
00474
00475 int x;
00476 static int prefs[] =
00477 {
00478
00479 AST_FORMAT_ULAW,
00480
00481 AST_FORMAT_ALAW,
00482
00483 AST_FORMAT_SLINEAR,
00484
00485 AST_FORMAT_G726,
00486
00487 AST_FORMAT_ADPCM,
00488
00489
00490 AST_FORMAT_GSM,
00491
00492 AST_FORMAT_ILBC,
00493
00494 AST_FORMAT_SPEEX,
00495
00496
00497 AST_FORMAT_LPC10,
00498
00499 AST_FORMAT_G729A,
00500
00501 AST_FORMAT_G723_1,
00502 };
00503
00504
00505
00506 for (x=0; x < (sizeof(prefs) / sizeof(prefs[0]) ); x++)
00507 if (fmts & prefs[x])
00508 return prefs[x];
00509 ast_log(LOG_WARNING, "Don't know any of 0x%x formats\n", fmts);
00510 return 0;
00511 }
00512
00513 static const struct ast_channel_tech null_tech = {
00514 .type = "NULL",
00515 .description = "Null channel (should not see this)",
00516 };
00517
00518
00519 struct ast_channel *ast_channel_alloc(int needqueue)
00520 {
00521 struct ast_channel *tmp;
00522 int x;
00523 int flags;
00524 struct varshead *headp;
00525
00526
00527
00528 if (shutting_down) {
00529 ast_log(LOG_WARNING, "Channel allocation failed: Refusing due to active shutdown\n");
00530 return NULL;
00531 }
00532
00533 tmp = malloc(sizeof(struct ast_channel));
00534 if (!tmp) {
00535 ast_log(LOG_WARNING, "Channel allocation failed: Out of memory\n");
00536 return NULL;
00537 }
00538
00539 memset(tmp, 0, sizeof(struct ast_channel));
00540 tmp->sched = sched_context_create();
00541 if (!tmp->sched) {
00542 ast_log(LOG_WARNING, "Channel allocation failed: Unable to create schedule context\n");
00543 free(tmp);
00544 return NULL;
00545 }
00546
00547 for (x=0; x<AST_MAX_FDS - 1; x++)
00548 tmp->fds[x] = -1;
00549
00550 #ifdef ZAPTEL_OPTIMIZATIONS
00551 tmp->timingfd = open("/dev/zap/timer", O_RDWR);
00552 if (tmp->timingfd > -1) {
00553
00554
00555 flags = 1;
00556 if (!ioctl(tmp->timingfd, ZT_TIMERPONG, &flags))
00557 needqueue = 0;
00558 }
00559 #else
00560 tmp->timingfd = -1;
00561 #endif
00562
00563 if (needqueue) {
00564 if (pipe(tmp->alertpipe)) {
00565 ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe!\n");
00566 free(tmp);
00567 return NULL;
00568 } else {
00569 flags = fcntl(tmp->alertpipe[0], F_GETFL);
00570 fcntl(tmp->alertpipe[0], F_SETFL, flags | O_NONBLOCK);
00571 flags = fcntl(tmp->alertpipe[1], F_GETFL);
00572 fcntl(tmp->alertpipe[1], F_SETFL, flags | O_NONBLOCK);
00573 }
00574 } else
00575
00576 tmp->alertpipe[0] = tmp->alertpipe[1] = -1;
00577
00578
00579 tmp->fds[AST_MAX_FDS-1] = tmp->alertpipe[0];
00580
00581 tmp->fds[AST_MAX_FDS-2] = tmp->timingfd;
00582 strcpy(tmp->name, "**Unknown**");
00583
00584 tmp->_state = AST_STATE_DOWN;
00585 tmp->streamid = -1;
00586 tmp->appl = NULL;
00587 tmp->data = NULL;
00588 tmp->fin = global_fin;
00589 tmp->fout = global_fout;
00590 ast_mutex_lock(&uniquelock);
00591 snprintf(tmp->uniqueid, sizeof(tmp->uniqueid), "%li.%d", (long) time(NULL), uniqueint++);
00592 ast_mutex_unlock(&uniquelock);
00593 headp = &tmp->varshead;
00594 ast_mutex_init(&tmp->lock);
00595 AST_LIST_HEAD_INIT_NOLOCK(headp);
00596 strcpy(tmp->context, "default");
00597 ast_copy_string(tmp->language, defaultlanguage, sizeof(tmp->language));
00598 strcpy(tmp->exten, "s");
00599 tmp->priority = 1;
00600 tmp->amaflags = ast_default_amaflags;
00601 ast_copy_string(tmp->accountcode, ast_default_accountcode, sizeof(tmp->accountcode));
00602
00603 tmp->tech = &null_tech;
00604
00605 ast_mutex_lock(&chlock);
00606 tmp->next = channels;
00607 channels = tmp;
00608
00609 ast_mutex_unlock(&chlock);
00610 return tmp;
00611 }
00612
00613
00614 int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin)
00615 {
00616 struct ast_frame *f;
00617 struct ast_frame *prev, *cur;
00618 int blah = 1;
00619 int qlen = 0;
00620
00621
00622 f = ast_frdup(fin);
00623 if (!f) {
00624 ast_log(LOG_WARNING, "Unable to duplicate frame\n");
00625 return -1;
00626 }
00627 ast_mutex_lock(&chan->lock);
00628 prev = NULL;
00629 cur = chan->readq;
00630 while(cur) {
00631 if ((cur->frametype == AST_FRAME_CONTROL) && (cur->subclass == AST_CONTROL_HANGUP)) {
00632
00633 ast_frfree(f);
00634 ast_mutex_unlock(&chan->lock);
00635 return 0;
00636 }
00637 prev = cur;
00638 cur = cur->next;
00639 qlen++;
00640 }
00641
00642 if (((fin->frametype == AST_FRAME_VOICE) && (qlen > 96)) || (qlen > 128)) {
00643 if (fin->frametype != AST_FRAME_VOICE) {
00644 ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name);
00645 CRASH;
00646 } else {
00647 ast_log(LOG_DEBUG, "Dropping voice to exceptionally long queue on %s\n", chan->name);
00648 ast_frfree(f);
00649 ast_mutex_unlock(&chan->lock);
00650 return 0;
00651 }
00652 }
00653 if (prev)
00654 prev->next = f;
00655 else
00656 chan->readq = f;
00657 if (chan->alertpipe[1] > -1) {
00658 if (write(chan->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah))
00659 ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d (qlen = %d): %s!\n",
00660 chan->name, f->frametype, f->subclass, qlen, strerror(errno));
00661 #ifdef ZAPTEL_OPTIMIZATIONS
00662 } else if (chan->timingfd > -1) {
00663 ioctl(chan->timingfd, ZT_TIMERPING, &blah);
00664 #endif
00665 } else if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
00666 pthread_kill(chan->blocker, SIGURG);
00667 }
00668 ast_mutex_unlock(&chan->lock);
00669 return 0;
00670 }
00671
00672
00673 int ast_queue_hangup(struct ast_channel *chan)
00674 {
00675 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
00676
00677 if (!ast_mutex_trylock(&chan->lock)) {
00678 chan->_softhangup |= AST_SOFTHANGUP_DEV;
00679 ast_mutex_unlock(&chan->lock);
00680 }
00681 return ast_queue_frame(chan, &f);
00682 }
00683
00684
00685 int ast_queue_control(struct ast_channel *chan, int control)
00686 {
00687 struct ast_frame f = { AST_FRAME_CONTROL, };
00688 f.subclass = control;
00689 return ast_queue_frame(chan, &f);
00690 }
00691
00692
00693 int ast_channel_defer_dtmf(struct ast_channel *chan)
00694 {
00695 int pre = 0;
00696
00697 if (chan) {
00698 pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF);
00699 ast_set_flag(chan, AST_FLAG_DEFER_DTMF);
00700 }
00701 return pre;
00702 }
00703
00704
00705 void ast_channel_undefer_dtmf(struct ast_channel *chan)
00706 {
00707 if (chan)
00708 ast_clear_flag(chan, AST_FLAG_DEFER_DTMF);
00709 }
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733 static struct ast_channel *channel_find_locked(const struct ast_channel *prev,
00734 const char *name, const int namelen,
00735 const char *context, const char *exten)
00736 {
00737 const char *msg = prev ? "deadlock" : "initial deadlock";
00738 int retries;
00739 struct ast_channel *c;
00740
00741 for (retries = 0; retries < 10; retries++) {
00742 int done;
00743
00744 ast_mutex_lock(&chlock);
00745 for (c = channels; c; c = c->next) {
00746 if (prev) {
00747 if (c != prev)
00748 continue;
00749
00750 if ((c = c->next) == NULL) break;
00751
00752
00753
00754
00755 }
00756 if (name) {
00757 if ((!namelen && strcasecmp(c->name, name)) ||
00758 (namelen && strncasecmp(c->name, name, namelen)))
00759 continue;
00760 } else if (exten) {
00761 if (context && strcasecmp(c->context, context) &&
00762 strcasecmp(c->macrocontext, context))
00763 continue;
00764 if (strcasecmp(c->exten, exten) &&
00765 strcasecmp(c->macroexten, exten))
00766 continue;
00767 }
00768
00769 break;
00770 }
00771
00772 done = (c == NULL) || (ast_mutex_trylock(&c->lock) == 0);
00773
00774 if (!done && c) {
00775 ast_log(LOG_DEBUG, "Avoiding %s for '%s'\n", msg, c->name);
00776 if (retries == 9) {
00777
00778
00779
00780 ast_log(LOG_WARNING, "Avoided %s for '%p', %d retries!\n", msg, c, retries);
00781
00782
00783
00784
00785
00786 if (!(name && !namelen)) {
00787 prev = c;
00788 retries = -1;
00789 }
00790 }
00791 }
00792 ast_mutex_unlock(&chlock);
00793 if (done)
00794 return c;
00795 usleep(1);
00796 }
00797
00798 return NULL;
00799 }
00800
00801
00802 struct ast_channel *ast_channel_walk_locked(const struct ast_channel *prev)
00803 {
00804 return channel_find_locked(prev, NULL, 0, NULL, NULL);
00805 }
00806
00807
00808 struct ast_channel *ast_get_channel_by_name_locked(const char *name)
00809 {
00810 return channel_find_locked(NULL, name, 0, NULL, NULL);
00811 }
00812
00813
00814 struct ast_channel *ast_get_channel_by_name_prefix_locked(const char *name, const int namelen)
00815 {
00816 return channel_find_locked(NULL, name, namelen, NULL, NULL);
00817 }
00818
00819
00820 struct ast_channel *ast_walk_channel_by_name_prefix_locked(struct ast_channel *chan, const char *name, const int namelen)
00821 {
00822 return channel_find_locked(chan, name, namelen, NULL, NULL);
00823 }
00824
00825
00826 struct ast_channel *ast_get_channel_by_exten_locked(const char *exten, const char *context)
00827 {
00828 return channel_find_locked(NULL, NULL, 0, context, exten);
00829 }
00830
00831
00832 int ast_safe_sleep_conditional( struct ast_channel *chan, int ms,
00833 int (*cond)(void*), void *data )
00834 {
00835 struct ast_frame *f;
00836
00837 while(ms > 0) {
00838 if( cond && ((*cond)(data) == 0 ) )
00839 return 0;
00840 ms = ast_waitfor(chan, ms);
00841 if (ms <0)
00842 return -1;
00843 if (ms > 0) {
00844 f = ast_read(chan);
00845 if (!f)
00846 return -1;
00847 ast_frfree(f);
00848 }
00849 }
00850 return 0;
00851 }
00852
00853
00854 int ast_safe_sleep(struct ast_channel *chan, int ms)
00855 {
00856 struct ast_frame *f;
00857 while(ms > 0) {
00858 ms = ast_waitfor(chan, ms);
00859 if (ms <0)
00860 return -1;
00861 if (ms > 0) {
00862 f = ast_read(chan);
00863 if (!f)
00864 return -1;
00865 ast_frfree(f);
00866 }
00867 }
00868 return 0;
00869 }
00870
00871 static void free_cid(struct ast_callerid *cid)
00872 {
00873 if (cid->cid_dnid)
00874 free(cid->cid_dnid);
00875 if (cid->cid_num)
00876 free(cid->cid_num);
00877 if (cid->cid_name)
00878 free(cid->cid_name);
00879 if (cid->cid_ani)
00880 free(cid->cid_ani);
00881 if (cid->cid_rdnis)
00882 free(cid->cid_rdnis);
00883 }
00884
00885
00886 void ast_channel_free(struct ast_channel *chan)
00887 {
00888 struct ast_channel *last=NULL, *cur;
00889 int fd;
00890 struct ast_var_t *vardata;
00891 struct ast_frame *f, *fp;
00892 struct varshead *headp;
00893 char name[AST_CHANNEL_NAME];
00894
00895 headp=&chan->varshead;
00896
00897 ast_mutex_lock(&chlock);
00898 cur = channels;
00899 while(cur) {
00900 if (cur == chan) {
00901 if (last)
00902 last->next = cur->next;
00903 else
00904 channels = cur->next;
00905 break;
00906 }
00907 last = cur;
00908 cur = cur->next;
00909 }
00910 if (!cur) {
00911 ast_mutex_unlock(&chlock);
00912 ast_log(LOG_ERROR, "Unable to find channel in list to free. Assuming it has already been done.\n");
00913 return;
00914 }
00915
00916
00917
00918 ast_mutex_lock(&cur->lock);
00919 ast_mutex_unlock(&cur->lock);
00920 if (chan->tech_pvt) {
00921 ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
00922 free(chan->tech_pvt);
00923 }
00924
00925 if (chan->sched)
00926 sched_context_destroy(chan->sched);
00927
00928 ast_copy_string(name, chan->name, sizeof(name));
00929
00930
00931 if (chan->monitor) {
00932 chan->monitor->stop( chan, 0 );
00933 }
00934
00935
00936 if(chan->music_state)
00937 ast_moh_cleanup(chan);
00938
00939
00940 if (chan->readtrans)
00941 ast_translator_free_path(chan->readtrans);
00942 if (chan->writetrans)
00943 ast_translator_free_path(chan->writetrans);
00944 if (chan->pbx)
00945 ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
00946 free_cid(&chan->cid);
00947 ast_mutex_destroy(&chan->lock);
00948
00949 if ((fd = chan->alertpipe[0]) > -1)
00950 close(fd);
00951 if ((fd = chan->alertpipe[1]) > -1)
00952 close(fd);
00953 if ((fd = chan->timingfd) > -1)
00954 close(fd);
00955 f = chan->readq;
00956 chan->readq = NULL;
00957 while(f) {
00958 fp = f;
00959 f = f->next;
00960 ast_frfree(fp);
00961 }
00962
00963
00964
00965
00966 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
00967 ast_var_delete(vardata);
00968
00969
00970 ast_app_group_discard(chan);
00971
00972 free(chan);
00973 ast_mutex_unlock(&chlock);
00974
00975 ast_device_state_changed_literal(name);
00976 }
00977
00978 int ast_channel_spy_add(struct ast_channel *chan, struct ast_channel_spy *spy)
00979 {
00980
00981 spy->chan = chan;
00982
00983 if (!ast_test_flag(spy, CHANSPY_FORMAT_AUDIO)) {
00984 ast_log(LOG_WARNING, "Could not add channel spy '%s' to channel '%s', only audio format spies are supported.\n",
00985 spy->type, chan->name);
00986 return -1;
00987 }
00988
00989 if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST) && (spy->read_queue.format != AST_FORMAT_SLINEAR)) {
00990 ast_log(LOG_WARNING, "Cannot provide volume adjustment on '%s' format spies\n",
00991 ast_getformatname(spy->read_queue.format));
00992 return -1;
00993 }
00994
00995 if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST) && (spy->write_queue.format != AST_FORMAT_SLINEAR)) {
00996 ast_log(LOG_WARNING, "Cannot provide volume adjustment on '%s' format spies\n",
<