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