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
00026 #include "asterisk.h"
00027
00028 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 168561 $")
00029
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <stdarg.h>
00033 #include <string.h>
00034 #include <sys/time.h>
00035 #include <signal.h>
00036 #include <errno.h>
00037 #include <unistd.h>
00038 #include <math.h>
00039
00040 #if defined(HAVE_DAHDI)
00041 #include <sys/ioctl.h>
00042 #include "asterisk/dahdi_compat.h"
00043 #endif
00044
00045 #include "asterisk/pbx.h"
00046 #include "asterisk/frame.h"
00047 #include "asterisk/sched.h"
00048 #include "asterisk/options.h"
00049 #include "asterisk/channel.h"
00050 #include "asterisk/audiohook.h"
00051 #include "asterisk/musiconhold.h"
00052 #include "asterisk/logger.h"
00053 #include "asterisk/say.h"
00054 #include "asterisk/file.h"
00055 #include "asterisk/cli.h"
00056 #include "asterisk/translate.h"
00057 #include "asterisk/manager.h"
00058 #include "asterisk/chanvars.h"
00059 #include "asterisk/linkedlists.h"
00060 #include "asterisk/indications.h"
00061 #include "asterisk/monitor.h"
00062 #include "asterisk/causes.h"
00063 #include "asterisk/callerid.h"
00064 #include "asterisk/utils.h"
00065 #include "asterisk/lock.h"
00066 #include "asterisk/app.h"
00067 #include "asterisk/transcap.h"
00068 #include "asterisk/devicestate.h"
00069 #include "asterisk/sha1.h"
00070 #include "asterisk/threadstorage.h"
00071 #include "asterisk/slinfactory.h"
00072
00073
00074 #define MONITOR_CONSTANT_DELAY
00075 #define MONITOR_DELAY 150 * 8
00076
00077
00078 static int shutting_down;
00079
00080 static int uniqueint;
00081
00082 unsigned long global_fin, global_fout;
00083
00084 AST_THREADSTORAGE(state2str_threadbuf, state2str_threadbuf_init);
00085 #define STATE2STR_BUFSIZE 32
00086
00087
00088
00089 #define AST_DEFAULT_EMULATE_DTMF_DURATION 100
00090
00091
00092 #define AST_MIN_DTMF_DURATION 80
00093
00094
00095
00096 #define AST_MIN_DTMF_GAP 45
00097
00098 struct chanlist {
00099 const struct ast_channel_tech *tech;
00100 AST_LIST_ENTRY(chanlist) list;
00101 };
00102
00103
00104 static AST_LIST_HEAD_NOLOCK_STATIC(backends, chanlist);
00105
00106
00107
00108 static AST_LIST_HEAD_STATIC(channels, ast_channel);
00109
00110
00111 const struct ast_cause {
00112 int cause;
00113 const char *name;
00114 const char *desc;
00115 } causes[] = {
00116 { AST_CAUSE_NOTDEFINED, "Not defined" },
00117 { AST_CAUSE_UNALLOCATED, "UNALLOCATED", "Unallocated (unassigned) number" },
00118 { AST_CAUSE_NO_ROUTE_TRANSIT_NET, "NO_ROUTE_TRANSIT_NET", "No route to specified transmit network" },
00119 { AST_CAUSE_NO_ROUTE_DESTINATION, "NO_ROUTE_DESTINATION", "No route to destination" },
00120 { AST_CAUSE_CHANNEL_UNACCEPTABLE, "CHANNEL_UNACCEPTABLE", "Channel unacceptable" },
00121 { AST_CAUSE_CALL_AWARDED_DELIVERED, "CALL_AWARDED_DELIVERED", "Call awarded and being delivered in an established channel" },
00122 { AST_CAUSE_NORMAL_CLEARING, "NORMAL_CLEARING", "Normal Clearing" },
00123 { AST_CAUSE_USER_BUSY, "USER_BUSY", "User busy" },
00124 { AST_CAUSE_NO_USER_RESPONSE, "NO_USER_RESPONSE", "No user responding" },
00125 { AST_CAUSE_NO_ANSWER, "NO_ANSWER", "User alerting, no answer" },
00126 { AST_CAUSE_CALL_REJECTED, "CALL_REJECTED", "Call Rejected" },
00127 { AST_CAUSE_NUMBER_CHANGED, "NUMBER_CHANGED", "Number changed" },
00128 { AST_CAUSE_DESTINATION_OUT_OF_ORDER, "DESTINATION_OUT_OF_ORDER", "Destination out of order" },
00129 { AST_CAUSE_INVALID_NUMBER_FORMAT, "INVALID_NUMBER_FORMAT", "Invalid number format" },
00130 { AST_CAUSE_FACILITY_REJECTED, "FACILITY_REJECTED", "Facility rejected" },
00131 { AST_CAUSE_RESPONSE_TO_STATUS_ENQUIRY, "RESPONSE_TO_STATUS_ENQUIRY", "Response to STATus ENQuiry" },
00132 { AST_CAUSE_NORMAL_UNSPECIFIED, "NORMAL_UNSPECIFIED", "Normal, unspecified" },
00133 { AST_CAUSE_NORMAL_CIRCUIT_CONGESTION, "NORMAL_CIRCUIT_CONGESTION", "Circuit/channel congestion" },
00134 { AST_CAUSE_NETWORK_OUT_OF_ORDER, "NETWORK_OUT_OF_ORDER", "Network out of order" },
00135 { AST_CAUSE_NORMAL_TEMPORARY_FAILURE, "NORMAL_TEMPORARY_FAILURE", "Temporary failure" },
00136 { AST_CAUSE_SWITCH_CONGESTION, "SWITCH_CONGESTION", "Switching equipment congestion" },
00137 { AST_CAUSE_ACCESS_INFO_DISCARDED, "ACCESS_INFO_DISCARDED", "Access information discarded" },
00138 { AST_CAUSE_REQUESTED_CHAN_UNAVAIL, "REQUESTED_CHAN_UNAVAIL", "Requested channel not available" },
00139 { AST_CAUSE_PRE_EMPTED, "PRE_EMPTED", "Pre-empted" },
00140 { AST_CAUSE_FACILITY_NOT_SUBSCRIBED, "FACILITY_NOT_SUBSCRIBED", "Facility not subscribed" },
00141 { AST_CAUSE_OUTGOING_CALL_BARRED, "OUTGOING_CALL_BARRED", "Outgoing call barred" },
00142 { AST_CAUSE_INCOMING_CALL_BARRED, "INCOMING_CALL_BARRED", "Incoming call barred" },
00143 { AST_CAUSE_BEARERCAPABILITY_NOTAUTH, "BEARERCAPABILITY_NOTAUTH", "Bearer capability not authorized" },
00144 { AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, "BEARERCAPABILITY_NOTAVAIL", "Bearer capability not available" },
00145 { AST_CAUSE_BEARERCAPABILITY_NOTIMPL, "BEARERCAPABILITY_NOTIMPL", "Bearer capability not implemented" },
00146 { AST_CAUSE_CHAN_NOT_IMPLEMENTED, "CHAN_NOT_IMPLEMENTED", "Channel not implemented" },
00147 { AST_CAUSE_FACILITY_NOT_IMPLEMENTED, "FACILITY_NOT_IMPLEMENTED", "Facility not implemented" },
00148 { AST_CAUSE_INVALID_CALL_REFERENCE, "INVALID_CALL_REFERENCE", "Invalid call reference value" },
00149 { AST_CAUSE_INCOMPATIBLE_DESTINATION, "INCOMPATIBLE_DESTINATION", "Incompatible destination" },
00150 { AST_CAUSE_INVALID_MSG_UNSPECIFIED, "INVALID_MSG_UNSPECIFIED", "Invalid message unspecified" },
00151 { AST_CAUSE_MANDATORY_IE_MISSING, "MANDATORY_IE_MISSING", "Mandatory information element is missing" },
00152 { AST_CAUSE_MESSAGE_TYPE_NONEXIST, "MESSAGE_TYPE_NONEXIST", "Message type nonexist." },
00153 { AST_CAUSE_WRONG_MESSAGE, "WRONG_MESSAGE", "Wrong message" },
00154 { AST_CAUSE_IE_NONEXIST, "IE_NONEXIST", "Info. element nonexist or not implemented" },
00155 { AST_CAUSE_INVALID_IE_CONTENTS, "INVALID_IE_CONTENTS", "Invalid information element contents" },
00156 { AST_CAUSE_WRONG_CALL_STATE, "WRONG_CALL_STATE", "Message not compatible with call state" },
00157 { AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, "RECOVERY_ON_TIMER_EXPIRE", "Recover on timer expiry" },
00158 { AST_CAUSE_MANDATORY_IE_LENGTH_ERROR, "MANDATORY_IE_LENGTH_ERROR", "Mandatory IE length error" },
00159 { AST_CAUSE_PROTOCOL_ERROR, "PROTOCOL_ERROR", "Protocol error, unspecified" },
00160 { AST_CAUSE_INTERWORKING, "INTERWORKING", "Interworking, unspecified" },
00161 };
00162
00163 struct ast_variable *ast_channeltype_list(void)
00164 {
00165 struct chanlist *cl;
00166 struct ast_variable *var=NULL, *prev = NULL;
00167 AST_LIST_TRAVERSE(&backends, cl, list) {
00168 if (prev) {
00169 if ((prev->next = ast_variable_new(cl->tech->type, cl->tech->description)))
00170 prev = prev->next;
00171 } else {
00172 var = ast_variable_new(cl->tech->type, cl->tech->description);
00173 prev = var;
00174 }
00175 }
00176 return var;
00177 }
00178
00179 static int show_channeltypes(int fd, int argc, char *argv[])
00180 {
00181 #define FORMAT "%-10.10s %-40.40s %-12.12s %-12.12s %-12.12s\n"
00182 struct chanlist *cl;
00183 int count_chan = 0;
00184
00185 ast_cli(fd, FORMAT, "Type", "Description", "Devicestate", "Indications", "Transfer");
00186 ast_cli(fd, FORMAT, "----------", "-----------", "-----------", "-----------", "--------");
00187 if (AST_LIST_LOCK(&channels)) {
00188 ast_log(LOG_WARNING, "Unable to lock channel list\n");
00189 return -1;
00190 }
00191 AST_LIST_TRAVERSE(&backends, cl, list) {
00192 ast_cli(fd, FORMAT, cl->tech->type, cl->tech->description,
00193 (cl->tech->devicestate) ? "yes" : "no",
00194 (cl->tech->indicate) ? "yes" : "no",
00195 (cl->tech->transfer) ? "yes" : "no");
00196 count_chan++;
00197 }
00198 AST_LIST_UNLOCK(&channels);
00199 ast_cli(fd, "----------\n%d channel drivers registered.\n", count_chan);
00200 return RESULT_SUCCESS;
00201
00202 #undef FORMAT
00203
00204 }
00205
00206 static int show_channeltype_deprecated(int fd, int argc, char *argv[])
00207 {
00208 struct chanlist *cl = NULL;
00209
00210 if (argc != 3)
00211 return RESULT_SHOWUSAGE;
00212
00213 if (AST_LIST_LOCK(&channels)) {
00214 ast_log(LOG_WARNING, "Unable to lock channel list\n");
00215 return RESULT_FAILURE;
00216 }
00217
00218 AST_LIST_TRAVERSE(&backends, cl, list) {
00219 if (!strncasecmp(cl->tech->type, argv[2], strlen(cl->tech->type))) {
00220 break;
00221 }
00222 }
00223
00224
00225 if (!cl) {
00226 ast_cli(fd, "\n%s is not a registered channel driver.\n", argv[2]);
00227 AST_LIST_UNLOCK(&channels);
00228 return RESULT_FAILURE;
00229 }
00230
00231 ast_cli(fd,
00232 "-- Info about channel driver: %s --\n"
00233 " Device State: %s\n"
00234 " Indication: %s\n"
00235 " Transfer : %s\n"
00236 " Capabilities: %d\n"
00237 " Digit Begin: %s\n"
00238 " Digit End: %s\n"
00239 " Send HTML : %s\n"
00240 " Image Support: %s\n"
00241 " Text Support: %s\n",
00242 cl->tech->type,
00243 (cl->tech->devicestate) ? "yes" : "no",
00244 (cl->tech->indicate) ? "yes" : "no",
00245 (cl->tech->transfer) ? "yes" : "no",
00246 (cl->tech->capabilities) ? cl->tech->capabilities : -1,
00247 (cl->tech->send_digit_begin) ? "yes" : "no",
00248 (cl->tech->send_digit_end) ? "yes" : "no",
00249 (cl->tech->send_html) ? "yes" : "no",
00250 (cl->tech->send_image) ? "yes" : "no",
00251 (cl->tech->send_text) ? "yes" : "no"
00252
00253 );
00254
00255 AST_LIST_UNLOCK(&channels);
00256 return RESULT_SUCCESS;
00257 }
00258
00259 static int show_channeltype(int fd, int argc, char *argv[])
00260 {
00261 struct chanlist *cl = NULL;
00262
00263 if (argc != 4)
00264 return RESULT_SHOWUSAGE;
00265
00266 if (AST_LIST_LOCK(&channels)) {
00267 ast_log(LOG_WARNING, "Unable to lock channel list\n");
00268 return RESULT_FAILURE;
00269 }
00270
00271 AST_LIST_TRAVERSE(&backends, cl, list) {
00272 if (!strncasecmp(cl->tech->type, argv[3], strlen(cl->tech->type))) {
00273 break;
00274 }
00275 }
00276
00277
00278 if (!cl) {
00279 ast_cli(fd, "\n%s is not a registered channel driver.\n", argv[3]);
00280 AST_LIST_UNLOCK(&channels);
00281 return RESULT_FAILURE;
00282 }
00283
00284 ast_cli(fd,
00285 "-- Info about channel driver: %s --\n"
00286 " Device State: %s\n"
00287 " Indication: %s\n"
00288 " Transfer : %s\n"
00289 " Capabilities: %d\n"
00290 " Digit Begin: %s\n"
00291 " Digit End: %s\n"
00292 " Send HTML : %s\n"
00293 " Image Support: %s\n"
00294 " Text Support: %s\n",
00295 cl->tech->type,
00296 (cl->tech->devicestate) ? "yes" : "no",
00297 (cl->tech->indicate) ? "yes" : "no",
00298 (cl->tech->transfer) ? "yes" : "no",
00299 (cl->tech->capabilities) ? cl->tech->capabilities : -1,
00300 (cl->tech->send_digit_begin) ? "yes" : "no",
00301 (cl->tech->send_digit_end) ? "yes" : "no",
00302 (cl->tech->send_html) ? "yes" : "no",
00303 (cl->tech->send_image) ? "yes" : "no",
00304 (cl->tech->send_text) ? "yes" : "no"
00305
00306 );
00307
00308 AST_LIST_UNLOCK(&channels);
00309 return RESULT_SUCCESS;
00310 }
00311
00312 static char *complete_channeltypes_deprecated(const char *line, const char *word, int pos, int state)
00313 {
00314 struct chanlist *cl;
00315 int which = 0;
00316 int wordlen;
00317 char *ret = NULL;
00318
00319 if (pos != 2)
00320 return NULL;
00321
00322 wordlen = strlen(word);
00323
00324 AST_LIST_TRAVERSE(&backends, cl, list) {
00325 if (!strncasecmp(word, cl->tech->type, wordlen) && ++which > state) {
00326 ret = strdup(cl->tech->type);
00327 break;
00328 }
00329 }
00330
00331 return ret;
00332 }
00333
00334 static char *complete_channeltypes(const char *line, const char *word, int pos, int state)
00335 {
00336 struct chanlist *cl;
00337 int which = 0;
00338 int wordlen;
00339 char *ret = NULL;
00340
00341 if (pos != 3)
00342 return NULL;
00343
00344 wordlen = strlen(word);
00345
00346 AST_LIST_TRAVERSE(&backends, cl, list) {
00347 if (!strncasecmp(word, cl->tech->type, wordlen) && ++which > state) {
00348 ret = strdup(cl->tech->type);
00349 break;
00350 }
00351 }
00352
00353 return ret;
00354 }
00355
00356 static char show_channeltypes_usage[] =
00357 "Usage: core show channeltypes\n"
00358 " Lists available channel types registered in your Asterisk server.\n";
00359
00360 static char show_channeltype_usage[] =
00361 "Usage: core show channeltype <name>\n"
00362 " Show details about the specified channel type, <name>.\n";
00363
00364 static struct ast_cli_entry cli_show_channeltypes_deprecated = {
00365 { "show", "channeltypes", NULL },
00366 show_channeltypes, NULL,
00367 NULL };
00368
00369 static struct ast_cli_entry cli_show_channeltype_deprecated = {
00370 { "show", "channeltype", NULL },
00371 show_channeltype_deprecated, NULL,
00372 NULL, complete_channeltypes_deprecated };
00373
00374 static struct ast_cli_entry cli_channel[] = {
00375 { { "core", "show", "channeltypes", NULL },
00376 show_channeltypes, "List available channel types",
00377 show_channeltypes_usage, NULL, &cli_show_channeltypes_deprecated },
00378
00379 { { "core", "show", "channeltype", NULL },
00380 show_channeltype, "Give more details on that channel type",
00381 show_channeltype_usage, complete_channeltypes, &cli_show_channeltype_deprecated },
00382 };
00383
00384
00385 int ast_check_hangup(struct ast_channel *chan)
00386 {
00387 if (chan->_softhangup)
00388 return 1;
00389 if (!chan->tech_pvt)
00390 return 1;
00391 if (!chan->whentohangup)
00392 return 0;
00393 if (chan->whentohangup > time(NULL))
00394 return 0;
00395 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
00396 return 1;
00397 }
00398
00399 static int ast_check_hangup_locked(struct ast_channel *chan)
00400 {
00401 int res;
00402 ast_channel_lock(chan);
00403 res = ast_check_hangup(chan);
00404 ast_channel_unlock(chan);
00405 return res;
00406 }
00407
00408
00409 char *ast_safe_string_alloc(const char *fmt, ...)
00410 {
00411 char *b2, buf[1];
00412 int len;
00413 va_list args;
00414
00415 va_start(args, fmt);
00416 len = vsnprintf(buf, 1, fmt, args);
00417 va_end(args);
00418
00419 if (!(b2 = ast_malloc(len + 1)))
00420 return NULL;
00421
00422 va_start(args, fmt);
00423 vsnprintf(b2, len + 1, fmt, args);
00424 va_end(args);
00425
00426 return b2;
00427 }
00428
00429
00430 void ast_begin_shutdown(int hangup)
00431 {
00432 struct ast_channel *c;
00433 shutting_down = 1;
00434 if (hangup) {
00435 AST_LIST_LOCK(&channels);
00436 AST_LIST_TRAVERSE(&channels, c, chan_list)
00437 ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN);
00438 AST_LIST_UNLOCK(&channels);
00439 }
00440 }
00441
00442
00443 int ast_active_channels(void)
00444 {
00445 struct ast_channel *c;
00446 int cnt = 0;
00447 AST_LIST_LOCK(&channels);
00448 AST_LIST_TRAVERSE(&channels, c, chan_list)
00449 cnt++;
00450 AST_LIST_UNLOCK(&channels);
00451 return cnt;
00452 }
00453
00454
00455 void ast_cancel_shutdown(void)
00456 {
00457 shutting_down = 0;
00458 }
00459
00460
00461 int ast_shutting_down(void)
00462 {
00463 return shutting_down;
00464 }
00465
00466
00467 void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset)
00468 {
00469 chan->whentohangup = offset ? time(NULL) + offset : 0;
00470 ast_queue_frame(chan, &ast_null_frame);
00471 return;
00472 }
00473
00474
00475 int ast_channel_cmpwhentohangup(struct ast_channel *chan, time_t offset)
00476 {
00477 time_t whentohangup;
00478
00479 if (chan->whentohangup == 0) {
00480 return (offset == 0) ? 0 : -1;
00481 } else {
00482 if (offset == 0)
00483 return (1);
00484 else {
00485 whentohangup = offset + time (NULL);
00486 if (chan->whentohangup < whentohangup)
00487 return (1);
00488 else if (chan->whentohangup == whentohangup)
00489 return (0);
00490 else
00491 return (-1);
00492 }
00493 }
00494 }
00495
00496
00497 int ast_channel_register(const struct ast_channel_tech *tech)
00498 {
00499 struct chanlist *chan;
00500
00501 AST_LIST_LOCK(&channels);
00502
00503 AST_LIST_TRAVERSE(&backends, chan, list) {
00504 if (!strcasecmp(tech->type, chan->tech->type)) {
00505 ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type);
00506 AST_LIST_UNLOCK(&channels);
00507 return -1;
00508 }
00509 }
00510
00511 if (!(chan = ast_calloc(1, sizeof(*chan)))) {
00512 AST_LIST_UNLOCK(&channels);
00513 return -1;
00514 }
00515 chan->tech = tech;
00516 AST_LIST_INSERT_HEAD(&backends, chan, list);
00517
00518 if (option_debug)
00519 ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description);
00520
00521 if (option_verbose > 1)
00522 ast_verbose(VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->tech->type,
00523 chan->tech->description);
00524
00525 AST_LIST_UNLOCK(&channels);
00526 return 0;
00527 }
00528
00529 void ast_channel_unregister(const struct ast_channel_tech *tech)
00530 {
00531 struct chanlist *chan;
00532
00533 if (option_debug)
00534 ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", tech->type);
00535
00536 AST_LIST_LOCK(&channels);
00537
00538 AST_LIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) {
00539 if (chan->tech == tech) {
00540 AST_LIST_REMOVE_CURRENT(&backends, list);
00541 free(chan);
00542 if (option_verbose > 1)
00543 ast_verbose(VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", tech->type);
00544 break;
00545 }
00546 }
00547 AST_LIST_TRAVERSE_SAFE_END
00548
00549 AST_LIST_UNLOCK(&channels);
00550 }
00551
00552 const struct ast_channel_tech *ast_get_channel_tech(const char *name)
00553 {
00554 struct chanlist *chanls;
00555 const struct ast_channel_tech *ret = NULL;
00556
00557 if (AST_LIST_LOCK(&channels)) {
00558 ast_log(LOG_WARNING, "Unable to lock channel tech list\n");
00559 return NULL;
00560 }
00561
00562 AST_LIST_TRAVERSE(&backends, chanls, list) {
00563 if (!strcasecmp(name, chanls->tech->type)) {
00564 ret = chanls->tech;
00565 break;
00566 }
00567 }
00568
00569 AST_LIST_UNLOCK(&channels);
00570
00571 return ret;
00572 }
00573
00574
00575 const char *ast_cause2str(int cause)
00576 {
00577 int x;
00578
00579 for (x=0; x < sizeof(causes) / sizeof(causes[0]); x++) {
00580 if (causes[x].cause == cause)
00581 return causes[x].desc;
00582 }
00583
00584 return "Unknown";
00585 }
00586
00587
00588 int ast_str2cause(const char *name)
00589 {
00590 int x;
00591
00592 for (x = 0; x < sizeof(causes) / sizeof(causes[0]); x++)
00593 if (strncasecmp(causes[x].name, name, strlen(causes[x].name)) == 0)
00594 return causes[x].cause;
00595
00596 return -1;
00597 }
00598
00599
00600 char *ast_state2str(enum ast_channel_state state)
00601 {
00602 char *buf;
00603
00604 switch(state) {
00605 case AST_STATE_DOWN:
00606 return "Down";
00607 case AST_STATE_RESERVED:
00608 return "Rsrvd";
00609 case AST_STATE_OFFHOOK:
00610 return "OffHook";
00611 case AST_STATE_DIALING:
00612 return "Dialing";
00613 case AST_STATE_RING:
00614 return "Ring";
00615 case AST_STATE_RINGING:
00616 return "Ringing";
00617 case AST_STATE_UP:
00618 return "Up";
00619 case AST_STATE_BUSY:
00620 return "Busy";
00621 case AST_STATE_DIALING_OFFHOOK:
00622 return "Dialing Offhook";
00623 case AST_STATE_PRERING:
00624 return "Pre-ring";
00625 default:
00626 if (!(buf = ast_threadstorage_get(&state2str_threadbuf, STATE2STR_BUFSIZE)))
00627 return "Unknown";
00628 snprintf(buf, STATE2STR_BUFSIZE, "Unknown (%d)", state);
00629 return buf;
00630 }
00631 }
00632
00633
00634 char *ast_transfercapability2str(int transfercapability)
00635 {
00636 switch(transfercapability) {
00637 case AST_TRANS_CAP_SPEECH:
00638 return "SPEECH";
00639 case AST_TRANS_CAP_DIGITAL:
00640 return "DIGITAL";
00641 case AST_TRANS_CAP_RESTRICTED_DIGITAL:
00642 return "RESTRICTED_DIGITAL";
00643 case AST_TRANS_CAP_3_1K_AUDIO:
00644 return "3K1AUDIO";
00645 case AST_TRANS_CAP_DIGITAL_W_TONES:
00646 return "DIGITAL_W_TONES";
00647 case AST_TRANS_CAP_VIDEO:
00648 return "VIDEO";
00649 default:
00650 return "UNKNOWN";
00651 }
00652 }
00653
00654
00655 int ast_best_codec(int fmts)
00656 {
00657
00658
00659 int x;
00660 static int prefs[] =
00661 {
00662
00663 AST_FORMAT_ULAW,
00664
00665 AST_FORMAT_ALAW,
00666
00667 AST_FORMAT_G722,
00668
00669 AST_FORMAT_SLINEAR,
00670
00671 AST_FORMAT_G726,
00672
00673 AST_FORMAT_G726_AAL2,
00674
00675 AST_FORMAT_ADPCM,
00676
00677
00678 AST_FORMAT_GSM,
00679
00680 AST_FORMAT_ILBC,
00681
00682 AST_FORMAT_SPEEX,
00683
00684
00685 AST_FORMAT_LPC10,
00686
00687 AST_FORMAT_G729A,
00688
00689 AST_FORMAT_G723_1,
00690 };
00691
00692
00693 fmts &= AST_FORMAT_AUDIO_MASK;
00694
00695
00696 for (x=0; x < (sizeof(prefs) / sizeof(prefs[0]) ); x++)
00697 if (fmts & prefs[x])
00698 return prefs[x];
00699 ast_log(LOG_WARNING, "Don't know any of 0x%x formats\n", fmts);
00700 return 0;
00701 }
00702
00703 static const struct ast_channel_tech null_tech = {
00704 .type = "NULL",
00705 .description = "Null channel (should not see this)",
00706 };
00707
00708
00709 struct ast_channel *ast_channel_alloc(int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const int amaflag, const char *name_fmt, ...)
00710 {
00711 struct ast_channel *tmp;
00712 int x;
00713 int flags;
00714 struct varshead *headp;
00715 va_list ap1, ap2;
00716
00717
00718 if (shutting_down) {
00719 ast_log(LOG_WARNING, "Channel allocation failed: Refusing due to active shutdown\n");
00720 return NULL;
00721 }
00722
00723 if (!(tmp = ast_calloc(1, sizeof(*tmp))))
00724 return NULL;
00725
00726 if (!(tmp->sched = sched_context_create())) {
00727 ast_log(LOG_WARNING, "Channel allocation failed: Unable to create schedule context\n");
00728 free(tmp);
00729 return NULL;
00730 }
00731
00732 if ((ast_string_field_init(tmp, 128))) {
00733 sched_context_destroy(tmp->sched);
00734 free(tmp);
00735 return NULL;
00736 }
00737
00738
00739
00740
00741 for (x = 0; x < AST_MAX_FDS - 2; x++)
00742 tmp->fds[x] = -1;
00743
00744 #ifdef HAVE_DAHDI
00745
00746 tmp->timingfd = open(DAHDI_FILE_TIMER, O_RDWR);
00747
00748 if (tmp->timingfd > -1) {
00749
00750
00751 flags = 1;
00752 if (!ioctl(tmp->timingfd, DAHDI_TIMERPONG, &flags))
00753 needqueue = 0;
00754 }
00755 #else
00756 tmp->timingfd = -1;
00757 #endif
00758
00759 if (needqueue) {
00760 if (pipe(tmp->alertpipe)) {
00761 ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe!\n");
00762 alertpipe_failed:
00763 #ifdef HAVE_DAHDI
00764 if (tmp->timingfd > -1)
00765 close(tmp->timingfd);
00766 #endif
00767 sched_context_destroy(tmp->sched);
00768 ast_string_field_free_memory(tmp);
00769 free(tmp);
00770 return NULL;
00771 } else {
00772 flags = fcntl(tmp->alertpipe[0], F_GETFL);
00773 if (fcntl(tmp->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) {
00774 ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
00775 close(tmp->alertpipe[0]);
00776 close(tmp->alertpipe[1]);
00777 goto alertpipe_failed;
00778 }
00779 flags = fcntl(tmp->alertpipe[1], F_GETFL);
00780 if (fcntl(tmp->alertpipe[1], F_SETFL, flags | O_NONBLOCK) < 0) {
00781 ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
00782 close(tmp->alertpipe[0]);
00783 close(tmp->alertpipe[1]);
00784 goto alertpipe_failed;
00785 }
00786 }
00787 } else
00788 tmp->alertpipe[0] = tmp->alertpipe[1] = -1;
00789
00790
00791 tmp->fds[AST_ALERT_FD] = tmp->alertpipe[0];
00792
00793 tmp->fds[AST_TIMING_FD] = tmp->timingfd;
00794 ast_string_field_set(tmp, name, "**Unknown**");
00795
00796
00797 tmp->_state = state;
00798
00799 tmp->streamid = -1;
00800
00801 tmp->fin = global_fin;
00802 tmp->fout = global_fout;
00803
00804 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) {
00805 ast_string_field_build(tmp, uniqueid, "%li.%d", (long) time(NULL),
00806 ast_atomic_fetchadd_int(&uniqueint, 1));
00807 } else {
00808 ast_string_field_build(tmp, uniqueid, "%s-%li.%d", ast_config_AST_SYSTEM_NAME,
00809 (long) time(NULL), ast_atomic_fetchadd_int(&uniqueint, 1));
00810 }
00811
00812 tmp->cid.cid_name = ast_strdup(cid_name);
00813 tmp->cid.cid_num = ast_strdup(cid_num);
00814
00815 if (!ast_strlen_zero(name_fmt)) {
00816
00817
00818
00819
00820
00821
00822
00823 va_start(ap1, name_fmt);
00824 va_start(ap2, name_fmt);
00825 ast_string_field_build_va(tmp, name, name_fmt, ap1, ap2);
00826 va_end(ap1);
00827 va_end(ap2);
00828 }
00829
00830
00831
00832
00833 if (amaflag)
00834 tmp->amaflags = amaflag;
00835 else
00836 tmp->amaflags = ast_default_amaflags;
00837
00838 if (!ast_strlen_zero(acctcode))
00839 ast_string_field_set(tmp, accountcode, acctcode);
00840 else
00841 ast_string_field_set(tmp, accountcode, ast_default_accountcode);
00842
00843 if (!ast_strlen_zero(context))
00844 ast_copy_string(tmp->context, context, sizeof(tmp->context));
00845 else
00846 strcpy(tmp->context, "default");
00847
00848 if (!ast_strlen_zero(exten))
00849 ast_copy_string(tmp->exten, exten, sizeof(tmp->exten));
00850 else
00851 strcpy(tmp->exten, "s");
00852
00853 tmp->priority = 1;
00854
00855 tmp->cdr = ast_cdr_alloc();
00856 ast_cdr_init(tmp->cdr, tmp);
00857 ast_cdr_start(tmp->cdr);
00858
00859 headp = &tmp->varshead;
00860 AST_LIST_HEAD_INIT_NOLOCK(headp);
00861
00862 ast_mutex_init(&tmp->lock);
00863
00864 AST_LIST_HEAD_INIT_NOLOCK(&tmp->datastores);
00865
00866 ast_string_field_set(tmp, language, defaultlanguage);
00867
00868 tmp->tech = &null_tech;
00869
00870 AST_LIST_LOCK(&channels);
00871 AST_LIST_INSERT_HEAD(&channels, tmp, chan_list);
00872 AST_LIST_UNLOCK(&channels);
00873
00874
00875
00876
00877
00878
00879
00880 if (!ast_strlen_zero(name_fmt)) {
00881 manager_event(EVENT_FLAG_CALL, "Newchannel",
00882 "Channel: %s\r\n"
00883 "State: %s\r\n"
00884 "CallerIDNum: %s\r\n"
00885 "CallerIDName: %s\r\n"
00886 "Uniqueid: %s\r\n",
00887 tmp->name, ast_state2str(state),
00888 S_OR(cid_num, "<unknown>"),
00889 S_OR(cid_name, "<unknown>"),
00890 tmp->uniqueid);
00891 }
00892
00893 return tmp;
00894 }
00895
00896
00897 static int __ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin, int head)
00898 {
00899 struct ast_frame *f;
00900 struct ast_frame *cur;
00901 int blah = 1;
00902 int qlen = 0;
00903
00904
00905 if (!(f = ast_frdup(fin))) {
00906 return -1;
00907 }
00908
00909 ast_channel_lock(chan);
00910
00911
00912 if ((cur = AST_LIST_LAST(&chan->readq)) && (cur->frametype == AST_FRAME_CONTROL) && (cur->subclass == AST_CONTROL_HANGUP)) {
00913 ast_frfree(f);
00914 ast_channel_unlock(chan);
00915 return 0;
00916 }
00917
00918
00919 AST_LIST_TRAVERSE(&chan->readq, cur, frame_list) {
00920 qlen++;
00921 }
00922
00923
00924 if (((fin->frametype == AST_FRAME_VOICE) && (qlen > 96)) || (qlen > 128)) {
00925 if (fin->frametype != AST_FRAME_VOICE) {
00926 ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name);
00927 ast_assert(fin->frametype == AST_FRAME_VOICE);
00928 } else {
00929 if (option_debug)
00930 ast_log(LOG_DEBUG, "Dropping voice to exceptionally long queue on %s\n", chan->name);
00931 ast_frfree(f);
00932 ast_channel_unlock(chan);
00933 return 0;
00934 }
00935 }
00936
00937 if (head) {
00938 AST_LIST_INSERT_HEAD(&chan->readq, f, frame_list);
00939 } else {
00940 AST_LIST_INSERT_TAIL(&chan->readq, f, frame_list);
00941 }
00942
00943 if (chan->alertpipe[1] > -1) {
00944 if (write(chan->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah)) {
00945 ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d (qlen = %d): %s!\n",
00946 chan->name, f->frametype, f->subclass, qlen, strerror(errno));
00947 }
00948 #ifdef HAVE_DAHDI
00949 } else if (chan->timingfd > -1) {
00950 ioctl(chan->timingfd, DAHDI_TIMERPING, &blah);
00951 #endif
00952 } else if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
00953 pthread_kill(chan->blocker, SIGURG);
00954 }
00955
00956 ast_channel_unlock(chan);
00957
00958 return 0;
00959 }
00960
00961 int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin)
00962 {
00963 return __ast_queue_frame(chan, fin, 0);
00964 }
00965
00966 int ast_queue_frame_head(struct ast_channel *chan, struct ast_frame *fin)
00967 {
00968 return __ast_queue_frame(chan, fin, 1);
00969 }
00970
00971
00972 int ast_queue_hangup(struct ast_channel *chan)
00973 {
00974 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
00975
00976 if (!ast_channel_trylock(chan)) {
00977 chan->_softhangup |= AST_SOFTHANGUP_DEV;
00978 ast_channel_unlock(chan);
00979 }
00980 return ast_queue_frame(chan, &f);
00981 }
00982
00983
00984 int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
00985 {
00986 struct ast_frame f = { AST_FRAME_CONTROL, };
00987
00988 f.subclass = control;
00989
00990 return ast_queue_frame(chan, &f);
00991 }
00992
00993
00994 int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control,
00995 const void *data, size_t datalen)
00996 {
00997 struct ast_frame f = { AST_FRAME_CONTROL, };
00998
00999 f.subclass = control;
01000 f.data = (void *) data;
01001 f.datalen = datalen;
01002
01003 return ast_queue_frame(chan, &f);
01004 }
01005
01006
01007 int ast_channel_defer_dtmf(struct ast_channel *chan)
01008 {
01009 int pre = 0;
01010
01011 if (chan) {
01012 pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF);
01013 ast_set_flag(chan, AST_FLAG_DEFER_DTMF);
01014 }
01015 return pre;
01016 }
01017
01018
01019 void ast_channel_undefer_dtmf(struct ast_channel *chan)
01020 {
01021 if (chan)
01022 ast_clear_flag(chan, AST_FLAG_DEFER_DTMF);
01023 }
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049 static struct ast_channel *channel_find_locked(const struct ast_channel *prev,
01050 const char *name, const int namelen,
01051 const char *context, const char *exten)
01052 {
01053 const char *msg = prev ? "deadlock" : "initial deadlock";
01054 int retries;
01055 struct ast_channel *c;
01056 const struct ast_channel *_prev = prev;
01057
01058 for (retries = 0; retries < 200; retries++) {
01059 int done;
01060
01061 prev = _prev;
01062 AST_LIST_LOCK(&channels);
01063 AST_LIST_TRAVERSE(&channels, c, chan_list) {
01064 if (prev) {
01065 if (c != prev)
01066 continue;
01067
01068 if ((c = AST_LIST_NEXT(c, chan_list)) == NULL) break;
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080 prev = NULL;
01081 }
01082 if (name) {
01083 if ((!namelen && strcasecmp(c->name, name)) ||
01084 (namelen && strncasecmp(c->name, name, namelen)))
01085 continue;
01086 } else if (exten) {
01087 if (context && strcasecmp(c->context, context) &&
01088 strcasecmp(c->macrocontext, context))
01089 continue;
01090 if (strcasecmp(c->exten, exten) &&
01091 strcasecmp(c->macroexten, exten))
01092 continue;
01093 }
01094
01095 break;
01096 }
01097
01098
01099 done = c == NULL || ast_channel_trylock(c) == 0;
01100 if (!done) {
01101 if (option_debug)
01102 ast_log(LOG_DEBUG, "Avoiding %s for channel '%p'\n", msg, c);
01103 if (retries == 199) {
01104
01105
01106
01107 if (option_debug)
01108 ast_log(LOG_DEBUG, "Failure, could not lock '%p' after %d retries!\n", c, retries);
01109
01110
01111
01112
01113
01114 if (!(name && !namelen)) {
01115 prev = c;
01116 retries = -1;
01117 }
01118 }
01119 }
01120 AST_LIST_UNLOCK(&channels);
01121 if (done)
01122 return c;
01123
01124
01125
01126
01127 prev = _prev;
01128 usleep(1);
01129 }
01130
01131 return NULL;
01132 }
01133
01134
01135 struct ast_channel *ast_channel_walk_locked(const struct ast_channel *prev)
01136 {
01137 return channel_find_locked(prev, NULL, 0, NULL, NULL);
01138 }
01139
01140
01141 struct ast_channel *ast_get_channel_by_name_locked(const char *name)
01142 {
01143 return channel_find_locked(NULL, name, 0, NULL, NULL);
01144 }
01145
01146
01147 struct ast_channel *ast_get_channel_by_name_prefix_locked(const char *name, const int namelen)
01148 {
01149 return channel_find_locked(NULL, name, namelen, NULL, NULL);
01150 }
01151
01152
01153 struct ast_channel *ast_walk_channel_by_name_prefix_locked(const struct ast_channel *chan, const char *name,
01154 const int namelen)
01155 {
01156 return channel_find_locked(chan, name, namelen, NULL, NULL);
01157 }
01158
01159
01160 struct ast_channel *ast_get_channel_by_exten_locked(const char *exten, const char *context)
01161 {
01162 return channel_find_locked(NULL, NULL, 0, context, exten);
01163 }
01164
01165
01166 struct ast_channel *ast_walk_channel_by_exten_locked(const struct ast_channel *chan, const char *exten,
01167 const char *context)
01168 {
01169 return channel_find_locked(chan, NULL, 0, context, exten);
01170 }
01171
01172
01173 int ast_safe_sleep_conditional(struct ast_channel *chan, int ms, int (*cond)(void*), void *data)
01174 {
01175 struct ast_frame *f;
01176
01177 while (ms > 0) {
01178 if (cond && ((*cond)(data) == 0))
01179 return 0;
01180 ms = ast_waitfor(chan, ms);
01181 if (ms < 0)
01182 return -1;
01183 if (ms > 0) {
01184 f = ast_read(chan);
01185 if (!f)
01186 return -1;
01187 ast_frfree(f);
01188 }
01189 }
01190 return 0;
01191 }
01192
01193
01194 int ast_safe_sleep(struct ast_channel *chan, int ms)
01195 {
01196 return ast_safe_sleep_conditional(chan, ms, NULL, NULL);
01197 }
01198
01199 static void free_cid(struct ast_callerid *cid)
01200 {
01201 if (cid->cid_dnid)
01202 free(cid->cid_dnid);
01203 if (cid->cid_num)
01204 free(cid->cid_num);
01205 if (cid->cid_name)
01206 free(cid->cid_name);
01207 if (cid->cid_ani)
01208 free(cid->cid_ani);
01209 if (cid->cid_rdnis)
01210 free(cid->cid_rdnis);
01211 }
01212
01213
01214 void ast_channel_free(struct ast_channel *chan)
01215 {
01216 int fd;
01217 struct ast_var_t *vardata;
01218 struct ast_frame *f;
01219 struct varshead *headp;
01220 struct ast_datastore *datastore = NULL;
01221 char name[AST_CHANNEL_NAME], *dashptr;
01222
01223 headp=&chan->varshead;
01224
01225 AST_LIST_LOCK(&channels);
01226 if (!AST_LIST_REMOVE(&channels, chan, chan_list)) {
01227 AST_LIST_UNLOCK(&channels);
01228 ast_log(LOG_ERROR, "Unable to find channel in list to free. Assuming it has already been done.\n");
01229 }
01230
01231
01232 ast_channel_lock(chan);
01233 ast_channel_unlock(chan);
01234
01235
01236 while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry)))
01237
01238 ast_channel_datastore_free(datastore);
01239
01240
01241
01242 ast_channel_lock(chan);
01243 ast_channel_unlock(chan);
01244
01245 if (chan->tech_pvt) {
01246 ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
01247 free(chan->tech_pvt);
01248 }
01249
01250 if (chan->sched)
01251 sched_context_destroy(chan->sched);
01252
01253 ast_copy_string(name, chan->name, sizeof(name));
01254 if ((dashptr = strrchr(name, '-'))) {
01255 *dashptr = '\0';
01256 }
01257
01258
01259 if (chan->monitor)
01260 chan->monitor->stop( chan, 0 );
01261
01262
01263 if (chan->music_state)
01264 ast_moh_cleanup(chan);
01265
01266
01267 if (chan->readtrans)
01268 ast_translator_free_path(chan->readtrans);
01269 if (chan->writetrans)
01270 ast_translator_free_path(chan->writetrans);
01271 if (chan->pbx)
01272 ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
01273 free_cid(&chan->cid);
01274
01275 if ((fd = chan->alertpipe[0]) > -1)
01276 close(fd);
01277 if ((fd = chan->alertpipe[1]) > -1)
01278 close(fd);
01279 if ((fd = chan->timingfd) > -1)
01280 close(fd);
01281 while ((f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list)))
01282 ast_frfree(f);
01283
01284
01285
01286
01287 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
01288 ast_var_delete(vardata);
01289
01290 ast_app_group_discard(chan);
01291
01292
01293 ast_jb_destroy(chan);
01294
01295 if (chan->cdr) {
01296 ast_cdr_discard(chan->cdr);
01297 chan->cdr = NULL;
01298 }
01299
01300 ast_mutex_destroy(&chan->lock);
01301
01302 ast_string_field_free_memory(chan);
01303 free(chan);
01304 AST_LIST_UNLOCK(&channels);
01305
01306 ast_device_state_changed_literal(name);
01307 }
01308
01309 struct ast_datastore *ast_channel_datastore_alloc(const struct ast_datastore_info *info, char *uid)
01310 {
01311 struct ast_datastore *datastore = NULL;
01312
01313
01314 if (info == NULL) {
01315 return NULL;
01316 }
01317
01318
01319 datastore = ast_calloc(1, sizeof(*datastore));
01320 if (datastore == NULL) {
01321 return NULL;
01322 }
01323
01324 datastore->info = info;
01325
01326 datastore->uid = ast_strdup(uid);
01327
01328 return datastore;
01329 }
01330
01331 int ast_channel_datastore_free(struct ast_datastore *datastore)
01332 {
01333 int res = 0;
01334
01335
01336 if (datastore->info->destroy != NULL && datastore->data != NULL) {
01337 datastore->info->destroy(datastore->data);
01338 datastore->data = NULL;
01339 }
01340
01341
01342 if (datastore->uid != NULL) {
01343 free(datastore->uid);
01344 datastore->uid = NULL;
01345 }
01346
01347
01348 free(datastore);
01349
01350 return res;
01351 }
01352
01353 int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel *to)
01354 {
01355 struct ast_datastore *datastore = NULL, *datastore2;
01356
01357 AST_LIST_TRAVERSE(&from->datastores, datastore, entry) {
01358 if (datastore->inheritance > 0) {
01359 datastore2 = ast_channel_datastore_alloc(datastore->info, datastore->uid);
01360 if (datastore2) {
01361 datastore2->data = datastore->info->duplicate ? datastore->info->duplicate(datastore->data) : NULL;
01362 datastore2->inheritance = datastore->inheritance == DATASTORE_INHERIT_FOREVER ? DATASTORE_INHERIT_FOREVER : datastore->inheritance - 1;
01363 AST_LIST_INSERT_TAIL(&to->datastores, datastore2, entry);
01364 }
01365 }
01366 }
01367 return 0;
01368 }
01369
01370 int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
01371 {
01372 int res = 0;
01373
01374 AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry);
01375
01376 return res;
01377 }
01378
01379 int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
01380 {
01381 struct ast_datastore *datastore2 = NULL;
01382 int res = -1;
01383
01384
01385 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore2, entry) {
01386 if (datastore2 == datastore) {
01387 AST_LIST_REMOVE_CURRENT(&chan->datastores, entry);
01388 res = 0;
01389 break;
01390 }
01391 }
01392 AST_LIST_TRAVERSE_SAFE_END
01393
01394 return res;
01395 }
01396
01397 struct ast_datastore *ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, char *uid)
01398 {
01399 struct ast_datastore *datastore = NULL;
01400
01401 if (info == NULL)
01402 return NULL;
01403
01404 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore, entry) {
01405 if (datastore->info == info) {
01406 if (uid != NULL && datastore->uid != NULL) {
01407 if (!strcasecmp(uid, datastore->uid)) {
01408
01409 break;
01410 }
01411 } else {
01412
01413 break;
01414 }
01415 }
01416 }
01417 AST_LIST_TRAVERSE_SAFE_END
01418
01419 return datastore;
01420 }
01421
01422
01423 int ast_softhangup_nolock(struct ast_channel *chan, int cause)
01424 {
01425 if (option_debug)
01426 ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name);
01427
01428 chan->_softhangup |= cause;
01429 ast_queue_frame(chan, &ast_null_frame);
01430
01431 if (ast_test_flag(chan, AST_FLAG_BLOCKING))
01432 pthread_kill(chan->blocker, SIGURG);
01433 return 0;
01434 }
01435
01436
01437 int ast_softhangup(struct ast_channel *chan, int cause)
01438 {
01439 int res;
01440 ast_channel_lock(chan);
01441 res = ast_softhangup_nolock(chan, cause);
01442 ast_channel_unlock(chan);
01443 return res;
01444 }
01445
01446 static void free_translation(struct ast_channel *clone)
01447 {
01448 if (clone->writetrans)
01449 ast_translator_free_path(clone->writetrans);
01450 if (clone->readtrans)
01451 ast_translator_free_path(clone->readtrans);
01452 clone->writetrans = NULL;
01453 clone->readtrans = NULL;
01454 clone->rawwriteformat = clone->nativeformats;
01455 clone->rawreadformat = clone->nativeformats;
01456 }
01457
01458
01459 int ast_hangup(struct ast_channel *chan)
01460 {
01461 int res = 0;
01462
01463
01464
01465 ast_channel_lock(chan);
01466
01467 if (chan->audiohooks) {
01468 ast_audiohook_detach_list(chan->audiohooks);
01469 chan->audiohooks = NULL;
01470 }
01471
01472 ast_autoservice_stop(chan);
01473
01474 if (chan->masq) {
01475 if (ast_do_masquerade(chan))
01476 ast_log(LOG_WARNING, "Failed to perform masquerade\n");
01477 }
01478
01479 if (chan->masq) {
01480 ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name);
01481 ast_channel_unlock(chan);
01482 return 0;
01483 }
01484
01485
01486 if (chan->masqr) {
01487 ast_set_flag(chan, AST_FLAG_ZOMBIE);
01488 ast_channel_unlock(chan);
01489 return 0;
01490 }
01491 free_translation(chan);
01492
01493 if (chan->stream) {
01494 ast_closestream(chan->stream);
01495 chan->stream = NULL;
01496 }
01497
01498 if (chan->vstream) {
01499 ast_closestream(chan->vstream);
01500 chan->vstream = NULL;
01501 }
01502 if (chan->sched) {
01503 sched_context_destroy(chan->sched);
01504 chan->sched = NULL;
01505 }
01506
01507 if (chan->generatordata)
01508 chan->generator->release(chan, chan->generatordata);
01509 chan->generatordata = NULL;
01510 chan->generator = NULL;
01511 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
01512 ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
01513 "is blocked by thread %ld in procedure %s! Expect a failure\n",
01514 (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc);
01515 ast_assert(ast_test_flag(chan, AST_FLAG_BLOCKING) == 0);
01516 }
01517 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) {
01518 if (option_debug)
01519 ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name);
01520 if (chan->tech->hangup)
01521 res = chan->tech->hangup(chan);
01522 } else {
01523 if (option_debug)
01524 ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name);
01525 }
01526
01527 ast_channel_unlock(chan);
01528 manager_event(EVENT_FLAG_CALL, "Hangup",
01529 "Channel: %s\r\n"
01530 "Uniqueid: %s\r\n"
01531 "Cause: %d\r\n"
01532 "Cause-txt: %s\r\n",
01533 chan->name,
01534 chan->uniqueid,
01535 chan->hangupcause,
01536 ast_cause2str(chan->hangupcause)
01537 );
01538
01539 if (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_BRIDGED) &&
01540 !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED) &&
01541 (chan->cdr->disposition != AST_CDR_NULL || ast_test_flag(chan->cdr, AST_CDR_FLAG_DIALED))) {
01542
01543 ast_cdr_end(chan->cdr);
01544 ast_cdr_detach(chan->cdr);
01545 chan->cdr = NULL;
01546 }
01547
01548 ast_channel_free(chan);
01549
01550 return res;
01551 }
01552
01553 int ast_answer(struct ast_channel *chan)
01554 {
01555 int res = 0;
01556 ast_channel_lock(chan);
01557
01558 if (ast_test_flag(chan, AST_FLAG_OUTGOING)) {
01559 ast_channel_unlock(chan);
01560 return 0;
01561 }
01562
01563 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
01564 ast_channel_unlock(chan);
01565 return -1;
01566 }
01567 switch(chan->_state) {
01568 case AST_STATE_RINGING:
01569 case AST_STATE_RING:
01570 if (chan->tech->answer)
01571 res = chan->tech->answer(chan);
01572 ast_setstate(chan, AST_STATE_UP);
01573 ast_cdr_answer(chan->cdr);
01574 break;
01575 case AST_STATE_UP:
01576 break;
01577 default:
01578 break;
01579 }
01580 ast_indicate(chan, -1);
01581 chan->visible_indication = 0;
01582 ast_channel_unlock(chan);
01583 return res;
01584 }
01585
01586 void ast_deactivate_generator(struct ast_channel *chan)
01587 {
01588 ast_channel_lock(chan);
01589 if (chan->generatordata) {
01590 if (chan->generator && chan->generator->release)
01591 chan->generator->release(chan, chan->generatordata);
01592 chan->generatordata = NULL;
01593 chan->generator = NULL;
01594 chan->fds[AST_GENERATOR_FD] = -1;
01595 ast_clear_flag(chan, AST_FLAG_WRITE_INT);
01596 ast_settimeout(chan, 0, NULL, NULL);
01597 }
01598 ast_channel_unlock(chan);
01599 }
01600
01601 static int generator_force(const void *data)
01602 {
01603
01604 void *tmp;
01605 int res;
01606 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = NULL;
01607 struct ast_channel *chan = (struct ast_channel *)data;
01608
01609 ast_channel_lock(chan);
01610 tmp = chan->generatordata;
01611 chan->generatordata = NULL;
01612 if (chan->generator)
01613 generate = chan->generator->generate;
01614 ast_channel_unlock(chan);
01615
01616 if (!tmp || !generate)
01617 return 0;
01618
01619 res = generate(chan, tmp, 0, ast_format_rate(chan->writeformat & AST_FORMAT_AUDIO_MASK) / 50);
01620
01621 chan->generatordata = tmp;
01622
01623 if (res) {
01624 if (option_debug)
01625 ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
01626 ast_deactivate_generator(chan);
01627 }
01628
01629 return 0;
01630 }
01631
01632 int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, void *params)
01633 {
01634 int res = 0;
01635
01636 ast_channel_lock(chan);
01637
01638 if (chan->generatordata) {
01639 if (chan->generator && chan->generator->release)
01640 chan->generator->release(chan, chan->generatordata);
01641 chan->generatordata = NULL;
01642 }
01643
01644 ast_prod(chan);
01645 if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) {
01646 res = -1;
01647 }
01648
01649 if (!res) {
01650 ast_settimeout(chan, 160, generator_force, chan);
01651 chan->generator = gen;
01652 }
01653
01654 ast_channel_unlock(chan);
01655
01656 return res;
01657 }
01658
01659
01660 int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception)
01661 {
01662 int winner = -1;
01663 ast_waitfor_nandfds(NULL, 0, fds, n, exception, &winner, ms);
01664 return winner;
01665 }
01666
01667
01668 struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds, int nfds,
01669 int *exception, int *outfd, int *ms)
01670 {
01671 struct timeval start = { 0 , 0 };
01672 struct pollfd *pfds = NULL;
01673 int res;
01674 long rms;
01675 int x, y, max;
01676 int sz;
01677 time_t now = 0;
01678 long whentohangup = 0, diff;
01679 struct ast_channel *winner = NULL;
01680 struct fdmap {
01681 int chan;
01682 int fdno;
01683 } *fdmap = NULL;
01684
01685 if ((sz = n * AST_MAX_FDS + nfds)) {
01686 pfds = alloca(sizeof(*pfds) * sz);
01687 fdmap = alloca(sizeof(*fdmap) * sz);
01688 }
01689
01690 if (outfd)
01691 *outfd = -99999;
01692 if (exception)
01693 *exception = 0;
01694
01695
01696 for (x=0; x < n; x++) {
01697 ast_channel_lock(c[x]);
01698 if (c[x]->masq) {
01699 if (ast_do_masquerade(c[x])) {
01700 ast_log(LOG_WARNING, "Masquerade failed\n");
01701 *ms = -1;
01702 ast_channel_unlock(c[x]);
01703 return NULL;
01704 }
01705 }
01706 if (c[x]->whentohangup) {
01707 if (!whentohangup)
01708 time(&now);
01709 diff = c[x]->whentohangup - now;
01710 if (diff < 1) {
01711
01712 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
01713 ast_channel_unlock(c[x]);
01714 return c[x];
01715 }
01716 if (!whentohangup || (diff < whentohangup))
01717 whentohangup = diff;
01718 }
01719 ast_channel_unlock(c[x]);
01720 }
01721
01722 rms = *ms;
01723 if (whentohangup) {
01724 rms = whentohangup * 1000;
01725 if (*ms >= 0 && *ms < rms)
01726 rms = *ms;
01727 }
01728
01729
01730
01731
01732
01733 max = 0;
01734 for (x=0; x<n; x++) {
01735 for (y=0; y<AST_MAX_FDS; y++) {
01736 fdmap[max].fdno = y;
01737 fdmap[max].chan = x;
01738 max += ast_add_fd(&pfds[max], c[x]->fds[y]);
01739 }
01740 CHECK_BLOCKING(c[x]);
01741 }
01742
01743 for (x=0; x<nfds; x++) {
01744 fdmap[max].chan = -1;
01745 max += ast_add_fd(&pfds[max], fds[x]);
01746 }
01747
01748 if (*ms > 0)
01749 start = ast_tvnow();
01750
01751 if (sizeof(int) == 4) {
01752 do {
01753 int kbrms = rms;
01754 if (kbrms > 600000)
01755 kbrms = 600000;
01756 res = poll(pfds, max, kbrms);
01757 if (!res)
01758 rms -= kbrms;
01759 } while (!res && (rms > 0));
01760 } else {
01761 res = poll(pfds, max, rms);
01762 }
01763 for (x=0; x<n; x++)
01764 ast_clear_flag(c[x], AST_FLAG_BLOCKING);
01765 if (res < 0) {
01766 if (errno != EINTR)
01767 *ms = -1;
01768 return NULL;
01769 }
01770 if (whentohangup) {
01771 time(&now);
01772 for (x=0; x<n; x++) {
01773 if (c[x]->whentohangup && now >= c[x]->whentohangup) {
01774 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
01775 if (winner == NULL)
01776 winner = c[x];
01777 }
01778 }
01779 }
01780 if (res == 0) {
01781 *ms = 0;
01782 return winner;
01783 }
01784
01785
01786
01787
01788
01789 for (x = 0; x < max; x++) {
01790 res = pfds[x].revents;
01791 if (res == 0)
01792 continue;
01793 if (fdmap[x].chan >= 0) {
01794 winner = c[fdmap[x].chan];
01795 if (res & POLLPRI)
01796 ast_set_flag(winner, AST_FLAG_EXCEPTION);
01797 else
01798 ast_clear_flag(winner, AST_FLAG_EXCEPTION);
01799 winner->fdno = fdmap[x].fdno;
01800 } else {
01801 if (outfd)
01802 *outfd = pfds[x].fd;
01803 if (exception)
01804 *exception = (res & POLLPRI) ? -1 : 0;
01805 winner = NULL;
01806 }
01807 }
01808 if (*ms > 0) {
01809 *ms -= ast_tvdiff_ms(ast_tvnow(), start);
01810 if (*ms < 0)
01811 *ms = 0;
01812 }
01813 return winner;
01814 }
01815
01816 struct ast_channel *ast_waitfor_n(struct ast_channel **c, int n, int *ms)
01817 {
01818 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
01819 }
01820
01821 int ast_waitfor(struct ast_channel *c, int ms)
01822 {
01823 int oldms = ms;
01824
01825 ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms);
01826 if ((ms < 0) && (oldms < 0))
01827 ms = 0;
01828 return ms;
01829 }
01830
01831
01832 int ast_waitfordigit(struct ast_channel *c, int ms)
01833 {
01834 return ast_waitfordigit_full(c, ms, -1, -1);
01835 }
01836
01837 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(const void *data), void *data)
01838 {
01839 int res = -1;
01840 #ifdef HAVE_DAHDI
01841 if (c->timingfd > -1) {
01842 if (!func) {
01843 samples = 0;
01844 data = 0;
01845 }
01846 if (option_debug)
01847 ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01848 res = ioctl(c->timingfd, DAHDI_TIMERCONFIG, &samples);
01849 c->timingfunc = func;
01850 c->timingdata = data;
01851 }
01852 #endif
01853 return res;
01854 }
01855
01856 int ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
01857 {
01858
01859 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
01860 return -1;
01861
01862
01863 ast_set_flag(c, AST_FLAG_END_DTMF_ONLY);
01864
01865
01866 while (ms) {
01867 struct ast_channel *rchan;
01868 int outfd;
01869
01870 errno = 0;
01871 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01872 if (!rchan && outfd < 0 && ms) {
01873 if (errno == 0 || errno == EINTR)
01874 continue;
01875 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01876 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01877 return -1;
01878 } else if (outfd > -1) {
01879
01880 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01881 return 1;
01882 } else if (rchan) {
01883 int res;
01884 struct ast_frame *f = ast_read(c);
01885 if (!f)
01886 return -1;
01887
01888 switch(f->frametype) {
01889 case AST_FRAME_DTMF_BEGIN:
01890 break;
01891 case AST_FRAME_DTMF_END:
01892 res = f->subclass;
01893 ast_frfree(f);
01894 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01895 return res;
01896 case AST_FRAME_CONTROL:
01897 switch(f->subclass) {
01898 case AST_CONTROL_HANGUP:
01899 ast_frfree(f);
01900 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01901 return -1;
01902 case AST_CONTROL_RINGING:
01903 case AST_CONTROL_ANSWER:
01904 case AST_CONTROL_SRCUPDATE:
01905
01906 break;
01907 default:
01908 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01909 break;
01910 }
01911 break;
01912 case AST_FRAME_VOICE:
01913
01914 if (audiofd > -1) {
01915 if (write(audiofd, f->data, f->datalen) < 0) {
01916 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
01917 }
01918 }
01919 default:
01920
01921 break;
01922 }
01923 ast_frfree(f);
01924 }
01925 }
01926
01927 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01928
01929 return 0;
01930 }
01931
01932 static void ast_read_generator_actions(struct ast_channel *chan, struct ast_frame *f)
01933 {
01934 if (chan->generatordata && !ast_internal_timing_enabled(chan)) {
01935 void *tmp = chan->generatordata;
01936 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = NULL;
01937 int res;
01938 int samples;
01939
01940 if (chan->timingfunc) {
01941 if (option_debug > 1)
01942 ast_log(LOG_DEBUG, "Generator got voice, switching to phase locked mode\n");
01943 ast_settimeout(chan, 0, NULL, NULL);
01944 }
01945
01946 chan->generatordata = NULL;
01947
01948 if (f->subclass != chan->writeformat) {
01949 float factor;
01950 factor = ((float) ast_format_rate(chan->writeformat)) / ((float) ast_format_rate(f->subclass));
01951 samples = (int) ( ((float) f->samples) * factor );
01952 } else {
01953 samples = f->samples;
01954 }
01955
01956 if (chan->generator->generate) {
01957 generate = chan->generator->generate;
01958 }
01959
01960
01961
01962
01963
01964
01965
01966
01967 ast_channel_unlock(chan);
01968 res = generate(chan, tmp, f->datalen, samples);
01969 ast_channel_lock(chan);
01970 chan->generatordata = tmp;
01971 if (res) {
01972 if (option_debug > 1)
01973 ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
01974 ast_deactivate_generator(chan);
01975 }
01976
01977 } else if (f->frametype == AST_FRAME_CNG) {
01978 if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) {
01979 if (option_debug > 1)
01980 ast_log(LOG_DEBUG, "Generator got CNG, switching to timed mode\n");
01981 ast_settimeout(chan, 160, generator_force, chan);
01982 }
01983 }
01984 }
01985
01986 static inline void queue_dtmf_readq(struct ast_channel *chan, struct ast_frame *f)
01987 {
01988 struct ast_frame *fr = &chan->dtmff;
01989
01990 fr->frametype = AST_FRAME_DTMF_END;
01991 fr->subclass = f->subclass;
01992 fr->len = f->len;
01993
01994
01995
01996
01997
01998 ast_queue_frame(chan, fr);
01999 }
02000
02001
02002
02003
02004 static inline int should_skip_dtmf(struct ast_channel *chan)
02005 {
02006 if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF)) {
02007
02008
02009 return 1;
02010 }
02011
02012 if (!ast_tvzero(chan->dtmf_tv) &&
02013 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) {
02014
02015
02016 return 1;
02017 }
02018
02019 return 0;
02020 }
02021
02022 static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
02023 {
02024 struct ast_frame *f = NULL;
02025 int blah;
02026 int prestate;
02027 int count = 0;
02028
02029
02030
02031
02032 while(ast_channel_trylock(chan)) {
02033 if(count++ > 10)
02034
02035 return &ast_null_frame;
02036 usleep(1);
02037 }
02038
02039 if (chan->masq) {
02040 if (ast_do_masquerade(chan))
02041 ast_log(LOG_WARNING, "Failed to perform masquerade\n");
02042 else
02043 f = &ast_null_frame;
02044 goto done;
02045 }
02046
02047
02048 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
02049 if (chan->generator)
02050 ast_deactivate_generator(chan);
02051 goto done;
02052 }
02053 prestate = chan->_state;
02054
02055
02056
02057 if (chan->alertpipe[0] > -1) {
02058 int flags = fcntl(chan->alertpipe[0], F_GETFL);
02059
02060
02061 if ((flags & O_NONBLOCK) == 0) {
02062 ast_log(LOG_ERROR, "Alertpipe on channel %s lost O_NONBLOCK?!!\n", chan->name);
02063 if (fcntl(chan->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) {
02064 ast_log(LOG_WARNING, "Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
02065 f = &ast_null_frame;
02066 goto done;
02067 }
02068 }
02069 if (read(chan->alertpipe[0], &blah, sizeof(blah)) < 0) {
02070 if (errno != EINTR && errno != EAGAIN)
02071 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno));
02072 }
02073 }
02074
02075 #ifdef HAVE_DAHDI
02076 if (chan->timingfd > -1 && chan->fdno == AST_TIMING_FD && ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
02077 int res;
02078
02079 ast_clear_flag(chan, AST_FLAG_EXCEPTION);
02080 blah = -1;
02081
02082 res = ioctl(chan->timingfd, DAHDI_GETEVENT, &blah);
02083 if (res)
02084 blah = DAHDI_EVENT_TIMER_EXPIRED;
02085
02086 if (blah == DAHDI_EVENT_TIMER_PING) {
02087 if (AST_LIST_EMPTY(&chan->readq) || !AST_LIST_NEXT(AST_LIST_FIRST(&chan->readq), frame_list)) {
02088
02089 if (ioctl(chan->timingfd, DAHDI_TIMERPONG, &blah)) {
02090 ast_log(LOG_WARNING, "Failed to pong timer on '%s': %s\n", chan->name, strerror(errno));
02091 }
02092 }
02093 } else if (blah == DAHDI_EVENT_TIMER_EXPIRED) {
02094 ioctl(chan->timingfd, DAHDI_TIMERACK, &blah);
02095 if (chan->timingfunc) {
02096
02097 int (*func)(const void *) = chan->timingfunc;
02098 void *data = chan->timingdata;
02099 ast_channel_unlock(chan);
02100 func(data);
02101 } else {
02102 blah = 0;
02103 ioctl(chan->timingfd, DAHDI_TIMERCONFIG, &blah);
02104 chan->timingdata = NULL;
02105 ast_channel_unlock(chan);
02106 }
02107
02108 return &ast_null_frame;
02109 } else
02110 ast_log(LOG_NOTICE, "No/unknown event '%d' on timer for '%s'?\n", blah, chan->name);
02111 } else
02112 #endif
02113 if (chan->fds[AST_GENERATOR_FD] > -1 && chan->fdno == AST_GENERATOR_FD) {
02114
02115
02116
02117 void *tmp = chan->generatordata;
02118 chan->generatordata = NULL;
02119 chan->generator->generate(chan, tmp, -1, -1);
02120 chan->generatordata = tmp;
02121 f = &ast_null_frame;
02122 goto done;
02123 }
02124
02125
02126 if (!AST_LIST_EMPTY(&chan->readq)) {
02127 int skip_dtmf = should_skip_dtmf(chan);
02128
02129 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->readq, f, frame_list) {
02130
02131
02132
02133
02134 if ( (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && skip_dtmf) {
02135 continue;
02136 }
02137
02138 AST_LIST_REMOVE_CURRENT(&chan->readq, frame_list);
02139 break;
02140 }
02141 AST_LIST_TRAVERSE_SAFE_END
02142
02143 if (!f) {
02144
02145 f = &ast_null_frame;
02146 if (chan->alertpipe[0] > -1) {
02147 int poke = 0;
02148
02149
02150 if (write(chan->alertpipe[1], &poke, sizeof(poke)) != sizeof(poke)) {
02151 ast_log(LOG_ERROR, "Failed to write to alertpipe: %s\n", strerror(errno));
02152 }
02153 }
02154 }
02155
02156
02157
02158 if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP) {
02159 ast_frfree(f);
02160 f = NULL;
02161 }
02162 } else {
02163 chan->blocker = pthread_self();
02164 if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
02165 if (chan->tech->exception)
02166 f = chan->tech->exception(chan);
02167 else {
02168 ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name);
02169 f = &ast_null_frame;
02170 }
02171
02172 ast_clear_flag(chan, AST_FLAG_EXCEPTION);
02173 } else if (chan->tech->read)
02174 f = chan->tech->read(chan);
02175 else
02176 ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
02177 }
02178
02179 if (f) {
02180
02181
02182
02183
02184
02185 if (AST_LIST_NEXT(f, frame_list)) {
02186 AST_LIST_HEAD_SET_NOLOCK(&chan->readq, AST_LIST_NEXT(f, frame_list));
02187 AST_LIST_NEXT(f, frame_list) = NULL;
02188 }
02189
02190 switch (f->frametype) {
02191 case AST_FRAME_CONTROL:
02192 if (f->subclass == AST_CONTROL_ANSWER) {
02193 if (!ast_test_flag(chan, AST_FLAG_OUTGOING)) {
02194 if (option_debug)
02195 ast_log(LOG_DEBUG, "Ignoring answer on an inbound call!\n");
02196 ast_frfree(f);
02197 f = &ast_null_frame;
02198 } else if (prestate == AST_STATE_UP) {
02199 if (option_debug)
02200 ast_log(LOG_DEBUG, "Dropping duplicate answer!\n");
02201 ast_frfree(f);
02202 f = &ast_null_frame;
02203 } else {
02204
02205 ast_setstate(chan, AST_STATE_UP);
02206
02207 }
02208 }
02209 break;
02210 case AST_FRAME_DTMF_END:
02211 ast_log(LOG_DTMF, "DTMF end '%c' received on %s, duration %ld ms\n", f->subclass, chan->name, f->len);
02212
02213 if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF) || ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
02214 queue_dtmf_readq(chan, f);
02215 ast_frfree(f);
02216 f = &ast_null_frame;
02217 } else if (!ast_test_flag(chan, AST_FLAG_IN_DTMF | AST_FLAG_END_DTMF_ONLY)) {
02218 if (!ast_tvzero(chan->dtmf_tv) &&
02219 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) {
02220
02221 queue_dtmf_readq(chan, f);
02222 ast_frfree(f);
02223 f = &ast_null_frame;
02224 } else {
02225
02226 f->frametype = AST_FRAME_DTMF_BEGIN;
02227 ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
02228 chan->emulate_dtmf_digit = f->subclass;
02229 chan->dtmf_tv = ast_tvnow();
02230 if (f->len) {
02231 if (f->len > AST_MIN_DTMF_DURATION)
02232 chan->emulate_dtmf_duration = f->len;
02233 else
02234 chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION;
02235 } else
02236 chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION;
02237 ast_log(LOG_DTMF, "DTMF begin emulation of '%c' with duration %u queued on %s\n", f->subclass, chan->emulate_dtmf_duration, chan->name);
02238 }
02239 if (chan->audiohooks) {
02240 struct ast_frame *old_frame = f;
02241 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
02242 if (old_frame != f)
02243 ast_frfree(old_frame);
02244 }
02245 } else {
02246 struct timeval now = ast_tvnow();
02247 if (ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
02248 ast_log(LOG_DTMF, "DTMF end accepted with begin '%c' on %s\n", f->subclass, chan->name);
02249 ast_clear_flag(chan, AST_FLAG_IN_DTMF);
02250 if (!f->len)
02251 f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
02252 } else if (!f->len) {
02253 ast_log(LOG_DTMF, "DTMF end accepted without begin '%c' on %s\n", f->subclass, chan->name);
02254 f->len = AST_MIN_DTMF_DURATION;
02255 }
02256 if (f->len < AST_MIN_DTMF_DURATION && !ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)) {
02257 ast_log(LOG_DTMF, "DTMF end '%c' has duration %ld but want minimum %d, emulating on %s\n", f->subclass, f->len, AST_MIN_DTMF_DURATION, chan->name);
02258 ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
02259 chan->emulate_dtmf_digit = f->subclass;
02260 chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION - f->len;
02261 ast_frfree(f);
02262 f = &ast_null_frame;
02263 } else {
02264 ast_log(LOG_DTMF, "DTMF end passthrough '%c' on %s\n", f->subclass, chan->name);
02265 if (f->len < AST_MIN_DTMF_DURATION) {
02266 f->len = AST_MIN_DTMF_DURATION;
02267 }
02268 chan->dtmf_tv = now;
02269 }
02270 if (chan->audiohooks) {
02271 struct ast_frame *old_frame = f;
02272 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
02273 if (old_frame != f)
02274 ast_frfree(old_frame);
02275 }
02276 }
02277 break;
02278 case AST_FRAME_DTMF_BEGIN:
02279 ast_log(LOG_DTMF, "DTMF begin '%c' received on %s\n", f->subclass, chan->name);
02280 if ( ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_END_DTMF_ONLY | AST_FLAG_EMULATE_DTMF) ||
02281 (!ast_tvzero(chan->dtmf_tv) &&
02282 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) ) {
02283 ast_log(LOG_DTMF, "DTMF begin ignored '%c' on %s\n", f->subclass, chan->name);
02284 ast_frfree(f);
02285 f = &ast_null_frame;
02286 } else {
02287 ast_set_flag(chan, AST_FLAG_IN_DTMF);
02288 chan->dtmf_tv = ast_tvnow();
02289 ast_log(LOG_DTMF, "DTMF begin passthrough '%c' on %s\n", f->subclass, chan->name);
02290 }
02291 break;
02292 case AST_FRAME_NULL:
02293
02294
02295
02296
02297 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
02298 struct timeval now = ast_tvnow();
02299 if (!chan->emulate_dtmf_duration) {
02300 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
02301 chan->emulate_dtmf_digit = 0;
02302 } else if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
02303 chan->emulate_dtmf_duration = 0;
02304 ast_frfree(f);
02305 f = &chan->dtmff;
02306 f->frametype = AST_FRAME_DTMF_END;
02307 f->subclass = chan->emulate_dtmf_digit;
02308 f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
02309 chan->dtmf_tv = now;
02310 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
02311 chan->emulate_dtmf_digit = 0;
02312 ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass, chan->name);
02313 }
02314 }
02315 break;
02316 case AST_FRAME_VOICE:
02317
02318
02319
02320
02321 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !chan->emulate_dtmf_duration) {
02322 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
02323 chan->emulate_dtmf_digit = 0;
02324 }
02325
02326 if (dropaudio || ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
02327 if (dropaudio)
02328 ast_read_generator_actions(chan, f);
02329 ast_frfree(f);
02330 f = &ast_null_frame;
02331 }
02332
02333 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
02334 struct timeval now = ast_tvnow();
02335 if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
02336 chan->emulate_dtmf_duration = 0;
02337 ast_frfree(f);
02338 f = &chan->dtmff;
02339 f->frametype = AST_FRAME_DTMF_END;
02340 f->subclass = chan->emulate_dtmf_digit;
02341 f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
02342 chan->dtmf_tv = now;
02343 if (chan->audiohooks) {
02344 struct ast_frame *old_frame = f;
02345 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
02346 if (old_frame != f)
02347 ast_frfree(old_frame);
02348 }
02349 ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass, chan->name);
02350 } else {
02351
02352 ast_frfree(f);
02353 f = &ast_null_frame;
02354 }
02355 } else if ((f->frametype == AST_FRAME_VOICE) && !(f->subclass & chan->nativeformats)) {
02356
02357 char to[200];
02358 ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n",
02359 chan->name, ast_getformatname(f->subclass), ast_getformatname_multiple(to, sizeof(to), chan->nativeformats));
02360 ast_frfree(f);
02361 f = &ast_null_frame;
02362 } else if ((f->frametype == AST_FRAME_VOICE)) {
02363 if (chan->audiohooks) {
02364 struct ast_frame *old_frame = f;
02365 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
02366 if (old_frame != f)
02367 ast_frfree(old_frame);
02368 }
02369 if (chan->monitor && chan->monitor->read_stream ) {
02370
02371 #ifndef MONITOR_CONSTANT_DELAY
02372 int jump = chan->outsmpl - chan->insmpl - 4 * f->samples;
02373 if (jump >= 0) {
02374 jump = chan->outsmpl - chan->insmpl;
02375 if (ast_seekstream(chan->monitor->read_stream, jump, SEEK_FORCECUR) == -1)
02376 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
02377 chan->insmpl += jump + f->samples;
02378 } else
02379 chan->insmpl+= f->samples;
02380 #else
02381 int jump = chan->outsmpl - chan->insmpl;
02382 if (jump - MONITOR_DELAY >= 0) {
02383 if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
02384 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
02385 chan->insmpl += jump;
02386 } else
02387 chan->insmpl += f->samples;
02388 #endif
02389 if (chan->monitor->state == AST_MONITOR_RUNNING) {
02390 if (ast_writestream(chan->monitor->read_stream, f) < 0)
02391 ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
02392 }
02393 }
02394
02395 if (chan->readtrans && (f = ast_translate(chan->readtrans, f, 1)) == NULL)
02396 f = &ast_null_frame;
02397
02398
02399
02400 ast_read_generator_actions(chan, f);
02401 }
02402 default:
02403
02404 break;
02405 }
02406 } else {
02407
02408 chan->_softhangup |= AST_SOFTHANGUP_DEV;
02409 if (chan->generator)
02410 ast_deactivate_generator(chan);
02411
02412 }
02413
02414
02415 if (chan->fin & DEBUGCHAN_FLAG)
02416 ast_frame_dump(chan->name, f, "<<");
02417 chan->fin = FRAMECOUNT_INC(chan->fin);
02418
02419 done:
02420 ast_channel_unlock(chan);
02421 return f;
02422 }
02423
02424 int ast_internal_timing_enabled(struct ast_channel *chan)
02425 {
02426 int ret = ast_opt_internal_timing && chan->timingfd > -1;
02427 if (option_debug > 4)
02428 ast_log(LOG_DEBUG, "Internal timing is %s (option_internal_timing=%d chan->timingfd=%d)\n", ret? "enabled": "disabled", ast_opt_internal_timing, chan->timingfd);
02429 return ret;
02430 }
02431
02432 struct ast_frame *ast_read(struct ast_channel *chan)
02433 {
02434 return __ast_read(chan, 0);
02435 }
02436
02437 struct ast_frame *ast_read_noaudio(struct ast_channel *chan)
02438 {
02439 return __ast_read(chan, 1);
02440 }
02441
02442 int ast_indicate(struct ast_channel *chan, int condition)
02443 {
02444 return ast_indicate_data(chan, condition, NULL, 0);
02445 }
02446
02447 static int attribute_const is_visible_indication(enum ast_control_frame_type condition)
02448 {
02449
02450
02451
02452 switch (condition) {
02453 case AST_CONTROL_PROGRESS:
02454 case AST_CONTROL_PROCEEDING:
02455 case AST_CONTROL_VIDUPDATE:
02456 case AST_CONTROL_SRCUPDATE:
02457 case AST_CONTROL_RADIO_KEY:
02458 case AST_CONTROL_RADIO_UNKEY:
02459 case AST_CONTROL_OPTION:
02460 case AST_CONTROL_WINK:
02461 case AST_CONTROL_FLASH:
02462 case AST_CONTROL_OFFHOOK:
02463 case AST_CONTROL_TAKEOFFHOOK:
02464 case AST_CONTROL_ANSWER:
02465 case AST_CONTROL_HANGUP:
02466 return 0;
02467
02468 case AST_CONTROL_CONGESTION:
02469 case AST_CONTROL_BUSY:
02470 case AST_CONTROL_RINGING:
02471 case AST_CONTROL_RING:
02472 case AST_CONTROL_HOLD:
02473 case AST_CONTROL_UNHOLD:
02474 return 1;
02475 }
02476
02477 return 0;
02478 }
02479
02480 int ast_indicate_data(struct ast_channel *chan, int _condition,
02481 const void *data, size_t datalen)
02482 {
02483
02484
02485 enum ast_control_frame_type condition = _condition;
02486 const struct tone_zone_sound *ts = NULL;
02487 int res = -1;
02488
02489 ast_channel_lock(chan);
02490
02491
02492 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
02493 ast_channel_unlock(chan);
02494 return -1;
02495 }
02496
02497 if (chan->tech->indicate) {
02498
02499 res = chan->tech->indicate(chan, condition, data, datalen);
02500 }
02501
02502 ast_channel_unlock(chan);
02503
02504 if (chan->tech->indicate && !res) {
02505
02506 if (is_visible_indication(condition)) {
02507 chan->visible_indication = condition;
02508 }
02509 return 0;
02510 }
02511
02512
02513
02514
02515
02516
02517
02518 if (_condition < 0) {
02519
02520 ast_playtones_stop(chan);
02521 return 0;
02522 }
02523
02524
02525 switch (condition) {
02526 case AST_CONTROL_RINGING:
02527 ts = ast_get_indication_tone(chan->zone, "ring");
02528 break;
02529 case AST_CONTROL_BUSY:
02530 ts = ast_get_indication_tone(chan->zone, "busy");
02531 break;
02532 case AST_CONTROL_CONGESTION:
02533 ts = ast_get_indication_tone(chan->zone, "congestion");
02534 break;
02535 case AST_CONTROL_PROGRESS:
02536 case AST_CONTROL_PROCEEDING:
02537 case AST_CONTROL_VIDUPDATE:
02538 case AST_CONTROL_SRCUPDATE:
02539 case AST_CONTROL_RADIO_KEY:
02540 case AST_CONTROL_RADIO_UNKEY:
02541 case AST_CONTROL_OPTION:
02542 case AST_CONTROL_WINK:
02543 case AST_CONTROL_FLASH:
02544 case AST_CONTROL_OFFHOOK:
02545 case AST_CONTROL_TAKEOFFHOOK:
02546 case AST_CONTROL_ANSWER:
02547 case AST_CONTROL_HANGUP:
02548 case AST_CONTROL_RING:
02549 case AST_CONTROL_HOLD:
02550 case AST_CONTROL_UNHOLD:
02551
02552 res = 0;
02553 break;
02554 }
02555
02556 if (ts && ts->data[0]) {
02557
02558 if (option_debug) {
02559 ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
02560 }
02561 ast_playtones_start(chan, 0, ts->data, 1);
02562 res = 0;
02563 chan->visible_indication = condition;
02564 }
02565
02566 if (res) {
02567
02568 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
02569 }
02570
02571 return res;
02572 }
02573
02574 int ast_recvchar(struct ast_channel *chan, int timeout)
02575 {
02576 int c;
02577 char *buf = ast_recvtext(chan, timeout);
02578 if (buf == NULL)
02579 return -1;
02580 c = *(unsigned char *)buf;
02581 free(buf);
02582 return c;
02583 }
02584
02585 char *ast_recvtext(struct ast_channel *chan, int timeout)
02586 {
02587 int res, done = 0;
02588 char *buf = NULL;
02589
02590 while (!done) {
02591 struct ast_frame *f;
02592 if (ast_check_hangup(chan))
02593 break;
02594 res = ast_waitfor(chan, timeout);
02595 if (res <= 0)
02596 break;
02597 timeout = res;
02598 f = ast_read(chan);
02599 if (f == NULL)
02600 break;
02601 if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP)
02602 done = 1;
02603 else if (f->frametype == AST_FRAME_TEXT) {
02604 buf = ast_strndup((char *) f->data, f->datalen);
02605 done = 1;
02606 }
02607 ast_frfree(f);
02608 }
02609 return buf;
02610 }
02611
02612 int ast_sendtext(struct ast_channel *chan, const char *text)
02613 {
02614 int res = 0;
02615
02616 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
02617 return -1;
02618 CHECK_BLOCKING(chan);
02619 if (chan->tech->send_text)
02620 res = chan->tech->send_text(chan, text);
02621 ast_clear_flag(chan, AST_FLAG_BLOCKING);
02622 return res;
02623 }
02624
02625 int ast_senddigit_begin(struct ast_channel *chan, char digit)
02626 {
02627
02628
02629 static const char* dtmf_tones[] = {
02630 "941+1336",
02631 "697+1209",
02632 "697+1336",
02633 "697+1477",
02634 "770+1209",
02635 "770+1336",
02636 "770+1477",
02637 "852+1209",
02638 "852+1336",
02639 "852+1477",
02640 "697+1633",
02641 "770+1633",
02642 "852+1633",
02643 "941+1633",
02644 "941+1209",
02645 "941+1477"
02646 };
02647
02648 if (!chan->tech->send_digit_begin)
02649 return 0;
02650
02651 if (!chan->tech->send_digit_begin(chan, digit))
02652 return 0;
02653
02654 if (digit >= '0' && digit <='9')
02655 ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0);
02656 else if (digit >= 'A' && digit <= 'D')
02657 ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0);
02658 else if (digit == '*')
02659 ast_playtones_start(chan, 0, dtmf_tones[14], 0);
02660 else if (digit == '#')
02661 ast_playtones_start(chan, 0, dtmf_tones[15], 0);
02662 else {
02663
02664 if (option_debug)
02665 ast_log(LOG_DEBUG, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name);
02666 }
02667
02668 return 0;
02669 }
02670
02671 int ast_senddigit_end(struct ast_channel *chan, char digit, unsigned int duration)
02672 {
02673 int res = -1;
02674
02675 if (chan->tech->send_digit_end)
02676 res = chan->tech->send_digit_end(chan, digit, duration);
02677
02678 if (res && chan->generator)
02679 ast_playtones_stop(chan);
02680
02681 return 0;
02682 }
02683
02684 int ast_senddigit(struct ast_channel *chan, char digit)
02685 {
02686 if (chan->tech->send_digit_begin) {
02687 ast_senddigit_begin(chan, digit);
02688 ast_safe_sleep(chan, AST_DEFAULT_EMULATE_DTMF_DURATION);
02689 }
02690
02691 return ast_senddigit_end(chan, digit, AST_DEFAULT_EMULATE_DTMF_DURATION);
02692 }
02693
02694 int ast_prod(struct ast_channel *chan)
02695 {
02696 struct ast_frame a = { AST_FRAME_VOICE };
02697 char nothing[128];
02698
02699
02700 if (chan->_state != AST_STATE_UP) {
02701 if (option_debug)
02702 ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name);
02703 a.subclass = chan->rawwriteformat;
02704 a.data = nothing + AST_FRIENDLY_OFFSET;
02705 a.src = "ast_prod";
02706 if (ast_write(chan, &a))
02707 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name);
02708 }
02709 return 0;
02710 }
02711
02712 int ast_write_video(struct ast_channel *chan, struct ast_frame *fr)
02713 {
02714 int res;
02715 if (!chan->tech->write_video)
02716 return 0;
02717 res = ast_write(chan, fr);
02718 if (!res)
02719 res = 1;
02720 return res;
02721 }
02722
02723 int ast_write(struct ast_channel *chan, struct ast_frame *fr)
02724 {
02725 int res = -1;
02726 int count = 0;
02727 struct ast_frame *f = NULL, *f2 = NULL;
02728
02729
02730 while(ast_channel_trylock(chan)) {
02731
02732 if(count++ > 10) {
02733 if(option_debug)
02734 ast_log(LOG_DEBUG, "Deadlock avoided for write to channel '%s'\n", chan->name);
02735 return 0;
02736 }
02737 usleep(1);
02738 }
02739
02740 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
02741 goto done;
02742
02743
02744 if (chan->masq && ast_do_masquerade(chan)) {
02745 ast_log(LOG_WARNING, "Failed to perform masquerade\n");
02746 goto done;
02747 }
02748 if (chan->masqr) {
02749 res = 0;
02750 goto done;
02751 }
02752 if (chan->generatordata) {
02753 if (ast_test_flag(chan, AST_FLAG_WRITE_INT))
02754 ast_deactivate_generator(chan);
02755 else {
02756 if (fr->frametype == AST_FRAME_DTMF_END) {
02757
02758
02759
02760 ast_clear_flag(chan, AST_FLAG_BLOCKING);
02761 ast_channel_unlock(chan);
02762 res = ast_senddigit_end(chan, fr->subclass, fr->len);
02763 ast_channel_lock(chan);
02764 CHECK_BLOCKING(chan);
02765 } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass == AST_CONTROL_UNHOLD) {
02766
02767 res = (chan->tech->indicate == NULL) ? 0 :
02768 chan->tech->indicate(chan, fr->subclass, fr->data, fr->datalen);
02769 }
02770 res = 0;
02771 goto done;
02772 }
02773 }
02774
02775 if (chan->fout & DEBUGCHAN_FLAG)
02776 ast_frame_dump(chan->name, fr, ">>");
02777 CHECK_BLOCKING(chan);
02778 switch(fr->frametype) {
02779 case AST_FRAME_CONTROL:
02780 res = (chan->tech->indicate == NULL) ? 0 :
02781 chan->tech->indicate(chan, fr->subclass, fr->data, fr->datalen);
02782 break;
02783 case AST_FRAME_DTMF_BEGIN:
02784 if (chan->audiohooks) {
02785 struct ast_frame *old_frame = fr;
02786 fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
02787 if (old_frame != fr)
02788 f = fr;
02789 }
02790 ast_clear_flag(chan, AST_FLAG_BLOCKING);
02791 ast_channel_unlock(chan);
02792 res = ast_senddigit_begin(chan, fr->subclass);
02793 ast_channel_lock(chan);
02794 CHECK_BLOCKING(chan);
02795 break;
02796 case AST_FRAME_DTMF_END:
02797 if (chan->audiohooks) {
02798 struct ast_frame *old_frame = fr;
02799 fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
02800 if (old_frame != fr)
02801 f = fr;
02802 }
02803 ast_clear_flag(chan, AST_FLAG_BLOCKING);
02804 ast_channel_unlock(chan);
02805 res = ast_senddigit_end(chan, fr->subclass, fr->len);
02806 ast_channel_lock(chan);
02807 CHECK_BLOCKING(chan);
02808 break;
02809 case AST_FRAME_TEXT:
02810 res = (chan->tech->send_text == NULL) ? 0 :
02811 chan->tech->send_text(chan, (char *) fr->data);
02812 break;
02813 case AST_FRAME_HTML:
02814 res = (chan->tech->send_html == NULL) ? 0 :
02815 chan->tech->send_html(chan, fr->subclass, (char *) fr->data, fr->datalen);
02816 break;
02817 case AST_FRAME_VIDEO:
02818
02819 res = (chan->tech->write_video == NULL) ? 0 :
02820 chan->tech->write_video(chan, fr);
02821 break;
02822 case AST_FRAME_MODEM:
02823 res = (chan->tech->write == NULL) ? 0 :
02824 chan->tech->write(chan, fr);
02825 break;
02826 case AST_FRAME_VOICE:
02827 if (chan->tech->write == NULL)
02828 break;
02829
02830 if (chan->audiohooks) {
02831 struct ast_frame *old_frame = fr;
02832 fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
02833 if (old_frame != fr)
02834 f2 = fr;
02835 }
02836
02837
02838 if (fr->subclass == chan->rawwriteformat)
02839 f = fr;
02840 else
02841 f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
02842
02843
02844 if (!f) {
02845 res = 0;
02846 break;
02847 }
02848
02849
02850 if (chan->monitor && chan->monitor->write_stream) {
02851
02852 #ifndef MONITOR_CONSTANT_DELAY
02853 int jump = chan->insmpl - chan->outsmpl - 4 * f->samples;
02854 if (jump >= 0) {
02855 jump = chan->insmpl - chan->outsmpl;
02856 if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1)
02857 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
02858 chan->outsmpl += jump + f->samples;
02859 } else
02860 chan->outsmpl += f->samples;
02861 #else
02862 int jump = chan->insmpl - chan->outsmpl;
02863 if (jump - MONITOR_DELAY >= 0) {
02864 if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1)
02865 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
02866 chan->outsmpl += jump;
02867 } else
02868 chan->outsmpl += f->samples;
02869 #endif
02870 if (chan->monitor->state == AST_MONITOR_RUNNING) {
02871 if (ast_writestream(chan->monitor->write_stream, f) < 0)
02872 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
02873 }
02874 }
02875
02876 if (f)
02877 res = chan->tech->write(chan,f);
02878 else
02879 res = 0;
02880 break;
02881 case AST_FRAME_NULL:
02882 case AST_FRAME_IAX:
02883
02884 res = 0;
02885 break;
02886 default:
02887
02888
02889
02890 res = chan->tech->write(chan, fr);
02891 break;
02892 }
02893
02894 if (f && f != fr)
02895 ast_frfree(f);
02896 if (f2)
02897 ast_frfree(f2);
02898 ast_clear_flag(chan, AST_FLAG_BLOCKING);
02899
02900 if (res < 0)
02901 chan->_softhangup |= AST_SOFTHANGUP_DEV;
02902 else {
02903 chan->fout = FRAMECOUNT_INC(chan->fout);
02904 }
02905 done:
02906 ast_channel_unlock(chan);
02907 return res;
02908 }
02909
02910 static int set_format(struct ast_channel *chan, int fmt, int *rawformat, int *format,
02911 struct ast_trans_pvt **trans, const int direction)
02912 {
02913 int native;
02914 int res;
02915 char from[200], to[200];
02916
02917
02918 fmt &= AST_FORMAT_AUDIO_MASK;
02919
02920 native = chan->nativeformats;
02921
02922 if (!direction)
02923
02924 res = ast_translator_best_choice(&fmt, &native);
02925 else
02926
02927 res = ast_translator_best_choice(&native, &fmt);
02928
02929 if (res < 0) {
02930 ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n",
02931 ast_getformatname_multiple(from, sizeof(from), native),
02932 ast_getformatname_multiple(to, sizeof(to), fmt));
02933 return -1;
02934 }
02935
02936
02937 ast_channel_lock(chan);
02938
02939 if ((*rawformat == native) && (*format == fmt) && ((*rawformat == *format) || (*trans))) {
02940
02941 ast_channel_unlock(chan);
02942 return 0;
02943 }
02944
02945 *rawformat = native;
02946
02947 *format = fmt;
02948
02949 if (*trans)
02950 ast_translator_free_path(*trans);
02951
02952 if (!direction)
02953
02954 *trans = ast_translator_build_path(*format, *rawformat);
02955 else
02956
02957 *trans = ast_translator_build_path(*rawformat, *format);
02958 ast_channel_unlock(chan);
02959 if (option_debug)
02960 ast_log(LOG_DEBUG, "Set channel %s to %s format %s\n", chan->name,
02961 direction ? "write" : "read", ast_getformatname(fmt));
02962 return 0;
02963 }
02964
02965 int ast_set_read_format(struct ast_channel *chan, int fmt)
02966 {
02967 return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat,
02968 &chan->readtrans, 0);
02969 }
02970
02971 int ast_set_write_format(struct ast_channel *chan, int fmt)
02972 {
02973 return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat,
02974 &chan->writetrans, 1);
02975 }
02976
02977 char *ast_channel_reason2str(int reason)
02978 {
02979 switch (reason)
02980 {
02981 case 0:
02982 return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)";
02983 case AST_CONTROL_HANGUP:
02984 return "Hangup";
02985 case AST_CONTROL_RING:
02986 return "Local Ring";
02987 case AST_CONTROL_RINGING:
02988 return "Remote end Ringing";
02989 case AST_CONTROL_ANSWER:
02990 return "Remote end has Answered";
02991 case AST_CONTROL_BUSY:
02992 return "Remote end is Busy";
02993 case AST_CONTROL_CONGESTION:
02994 return "Congestion (circuits busy)";
02995 default:
02996 return "Unknown Reason!!";
02997 }
02998 }
02999
03000 struct ast_channel *__ast_request_and_dial(const char *type, int format, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, struct outgoing_helper *oh)
03001 {
03002 int dummy_outstate;
03003 int cause = 0;
03004 struct ast_channel *chan;
03005 int res = 0;
03006 int last_subclass = 0;
03007
03008 if (outstate)
03009 *outstate = 0;
03010 else
03011 outstate = &dummy_outstate;
03012
03013 chan = ast_request(type, format, data, &cause);
03014 if (!chan) {
03015 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
03016
03017 if (cause == AST_CAUSE_BUSY)
03018 *outstate = AST_CONTROL_BUSY;
03019 else if (cause == AST_CAUSE_CONGESTION)
03020 *outstate = AST_CONTROL_CONGESTION;
03021 return NULL;
03022 }
03023
03024 if (oh) {
03025 if (oh->vars)
03026 ast_set_variables(chan, oh->vars);
03027
03028 if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name))
03029 ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num);
03030 if (oh->parent_channel)
03031 ast_channel_inherit_variables(oh->parent_channel, chan);
03032 if (oh->account)
03033 ast_cdr_setaccount(chan, oh->account);
03034 }
03035 ast_set_callerid(chan, cid_num, cid_name, cid_num);
03036
03037 if (ast_call(chan, data, 0)) {
03038 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
03039 } else {
03040 res = 1;
03041 while (timeout && chan->_state != AST_STATE_UP) {
03042 struct ast_frame *f;
03043 res = ast_waitfor(chan, timeout);
03044 if (res <= 0)
03045 break;
03046 if (timeout > -1)
03047 timeout = res;
03048 f = ast_read(chan);
03049 if (!f) {
03050 *outstate = AST_CONTROL_HANGUP;
03051 res = 0;
03052 break;
03053 }
03054 if (f->frametype == AST_FRAME_CONTROL) {
03055 switch (f->subclass) {
03056 case AST_CONTROL_RINGING:
03057 *outstate = f->subclass;
03058 break;
03059
03060 case AST_CONTROL_BUSY:
03061 case AST_CONTROL_CONGESTION:
03062 case AST_CONTROL_ANSWER:
03063 *outstate = f->subclass;
03064 timeout = 0;
03065 break;
03066
03067
03068 case AST_CONTROL_PROGRESS:
03069 case AST_CONTROL_PROCEEDING:
03070 case AST_CONTROL_HOLD:
03071 case AST_CONTROL_UNHOLD:
03072 case AST_CONTROL_VIDUPDATE:
03073 case AST_CONTROL_SRCUPDATE:
03074 case -1:
03075 break;
03076
03077 default:
03078 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
03079 }
03080 last_subclass = f->subclass;
03081 }
03082 ast_frfree(f);
03083 }
03084 }
03085
03086
03087 if (oh) {
03088 if (!ast_strlen_zero(oh->context))
03089 ast_copy_string(chan->context, oh->context, sizeof(chan->context));
03090 if (!ast_strlen_zero(oh->exten))
03091 ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten));
03092 if (oh->priority)
03093 chan->priority = oh->priority;
03094 }
03095 if (chan->_state == AST_STATE_UP)
03096 *outstate = AST_CONTROL_ANSWER;
03097
03098 if (res <= 0) {
03099 if ( AST_CONTROL_RINGING == last_subclass )
03100 chan->hangupcause = AST_CAUSE_NO_ANSWER;
03101 if (!chan->cdr && (chan->cdr = ast_cdr_alloc()))
03102 ast_cdr_init(chan->cdr, chan);
03103 if (chan->cdr) {
03104 char tmp[256];
03105 snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data);
03106 ast_cdr_setapp(chan->cdr,"Dial",tmp);
03107 ast_cdr_update(chan);
03108 ast_cdr_start(chan->cdr);
03109 ast_cdr_end(chan->cdr);
03110
03111 if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
03112 ast_cdr_failed(chan->cdr);
03113 }
03114 ast_hangup(chan);
03115 chan = NULL;
03116 }
03117 return chan;
03118 }
03119
03120 struct ast_channel *ast_request_and_dial(const char *type, int format, void *data, int timeout, int *outstate, const char *cidnum, const char *cidname)
03121 {
03122 return __ast_request_and_dial(type, format, data, timeout, outstate, cidnum, cidname, NULL);
03123 }
03124
03125 struct ast_channel *ast_request(const char *type, int format, void *data, int *cause)
03126 {
03127 struct chanlist *chan;
03128 struct ast_channel *c;
03129 int capabilities;
03130 int fmt;
03131 int res;
03132 int foo;
03133 int videoformat = format & AST_FORMAT_VIDEO_MASK;
03134
03135 if (!cause)
03136 cause = &foo;
03137 *cause = AST_CAUSE_NOTDEFINED;
03138
03139 if (AST_LIST_LOCK(&channels)) {
03140 ast_log(LOG_WARNING, "Unable to lock channel list\n");
03141 return NULL;
03142 }
03143
03144 AST_LIST_TRAVERSE(&backends, chan, list) {
03145 if (strcasecmp(type, chan->tech->type))
03146 continue;
03147
03148 capabilities = chan->tech->capabilities;
03149 fmt = format & AST_FORMAT_AUDIO_MASK;
03150 res = ast_translator_best_choice(&fmt, &capabilities);
03151 if (res < 0) {
03152 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->tech->capabilities, format);
03153 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
03154 AST_LIST_UNLOCK(&channels);
03155 return NULL;
03156 }
03157 AST_LIST_UNLOCK(&channels);
03158 if (!chan->tech->requester)
03159 return NULL;
03160
03161 if (!(c = chan->tech->requester(type, capabilities | videoformat, data, cause)))
03162 return NULL;
03163
03164
03165 return c;
03166 }
03167
03168 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
03169 *cause = AST_CAUSE_NOSUCHDRIVER;
03170 AST_LIST_UNLOCK(&channels);
03171
03172 return NULL;
03173 }
03174
03175 int ast_call(struct ast_channel *chan, char *addr, int timeout)
03176 {
03177
03178
03179
03180 int res = -1;
03181
03182 ast_channel_lock(chan);
03183 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
03184 if (chan->cdr)
03185 ast_set_flag(chan->cdr, AST_CDR_FLAG_DIALED);
03186 if (chan->tech->call)
03187 res = chan->tech->call(chan, addr, timeout);
03188 ast_set_flag(chan, AST_FLAG_OUTGOING);
03189 }
03190 ast_channel_unlock(chan);
03191 return res;
03192 }
03193
03194
03195
03196
03197
03198
03199
03200
03201 int ast_transfer(struct ast_channel *chan, char *dest)
03202 {
03203 int res = -1;
03204
03205
03206 ast_channel_lock(chan);
03207 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
03208 if (chan->tech->transfer) {
03209 res = chan->tech->transfer(chan, dest);
03210 if (!res)
03211 res = 1;
03212 } else
03213 res = 0;
03214 }
03215 ast_channel_unlock(chan);
03216 return res;
03217 }
03218
03219 int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders)
03220 {
03221 return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1);
03222 }
03223
03224 int ast_readstring_full(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders, int audiofd, int ctrlfd)
03225 {
03226 int pos = 0;
03227 int to = ftimeout;
03228
03229
03230 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
03231 return -1;
03232 if (!len)
03233 return -1;
03234 for (;;) {
03235 int d;
03236 if (c->stream) {
03237 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
03238 ast_stopstream(c);
03239 usleep(1000);
03240 if (!d)
03241 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
03242 } else {
03243 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
03244 }
03245 if (d < 0)
03246 return -1;
03247 if (d == 0) {
03248 s[pos]='\0';
03249 return 1;
03250 }
03251 if (d == 1) {
03252 s[pos]='\0';
03253 return 2;
03254 }
03255 if (!strchr(enders, d))
03256 s[pos++] = d;
03257 if (strchr(enders, d) || (pos >= len)) {
03258 s[pos]='\0';
03259 return 0;
03260 }
03261 to = timeout;
03262 }
03263
03264 return 0;
03265 }
03266
03267 int ast_channel_supports_html(struct ast_channel *chan)
03268 {
03269 return (chan->tech->send_html) ? 1 : 0;
03270 }
03271
03272 int ast_channel_sendhtml(struct ast_channel *chan, int subclass, const char *data, int datalen)
03273 {
03274 if (chan->tech->send_html)
03275 return chan->tech->send_html(chan, subclass, data, datalen);
03276 return -1;
03277 }
03278
03279 int ast_channel_sendurl(struct ast_channel *chan, const char *url)
03280 {
03281 return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1);
03282 }
03283
03284 int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
03285 {
03286 int src;
03287 int dst;
03288
03289 if (chan->readformat == peer->writeformat && chan->writeformat == peer->readformat) {
03290
03291 return 0;
03292 }
03293
03294
03295 src = chan->nativeformats;
03296 dst = peer->nativeformats;
03297 if (ast_translator_best_choice(&dst, &src) < 0) {
03298 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, src, peer->name, dst);
03299 return -1;
03300 }
03301
03302
03303
03304
03305
03306 if ((src != dst) && ast_opt_transcode_via_slin &&
03307 (ast_translate_path_steps(dst, src) != 1))
03308 dst = AST_FORMAT_SLINEAR;
03309 if (ast_set_read_format(chan, dst) < 0) {
03310 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, dst);
03311 return -1;
03312 }
03313 if (ast_set_write_format(peer, dst) < 0) {
03314 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, dst);
03315 return -1;
03316 }
03317
03318
03319 src = peer->nativeformats;
03320 dst = chan->nativeformats;
03321 if (ast_translator_best_choice(&dst, &src) < 0) {
03322 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, src, chan->name, dst);
03323 return -1;
03324 }
03325
03326
03327
03328
03329
03330 if ((src != dst) && ast_opt_transcode_via_slin &&
03331 (ast_translate_path_steps(dst, src) != 1))
03332 dst = AST_FORMAT_SLINEAR;
03333 if (ast_set_read_format(peer, dst) < 0) {
03334 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, dst);
03335 return -1;
03336 }
03337 if (ast_set_write_format(chan, dst) < 0) {
03338 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, dst);
03339 return -1;
03340 }
03341 return 0;
03342 }
03343
03344 int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone)
03345 {
03346 int res = -1;
03347 struct ast_channel *final_orig, *final_clone, *base;
03348
03349 retrymasq:
03350 final_orig = original;
03351 final_clone = clone;
03352
03353 ast_channel_lock(original);
03354 while (ast_channel_trylock(clone)) {
03355 ast_channel_unlock(original);
03356 usleep(1);
03357 ast_channel_lock(original);
03358 }
03359
03360
03361
03362 if (original->_bridge && (original->_bridge != ast_bridged_channel(original)) && (original->_bridge->_bridge != original))
03363 final_orig = original->_bridge;
03364
03365 if (clone->_bridge && (clone->_bridge != ast_bridged_channel(clone)) && (clone->_bridge->_bridge != clone))
03366 final_clone = clone->_bridge;
03367
03368 if (final_clone->tech->get_base_channel && (base = final_clone->tech->get_base_channel(final_clone))) {
03369 final_clone = base;
03370 }
03371
03372 if ((final_orig != original) || (final_clone != clone)) {
03373
03374
03375
03376 if (ast_channel_trylock(final_orig)) {
03377 ast_channel_unlock(clone);
03378 ast_channel_unlock(original);
03379 goto retrymasq;
03380 }
03381 if (ast_channel_trylock(final_clone)) {
03382 ast_channel_unlock(final_orig);
03383 ast_channel_unlock(clone);
03384 ast_channel_unlock(original);
03385 goto retrymasq;
03386 }
03387 ast_channel_unlock(clone);
03388 ast_channel_unlock(original);
03389 original = final_orig;
03390 clone = final_clone;
03391 }
03392
03393 if (original == clone) {
03394 ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name);
03395 ast_channel_unlock(clone);
03396 ast_channel_unlock(original);
03397 return -1;
03398 }
03399
03400 if (option_debug)
03401 ast_log(LOG_DEBUG, "Planning to masquerade channel %s into the structure of %s\n",
03402 clone->name, original->name);
03403 if (original->masq) {
03404 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
03405 original->masq->name, original->name);
03406 } else if (clone->masqr) {
03407 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
03408 clone->name, clone->masqr->name);
03409 } else {
03410 original->masq = clone;
03411 clone->masqr = original;
03412 ast_queue_frame(original, &ast_null_frame);
03413 ast_queue_frame(clone, &ast_null_frame);
03414 if (option_debug)
03415 ast_log(LOG_DEBUG, "Done planning to masquerade channel %s into the structure of %s\n", clone->name, original->name);
03416 res = 0;
03417 }
03418
03419 ast_channel_unlock(clone);
03420 ast_channel_unlock(original);
03421
03422 return res;
03423 }
03424
03425 void ast_change_name(struct ast_channel *chan, char *newname)
03426 {
03427 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", chan->name, newname, chan->uniqueid);
03428 ast_string_field_set(chan, name, newname);
03429 }
03430
03431 void ast_channel_inherit_variables(const struct ast_channel *parent, struct ast_channel *child)
03432 {
03433 struct ast_var_t *current, *newvar;
03434 const char *varname;
03435
03436 AST_LIST_TRAVERSE(&parent->varshead, current, entries) {
03437 int vartype = 0;
03438
03439 varname = ast_var_full_name(current);
03440 if (!varname)
03441 continue;
03442
03443 if (varname[0] == '_') {
03444 vartype = 1;
03445 if (varname[1] == '_')
03446 vartype = 2;
03447 }
03448
03449 switch (vartype) {
03450 case 1:
03451 newvar = ast_var_assign(&varname[1], ast_var_value(current));
03452 if (newvar) {
03453 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
03454 if (option_debug)
03455 ast_log(LOG_DEBUG, "Copying soft-transferable variable %s.\n", ast_var_name(newvar));
03456 }
03457 break;
03458 case 2:
03459 newvar = ast_var_assign(ast_var_full_name(current), ast_var_value(current));
03460 if (newvar) {
03461 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
03462 if (option_debug)
03463 ast_log(LOG_DEBUG, "Copying hard-transferable variable %s.\n", ast_var_name(newvar));
03464 }
03465 break;
03466 default:
03467 if (option_debug)
03468 ast_log(LOG_DEBUG, "Not copying variable %s.\n", ast_var_name(current));
03469 break;
03470 }
03471 }
03472 }
03473
03474
03475
03476
03477
03478
03479
03480
03481
03482
03483 static void clone_variables(struct ast_channel *original, struct ast_channel *clone)
03484 {
03485 struct ast_var_t *current, *newvar;
03486
03487
03488 if (AST_LIST_FIRST(&clone->varshead))
03489 AST_LIST_APPEND_LIST(&original->varshead, &clone->varshead, entries);
03490
03491
03492
03493 AST_LIST_TRAVERSE(&original->varshead, current, entries) {
03494 newvar = ast_var_assign(current->name, current->value);
03495 if (newvar)
03496 AST_LIST_INSERT_TAIL(&clone->varshead, newvar, entries);
03497 }
03498 }
03499
03500
03501
03502
03503
03504
03505 int ast_do_masquerade(struct ast_channel *original)
03506 {
03507 int x,i;
03508 int res=0;
03509 int origstate;
03510 struct ast_frame *cur;
03511 const struct ast_channel_tech *t;
03512 void *t_pvt;
03513 struct ast_callerid tmpcid;
03514 struct ast_channel *clone = original->masq;
03515 struct ast_cdr *cdr;
03516 int rformat = original->readformat;
03517 int wformat = original->writeformat;
03518 char newn[100];
03519 char orig[100];
03520 char masqn[100];
03521 char zombn[100];
03522
03523 if (option_debug > 3)
03524 ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",
03525 clone->name, clone->_state, original->name, original->_state);
03526
03527
03528
03529
03530
03531
03532
03533 ast_channel_lock(clone);
03534
03535 if (option_debug > 1)
03536 ast_log(LOG_DEBUG, "Got clone lock for masquerade on '%s' at %p\n", clone->name, &clone->lock);
03537
03538
03539
03540 free_translation(clone);
03541 free_translation(original);
03542
03543
03544
03545 original->masq = NULL;
03546 clone->masqr = NULL;
03547
03548
03549 ast_copy_string(orig, original->name, sizeof(orig));
03550
03551 ast_copy_string(newn, clone->name, sizeof(newn));
03552
03553 snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn);
03554
03555
03556 ast_string_field_set(original, name, newn);
03557
03558
03559 ast_string_field_set(clone, name, masqn);
03560
03561
03562 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", newn, masqn, clone->uniqueid);
03563 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", orig, newn, original->uniqueid);
03564
03565
03566 t = original->tech;
03567 original->tech = clone->tech;
03568 clone->tech = t;
03569
03570
03571 cdr = original->cdr;
03572 original->cdr = clone->cdr;
03573 clone->cdr = cdr;
03574
03575 t_pvt = original->tech_pvt;
03576 original->tech_pvt = clone->tech_pvt;
03577 clone->tech_pvt = t_pvt;
03578
03579
03580 for (i = 0; i < 2; i++) {
03581 x = original->alertpipe[i];
03582 original->alertpipe[i] = clone->alertpipe[i];
03583 clone->alertpipe[i] = x;
03584 }
03585
03586
03587
03588
03589
03590
03591
03592
03593
03594
03595
03596
03597 {
03598 AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq;
03599 AST_LIST_HEAD_SET_NOLOCK(&tmp_readq, NULL);
03600
03601 AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list);
03602 AST_LIST_APPEND_LIST(&original->readq, &clone->readq, frame_list);
03603
03604 while ((cur = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) {
03605 AST_LIST_INSERT_TAIL(&original->readq, cur, frame_list);
03606 if (original->alertpipe[1] > -1) {
03607 int poke = 0;
03608
03609 if (write(original->alertpipe[1], &poke, sizeof(poke)) < 0) {
03610 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
03611 }
03612 }
03613 }
03614 }
03615
03616
03617 x = original->rawreadformat;
03618 original->rawreadformat = clone->rawreadformat;
03619 clone->rawreadformat = x;
03620 x = original->rawwriteformat;
03621 original->rawwriteformat = clone->rawwriteformat;
03622 clone->rawwriteformat = x;
03623
03624 clone->_softhangup = AST_SOFTHANGUP_DEV;
03625
03626
03627
03628
03629
03630 origstate = original->_state;
03631 original->_state = clone->_state;
03632 clone->_state = origstate;
03633
03634 if (clone->tech->fixup){
03635 res = clone->tech->fixup(original, clone);
03636 if (res)
03637 ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name);
03638 }
03639
03640
03641 if (clone->tech->hangup)
03642 res = clone->tech->hangup(clone);
03643 if (res) {
03644 ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n");
03645 ast_channel_unlock(clone);
03646 return -1;
03647 }
03648
03649 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig);
03650
03651 ast_string_field_set(clone, name, zombn);
03652 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", masqn, zombn, clone->uniqueid);
03653
03654
03655 t_pvt = original->monitor;
03656 original->monitor = clone->monitor;
03657 clone->monitor = t_pvt;
03658
03659
03660 ast_string_field_set(original, language, clone->language);
03661
03662 for (x = 0; x < AST_MAX_FDS; x++) {
03663 if (x != AST_GENERATOR_FD)
03664 original->fds[x] = clone->fds[x];
03665 }
03666
03667 ast_app_group_update(clone, original);
03668
03669 if (AST_LIST_FIRST(&clone->datastores)) {
03670 struct ast_datastore *ds;
03671 AST_LIST_TRAVERSE(&clone->datastores, ds, entry) {
03672 if (ds->info->chan_fixup)
03673 ds->info->chan_fixup(ds->data, clone, original);
03674 }
03675 AST_LIST_APPEND_LIST(&original->datastores, &clone->datastores, entry);
03676 }
03677
03678 clone_variables(original, clone);
03679
03680 original->adsicpe = clone->adsicpe;
03681
03682
03683
03684
03685
03686 ast_set_flag(original, ast_test_flag(clone, AST_FLAG_OUTGOING | AST_FLAG_EXCEPTION));
03687 original->fdno = clone->fdno;
03688
03689
03690
03691
03692
03693
03694 tmpcid = original->cid;
03695 original->cid = clone->cid;
03696 clone->cid = tmpcid;
03697
03698
03699 original->fds[AST_TIMING_FD] = original->timingfd;
03700
03701
03702 original->nativeformats = clone->nativeformats;
03703
03704
03705
03706
03707
03708 ast_set_write_format(original, wformat);
03709
03710
03711 ast_set_read_format(original, rformat);
03712
03713
03714 ast_string_field_set(original, musicclass, clone->musicclass);
03715
03716 if (option_debug)
03717 ast_log(LOG_DEBUG, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat);
03718
03719
03720
03721 if (original->tech->fixup) {
03722 res = original->tech->fixup(clone, original);
03723 if (res) {
03724 ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n",
03725 original->tech->type, original->name);
03726 ast_channel_unlock(clone);
03727 return -1;
03728 }
03729 } else
03730 ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)! Bad things may happen.\n",
03731 original->tech->type, original->name);
03732
03733
03734
03735
03736
03737
03738
03739
03740
03741 if (original->visible_indication) {
03742 ast_indicate(original, original->visible_indication);
03743 }
03744
03745
03746
03747
03748 if (ast_test_flag(clone, AST_FLAG_ZOMBIE)) {
03749 if (option_debug)
03750 ast_log(LOG_DEBUG, "Destroying channel clone '%s'\n", clone->name);
03751 ast_channel_unlock(clone);
03752 manager_event(EVENT_FLAG_CALL, "Hangup",
03753 "Channel: %s\r\n"
03754 "Uniqueid: %s\r\n"
03755 "Cause: %d\r\n"
03756 "Cause-txt: %s\r\n",
03757 clone->name,
03758 clone->uniqueid,
03759 clone->hangupcause,
03760 ast_cause2str(clone->hangupcause)
03761 );
03762 ast_channel_free(clone);
03763 } else {
03764 if (option_debug)
03765 ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name);
03766 ast_set_flag(clone, AST_FLAG_ZOMBIE);
03767 ast_queue_frame(clone, &ast_null_frame);
03768 ast_channel_unlock(clone);
03769 }
03770
03771
03772 if (ast_test_flag(original, AST_FLAG_BLOCKING))
03773 pthread_kill(original->blocker, SIGURG);
03774 if (option_debug)
03775 ast_log(LOG_DEBUG, "Done Masquerading %s (%d)\n", original->name, original->_state);
03776 return 0;
03777 }
03778
03779 void ast_set_callerid(struct ast_channel *chan, const char *callerid, const char *calleridname, const char *ani)
03780 {
03781 ast_channel_lock(chan);
03782
03783 if (callerid) {
03784 if (chan->cid.cid_num)
03785 free(chan->cid.cid_num);
03786 chan->cid.cid_num = ast_strdup(callerid);
03787 }
03788 if (calleridname) {
03789 if (chan->cid.cid_name)
03790 free(chan->cid.cid_name);
03791 chan->cid.cid_name = ast_strdup(calleridname);
03792 }
03793 if (ani) {
03794 if (chan->cid.cid_ani)
03795 free(chan->cid.cid_ani);
03796 chan->cid.cid_ani = ast_strdup(ani);
03797 }
03798 manager_event(EVENT_FLAG_CALL, "Newcallerid",
03799 "Channel: %s\r\n"
03800 "CallerID: %s\r\n"
03801 "CallerIDName: %s\r\n"
03802 "Uniqueid: %s\r\n"
03803 "CID-CallingPres: %d (%s)\r\n",
03804 chan->name,
03805 S_OR(chan->cid.cid_num, "<Unknown>"),
03806 S_OR(chan->cid.cid_name, "<Unknown>"),
03807 chan->uniqueid,
03808 chan->cid.cid_pres,
03809 ast_describe_caller_presentation(chan->cid.cid_pres)
03810 );
03811
03812 ast_channel_unlock(chan);
03813 }
03814
03815 int ast_setstate(struct ast_channel *chan, enum ast_channel_state state)
03816 {
03817 char name[AST_CHANNEL_NAME], *dashptr;
03818 int oldstate = chan->_state;
03819
03820 if (oldstate == state)
03821 return 0;
03822
03823 ast_copy_string(name, chan->name, sizeof(name));
03824 if ((dashptr = strrchr(name, '-'))) {
03825 *dashptr = '\0';
03826 }
03827
03828 chan->_state = state;
03829 ast_device_state_changed_literal(name);
03830
03831 manager_event(EVENT_FLAG_CALL,
03832 "Newstate",
03833 "Channel: %s\r\n"
03834 "State: %s\r\n"
03835 "CallerID: %s\r\n"
03836 "CallerIDName: %s\r\n"
03837 "Uniqueid: %s\r\n",
03838 chan->name, ast_state2str(chan->_state),
03839 S_OR(chan->cid.cid_num, "<unknown>"),
03840 S_OR(chan->cid.cid_name, "<unknown>"),
03841 chan->uniqueid);
03842
03843 return 0;
03844 }
03845
03846
03847 struct ast_channel *ast_bridged_channel(struct ast_channel *chan)
03848 {
03849 struct ast_channel *bridged;
03850 bridged = chan->_bridge;
03851 if (bridged && bridged->tech->bridged_channel)
03852 bridged = bridged->tech->bridged_channel(chan, bridged);
03853 return bridged;
03854 }
03855
03856 static void bridge_playfile(struct ast_channel *chan, struct ast_channel *peer, const char *sound, int remain)
03857 {
03858 int min = 0, sec = 0, check;
03859
03860 check = ast_autoservice_start(peer);
03861 if (check)
03862 return;
03863
03864 if (remain > 0) {
03865 if (remain / 60 > 1) {
03866 min = remain / 60;
03867 sec = remain % 60;
03868 } else {
03869 sec = remain;
03870 }
03871 }
03872
03873 if (!strcmp(sound,"timeleft")) {
03874 ast_stream_and_wait(chan, "vm-youhave", chan->language, "");
03875 if (min) {
03876 ast_say_number(chan, min, AST_DIGIT_ANY, chan->language, NULL);
03877 ast_stream_and_wait(chan, "queue-minutes", chan->language, "");
03878 }
03879 if (sec) {
03880 ast_say_number(chan, sec, AST_DIGIT_ANY, chan->language, NULL);
03881 ast_stream_and_wait(chan, "queue-seconds", chan->language, "");
03882 }
03883 } else {
03884 ast_stream_and_wait(chan, sound, chan->language, "");
03885 }
03886
03887 ast_autoservice_stop(peer);
03888 }
03889
03890 static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct ast_channel *c1,
03891 struct ast_bridge_config *config, struct ast_frame **fo,
03892 struct ast_channel **rc, struct timeval bridge_end)
03893 {
03894
03895 struct ast_channel *cs[3];
03896 struct ast_frame *f;
03897 enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
03898 int o0nativeformats;
03899 int o1nativeformats;
03900 int watch_c0_dtmf;
03901 int watch_c1_dtmf;
03902 void *pvt0, *pvt1;
03903
03904 int frame_put_in_jb = 0;
03905 int jb_in_use;
03906 int to;
03907
03908 cs[0] = c0;
03909 cs[1] = c1;
03910 pvt0 = c0->tech_pvt;
03911 pvt1 = c1->tech_pvt;
03912 o0nativeformats = c0->nativeformats;
03913 o1nativeformats = c1->nativeformats;
03914 watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0;
03915 watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1;
03916
03917
03918 jb_in_use = ast_jb_do_usecheck(c0, c1);
03919 if (jb_in_use)
03920 ast_jb_empty_and_reset(c0, c1);
03921
03922 for (;;) {
03923 struct ast_channel *who, *other;
03924
03925 if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) ||
03926 (o0nativeformats != c0->nativeformats) ||
03927 (o1nativeformats != c1->nativeformats)) {
03928
03929 res = AST_BRIDGE_RETRY;
03930 break;
03931 }
03932 if (bridge_end.tv_sec) {
03933 to = ast_tvdiff_ms(bridge_end, ast_tvnow());
03934 if (to <= 0) {
03935 if (config->timelimit)
03936 res = AST_BRIDGE_RETRY;
03937 else
03938 res = AST_BRIDGE_COMPLETE;
03939 break;
03940 }
03941 } else
03942 to = -1;
03943
03944
03945 if (jb_in_use)
03946 to = ast_jb_get_when_to_wakeup(c0, c1, to);
03947 who = ast_waitfor_n(cs, 2, &to);
03948 if (!who) {
03949
03950 if (jb_in_use)
03951 ast_jb_get_and_deliver(c0, c1);
03952 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
03953 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03954 c0->_softhangup = 0;
03955 if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03956 c1->_softhangup = 0;
03957 c0->_bridge = c1;
03958 c1->_bridge = c0;
03959 }
03960 continue;
03961 }
03962 f = ast_read(who);
03963 if (!f) {
03964 *fo = NULL;
03965 *rc = who;
03966 if (option_debug)
03967 ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name);
03968 break;
03969 }
03970
03971 other = (who == c0) ? c1 : c0;
03972
03973 if (jb_in_use)
03974 frame_put_in_jb = !ast_jb_put(other, f);
03975
03976 if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) {
03977 int bridge_exit = 0;
03978
03979 switch (f->subclass) {
03980 case AST_CONTROL_HOLD:
03981 case AST_CONTROL_UNHOLD:
03982 case AST_CONTROL_VIDUPDATE:
03983 case AST_CONTROL_SRCUPDATE:
03984 ast_indicate_data(other, f->subclass, f->data, f->datalen);
03985 if (jb_in_use) {
03986 ast_jb_empty_and_reset(c0, c1);
03987 }
03988 break;
03989 default:
03990 *fo = f;
03991 *rc = who;
03992 bridge_exit = 1;
03993 if (option_debug)
03994 ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name);
03995 break;
03996 }
03997 if (bridge_exit)
03998 break;
03999 }
04000 if ((f->frametype == AST_FRAME_VOICE) ||
04001 (f->frametype == AST_FRAME_DTMF_BEGIN) ||
04002 (f->frametype == AST_FRAME_DTMF) ||
04003 (f->frametype == AST_FRAME_VIDEO) ||
04004 (f->frametype == AST_FRAME_IMAGE) ||
04005 (f->frametype == AST_FRAME_HTML) ||
04006 (f->frametype == AST_FRAME_MODEM) ||
04007 (f->frametype == AST_FRAME_TEXT)) {
04008
04009 int monitored_source = (who == c0) ? watch_c0_dtmf : watch_c1_dtmf;
04010
04011 if (monitored_source &&
04012 (f->frametype == AST_FRAME_DTMF_END ||
04013 f->frametype == AST_FRAME_DTMF_BEGIN)) {
04014 *fo = f;
04015 *rc = who;
04016 if (option_debug)
04017 ast_log(LOG_DEBUG, "Got DTMF %s on channel (%s)\n",
04018 f->frametype == AST_FRAME_DTMF_END ? "end" : "begin",
04019 who->name);
04020 break;
04021 }
04022
04023 if (!frame_put_in_jb)
04024 ast_write(other, f);
04025
04026
04027 if (jb_in_use)
04028 ast_jb_get_and_deliver(c0, c1);
04029 }
04030
04031 ast_frfree(f);
04032
04033
04034 cs[2] = cs[0];
04035 cs[0] = cs[1];
04036 cs[1] = cs[2];
04037 }
04038 return res;
04039 }
04040
04041
04042 enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1,
04043 struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc)
04044 {
04045 struct ast_channel *who = NULL;
04046 enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
04047 int nativefailed=0;
04048 int firstpass;
04049 int o0nativeformats;
04050 int o1nativeformats;
04051 long time_left_ms=0;
04052 struct timeval nexteventts = { 0, };
04053 char caller_warning = 0;
04054 char callee_warning = 0;
04055
04056 if (c0->_bridge) {
04057 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
04058 c0->name, c0->_bridge->name);
04059 return -1;
04060 }
04061 if (c1->_bridge) {
04062 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
04063 c1->name, c1->_bridge->name);
04064 return -1;
04065 }
04066
04067
04068 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
04069 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1))
04070 return -1;
04071
04072 *fo = NULL;
04073 firstpass = config->firstpass;
04074 config->firstpass = 0;
04075
04076 if (ast_tvzero(config->start_time))
04077 config->start_time = ast_tvnow();
04078 time_left_ms = config->timelimit;
04079
04080 caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING);
04081 callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING);
04082
04083 if (config->start_sound && firstpass) {
04084 if (caller_warning)
04085 bridge_playfile(c0, c1, config->start_sound, time_left_ms / 1000);
04086 if (callee_warning)
04087 bridge_playfile(c1, c0, config->start_sound, time_left_ms / 1000);
04088 }
04089
04090
04091 c0->_bridge = c1;
04092 c1->_bridge = c0;
04093
04094
04095 manager_event(EVENT_FLAG_CALL, "Link",
04096 "Channel1: %s\r\n"
04097 "Channel2: %s\r\n"
04098 "Uniqueid1: %s\r\n"
04099 "Uniqueid2: %s\r\n"
04100 "CallerID1: %s\r\n"
04101 "CallerID2: %s\r\n",
04102 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
04103
04104 o0nativeformats = c0->nativeformats;
04105 o1nativeformats = c1->nativeformats;
04106
04107 if (config->feature_timer) {
04108 nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->feature_timer, 1000));
04109 } else if (config->timelimit) {
04110 nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
04111 if (caller_warning || callee_warning)
04112 nexteventts = ast_tvsub(nexteventts, ast_samp2tv(config->play_warning, 1000));
04113 }
04114
04115 if (!c0->tech->send_digit_begin)
04116 ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY);
04117 if (!c1->tech->send_digit_begin)
04118 ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY);
04119
04120
04121 ast_indicate(c0, AST_CONTROL_SRCUPDATE);
04122 ast_indicate(c1, AST_CONTROL_SRCUPDATE);
04123
04124 for (;;) {
04125 struct timeval now = { 0, };
04126 int to;
04127
04128 to = -1;
04129
04130 if (!ast_tvzero(nexteventts)) {
04131 now = ast_tvnow();
04132 to = ast_tvdiff_ms(nexteventts, now);
04133 if (to <= 0) {
04134 if (!config->timelimit) {
04135 res = AST_BRIDGE_COMPLETE;
04136 break;
04137 }
04138 to = 0;
04139 }
04140 }
04141
04142 if (config->timelimit) {
04143 time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time);
04144 if (time_left_ms < to)
04145 to = time_left_ms;
04146
04147 if (time_left_ms <= 0) {
04148 if (caller_warning && config->end_sound)
04149 bridge_playfile(c0, c1, config->end_sound, 0);
04150 if (callee_warning && config->end_sound)
04151 bridge_playfile(c1, c0, config->end_sound, 0);
04152 *fo = NULL;
04153 if (who)
04154 *rc = who;
04155 res = 0;
04156 break;
04157 }
04158
04159 if (!to) {
04160 if (time_left_ms >= 5000 && config->warning_sound && config->play_warning) {
04161 int t = (time_left_ms + 500) / 1000;
04162 if (caller_warning)
04163 bridge_playfile(c0, c1, config->warning_sound, t);
04164 if (callee_warning)
04165 bridge_playfile(c1, c0, config->warning_sound, t);
04166 }
04167 if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000)))
04168 nexteventts = ast_tvadd(nexteventts, ast_samp2tv(config->warning_freq, 1000));
04169 else
04170 nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
04171 }
04172 }
04173
04174 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
04175 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
04176 c0->_softhangup = 0;
04177 if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
04178 c1->_softhangup = 0;
04179 c0->_bridge = c1;
04180 c1->_bridge = c0;
04181 if (option_debug)
04182 ast_log(LOG_DEBUG, "Unbridge signal received. Ending native bridge.\n");
04183 continue;
04184 }
04185
04186
04187 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
04188 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) {
04189 *fo = NULL;
04190 if (who)
04191 *rc = who;
04192 res = 0;
04193 if (option_debug)
04194 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",
04195 c0->name, c1->name,
04196 ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No",
04197 ast_check_hangup(c0) ? "Yes" : "No",
04198 ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No",
04199 ast_check_hangup(c1) ? "Yes" : "No");
04200 break;
04201 }
04202
04203
04204 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER")))
04205 pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1->name);
04206 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER")))
04207 pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0->name);
04208
04209 if (c0->tech->bridge &&
04210 (config->timelimit == 0) &&
04211 (c0->tech->bridge == c1->tech->bridge) &&
04212 !nativefailed && !c0->monitor && !c1->monitor &&
04213 !c0->audiohooks && !c1->audiohooks && !ast_test_flag(&(config->features_callee),AST_FEATURE_REDIRECT) &&
04214 !ast_test_flag(&(config->features_caller),AST_FEATURE_REDIRECT) &&
04215 !c0->masq && !c0->masqr && !c1->masq && !c1->masqr) {
04216
04217 ast_set_flag(c0, AST_FLAG_NBRIDGE);
04218 ast_set_flag(c1, AST_FLAG_NBRIDGE);
04219 if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, to)) == AST_BRIDGE_COMPLETE) {
04220
04221 manager_event(EVENT_FLAG_CALL, "Unlink",
04222 "Channel1: %s\r\n"
04223 "Channel2: %s\r\n"
04224 "Uniqueid1: %s\r\n"
04225 "Uniqueid2: %s\r\n"
04226 "CallerID1: %s\r\n"
04227 "CallerID2: %s\r\n",
04228 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
04229 if (option_debug)
04230 ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name);
04231
04232 ast_clear_flag(c0, AST_FLAG_NBRIDGE);
04233 ast_clear_flag(c1, AST_FLAG_NBRIDGE);
04234
04235 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
04236 continue;
04237
04238 c0->_bridge = NULL;
04239 c1->_bridge = NULL;
04240
04241 return res;
04242 } else {
04243 ast_clear_flag(c0, AST_FLAG_NBRIDGE);
04244 ast_clear_flag(c1, AST_FLAG_NBRIDGE);
04245 }
04246 switch (res) {
04247 case AST_BRIDGE_RETRY:
04248 continue;
04249 default:
04250 if (option_verbose > 2)
04251 ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s ended\n",
04252 c0->name, c1->name);
04253
04254 case AST_BRIDGE_FAILED_NOWARN:
04255 nativefailed++;
04256 break;
04257 }
04258 }
04259
04260 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) ||
04261 (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) &&
04262 !(c0->generator || c1->generator)) {
04263 if (ast_channel_make_compatible(c0, c1)) {
04264 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
04265
04266 manager_event(EVENT_FLAG_CALL, "Unlink",
04267 "Channel1: %s\r\n"
04268 "Channel2: %s\r\n"
04269 "Uniqueid1: %s\r\n"
04270 "Uniqueid2: %s\r\n"
04271 "CallerID1: %s\r\n"
04272 "CallerID2: %s\r\n",
04273 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
04274 return AST_BRIDGE_FAILED;
04275 }
04276 o0nativeformats = c0->nativeformats;
04277 o1nativeformats = c1->nativeformats;
04278 }
04279
04280 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER")))
04281 pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1->name);
04282 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER")))
04283 pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0->name);
04284
04285 res = ast_generic_bridge(c0, c1, config, fo, rc, nexteventts);
04286 if (res != AST_BRIDGE_RETRY)
04287 break;
04288 }
04289
04290 ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY);
04291 ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY);
04292
04293
04294 ast_indicate(c0, AST_CONTROL_SRCUPDATE);
04295 ast_indicate(c1, AST_CONTROL_SRCUPDATE);
04296
04297 c0->_bridge = NULL;
04298 c1->_bridge = NULL;
04299
04300
04301 manager_event(EVENT_FLAG_CALL, "Unlink",
04302 "Channel1: %s\r\n"
04303 "Channel2: %s\r\n"
04304 "Uniqueid1: %s\r\n"
04305 "Uniqueid2: %s\r\n"
04306 "CallerID1: %s\r\n"
04307 "CallerID2: %s\r\n",
04308 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
04309 if (option_debug)
04310 ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name);
04311
04312 return res;
04313 }
04314
04315
04316 int ast_channel_setoption(struct ast_channel *chan, int option, void *data, int datalen, int block)
04317 {
04318 int res;
04319
04320 if (chan->tech->setoption) {
04321 res = chan->tech->setoption(chan, option, data, datalen);
04322 if (res < 0)
04323 return res;
04324 } else {
04325 errno = ENOSYS;
04326 return -1;
04327 }
04328 if (block) {
04329
04330
04331 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
04332 return -1;
04333 }
04334 return 0;
04335 }
04336
04337 struct tonepair_def {
04338 int freq1;
04339 int freq2;
04340 int duration;
04341 int vol;
04342 };
04343
04344 struct tonepair_state {
04345 int fac1;
04346 int fac2;
04347 int v1_1;
04348 int v2_1;
04349 int v3_1;
04350 int v1_2;
04351 int v2_2;
04352 int v3_2;
04353 int origwfmt;
04354 int pos;
04355 int duration;
04356 int modulate;
04357 struct ast_frame f;
04358 unsigned char offset[AST_FRIENDLY_OFFSET];
04359 short data[4000];
04360 };
04361
04362 static void tonepair_release(struct ast_channel *chan, void *params)
04363 {
04364 struct tonepair_state *ts = params;
04365
04366 if (chan)
04367 ast_set_write_format(chan, ts->origwfmt);
04368 free(ts);
04369 }
04370
04371 static void *tonepair_alloc(struct ast_channel *chan, void *params)
04372 {
04373 struct tonepair_state *ts;
04374 struct tonepair_def *td = params;
04375
04376 if (!(ts = ast_calloc(1, sizeof(*ts))))
04377 return NULL;
04378 ts->origwfmt = chan->writeformat;
04379 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
04380 ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
04381 tonepair_release(NULL, ts);
04382 ts = NULL;
04383 } else {
04384 ts->fac1 = 2.0 * cos(2.0 * M_PI * (td->freq1 / 8000.0)) * 32768.0;
04385 ts->v1_1 = 0;
04386 ts->v2_1 = sin(-4.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
04387 ts->v3_1 = sin(-2.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
04388 ts->v2_1 = 0;
04389 ts->fac2 = 2.0 * cos(2.0 * M_PI * (td->freq2 / 8000.0)) * 32768.0;
04390 ts->v2_2 = sin(-4.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
04391 ts->v3_2 = sin(-2.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
04392 ts->duration = td->duration;
04393 ts->modulate = 0;
04394 }
04395
04396 ast_set_flag(chan, AST_FLAG_WRITE_INT);
04397 return ts;
04398 }
04399
04400 static int tonepair_generator(struct ast_channel *chan, void *data, int len, int samples)
04401 {
04402 struct tonepair_state *ts = data;
04403 int x;
04404
04405
04406
04407
04408 len = samples * 2;
04409
04410 if (len > sizeof(ts->data) / 2 - 1) {
04411 ast_log(LOG_WARNING, "Can't generate that much data!\n");
04412 return -1;
04413 }
04414 memset(&ts->f, 0, sizeof(ts->f));
04415 for (x=0;x<len/2;x++) {
04416 ts->v1_1 = ts->v2_1;
04417 ts->v2_1 = ts->v3_1;
04418 ts->v3_1 = (ts->fac1 * ts->v2_1 >> 15) - ts->v1_1;
04419
04420 ts->v1_2 = ts->v2_2;
04421 ts->v2_2 = ts->v3_2;
04422 ts->v3_2 = (ts->fac2 * ts->v2_2 >> 15) - ts->v1_2;
04423 if (ts->modulate) {
04424 int p;
04425 p = ts->v3_2 - 32768;
04426 if (p < 0) p = -p;
04427 p = ((p * 9) / 10) + 1;
04428 ts->data[x] = (ts->v3_1 * p) >> 15;
04429 } else
04430 ts->data[x] = ts->v3_1 + ts->v3_2;
04431 }
04432 ts->f.frametype = AST_FRAME_VOICE;
04433 ts->f.subclass = AST_FORMAT_SLINEAR;
04434 ts->f.datalen = len;
04435 ts->f.samples = samples;
04436 ts->f.offset = AST_FRIENDLY_OFFSET;
04437 ts->f.data = ts->data;
04438 ast_write(chan, &ts->f);
04439 ts->pos += x;
04440 if (ts->duration > 0) {
04441 if (ts->pos >= ts->duration * 8)
04442 return -1;
04443 }
04444 return 0;
04445 }
04446
04447 static struct ast_generator tonepair = {
04448 alloc: tonepair_alloc,
04449 release: tonepair_release,
04450 generate: tonepair_generator,
04451 };
04452
04453 int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
04454 {
04455 struct tonepair_def d = { 0, };
04456
04457 d.freq1 = freq1;
04458 d.freq2 = freq2;
04459 d.duration = duration;
04460 d.vol = (vol < 1) ? 8192 : vol;
04461 if (ast_activate_generator(chan, &tonepair, &d))
04462 return -1;
04463 return 0;
04464 }
04465
04466 void ast_tonepair_stop(struct ast_channel *chan)
04467 {
04468 ast_deactivate_generator(chan);
04469 }
04470
04471 int ast_tonepair(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
04472 {
04473 int res;
04474
04475 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
04476 return res;
04477
04478
04479 while (chan->generatordata && ast_waitfor(chan, 100) >= 0) {
04480 struct ast_frame *f = ast_read(chan);
04481 if (f)
04482 ast_frfree(f);
04483 else
04484 return -1;
04485 }
04486 return 0;
04487 }
04488
04489 ast_group_t ast_get_group(const char *s)
04490 {
04491 char *piece;
04492 char *c;
04493 int start=0, finish=0, x;
04494 ast_group_t group = 0;
04495
04496 if (ast_strlen_zero(s))
04497 return 0;
04498
04499 c = ast_strdupa(s);
04500
04501 while ((piece = strsep(&c, ","))) {
04502 if (sscanf(piece, "%d-%d", &start, &finish) == 2) {
04503
04504 } else if (sscanf(piece, "%d", &start)) {
04505
04506 finish = start;
04507 } else {
04508 ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece);
04509 continue;
04510 }
04511 for (x = start; x <= finish; x++) {
04512 if ((x > 63) || (x < 0)) {
04513 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x);
04514 } else
04515 group |= ((ast_group_t) 1 << x);
04516 }
04517 }
04518 return group;
04519 }
04520
04521 static int (*ast_moh_start_ptr)(struct ast_channel *, const char *, const char *) = NULL;
04522 static void (*ast_moh_stop_ptr)(struct ast_channel *) = NULL;
04523 static void (*ast_moh_cleanup_ptr)(struct ast_channel *) = NULL;
04524
04525 void ast_install_music_functions(int (*start_ptr)(struct ast_channel *, const char *, const char *),
04526 void (*stop_ptr)(struct ast_channel *),
04527 void (*cleanup_ptr)(struct ast_channel *))
04528 {
04529 ast_moh_start_ptr = start_ptr;
04530 ast_moh_stop_ptr = stop_ptr;
04531 ast_moh_cleanup_ptr = cleanup_ptr;
04532 }
04533
04534 void ast_uninstall_music_functions(void)
04535 {
04536 ast_moh_start_ptr = NULL;
04537 ast_moh_stop_ptr = NULL;
04538 ast_moh_cleanup_ptr = NULL;
04539 }
04540
04541
04542 int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
04543 {
04544 if (ast_moh_start_ptr)
04545 return ast_moh_start_ptr(chan, mclass, interpclass);
04546
04547 if (option_verbose > 2) {
04548 ast_verbose(VERBOSE_PREFIX_3 "Music class %s requested but no musiconhold loaded.\n",
04549 mclass ? mclass : (interpclass ? interpclass : "default"));
04550 }
04551
04552 return 0;
04553 }
04554
04555
04556 void ast_moh_stop(struct ast_channel *chan)
04557 {
04558 if (ast_moh_stop_ptr)
04559 ast_moh_stop_ptr(chan);
04560 }
04561
04562 void ast_moh_cleanup(struct ast_channel *chan)
04563 {
04564 if (ast_moh_cleanup_ptr)
04565 ast_moh_cleanup_ptr(chan);
04566 }
04567
04568 void ast_channels_init(void)
04569 {
04570 ast_cli_register_multiple(cli_channel, sizeof(cli_channel) / sizeof(struct ast_cli_entry));
04571 }
04572
04573
04574 char *ast_print_group(char *buf, int buflen, ast_group_t group)
04575 {
04576 unsigned int i;
04577 int first=1;
04578 char num[3];
04579
04580 buf[0] = '\0';
04581
04582 if (!group)
04583 return buf;
04584
04585 for (i = 0; i <= 63; i++) {
04586 if (group & ((ast_group_t) 1 << i)) {
04587 if (!first) {
04588 strncat(buf, ", ", buflen - strlen(buf) - 1);
04589 } else {
04590 first=0;
04591 }
04592 snprintf(num, sizeof(num), "%u", i);
04593 strncat(buf, num, buflen - strlen(buf) - 1);
04594 }
04595 }
04596 return buf;
04597 }
04598
04599 void ast_set_variables(struct ast_channel *chan, struct ast_variable *vars)
04600 {
04601 struct ast_variable *cur;
04602
04603 for (cur = vars; cur; cur = cur->next)
04604 pbx_builtin_setvar_helper(chan, cur->name, cur->value);
04605 }
04606
04607 static void *silence_generator_alloc(struct ast_channel *chan, void *data)
04608 {
04609
04610 return data;
04611 }
04612
04613 static void silence_generator_release(struct ast_channel *chan, void *data)
04614 {
04615
04616 }
04617
04618 static int silence_generator_generate(struct ast_channel *chan, void *data, int len, int samples)
04619 {
04620 short buf[samples];
04621 struct ast_frame frame = {
04622 .frametype = AST_FRAME_VOICE,
04623 .subclass = AST_FORMAT_SLINEAR,
04624 .data = buf,
04625 .samples = samples,
04626 .datalen = sizeof(buf),
04627 };
04628 memset(buf, 0, sizeof(buf));
04629 if (ast_write(chan, &frame))
04630 return -1;
04631 return 0;
04632 }
04633
04634 static struct ast_generator silence_generator = {
04635 .alloc = silence_generator_alloc,
04636 .release = silence_generator_release,
04637 .generate = silence_generator_generate,
04638 };
04639
04640 struct ast_silence_generator {
04641 int old_write_format;
04642 };
04643
04644 struct ast_silence_generator *ast_channel_start_silence_generator(struct ast_channel *chan)
04645 {
04646 struct ast_silence_generator *state;
04647
04648 if (!(state = ast_calloc(1, sizeof(*state)))) {
04649 return NULL;
04650 }
04651
04652 state->old_write_format = chan->writeformat;
04653
04654 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
04655 ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
04656 free(state);
04657 return NULL;
04658 }
04659
04660 ast_activate_generator(chan, &silence_generator, state);
04661
04662 if (option_debug)
04663 ast_log(LOG_DEBUG, "Started silence generator on '%s'\n", chan->name);
04664
04665 return state;
04666 }
04667
04668 void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_silence_generator *state)
04669 {
04670 if (!state)
04671 return;
04672
04673 ast_deactivate_generator(chan);
04674
04675 if (option_debug)
04676 ast_log(LOG_DEBUG, "Stopped silence generator on '%s'\n", chan->name);
04677
04678 if (ast_set_write_format(chan, state->old_write_format) < 0)
04679 ast_log(LOG_ERROR, "Could not return write format to its original state\n");
04680
04681 free(state);
04682 }
04683
04684
04685
04686 const char *channelreloadreason2txt(enum channelreloadreason reason)
04687 {
04688 switch (reason) {
04689 case CHANNEL_MODULE_LOAD:
04690 return "LOAD (Channel module load)";
04691
04692 case CHANNEL_MODULE_RELOAD:
04693 return "RELOAD (Channel module reload)";
04694
04695 case CHANNEL_CLI_RELOAD:
04696 return "CLIRELOAD (Channel module reload by CLI command)";
04697
04698 default:
04699 return "MANAGERRELOAD (Channel module reload by manager)";
04700 }
04701 };
04702
04703 #ifdef DEBUG_CHANNEL_LOCKS
04704
04705
04706
04707
04708 int __ast_channel_unlock(struct ast_channel *chan, const char *filename, int lineno, const char *func)
04709 {
04710 int res = 0;
04711 if (option_debug > 2)
04712 ast_log(LOG_DEBUG, "::::==== Unlocking AST channel %s\n", chan->name);
04713
04714 if (!chan) {
04715 if (option_debug)
04716 ast_log(LOG_DEBUG, "::::==== Unlocking non-existing channel \n");
04717 return 0;
04718 }
04719 #ifdef DEBUG_THREADS
04720 res = __ast_pthread_mutex_unlock(filename, lineno, func, "(channel lock)", &chan->lock);
04721 #else
04722 res = ast_mutex_unlock(&chan->lock);
04723 #endif
04724
04725 if (option_debug > 2) {
04726 #ifdef DEBUG_THREADS
04727 int count = 0;
04728 if ((count = chan->lock.reentrancy))
04729 ast_log(LOG_DEBUG, ":::=== Still have %d locks (recursive)\n", count);
04730 #endif
04731 if (!res)
04732 if (option_debug)
04733 ast_log(LOG_DEBUG, "::::==== Channel %s was unlocked\n", chan->name);
04734 if (res == EINVAL) {
04735 if (option_debug)
04736 ast_log(LOG_DEBUG, "::::==== Channel %s had no lock by this thread. Failed unlocking\n", chan->name);
04737 }
04738 }
04739 if (res == EPERM) {
04740
04741 if (option_debug > 3)
04742 ast_log(LOG_DEBUG, "::::==== Channel %s was not locked at all \n", chan->name);
04743 res = 0;
04744 }
04745 return res;
04746 }
04747
04748
04749
04750 int __ast_channel_lock(struct ast_channel *chan, const char *filename, int lineno, const char *func)
04751 {
04752 int res;
04753
04754 if (option_debug > 3)
04755 ast_log(LOG_DEBUG, "====:::: Locking AST channel %s\n", chan->name);
04756
04757 #ifdef DEBUG_THREADS
04758 res = __ast_pthread_mutex_lock(filename, lineno, func, "(channel lock)", &chan->lock);
04759 #else
04760 res = ast_mutex_lock(&chan->lock);
04761 #endif
04762
04763 if (option_debug > 3) {
04764 #ifdef DEBUG_THREADS
04765 int count = 0;
04766 if ((count = chan->lock.reentrancy))
04767 ast_log(LOG_DEBUG, ":::=== Now have %d locks (recursive)\n", count);
04768 #endif
04769 if (!res)
04770 ast_log(LOG_DEBUG, "::::==== Channel %s was locked\n", chan->name);
04771 if (res == EDEADLK) {
04772
04773 if (option_debug > 3)
04774 ast_log(LOG_DEBUG, "::::==== Channel %s was not locked by us. Lock would cause deadlock.\n", chan->name);
04775 }
04776 if (res == EINVAL) {
04777 if (option_debug > 3)
04778 ast_log(LOG_DEBUG, "::::==== Channel %s lock failed. No mutex.\n", chan->name);
04779 }
04780 }
04781 return res;
04782 }
04783
04784
04785
04786 int __ast_channel_trylock(struct ast_channel *chan, const char *filename, int lineno, const char *func)
04787 {
04788 int res;
04789
04790 if (option_debug > 2)
04791 ast_log(LOG_DEBUG, "====:::: Trying to lock AST channel %s\n", chan->name);
04792 #ifdef DEBUG_THREADS
04793 res = __ast_pthread_mutex_trylock(filename, lineno, func, "(channel lock)", &chan->lock);
04794 #else
04795 res = ast_mutex_trylock(&chan->lock);
04796 #endif
04797
04798 if (option_debug > 2) {
04799 #ifdef DEBUG_THREADS
04800 int count = 0;
04801 if ((count = chan->lock.reentrancy))
04802 ast_log(LOG_DEBUG, ":::=== Now have %d locks (recursive)\n", count);
04803 #endif
04804 if (!res)
04805 ast_log(LOG_DEBUG, "::::==== Channel %s was locked\n", chan->name);
04806 if (res == EBUSY) {
04807
04808 if (option_debug > 2)
04809 ast_log(LOG_DEBUG, "::::==== Channel %s failed to lock. Not waiting around...\n", chan->name);
04810 }
04811 if (res == EDEADLK) {
04812
04813 if (option_debug > 2)
04814 ast_log(LOG_DEBUG, "::::==== Channel %s was not locked. Lock would cause deadlock.\n", chan->name);
04815 }
04816 if (res == EINVAL && option_debug > 2)
04817 ast_log(LOG_DEBUG, "::::==== Channel %s lock failed. No mutex.\n", chan->name);
04818 }
04819 return res;
04820 }
04821
04822 #endif
04823
04824
04825
04826
04827
04828
04829
04830
04831
04832 int ast_say_number(struct ast_channel *chan, int num,
04833 const char *ints, const char *language, const char *options)
04834 {
04835 return ast_say_number_full(chan, num, ints, language, options, -1, -1);
04836 }
04837
04838 int ast_say_enumeration(struct ast_channel *chan, int num,
04839 const char *ints, const char *language, const char *options)
04840 {
04841 return ast_say_enumeration_full(chan, num, ints, language, options, -1, -1);
04842 }
04843
04844 int ast_say_digits(struct ast_channel *chan, int num,
04845 const char *ints, const char *lang)
04846 {
04847 return ast_say_digits_full(chan, num, ints, lang, -1, -1);
04848 }
04849
04850 int ast_say_digit_str(struct ast_channel *chan, const char *str,
04851 const char *ints, const char *lang)
04852 {
04853 return ast_say_digit_str_full(chan, str, ints, lang, -1, -1);
04854 }
04855
04856 int ast_say_character_str(struct ast_channel *chan, const char *str,
04857 const char *ints, const char *lang)
04858 {
04859 return ast_say_character_str_full(chan, str, ints, lang, -1, -1);
04860 }
04861
04862 int ast_say_phonetic_str(struct ast_channel *chan, const char *str,
04863 const char *ints, const char *lang)
04864 {
04865 return ast_say_phonetic_str_full(chan, str, ints, lang, -1, -1);
04866 }
04867
04868 int ast_say_digits_full(struct ast_channel *chan, int num,
04869 const char *ints, const char *lang, int audiofd, int ctrlfd)
04870 {
04871 char buf[256];
04872
04873 snprintf(buf, sizeof(buf), "%d", num);
04874 return ast_say_digit_str_full(chan, buf, ints, lang, audiofd, ctrlfd);
04875 }
04876