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