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