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