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 case AST_CONTROL_SRCCHANGE:
01880
01881 break;
01882 default:
01883 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01884 break;
01885 }
01886 break;
01887 case AST_FRAME_VOICE:
01888
01889 if (audiofd > -1)
01890 write(audiofd, f->data, f->datalen);
01891 default:
01892
01893 break;
01894 }
01895 ast_frfree(f);
01896 }
01897 }
01898
01899 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01900
01901 return 0;
01902 }
01903
01904 static void ast_read_generator_actions(struct ast_channel *chan, struct ast_frame *f)
01905 {
01906 if (chan->generatordata && !ast_internal_timing_enabled(chan)) {
01907 void *tmp = chan->generatordata;
01908 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = NULL;
01909 int res;
01910 int samples;
01911
01912 if (chan->timingfunc) {
01913 if (option_debug > 1)
01914 ast_log(LOG_DEBUG, "Generator got voice, switching to phase locked mode\n");
01915 ast_settimeout(chan, 0, NULL, NULL);
01916 }
01917
01918 chan->generatordata = NULL;
01919
01920 if (f->subclass != chan->writeformat) {
01921 float factor;
01922 factor = ((float) ast_format_rate(chan->writeformat)) / ((float) ast_format_rate(f->subclass));
01923 samples = (int) ( ((float) f->samples) * factor );
01924 } else {
01925 samples = f->samples;
01926 }
01927
01928 if (chan->generator->generate) {
01929 generate = chan->generator->generate;
01930 }
01931
01932
01933
01934
01935
01936
01937
01938
01939 ast_channel_unlock(chan);
01940 res = generate(chan, tmp, f->datalen, samples);
01941 ast_channel_lock(chan);
01942 chan->generatordata = tmp;
01943 if (res) {
01944 if (option_debug > 1)
01945 ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
01946 ast_deactivate_generator(chan);
01947 }
01948
01949 } else if (f->frametype == AST_FRAME_CNG) {
01950 if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) {
01951 if (option_debug > 1)
01952 ast_log(LOG_DEBUG, "Generator got CNG, switching to timed mode\n");
01953 ast_settimeout(chan, 160, generator_force, chan);
01954 }
01955 }
01956 }
01957
01958 static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
01959 {
01960 struct ast_frame *f = NULL;
01961 int blah;
01962 int prestate;
01963 int count = 0;
01964
01965
01966
01967
01968 while(ast_channel_trylock(chan)) {
01969 if(count++ > 10)
01970
01971 return &ast_null_frame;
01972 usleep(1);
01973 }
01974
01975 if (chan->masq) {
01976 if (ast_do_masquerade(chan))
01977 ast_log(LOG_WARNING, "Failed to perform masquerade\n");
01978 else
01979 f = &ast_null_frame;
01980 goto done;
01981 }
01982
01983
01984 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
01985 if (chan->generator)
01986 ast_deactivate_generator(chan);
01987 goto done;
01988 }
01989 prestate = chan->_state;
01990
01991 if (!ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF | AST_FLAG_IN_DTMF) &&
01992 !ast_strlen_zero(chan->dtmfq) &&
01993 (ast_tvzero(chan->dtmf_tv) || ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) > AST_MIN_DTMF_GAP) ) {
01994
01995 chan->dtmff.subclass = chan->dtmfq[0];
01996
01997 memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1);
01998 f = &chan->dtmff;
01999 if (ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)) {
02000 ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass, chan->name);
02001 chan->dtmff.frametype = AST_FRAME_DTMF_END;
02002 } else {
02003 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);
02004 chan->dtmff.frametype = AST_FRAME_DTMF_BEGIN;
02005 ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
02006 chan->emulate_dtmf_digit = f->subclass;
02007 chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION;
02008 }
02009 chan->dtmf_tv = ast_tvnow();
02010 goto done;
02011 }
02012
02013
02014
02015 if (chan->alertpipe[0] > -1)
02016 read(chan->alertpipe[0], &blah, sizeof(blah));
02017
02018 #ifdef HAVE_ZAPTEL
02019 if (chan->timingfd > -1 && chan->fdno == AST_TIMING_FD && ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
02020 int res;
02021
02022 ast_clear_flag(chan, AST_FLAG_EXCEPTION);
02023 blah = -1;
02024
02025 res = ioctl(chan->timingfd, ZT_GETEVENT, &blah);
02026 if (res)
02027 blah = ZT_EVENT_TIMER_EXPIRED;
02028
02029 if (blah == ZT_EVENT_TIMER_PING) {
02030 if (AST_LIST_EMPTY(&chan->readq) || !AST_LIST_NEXT(AST_LIST_FIRST(&chan->readq), frame_list)) {
02031
02032 if (ioctl(chan->timingfd, ZT_TIMERPONG, &blah)) {
02033 ast_log(LOG_WARNING, "Failed to pong timer on '%s': %s\n", chan->name, strerror(errno));
02034 }
02035 }
02036 } else if (blah == ZT_EVENT_TIMER_EXPIRED) {
02037 ioctl(chan->timingfd, ZT_TIMERACK, &blah);
02038 if (chan->timingfunc) {
02039
02040 int (*func)(const void *) = chan->timingfunc;
02041 void *data = chan->timingdata;
02042 ast_channel_unlock(chan);
02043 func(data);
02044 } else {
02045 blah = 0;
02046 ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah);
02047 chan->timingdata = NULL;
02048 ast_channel_unlock(chan);
02049 }
02050
02051 return &ast_null_frame;
02052 } else
02053 ast_log(LOG_NOTICE, "No/unknown event '%d' on timer for '%s'?\n", blah, chan->name);
02054 } else
02055 #endif
02056 if (chan->fds[AST_GENERATOR_FD] > -1 && chan->fdno == AST_GENERATOR_FD) {
02057
02058
02059
02060 void *tmp = chan->generatordata;
02061 chan->generatordata = NULL;
02062 chan->generator->generate(chan, tmp, -1, -1);
02063 chan->generatordata = tmp;
02064 f = &ast_null_frame;
02065 goto done;
02066 }
02067
02068
02069 if (!AST_LIST_EMPTY(&chan->readq)) {
02070 f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list);
02071
02072
02073 if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP) {
02074 ast_frfree(f);
02075 f = NULL;
02076 }
02077 } else {
02078 chan->blocker = pthread_self();
02079 if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
02080 if (chan->tech->exception)
02081 f = chan->tech->exception(chan);
02082 else {
02083 ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name);
02084 f = &ast_null_frame;
02085 }
02086
02087 ast_clear_flag(chan, AST_FLAG_EXCEPTION);
02088 } else if (chan->tech->read)
02089 f = chan->tech->read(chan);
02090 else
02091 ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
02092 }
02093
02094 if (f) {
02095
02096
02097
02098
02099
02100 if (AST_LIST_NEXT(f, frame_list)) {
02101 AST_LIST_HEAD_SET_NOLOCK(&chan->readq, AST_LIST_NEXT(f, frame_list));
02102 AST_LIST_NEXT(f, frame_list) = NULL;
02103 }
02104
02105 switch (f->frametype) {
02106 case AST_FRAME_CONTROL:
02107 if (f->subclass == AST_CONTROL_ANSWER) {
02108 if (!ast_test_flag(chan, AST_FLAG_OUTGOING)) {
02109 if (option_debug)
02110 ast_log(LOG_DEBUG, "Ignoring answer on an inbound call!\n");
02111 ast_frfree(f);
02112 f = &ast_null_frame;
02113 } else if (prestate == AST_STATE_UP) {
02114 if (option_debug)
02115 ast_log(LOG_DEBUG, "Dropping duplicate answer!\n");
02116 ast_frfree(f);
02117 f = &ast_null_frame;
02118 } else {
02119
02120 ast_setstate(chan, AST_STATE_UP);
02121 if (!chan->cdr) {
02122
02123
02124 chan->cdr = ast_cdr_alloc();
02125 ast_cdr_init(chan->cdr, chan);
02126 ast_cdr_start(chan->cdr);
02127 }
02128
02129 ast_cdr_answer(chan->cdr);
02130 }
02131 }
02132 break;
02133 case AST_FRAME_DTMF_END:
02134 ast_log(LOG_DTMF, "DTMF end '%c' received on %s, duration %ld ms\n", f->subclass, chan->name, f->len);
02135
02136
02137 if ( ast_test_flag(chan, AST_FLAG_DEFER_DTMF) ||
02138 (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)) ) {
02139 if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2) {
02140 ast_log(LOG_DTMF, "DTMF end '%c' put into dtmf queue on %s\n", f->subclass, chan->name);
02141 chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
02142 } else
02143 ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
02144 ast_frfree(f);
02145 f = &ast_null_frame;
02146 } else if (!ast_test_flag(chan, AST_FLAG_IN_DTMF | AST_FLAG_END_DTMF_ONLY)) {
02147 if (!ast_tvzero(chan->dtmf_tv) &&
02148 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) {
02149
02150 if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2) {
02151 ast_log(LOG_DTMF, "DTMF end '%c' put into dtmf queue on %s\n", f->subclass, chan->name);
02152 chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
02153 } else
02154 ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
02155 ast_frfree(f);
02156 f = &ast_null_frame;
02157 } else {
02158
02159 f->frametype = AST_FRAME_DTMF_BEGIN;
02160 ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
02161 chan->emulate_dtmf_digit = f->subclass;
02162 chan->dtmf_tv = ast_tvnow();
02163 if (f->len) {
02164 if (f->len > AST_MIN_DTMF_DURATION)
02165 chan->emulate_dtmf_duration = f->len;
02166 else
02167 chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION;
02168 } else
02169 chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION;
02170 ast_log(LOG_DTMF, "DTMF begin emulation of '%c' with duration %u queued on %s\n", f->subclass, chan->emulate_dtmf_duration, chan->name);
02171 }
02172 if (chan->audiohooks) {
02173 struct ast_frame *old_frame = f;
02174 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
02175 if (old_frame != f)
02176 ast_frfree(old_frame);
02177 }
02178 } else {
02179 struct timeval now = ast_tvnow();
02180 if (ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
02181 ast_log(LOG_DTMF, "DTMF end accepted with begin '%c' on %s\n", f->subclass, chan->name);
02182 ast_clear_flag(chan, AST_FLAG_IN_DTMF);
02183 if (!f->len)
02184 f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
02185 } else if (!f->len) {
02186 ast_log(LOG_DTMF, "DTMF end accepted without begin '%c' on %s\n", f->subclass, chan->name);
02187 f->len = AST_MIN_DTMF_DURATION;
02188 }
02189 if (f->len < AST_MIN_DTMF_DURATION) {
02190 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);
02191 ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
02192 chan->emulate_dtmf_digit = f->subclass;
02193 chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION - f->len;
02194 ast_frfree(f);
02195 f = &ast_null_frame;
02196 } else {
02197 ast_log(LOG_DTMF, "DTMF end passthrough '%c' on %s\n", f->subclass, chan->name);
02198 chan->dtmf_tv = now;
02199 }
02200 if (chan->audiohooks) {
02201 struct ast_frame *old_frame = f;
02202 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
02203 if (old_frame != f)
02204 ast_frfree(old_frame);
02205 }
02206 }
02207 break;
02208 case AST_FRAME_DTMF_BEGIN:
02209 ast_log(LOG_DTMF, "DTMF begin '%c' received on %s\n", f->subclass, chan->name);
02210 if ( ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_END_DTMF_ONLY | AST_FLAG_EMULATE_DTMF) ||
02211 (!ast_tvzero(chan->dtmf_tv) &&
02212 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) ) {
02213 ast_log(LOG_DTMF, "DTMF begin ignored '%c' on %s\n", f->subclass, chan->name);
02214 ast_frfree(f);
02215 f = &ast_null_frame;
02216 } else {
02217 ast_set_flag(chan, AST_FLAG_IN_DTMF);
02218 chan->dtmf_tv = ast_tvnow();
02219 ast_log(LOG_DTMF, "DTMF begin passthrough '%c' on %s\n", f->subclass, chan->name);
02220 }
02221 break;
02222 case AST_FRAME_NULL:
02223
02224
02225
02226
02227 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
02228 struct timeval now = ast_tvnow();
02229 if (!chan->emulate_dtmf_duration) {
02230 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
02231 chan->emulate_dtmf_digit = 0;
02232 } else if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
02233 chan->emulate_dtmf_duration = 0;
02234 ast_frfree(f);
02235 f = &chan->dtmff;
02236 f->frametype = AST_FRAME_DTMF_END;
02237 f->subclass = chan->emulate_dtmf_digit;
02238 f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
02239 chan->dtmf_tv = now;
02240 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
02241 chan->emulate_dtmf_digit = 0;
02242 ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass, chan->name);
02243 }
02244 }
02245 break;
02246 case AST_FRAME_VOICE:
02247
02248
02249
02250
02251 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !chan->emulate_dtmf_duration) {
02252 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
02253 chan->emulate_dtmf_digit = 0;
02254 }
02255
02256 if (dropaudio || ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
02257 if (dropaudio)
02258 ast_read_generator_actions(chan, f);
02259 ast_frfree(f);
02260 f = &ast_null_frame;
02261 }
02262
02263 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
02264 struct timeval now = ast_tvnow();
02265 if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
02266 chan->emulate_dtmf_duration = 0;
02267 ast_frfree(f);
02268 f = &chan->dtmff;
02269 f->frametype = AST_FRAME_DTMF_END;
02270 f->subclass = chan->emulate_dtmf_digit;
02271 f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
02272 chan->dtmf_tv = now;
02273 if (chan->audiohooks) {
02274 struct ast_frame *old_frame = f;
02275 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
02276 if (old_frame != f)
02277 ast_frfree(old_frame);
02278 }
02279 ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass, chan->name);
02280 } else {
02281
02282 ast_frfree(f);
02283 f = &ast_null_frame;
02284 }
02285 } else if ((f->frametype == AST_FRAME_VOICE) && !(f->subclass & chan->nativeformats)) {
02286
02287
02288 ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n",
02289 chan->name, ast_getformatname(f->subclass), ast_getformatname(chan->nativeformats));
02290 ast_frfree(f);
02291 f = &ast_null_frame;
02292 } else if ((f->frametype == AST_FRAME_VOICE)) {
02293 if (chan->audiohooks) {
02294 struct ast_frame *old_frame = f;
02295 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
02296 if (old_frame != f)
02297 ast_frfree(old_frame);
02298 }
02299 if (chan->monitor && chan->monitor->read_stream ) {
02300
02301 #ifndef MONITOR_CONSTANT_DELAY
02302 int jump = chan->outsmpl - chan->insmpl - 4 * f->samples;
02303 if (jump >= 0) {
02304 jump = chan->outsmpl - chan->insmpl;
02305 if (ast_seekstream(chan->monitor->read_stream, jump, SEEK_FORCECUR) == -1)
02306 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
02307 chan->insmpl += jump + f->samples;
02308 } else
02309 chan->insmpl+= f->samples;
02310 #else
02311 int jump = chan->outsmpl - chan->insmpl;
02312 if (jump - MONITOR_DELAY >= 0) {
02313 if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
02314 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
02315 chan->insmpl += jump;
02316 } else
02317 chan->insmpl += f->samples;
02318 #endif
02319 if (chan->monitor->state == AST_MONITOR_RUNNING) {
02320 if (ast_writestream(chan->monitor->read_stream, f) < 0)
02321 ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
02322 }
02323 }
02324
02325 if (chan->readtrans && (f = ast_translate(chan->readtrans, f, 1)) == NULL)
02326 f = &ast_null_frame;
02327
02328
02329
02330 ast_read_generator_actions(chan, f);
02331 }
02332 default:
02333
02334 break;
02335 }
02336 } else {
02337
02338 chan->_softhangup |= AST_SOFTHANGUP_DEV;
02339 if (chan->generator)
02340 ast_deactivate_generator(chan);
02341
02342 if (chan->cdr)
02343 ast_cdr_end(chan->cdr);
02344 }
02345
02346
02347 if (chan->fin & DEBUGCHAN_FLAG)
02348 ast_frame_dump(chan->name, f, "<<");
02349 chan->fin = FRAMECOUNT_INC(chan->fin);
02350
02351 done:
02352 ast_channel_unlock(chan);
02353 return f;
02354 }
02355
02356 int ast_internal_timing_enabled(struct ast_channel *chan)
02357 {
02358 int ret = ast_opt_internal_timing && chan->timingfd > -1;
02359 if (option_debug > 4)
02360 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);
02361 return ret;
02362 }
02363
02364 struct ast_frame *ast_read(struct ast_channel *chan)
02365 {
02366 return __ast_read(chan, 0);
02367 }
02368
02369 struct ast_frame *ast_read_noaudio(struct ast_channel *chan)
02370 {
02371 return __ast_read(chan, 1);
02372 }
02373
02374 int ast_indicate(struct ast_channel *chan, int condition)
02375 {
02376 return ast_indicate_data(chan, condition, NULL, 0);
02377 }
02378
02379 int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, size_t datalen)
02380 {
02381 int res = -1;
02382
02383 ast_channel_lock(chan);
02384
02385 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
02386 ast_channel_unlock(chan);
02387 return -1;
02388 }
02389 if (chan->tech->indicate)
02390 res = chan->tech->indicate(chan, condition, data, datalen);
02391 ast_channel_unlock(chan);
02392 if (!chan->tech->indicate || res) {
02393
02394
02395
02396
02397 if (condition < 0)
02398 ast_playtones_stop(chan);
02399 else {
02400 const struct tone_zone_sound *ts = NULL;
02401 switch (condition) {
02402 case AST_CONTROL_RINGING:
02403 ts = ast_get_indication_tone(chan->zone, "ring");
02404 break;
02405 case AST_CONTROL_BUSY:
02406 ts = ast_get_indication_tone(chan->zone, "busy");
02407 break;
02408 case AST_CONTROL_CONGESTION:
02409 ts = ast_get_indication_tone(chan->zone, "congestion");
02410 break;
02411 }
02412 if (ts && ts->data[0]) {
02413 if (option_debug)
02414 ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
02415 ast_playtones_start(chan,0,ts->data, 1);
02416 res = 0;
02417 chan->visible_indication = condition;
02418 } else if (condition == AST_CONTROL_PROGRESS) {
02419
02420 } else if (condition == AST_CONTROL_PROCEEDING) {
02421
02422 } else if (condition == AST_CONTROL_HOLD) {
02423
02424 } else if (condition == AST_CONTROL_UNHOLD) {
02425
02426 } else if (condition == AST_CONTROL_VIDUPDATE) {
02427
02428 } else if (condition == AST_CONTROL_SRCUPDATE) {
02429
02430 } else if (condition == AST_CONTROL_SRCCHANGE) {
02431
02432 } else {
02433
02434 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
02435 res = -1;
02436 }
02437 }
02438 } else
02439 chan->visible_indication = condition;
02440
02441 return res;
02442 }
02443
02444 int ast_recvchar(struct ast_channel *chan, int timeout)
02445 {
02446 int c;
02447 char *buf = ast_recvtext(chan, timeout);
02448 if (buf == NULL)
02449 return -1;
02450 c = *(unsigned char *)buf;
02451 free(buf);
02452 return c;
02453 }
02454
02455 char *ast_recvtext(struct ast_channel *chan, int timeout)
02456 {
02457 int res, done = 0;
02458 char *buf = NULL;
02459
02460 while (!done) {
02461 struct ast_frame *f;
02462 if (ast_check_hangup(chan))
02463 break;
02464 res = ast_waitfor(chan, timeout);
02465 if (res <= 0)
02466 break;
02467 timeout = res;
02468 f = ast_read(chan);
02469 if (f == NULL)
02470 break;
02471 if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP)
02472 done = 1;
02473 else if (f->frametype == AST_FRAME_TEXT) {
02474 buf = ast_strndup((char *) f->data, f->datalen);
02475 done = 1;
02476 }
02477 ast_frfree(f);
02478 }
02479 return buf;
02480 }
02481
02482 int ast_sendtext(struct ast_channel *chan, const char *text)
02483 {
02484 int res = 0;
02485
02486 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
02487 return -1;
02488 CHECK_BLOCKING(chan);
02489 if (chan->tech->send_text)
02490 res = chan->tech->send_text(chan, text);
02491 ast_clear_flag(chan, AST_FLAG_BLOCKING);
02492 return res;
02493 }
02494
02495 int ast_sendmessage(struct ast_channel *chan, const char *dest, const char *text, int ispdu)
02496 {
02497 int res = 0;
02498
02499 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
02500 return -1;
02501 CHECK_BLOCKING(chan);
02502 #if 0
02503 if (chan->tech->send_message)
02504 res = chan->tech->send_message(chan, dest, text, ispdu);
02505 #endif
02506 ast_clear_flag(chan, AST_FLAG_BLOCKING);
02507 return res;
02508 }
02509
02510 int ast_senddigit_begin(struct ast_channel *chan, char digit)
02511 {
02512
02513
02514 static const char* dtmf_tones[] = {
02515 "941+1336",
02516 "697+1209",
02517 "697+1336",
02518 "697+1477",
02519 "770+1209",
02520 "770+1336",
02521 "770+1477",
02522 "852+1209",
02523 "852+1336",
02524 "852+1477",
02525 "697+1633",
02526 "770+1633",
02527 "852+1633",
02528 "941+1633",
02529 "941+1209",
02530 "941+1477"
02531 };
02532
02533 if (!chan->tech->send_digit_begin)
02534 return 0;
02535
02536 if (!chan->tech->send_digit_begin(chan, digit))
02537 return 0;
02538
02539 if (digit >= '0' && digit <='9')
02540 ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0);
02541 else if (digit >= 'A' && digit <= 'D')
02542 ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0);
02543 else if (digit == '*')
02544 ast_playtones_start(chan, 0, dtmf_tones[14], 0);
02545 else if (digit == '#')
02546 ast_playtones_start(chan, 0, dtmf_tones[15], 0);
02547 else {
02548
02549 if (option_debug)
02550 ast_log(LOG_DEBUG, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name);
02551 }
02552
02553 return 0;
02554 }
02555
02556 int ast_senddigit_end(struct ast_channel *chan, char digit, unsigned int duration)
02557 {
02558 int res = -1;
02559
02560 if (chan->tech->send_digit_end)
02561 res = chan->tech->send_digit_end(chan, digit, duration);
02562
02563 if (res && chan->generator)
02564 ast_playtones_stop(chan);
02565
02566 return 0;
02567 }
02568
02569 int ast_senddigit(struct ast_channel *chan, char digit)
02570 {
02571 if (chan->tech->send_digit_begin) {
02572 ast_senddigit_begin(chan, digit);
02573 ast_safe_sleep(chan, AST_DEFAULT_EMULATE_DTMF_DURATION);
02574 }
02575
02576 return ast_senddigit_end(chan, digit, AST_DEFAULT_EMULATE_DTMF_DURATION);
02577 }
02578
02579 int ast_prod(struct ast_channel *chan)
02580 {
02581 struct ast_frame a = { AST_FRAME_VOICE };
02582 char nothing[128];
02583
02584
02585 if (chan->_state != AST_STATE_UP) {
02586 if (option_debug)
02587 ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name);
02588 a.subclass = chan->rawwriteformat;
02589 a.data = nothing + AST_FRIENDLY_OFFSET;
02590 a.src = "ast_prod";
02591 if (ast_write(chan, &a))
02592 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name);
02593 }
02594 return 0;
02595 }
02596
02597 int ast_write_video(struct ast_channel *chan, struct ast_frame *fr)
02598 {
02599 int res;
02600 if (!chan->tech->write_video)
02601 return 0;
02602 res = ast_write(chan, fr);
02603 if (!res)
02604 res = 1;
02605 return res;
02606 }
02607
02608 int ast_write(struct ast_channel *chan, struct ast_frame *fr)
02609 {
02610 int res = -1;
02611 int count = 0;
02612 struct ast_frame *f = NULL, *f2 = NULL;
02613
02614
02615 while(ast_channel_trylock(chan)) {
02616
02617 if(count++ > 10) {
02618 if(option_debug)
02619 ast_log(LOG_DEBUG, "Deadlock avoided for write to channel '%s'\n", chan->name);
02620 return 0;
02621 }
02622 usleep(1);
02623 }
02624
02625 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
02626 goto done;
02627
02628
02629 if (chan->masq && ast_do_masquerade(chan)) {
02630 ast_log(LOG_WARNING, "Failed to perform masquerade\n");
02631 goto done;
02632 }
02633 if (chan->masqr) {
02634 res = 0;
02635 goto done;
02636 }
02637 if (chan->generatordata) {
02638 if (ast_test_flag(chan, AST_FLAG_WRITE_INT))
02639 ast_deactivate_generator(chan);
02640 else {
02641 if (fr->frametype == AST_FRAME_DTMF_END) {
02642
02643
02644
02645 ast_clear_flag(chan, AST_FLAG_BLOCKING);
02646 ast_channel_unlock(chan);
02647 res = ast_senddigit_end(chan, fr->subclass, fr->len);
02648 ast_channel_lock(chan);
02649 CHECK_BLOCKING(chan);
02650 } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass == AST_CONTROL_UNHOLD) {
02651
02652 res = (chan->tech->indicate == NULL) ? 0 :
02653 chan->tech->indicate(chan, fr->subclass, fr->data, fr->datalen);
02654 }
02655 res = 0;
02656 goto done;
02657 }
02658 }
02659
02660 if (chan->fout & DEBUGCHAN_FLAG)
02661 ast_frame_dump(chan->name, fr, ">>");
02662 CHECK_BLOCKING(chan);
02663 switch(fr->frametype) {
02664 case AST_FRAME_CONTROL:
02665 res = (chan->tech->indicate == NULL) ? 0 :
02666 chan->tech->indicate(chan, fr->subclass, fr->data, fr->datalen);
02667 break;
02668 case AST_FRAME_DTMF_BEGIN:
02669 if (chan->audiohooks) {
02670 struct ast_frame *old_frame = fr;
02671 fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
02672 if (old_frame != fr)
02673 f = fr;
02674 }
02675 ast_clear_flag(chan, AST_FLAG_BLOCKING);
02676 ast_channel_unlock(chan);
02677 res = ast_senddigit_begin(chan, fr->subclass);
02678 ast_channel_lock(chan);
02679 CHECK_BLOCKING(chan);
02680 break;
02681 case AST_FRAME_DTMF_END:
02682 if (chan->audiohooks) {
02683 struct ast_frame *old_frame = fr;
02684 fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
02685 if (old_frame != fr)
02686 f = fr;
02687 }
02688 ast_clear_flag(chan, AST_FLAG_BLOCKING);
02689 ast_channel_unlock(chan);
02690 res = ast_senddigit_end(chan, fr->subclass, fr->len);
02691 ast_channel_lock(chan);
02692 CHECK_BLOCKING(chan);
02693 break;
02694 case AST_FRAME_TEXT:
02695 res = (chan->tech->send_text == NULL) ? 0 :
02696 chan->tech->send_text(chan, (char *) fr->data);
02697 break;
02698 case AST_FRAME_HTML:
02699 res = (chan->tech->send_html == NULL) ? 0 :
02700 chan->tech->send_html(chan, fr->subclass, (char *) fr->data, fr->datalen);
02701 break;
02702 case AST_FRAME_VIDEO:
02703
02704 res = (chan->tech->write_video == NULL) ? 0 :
02705 chan->tech->write_video(chan, fr);
02706 break;
02707 case AST_FRAME_MODEM:
02708 res = (chan->tech->write == NULL) ? 0 :
02709 chan->tech->write(chan, fr);
02710 break;
02711 case AST_FRAME_VOICE:
02712 if (chan->tech->write == NULL)
02713 break;
02714
02715 if (chan->audiohooks) {
02716 struct ast_frame *old_frame = fr;
02717 fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
02718 if (old_frame != fr)
02719 f2 = fr;
02720 }
02721
02722
02723 if (fr->subclass == chan->rawwriteformat)
02724 f = fr;
02725 else
02726 f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
02727
02728
02729 if (!f) {
02730 res = 0;
02731 break;
02732 }
02733
02734
02735 if (chan->monitor && chan->monitor->write_stream) {
02736
02737 #ifndef MONITOR_CONSTANT_DELAY
02738 int jump = chan->insmpl - chan->outsmpl - 4 * f->samples;
02739 if (jump >= 0) {
02740 jump = chan->insmpl - chan->outsmpl;
02741 if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1)
02742 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
02743 chan->outsmpl += jump + f->samples;
02744 } else
02745 chan->outsmpl += f->samples;
02746 #else
02747 int jump = chan->insmpl - chan->outsmpl;
02748 if (jump - MONITOR_DELAY >= 0) {
02749 if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1)
02750 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
02751 chan->outsmpl += jump;
02752 } else
02753 chan->outsmpl += f->samples;
02754 #endif
02755 if (chan->monitor->state == AST_MONITOR_RUNNING) {
02756 if (ast_writestream(chan->monitor->write_stream, f) < 0)
02757 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
02758 }
02759 }
02760
02761 if (f)
02762 res = chan->tech->write(chan,f);
02763 else
02764 res = 0;
02765 break;
02766 case AST_FRAME_NULL:
02767 case AST_FRAME_IAX:
02768
02769 res = 0;
02770 break;
02771 default:
02772
02773
02774
02775 res = chan->tech->write(chan, fr);
02776 break;
02777 }
02778
02779 if (f && f != fr)
02780 ast_frfree(f);
02781 if (f2)
02782 ast_frfree(f2);
02783 ast_clear_flag(chan, AST_FLAG_BLOCKING);
02784
02785 if (res < 0)
02786 chan->_softhangup |= AST_SOFTHANGUP_DEV;
02787 else {
02788 chan->fout = FRAMECOUNT_INC(chan->fout);
02789 }
02790 done:
02791 ast_channel_unlock(chan);
02792 return res;
02793 }
02794
02795 static int set_format(struct ast_channel *chan, int fmt, int *rawformat, int *format,
02796 struct ast_trans_pvt **trans, const int direction)
02797 {
02798 int native;
02799 int res;
02800
02801
02802 fmt &= AST_FORMAT_AUDIO_MASK;
02803
02804 native = chan->nativeformats;
02805
02806 if (!direction)
02807
02808 res = ast_translator_best_choice(&fmt, &native);
02809 else
02810
02811 res = ast_translator_best_choice(&native, &fmt);
02812
02813 if (res < 0) {
02814 ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n",
02815 ast_getformatname(native), ast_getformatname(fmt));
02816 return -1;
02817 }
02818
02819
02820 ast_channel_lock(chan);
02821
02822 if ((*rawformat == native) && (*format == fmt) && ((*rawformat == *format) || (*trans))) {
02823
02824 ast_channel_unlock(chan);
02825 return 0;
02826 }
02827
02828 *rawformat = native;
02829
02830 *format = fmt;
02831
02832 if (*trans)
02833 ast_translator_free_path(*trans);
02834
02835 if (!direction)
02836
02837 *trans = ast_translator_build_path(*format, *rawformat);
02838 else
02839
02840 *trans = ast_translator_build_path(*rawformat, *format);
02841 ast_channel_unlock(chan);
02842 if (option_debug)
02843 ast_log(LOG_DEBUG, "Set channel %s to %s format %s\n", chan->name,
02844 direction ? "write" : "read", ast_getformatname(fmt));
02845 return 0;
02846 }
02847
02848 int ast_set_read_format(struct ast_channel *chan, int fmt)
02849 {
02850 return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat,
02851 &chan->readtrans, 0);
02852 }
02853
02854 int ast_set_write_format(struct ast_channel *chan, int fmt)
02855 {
02856 return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat,
02857 &chan->writetrans, 1);
02858 }
02859
02860 char *ast_channel_reason2str(int reason)
02861 {
02862 switch (reason)
02863 {
02864 case 0:
02865 return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)";
02866 case AST_CONTROL_HANGUP:
02867 return "Hangup";
02868 case AST_CONTROL_RING:
02869 return "Local Ring";
02870 case AST_CONTROL_RINGING:
02871 return "Remote end Ringing";
02872 case AST_CONTROL_ANSWER:
02873 return "Remote end has Answered";
02874 case AST_CONTROL_BUSY:
02875 return "Remote end is Busy";
02876 case AST_CONTROL_CONGESTION:
02877 return "Congestion (circuits busy)";
02878 default:
02879 return "Unknown Reason!!";
02880 }
02881 }
02882
02883 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)
02884 {
02885 return __ast_request_and_dial_uniqueid(type, format, data,
02886 timeout, outstate, 0, cid_num, cid_name, oh, NULL);
02887 }
02888
02889 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)
02890 {
02891 int dummy_outstate;
02892 int cause = 0;
02893 struct ast_channel *chan;
02894 int res = 0;
02895 int last_subclass = 0;
02896
02897 if (outstate)
02898 *outstate = 0;
02899 else
02900 outstate = &dummy_outstate;
02901
02902 chan = ast_request_with_uniqueid(type, format, data, &cause, uniqueid);
02903 if (!chan) {
02904 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
02905
02906 if (cause == AST_CAUSE_BUSY)
02907 *outstate = AST_CONTROL_BUSY;
02908 else if (cause == AST_CAUSE_CONGESTION)
02909 *outstate = AST_CONTROL_CONGESTION;
02910 return NULL;
02911 }
02912
02913 if (oh) {
02914 if (oh->vars)
02915 ast_set_variables(chan, oh->vars);
02916
02917 if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name))
02918 ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num);
02919 if (oh->parent_channel)
02920 ast_channel_inherit_variables(oh->parent_channel, chan);
02921 if (oh->account)
02922 ast_cdr_setaccount(chan, oh->account);
02923 }
02924 ast_set_callerid(chan, cid_num, cid_name, cid_num);
02925
02926
02927
02928 if (!chan->cdr) {
02929
02930
02931 chan->cdr = ast_cdr_alloc();
02932 ast_cdr_init(chan->cdr, chan);
02933 ast_cdr_start(chan->cdr);
02934 }
02935 if (ast_call(chan, data, 0)) {
02936 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
02937 } else {
02938 res = 1;
02939 while (timeout && chan->_state != AST_STATE_UP) {
02940 struct ast_frame *f;
02941 res = ast_waitfor(chan, timeout);
02942 if (res <= 0)
02943 break;
02944 if (timeout > -1)
02945 timeout = res;
02946 f = ast_read(chan);
02947 if (!f) {
02948 *outstate = AST_CONTROL_HANGUP;
02949 res = 0;
02950 break;
02951 }
02952 if (f->frametype == AST_FRAME_CONTROL) {
02953 switch (f->subclass) {
02954 case AST_CONTROL_RINGING:
02955 *outstate = f->subclass;
02956 break;
02957
02958 case AST_CONTROL_BUSY:
02959 case AST_CONTROL_CONGESTION:
02960 case AST_CONTROL_ANSWER:
02961 *outstate = f->subclass;
02962 timeout = 0;
02963 break;
02964
02965
02966 case AST_CONTROL_PROGRESS:
02967 case AST_CONTROL_PROCEEDING:
02968 case AST_CONTROL_HOLD:
02969 case AST_CONTROL_UNHOLD:
02970 case AST_CONTROL_VIDUPDATE:
02971 case AST_CONTROL_SRCUPDATE:
02972 case AST_CONTROL_SRCCHANGE:
02973 case -1:
02974 break;
02975
02976 default:
02977 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
02978 }
02979 last_subclass = f->subclass;
02980 }
02981 ast_frfree(f);
02982 }
02983 }
02984
02985
02986 if (oh) {
02987 if (!ast_strlen_zero(oh->context))
02988 ast_copy_string(chan->context, oh->context, sizeof(chan->context));
02989 if (!ast_strlen_zero(oh->exten))
02990 ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten));
02991 if (oh->priority)
02992 chan->priority = oh->priority;
02993 }
02994 if (chan->_state == AST_STATE_UP)
02995 *outstate = AST_CONTROL_ANSWER;
02996
02997 if (res <= 0) {
02998 if ( AST_CONTROL_RINGING == last_subclass )
02999 chan->hangupcause = AST_CAUSE_NO_ANSWER;
03000 if (!chan->cdr && (chan->cdr = ast_cdr_alloc()))
03001 ast_cdr_init(chan->cdr, chan);
03002 if (chan->cdr) {
03003 char tmp[256];
03004 snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data);
03005 ast_cdr_setapp(chan->cdr,"Dial",tmp);
03006 ast_cdr_update(chan);
03007 ast_cdr_start(chan->cdr);
03008 ast_cdr_end(chan->cdr);
03009
03010 if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
03011 ast_cdr_failed(chan->cdr);
03012 }
03013 ast_hangup(chan);
03014 chan = NULL;
03015 }
03016 return chan;
03017 }
03018
03019 struct ast_channel *ast_request_and_dial(const char *type, int format, void *data, int timeout, int *outstate, const char *cidnum, const char *cidname)
03020 {
03021 return __ast_request_and_dial(type, format, data, timeout, outstate, cidnum, cidname, NULL);
03022 }
03023 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)
03024 {
03025 return __ast_request_and_dial_uniqueid(type, format, data, timeout, outstate, 0, cidnum, cidname, NULL, uniqueid);
03026 }
03027
03028 struct ast_channel *ast_request_with_uniqueid(const char *type, int format, void *data, int *cause, char *uniqueid)
03029 {
03030 struct chanlist *chan;
03031 struct ast_channel *c;
03032 int capabilities;
03033 int fmt;
03034 int res;
03035 int foo;
03036 int videoformat = format & AST_FORMAT_VIDEO_MASK;
03037
03038 if (!cause)
03039 cause = &foo;
03040 *cause = AST_CAUSE_NOTDEFINED;
03041
03042 if (AST_LIST_LOCK(&channels)) {
03043 ast_log(LOG_WARNING, "Unable to lock channel list\n");
03044 return NULL;
03045 }
03046
03047 AST_LIST_TRAVERSE(&backends, chan, list) {
03048 if (strcasecmp(type, chan->tech->type))
03049 continue;
03050
03051 capabilities = chan->tech->capabilities;
03052 fmt = format & AST_FORMAT_AUDIO_MASK;
03053 res = ast_translator_best_choice(&fmt, &capabilities);
03054 if (res < 0) {
03055 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->tech->capabilities, format);
03056 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
03057 AST_LIST_UNLOCK(&channels);
03058 return NULL;
03059 }
03060 AST_LIST_UNLOCK(&channels);
03061 if (!chan->tech->requester)
03062 return NULL;
03063
03064 if (!(c = chan->tech->requester(type, capabilities | videoformat, data, cause)))
03065 return NULL;
03066
03067 if (uniqueid) strncpy(c->uniqueid, uniqueid, sizeof(c->uniqueid));
03068
03069 return c;
03070 }
03071
03072 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
03073 *cause = AST_CAUSE_NOSUCHDRIVER;
03074 AST_LIST_UNLOCK(&channels);
03075
03076 return NULL;
03077 }
03078
03079 struct ast_channel *ast_request(const char *type, int format, void *data, int *cause)
03080 {
03081 return ast_request_with_uniqueid(type, format, data, cause, NULL);
03082 }
03083
03084 int ast_call(struct ast_channel *chan, char *addr, int timeout)
03085 {
03086
03087
03088
03089 int res = -1;
03090
03091 ast_channel_lock(chan);
03092 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
03093 if (chan->tech->call)
03094 res = chan->tech->call(chan, addr, timeout);
03095 ast_set_flag(chan, AST_FLAG_OUTGOING);
03096 }
03097 ast_channel_unlock(chan);
03098 return res;
03099 }
03100
03101
03102
03103
03104
03105
03106
03107
03108 int ast_transfer(struct ast_channel *chan, char *dest)
03109 {
03110 int res = -1;
03111
03112
03113 ast_channel_lock(chan);
03114 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
03115 if (chan->tech->transfer) {
03116 res = chan->tech->transfer(chan, dest);
03117 if (!res)
03118 res = 1;
03119 } else
03120 res = 0;
03121 }
03122 ast_channel_unlock(chan);
03123 return res;
03124 }
03125
03126 int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders)
03127 {
03128 return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1);
03129 }
03130
03131 int ast_readstring_full(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders, int audiofd, int ctrlfd)
03132 {
03133 int pos = 0;
03134 int to = ftimeout;
03135
03136
03137 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
03138 return -1;
03139 if (!len)
03140 return -1;
03141 for (;;) {
03142 int d;
03143 if (c->stream) {
03144 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
03145 ast_stopstream(c);
03146 usleep(1000);
03147 if (!d)
03148 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
03149 } else {
03150 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
03151 }
03152 if (d < 0)
03153 return -1;
03154 if (d == 0) {
03155 s[pos]='\0';
03156 return 1;
03157 }
03158 if (d == 1) {
03159 s[pos]='\0';
03160 return 2;
03161 }
03162 if (!strchr(enders, d))
03163 s[pos++] = d;
03164 if (strchr(enders, d) || (pos >= len)) {
03165 s[pos]='\0';
03166 return 0;
03167 }
03168 to = timeout;
03169 }
03170
03171 return 0;
03172 }
03173
03174 int ast_channel_supports_html(struct ast_channel *chan)
03175 {
03176 return (chan->tech->send_html) ? 1 : 0;
03177 }
03178
03179 int ast_channel_sendhtml(struct ast_channel *chan, int subclass, const char *data, int datalen)
03180 {
03181 if (chan->tech->send_html)
03182 return chan->tech->send_html(chan, subclass, data, datalen);
03183 return -1;
03184 }
03185
03186 int ast_channel_sendurl(struct ast_channel *chan, const char *url)
03187 {
03188 return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1);
03189 }
03190
03191 int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
03192 {
03193 int src;
03194 int dst;
03195
03196 if (chan->readformat == peer->writeformat && chan->writeformat == peer->readformat) {
03197
03198 return 0;
03199 }
03200
03201
03202 src = chan->nativeformats;
03203 dst = peer->nativeformats;
03204 if (ast_translator_best_choice(&dst, &src) < 0) {
03205 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, src, peer->name, dst);
03206 return -1;
03207 }
03208
03209
03210
03211
03212
03213 if ((src != dst) && ast_opt_transcode_via_slin &&
03214 (ast_translate_path_steps(dst, src) != 1))
03215 dst = AST_FORMAT_SLINEAR;
03216 if (ast_set_read_format(chan, dst) < 0) {
03217 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, dst);
03218 return -1;
03219 }
03220 if (ast_set_write_format(peer, dst) < 0) {
03221 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, dst);
03222 return -1;
03223 }
03224
03225
03226 src = peer->nativeformats;
03227 dst = chan->nativeformats;
03228 if (ast_translator_best_choice(&dst, &src) < 0) {
03229 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, src, chan->name, dst);
03230 return -1;
03231 }
03232
03233
03234
03235
03236
03237 if ((src != dst) && ast_opt_transcode_via_slin &&
03238 (ast_translate_path_steps(dst, src) != 1))
03239 dst = AST_FORMAT_SLINEAR;
03240 if (ast_set_read_format(peer, dst) < 0) {
03241 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, dst);
03242 return -1;
03243 }
03244 if (ast_set_write_format(chan, dst) < 0) {
03245 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, dst);
03246 return -1;
03247 }
03248 return 0;
03249 }
03250
03251 int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone)
03252 {
03253 int res = -1;
03254 struct ast_channel *final_orig, *final_clone, *base;
03255
03256 retrymasq:
03257 final_orig = original;
03258 final_clone = clone;
03259
03260 ast_channel_lock(original);
03261 while (ast_channel_trylock(clone)) {
03262 ast_channel_unlock(original);
03263 usleep(1);
03264 ast_channel_lock(original);
03265 }
03266
03267
03268
03269 if (original->_bridge && (original->_bridge != ast_bridged_channel(original)) && (original->_bridge->_bridge != original))
03270 final_orig = original->_bridge;
03271
03272 if (clone->_bridge && (clone->_bridge != ast_bridged_channel(clone)) && (clone->_bridge->_bridge != clone))
03273 final_clone = clone->_bridge;
03274
03275 if (final_clone->tech->get_base_channel && (base = final_clone->tech->get_base_channel(final_clone))) {
03276 final_clone = base;
03277 }
03278
03279 if ((final_orig != original) || (final_clone != clone)) {
03280
03281
03282
03283 if (ast_channel_trylock(final_orig)) {
03284 ast_channel_unlock(clone);
03285 ast_channel_unlock(original);
03286 goto retrymasq;
03287 }
03288 if (ast_channel_trylock(final_clone)) {
03289 ast_channel_unlock(final_orig);
03290 ast_channel_unlock(clone);
03291 ast_channel_unlock(original);
03292 goto retrymasq;
03293 }
03294 ast_channel_unlock(clone);
03295 ast_channel_unlock(original);
03296 original = final_orig;
03297 clone = final_clone;
03298 }
03299
03300 if (original == clone) {
03301 ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name);
03302 ast_channel_unlock(clone);
03303 ast_channel_unlock(original);
03304 return -1;
03305 }
03306
03307 if (option_debug)
03308 ast_log(LOG_DEBUG, "Planning to masquerade channel %s into the structure of %s\n",
03309 clone->name, original->name);
03310 if (original->masq) {
03311 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
03312 original->masq->name, original->name);
03313 } else if (clone->masqr) {
03314 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
03315 clone->name, clone->masqr->name);
03316 } else {
03317 original->masq = clone;
03318 clone->masqr = original;
03319 ast_queue_frame(original, &ast_null_frame);
03320 ast_queue_frame(clone, &ast_null_frame);
03321 if (option_debug)
03322 ast_log(LOG_DEBUG, "Done planning to masquerade channel %s into the structure of %s\n", clone->name, original->name);
03323 res = 0;
03324 }
03325
03326 ast_channel_unlock(clone);
03327 ast_channel_unlock(original);
03328
03329 return res;
03330 }
03331
03332 void ast_change_name(struct ast_channel *chan, char *newname)
03333 {
03334 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", chan->name, newname, chan->uniqueid);
03335 ast_string_field_set(chan, name, newname);
03336 }
03337
03338 void ast_channel_inherit_variables(const struct ast_channel *parent, struct ast_channel *child)
03339 {
03340 struct ast_var_t *current, *newvar;
03341 const char *varname;
03342
03343 AST_LIST_TRAVERSE(&parent->varshead, current, entries) {
03344 int vartype = 0;
03345
03346 varname = ast_var_full_name(current);
03347 if (!varname)
03348 continue;
03349
03350 if (varname[0] == '_') {
03351 vartype = 1;
03352 if (varname[1] == '_')
03353 vartype = 2;
03354 }
03355
03356 switch (vartype) {
03357 case 1:
03358 newvar = ast_var_assign(&varname[1], ast_var_value(current));
03359 if (newvar) {
03360 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
03361 if (option_debug)
03362 ast_log(LOG_DEBUG, "Copying soft-transferable variable %s.\n", ast_var_name(newvar));
03363 }
03364 break;
03365 case 2:
03366 newvar = ast_var_assign(ast_var_full_name(current), ast_var_value(current));
03367 if (newvar) {
03368 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
03369 if (option_debug)
03370 ast_log(LOG_DEBUG, "Copying hard-transferable variable %s.\n", ast_var_name(newvar));
03371 }
03372 break;
03373 default:
03374 if (option_debug)
03375 ast_log(LOG_DEBUG, "Not copying variable %s.\n", ast_var_name(current));
03376 break;
03377 }
03378 }
03379 }
03380
03381
03382
03383
03384
03385
03386
03387
03388
03389
03390 static void clone_variables(struct ast_channel *original, struct ast_channel *clone)
03391 {
03392 struct ast_var_t *current, *newvar;
03393
03394
03395 if (AST_LIST_FIRST(&clone->varshead))
03396 AST_LIST_APPEND_LIST(&original->varshead, &clone->varshead, entries);
03397
03398
03399
03400 AST_LIST_TRAVERSE(&original->varshead, current, entries) {
03401 newvar = ast_var_assign(current->name, current->value);
03402 if (newvar)
03403 AST_LIST_INSERT_TAIL(&clone->varshead, newvar, entries);
03404 }
03405 }
03406
03407
03408
03409
03410
03411
03412 int ast_do_masquerade(struct ast_channel *original)
03413 {
03414 int x,i;
03415 int res=0;
03416 int origstate;
03417 struct ast_frame *cur;
03418 const struct ast_channel_tech *t;
03419 void *t_pvt;
03420 struct ast_callerid tmpcid;
03421 struct ast_channel *clone = original->masq;
03422 struct ast_channel *bridged;
03423 struct ast_cdr *cdr;
03424 int rformat = original->readformat;
03425 int wformat = original->writeformat;
03426 char newn[100];
03427 char orig[100];
03428 char masqn[100];
03429 char zombn[100];
03430
03431 if (option_debug > 3)
03432 ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",
03433 clone->name, clone->_state, original->name, original->_state);
03434
03435
03436
03437
03438
03439
03440
03441 ast_channel_lock(clone);
03442
03443 if (option_debug > 1)
03444 ast_log(LOG_DEBUG, "Got clone lock for masquerade on '%s' at %p\n", clone->name, &clone->lock);
03445
03446
03447
03448 free_translation(clone);
03449 free_translation(original);
03450
03451
03452
03453 original->masq = NULL;
03454 clone->masqr = NULL;
03455
03456
03457 ast_copy_string(orig, original->name, sizeof(orig));
03458
03459 ast_copy_string(newn, clone->name, sizeof(newn));
03460
03461 snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn);
03462
03463
03464 ast_string_field_set(original, name, newn);
03465
03466
03467 ast_string_field_set(clone, name, masqn);
03468
03469
03470 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", newn, masqn, clone->uniqueid);
03471 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", orig, newn, original->uniqueid);
03472
03473
03474 t = original->tech;
03475 original->tech = clone->tech;
03476 clone->tech = t;
03477
03478
03479 cdr = original->cdr;
03480 original->cdr = clone->cdr;
03481 clone->cdr = cdr;
03482
03483 t_pvt = original->tech_pvt;
03484 original->tech_pvt = clone->tech_pvt;
03485 clone->tech_pvt = t_pvt;
03486
03487
03488 for (i = 0; i < 2; i++) {
03489 x = original->alertpipe[i];
03490 original->alertpipe[i] = clone->alertpipe[i];
03491 clone->alertpipe[i] = x;
03492 }
03493
03494
03495
03496
03497
03498
03499
03500
03501
03502
03503
03504
03505 {
03506 AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq;
03507 AST_LIST_HEAD_SET_NOLOCK(&tmp_readq, NULL);
03508
03509 AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list);
03510 AST_LIST_APPEND_LIST(&original->readq, &clone->readq, frame_list);
03511
03512 while ((cur = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) {
03513 AST_LIST_INSERT_TAIL(&original->readq, cur, frame_list);
03514 if (original->alertpipe[1] > -1) {
03515 int poke = 0;
03516 write(original->alertpipe[1], &poke, sizeof(poke));
03517 }
03518 }
03519 }
03520
03521
03522 x = original->rawreadformat;
03523 original->rawreadformat = clone->rawreadformat;
03524 clone->rawreadformat = x;
03525 x = original->rawwriteformat;
03526 original->rawwriteformat = clone->rawwriteformat;
03527 clone->rawwriteformat = x;
03528
03529 clone->_softhangup = AST_SOFTHANGUP_DEV;
03530
03531
03532
03533
03534
03535 origstate = original->_state;
03536 original->_state = clone->_state;
03537 clone->_state = origstate;
03538
03539 if (clone->tech->fixup){
03540 res = clone->tech->fixup(original, clone);
03541 if (res)
03542 ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name);
03543 }
03544
03545
03546 if (clone->tech->hangup)
03547 res = clone->tech->hangup(clone);
03548 if (res) {
03549 ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n");
03550 ast_channel_unlock(clone);
03551 return -1;
03552 }
03553
03554 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig);
03555
03556 ast_string_field_set(clone, name, zombn);
03557 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", masqn, zombn, clone->uniqueid);
03558
03559
03560 t_pvt = original->monitor;
03561 original->monitor = clone->monitor;
03562 clone->monitor = t_pvt;
03563
03564
03565 ast_string_field_set(original, language, clone->language);
03566
03567 for (x = 0; x < AST_MAX_FDS; x++) {
03568 if (x != AST_GENERATOR_FD)
03569 original->fds[x] = clone->fds[x];
03570 }
03571
03572 ast_app_group_update(clone, original);
03573
03574 if (AST_LIST_FIRST(&clone->datastores)) {
03575 struct ast_datastore *ds;
03576 AST_LIST_APPEND_LIST(&original->datastores, &clone->datastores, entry);
03577 AST_LIST_TRAVERSE(&original->datastores, ds, entry) {
03578 if (ds->info->chan_fixup)
03579 ds->info->chan_fixup(ds->data, clone, original);
03580 }
03581 }
03582
03583 clone_variables(original, clone);
03584
03585 original->adsicpe = clone->adsicpe;
03586
03587
03588
03589
03590
03591 ast_copy_flags(original, clone, AST_FLAG_EXCEPTION);
03592 original->fdno = clone->fdno;
03593
03594
03595
03596
03597
03598
03599 tmpcid = original->cid;
03600 original->cid = clone->cid;
03601 clone->cid = tmpcid;
03602
03603
03604 original->fds[AST_TIMING_FD] = original->timingfd;
03605
03606
03607 original->nativeformats = clone->nativeformats;
03608
03609
03610
03611
03612
03613 ast_set_write_format(original, wformat);
03614
03615
03616 ast_set_read_format(original, rformat);
03617
03618
03619 ast_string_field_set(original, musicclass, clone->musicclass);
03620
03621 if (option_debug)
03622 ast_log(LOG_DEBUG, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat);
03623
03624
03625
03626 if (original->tech->fixup) {
03627 res = original->tech->fixup(clone, original);
03628 if (res) {
03629 ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n",
03630 original->tech->type, original->name);
03631 ast_channel_unlock(clone);
03632 return -1;
03633 }
03634 } else
03635 ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)! Bad things may happen.\n",
03636 original->tech->type, original->name);
03637
03638
03639 if (original->visible_indication)
03640 ast_indicate(original, original->visible_indication);
03641
03642
03643
03644
03645 if (ast_test_flag(clone, AST_FLAG_ZOMBIE)) {
03646 if (option_debug)
03647 ast_log(LOG_DEBUG, "Destroying channel clone '%s'\n", clone->name);
03648 ast_channel_unlock(clone);
03649 manager_event(EVENT_FLAG_CALL, "Hangup",
03650 "Channel: %s\r\n"
03651 "Uniqueid: %s\r\n"
03652 "Cause: %d\r\n"
03653 "Cause-txt: %s\r\n",
03654 clone->name,
03655 clone->uniqueid,
03656 clone->hangupcause,
03657 ast_cause2str(clone->hangupcause)
03658 );
03659 ast_channel_free(clone);
03660 } else {
03661 if (option_debug)
03662 ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name);
03663 ast_set_flag(clone, AST_FLAG_ZOMBIE);
03664 ast_queue_frame(clone, &ast_null_frame);
03665 ast_channel_unlock(clone);
03666 }
03667
03668
03669 if (ast_test_flag(original, AST_FLAG_BLOCKING))
03670 pthread_kill(original->blocker, SIGURG);
03671 if (option_debug)
03672 ast_log(LOG_DEBUG, "Done Masquerading %s (%d)\n", original->name, original->_state);
03673
03674 if ((bridged = ast_bridged_channel(original))) {
03675 ast_channel_lock(bridged);
03676 ast_indicate(bridged, AST_CONTROL_SRCCHANGE);
03677 ast_channel_unlock(bridged);
03678 }
03679
03680 ast_indicate(original, AST_CONTROL_SRCCHANGE);
03681
03682 return 0;
03683 }
03684
03685 void ast_set_callerid(struct ast_channel *chan, const char *callerid, const char *calleridname, const char *ani)
03686 {
03687 ast_channel_lock(chan);
03688
03689 if (callerid) {
03690 if (chan->cid.cid_num)
03691 free(chan->cid.cid_num);
03692 chan->cid.cid_num = ast_strdup(callerid);
03693 }
03694 if (calleridname) {
03695 if (chan->cid.cid_name)
03696 free(chan->cid.cid_name);
03697 chan->cid.cid_name = ast_strdup(calleridname);
03698 }
03699 if (ani) {
03700 if (chan->cid.cid_ani)
03701 free(chan->cid.cid_ani);
03702 chan->cid.cid_ani = ast_strdup(ani);
03703 }
03704 if (chan->cdr)
03705 ast_cdr_setcid(chan->cdr, chan);
03706 manager_event(EVENT_FLAG_CALL, "Newcallerid",
03707 "Channel: %s\r\n"
03708 "CallerID: %s\r\n"
03709 "CallerIDName: %s\r\n"
03710 "Uniqueid: %s\r\n"
03711 "CID-CallingPres: %d (%s)\r\n",
03712 chan->name,
03713 S_OR(chan->cid.cid_num, "<Unknown>"),
03714 S_OR(chan->cid.cid_name, "<Unknown>"),
03715 chan->uniqueid,
03716 chan->cid.cid_pres,
03717 ast_describe_caller_presentation(chan->cid.cid_pres)
03718 );
03719
03720 ast_channel_unlock(chan);
03721 }
03722
03723 int ast_setstate_and_callerid(struct ast_channel *chan, enum ast_channel_state state, char *cid_num, char *cid_name)
03724 {
03725 int oldstate = chan->_state;
03726
03727 if (oldstate == state)
03728 return 0;
03729
03730 chan->_state = state;
03731 ast_device_state_changed_literal(chan->name, cid_num, cid_name);
03732
03733 manager_event(EVENT_FLAG_CALL,
03734 "Newstate",
03735 "Channel: %s\r\n"
03736 "State: %s\r\n"
03737 "CallerID: %s\r\n"
03738 "CallerIDName: %s\r\n"
03739 "Uniqueid: %s\r\n",
03740 chan->name, ast_state2str(chan->_state),
03741 S_OR(chan->cid.cid_num, "<unknown>"),
03742 S_OR(chan->cid.cid_name, "<unknown>"),
03743 chan->uniqueid);
03744
03745 return 0;
03746 }
03747
03748 int ast_setstate(struct ast_channel *chan, enum ast_channel_state state)
03749 {
03750 return ast_setstate_and_callerid(chan, state, NULL, NULL);
03751 }
03752
03753
03754 struct ast_channel *ast_bridged_channel(struct ast_channel *chan)
03755 {
03756 struct ast_channel *bridged;
03757 bridged = chan->_bridge;
03758 if (bridged && bridged->tech->bridged_channel)
03759 bridged = bridged->tech->bridged_channel(chan, bridged);
03760 return bridged;
03761 }
03762
03763 static void bridge_playfile(struct ast_channel *chan, struct ast_channel *peer, const char *sound, int remain)
03764 {
03765 int min = 0, sec = 0, check;
03766
03767 check = ast_autoservice_start(peer);
03768 if (check)
03769 return;
03770
03771 if (remain > 0) {
03772 if (remain / 60 > 1) {
03773 min = remain / 60;
03774 sec = remain % 60;
03775 } else {
03776 sec = remain;
03777 }
03778 }
03779
03780 if (!strcmp(sound,"timeleft")) {
03781 ast_stream_and_wait(chan, "vm-youhave", chan->language, "");
03782 if (min) {
03783 ast_say_number(chan, min, AST_DIGIT_ANY, chan->language, NULL);
03784 ast_stream_and_wait(chan, "queue-minutes", chan->language, "");
03785 }
03786 if (sec) {
03787 ast_say_number(chan, sec, AST_DIGIT_ANY, chan->language, NULL);
03788 ast_stream_and_wait(chan, "queue-seconds", chan->language, "");
03789 }
03790 } else {
03791 ast_stream_and_wait(chan, sound, chan->language, "");
03792 }
03793
03794 ast_autoservice_stop(peer);
03795 }
03796
03797 static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct ast_channel *c1,
03798 struct ast_bridge_config *config, struct ast_frame **fo,
03799 struct ast_channel **rc, struct timeval bridge_end)
03800 {
03801
03802 struct ast_channel *cs[3];
03803 struct ast_frame *f;
03804 enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
03805 int o0nativeformats;
03806 int o1nativeformats;
03807 int watch_c0_dtmf;
03808 int watch_c1_dtmf;
03809 void *pvt0, *pvt1;
03810
03811 int frame_put_in_jb = 0;
03812 int jb_in_use;
03813 int to;
03814
03815 cs[0] = c0;
03816 cs[1] = c1;
03817 pvt0 = c0->tech_pvt;
03818 pvt1 = c1->tech_pvt;
03819 o0nativeformats = c0->nativeformats;
03820 o1nativeformats = c1->nativeformats;
03821 watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0;
03822 watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1;
03823
03824
03825 jb_in_use = ast_jb_do_usecheck(c0, c1);
03826
03827 for (;;) {
03828 struct ast_channel *who, *other;
03829
03830 if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) ||
03831 (o0nativeformats != c0->nativeformats) ||
03832 (o1nativeformats != c1->nativeformats)) {
03833
03834 res = AST_BRIDGE_RETRY;
03835 break;
03836 }
03837 if (bridge_end.tv_sec) {
03838 to = ast_tvdiff_ms(bridge_end, ast_tvnow());
03839 if (to <= 0) {
03840 if (config->timelimit)
03841 res = AST_BRIDGE_RETRY;
03842 else
03843 res = AST_BRIDGE_COMPLETE;
03844 break;
03845 }
03846 } else
03847 to = -1;
03848
03849
03850 if (jb_in_use)
03851 to = ast_jb_get_when_to_wakeup(c0, c1, to);
03852 who = ast_waitfor_n(cs, 2, &to);
03853 if (!who) {
03854
03855 if (jb_in_use)
03856 ast_jb_get_and_deliver(c0, c1);
03857 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
03858 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03859 c0->_softhangup = 0;
03860 if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03861 c1->_softhangup = 0;
03862 c0->_bridge = c1;
03863 c1->_bridge = c0;
03864 }
03865 continue;
03866 }
03867 f = ast_read(who);
03868 if (!f) {
03869 *fo = NULL;
03870 *rc = who;
03871 if (option_debug)
03872 ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name);
03873 break;
03874 }
03875
03876 other = (who == c0) ? c1 : c0;
03877
03878 if (jb_in_use)
03879 frame_put_in_jb = !ast_jb_put(other, f);
03880
03881 if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) {
03882 int bridge_exit = 0;
03883
03884 switch (f->subclass) {
03885 case AST_CONTROL_HOLD:
03886 case AST_CONTROL_UNHOLD:
03887 case AST_CONTROL_VIDUPDATE:
03888 case AST_CONTROL_SRCUPDATE:
03889 case AST_CONTROL_SRCCHANGE:
03890 ast_indicate_data(other, f->subclass, f->data, f->datalen);
03891 break;
03892 default:
03893 *fo = f;
03894 *rc = who;
03895 bridge_exit = 1;
03896 if (option_debug)
03897 ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name);
03898 break;
03899 }
03900 if (bridge_exit)
03901 break;
03902 }
03903 if ((f->frametype == AST_FRAME_VOICE) ||
03904 (f->frametype == AST_FRAME_DTMF_BEGIN) ||
03905 (f->frametype == AST_FRAME_DTMF) ||
03906 (f->frametype == AST_FRAME_VIDEO) ||
03907 (f->frametype == AST_FRAME_IMAGE) ||
03908 (f->frametype == AST_FRAME_HTML) ||
03909 (f->frametype == AST_FRAME_MODEM) ||
03910 (f->frametype == AST_FRAME_TEXT)) {
03911
03912 int monitored_source = (who == c0) ? watch_c0_dtmf : watch_c1_dtmf;
03913
03914 if (monitored_source &&
03915 (f->frametype == AST_FRAME_DTMF_END ||
03916 f->frametype == AST_FRAME_DTMF_BEGIN)) {
03917 *fo = f;
03918 *rc = who;
03919 if (option_debug)
03920 ast_log(LOG_DEBUG, "Got DTMF %s on channel (%s)\n",
03921 f->frametype == AST_FRAME_DTMF_END ? "end" : "begin",
03922 who->name);
03923 break;
03924 }
03925
03926 if (!frame_put_in_jb)
03927 ast_write(other, f);
03928
03929
03930 if (jb_in_use)
03931 ast_jb_get_and_deliver(c0, c1);
03932 }
03933
03934 ast_frfree(f);
03935
03936
03937 cs[2] = cs[0];
03938 cs[0] = cs[1];
03939 cs[1] = cs[2];
03940 }
03941 return res;
03942 }
03943
03944
03945 enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1,
03946 struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc)
03947 {
03948 struct ast_channel *who = NULL;
03949 enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
03950 int nativefailed=0;
03951 int firstpass;
03952 int o0nativeformats;
03953 int o1nativeformats;
03954 long time_left_ms=0;
03955 struct timeval nexteventts = { 0, };
03956 char caller_warning = 0;
03957 char callee_warning = 0;
03958
03959 if (c0->_bridge) {
03960 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
03961 c0->name, c0->_bridge->name);
03962 return -1;
03963 }
03964 if (c1->_bridge) {
03965 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
03966 c1->name, c1->_bridge->name);
03967 return -1;
03968 }
03969
03970 if (IS_DIGITAL(c0->transfercapability) || IS_DIGITAL(c1->transfercapability)) {
03971 config->flags = 0;
03972 }
03973
03974
03975 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
03976 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1))
03977 return -1;
03978
03979 *fo = NULL;
03980 firstpass = config->firstpass;
03981 config->firstpass = 0;
03982
03983 if (ast_tvzero(config->start_time))
03984 config->start_time = ast_tvnow();
03985 time_left_ms = config->timelimit;
03986
03987 caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING);
03988 callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING);
03989
03990 if (config->start_sound && firstpass) {
03991 if (caller_warning)
03992 bridge_playfile(c0, c1, config->start_sound, time_left_ms / 1000);
03993 if (callee_warning)
03994 bridge_playfile(c1, c0, config->start_sound, time_left_ms / 1000);
03995 }
03996
03997
03998 c0->_bridge = c1;
03999 c1->_bridge = c0;
04000
04001
04002 manager_event(EVENT_FLAG_CALL, "Link",
04003 "Channel1: %s\r\n"
04004 "Channel2: %s\r\n"
04005 "Uniqueid1: %s\r\n"
04006 "Uniqueid2: %s\r\n"
04007 "CallerID1: %s\r\n"
04008 "CallerID2: %s\r\n",
04009 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
04010
04011 o0nativeformats = c0->nativeformats;
04012 o1nativeformats = c1->nativeformats;
04013
04014 if (config->feature_timer) {
04015 nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->feature_timer, 1000));
04016 } else if (config->timelimit) {
04017 nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
04018 if (caller_warning || callee_warning)
04019 nexteventts = ast_tvsub(nexteventts, ast_samp2tv(config->play_warning, 1000));
04020 }
04021
04022 if (!c0->tech->send_digit_begin)
04023 ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY);
04024 if (!c1->tech->send_digit_begin)
04025 ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY);
04026
04027
04028 ast_indicate(c0, AST_CONTROL_SRCCHANGE);
04029 ast_indicate(c1, AST_CONTROL_SRCCHANGE);
04030
04031 for (;;) {
04032 struct timeval now = { 0, };
04033 int to;
04034
04035 to = -1;
04036
04037 if (!ast_tvzero(nexteventts)) {
04038 now = ast_tvnow();
04039 to = ast_tvdiff_ms(nexteventts, now);
04040 if (to <= 0) {
04041 if (!config->timelimit) {
04042 res = AST_BRIDGE_COMPLETE;
04043 break;
04044 }
04045 to = 0;
04046 }
04047 }
04048
04049 if (config->timelimit) {
04050 time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time);
04051 if (time_left_ms < to)
04052 to = time_left_ms;
04053
04054 if (time_left_ms <= 0) {
04055 if (caller_warning && config->end_sound)
04056 bridge_playfile(c0, c1, config->end_sound, 0);
04057 if (callee_warning && config->end_sound)
04058 bridge_playfile(c1, c0, config->end_sound, 0);
04059 *fo = NULL;
04060 if (who)
04061 *rc = who;
04062 res = 0;
04063 break;
04064 }
04065
04066 if (!to) {
04067 if (time_left_ms >= 5000 && config->warning_sound && config->play_warning) {
04068 int t = (time_left_ms + 500) / 1000;
04069 if (caller_warning)
04070 bridge_playfile(c0, c1, config->warning_sound, t);
04071 if (callee_warning)
04072 bridge_playfile(c1, c0, config->warning_sound, t);
04073 }
04074 if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000)))
04075 nexteventts = ast_tvadd(nexteventts, ast_samp2tv(config->warning_freq, 1000));
04076 else
04077 nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
04078 }
04079 }
04080
04081 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
04082 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
04083 c0->_softhangup = 0;
04084 if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
04085 c1->_softhangup = 0;
04086 c0->_bridge = c1;
04087 c1->_bridge = c0;
04088 if (option_debug)
04089 ast_log(LOG_DEBUG, "Unbridge signal received. Ending native bridge.\n");
04090 continue;
04091 }
04092
04093
04094 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
04095 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) {
04096 *fo = NULL;
04097 if (who)
04098 *rc = who;
04099 res = 0;
04100 if (option_debug)
04101 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",
04102 c0->name, c1->name,
04103 ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No",
04104 ast_check_hangup(c0) ? "Yes" : "No",
04105 ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No",
04106 ast_check_hangup(c1) ? "Yes" : "No");
04107 break;
04108 }
04109
04110
04111 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER")))
04112 pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1->name);
04113 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER")))
04114 pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0->name);
04115
04116 if (c0->tech->bridge &&
04117 (config->timelimit == 0) &&
04118 (c0->tech->bridge == c1->tech->bridge) &&
04119 !nativefailed && !c0->monitor && !c1->monitor &&
04120 !c0->audiohooks && !c1->audiohooks && !ast_test_flag(&(config->features_callee),AST_FEATURE_REDIRECT) &&
04121 !ast_test_flag(&(config->features_caller),AST_FEATURE_REDIRECT) &&
04122 !c0->masq && !c0->masqr && !c1->masq && !c1->masqr) {
04123
04124 ast_set_flag(c0, AST_FLAG_NBRIDGE);
04125 ast_set_flag(c1, AST_FLAG_NBRIDGE);
04126 if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, to)) == AST_BRIDGE_COMPLETE) {
04127
04128 manager_event(EVENT_FLAG_CALL, "Unlink",
04129 "Channel1: %s\r\n"
04130 "Channel2: %s\r\n"
04131 "Uniqueid1: %s\r\n"
04132 "Uniqueid2: %s\r\n"
04133 "CallerID1: %s\r\n"
04134 "CallerID2: %s\r\n",
04135 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
04136 if (option_debug)
04137 ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name);
04138
04139 ast_clear_flag(c0, AST_FLAG_NBRIDGE);
04140 ast_clear_flag(c1, AST_FLAG_NBRIDGE);
04141
04142 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
04143 continue;
04144
04145 c0->_bridge = NULL;
04146 c1->_bridge = NULL;
04147
04148 return res;
04149 } else {
04150 ast_clear_flag(c0, AST_FLAG_NBRIDGE);
04151 ast_clear_flag(c1, AST_FLAG_NBRIDGE);
04152 }
04153 switch (res) {
04154 case AST_BRIDGE_RETRY:
04155 continue;
04156 default:
04157 if (option_verbose > 2)
04158 ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s ended\n",
04159 c0->name, c1->name);
04160
04161 case AST_BRIDGE_FAILED_NOWARN:
04162 nativefailed++;
04163 break;
04164 }
04165 }
04166
04167 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) ||
04168 (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) &&
04169 !(c0->generator || c1->generator)) {
04170 if (ast_channel_make_compatible(c0, c1)) {
04171 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
04172
04173 manager_event(EVENT_FLAG_CALL, "Unlink",
04174 "Channel1: %s\r\n"
04175 "Channel2: %s\r\n"
04176 "Uniqueid1: %s\r\n"
04177 "Uniqueid2: %s\r\n"
04178 "CallerID1: %s\r\n"
04179 "CallerID2: %s\r\n",
04180 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
04181 return AST_BRIDGE_FAILED;
04182 }
04183 o0nativeformats = c0->nativeformats;
04184 o1nativeformats = c1->nativeformats;
04185 }
04186 res = ast_generic_bridge(c0, c1, config, fo, rc, nexteventts);
04187 if (res != AST_BRIDGE_RETRY)
04188 break;
04189 }
04190
04191 ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY);
04192 ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY);
04193
04194
04195 ast_indicate(c0, AST_CONTROL_SRCUPDATE);
04196 ast_indicate(c1, AST_CONTROL_SRCUPDATE);
04197
04198 c0->_bridge = NULL;
04199 c1->_bridge = NULL;
04200
04201
04202 manager_event(EVENT_FLAG_CALL, "Unlink",
04203 "Channel1: %s\r\n"
04204 "Channel2: %s\r\n"
04205 "Uniqueid1: %s\r\n"
04206 "Uniqueid2: %s\r\n"
04207 "CallerID1: %s\r\n"
04208 "CallerID2: %s\r\n",
04209 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
04210 if (option_debug)
04211 ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name);
04212
04213 return res;
04214 }
04215
04216
04217 int ast_channel_setoption(struct ast_channel *chan, int option, void *data, int datalen, int block)
04218 {
04219 int res;
04220
04221 if (chan->tech->setoption) {
04222 res = chan->tech->setoption(chan, option, data, datalen);
04223 if (res < 0)
04224 return res;
04225 } else {
04226 errno = ENOSYS;
04227 return -1;
04228 }
04229 if (block) {
04230
04231
04232 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
04233 return -1;
04234 }
04235 return 0;
04236 }
04237
04238 struct tonepair_def {
04239 int freq1;
04240 int freq2;
04241 int duration;
04242 int vol;
04243 };
04244
04245 struct tonepair_state {
04246 int fac1;
04247 int fac2;
04248 int v1_1;
04249 int v2_1;
04250 int v3_1;
04251 int v1_2;
04252 int v2_2;
04253 int v3_2;
04254 int origwfmt;
04255 int pos;
04256 int duration;
04257 int modulate;
04258 struct ast_frame f;
04259 unsigned char offset[AST_FRIENDLY_OFFSET];
04260 short data[4000];
04261 };
04262
04263 static void tonepair_release(struct ast_channel *chan, void *params)
04264 {
04265 struct tonepair_state *ts = params;
04266
04267 if (chan)
04268 ast_set_write_format(chan, ts->origwfmt);
04269 free(ts);
04270 }
04271
04272 static void *tonepair_alloc(struct ast_channel *chan, void *params)
04273 {
04274 struct tonepair_state *ts;
04275 struct tonepair_def *td = params;
04276
04277 if (!(ts = ast_calloc(1, sizeof(*ts))))
04278 return NULL;
04279 ts->origwfmt = chan->writeformat;
04280 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
04281 ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
04282 tonepair_release(NULL, ts);
04283 ts = NULL;
04284 } else {
04285 ts->fac1 = 2.0 * cos(2.0 * M_PI * (td->freq1 / 8000.0)) * 32768.0;
04286 ts->v1_1 = 0;
04287 ts->v2_1 = sin(-4.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
04288 ts->v3_1 = sin(-2.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
04289 ts->v2_1 = 0;
04290 ts->fac2 = 2.0 * cos(2.0 * M_PI * (td->freq2 / 8000.0)) * 32768.0;
04291 ts->v2_2 = sin(-4.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
04292 ts->v3_2 = sin(-2.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
04293 ts->duration = td->duration;
04294 ts->modulate = 0;
04295 }
04296
04297 ast_set_flag(chan, AST_FLAG_WRITE_INT);
04298 return ts;
04299 }
04300
04301 static int tonepair_generator(struct ast_channel *chan, void *data, int len, int samples)
04302 {
04303 struct tonepair_state *ts = data;
04304 int x;
04305
04306
04307
04308
04309 len = samples * 2;
04310
04311 if (len > sizeof(ts->data) / 2 - 1) {
04312 ast_log(LOG_WARNING, "Can't generate that much data!\n");
04313 return -1;
04314 }
04315 memset(&ts->f, 0, sizeof(ts->f));
04316 for (x=0;x<len/2;x++) {
04317 ts->v1_1 = ts->v2_1;
04318 ts->v2_1 = ts->v3_1;
04319 ts->v3_1 = (ts->fac1 * ts->v2_1 >> 15) - ts->v1_1;
04320
04321 ts->v1_2 = ts->v2_2;
04322 ts->v2_2 = ts->v3_2;
04323 ts->v3_2 = (ts->fac2 * ts->v2_2 >> 15) - ts->v1_2;
04324 if (ts->modulate) {
04325 int p;
04326 p = ts->v3_2 - 32768;
04327 if (p < 0) p = -p;
04328 p = ((p * 9) / 10) + 1;
04329 ts->data[x] = (ts->v3_1 * p) >> 15;
04330 } else
04331 ts->data[x] = ts->v3_1 + ts->v3_2;
04332 }
04333 ts->f.frametype = AST_FRAME_VOICE;
04334 ts->f.subclass = AST_FORMAT_SLINEAR;
04335 ts->f.datalen = len;
04336 ts->f.samples = samples;
04337 ts->f.offset = AST_FRIENDLY_OFFSET;
04338 ts->f.data = ts->data;
04339 ast_write(chan, &ts->f);
04340 ts->pos += x;
04341 if (ts->duration > 0) {
04342 if (ts->pos >= ts->duration * 8)
04343 return -1;
04344 }
04345 return 0;
04346 }
04347
04348 static struct ast_generator tonepair = {
04349 alloc: tonepair_alloc,
04350 release: tonepair_release,
04351 generate: tonepair_generator,
04352 };
04353
04354 int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
04355 {
04356 struct tonepair_def d = { 0, };
04357
04358 d.freq1 = freq1;
04359 d.freq2 = freq2;
04360 d.duration = duration;
04361 d.vol = (vol < 1) ? 8192 : vol;
04362 if (ast_activate_generator(chan, &tonepair, &d))
04363 return -1;
04364 return 0;
04365 }
04366
04367 void ast_tonepair_stop(struct ast_channel *chan)
04368 {
04369 ast_deactivate_generator(chan);
04370 }
04371
04372 int ast_tonepair(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
04373 {
04374 int res;
04375
04376 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
04377 return res;
04378
04379
04380 while (chan->generatordata && ast_waitfor(chan, 100) >= 0) {
04381 struct ast_frame *f = ast_read(chan);
04382 if (f)
04383 ast_frfree(f);
04384 else
04385 return -1;
04386 }
04387 return 0;
04388 }
04389
04390 ast_group_t ast_get_group(const char *s)
04391 {
04392 char *piece;
04393 char *c;
04394 int start=0, finish=0, x;
04395 ast_group_t group = 0;
04396
04397 if (ast_strlen_zero(s))
04398 return 0;
04399
04400 c = ast_strdupa(s);
04401
04402 while ((piece = strsep(&c, ","))) {
04403 if (sscanf(piece, "%d-%d", &start, &finish) == 2) {
04404
04405 } else if (sscanf(piece, "%d", &start)) {
04406
04407 finish = start;
04408 } else {
04409 ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece);
04410 continue;
04411 }
04412 for (x = start; x <= finish; x++) {
04413 if ((x > 63) || (x < 0)) {
04414 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x);
04415 } else
04416 group |= ((ast_group_t) 1 << x);
04417 }
04418 }
04419 return group;
04420 }
04421
04422 static int (*ast_moh_start_ptr)(struct ast_channel *, const char *, const char *) = NULL;
04423 static void (*ast_moh_stop_ptr)(struct ast_channel *) = NULL;
04424 static void (*ast_moh_cleanup_ptr)(struct ast_channel *) = NULL;
04425
04426 void ast_install_music_functions(int (*start_ptr)(struct ast_channel *, const char *, const char *),
04427 void (*stop_ptr)(struct ast_channel *),
04428 void (*cleanup_ptr)(struct ast_channel *))
04429 {
04430 ast_moh_start_ptr = start_ptr;
04431 ast_moh_stop_ptr = stop_ptr;
04432 ast_moh_cleanup_ptr = cleanup_ptr;
04433 }
04434
04435 void ast_uninstall_music_functions(void)
04436 {
04437 ast_moh_start_ptr = NULL;
04438 ast_moh_stop_ptr = NULL;
04439 ast_moh_cleanup_ptr = NULL;
04440 }
04441
04442
04443 int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
04444 {
04445 if (ast_moh_start_ptr)
04446 return ast_moh_start_ptr(chan, mclass, interpclass);
04447
04448 if (option_verbose > 2) {
04449 ast_verbose(VERBOSE_PREFIX_3 "Music class %s requested but no musiconhold loaded.\n",
04450 mclass ? mclass : (interpclass ? interpclass : "default"));
04451 }
04452
04453 return 0;
04454 }
04455
04456
04457 void ast_moh_stop(struct ast_channel *chan)
04458 {
04459 if (ast_moh_stop_ptr)
04460 ast_moh_stop_ptr(chan);
04461 }
04462
04463 void ast_moh_cleanup(struct ast_channel *chan)
04464 {
04465 if (ast_moh_cleanup_ptr)
04466 ast_moh_cleanup_ptr(chan);
04467 }
04468
04469 void ast_channels_init(void)
04470 {
04471 ast_cli_register_multiple(cli_channel, sizeof(cli_channel) / sizeof(struct ast_cli_entry));
04472 }
04473
04474
04475 char *ast_print_group(char *buf, int buflen, ast_group_t group)
04476 {
04477 unsigned int i;
04478 int first=1;
04479 char num[3];
04480
04481 buf[0] = '\0';
04482
04483 if (!group)
04484 return buf;
04485
04486 for (i = 0; i <= 63; i++) {
04487 if (group & ((ast_group_t) 1 << i)) {
04488 if (!first) {
04489 strncat(buf, ", ", buflen - strlen(buf) - 1);
04490 } else {
04491 first=0;
04492 }
04493 snprintf(num, sizeof(num), "%u", i);
04494 strncat(buf, num, buflen - strlen(buf) - 1);
04495 }
04496 }
04497 return buf;
04498 }
04499
04500 void ast_set_variables(struct ast_channel *chan, struct ast_variable *vars)
04501 {
04502 struct ast_variable *cur;
04503
04504 for (cur = vars; cur; cur = cur->next)
04505 pbx_builtin_setvar_helper(chan, cur->name, cur->value);
04506 }
04507
04508 static void *silence_generator_alloc(struct ast_channel *chan, void *data)
04509 {
04510
04511 return data;
04512 }
04513
04514 static void silence_generator_release(struct ast_channel *chan, void *data)
04515 {
04516
04517 }
04518
04519 static int silence_generator_generate(struct ast_channel *chan, void *data, int len, int samples)
04520 {
04521 short buf[samples];
04522 struct ast_frame frame = {
04523 .frametype = AST_FRAME_VOICE,
04524 .subclass = AST_FORMAT_SLINEAR,
04525 .data = buf,
04526 .samples = samples,
04527 .datalen = sizeof(buf),
04528 };
04529 memset(buf, 0, sizeof(buf));
04530 if (ast_write(chan, &frame))
04531 return -1;
04532 return 0;
04533 }
04534
04535 static struct ast_generator silence_generator = {
04536 .alloc = silence_generator_alloc,
04537 .release = silence_generator_release,
04538 .generate = silence_generator_generate,
04539 };
04540
04541 struct ast_silence_generator {
04542 int old_write_format;
04543 };
04544
04545 struct ast_silence_generator *ast_channel_start_silence_generator(struct ast_channel *chan)
04546 {
04547 struct ast_silence_generator *state;
04548
04549 if (!(state = ast_calloc(1, sizeof(*state)))) {
04550 return NULL;
04551 }
04552
04553 state->old_write_format = chan->writeformat;
04554
04555 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
04556 ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
04557 free(state);
04558 return NULL;
04559 }
04560
04561 ast_activate_generator(chan, &silence_generator, state);
04562
04563 if (option_debug)
04564 ast_log(LOG_DEBUG, "Started silence generator on '%s'\n", chan->name);
04565
04566 return state;
04567 }
04568
04569 void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_silence_generator *state)
04570 {
04571 if (!state)
04572 return;
04573
04574 ast_deactivate_generator(chan);
04575
04576 if (option_debug)
04577 ast_log(LOG_DEBUG, "Stopped silence generator on '%s'\n", chan->name);
04578
04579 if (ast_set_write_format(chan, state->old_write_format) < 0)
04580 ast_log(LOG_ERROR, "Could not return write format to its original state\n");
04581
04582 free(state);
04583 }
04584
04585
04586 int ast_send_message(const char *type, void *data, char *to, char *from, char *message, int ispdu) {
04587 struct ast_channel *chan = NULL;
04588 int status;
04589 int res = -1;
04590
04591 chan = ast_request(type, AST_FORMAT_SLINEAR, data, &status);
04592 if (chan) {
04593 if (from) {
04594 ast_set_callerid(chan, from, from, from);
04595 }
04596 res = ast_sendmessage(chan, to, message, ispdu);
04597
04598 ast_hangup(chan);
04599 return res;
04600 }
04601
04602 return res;
04603 }
04604
04605
04606 const char *channelreloadreason2txt(enum channelreloadreason reason)
04607 {
04608 switch (reason) {
04609 case CHANNEL_MODULE_LOAD:
04610 return "LOAD (Channel module load)";
04611
04612 case CHANNEL_MODULE_RELOAD:
04613 return "RELOAD (Channel module reload)";
04614
04615 case CHANNEL_CLI_RELOAD:
04616 return "CLIRELOAD (Channel module reload by CLI command)";
04617
04618 default:
04619 return "MANAGERRELOAD (Channel module reload by manager)";
04620 }
04621 };
04622
04623 #ifdef DEBUG_CHANNEL_LOCKS
04624
04625
04626
04627
04628 int __ast_channel_unlock(struct ast_channel *chan, const char *filename, int lineno, const char *func)
04629 {
04630 int res = 0;
04631 if (option_debug > 2)
04632 ast_log(LOG_DEBUG, "::::==== Unlocking AST channel %s\n", chan->name);
04633
04634 if (!chan) {
04635 if (option_debug)
04636 ast_log(LOG_DEBUG, "::::==== Unlocking non-existing channel \n");
04637 return 0;
04638 }
04639 #ifdef DEBUG_THREADS
04640 res = __ast_pthread_mutex_unlock(filename, lineno, func, "(channel lock)", &chan->lock);
04641 #else
04642 res = ast_mutex_unlock(&chan->lock);
04643 #endif
04644
04645 if (option_debug > 2) {
04646 #ifdef DEBUG_THREADS
04647 int count = 0;
04648 if ((count = chan->lock.reentrancy))
04649 ast_log(LOG_DEBUG, ":::=== Still have %d locks (recursive)\n", count);
04650 #endif
04651 if (!res)
04652 if (option_debug)
04653 ast_log(LOG_DEBUG, "::::==== Channel %s was unlocked\n", chan->name);
04654 if (res == EINVAL) {
04655 if (option_debug)
04656 ast_log(LOG_DEBUG, "::::==== Channel %s had no lock by this thread. Failed unlocking\n", chan->name);
04657 }
04658 }
04659 if (res == EPERM) {
04660
04661 if (option_debug > 3)
04662 ast_log(LOG_DEBUG, "::::==== Channel %s was not locked at all \n", chan->name);
04663 res = 0;
04664 }
04665 return res;
04666 }
04667
04668
04669
04670 int __ast_channel_lock(struct ast_channel *chan, const char *filename, int lineno, const char *func)
04671 {
04672 int res;
04673
04674 if (option_debug > 3)
04675 ast_log(LOG_DEBUG, "====:::: Locking AST channel %s\n", chan->name);
04676
04677 #ifdef DEBUG_THREADS
04678 res = __ast_pthread_mutex_lock(filename, lineno, func, "(channel lock)", &chan->lock);
04679 #else
04680 res = ast_mutex_lock(&chan->lock);
04681 #endif
04682
04683 if (option_debug > 3) {
04684 #ifdef DEBUG_THREADS
04685 int count = 0;
04686 if ((count = chan->lock.reentrancy))
04687 ast_log(LOG_DEBUG, ":::=== Now have %d locks (recursive)\n", count);
04688 #endif
04689 if (!res)
04690 ast_log(LOG_DEBUG, "::::==== Channel %s was locked\n", chan->name);
04691 if (res == EDEADLK) {
04692
04693 if (option_debug > 3)
04694 ast_log(LOG_DEBUG, "::::==== Channel %s was not locked by us. Lock would cause deadlock.\n", chan->name);
04695 }
04696 if (res == EINVAL) {
04697 if (option_debug > 3)
04698 ast_log(LOG_DEBUG, "::::==== Channel %s lock failed. No mutex.\n", chan->name);
04699 }
04700 }
04701 return res;
04702 }
04703
04704
04705
04706 int __ast_channel_trylock(struct ast_channel *chan, const char *filename, int lineno, const char *func)
04707 {
04708 int res;
04709
04710 if (option_debug > 2)
04711 ast_log(LOG_DEBUG, "====:::: Trying to lock AST channel %s\n", chan->name);
04712 #ifdef DEBUG_THREADS
04713 res = __ast_pthread_mutex_trylock(filename, lineno, func, "(channel lock)", &chan->lock);
04714 #else
04715 res = ast_mutex_trylock(&chan->lock);
04716 #endif
04717
04718 if (option_debug > 2) {
04719 #ifdef DEBUG_THREADS
04720 int count = 0;
04721 if ((count = chan->lock.reentrancy))
04722 ast_log(LOG_DEBUG, ":::=== Now have %d locks (recursive)\n", count);
04723 #endif
04724 if (!res)
04725 ast_log(LOG_DEBUG, "::::==== Channel %s was locked\n", chan->name);
04726 if (res == EBUSY) {
04727
04728 if (option_debug > 2)
04729 ast_log(LOG_DEBUG, "::::==== Channel %s failed to lock. Not waiting around...\n", chan->name);
04730 }
04731 if (res == EDEADLK) {
04732
04733 if (option_debug > 2)
04734 ast_log(LOG_DEBUG, "::::==== Channel %s was not locked. Lock would cause deadlock.\n", chan->name);
04735 }
04736 if (res == EINVAL && option_debug > 2)
04737 ast_log(LOG_DEBUG, "::::==== Channel %s lock failed. No mutex.\n", chan->name);
04738 }
04739 return res;
04740 }
04741
04742 #endif
04743
04744
04745
04746
04747
04748
04749
04750
04751
04752 int ast_say_number(struct ast_channel *chan, int num,
04753 const char *ints, const char *language, const char *options)
04754 {
04755 return ast_say_number_full(chan, num, ints, language, options, -1, -1);
04756 }
04757
04758 int ast_say_enumeration(struct ast_channel *chan, int num,
04759 const char *ints, const char *language, const char *options)
04760 {
04761 return ast_say_enumeration_full(chan, num, ints, language, options, -1, -1);
04762 }
04763
04764 int ast_say_digits(struct ast_channel *chan, int num,
04765 const char *ints, const char *lang)
04766 {
04767 return ast_say_digits_full(chan, num, ints, lang, -1, -1);
04768 }
04769
04770 int ast_say_digit_str(struct ast_channel *chan, const char *str,
04771 const char *ints, const char *lang)
04772 {
04773 return ast_say_digit_str_full(chan, str, ints, lang, -1, -1);
04774 }
04775
04776 int ast_say_character_str(struct ast_channel *chan, const char *str,
04777 const char *ints, const char *lang)
04778 {
04779 return ast_say_character_str_full(chan, str, ints, lang, -1, -1);
04780 }
04781
04782 int ast_say_phonetic_str(struct ast_channel *chan, const char *str,
04783 const char *ints, const char *lang)
04784 {
04785 return ast_say_phonetic_str_full(chan, str, ints, lang, -1, -1);
04786 }
04787
04788 int ast_say_digits_full(struct ast_channel *chan, int num,
04789 const char *ints, const char *lang, int audiofd, int ctrlfd)
04790 {
04791 char buf[256];
04792
04793 snprintf(buf, sizeof(buf), "%d", num);
04794 return ast_say_digit_str_full(chan, buf, ints, lang, audiofd, ctrlfd);
04795 }
04796