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