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