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