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: 354494 $")
00029
00030 #include "asterisk/_private.h"
00031
00032 #include <sys/time.h>
00033 #include <signal.h>
00034 #include <math.h>
00035
00036 #include "asterisk/paths.h"
00037
00038 #include "asterisk/pbx.h"
00039 #include "asterisk/frame.h"
00040 #include "asterisk/mod_format.h"
00041 #include "asterisk/sched.h"
00042 #include "asterisk/channel.h"
00043 #include "asterisk/musiconhold.h"
00044 #include "asterisk/say.h"
00045 #include "asterisk/file.h"
00046 #include "asterisk/cli.h"
00047 #include "asterisk/translate.h"
00048 #include "asterisk/manager.h"
00049 #include "asterisk/cel.h"
00050 #include "asterisk/chanvars.h"
00051 #include "asterisk/linkedlists.h"
00052 #include "asterisk/indications.h"
00053 #include "asterisk/monitor.h"
00054 #include "asterisk/causes.h"
00055 #include "asterisk/callerid.h"
00056 #include "asterisk/utils.h"
00057 #include "asterisk/lock.h"
00058 #include "asterisk/app.h"
00059 #include "asterisk/transcap.h"
00060 #include "asterisk/devicestate.h"
00061 #include "asterisk/threadstorage.h"
00062 #include "asterisk/slinfactory.h"
00063 #include "asterisk/audiohook.h"
00064 #include "asterisk/framehook.h"
00065 #include "asterisk/timing.h"
00066 #include "asterisk/autochan.h"
00067 #include "asterisk/stringfields.h"
00068 #include "asterisk/global_datastores.h"
00069 #include "asterisk/data.h"
00070
00071 #ifdef HAVE_EPOLL
00072 #include <sys/epoll.h>
00073 #endif
00074
00075 #if defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED)
00076 #if defined(HAVE_PRI)
00077 #include "libpri.h"
00078 #endif
00079 #endif
00080
00081 struct ast_epoll_data {
00082 struct ast_channel *chan;
00083 int which;
00084 };
00085
00086
00087 #if 0
00088 #define MONITOR_CONSTANT_DELAY
00089 #define MONITOR_DELAY 150 * 8
00090 #endif
00091
00092
00093 static int shutting_down;
00094
00095 static int uniqueint;
00096
00097 unsigned long global_fin, global_fout;
00098
00099 AST_THREADSTORAGE(state2str_threadbuf);
00100 #define STATE2STR_BUFSIZE 32
00101
00102
00103
00104 #define AST_DEFAULT_EMULATE_DTMF_DURATION 100
00105
00106
00107 #define AST_MIN_DTMF_DURATION 80
00108
00109
00110
00111 #define AST_MIN_DTMF_GAP 45
00112
00113
00114 struct chanlist {
00115 const struct ast_channel_tech *tech;
00116 AST_LIST_ENTRY(chanlist) list;
00117 };
00118
00119 #ifdef CHANNEL_TRACE
00120
00121 struct ast_chan_trace_data {
00122 int enabled;
00123 AST_LIST_HEAD_NOLOCK(, ast_chan_trace) trace;
00124 };
00125
00126
00127 struct ast_chan_trace {
00128 char context[AST_MAX_CONTEXT];
00129 char exten[AST_MAX_EXTENSION];
00130 int priority;
00131 AST_LIST_ENTRY(ast_chan_trace) entry;
00132 };
00133 #endif
00134
00135
00136 static AST_RWLIST_HEAD_STATIC(backends, chanlist);
00137
00138 #ifdef LOW_MEMORY
00139 #define NUM_CHANNEL_BUCKETS 61
00140 #else
00141 #define NUM_CHANNEL_BUCKETS 1567
00142 #endif
00143
00144
00145 static struct ao2_container *channels;
00146
00147
00148
00149
00150
00151 static const struct {
00152 int cause;
00153 const char *name;
00154 const char *desc;
00155 } causes[] = {
00156 { AST_CAUSE_UNALLOCATED, "UNALLOCATED", "Unallocated (unassigned) number" },
00157 { AST_CAUSE_NO_ROUTE_TRANSIT_NET, "NO_ROUTE_TRANSIT_NET", "No route to specified transmit network" },
00158 { AST_CAUSE_NO_ROUTE_DESTINATION, "NO_ROUTE_DESTINATION", "No route to destination" },
00159 { AST_CAUSE_CHANNEL_UNACCEPTABLE, "CHANNEL_UNACCEPTABLE", "Channel unacceptable" },
00160 { AST_CAUSE_CALL_AWARDED_DELIVERED, "CALL_AWARDED_DELIVERED", "Call awarded and being delivered in an established channel" },
00161 { AST_CAUSE_NORMAL_CLEARING, "NORMAL_CLEARING", "Normal Clearing" },
00162 { AST_CAUSE_USER_BUSY, "USER_BUSY", "User busy" },
00163 { AST_CAUSE_NO_USER_RESPONSE, "NO_USER_RESPONSE", "No user responding" },
00164 { AST_CAUSE_NO_ANSWER, "NO_ANSWER", "User alerting, no answer" },
00165 { AST_CAUSE_CALL_REJECTED, "CALL_REJECTED", "Call Rejected" },
00166 { AST_CAUSE_NUMBER_CHANGED, "NUMBER_CHANGED", "Number changed" },
00167 { AST_CAUSE_DESTINATION_OUT_OF_ORDER, "DESTINATION_OUT_OF_ORDER", "Destination out of order" },
00168 { AST_CAUSE_INVALID_NUMBER_FORMAT, "INVALID_NUMBER_FORMAT", "Invalid number format" },
00169 { AST_CAUSE_FACILITY_REJECTED, "FACILITY_REJECTED", "Facility rejected" },
00170 { AST_CAUSE_RESPONSE_TO_STATUS_ENQUIRY, "RESPONSE_TO_STATUS_ENQUIRY", "Response to STATus ENQuiry" },
00171 { AST_CAUSE_NORMAL_UNSPECIFIED, "NORMAL_UNSPECIFIED", "Normal, unspecified" },
00172 { AST_CAUSE_NORMAL_CIRCUIT_CONGESTION, "NORMAL_CIRCUIT_CONGESTION", "Circuit/channel congestion" },
00173 { AST_CAUSE_NETWORK_OUT_OF_ORDER, "NETWORK_OUT_OF_ORDER", "Network out of order" },
00174 { AST_CAUSE_NORMAL_TEMPORARY_FAILURE, "NORMAL_TEMPORARY_FAILURE", "Temporary failure" },
00175 { AST_CAUSE_SWITCH_CONGESTION, "SWITCH_CONGESTION", "Switching equipment congestion" },
00176 { AST_CAUSE_ACCESS_INFO_DISCARDED, "ACCESS_INFO_DISCARDED", "Access information discarded" },
00177 { AST_CAUSE_REQUESTED_CHAN_UNAVAIL, "REQUESTED_CHAN_UNAVAIL", "Requested channel not available" },
00178 { AST_CAUSE_PRE_EMPTED, "PRE_EMPTED", "Pre-empted" },
00179 { AST_CAUSE_FACILITY_NOT_SUBSCRIBED, "FACILITY_NOT_SUBSCRIBED", "Facility not subscribed" },
00180 { AST_CAUSE_OUTGOING_CALL_BARRED, "OUTGOING_CALL_BARRED", "Outgoing call barred" },
00181 { AST_CAUSE_INCOMING_CALL_BARRED, "INCOMING_CALL_BARRED", "Incoming call barred" },
00182 { AST_CAUSE_BEARERCAPABILITY_NOTAUTH, "BEARERCAPABILITY_NOTAUTH", "Bearer capability not authorized" },
00183 { AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, "BEARERCAPABILITY_NOTAVAIL", "Bearer capability not available" },
00184 { AST_CAUSE_BEARERCAPABILITY_NOTIMPL, "BEARERCAPABILITY_NOTIMPL", "Bearer capability not implemented" },
00185 { AST_CAUSE_CHAN_NOT_IMPLEMENTED, "CHAN_NOT_IMPLEMENTED", "Channel not implemented" },
00186 { AST_CAUSE_FACILITY_NOT_IMPLEMENTED, "FACILITY_NOT_IMPLEMENTED", "Facility not implemented" },
00187 { AST_CAUSE_INVALID_CALL_REFERENCE, "INVALID_CALL_REFERENCE", "Invalid call reference value" },
00188 { AST_CAUSE_INCOMPATIBLE_DESTINATION, "INCOMPATIBLE_DESTINATION", "Incompatible destination" },
00189 { AST_CAUSE_INVALID_MSG_UNSPECIFIED, "INVALID_MSG_UNSPECIFIED", "Invalid message unspecified" },
00190 { AST_CAUSE_MANDATORY_IE_MISSING, "MANDATORY_IE_MISSING", "Mandatory information element is missing" },
00191 { AST_CAUSE_MESSAGE_TYPE_NONEXIST, "MESSAGE_TYPE_NONEXIST", "Message type nonexist." },
00192 { AST_CAUSE_WRONG_MESSAGE, "WRONG_MESSAGE", "Wrong message" },
00193 { AST_CAUSE_IE_NONEXIST, "IE_NONEXIST", "Info. element nonexist or not implemented" },
00194 { AST_CAUSE_INVALID_IE_CONTENTS, "INVALID_IE_CONTENTS", "Invalid information element contents" },
00195 { AST_CAUSE_WRONG_CALL_STATE, "WRONG_CALL_STATE", "Message not compatible with call state" },
00196 { AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, "RECOVERY_ON_TIMER_EXPIRE", "Recover on timer expiry" },
00197 { AST_CAUSE_MANDATORY_IE_LENGTH_ERROR, "MANDATORY_IE_LENGTH_ERROR", "Mandatory IE length error" },
00198 { AST_CAUSE_PROTOCOL_ERROR, "PROTOCOL_ERROR", "Protocol error, unspecified" },
00199 { AST_CAUSE_INTERWORKING, "INTERWORKING", "Interworking, unspecified" },
00200 };
00201
00202 struct ast_variable *ast_channeltype_list(void)
00203 {
00204 struct chanlist *cl;
00205 struct ast_variable *var = NULL, *prev = NULL;
00206
00207 AST_RWLIST_RDLOCK(&backends);
00208 AST_RWLIST_TRAVERSE(&backends, cl, list) {
00209 if (prev) {
00210 if ((prev->next = ast_variable_new(cl->tech->type, cl->tech->description, "")))
00211 prev = prev->next;
00212 } else {
00213 var = ast_variable_new(cl->tech->type, cl->tech->description, "");
00214 prev = var;
00215 }
00216 }
00217 AST_RWLIST_UNLOCK(&backends);
00218
00219 return var;
00220 }
00221
00222 #if defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED)
00223 static const char *party_number_ton2str(int ton)
00224 {
00225 #if defined(HAVE_PRI)
00226 switch ((ton >> 4) & 0x07) {
00227 case PRI_TON_INTERNATIONAL:
00228 return "International";
00229 case PRI_TON_NATIONAL:
00230 return "National";
00231 case PRI_TON_NET_SPECIFIC:
00232 return "Network Specific";
00233 case PRI_TON_SUBSCRIBER:
00234 return "Subscriber";
00235 case PRI_TON_ABBREVIATED:
00236 return "Abbreviated";
00237 case PRI_TON_RESERVED:
00238 return "Reserved";
00239 case PRI_TON_UNKNOWN:
00240 default:
00241 break;
00242 }
00243 #endif
00244 return "Unknown";
00245 }
00246 #endif
00247
00248 #if defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED)
00249 static const char *party_number_plan2str(int plan)
00250 {
00251 #if defined(HAVE_PRI)
00252 switch (plan & 0x0F) {
00253 default:
00254 case PRI_NPI_UNKNOWN:
00255 break;
00256 case PRI_NPI_E163_E164:
00257 return "Public (E.163/E.164)";
00258 case PRI_NPI_X121:
00259 return "Data (X.121)";
00260 case PRI_NPI_F69:
00261 return "Telex (F.69)";
00262 case PRI_NPI_NATIONAL:
00263 return "National Standard";
00264 case PRI_NPI_PRIVATE:
00265 return "Private";
00266 case PRI_NPI_RESERVED:
00267 return "Reserved";
00268 }
00269 #endif
00270 return "Unknown";
00271 }
00272 #endif
00273
00274
00275 static char *handle_cli_core_show_channeltypes(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
00276 {
00277 #define FORMAT "%-10.10s %-40.40s %-12.12s %-12.12s %-12.12s\n"
00278 struct chanlist *cl;
00279 int count_chan = 0;
00280
00281 switch (cmd) {
00282 case CLI_INIT:
00283 e->command = "core show channeltypes";
00284 e->usage =
00285 "Usage: core show channeltypes\n"
00286 " Lists available channel types registered in your\n"
00287 " Asterisk server.\n";
00288 return NULL;
00289 case CLI_GENERATE:
00290 return NULL;
00291 }
00292
00293 if (a->argc != 3)
00294 return CLI_SHOWUSAGE;
00295
00296 ast_cli(a->fd, FORMAT, "Type", "Description", "Devicestate", "Indications", "Transfer");
00297 ast_cli(a->fd, FORMAT, "----------", "-----------", "-----------", "-----------", "--------");
00298
00299 AST_RWLIST_RDLOCK(&backends);
00300 AST_RWLIST_TRAVERSE(&backends, cl, list) {
00301 ast_cli(a->fd, FORMAT, cl->tech->type, cl->tech->description,
00302 (cl->tech->devicestate) ? "yes" : "no",
00303 (cl->tech->indicate) ? "yes" : "no",
00304 (cl->tech->transfer) ? "yes" : "no");
00305 count_chan++;
00306 }
00307 AST_RWLIST_UNLOCK(&backends);
00308
00309 ast_cli(a->fd, "----------\n%d channel drivers registered.\n", count_chan);
00310
00311 return CLI_SUCCESS;
00312
00313 #undef FORMAT
00314 }
00315
00316 static char *complete_channeltypes(struct ast_cli_args *a)
00317 {
00318 struct chanlist *cl;
00319 int which = 0;
00320 int wordlen;
00321 char *ret = NULL;
00322
00323 if (a->pos != 3)
00324 return NULL;
00325
00326 wordlen = strlen(a->word);
00327
00328 AST_RWLIST_RDLOCK(&backends);
00329 AST_RWLIST_TRAVERSE(&backends, cl, list) {
00330 if (!strncasecmp(a->word, cl->tech->type, wordlen) && ++which > a->n) {
00331 ret = ast_strdup(cl->tech->type);
00332 break;
00333 }
00334 }
00335 AST_RWLIST_UNLOCK(&backends);
00336
00337 return ret;
00338 }
00339
00340
00341 static char *handle_cli_core_show_channeltype(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
00342 {
00343 struct chanlist *cl = NULL;
00344 char buf[512];
00345
00346 switch (cmd) {
00347 case CLI_INIT:
00348 e->command = "core show channeltype";
00349 e->usage =
00350 "Usage: core show channeltype <name>\n"
00351 " Show details about the specified channel type, <name>.\n";
00352 return NULL;
00353 case CLI_GENERATE:
00354 return complete_channeltypes(a);
00355 }
00356
00357 if (a->argc != 4)
00358 return CLI_SHOWUSAGE;
00359
00360 AST_RWLIST_RDLOCK(&backends);
00361
00362 AST_RWLIST_TRAVERSE(&backends, cl, list) {
00363 if (!strncasecmp(cl->tech->type, a->argv[3], strlen(cl->tech->type)))
00364 break;
00365 }
00366
00367
00368 if (!cl) {
00369 ast_cli(a->fd, "\n%s is not a registered channel driver.\n", a->argv[3]);
00370 AST_RWLIST_UNLOCK(&backends);
00371 return CLI_FAILURE;
00372 }
00373
00374 ast_cli(a->fd,
00375 "-- Info about channel driver: %s --\n"
00376 " Device State: %s\n"
00377 " Indication: %s\n"
00378 " Transfer : %s\n"
00379 " Capabilities: %s\n"
00380 " Digit Begin: %s\n"
00381 " Digit End: %s\n"
00382 " Send HTML : %s\n"
00383 " Image Support: %s\n"
00384 " Text Support: %s\n",
00385 cl->tech->type,
00386 (cl->tech->devicestate) ? "yes" : "no",
00387 (cl->tech->indicate) ? "yes" : "no",
00388 (cl->tech->transfer) ? "yes" : "no",
00389 ast_getformatname_multiple(buf, sizeof(buf), cl->tech->capabilities),
00390 (cl->tech->send_digit_begin) ? "yes" : "no",
00391 (cl->tech->send_digit_end) ? "yes" : "no",
00392 (cl->tech->send_html) ? "yes" : "no",
00393 (cl->tech->send_image) ? "yes" : "no",
00394 (cl->tech->send_text) ? "yes" : "no"
00395
00396 );
00397
00398 AST_RWLIST_UNLOCK(&backends);
00399
00400 return CLI_SUCCESS;
00401 }
00402
00403 static struct ast_cli_entry cli_channel[] = {
00404 AST_CLI_DEFINE(handle_cli_core_show_channeltypes, "List available channel types"),
00405 AST_CLI_DEFINE(handle_cli_core_show_channeltype, "Give more details on that channel type")
00406 };
00407
00408 static struct ast_frame *kill_read(struct ast_channel *chan)
00409 {
00410
00411 return NULL;
00412 }
00413
00414 static struct ast_frame *kill_exception(struct ast_channel *chan)
00415 {
00416
00417 return NULL;
00418 }
00419
00420 static int kill_write(struct ast_channel *chan, struct ast_frame *frame)
00421 {
00422
00423 return -1;
00424 }
00425
00426 static int kill_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
00427 {
00428
00429 return 0;
00430 }
00431
00432 static int kill_hangup(struct ast_channel *chan)
00433 {
00434 chan->tech_pvt = NULL;
00435 return 0;
00436 }
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447 const struct ast_channel_tech ast_kill_tech = {
00448 .type = "Kill",
00449 .description = "Kill channel (should not see this)",
00450 .read = kill_read,
00451 .exception = kill_exception,
00452 .write = kill_write,
00453 .fixup = kill_fixup,
00454 .hangup = kill_hangup,
00455 };
00456
00457 #ifdef CHANNEL_TRACE
00458
00459 static void ast_chan_trace_destroy_cb(void *data)
00460 {
00461 struct ast_chan_trace *trace;
00462 struct ast_chan_trace_data *traced = data;
00463 while ((trace = AST_LIST_REMOVE_HEAD(&traced->trace, entry))) {
00464 ast_free(trace);
00465 }
00466 ast_free(traced);
00467 }
00468
00469
00470 static const struct ast_datastore_info ast_chan_trace_datastore_info = {
00471 .type = "ChanTrace",
00472 .destroy = ast_chan_trace_destroy_cb
00473 };
00474
00475
00476 int ast_channel_trace_serialize(struct ast_channel *chan, struct ast_str **buf)
00477 {
00478 int total = 0;
00479 struct ast_chan_trace *trace;
00480 struct ast_chan_trace_data *traced;
00481 struct ast_datastore *store;
00482
00483 ast_channel_lock(chan);
00484 store = ast_channel_datastore_find(chan, &ast_chan_trace_datastore_info, NULL);
00485 if (!store) {
00486 ast_channel_unlock(chan);
00487 return total;
00488 }
00489 traced = store->data;
00490 ast_str_reset(*buf);
00491 AST_LIST_TRAVERSE(&traced->trace, trace, entry) {
00492 if (ast_str_append(buf, 0, "[%d] => %s, %s, %d\n", total, trace->context, trace->exten, trace->priority) < 0) {
00493 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
00494 total = -1;
00495 break;
00496 }
00497 total++;
00498 }
00499 ast_channel_unlock(chan);
00500 return total;
00501 }
00502
00503
00504 int ast_channel_trace_is_enabled(struct ast_channel *chan)
00505 {
00506 struct ast_datastore *store = ast_channel_datastore_find(chan, &ast_chan_trace_datastore_info, NULL);
00507 if (!store)
00508 return 0;
00509 return ((struct ast_chan_trace_data *)store->data)->enabled;
00510 }
00511
00512
00513 static int ast_channel_trace_data_update(struct ast_channel *chan, struct ast_chan_trace_data *traced)
00514 {
00515 struct ast_chan_trace *trace;
00516 if (!traced->enabled)
00517 return 0;
00518
00519
00520 if ((!AST_LIST_EMPTY(&traced->trace) && strcasecmp(AST_LIST_FIRST(&traced->trace)->context, chan->context)) ||
00521 (AST_LIST_EMPTY(&traced->trace))) {
00522
00523 if (AST_LIST_EMPTY(&traced->trace))
00524 ast_debug(1, "Setting initial trace context to %s\n", chan->context);
00525 else
00526 ast_debug(1, "Changing trace context from %s to %s\n", AST_LIST_FIRST(&traced->trace)->context, chan->context);
00527
00528 trace = ast_malloc(sizeof(*trace));
00529 if (!trace)
00530 return -1;
00531
00532 ast_copy_string(trace->context, chan->context, sizeof(trace->context));
00533 ast_copy_string(trace->exten, chan->exten, sizeof(trace->exten));
00534 trace->priority = chan->priority;
00535 AST_LIST_INSERT_HEAD(&traced->trace, trace, entry);
00536 }
00537 return 0;
00538 }
00539
00540
00541 int ast_channel_trace_update(struct ast_channel *chan)
00542 {
00543 struct ast_datastore *store = ast_channel_datastore_find(chan, &ast_chan_trace_datastore_info, NULL);
00544 if (!store)
00545 return 0;
00546 return ast_channel_trace_data_update(chan, store->data);
00547 }
00548
00549
00550 int ast_channel_trace_enable(struct ast_channel *chan)
00551 {
00552 struct ast_datastore *store = ast_channel_datastore_find(chan, &ast_chan_trace_datastore_info, NULL);
00553 struct ast_chan_trace_data *traced;
00554 if (!store) {
00555 store = ast_datastore_alloc(&ast_chan_trace_datastore_info, "ChanTrace");
00556 if (!store)
00557 return -1;
00558 traced = ast_calloc(1, sizeof(*traced));
00559 if (!traced) {
00560 ast_datastore_free(store);
00561 return -1;
00562 }
00563 store->data = traced;
00564 AST_LIST_HEAD_INIT_NOLOCK(&traced->trace);
00565 ast_channel_datastore_add(chan, store);
00566 }
00567 ((struct ast_chan_trace_data *)store->data)->enabled = 1;
00568 ast_channel_trace_data_update(chan, store->data);
00569 return 0;
00570 }
00571
00572
00573 int ast_channel_trace_disable(struct ast_channel *chan)
00574 {
00575 struct ast_datastore *store = ast_channel_datastore_find(chan, &ast_chan_trace_datastore_info, NULL);
00576 if (!store)
00577 return 0;
00578 ((struct ast_chan_trace_data *)store->data)->enabled = 0;
00579 return 0;
00580 }
00581 #endif
00582
00583
00584 int ast_check_hangup(struct ast_channel *chan)
00585 {
00586 if (chan->_softhangup)
00587 return 1;
00588 if (ast_tvzero(chan->whentohangup))
00589 return 0;
00590 if (ast_tvdiff_ms(chan->whentohangup, ast_tvnow()) > 0)
00591 return 0;
00592 ast_debug(4, "Hangup time has come: %" PRIi64 "\n", ast_tvdiff_ms(chan->whentohangup, ast_tvnow()));
00593 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
00594 return 1;
00595 }
00596
00597 int ast_check_hangup_locked(struct ast_channel *chan)
00598 {
00599 int res;
00600 ast_channel_lock(chan);
00601 res = ast_check_hangup(chan);
00602 ast_channel_unlock(chan);
00603 return res;
00604 }
00605
00606 static int ast_channel_softhangup_cb(void *obj, void *arg, int flags)
00607 {
00608 struct ast_channel *chan = obj;
00609
00610 ast_softhangup(chan, AST_SOFTHANGUP_SHUTDOWN);
00611
00612 return 0;
00613 }
00614
00615 void ast_begin_shutdown(int hangup)
00616 {
00617 shutting_down = 1;
00618
00619 if (hangup) {
00620 ao2_callback(channels, OBJ_NODATA | OBJ_MULTIPLE, ast_channel_softhangup_cb, NULL);
00621 }
00622 }
00623
00624
00625 int ast_active_channels(void)
00626 {
00627 return channels ? ao2_container_count(channels) : 0;
00628 }
00629
00630
00631 void ast_cancel_shutdown(void)
00632 {
00633 shutting_down = 0;
00634 }
00635
00636
00637 int ast_shutting_down(void)
00638 {
00639 return shutting_down;
00640 }
00641
00642
00643 void ast_channel_setwhentohangup_tv(struct ast_channel *chan, struct timeval offset)
00644 {
00645 chan->whentohangup = ast_tvzero(offset) ? offset : ast_tvadd(offset, ast_tvnow());
00646 ast_queue_frame(chan, &ast_null_frame);
00647 return;
00648 }
00649
00650 void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset)
00651 {
00652 struct timeval when = { offset, };
00653 ast_channel_setwhentohangup_tv(chan, when);
00654 }
00655
00656
00657 int ast_channel_cmpwhentohangup_tv(struct ast_channel *chan, struct timeval offset)
00658 {
00659 struct timeval whentohangup;
00660
00661 if (ast_tvzero(chan->whentohangup))
00662 return ast_tvzero(offset) ? 0 : -1;
00663
00664 if (ast_tvzero(offset))
00665 return 1;
00666
00667 whentohangup = ast_tvadd(offset, ast_tvnow());
00668
00669 return ast_tvdiff_ms(whentohangup, chan->whentohangup);
00670 }
00671
00672 int ast_channel_cmpwhentohangup(struct ast_channel *chan, time_t offset)
00673 {
00674 struct timeval when = { offset, };
00675 return ast_channel_cmpwhentohangup_tv(chan, when);
00676 }
00677
00678
00679 int ast_channel_register(const struct ast_channel_tech *tech)
00680 {
00681 struct chanlist *chan;
00682
00683 AST_RWLIST_WRLOCK(&backends);
00684
00685 AST_RWLIST_TRAVERSE(&backends, chan, list) {
00686 if (!strcasecmp(tech->type, chan->tech->type)) {
00687 ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type);
00688 AST_RWLIST_UNLOCK(&backends);
00689 return -1;
00690 }
00691 }
00692
00693 if (!(chan = ast_calloc(1, sizeof(*chan)))) {
00694 AST_RWLIST_UNLOCK(&backends);
00695 return -1;
00696 }
00697 chan->tech = tech;
00698 AST_RWLIST_INSERT_HEAD(&backends, chan, list);
00699
00700 ast_debug(1, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description);
00701
00702 ast_verb(2, "Registered channel type '%s' (%s)\n", chan->tech->type, chan->tech->description);
00703
00704 AST_RWLIST_UNLOCK(&backends);
00705
00706 return 0;
00707 }
00708
00709
00710 void ast_channel_unregister(const struct ast_channel_tech *tech)
00711 {
00712 struct chanlist *chan;
00713
00714 ast_debug(1, "Unregistering channel type '%s'\n", tech->type);
00715
00716 AST_RWLIST_WRLOCK(&backends);
00717
00718 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) {
00719 if (chan->tech == tech) {
00720 AST_LIST_REMOVE_CURRENT(list);
00721 ast_free(chan);
00722 ast_verb(2, "Unregistered channel type '%s'\n", tech->type);
00723 break;
00724 }
00725 }
00726 AST_LIST_TRAVERSE_SAFE_END;
00727
00728 AST_RWLIST_UNLOCK(&backends);
00729 }
00730
00731
00732 const struct ast_channel_tech *ast_get_channel_tech(const char *name)
00733 {
00734 struct chanlist *chanls;
00735 const struct ast_channel_tech *ret = NULL;
00736
00737 AST_RWLIST_RDLOCK(&backends);
00738
00739 AST_RWLIST_TRAVERSE(&backends, chanls, list) {
00740 if (!strcasecmp(name, chanls->tech->type)) {
00741 ret = chanls->tech;
00742 break;
00743 }
00744 }
00745
00746 AST_RWLIST_UNLOCK(&backends);
00747
00748 return ret;
00749 }
00750
00751
00752 const char *ast_cause2str(int cause)
00753 {
00754 int x;
00755
00756 for (x = 0; x < ARRAY_LEN(causes); x++) {
00757 if (causes[x].cause == cause)
00758 return causes[x].desc;
00759 }
00760
00761 return "Unknown";
00762 }
00763
00764
00765 int ast_str2cause(const char *name)
00766 {
00767 int x;
00768
00769 for (x = 0; x < ARRAY_LEN(causes); x++)
00770 if (!strncasecmp(causes[x].name, name, strlen(causes[x].name)))
00771 return causes[x].cause;
00772
00773 return -1;
00774 }
00775
00776
00777
00778
00779 const char *ast_state2str(enum ast_channel_state state)
00780 {
00781 char *buf;
00782
00783 switch (state) {
00784 case AST_STATE_DOWN:
00785 return "Down";
00786 case AST_STATE_RESERVED:
00787 return "Rsrvd";
00788 case AST_STATE_OFFHOOK:
00789 return "OffHook";
00790 case AST_STATE_DIALING:
00791 return "Dialing";
00792 case AST_STATE_RING:
00793 return "Ring";
00794 case AST_STATE_RINGING:
00795 return "Ringing";
00796 case AST_STATE_UP:
00797 return "Up";
00798 case AST_STATE_BUSY:
00799 return "Busy";
00800 case AST_STATE_DIALING_OFFHOOK:
00801 return "Dialing Offhook";
00802 case AST_STATE_PRERING:
00803 return "Pre-ring";
00804 default:
00805 if (!(buf = ast_threadstorage_get(&state2str_threadbuf, STATE2STR_BUFSIZE)))
00806 return "Unknown";
00807 snprintf(buf, STATE2STR_BUFSIZE, "Unknown (%d)", state);
00808 return buf;
00809 }
00810 }
00811
00812
00813 char *ast_transfercapability2str(int transfercapability)
00814 {
00815 switch (transfercapability) {
00816 case AST_TRANS_CAP_SPEECH:
00817 return "SPEECH";
00818 case AST_TRANS_CAP_DIGITAL:
00819 return "DIGITAL";
00820 case AST_TRANS_CAP_RESTRICTED_DIGITAL:
00821 return "RESTRICTED_DIGITAL";
00822 case AST_TRANS_CAP_3_1K_AUDIO:
00823 return "3K1AUDIO";
00824 case AST_TRANS_CAP_DIGITAL_W_TONES:
00825 return "DIGITAL_W_TONES";
00826 case AST_TRANS_CAP_VIDEO:
00827 return "VIDEO";
00828 default:
00829 return "UNKNOWN";
00830 }
00831 }
00832
00833
00834 struct ast_format *ast_best_codec(struct ast_format_cap *cap, struct ast_format *result)
00835 {
00836
00837
00838 static const enum ast_format_id prefs[] =
00839 {
00840
00841 AST_FORMAT_ULAW,
00842
00843 AST_FORMAT_ALAW,
00844 AST_FORMAT_G719,
00845 AST_FORMAT_SIREN14,
00846 AST_FORMAT_SIREN7,
00847 AST_FORMAT_TESTLAW,
00848
00849 AST_FORMAT_G722,
00850
00851 AST_FORMAT_SLINEAR192,
00852 AST_FORMAT_SLINEAR96,
00853 AST_FORMAT_SLINEAR48,
00854 AST_FORMAT_SLINEAR44,
00855 AST_FORMAT_SLINEAR32,
00856 AST_FORMAT_SLINEAR24,
00857 AST_FORMAT_SLINEAR16,
00858 AST_FORMAT_SLINEAR12,
00859 AST_FORMAT_SLINEAR,
00860
00861 AST_FORMAT_G726,
00862
00863 AST_FORMAT_G726_AAL2,
00864
00865 AST_FORMAT_ADPCM,
00866
00867
00868 AST_FORMAT_GSM,
00869
00870 AST_FORMAT_ILBC,
00871
00872 AST_FORMAT_SPEEX32,
00873 AST_FORMAT_SPEEX16,
00874 AST_FORMAT_SPEEX,
00875
00876 AST_FORMAT_SILK,
00877
00878 AST_FORMAT_CELT,
00879
00880
00881 AST_FORMAT_LPC10,
00882
00883 AST_FORMAT_G729A,
00884
00885 AST_FORMAT_G723_1,
00886 };
00887 char buf[512];
00888 int x;
00889
00890
00891 for (x = 0; x < ARRAY_LEN(prefs); x++) {
00892 if (ast_format_cap_best_byid(cap, prefs[x], result)) {
00893 return result;
00894 }
00895 }
00896
00897 ast_format_clear(result);
00898 ast_log(LOG_WARNING, "Don't know any of %s formats\n", ast_getformatname_multiple(buf, sizeof(buf), cap));
00899
00900 return NULL;
00901 }
00902
00903 static const struct ast_channel_tech null_tech = {
00904 .type = "NULL",
00905 .description = "Null channel (should not see this)",
00906 };
00907
00908 static void ast_channel_destructor(void *obj);
00909 static void ast_dummy_channel_destructor(void *obj);
00910
00911
00912 static struct ast_channel * attribute_malloc __attribute__((format(printf, 13, 0)))
00913 __ast_channel_alloc_ap(int needqueue, int state, const char *cid_num, const char *cid_name,
00914 const char *acctcode, const char *exten, const char *context,
00915 const char *linkedid, const int amaflag, const char *file, int line,
00916 const char *function, const char *name_fmt, va_list ap)
00917 {
00918 struct ast_channel *tmp;
00919 int x;
00920 int flags;
00921 struct varshead *headp;
00922 char *tech = "", *tech2 = NULL;
00923
00924
00925 if (shutting_down) {
00926 ast_log(LOG_WARNING, "Channel allocation failed: Refusing due to active shutdown\n");
00927 return NULL;
00928 }
00929
00930 #if defined(REF_DEBUG)
00931 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_channel_destructor, "", file, line,
00932 function, 1);
00933 #elif defined(__AST_DEBUG_MALLOC)
00934 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_channel_destructor, "", file, line,
00935 function, 0);
00936 #else
00937 tmp = ao2_alloc(sizeof(*tmp), ast_channel_destructor);
00938 #endif
00939 if (!tmp) {
00940
00941 return NULL;
00942 }
00943 if (!(tmp->nativeformats = ast_format_cap_alloc())) {
00944 ao2_ref(tmp, -1);
00945
00946 return NULL;
00947 }
00948
00949
00950
00951
00952
00953 tmp->timingfd = -1;
00954 for (x = 0; x < ARRAY_LEN(tmp->alertpipe); ++x) {
00955 tmp->alertpipe[x] = -1;
00956 }
00957 for (x = 0; x < ARRAY_LEN(tmp->fds); ++x) {
00958 tmp->fds[x] = -1;
00959 }
00960 #ifdef HAVE_EPOLL
00961 tmp->epfd = epoll_create(25);
00962 #endif
00963
00964 if (!(tmp->sched = ast_sched_context_create())) {
00965 ast_log(LOG_WARNING, "Channel allocation failed: Unable to create schedule context\n");
00966 return ast_channel_unref(tmp);
00967 }
00968
00969 ast_party_dialed_init(&tmp->dialed);
00970 ast_party_caller_init(&tmp->caller);
00971 ast_party_connected_line_init(&tmp->connected);
00972 ast_party_redirecting_init(&tmp->redirecting);
00973
00974 if (cid_name) {
00975 tmp->caller.id.name.valid = 1;
00976 tmp->caller.id.name.str = ast_strdup(cid_name);
00977 if (!tmp->caller.id.name.str) {
00978 return ast_channel_unref(tmp);
00979 }
00980 }
00981 if (cid_num) {
00982 tmp->caller.id.number.valid = 1;
00983 tmp->caller.id.number.str = ast_strdup(cid_num);
00984 if (!tmp->caller.id.number.str) {
00985 return ast_channel_unref(tmp);
00986 }
00987 }
00988
00989 if ((tmp->timer = ast_timer_open())) {
00990 if (strcmp(ast_timer_get_name(tmp->timer), "timerfd")) {
00991 needqueue = 0;
00992 }
00993 tmp->timingfd = ast_timer_fd(tmp->timer);
00994 }
00995
00996 if (needqueue) {
00997 if (pipe(tmp->alertpipe)) {
00998 ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe! Try increasing max file descriptors with ulimit -n\n");
00999 return ast_channel_unref(tmp);
01000 } else {
01001 flags = fcntl(tmp->alertpipe[0], F_GETFL);
01002 if (fcntl(tmp->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) {
01003 ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
01004 return ast_channel_unref(tmp);
01005 }
01006 flags = fcntl(tmp->alertpipe[1], F_GETFL);
01007 if (fcntl(tmp->alertpipe[1], F_SETFL, flags | O_NONBLOCK) < 0) {
01008 ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
01009 return ast_channel_unref(tmp);
01010 }
01011 }
01012 }
01013
01014
01015
01016
01017
01018
01019
01020
01021 if ((ast_string_field_init(tmp, 128))) {
01022 return ast_channel_unref(tmp);
01023 }
01024
01025
01026 ast_channel_set_fd(tmp, AST_ALERT_FD, tmp->alertpipe[0]);
01027
01028 ast_channel_set_fd(tmp, AST_TIMING_FD, tmp->timingfd);
01029
01030
01031 tmp->_state = state;
01032
01033 tmp->streamid = -1;
01034
01035 tmp->fin = global_fin;
01036 tmp->fout = global_fout;
01037
01038 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) {
01039 ast_channel_uniqueid_build(tmp, "%li.%d", (long) time(NULL),
01040 ast_atomic_fetchadd_int(&uniqueint, 1));
01041 } else {
01042 ast_channel_uniqueid_build(tmp, "%s-%li.%d", ast_config_AST_SYSTEM_NAME,
01043 (long) time(NULL), ast_atomic_fetchadd_int(&uniqueint, 1));
01044 }
01045
01046 if (!ast_strlen_zero(linkedid)) {
01047 ast_channel_linkedid_set(tmp, linkedid);
01048 } else {
01049 ast_channel_linkedid_set(tmp, ast_channel_uniqueid(tmp));
01050 }
01051
01052 if (!ast_strlen_zero(name_fmt)) {
01053 char *slash, *slash2;
01054
01055
01056
01057
01058
01059
01060
01061 ast_channel_name_build_va(tmp, name_fmt, ap);
01062 tech = ast_strdupa(ast_channel_name(tmp));
01063 if ((slash = strchr(tech, '/'))) {
01064 if ((slash2 = strchr(slash + 1, '/'))) {
01065 tech2 = slash + 1;
01066 *slash2 = '\0';
01067 }
01068 *slash = '\0';
01069 }
01070 } else {
01071
01072
01073
01074
01075 ast_channel_name_set(tmp, "-**Unknown**");
01076 }
01077
01078
01079
01080
01081 if (amaflag)
01082 tmp->amaflags = amaflag;
01083 else
01084 tmp->amaflags = ast_default_amaflags;
01085
01086 if (!ast_strlen_zero(acctcode))
01087 ast_channel_accountcode_set(tmp, acctcode);
01088 else
01089 ast_channel_accountcode_set(tmp, ast_default_accountcode);
01090
01091 if (!ast_strlen_zero(context))
01092 ast_copy_string(tmp->context, context, sizeof(tmp->context));
01093 else
01094 strcpy(tmp->context, "default");
01095
01096 if (!ast_strlen_zero(exten))
01097 ast_copy_string(tmp->exten, exten, sizeof(tmp->exten));
01098 else
01099 strcpy(tmp->exten, "s");
01100
01101 tmp->priority = 1;
01102
01103 tmp->cdr = ast_cdr_alloc();
01104 ast_cdr_init(tmp->cdr, tmp);
01105 ast_cdr_start(tmp->cdr);
01106
01107 ast_cel_report_event(tmp, AST_CEL_CHANNEL_START, NULL, NULL, NULL);
01108
01109 headp = &tmp->varshead;
01110 AST_LIST_HEAD_INIT_NOLOCK(headp);
01111
01112 AST_LIST_HEAD_INIT_NOLOCK(&tmp->datastores);
01113
01114 AST_LIST_HEAD_INIT_NOLOCK(&tmp->autochans);
01115
01116 ast_channel_language_set(tmp, defaultlanguage);
01117
01118 tmp->tech = &null_tech;
01119
01120 ao2_link(channels, tmp);
01121
01122
01123
01124
01125
01126
01127
01128 if (ast_get_channel_tech(tech) || (tech2 && ast_get_channel_tech(tech2))) {
01129 ast_manager_event(tmp, EVENT_FLAG_CALL, "Newchannel",
01130 "Channel: %s\r\n"
01131 "ChannelState: %d\r\n"
01132 "ChannelStateDesc: %s\r\n"
01133 "CallerIDNum: %s\r\n"
01134 "CallerIDName: %s\r\n"
01135 "AccountCode: %s\r\n"
01136 "Exten: %s\r\n"
01137 "Context: %s\r\n"
01138 "Uniqueid: %s\r\n",
01139 ast_channel_name(tmp),
01140 state,
01141 ast_state2str(state),
01142 S_OR(cid_num, ""),
01143 S_OR(cid_name, ""),
01144 ast_channel_accountcode(tmp),
01145 S_OR(exten, ""),
01146 S_OR(context, ""),
01147 ast_channel_uniqueid(tmp));
01148 }
01149
01150 return tmp;
01151 }
01152
01153 struct ast_channel *__ast_channel_alloc(int needqueue, int state, const char *cid_num,
01154 const char *cid_name, const char *acctcode,
01155 const char *exten, const char *context,
01156 const char *linkedid, const int amaflag,
01157 const char *file, int line, const char *function,
01158 const char *name_fmt, ...)
01159 {
01160 va_list ap;
01161 struct ast_channel *result;
01162
01163 va_start(ap, name_fmt);
01164 result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context,
01165 linkedid, amaflag, file, line, function, name_fmt, ap);
01166 va_end(ap);
01167
01168 return result;
01169 }
01170
01171
01172
01173 #if defined(REF_DEBUG) || defined(__AST_DEBUG_MALLOC)
01174 struct ast_channel *__ast_dummy_channel_alloc(const char *file, int line, const char *function)
01175 #else
01176 struct ast_channel *ast_dummy_channel_alloc(void)
01177 #endif
01178 {
01179 struct ast_channel *tmp;
01180 struct varshead *headp;
01181
01182 #if defined(REF_DEBUG)
01183 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel",
01184 file, line, function, 1);
01185 #elif defined(__AST_DEBUG_MALLOC)
01186 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel",
01187 file, line, function, 0);
01188 #else
01189 tmp = ao2_alloc(sizeof(*tmp), ast_dummy_channel_destructor);
01190 #endif
01191 if (!tmp) {
01192
01193 return NULL;
01194 }
01195
01196 if ((ast_string_field_init(tmp, 128))) {
01197 return ast_channel_unref(tmp);
01198 }
01199
01200 headp = &tmp->varshead;
01201 AST_LIST_HEAD_INIT_NOLOCK(headp);
01202
01203 return tmp;
01204 }
01205
01206 static int __ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin, int head, struct ast_frame *after)
01207 {
01208 struct ast_frame *f;
01209 struct ast_frame *cur;
01210 unsigned int new_frames = 0;
01211 unsigned int new_voice_frames = 0;
01212 unsigned int queued_frames = 0;
01213 unsigned int queued_voice_frames = 0;
01214 AST_LIST_HEAD_NOLOCK(, ast_frame) frames;
01215
01216 ast_channel_lock(chan);
01217
01218
01219
01220
01221
01222 cur = AST_LIST_LAST(&chan->readq);
01223 if (cur && cur->frametype == AST_FRAME_CONTROL && !head && (!after || after == cur)) {
01224 switch (cur->subclass.integer) {
01225 case AST_CONTROL_END_OF_Q:
01226 if (fin->frametype == AST_FRAME_CONTROL
01227 && fin->subclass.integer == AST_CONTROL_HANGUP) {
01228
01229
01230
01231
01232 AST_LIST_REMOVE(&chan->readq, cur, frame_list);
01233 ast_frfree(cur);
01234
01235
01236
01237
01238
01239
01240 after = NULL;
01241 break;
01242 }
01243
01244 case AST_CONTROL_HANGUP:
01245
01246 ast_channel_unlock(chan);
01247 return 0;
01248 default:
01249 break;
01250 }
01251 }
01252
01253
01254 AST_LIST_HEAD_INIT_NOLOCK(&frames);
01255 for (cur = fin; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
01256 if (!(f = ast_frdup(cur))) {
01257 if (AST_LIST_FIRST(&frames)) {
01258 ast_frfree(AST_LIST_FIRST(&frames));
01259 }
01260 ast_channel_unlock(chan);
01261 return -1;
01262 }
01263
01264 AST_LIST_INSERT_TAIL(&frames, f, frame_list);
01265 new_frames++;
01266 if (f->frametype == AST_FRAME_VOICE) {
01267 new_voice_frames++;
01268 }
01269 }
01270
01271
01272 AST_LIST_TRAVERSE(&chan->readq, cur, frame_list) {
01273 queued_frames++;
01274 if (cur->frametype == AST_FRAME_VOICE) {
01275 queued_voice_frames++;
01276 }
01277 }
01278
01279 if ((queued_frames + new_frames > 128 || queued_voice_frames + new_voice_frames > 96)) {
01280 int count = 0;
01281 ast_log(LOG_WARNING, "Exceptionally long %squeue length queuing to %s\n", queued_frames + new_frames > 128 ? "" : "voice ", ast_channel_name(chan));
01282 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->readq, cur, frame_list) {
01283
01284 if (!AST_LIST_NEXT(cur, frame_list)) {
01285 break;
01286 } else if (cur->frametype == AST_FRAME_VOICE || cur->frametype == AST_FRAME_VIDEO || cur->frametype == AST_FRAME_NULL) {
01287 if (++count > 64) {
01288 break;
01289 }
01290 AST_LIST_REMOVE_CURRENT(frame_list);
01291 ast_frfree(cur);
01292 }
01293 }
01294 AST_LIST_TRAVERSE_SAFE_END;
01295 }
01296
01297 if (after) {
01298 AST_LIST_INSERT_LIST_AFTER(&chan->readq, &frames, after, frame_list);
01299 } else {
01300 if (head) {
01301 AST_LIST_APPEND_LIST(&frames, &chan->readq, frame_list);
01302 AST_LIST_HEAD_INIT_NOLOCK(&chan->readq);
01303 }
01304 AST_LIST_APPEND_LIST(&chan->readq, &frames, frame_list);
01305 }
01306
01307 if (chan->alertpipe[1] > -1) {
01308 int blah[new_frames];
01309
01310 memset(blah, 1, sizeof(blah));
01311 if (write(chan->alertpipe[1], &blah, sizeof(blah)) != (sizeof(blah))) {
01312 ast_log(LOG_WARNING, "Unable to write to alert pipe on %s (qlen = %d): %s!\n",
01313 ast_channel_name(chan), queued_frames, strerror(errno));
01314 }
01315 } else if (chan->timingfd > -1) {
01316 ast_timer_enable_continuous(chan->timer);
01317 } else if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
01318 pthread_kill(chan->blocker, SIGURG);
01319 }
01320
01321 ast_channel_unlock(chan);
01322
01323 return 0;
01324 }
01325
01326 int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin)
01327 {
01328 return __ast_queue_frame(chan, fin, 0, NULL);
01329 }
01330
01331 int ast_queue_frame_head(struct ast_channel *chan, struct ast_frame *fin)
01332 {
01333 return __ast_queue_frame(chan, fin, 1, NULL);
01334 }
01335
01336
01337 int ast_queue_hangup(struct ast_channel *chan)
01338 {
01339 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP };
01340
01341 if (!ast_channel_trylock(chan)) {
01342 chan->_softhangup |= AST_SOFTHANGUP_DEV;
01343 manager_event(EVENT_FLAG_CALL, "HangupRequest",
01344 "Channel: %s\r\n"
01345 "Uniqueid: %s\r\n",
01346 ast_channel_name(chan),
01347 ast_channel_uniqueid(chan));
01348 ast_channel_unlock(chan);
01349 }
01350 return ast_queue_frame(chan, &f);
01351 }
01352
01353
01354 int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
01355 {
01356 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP };
01357
01358 if (cause >= 0)
01359 f.data.uint32 = cause;
01360
01361
01362 if (!ast_channel_trylock(chan)) {
01363 chan->_softhangup |= AST_SOFTHANGUP_DEV;
01364 if (cause < 0)
01365 f.data.uint32 = chan->hangupcause;
01366
01367 manager_event(EVENT_FLAG_CALL, "HangupRequest",
01368 "Channel: %s\r\n"
01369 "Uniqueid: %s\r\n"
01370 "Cause: %d\r\n",
01371 ast_channel_name(chan),
01372 ast_channel_uniqueid(chan),
01373 cause);
01374 ast_channel_unlock(chan);
01375 }
01376
01377 return ast_queue_frame(chan, &f);
01378 }
01379
01380
01381 int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
01382 {
01383 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control };
01384 return ast_queue_frame(chan, &f);
01385 }
01386
01387
01388 int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control,
01389 const void *data, size_t datalen)
01390 {
01391 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control, .data.ptr = (void *) data, .datalen = datalen };
01392 return ast_queue_frame(chan, &f);
01393 }
01394
01395
01396 int ast_channel_defer_dtmf(struct ast_channel *chan)
01397 {
01398 int pre = 0;
01399
01400 if (chan) {
01401 pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF);
01402 ast_set_flag(chan, AST_FLAG_DEFER_DTMF);
01403 }
01404 return pre;
01405 }
01406
01407
01408 void ast_channel_undefer_dtmf(struct ast_channel *chan)
01409 {
01410 if (chan)
01411 ast_clear_flag(chan, AST_FLAG_DEFER_DTMF);
01412 }
01413
01414 struct ast_channel *ast_channel_callback(ao2_callback_data_fn *cb_fn, void *arg,
01415 void *data, int ao2_flags)
01416 {
01417 return ao2_callback_data(channels, ao2_flags, cb_fn, arg, data);
01418 }
01419
01420 static int ast_channel_by_name_cb(void *obj, void *arg, void *data, int flags)
01421 {
01422 struct ast_channel *chan = obj;
01423 const char *name = arg;
01424 size_t name_len = *(size_t *) data;
01425 int ret = CMP_MATCH;
01426
01427 if (ast_strlen_zero(name)) {
01428 ast_log(LOG_ERROR, "BUG! Must supply a channel name or partial name to match!\n");
01429 return CMP_STOP;
01430 }
01431
01432 ast_channel_lock(chan);
01433 if ((!name_len && strcasecmp(ast_channel_name(chan), name))
01434 || (name_len && strncasecmp(ast_channel_name(chan), name, name_len))) {
01435 ret = 0;
01436 }
01437 ast_channel_unlock(chan);
01438
01439 return ret;
01440 }
01441
01442 static int ast_channel_by_exten_cb(void *obj, void *arg, void *data, int flags)
01443 {
01444 struct ast_channel *chan = obj;
01445 char *context = arg;
01446 char *exten = data;
01447 int ret = CMP_MATCH;
01448
01449 if (ast_strlen_zero(exten) || ast_strlen_zero(context)) {
01450 ast_log(LOG_ERROR, "BUG! Must have a context and extension to match!\n");
01451 return CMP_STOP;
01452 }
01453
01454 ast_channel_lock(chan);
01455 if (strcasecmp(chan->context, context) && strcasecmp(chan->macrocontext, context)) {
01456 ret = 0;
01457 } else if (strcasecmp(chan->exten, exten) && strcasecmp(chan->macroexten, exten)) {
01458 ret = 0;
01459 }
01460 ast_channel_unlock(chan);
01461
01462 return ret;
01463 }
01464
01465 static int ast_channel_by_uniqueid_cb(void *obj, void *arg, void *data, int flags)
01466 {
01467 struct ast_channel *chan = obj;
01468 char *uniqueid = arg;
01469 size_t id_len = *(size_t *) data;
01470 int ret = CMP_MATCH;
01471
01472 if (ast_strlen_zero(uniqueid)) {
01473 ast_log(LOG_ERROR, "BUG! Must supply a uniqueid or partial uniqueid to match!\n");
01474 return CMP_STOP;
01475 }
01476
01477 ast_channel_lock(chan);
01478 if ((!id_len && strcasecmp(ast_channel_uniqueid(chan), uniqueid))
01479 || (id_len && strncasecmp(ast_channel_uniqueid(chan), uniqueid, id_len))) {
01480 ret = 0;
01481 }
01482 ast_channel_unlock(chan);
01483
01484 return ret;
01485 }
01486
01487 struct ast_channel_iterator {
01488
01489 struct ao2_iterator simple_iterator;
01490
01491
01492
01493 struct ao2_iterator *active_iterator;
01494 };
01495
01496 struct ast_channel_iterator *ast_channel_iterator_destroy(struct ast_channel_iterator *i)
01497 {
01498 ao2_iterator_destroy(i->active_iterator);
01499 ast_free(i);
01500
01501 return NULL;
01502 }
01503
01504 struct ast_channel_iterator *ast_channel_iterator_by_exten_new(const char *exten, const char *context)
01505 {
01506 struct ast_channel_iterator *i;
01507 char *l_exten = (char *) exten;
01508 char *l_context = (char *) context;
01509
01510 if (!(i = ast_calloc(1, sizeof(*i)))) {
01511 return NULL;
01512 }
01513
01514 i->active_iterator = (void *) ast_channel_callback(ast_channel_by_exten_cb,
01515 l_context, l_exten, OBJ_MULTIPLE);
01516 if (!i->active_iterator) {
01517 ast_free(i);
01518 return NULL;
01519 }
01520
01521 return i;
01522 }
01523
01524 struct ast_channel_iterator *ast_channel_iterator_by_name_new(const char *name, size_t name_len)
01525 {
01526 struct ast_channel_iterator *i;
01527 char *l_name = (char *) name;
01528
01529 if (!(i = ast_calloc(1, sizeof(*i)))) {
01530 return NULL;
01531 }
01532
01533 i->active_iterator = (void *) ast_channel_callback(ast_channel_by_name_cb,
01534 l_name, &name_len,
01535 OBJ_MULTIPLE | (name_len == 0 ? OBJ_KEY : 0));
01536 if (!i->active_iterator) {
01537 ast_free(i);
01538 return NULL;
01539 }
01540
01541 return i;
01542 }
01543
01544 struct ast_channel_iterator *ast_channel_iterator_all_new(void)
01545 {
01546 struct ast_channel_iterator *i;
01547
01548 if (!(i = ast_calloc(1, sizeof(*i)))) {
01549 return NULL;
01550 }
01551
01552 i->simple_iterator = ao2_iterator_init(channels, 0);
01553 i->active_iterator = &i->simple_iterator;
01554
01555 return i;
01556 }
01557
01558 struct ast_channel *ast_channel_iterator_next(struct ast_channel_iterator *i)
01559 {
01560 return ao2_iterator_next(i->active_iterator);
01561 }
01562
01563
01564 static int ast_channel_cmp_cb(void *obj, void *arg, int flags)
01565 {
01566 ast_log(LOG_ERROR, "BUG! Should never be called!\n");
01567 return CMP_STOP;
01568 }
01569
01570 struct ast_channel *ast_channel_get_by_name_prefix(const char *name, size_t name_len)
01571 {
01572 struct ast_channel *chan;
01573 char *l_name = (char *) name;
01574
01575 chan = ast_channel_callback(ast_channel_by_name_cb, l_name, &name_len,
01576 (name_len == 0) ? OBJ_KEY : 0);
01577 if (chan) {
01578 return chan;
01579 }
01580
01581 if (ast_strlen_zero(l_name)) {
01582
01583 return NULL;
01584 }
01585
01586
01587 return ast_channel_callback(ast_channel_by_uniqueid_cb, l_name, &name_len, 0);
01588 }
01589
01590 struct ast_channel *ast_channel_get_by_name(const char *name)
01591 {
01592 return ast_channel_get_by_name_prefix(name, 0);
01593 }
01594
01595 struct ast_channel *ast_channel_get_by_exten(const char *exten, const char *context)
01596 {
01597 char *l_exten = (char *) exten;
01598 char *l_context = (char *) context;
01599
01600 return ast_channel_callback(ast_channel_by_exten_cb, l_context, l_exten, 0);
01601 }
01602
01603 int ast_is_deferrable_frame(const struct ast_frame *frame)
01604 {
01605
01606
01607
01608
01609 switch (frame->frametype) {
01610 case AST_FRAME_CONTROL:
01611 case AST_FRAME_TEXT:
01612 case AST_FRAME_IMAGE:
01613 case AST_FRAME_HTML:
01614 return 1;
01615
01616 case AST_FRAME_DTMF_END:
01617 case AST_FRAME_DTMF_BEGIN:
01618 case AST_FRAME_VOICE:
01619 case AST_FRAME_VIDEO:
01620 case AST_FRAME_NULL:
01621 case AST_FRAME_IAX:
01622 case AST_FRAME_CNG:
01623 case AST_FRAME_MODEM:
01624 return 0;
01625 }
01626 return 0;
01627 }
01628
01629
01630 int ast_safe_sleep_conditional(struct ast_channel *chan, int ms, int (*cond)(void*), void *data)
01631 {
01632 struct ast_frame *f;
01633 struct ast_silence_generator *silgen = NULL;
01634 int res = 0;
01635 AST_LIST_HEAD_NOLOCK(, ast_frame) deferred_frames;
01636
01637 AST_LIST_HEAD_INIT_NOLOCK(&deferred_frames);
01638
01639
01640 if (ast_opt_transmit_silence && !chan->generatordata) {
01641 silgen = ast_channel_start_silence_generator(chan);
01642 }
01643
01644 while (ms > 0) {
01645 struct ast_frame *dup_f = NULL;
01646 if (cond && ((*cond)(data) == 0)) {
01647 break;
01648 }
01649 ms = ast_waitfor(chan, ms);
01650 if (ms < 0) {
01651 res = -1;
01652 break;
01653 }
01654 if (ms > 0) {
01655 f = ast_read(chan);
01656 if (!f) {
01657 res = -1;
01658 break;
01659 }
01660
01661 if (!ast_is_deferrable_frame(f)) {
01662 ast_frfree(f);
01663 continue;
01664 }
01665
01666 if ((dup_f = ast_frisolate(f))) {
01667 if (dup_f != f) {
01668 ast_frfree(f);
01669 }
01670 AST_LIST_INSERT_HEAD(&deferred_frames, dup_f, frame_list);
01671 }
01672 }
01673 }
01674
01675
01676 if (silgen) {
01677 ast_channel_stop_silence_generator(chan, silgen);
01678 }
01679
01680
01681
01682
01683
01684 ast_channel_lock(chan);
01685 while ((f = AST_LIST_REMOVE_HEAD(&deferred_frames, frame_list))) {
01686 if (!res) {
01687 ast_queue_frame_head(chan, f);
01688 }
01689 ast_frfree(f);
01690 }
01691 ast_channel_unlock(chan);
01692
01693 return res;
01694 }
01695
01696
01697 int ast_safe_sleep(struct ast_channel *chan, int ms)
01698 {
01699 return ast_safe_sleep_conditional(chan, ms, NULL, NULL);
01700 }
01701
01702 struct ast_channel *ast_channel_release(struct ast_channel *chan)
01703 {
01704
01705 ao2_unlink(channels, chan);
01706 return ast_channel_unref(chan);
01707 }
01708
01709 void ast_party_name_init(struct ast_party_name *init)
01710 {
01711 init->str = NULL;
01712 init->char_set = AST_PARTY_CHAR_SET_ISO8859_1;
01713 init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
01714 init->valid = 0;
01715 }
01716
01717 void ast_party_name_copy(struct ast_party_name *dest, const struct ast_party_name *src)
01718 {
01719 if (dest == src) {
01720
01721 return;
01722 }
01723
01724 ast_free(dest->str);
01725 dest->str = ast_strdup(src->str);
01726 dest->char_set = src->char_set;
01727 dest->presentation = src->presentation;
01728 dest->valid = src->valid;
01729 }
01730
01731 void ast_party_name_set_init(struct ast_party_name *init, const struct ast_party_name *guide)
01732 {
01733 init->str = NULL;
01734 init->char_set = guide->char_set;
01735 init->presentation = guide->presentation;
01736 init->valid = guide->valid;
01737 }
01738
01739 void ast_party_name_set(struct ast_party_name *dest, const struct ast_party_name *src)
01740 {
01741 if (dest == src) {
01742
01743 return;
01744 }
01745
01746 if (src->str && src->str != dest->str) {
01747 ast_free(dest->str);
01748 dest->str = ast_strdup(src->str);
01749 }
01750
01751 dest->char_set = src->char_set;
01752 dest->presentation = src->presentation;
01753 dest->valid = src->valid;
01754 }
01755
01756 void ast_party_name_free(struct ast_party_name *doomed)
01757 {
01758 ast_free(doomed->str);
01759 doomed->str = NULL;
01760 }
01761
01762 void ast_party_number_init(struct ast_party_number *init)
01763 {
01764 init->str = NULL;
01765 init->plan = 0;
01766 init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
01767 init->valid = 0;
01768 }
01769
01770 void ast_party_number_copy(struct ast_party_number *dest, const struct ast_party_number *src)
01771 {
01772 if (dest == src) {
01773
01774 return;
01775 }
01776
01777 ast_free(dest->str);
01778 dest->str = ast_strdup(src->str);
01779 dest->plan = src->plan;
01780 dest->presentation = src->presentation;
01781 dest->valid = src->valid;
01782 }
01783
01784 void ast_party_number_set_init(struct ast_party_number *init, const struct ast_party_number *guide)
01785 {
01786 init->str = NULL;
01787 init->plan = guide->plan;
01788 init->presentation = guide->presentation;
01789 init->valid = guide->valid;
01790 }
01791
01792 void ast_party_number_set(struct ast_party_number *dest, const struct ast_party_number *src)
01793 {
01794 if (dest == src) {
01795
01796 return;
01797 }
01798
01799 if (src->str && src->str != dest->str) {
01800 ast_free(dest->str);
01801 dest->str = ast_strdup(src->str);
01802 }
01803
01804 dest->plan = src->plan;
01805 dest->presentation = src->presentation;
01806 dest->valid = src->valid;
01807 }
01808
01809 void ast_party_number_free(struct ast_party_number *doomed)
01810 {
01811 ast_free(doomed->str);
01812 doomed->str = NULL;
01813 }
01814
01815 void ast_party_subaddress_init(struct ast_party_subaddress *init)
01816 {
01817 init->str = NULL;
01818 init->type = 0;
01819 init->odd_even_indicator = 0;
01820 init->valid = 0;
01821 }
01822
01823 void ast_party_subaddress_copy(struct ast_party_subaddress *dest, const struct ast_party_subaddress *src)
01824 {
01825 if (dest == src) {
01826
01827 return;
01828 }
01829
01830 ast_free(dest->str);
01831 dest->str = ast_strdup(src->str);
01832 dest->type = src->type;
01833 dest->odd_even_indicator = src->odd_even_indicator;
01834 dest->valid = src->valid;
01835 }
01836
01837 void ast_party_subaddress_set_init(struct ast_party_subaddress *init, const struct ast_party_subaddress *guide)
01838 {
01839 init->str = NULL;
01840 init->type = guide->type;
01841 init->odd_even_indicator = guide->odd_even_indicator;
01842 init->valid = guide->valid;
01843 }
01844
01845 void ast_party_subaddress_set(struct ast_party_subaddress *dest, const struct ast_party_subaddress *src)
01846 {
01847 if (dest == src) {
01848
01849 return;
01850 }
01851
01852 if (src->str && src->str != dest->str) {
01853 ast_free(dest->str);
01854 dest->str = ast_strdup(src->str);
01855 }
01856
01857 dest->type = src->type;
01858 dest->odd_even_indicator = src->odd_even_indicator;
01859 dest->valid = src->valid;
01860 }
01861
01862 void ast_party_subaddress_free(struct ast_party_subaddress *doomed)
01863 {
01864 ast_free(doomed->str);
01865 doomed->str = NULL;
01866 }
01867
01868 void ast_party_id_init(struct ast_party_id *init)
01869 {
01870 ast_party_name_init(&init->name);
01871 ast_party_number_init(&init->number);
01872 ast_party_subaddress_init(&init->subaddress);
01873 init->tag = NULL;
01874 }
01875
01876 void ast_party_id_copy(struct ast_party_id *dest, const struct ast_party_id *src)
01877 {
01878 if (dest == src) {
01879
01880 return;
01881 }
01882
01883 ast_party_name_copy(&dest->name, &src->name);
01884 ast_party_number_copy(&dest->number, &src->number);
01885 ast_party_subaddress_copy(&dest->subaddress, &src->subaddress);
01886
01887 ast_free(dest->tag);
01888 dest->tag = ast_strdup(src->tag);
01889 }
01890
01891 void ast_party_id_set_init(struct ast_party_id *init, const struct ast_party_id *guide)
01892 {
01893 ast_party_name_set_init(&init->name, &guide->name);
01894 ast_party_number_set_init(&init->number, &guide->number);
01895 ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress);
01896 init->tag = NULL;
01897 }
01898
01899 void ast_party_id_set(struct ast_party_id *dest, const struct ast_party_id *src, const struct ast_set_party_id *update)
01900 {
01901 if (dest == src) {
01902
01903 return;
01904 }
01905
01906 if (!update || update->name) {
01907 ast_party_name_set(&dest->name, &src->name);
01908 }
01909 if (!update || update->number) {
01910 ast_party_number_set(&dest->number, &src->number);
01911 }
01912 if (!update || update->subaddress) {
01913 ast_party_subaddress_set(&dest->subaddress, &src->subaddress);
01914 }
01915
01916 if (src->tag && src->tag != dest->tag) {
01917 ast_free(dest->tag);
01918 dest->tag = ast_strdup(src->tag);
01919 }
01920 }
01921
01922 void ast_party_id_free(struct ast_party_id *doomed)
01923 {
01924 ast_party_name_free(&doomed->name);
01925 ast_party_number_free(&doomed->number);
01926 ast_party_subaddress_free(&doomed->subaddress);
01927
01928 ast_free(doomed->tag);
01929 doomed->tag = NULL;
01930 }
01931
01932 int ast_party_id_presentation(const struct ast_party_id *id)
01933 {
01934 int number_priority;
01935 int number_value;
01936 int number_screening;
01937 int name_priority;
01938 int name_value;
01939
01940
01941 if (!id->name.valid) {
01942 name_value = AST_PRES_UNAVAILABLE;
01943 name_priority = 3;
01944 } else {
01945 name_value = id->name.presentation & AST_PRES_RESTRICTION;
01946 switch (name_value) {
01947 case AST_PRES_RESTRICTED:
01948 name_priority = 0;
01949 break;
01950 case AST_PRES_ALLOWED:
01951 name_priority = 1;
01952 break;
01953 case AST_PRES_UNAVAILABLE:
01954 name_priority = 2;
01955 break;
01956 default:
01957 name_value = AST_PRES_UNAVAILABLE;
01958 name_priority = 3;
01959 break;
01960 }
01961 }
01962
01963
01964 if (!id->number.valid) {
01965 number_screening = AST_PRES_USER_NUMBER_UNSCREENED;
01966 number_value = AST_PRES_UNAVAILABLE;
01967 number_priority = 3;
01968 } else {
01969 number_screening = id->number.presentation & AST_PRES_NUMBER_TYPE;
01970 number_value = id->number.presentation & AST_PRES_RESTRICTION;
01971 switch (number_value) {
01972 case AST_PRES_RESTRICTED:
01973 number_priority = 0;
01974 break;
01975 case AST_PRES_ALLOWED:
01976 number_priority = 1;
01977 break;
01978 case AST_PRES_UNAVAILABLE:
01979 number_priority = 2;
01980 break;
01981 default:
01982 number_screening = AST_PRES_USER_NUMBER_UNSCREENED;
01983 number_value = AST_PRES_UNAVAILABLE;
01984 number_priority = 3;
01985 break;
01986 }
01987 }
01988
01989
01990 if (name_priority < number_priority) {
01991 number_value = name_value;
01992 }
01993
01994 return number_value | number_screening;
01995 }
01996
01997 void ast_party_dialed_init(struct ast_party_dialed *init)
01998 {
01999 init->number.str = NULL;
02000 init->number.plan = 0;
02001 ast_party_subaddress_init(&init->subaddress);
02002 init->transit_network_select = 0;
02003 }
02004
02005 void ast_party_dialed_copy(struct ast_party_dialed *dest, const struct ast_party_dialed *src)
02006 {
02007 if (dest == src) {
02008
02009 return;
02010 }
02011
02012 ast_free(dest->number.str);
02013 dest->number.str = ast_strdup(src->number.str);
02014 dest->number.plan = src->number.plan;
02015 ast_party_subaddress_copy(&dest->subaddress, &src->subaddress);
02016 dest->transit_network_select = src->transit_network_select;
02017 }
02018
02019 void ast_party_dialed_set_init(struct ast_party_dialed *init, const struct ast_party_dialed *guide)
02020 {
02021 init->number.str = NULL;
02022 init->number.plan = guide->number.plan;
02023 ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress);
02024 init->transit_network_select = guide->transit_network_select;
02025 }
02026
02027 void ast_party_dialed_set(struct ast_party_dialed *dest, const struct ast_party_dialed *src)
02028 {
02029 if (src->number.str && src->number.str != dest->number.str) {
02030 ast_free(dest->number.str);
02031 dest->number.str = ast_strdup(src->number.str);
02032 }
02033 dest->number.plan = src->number.plan;
02034
02035 ast_party_subaddress_set(&dest->subaddress, &src->subaddress);
02036
02037 dest->transit_network_select = src->transit_network_select;
02038 }
02039
02040 void ast_party_dialed_free(struct ast_party_dialed *doomed)
02041 {
02042 ast_free(doomed->number.str);
02043 doomed->number.str = NULL;
02044 ast_party_subaddress_free(&doomed->subaddress);
02045 }
02046
02047 void ast_party_caller_init(struct ast_party_caller *init)
02048 {
02049 ast_party_id_init(&init->id);
02050 ast_party_id_init(&init->ani);
02051 init->ani2 = 0;
02052 }
02053
02054 void ast_party_caller_copy(struct ast_party_caller *dest, const struct ast_party_caller *src)
02055 {
02056 if (dest == src) {
02057
02058 return;
02059 }
02060
02061 ast_party_id_copy(&dest->id, &src->id);
02062 ast_party_id_copy(&dest->ani, &src->ani);
02063 dest->ani2 = src->ani2;
02064 }
02065
02066 void ast_party_caller_set_init(struct ast_party_caller *init, const struct ast_party_caller *guide)
02067 {
02068 ast_party_id_set_init(&init->id, &guide->id);
02069 ast_party_id_set_init(&init->ani, &guide->ani);
02070 init->ani2 = guide->ani2;
02071 }
02072
02073 void ast_party_caller_set(struct ast_party_caller *dest, const struct ast_party_caller *src, const struct ast_set_party_caller *update)
02074 {
02075 ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL);
02076 ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL);
02077 dest->ani2 = src->ani2;
02078 }
02079
02080 void ast_party_caller_free(struct ast_party_caller *doomed)
02081 {
02082 ast_party_id_free(&doomed->id);
02083 ast_party_id_free(&doomed->ani);
02084 }
02085
02086 void ast_party_connected_line_init(struct ast_party_connected_line *init)
02087 {
02088 ast_party_id_init(&init->id);
02089 ast_party_id_init(&init->ani);
02090 init->ani2 = 0;
02091 init->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN;
02092 }
02093
02094 void ast_party_connected_line_copy(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src)
02095 {
02096 if (dest == src) {
02097
02098 return;
02099 }
02100
02101 ast_party_id_copy(&dest->id, &src->id);
02102 ast_party_id_copy(&dest->ani, &src->ani);
02103 dest->ani2 = src->ani2;
02104 dest->source = src->source;
02105 }
02106
02107 void ast_party_connected_line_set_init(struct ast_party_connected_line *init, const struct ast_party_connected_line *guide)
02108 {
02109 ast_party_id_set_init(&init->id, &guide->id);
02110 ast_party_id_set_init(&init->ani, &guide->ani);
02111 init->ani2 = guide->ani2;
02112 init->source = guide->source;
02113 }
02114
02115 void ast_party_connected_line_set(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src, const struct ast_set_party_connected_line *update)
02116 {
02117 ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL);
02118 ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL);
02119 dest->ani2 = src->ani2;
02120 dest->source = src->source;
02121 }
02122
02123 void ast_party_connected_line_collect_caller(struct ast_party_connected_line *connected, struct ast_party_caller *caller)
02124 {
02125 connected->id = caller->id;
02126 connected->ani = caller->ani;
02127 connected->ani2 = caller->ani2;
02128 connected->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN;
02129 }
02130
02131 void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
02132 {
02133 ast_party_id_free(&doomed->id);
02134 ast_party_id_free(&doomed->ani);
02135 }
02136
02137 void ast_party_redirecting_init(struct ast_party_redirecting *init)
02138 {
02139 ast_party_id_init(&init->from);
02140 ast_party_id_init(&init->to);
02141 init->count = 0;
02142 init->reason = AST_REDIRECTING_REASON_UNKNOWN;
02143 }
02144
02145 void ast_party_redirecting_copy(struct ast_party_redirecting *dest, const struct ast_party_redirecting *src)
02146 {
02147 if (dest == src) {
02148
02149 return;
02150 }
02151
02152 ast_party_id_copy(&dest->from, &src->from);
02153 ast_party_id_copy(&dest->to, &src->to);
02154 dest->count = src->count;
02155 dest->reason = src->reason;
02156 }
02157
02158 void ast_party_redirecting_set_init(struct ast_party_redirecting *init, const struct ast_party_redirecting *guide)
02159 {
02160 ast_party_id_set_init(&init->from, &guide->from);
02161 ast_party_id_set_init(&init->to, &guide->to);
02162 init->count = guide->count;
02163 init->reason = guide->reason;
02164 }
02165
02166 void ast_party_redirecting_set(struct ast_party_redirecting *dest, const struct ast_party_redirecting *src, const struct ast_set_party_redirecting *update)
02167 {
02168 ast_party_id_set(&dest->from, &src->from, update ? &update->from : NULL);
02169 ast_party_id_set(&dest->to, &src->to, update ? &update->to : NULL);
02170 dest->reason = src->reason;
02171 dest->count = src->count;
02172 }
02173
02174 void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
02175 {
02176 ast_party_id_free(&doomed->from);
02177 ast_party_id_free(&doomed->to);
02178 }
02179
02180
02181 static void ast_channel_destructor(void *obj)
02182 {
02183 struct ast_channel *chan = obj;
02184 int fd;
02185 #ifdef HAVE_EPOLL
02186 int i;
02187 #endif
02188 struct ast_var_t *vardata;
02189 struct ast_frame *f;
02190 struct varshead *headp;
02191 struct ast_datastore *datastore;
02192 char device_name[AST_CHANNEL_NAME];
02193
02194 if (ast_channel_name(chan)) {
02195
02196 ast_cel_report_event(chan, AST_CEL_CHANNEL_END, NULL, NULL, NULL);
02197 ast_cel_check_retire_linkedid(chan);
02198 }
02199
02200
02201 ast_channel_lock(chan);
02202 while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry)))
02203
02204 ast_datastore_free(datastore);
02205 ast_channel_unlock(chan);
02206
02207
02208
02209 ast_channel_lock(chan);
02210 ast_channel_unlock(chan);
02211
02212 if (chan->tech_pvt) {
02213 ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", ast_channel_name(chan));
02214 ast_free(chan->tech_pvt);
02215 }
02216
02217 if (chan->sched) {
02218 ast_sched_context_destroy(chan->sched);
02219 }
02220
02221 if (ast_channel_name(chan)) {
02222 char *dashptr;
02223
02224
02225 ast_copy_string(device_name, ast_channel_name(chan), sizeof(device_name));
02226 if ((dashptr = strrchr(device_name, '-'))) {
02227 *dashptr = '\0';
02228 }
02229 } else {
02230 device_name[0] = '\0';
02231 }
02232
02233
02234 if (chan->monitor)
02235 chan->monitor->stop( chan, 0 );
02236
02237
02238 if (chan->music_state)
02239 ast_moh_cleanup(chan);
02240
02241
02242 if (chan->readtrans)
02243 ast_translator_free_path(chan->readtrans);
02244 if (chan->writetrans)
02245 ast_translator_free_path(chan->writetrans);
02246 if (chan->pbx)
02247 ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", ast_channel_name(chan));
02248
02249 ast_party_dialed_free(&chan->dialed);
02250 ast_party_caller_free(&chan->caller);
02251 ast_party_connected_line_free(&chan->connected);
02252 ast_party_redirecting_free(&chan->redirecting);
02253
02254
02255 if ((fd = chan->alertpipe[0]) > -1)
02256 close(fd);
02257 if ((fd = chan->alertpipe[1]) > -1)
02258 close(fd);
02259 if (chan->timer) {
02260 ast_timer_close(chan->timer);
02261 }
02262 #ifdef HAVE_EPOLL
02263 for (i = 0; i < AST_MAX_FDS; i++) {
02264 if (chan->epfd_data[i])
02265 free(chan->epfd_data[i]);
02266 }
02267 close(chan->epfd);
02268 #endif
02269 while ((f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list)))
02270 ast_frfree(f);
02271
02272
02273
02274 headp = &chan->varshead;
02275 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
02276 ast_var_delete(vardata);
02277
02278 ast_app_group_discard(chan);
02279
02280
02281 ast_jb_destroy(chan);
02282
02283 if (chan->cdr) {
02284 ast_cdr_discard(chan->cdr);
02285 chan->cdr = NULL;
02286 }
02287
02288 if (chan->zone) {
02289 chan->zone = ast_tone_zone_unref(chan->zone);
02290 }
02291
02292 ast_string_field_free_memory(chan);
02293
02294 if (device_name[0]) {
02295
02296
02297
02298
02299
02300
02301
02302 ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, device_name);
02303 }
02304
02305 chan->nativeformats = ast_format_cap_destroy(chan->nativeformats);
02306 }
02307
02308
02309 static void ast_dummy_channel_destructor(void *obj)
02310 {
02311 struct ast_channel *chan = obj;
02312 struct ast_var_t *vardata;
02313 struct varshead *headp;
02314
02315 headp = &chan->varshead;
02316
02317 ast_party_dialed_free(&chan->dialed);
02318 ast_party_caller_free(&chan->caller);
02319 ast_party_connected_line_free(&chan->connected);
02320 ast_party_redirecting_free(&chan->redirecting);
02321
02322
02323
02324 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
02325 ast_var_delete(vardata);
02326
02327 if (chan->cdr) {
02328 ast_cdr_discard(chan->cdr);
02329 chan->cdr = NULL;
02330 }
02331
02332 ast_string_field_free_memory(chan);
02333 }
02334
02335 struct ast_datastore *ast_channel_datastore_alloc(const struct ast_datastore_info *info, const char *uid)
02336 {
02337 return ast_datastore_alloc(info, uid);
02338 }
02339
02340 int ast_channel_datastore_free(struct ast_datastore *datastore)
02341 {
02342 return ast_datastore_free(datastore);
02343 }
02344
02345 int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel *to)
02346 {
02347 struct ast_datastore *datastore = NULL, *datastore2;
02348
02349 AST_LIST_TRAVERSE(&from->datastores, datastore, entry) {
02350 if (datastore->inheritance > 0) {
02351 datastore2 = ast_datastore_alloc(datastore->info, datastore->uid);
02352 if (datastore2) {
02353 datastore2->data = datastore->info->duplicate ? datastore->info->duplicate(datastore->data) : NULL;
02354 datastore2->inheritance = datastore->inheritance == DATASTORE_INHERIT_FOREVER ? DATASTORE_INHERIT_FOREVER : datastore->inheritance - 1;
02355 AST_LIST_INSERT_TAIL(&to->datastores, datastore2, entry);
02356 }
02357 }
02358 }
02359 return 0;
02360 }
02361
02362 int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
02363 {
02364 int res = 0;
02365
02366 AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry);
02367
02368 return res;
02369 }
02370
02371 int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
02372 {
02373 return AST_LIST_REMOVE(&chan->datastores, datastore, entry) ? 0 : -1;
02374 }
02375
02376 struct ast_datastore *ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
02377 {
02378 struct ast_datastore *datastore = NULL;
02379
02380 if (info == NULL)
02381 return NULL;
02382
02383 AST_LIST_TRAVERSE(&chan->datastores, datastore, entry) {
02384 if (datastore->info != info) {
02385 continue;
02386 }
02387
02388 if (uid == NULL) {
02389
02390 break;
02391 }
02392
02393 if ((datastore->uid != NULL) && !strcasecmp(uid, datastore->uid)) {
02394
02395 break;
02396 }
02397 }
02398
02399 return datastore;
02400 }
02401
02402
02403 void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
02404 {
02405 #ifdef HAVE_EPOLL
02406 struct epoll_event ev;
02407 struct ast_epoll_data *aed = NULL;
02408
02409 if (chan->fds[which] > -1) {
02410 epoll_ctl(chan->epfd, EPOLL_CTL_DEL, chan->fds[which], &ev);
02411 aed = chan->epfd_data[which];
02412 }
02413
02414
02415 if (fd > -1) {
02416 if (!aed && (!(aed = ast_calloc(1, sizeof(*aed)))))
02417 return;
02418
02419 chan->epfd_data[which] = aed;
02420 aed->chan = chan;
02421 aed->which = which;
02422
02423 ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP;
02424 ev.data.ptr = aed;
02425 epoll_ctl(chan->epfd, EPOLL_CTL_ADD, fd, &ev);
02426 } else if (aed) {
02427
02428 free(aed);
02429 chan->epfd_data[which] = NULL;
02430 }
02431 #endif
02432 chan->fds[which] = fd;
02433 return;
02434 }
02435
02436
02437 void ast_poll_channel_add(struct ast_channel *chan0, struct ast_channel *chan1)
02438 {
02439 #ifdef HAVE_EPOLL
02440 struct epoll_event ev;
02441 int i = 0;
02442
02443 if (chan0->epfd == -1)
02444 return;
02445
02446
02447 for (i = 0; i < AST_MAX_FDS; i++) {
02448 if (chan1->fds[i] == -1)
02449 continue;
02450 ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP;
02451 ev.data.ptr = chan1->epfd_data[i];
02452 epoll_ctl(chan0->epfd, EPOLL_CTL_ADD, chan1->fds[i], &ev);
02453 }
02454
02455 #endif
02456 return;
02457 }
02458
02459
02460 void ast_poll_channel_del(struct ast_channel *chan0, struct ast_channel *chan1)
02461 {
02462 #ifdef HAVE_EPOLL
02463 struct epoll_event ev;
02464 int i = 0;
02465
02466 if (chan0->epfd == -1)
02467 return;
02468
02469 for (i = 0; i < AST_MAX_FDS; i++) {
02470 if (chan1->fds[i] == -1)
02471 continue;
02472 epoll_ctl(chan0->epfd, EPOLL_CTL_DEL, chan1->fds[i], &ev);
02473 }
02474
02475 #endif
02476 return;
02477 }
02478
02479 void ast_channel_clear_softhangup(struct ast_channel *chan, int flag)
02480 {
02481 ast_channel_lock(chan);
02482
02483 chan->_softhangup &= ~flag;
02484
02485 if (!chan->_softhangup) {
02486 struct ast_frame *fr;
02487
02488
02489
02490
02491
02492
02493 fr = AST_LIST_LAST(&chan->readq);
02494 if (fr && fr->frametype == AST_FRAME_CONTROL &&
02495 fr->subclass.integer == AST_CONTROL_END_OF_Q) {
02496 AST_LIST_REMOVE(&chan->readq, fr, frame_list);
02497 ast_frfree(fr);
02498 }
02499 }
02500
02501 ast_channel_unlock(chan);
02502 }
02503
02504
02505 int ast_softhangup_nolock(struct ast_channel *chan, int cause)
02506 {
02507 ast_debug(1, "Soft-Hanging up channel '%s'\n", ast_channel_name(chan));
02508
02509 chan->_softhangup |= cause;
02510 ast_queue_frame(chan, &ast_null_frame);
02511
02512 if (ast_test_flag(chan, AST_FLAG_BLOCKING))
02513 pthread_kill(chan->blocker, SIGURG);
02514 return 0;
02515 }
02516
02517
02518 int ast_softhangup(struct ast_channel *chan, int cause)
02519 {
02520 int res;
02521
02522 ast_channel_lock(chan);
02523 res = ast_softhangup_nolock(chan, cause);
02524 manager_event(EVENT_FLAG_CALL, "SoftHangupRequest",
02525 "Channel: %s\r\n"
02526 "Uniqueid: %s\r\n"
02527 "Cause: %d\r\n",
02528 ast_channel_name(chan),
02529 ast_channel_uniqueid(chan),
02530 cause);
02531 ast_channel_unlock(chan);
02532
02533 return res;
02534 }
02535
02536 static void free_translation(struct ast_channel *clonechan)
02537 {
02538 if (clonechan->writetrans)
02539 ast_translator_free_path(clonechan->writetrans);
02540 if (clonechan->readtrans)
02541 ast_translator_free_path(clonechan->readtrans);
02542 clonechan->writetrans = NULL;
02543 clonechan->readtrans = NULL;
02544 if (ast_format_cap_is_empty(clonechan->nativeformats)) {
02545 ast_format_clear(&clonechan->rawwriteformat);
02546 ast_format_clear(&clonechan->rawreadformat);
02547 } else {
02548 struct ast_format tmpfmt;
02549 ast_best_codec(clonechan->nativeformats, &tmpfmt);
02550 ast_format_copy(&clonechan->rawwriteformat, &tmpfmt);
02551 ast_format_copy(&clonechan->rawreadformat, &tmpfmt);
02552 }
02553 }
02554
02555 void ast_set_hangupsource(struct ast_channel *chan, const char *source, int force)
02556 {
02557 struct ast_channel *bridge;
02558
02559 ast_channel_lock(chan);
02560 if (force || ast_strlen_zero(ast_channel_hangupsource(chan))) {
02561 ast_channel_hangupsource_set(chan, source);
02562 }
02563 bridge = ast_bridged_channel(chan);
02564 ast_channel_unlock(chan);
02565
02566 if (bridge && (force || ast_strlen_zero(ast_channel_hangupsource(bridge)))) {
02567 ast_channel_lock(bridge);
02568 ast_channel_hangupsource_set(chan, source);
02569 ast_channel_unlock(bridge);
02570 }
02571 }
02572
02573 static void destroy_hooks(struct ast_channel *chan)
02574 {
02575 if (chan->audiohooks) {
02576 ast_audiohook_detach_list(chan->audiohooks);
02577 chan->audiohooks = NULL;
02578 }
02579
02580 ast_framehook_list_destroy(chan);
02581 }
02582
02583
02584 int ast_hangup(struct ast_channel *chan)
02585 {
02586 char extra_str[64];
02587 int was_zombie;
02588
02589 ast_autoservice_stop(chan);
02590
02591 ast_channel_lock(chan);
02592
02593
02594
02595
02596
02597
02598
02599
02600
02601 while (chan->masq) {
02602 ast_channel_unlock(chan);
02603 if (ast_do_masquerade(chan)) {
02604 ast_log(LOG_WARNING, "Failed to perform masquerade\n");
02605
02606
02607 ast_channel_lock(chan);
02608 break;
02609 }
02610 ast_channel_lock(chan);
02611 }
02612
02613 if (chan->masqr) {
02614
02615
02616
02617
02618
02619 ast_set_flag(chan, AST_FLAG_ZOMBIE);
02620 destroy_hooks(chan);
02621 ast_channel_unlock(chan);
02622 return 0;
02623 }
02624
02625 if (!(was_zombie = ast_test_flag(chan, AST_FLAG_ZOMBIE))) {
02626 ast_set_flag(chan, AST_FLAG_ZOMBIE);
02627 }
02628
02629 ast_channel_unlock(chan);
02630 ao2_unlink(channels, chan);
02631 ast_channel_lock(chan);
02632
02633 destroy_hooks(chan);
02634
02635 free_translation(chan);
02636
02637 if (chan->stream) {
02638 ast_closestream(chan->stream);
02639 chan->stream = NULL;
02640 }
02641
02642 if (chan->vstream) {
02643 ast_closestream(chan->vstream);
02644 chan->vstream = NULL;
02645 }
02646 if (chan->sched) {
02647 ast_sched_context_destroy(chan->sched);
02648 chan->sched = NULL;
02649 }
02650
02651 if (chan->generatordata) {
02652 if (chan->generator && chan->generator->release) {
02653 chan->generator->release(chan, chan->generatordata);
02654 }
02655 }
02656 chan->generatordata = NULL;
02657 chan->generator = NULL;
02658
02659 snprintf(extra_str, sizeof(extra_str), "%d,%s,%s", chan->hangupcause, ast_channel_hangupsource(chan), S_OR(pbx_builtin_getvar_helper(chan, "DIALSTATUS"), ""));
02660 ast_cel_report_event(chan, AST_CEL_HANGUP, NULL, extra_str, NULL);
02661
02662 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
02663 ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
02664 "is blocked by thread %ld in procedure %s! Expect a failure\n",
02665 (long) pthread_self(), ast_channel_name(chan), (long)chan->blocker, chan->blockproc);
02666 ast_assert(ast_test_flag(chan, AST_FLAG_BLOCKING) == 0);
02667 }
02668 if (!was_zombie) {
02669 ast_debug(1, "Hanging up channel '%s'\n", ast_channel_name(chan));
02670
02671 if (chan->tech->hangup) {
02672 chan->tech->hangup(chan);
02673 }
02674 } else {
02675 ast_debug(1, "Hanging up zombie '%s'\n", ast_channel_name(chan));
02676 }
02677
02678 ast_channel_unlock(chan);
02679
02680 ast_cc_offer(chan);
02681 ast_manager_event(chan, EVENT_FLAG_CALL, "Hangup",
02682 "Channel: %s\r\n"
02683 "Uniqueid: %s\r\n"
02684 "CallerIDNum: %s\r\n"
02685 "CallerIDName: %s\r\n"
02686 "ConnectedLineNum: %s\r\n"
02687 "ConnectedLineName: %s\r\n"
02688 "Cause: %d\r\n"
02689 "Cause-txt: %s\r\n",
02690 ast_channel_name(chan),
02691 ast_channel_uniqueid(chan),
02692 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "<unknown>"),
02693 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, "<unknown>"),
02694 S_COR(chan->connected.id.number.valid, chan->connected.id.number.str, "<unknown>"),
02695 S_COR(chan->connected.id.name.valid, chan->connected.id.name.str, "<unknown>"),
02696 chan->hangupcause,
02697 ast_cause2str(chan->hangupcause)
02698 );
02699
02700 if (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_BRIDGED) &&
02701 !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED) &&
02702 (chan->cdr->disposition != AST_CDR_NULL || ast_test_flag(chan->cdr, AST_CDR_FLAG_DIALED))) {
02703 ast_channel_lock(chan);
02704 ast_cdr_end(chan->cdr);
02705 ast_cdr_detach(chan->cdr);
02706 chan->cdr = NULL;
02707 ast_channel_unlock(chan);
02708 }
02709
02710 ast_channel_unref(chan);
02711
02712 return 0;
02713 }
02714
02715 int ast_raw_answer(struct ast_channel *chan, int cdr_answer)
02716 {
02717 int res = 0;
02718
02719 ast_channel_lock(chan);
02720
02721
02722 if (ast_test_flag(chan, AST_FLAG_OUTGOING)) {
02723 ast_channel_unlock(chan);
02724 return 0;
02725 }
02726
02727
02728 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
02729 ast_channel_unlock(chan);
02730 return -1;
02731 }
02732
02733 ast_channel_unlock(chan);
02734
02735 switch (chan->_state) {
02736 case AST_STATE_RINGING:
02737 case AST_STATE_RING:
02738 ast_channel_lock(chan);
02739 if (chan->tech->answer) {
02740 res = chan->tech->answer(chan);
02741 }
02742 ast_setstate(chan, AST_STATE_UP);
02743 if (cdr_answer) {
02744 ast_cdr_answer(chan->cdr);
02745 }
02746 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL);
02747 ast_channel_unlock(chan);
02748 break;
02749 case AST_STATE_UP:
02750 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL);
02751
02752
02753
02754 if (cdr_answer) {
02755 ast_cdr_answer(chan->cdr);
02756 }
02757 break;
02758 default:
02759 break;
02760 }
02761
02762 ast_indicate(chan, -1);
02763
02764 return res;
02765 }
02766
02767 int __ast_answer(struct ast_channel *chan, unsigned int delay, int cdr_answer)
02768 {
02769 int res = 0;
02770 enum ast_channel_state old_state;
02771
02772 old_state = chan->_state;
02773 if ((res = ast_raw_answer(chan, cdr_answer))) {
02774 return res;
02775 }
02776
02777 switch (old_state) {
02778 case AST_STATE_RINGING:
02779 case AST_STATE_RING:
02780
02781
02782
02783 do {
02784 AST_LIST_HEAD_NOLOCK(, ast_frame) frames;
02785 struct ast_frame *cur, *new;
02786 int ms = MAX(delay, 500);
02787 unsigned int done = 0;
02788
02789 AST_LIST_HEAD_INIT_NOLOCK(&frames);
02790
02791 for (;;) {
02792 ms = ast_waitfor(chan, ms);
02793 if (ms < 0) {
02794 ast_log(LOG_WARNING, "Error condition occurred when polling channel %s for a voice frame: %s\n", ast_channel_name(chan), strerror(errno));
02795 res = -1;
02796 break;
02797 }
02798 if (ms == 0) {
02799 ast_debug(2, "Didn't receive a media frame from %s within %d ms of answering. Continuing anyway\n", ast_channel_name(chan), MAX(delay, 500));
02800 break;
02801 }
02802 cur = ast_read(chan);
02803 if (!cur || ((cur->frametype == AST_FRAME_CONTROL) &&
02804 (cur->subclass.integer == AST_CONTROL_HANGUP))) {
02805 if (cur) {
02806 ast_frfree(cur);
02807 }
02808 res = -1;
02809 ast_debug(2, "Hangup of channel %s detected in answer routine\n", ast_channel_name(chan));
02810 break;
02811 }
02812
02813 if ((new = ast_frisolate(cur)) != cur) {
02814 ast_frfree(cur);
02815 }
02816
02817 AST_LIST_INSERT_HEAD(&frames, new, frame_list);
02818
02819
02820
02821
02822
02823 if (delay) {
02824 continue;
02825 }
02826
02827 switch (new->frametype) {
02828
02829 case AST_FRAME_VOICE:
02830 case AST_FRAME_VIDEO:
02831 case AST_FRAME_TEXT:
02832 case AST_FRAME_DTMF_BEGIN:
02833 case AST_FRAME_DTMF_END:
02834 case AST_FRAME_IMAGE:
02835 case AST_FRAME_HTML:
02836 case AST_FRAME_MODEM:
02837 done = 1;
02838 break;
02839 case AST_FRAME_CONTROL:
02840 case AST_FRAME_IAX:
02841 case AST_FRAME_NULL:
02842 case AST_FRAME_CNG:
02843 break;
02844 }
02845
02846 if (done) {
02847 break;
02848 }
02849 }
02850
02851 if (res == 0) {
02852 ast_channel_lock(chan);
02853 while ((cur = AST_LIST_REMOVE_HEAD(&frames, frame_list))) {
02854 ast_queue_frame_head(chan, cur);
02855 ast_frfree(cur);
02856 }
02857 ast_channel_unlock(chan);
02858 }
02859 } while (0);
02860 break;
02861 default:
02862 break;
02863 }
02864
02865 return res;
02866 }
02867
02868 int ast_answer(struct ast_channel *chan)
02869 {
02870 return __ast_answer(chan, 0, 1);
02871 }
02872
02873 void ast_deactivate_generator(struct ast_channel *chan)
02874 {
02875 ast_channel_lock(chan);
02876 if (chan->generatordata) {
02877 if (chan->generator && chan->generator->release)
02878 chan->generator->release(chan, chan->generatordata);
02879 chan->generatordata = NULL;
02880 chan->generator = NULL;
02881 ast_channel_set_fd(chan, AST_GENERATOR_FD, -1);
02882 ast_clear_flag(chan, AST_FLAG_WRITE_INT);
02883 ast_settimeout(chan, 0, NULL, NULL);
02884 }
02885 ast_channel_unlock(chan);
02886 }
02887
02888 static void generator_write_format_change(struct ast_channel *chan)
02889 {
02890 ast_channel_lock(chan);
02891 if (chan->generator && chan->generator->write_format_change) {
02892 chan->generator->write_format_change(chan, chan->generatordata);
02893 }
02894 ast_channel_unlock(chan);
02895 }
02896
02897 static int generator_force(const void *data)
02898 {
02899
02900 void *tmp;
02901 int res;
02902 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = NULL;
02903 struct ast_channel *chan = (struct ast_channel *)data;
02904
02905 ast_channel_lock(chan);
02906 tmp = chan->generatordata;
02907 chan->generatordata = NULL;
02908 if (chan->generator)
02909 generate = chan->generator->generate;
02910 ast_channel_unlock(chan);
02911
02912 if (!tmp || !generate)
02913 return 0;
02914
02915 res = generate(chan, tmp, 0, ast_format_rate(&chan->writeformat) / 50);
02916
02917 chan->generatordata = tmp;
02918
02919 if (res) {
02920 ast_debug(1, "Auto-deactivating generator\n");
02921 ast_deactivate_generator(chan);
02922 }
02923
02924 return 0;
02925 }
02926
02927 int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, void *params)
02928 {
02929 int res = 0;
02930
02931 ast_channel_lock(chan);
02932 if (chan->generatordata) {
02933 if (chan->generator && chan->generator->release)
02934 chan->generator->release(chan, chan->generatordata);
02935 chan->generatordata = NULL;
02936 }
02937 if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) {
02938 res = -1;
02939 }
02940 if (!res) {
02941 ast_settimeout(chan, 50, generator_force, chan);
02942 chan->generator = gen;
02943 }
02944 ast_channel_unlock(chan);
02945
02946 ast_prod(chan);
02947
02948 return res;
02949 }
02950
02951
02952 int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception)
02953 {
02954 int winner = -1;
02955 ast_waitfor_nandfds(NULL, 0, fds, n, exception, &winner, ms);
02956 return winner;
02957 }
02958
02959
02960 #ifdef HAVE_EPOLL
02961 static struct ast_channel *ast_waitfor_nandfds_classic(struct ast_channel **c, int n, int *fds, int nfds,
02962 int *exception, int *outfd, int *ms)
02963 #else
02964 struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds, int nfds,
02965 int *exception, int *outfd, int *ms)
02966 #endif
02967 {
02968 struct timeval start = { 0 , 0 };
02969 struct pollfd *pfds = NULL;
02970 int res;
02971 long rms;
02972 int x, y, max;
02973 int sz;
02974 struct timeval now = { 0, 0 };
02975 struct timeval whentohangup = { 0, 0 }, diff;
02976 struct ast_channel *winner = NULL;
02977 struct fdmap {
02978 int chan;
02979 int fdno;
02980 } *fdmap = NULL;
02981
02982 if ((sz = n * AST_MAX_FDS + nfds)) {
02983 pfds = alloca(sizeof(*pfds) * sz);
02984 fdmap = alloca(sizeof(*fdmap) * sz);
02985 }
02986
02987 if (outfd)
02988 *outfd = -99999;
02989 if (exception)
02990 *exception = 0;
02991
02992
02993 for (x = 0; x < n; x++) {
02994 if (c[x]->masq && ast_do_masquerade(c[x])) {
02995 ast_log(LOG_WARNING, "Masquerade failed\n");
02996 *ms = -1;
02997 return NULL;
02998 }
02999
03000 ast_channel_lock(c[x]);
03001 if (!ast_tvzero(c[x]->whentohangup)) {
03002 if (ast_tvzero(whentohangup))
03003 now = ast_tvnow();
03004 diff = ast_tvsub(c[x]->whentohangup, now);
03005 if (diff.tv_sec < 0 || ast_tvzero(diff)) {
03006
03007 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03008 ast_channel_unlock(c[x]);
03009 return c[x];
03010 }
03011 if (ast_tvzero(whentohangup) || ast_tvcmp(diff, whentohangup) < 0)
03012 whentohangup = diff;
03013 }
03014 ast_channel_unlock(c[x]);
03015 }
03016
03017 rms = *ms;
03018
03019 if (!ast_tvzero(whentohangup) && whentohangup.tv_sec < INT_MAX / 1000) {
03020 rms = whentohangup.tv_sec * 1000 + whentohangup.tv_usec / 1000;
03021 if (*ms >= 0 && *ms < rms) {
03022 rms = *ms;
03023 }
03024 } else if (!ast_tvzero(whentohangup) && rms < 0) {
03025
03026 rms = INT_MAX;
03027 }
03028
03029
03030
03031
03032
03033 max = 0;
03034 for (x = 0; x < n; x++) {
03035 for (y = 0; y < AST_MAX_FDS; y++) {
03036 fdmap[max].fdno = y;
03037 fdmap[max].chan = x;
03038 max += ast_add_fd(&pfds[max], c[x]->fds[y]);
03039 }
03040 CHECK_BLOCKING(c[x]);
03041 }
03042
03043 for (x = 0; x < nfds; x++) {
03044 fdmap[max].chan = -1;
03045 max += ast_add_fd(&pfds[max], fds[x]);
03046 }
03047
03048 if (*ms > 0)
03049 start = ast_tvnow();
03050
03051 if (sizeof(int) == 4) {
03052 do {
03053 int kbrms = rms;
03054 if (kbrms > 600000)
03055 kbrms = 600000;
03056 res = ast_poll(pfds, max, kbrms);
03057 if (!res)
03058 rms -= kbrms;
03059 } while (!res && (rms > 0));
03060 } else {
03061 res = ast_poll(pfds, max, rms);
03062 }
03063 for (x = 0; x < n; x++)
03064 ast_clear_flag(c[x], AST_FLAG_BLOCKING);
03065 if (res < 0) {
03066 if (errno != EINTR)
03067 *ms = -1;
03068 return NULL;
03069 }
03070 if (!ast_tvzero(whentohangup)) {
03071 now = ast_tvnow();
03072 for (x = 0; x < n; x++) {
03073 if (!ast_tvzero(c[x]->whentohangup) && ast_tvcmp(c[x]->whentohangup, now) <= 0) {
03074 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03075 if (winner == NULL)
03076 winner = c[x];
03077 }
03078 }
03079 }
03080 if (res == 0) {
03081 *ms = 0;
03082 return winner;
03083 }
03084
03085
03086
03087
03088
03089 for (x = 0; x < max; x++) {
03090 res = pfds[x].revents;
03091 if (res == 0)
03092 continue;
03093 if (fdmap[x].chan >= 0) {
03094 winner = c[fdmap[x].chan];
03095 if (res & POLLPRI)
03096 ast_set_flag(winner, AST_FLAG_EXCEPTION);
03097 else
03098 ast_clear_flag(winner, AST_FLAG_EXCEPTION);
03099 winner->fdno = fdmap[x].fdno;
03100 } else {
03101 if (outfd)
03102 *outfd = pfds[x].fd;
03103 if (exception)
03104 *exception = (res & POLLPRI) ? -1 : 0;
03105 winner = NULL;
03106 }
03107 }
03108 if (*ms > 0) {
03109 *ms -= ast_tvdiff_ms(ast_tvnow(), start);
03110 if (*ms < 0)
03111 *ms = 0;
03112 }
03113 return winner;
03114 }
03115
03116 #ifdef HAVE_EPOLL
03117 static struct ast_channel *ast_waitfor_nandfds_simple(struct ast_channel *chan, int *ms)
03118 {
03119 struct timeval start = { 0 , 0 };
03120 int res = 0;
03121 struct epoll_event ev[1];
03122 long diff, rms = *ms;
03123 struct ast_channel *winner = NULL;
03124 struct ast_epoll_data *aed = NULL;
03125
03126
03127
03128 if (chan->masq && ast_do_masquerade(chan)) {
03129 ast_log(LOG_WARNING, "Failed to perform masquerade on %s\n", ast_channel_name(chan));
03130 *ms = -1;
03131 return NULL;
03132 }
03133
03134 ast_channel_lock(chan);
03135
03136 if (!ast_tvzero(chan->whentohangup)) {
03137 if ((diff = ast_tvdiff_ms(chan->whentohangup, ast_tvnow())) < 0) {
03138
03139 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03140 ast_channel_unlock(chan);
03141 return NULL;
03142 }
03143
03144 if (rms > diff)
03145 rms = diff;
03146 }
03147
03148 ast_channel_unlock(chan);
03149
03150
03151 CHECK_BLOCKING(chan);
03152
03153 if (*ms > 0)
03154 start = ast_tvnow();
03155
03156
03157 res = epoll_wait(chan->epfd, ev, 1, rms);
03158
03159
03160 ast_clear_flag(chan, AST_FLAG_BLOCKING);
03161
03162
03163 if (res < 0) {
03164 if (errno != EINTR)
03165 *ms = -1;
03166 return NULL;
03167 }
03168
03169
03170 if (!ast_tvzero(chan->whentohangup)) {
03171 if (ast_tvdiff_ms(ast_tvnow(), chan->whentohangup) >= 0) {
03172 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03173 winner = chan;
03174 }
03175 }
03176
03177
03178 if (!res) {
03179 *ms = 0;
03180 return winner;
03181 }
03182
03183
03184 aed = ev[0].data.ptr;
03185 chan->fdno = aed->which;
03186 if (ev[0].events & EPOLLPRI)
03187 ast_set_flag(chan, AST_FLAG_EXCEPTION);
03188 else
03189 ast_clear_flag(chan, AST_FLAG_EXCEPTION);
03190
03191 if (*ms > 0) {
03192 *ms -= ast_tvdiff_ms(ast_tvnow(), start);
03193 if (*ms < 0)
03194 *ms = 0;
03195 }
03196
03197 return chan;
03198 }
03199
03200 static struct ast_channel *ast_waitfor_nandfds_complex(struct ast_channel **c, int n, int *ms)
03201 {
03202 struct timeval start = { 0 , 0 };
03203 int res = 0, i;
03204 struct epoll_event ev[25] = { { 0, } };
03205 struct timeval now = { 0, 0 };
03206 long whentohangup = 0, diff = 0, rms = *ms;
03207 struct ast_channel *winner = NULL;
03208
03209 for (i = 0; i < n; i++) {
03210 if (c[i]->masq && ast_do_masquerade(c[i])) {
03211 ast_log(LOG_WARNING, "Masquerade failed\n");
03212 *ms = -1;
03213 return NULL;
03214 }
03215
03216 ast_channel_lock(c[i]);
03217 if (!ast_tvzero(c[i]->whentohangup)) {
03218 if (whentohangup == 0)
03219 now = ast_tvnow();
03220 if ((diff = ast_tvdiff_ms(c[i]->whentohangup, now)) < 0) {
03221 c[i]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03222 ast_channel_unlock(c[i]);
03223 return c[i];
03224 }
03225 if (!whentohangup || whentohangup > diff)
03226 whentohangup = diff;
03227 }
03228 ast_channel_unlock(c[i]);
03229 CHECK_BLOCKING(c[i]);
03230 }
03231
03232 rms = *ms;
03233 if (whentohangup) {
03234 rms = whentohangup;
03235 if (*ms >= 0 && *ms < rms)
03236 rms = *ms;
03237 }
03238
03239 if (*ms > 0)
03240 start = ast_tvnow();
03241
03242 res = epoll_wait(c[0]->epfd, ev, 25, rms);
03243
03244 for (i = 0; i < n; i++)
03245 ast_clear_flag(c[i], AST_FLAG_BLOCKING);
03246
03247 if (res < 0) {
03248 if (errno != EINTR)
03249 *ms = -1;
03250 return NULL;
03251 }
03252
03253 if (whentohangup) {
03254 now = ast_tvnow();
03255 for (i = 0; i < n; i++) {
03256 if (!ast_tvzero(c[i]->whentohangup) && ast_tvdiff_ms(now, c[i]->whentohangup) >= 0) {
03257 c[i]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
03258 if (!winner)
03259 winner = c[i];
03260 }
03261 }
03262 }
03263
03264 if (!res) {
03265 *ms = 0;
03266 return winner;
03267 }
03268
03269 for (i = 0; i < res; i++) {
03270 struct ast_epoll_data *aed = ev[i].data.ptr;
03271
03272 if (!ev[i].events || !aed)
03273 continue;
03274
03275 winner = aed->chan;
03276 if (ev[i].events & EPOLLPRI)
03277 ast_set_flag(winner, AST_FLAG_EXCEPTION);
03278 else
03279 ast_clear_flag(winner, AST_FLAG_EXCEPTION);
03280 winner->fdno = aed->which;
03281 }
03282
03283 if (*ms > 0) {
03284 *ms -= ast_tvdiff_ms(ast_tvnow(), start);
03285 if (*ms < 0)
03286 *ms = 0;
03287 }
03288
03289 return winner;
03290 }
03291
03292 struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds, int nfds,
03293 int *exception, int *outfd, int *ms)
03294 {
03295
03296 if (outfd)
03297 *outfd = -99999;
03298 if (exception)
03299 *exception = 0;
03300
03301
03302 if (!n || nfds || c[0]->epfd == -1)
03303 return ast_waitfor_nandfds_classic(c, n, fds, nfds, exception, outfd, ms);
03304 else if (!nfds && n == 1)
03305 return ast_waitfor_nandfds_simple(c[0], ms);
03306 else
03307 return ast_waitfor_nandfds_complex(c, n, ms);
03308 }
03309 #endif
03310
03311 struct ast_channel *ast_waitfor_n(struct ast_channel **c, int n, int *ms)
03312 {
03313 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
03314 }
03315
03316 int ast_waitfor(struct ast_channel *c, int ms)
03317 {
03318 int oldms = ms;
03319
03320 ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms);
03321 if ((ms < 0) && (oldms < 0))
03322 ms = 0;
03323 return ms;
03324 }
03325
03326
03327 int ast_waitfordigit(struct ast_channel *c, int ms)
03328 {
03329 return ast_waitfordigit_full(c, ms, -1, -1);
03330 }
03331
03332 int ast_settimeout(struct ast_channel *c, unsigned int rate, int (*func)(const void *data), void *data)
03333 {
03334 int res;
03335 unsigned int real_rate = rate, max_rate;
03336
03337 ast_channel_lock(c);
03338
03339 if (c->timingfd == -1) {
03340 ast_channel_unlock(c);
03341 return -1;
03342 }
03343
03344 if (!func) {
03345 rate = 0;
03346 data = NULL;
03347 }
03348
03349 if (rate && rate > (max_rate = ast_timer_get_max_rate(c->timer))) {
03350 real_rate = max_rate;
03351 }
03352
03353 ast_debug(1, "Scheduling timer at (%u requested / %u actual) timer ticks per second\n", rate, real_rate);
03354
03355 res = ast_timer_set_rate(c->timer, real_rate);
03356
03357 c->timingfunc = func;
03358 c->timingdata = data;
03359
03360 ast_channel_unlock(c);
03361
03362 return res;
03363 }
03364
03365 int ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
03366 {
03367
03368 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
03369 return -1;
03370
03371
03372 ast_set_flag(c, AST_FLAG_END_DTMF_ONLY);
03373
03374
03375
03376 while (ms) {
03377 struct ast_channel *rchan;
03378 int outfd=-1;
03379
03380 errno = 0;
03381 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
03382
03383 if (!rchan && outfd < 0 && ms) {
03384 if (errno == 0 || errno == EINTR)
03385 continue;
03386 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
03387 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03388 return -1;
03389 } else if (outfd > -1) {
03390
03391 ast_log(LOG_WARNING, "The FD we were waiting for has something waiting. Waitfordigit returning numeric 1\n");
03392 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03393 return 1;
03394 } else if (rchan) {
03395 int res;
03396 struct ast_frame *f = ast_read(c);
03397 if (!f)
03398 return -1;
03399
03400 switch (f->frametype) {
03401 case AST_FRAME_DTMF_BEGIN:
03402 break;
03403 case AST_FRAME_DTMF_END:
03404 res = f->subclass.integer;
03405 ast_frfree(f);
03406 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03407 return res;
03408 case AST_FRAME_CONTROL:
03409 switch (f->subclass.integer) {
03410 case AST_CONTROL_HANGUP:
03411 ast_frfree(f);
03412 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03413 return -1;
03414 case AST_CONTROL_RINGING:
03415 case AST_CONTROL_ANSWER:
03416 case AST_CONTROL_SRCUPDATE:
03417 case AST_CONTROL_SRCCHANGE:
03418 case AST_CONTROL_CONNECTED_LINE:
03419 case AST_CONTROL_REDIRECTING:
03420 case AST_CONTROL_UPDATE_RTP_PEER:
03421 case -1:
03422
03423 break;
03424 default:
03425 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass.integer);
03426 break;
03427 }
03428 break;
03429 case AST_FRAME_VOICE:
03430
03431 if (audiofd > -1) {
03432 if (write(audiofd, f->data.ptr, f->datalen) < 0) {
03433 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
03434 }
03435 }
03436 default:
03437
03438 break;
03439 }
03440 ast_frfree(f);
03441 }
03442 }
03443
03444 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
03445
03446 return 0;
03447 }
03448
03449 static void send_dtmf_event(struct ast_channel *chan, const char *direction, const char digit, const char *begin, const char *end)
03450 {
03451 ast_manager_event(chan, EVENT_FLAG_DTMF,
03452 "DTMF",
03453 "Channel: %s\r\n"
03454 "Uniqueid: %s\r\n"
03455 "Digit: %c\r\n"
03456 "Direction: %s\r\n"
03457 "Begin: %s\r\n"
03458 "End: %s\r\n",
03459 ast_channel_name(chan), ast_channel_uniqueid(chan), digit, direction, begin, end);
03460 }
03461
03462 static void ast_read_generator_actions(struct ast_channel *chan, struct ast_frame *f)
03463 {
03464 if (chan->generator && chan->generator->generate && chan->generatordata && !ast_internal_timing_enabled(chan)) {
03465 void *tmp = chan->generatordata;
03466 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = chan->generator->generate;
03467 int res;
03468 int samples;
03469
03470 if (chan->timingfunc) {
03471 ast_debug(1, "Generator got voice, switching to phase locked mode\n");
03472 ast_settimeout(chan, 0, NULL, NULL);
03473 }
03474
03475 chan->generatordata = NULL;
03476
03477 if (ast_format_cmp(&f->subclass.format, &chan->writeformat) == AST_FORMAT_CMP_NOT_EQUAL) {
03478 float factor;
03479 factor = ((float) ast_format_rate(&chan->writeformat)) / ((float) ast_format_rate(&f->subclass.format));
03480 samples = (int) ( ((float) f->samples) * factor );
03481 } else {
03482 samples = f->samples;
03483 }
03484
03485
03486
03487
03488
03489
03490
03491
03492
03493 ast_channel_unlock(chan);
03494 res = generate(chan, tmp, f->datalen, samples);
03495 ast_channel_lock(chan);
03496 chan->generatordata = tmp;
03497 if (res) {
03498 ast_debug(1, "Auto-deactivating generator\n");
03499 ast_deactivate_generator(chan);
03500 }
03501
03502 } else if (f->frametype == AST_FRAME_CNG) {
03503 if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) {
03504 ast_debug(1, "Generator got CNG, switching to timed mode\n");
03505 ast_settimeout(chan, 50, generator_force, chan);
03506 }
03507 }
03508 }
03509
03510 static inline void queue_dtmf_readq(struct ast_channel *chan, struct ast_frame *f)
03511 {
03512 struct ast_frame *fr = &chan->dtmff;
03513
03514 fr->frametype = AST_FRAME_DTMF_END;
03515 fr->subclass.integer = f->subclass.integer;
03516 fr->len = f->len;
03517
03518
03519
03520
03521
03522 ast_queue_frame(chan, fr);
03523 }
03524
03525
03526
03527
03528 static inline int should_skip_dtmf(struct ast_channel *chan)
03529 {
03530 if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF)) {
03531
03532
03533 return 1;
03534 }
03535
03536 if (!ast_tvzero(chan->dtmf_tv) &&
03537 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) {
03538
03539
03540 return 1;
03541 }
03542
03543 return 0;
03544 }
03545
03546
03547
03548
03549
03550
03551
03552
03553
03554
03555 static inline int calc_monitor_jump(int samples, int sample_rate, int seek_rate)
03556 {
03557 int diff = sample_rate - seek_rate;
03558
03559 if (diff > 0) {
03560 samples = samples / (float) (sample_rate / seek_rate);
03561 } else if (diff < 0) {
03562 samples = samples * (float) (seek_rate / sample_rate);
03563 }
03564
03565 return samples;
03566 }
03567
03568 static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
03569 {
03570 struct ast_frame *f = NULL;
03571 int blah;
03572 int prestate;
03573 int cause = 0;
03574
03575
03576
03577
03578
03579 if (chan->masq) {
03580 if (ast_do_masquerade(chan))
03581 ast_log(LOG_WARNING, "Failed to perform masquerade\n");
03582 else
03583 f = &ast_null_frame;
03584 return f;
03585 }
03586
03587
03588 ast_channel_lock(chan);
03589
03590
03591 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
03592 if (chan->generator)
03593 ast_deactivate_generator(chan);
03594
03595
03596
03597
03598
03599
03600
03601
03602
03603
03604 if (chan->_softhangup) {
03605 ast_queue_control(chan, AST_CONTROL_END_OF_Q);
03606 } else {
03607 goto done;
03608 }
03609 } else {
03610 #ifdef AST_DEVMODE
03611
03612
03613
03614
03615
03616
03617
03618
03619
03620
03621
03622
03623 if (chan->fdno == -1) {
03624 ast_log(LOG_ERROR,
03625 "ast_read() on chan '%s' called with no recorded file descriptor.\n",
03626 ast_channel_name(chan));
03627 }
03628 #endif
03629 }
03630
03631 prestate = chan->_state;
03632
03633
03634
03635 if (chan->alertpipe[0] > -1) {
03636 int flags = fcntl(chan->alertpipe[0], F_GETFL);
03637
03638
03639 if ((flags & O_NONBLOCK) == 0) {
03640 ast_log(LOG_ERROR, "Alertpipe on channel %s lost O_NONBLOCK?!!\n", ast_channel_name(chan));
03641 if (fcntl(chan->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) {
03642 ast_log(LOG_WARNING, "Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
03643 f = &ast_null_frame;
03644 goto done;
03645 }
03646 }
03647 if (read(chan->alertpipe[0], &blah, sizeof(blah)) < 0) {
03648 if (errno != EINTR && errno != EAGAIN)
03649 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno));
03650 }
03651 }
03652
03653 if (chan->timingfd > -1 && chan->fdno == AST_TIMING_FD) {
03654 enum ast_timer_event res;
03655
03656 ast_clear_flag(chan, AST_FLAG_EXCEPTION);
03657
03658 res = ast_timer_get_event(chan->timer);
03659
03660 switch (res) {
03661 case AST_TIMING_EVENT_EXPIRED:
03662 ast_timer_ack(chan->timer, 1);
03663
03664 if (chan->timingfunc) {
03665
03666 int (*func)(const void *) = chan->timingfunc;
03667 void *data = chan->timingdata;
03668 chan->fdno = -1;
03669 ast_channel_unlock(chan);
03670 func(data);
03671 } else {
03672 ast_timer_set_rate(chan->timer, 0);
03673 chan->fdno = -1;
03674 ast_channel_unlock(chan);
03675 }
03676
03677
03678 return &ast_null_frame;
03679
03680 case AST_TIMING_EVENT_CONTINUOUS:
03681 if (AST_LIST_EMPTY(&chan->readq) ||
03682 !AST_LIST_NEXT(AST_LIST_FIRST(&chan->readq), frame_list)) {
03683 ast_timer_disable_continuous(chan->timer);
03684 }
03685 break;
03686 }
03687
03688 } else if (chan->fds[AST_GENERATOR_FD] > -1 && chan->fdno == AST_GENERATOR_FD) {
03689
03690
03691
03692 void *tmp = chan->generatordata;
03693 chan->generatordata = NULL;
03694 chan->generator->generate(chan, tmp, -1, -1);
03695 chan->generatordata = tmp;
03696 f = &ast_null_frame;
03697 chan->fdno = -1;
03698 goto done;
03699 } else if (chan->fds[AST_JITTERBUFFER_FD] > -1 && chan->fdno == AST_JITTERBUFFER_FD) {
03700 ast_clear_flag(chan, AST_FLAG_EXCEPTION);
03701 }
03702
03703
03704 if (!AST_LIST_EMPTY(&chan->readq)) {
03705 int skip_dtmf = should_skip_dtmf(chan);
03706
03707 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->readq, f, frame_list) {
03708
03709
03710
03711
03712 if ( (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && skip_dtmf) {
03713 continue;
03714 }
03715
03716 AST_LIST_REMOVE_CURRENT(frame_list);
03717 break;
03718 }
03719 AST_LIST_TRAVERSE_SAFE_END;
03720
03721 if (!f) {
03722
03723 f = &ast_null_frame;
03724 if (chan->alertpipe[0] > -1) {
03725 int poke = 0;
03726
03727
03728 if (write(chan->alertpipe[1], &poke, sizeof(poke)) != sizeof(poke)) {
03729 ast_log(LOG_ERROR, "Failed to write to alertpipe: %s\n", strerror(errno));
03730 }
03731 }
03732 }
03733
03734
03735
03736 if (f->frametype == AST_FRAME_CONTROL) {
03737 switch (f->subclass.integer) {
03738 case AST_CONTROL_HANGUP:
03739 chan->_softhangup |= AST_SOFTHANGUP_DEV;
03740 cause = f->data.uint32;
03741
03742 case AST_CONTROL_END_OF_Q:
03743 ast_frfree(f);
03744 f = NULL;
03745 break;
03746 default:
03747 break;
03748 }
03749 }
03750 } else {
03751 chan->blocker = pthread_self();
03752 if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
03753 if (chan->tech->exception)
03754 f = chan->tech->exception(chan);
03755 else {
03756 ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", ast_channel_name(chan));
03757 f = &ast_null_frame;
03758 }
03759
03760 ast_clear_flag(chan, AST_FLAG_EXCEPTION);
03761 } else if (chan->tech && chan->tech->read)
03762 f = chan->tech->read(chan);
03763 else
03764 ast_log(LOG_WARNING, "No read routine on channel %s\n", ast_channel_name(chan));
03765 }
03766
03767
03768
03769 f = ast_framehook_list_read_event(chan->framehooks, f);
03770
03771
03772
03773
03774
03775 chan->fdno = -1;
03776
03777 if (f) {
03778 struct ast_frame *readq_tail = AST_LIST_LAST(&chan->readq);
03779 struct ast_control_read_action_payload *read_action_payload;
03780 struct ast_party_connected_line connected;
03781
03782
03783
03784
03785 if (AST_LIST_NEXT(f, frame_list)) {
03786 ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list));
03787 ast_frfree(AST_LIST_NEXT(f, frame_list));
03788 AST_LIST_NEXT(f, frame_list) = NULL;
03789 }
03790
03791 switch (f->frametype) {
03792 case AST_FRAME_CONTROL:
03793 if (f->subclass.integer == AST_CONTROL_ANSWER) {
03794 if (!ast_test_flag(chan, AST_FLAG_OUTGOING)) {
03795 ast_debug(1, "Ignoring answer on an inbound call!\n");
03796 ast_frfree(f);
03797 f = &ast_null_frame;
03798 } else if (prestate == AST_STATE_UP && ast_bridged_channel(chan)) {
03799 ast_debug(1, "Dropping duplicate answer!\n");
03800 ast_frfree(f);
03801 f = &ast_null_frame;
03802 } else {
03803
03804 ast_setstate(chan, AST_STATE_UP);
03805
03806 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL);
03807 }
03808 } else if (f->subclass.integer == AST_CONTROL_READ_ACTION) {
03809 read_action_payload = f->data.ptr;
03810 switch (read_action_payload->action) {
03811 case AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO:
03812 ast_party_connected_line_init(&connected);
03813 ast_party_connected_line_copy(&connected, &chan->connected);
03814 if (ast_connected_line_parse_data(read_action_payload->payload,
03815 read_action_payload->payload_size, &connected)) {
03816 ast_party_connected_line_free(&connected);
03817 break;
03818 }
03819 if (ast_channel_connected_line_macro(NULL, chan, &connected, 1, 0)) {
03820 ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE,
03821 read_action_payload->payload,
03822 read_action_payload->payload_size);
03823 }
03824 ast_party_connected_line_free(&connected);
03825 break;
03826 }
03827 ast_frfree(f);
03828 f = &ast_null_frame;
03829 }
03830 break;
03831 case AST_FRAME_DTMF_END:
03832 send_dtmf_event(chan, "Received", f->subclass.integer, "No", "Yes");
03833 ast_log(LOG_DTMF, "DTMF end '%c' received on %s, duration %ld ms\n", f->subclass.integer, ast_channel_name(chan), f->len);
03834
03835 if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF) || ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
03836 queue_dtmf_readq(chan, f);
03837 ast_frfree(f);
03838 f = &ast_null_frame;
03839 } else if (!ast_test_flag(chan, AST_FLAG_IN_DTMF | AST_FLAG_END_DTMF_ONLY)) {
03840 if (!ast_tvzero(chan->dtmf_tv) &&
03841 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) {
03842
03843 queue_dtmf_readq(chan, f);
03844 ast_frfree(f);
03845 f = &ast_null_frame;
03846 } else {
03847
03848 f->frametype = AST_FRAME_DTMF_BEGIN;
03849 ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
03850 chan->emulate_dtmf_digit = f->subclass.integer;
03851 chan->dtmf_tv = ast_tvnow();
03852 if (f->len) {
03853 if (f->len > AST_MIN_DTMF_DURATION)
03854 chan->emulate_dtmf_duration = f->len;
03855 else
03856 chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION;
03857 } else
03858 chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION;
03859 ast_log(LOG_DTMF, "DTMF begin emulation of '%c' with duration %u queued on %s\n", f->subclass.integer, chan->emulate_dtmf_duration, ast_channel_name(chan));
03860 }
03861 if (chan->audiohooks) {
03862 struct ast_frame *old_frame = f;
03863
03864
03865
03866 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
03867 if (old_frame != f)
03868 ast_frfree(old_frame);
03869 }
03870 } else {
03871 struct timeval now = ast_tvnow();
03872 if (ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
03873 ast_log(LOG_DTMF, "DTMF end accepted with begin '%c' on %s\n", f->subclass.integer, ast_channel_name(chan));
03874 ast_clear_flag(chan, AST_FLAG_IN_DTMF);
03875 if (!f->len)
03876 f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
03877
03878
03879
03880
03881
03882
03883
03884
03885
03886 if (ast_tvdiff_ms(now, chan->dtmf_tv) < AST_MIN_DTMF_DURATION) {
03887 f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
03888 ast_log(LOG_DTMF, "DTMF end '%c' detected to have actual duration %ld on the wire, emulation will be triggered on %s\n", f->subclass.integer, f->len, ast_channel_name(chan));
03889 }
03890 } else if (!f->len) {
03891 ast_log(LOG_DTMF, "DTMF end accepted without begin '%c' on %s\n", f->subclass.integer, ast_channel_name(chan));
03892 f->len = AST_MIN_DTMF_DURATION;
03893 }
03894 if (f->len < AST_MIN_DTMF_DURATION && !ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)) {
03895 ast_log(LOG_DTMF, "DTMF end '%c' has duration %ld but want minimum %d, emulating on %s\n", f->subclass.integer, f->len, AST_MIN_DTMF_DURATION, ast_channel_name(chan));
03896 ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
03897 chan->emulate_dtmf_digit = f->subclass.integer;
03898 chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION - f->len;
03899 ast_frfree(f);
03900 f = &ast_null_frame;
03901 } else {
03902 ast_log(LOG_DTMF, "DTMF end passthrough '%c' on %s\n", f->subclass.integer, ast_channel_name(chan));
03903 if (f->len < AST_MIN_DTMF_DURATION) {
03904 f->len = AST_MIN_DTMF_DURATION;
03905 }
03906 chan->dtmf_tv = now;
03907 }
03908 if (chan->audiohooks) {
03909 struct ast_frame *old_frame = f;
03910 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
03911 if (old_frame != f)
03912 ast_frfree(old_frame);
03913 }
03914 }
03915 break;
03916 case AST_FRAME_DTMF_BEGIN:
03917 send_dtmf_event(chan, "Received", f->subclass.integer, "Yes", "No");
03918 ast_log(LOG_DTMF, "DTMF begin '%c' received on %s\n", f->subclass.integer, ast_channel_name(chan));
03919 if ( ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_END_DTMF_ONLY | AST_FLAG_EMULATE_DTMF) ||
03920 (!ast_tvzero(chan->dtmf_tv) &&
03921 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) ) {
03922 ast_log(LOG_DTMF, "DTMF begin ignored '%c' on %s\n", f->subclass.integer, ast_channel_name(chan));
03923 ast_frfree(f);
03924 f = &ast_null_frame;
03925 } else {
03926 ast_set_flag(chan, AST_FLAG_IN_DTMF);
03927 chan->dtmf_tv = ast_tvnow();
03928 ast_log(LOG_DTMF, "DTMF begin passthrough '%c' on %s\n", f->subclass.integer, ast_channel_name(chan));
03929 }
03930 break;
03931 case AST_FRAME_NULL:
03932
03933
03934
03935
03936 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
03937 struct timeval now = ast_tvnow();
03938 if (!chan->emulate_dtmf_duration) {
03939 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
03940 chan->emulate_dtmf_digit = 0;
03941 } else if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
03942 chan->emulate_dtmf_duration = 0;
03943 ast_frfree(f);
03944 f = &chan->dtmff;
03945 f->frametype = AST_FRAME_DTMF_END;
03946 f->subclass.integer = chan->emulate_dtmf_digit;
03947 f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
03948 chan->dtmf_tv = now;
03949 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
03950 chan->emulate_dtmf_digit = 0;
03951 ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass.integer, ast_channel_name(chan));
03952 if (chan->audiohooks) {
03953 struct ast_frame *old_frame = f;
03954 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
03955 if (old_frame != f) {
03956 ast_frfree(old_frame);
03957 }
03958 }
03959 }
03960 }
03961 break;
03962 case AST_FRAME_VOICE:
03963
03964
03965
03966
03967 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !chan->emulate_dtmf_duration) {
03968 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
03969 chan->emulate_dtmf_digit = 0;
03970 }
03971
03972 if (dropaudio || ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
03973 if (dropaudio)
03974 ast_read_generator_actions(chan, f);
03975 ast_frfree(f);
03976 f = &ast_null_frame;
03977 }
03978
03979 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
03980 struct timeval now = ast_tvnow();
03981 if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
03982 chan->emulate_dtmf_duration = 0;
03983 ast_frfree(f);
03984 f = &chan->dtmff;
03985 f->frametype = AST_FRAME_DTMF_END;
03986 f->subclass.integer = chan->emulate_dtmf_digit;
03987 f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
03988 chan->dtmf_tv = now;
03989 if (chan->audiohooks) {
03990 struct ast_frame *old_frame = f;
03991 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
03992 if (old_frame != f)
03993 ast_frfree(old_frame);
03994 }
03995 ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass.integer, ast_channel_name(chan));
03996 } else {
03997
03998 ast_frfree(f);
03999 f = &ast_null_frame;
04000 }
04001 } else if ((f->frametype == AST_FRAME_VOICE) && !ast_format_cap_iscompatible(chan->nativeformats, &f->subclass.format)) {
04002
04003 char to[200];
04004 ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n",
04005 ast_channel_name(chan), ast_getformatname(&f->subclass.format), ast_getformatname_multiple(to, sizeof(to), chan->nativeformats));
04006 ast_frfree(f);
04007 f = &ast_null_frame;
04008 } else if ((f->frametype == AST_FRAME_VOICE)) {
04009
04010 if (chan->audiohooks) {
04011 struct ast_frame *old_frame = f;
04012 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
04013 if (old_frame != f)
04014 ast_frfree(old_frame);
04015 }
04016 if (chan->monitor && chan->monitor->read_stream ) {
04017
04018 #ifndef MONITOR_CONSTANT_DELAY
04019 int jump = chan->outsmpl - chan->insmpl - 4 * f->samples;
04020 if (jump >= 0) {
04021 jump = calc_monitor_jump((chan->outsmpl - chan->insmpl), ast_format_rate(&f->subclass.format), ast_format_rate(&chan->monitor->read_stream->fmt->format));
04022 if (ast_seekstream(chan->monitor->read_stream, jump, SEEK_FORCECUR) == -1)
04023 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
04024 chan->insmpl += (chan->outsmpl - chan->insmpl) + f->samples;
04025 } else
04026 chan->insmpl+= f->samples;
04027 #else
04028 int jump = calc_monitor_jump((chan->outsmpl - chan->insmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format));
04029 if (jump - MONITOR_DELAY >= 0) {
04030 if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
04031 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
04032 chan->insmpl += chan->outsmpl - chan->insmpl;
04033 } else
04034 chan->insmpl += f->samples;
04035 #endif
04036 if (chan->monitor->state == AST_MONITOR_RUNNING) {
04037 if (ast_writestream(chan->monitor->read_stream, f) < 0)
04038 ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
04039 }
04040 }
04041
04042 if (chan->readtrans && (f = ast_translate(chan->readtrans, f, 1)) == NULL) {
04043 f = &ast_null_frame;
04044 }
04045
04046
04047
04048
04049
04050
04051
04052
04053 if (AST_LIST_NEXT(f, frame_list)) {
04054 if (!readq_tail) {
04055 ast_queue_frame_head(chan, AST_LIST_NEXT(f, frame_list));
04056 } else {
04057 __ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list), 0, readq_tail);
04058 }
04059 ast_frfree(AST_LIST_NEXT(f, frame_list));
04060 AST_LIST_NEXT(f, frame_list) = NULL;
04061 }
04062
04063
04064
04065 ast_read_generator_actions(chan, f);
04066 }
04067 break;
04068 default:
04069
04070 break;
04071 }
04072 } else {
04073
04074 if (!chan->_softhangup) {
04075 chan->_softhangup |= AST_SOFTHANGUP_DEV;
04076 }
04077 if (cause)
04078 chan->hangupcause = cause;
04079 if (chan->generator)
04080 ast_deactivate_generator(chan);
04081
04082 }
04083
04084
04085 if (chan->fin & DEBUGCHAN_FLAG)
04086 ast_frame_dump(ast_channel_name(chan), f, "<<");
04087 chan->fin = FRAMECOUNT_INC(chan->fin);
04088
04089 done:
04090 if (chan->music_state && chan->generator && chan->generator->digit && f && f->frametype == AST_FRAME_DTMF_END)
04091 chan->generator->digit(chan, f->subclass.integer);
04092
04093 if (chan->audiohooks && ast_audiohook_write_list_empty(chan->audiohooks)) {
04094
04095 ast_audiohook_detach_list(chan->audiohooks);
04096 chan->audiohooks = NULL;
04097 }
04098 ast_channel_unlock(chan);
04099 return f;
04100 }
04101
04102 int ast_internal_timing_enabled(struct ast_channel *chan)
04103 {
04104 return (ast_opt_internal_timing && chan->timingfd > -1);
04105 }
04106
04107 struct ast_frame *ast_read(struct ast_channel *chan)
04108 {
04109 return __ast_read(chan, 0);
04110 }
04111
04112 struct ast_frame *ast_read_noaudio(struct ast_channel *chan)
04113 {
04114 return __ast_read(chan, 1);
04115 }
04116
04117 int ast_indicate(struct ast_channel *chan, int condition)
04118 {
04119 return ast_indicate_data(chan, condition, NULL, 0);
04120 }
04121
04122 static int attribute_const is_visible_indication(enum ast_control_frame_type condition)
04123 {
04124
04125
04126
04127 switch (condition) {
04128 case AST_CONTROL_PROGRESS:
04129 case AST_CONTROL_PROCEEDING:
04130 case AST_CONTROL_VIDUPDATE:
04131 case AST_CONTROL_SRCUPDATE:
04132 case AST_CONTROL_SRCCHANGE:
04133 case AST_CONTROL_RADIO_KEY:
04134 case AST_CONTROL_RADIO_UNKEY:
04135 case AST_CONTROL_OPTION:
04136 case AST_CONTROL_WINK:
04137 case AST_CONTROL_FLASH:
04138 case AST_CONTROL_OFFHOOK:
04139 case AST_CONTROL_TAKEOFFHOOK:
04140 case AST_CONTROL_ANSWER:
04141 case AST_CONTROL_HANGUP:
04142 case AST_CONTROL_CONNECTED_LINE:
04143 case AST_CONTROL_REDIRECTING:
04144 case AST_CONTROL_TRANSFER:
04145 case AST_CONTROL_T38_PARAMETERS:
04146 case _XXX_AST_CONTROL_T38:
04147 case AST_CONTROL_CC:
04148 case AST_CONTROL_READ_ACTION:
04149 case AST_CONTROL_AOC:
04150 case AST_CONTROL_END_OF_Q:
04151 case AST_CONTROL_MCID:
04152 case AST_CONTROL_UPDATE_RTP_PEER:
04153 break;
04154
04155 case AST_CONTROL_INCOMPLETE:
04156 case AST_CONTROL_CONGESTION:
04157 case AST_CONTROL_BUSY:
04158 case AST_CONTROL_RINGING:
04159 case AST_CONTROL_RING:
04160 case AST_CONTROL_HOLD:
04161
04162 return 1;
04163
04164 case AST_CONTROL_UNHOLD:
04165
04166 break;
04167 }
04168
04169 return 0;
04170 }
04171
04172 int ast_indicate_data(struct ast_channel *chan, int _condition,
04173 const void *data, size_t datalen)
04174 {
04175
04176
04177 enum ast_control_frame_type condition = _condition;
04178 struct ast_tone_zone_sound *ts = NULL;
04179 int res;
04180
04181 struct ast_frame *awesome_frame = NULL;
04182
04183 ast_channel_lock(chan);
04184
04185
04186 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
04187 res = -1;
04188 goto indicate_cleanup;
04189 }
04190
04191 if (!ast_framehook_list_is_empty(chan->framehooks)) {
04192
04193 struct ast_frame frame = {
04194 .frametype = AST_FRAME_CONTROL,
04195 .subclass.integer = condition,
04196 .data.ptr = (void *) data,
04197 .datalen = datalen
04198 };
04199
04200
04201 awesome_frame = ast_frdup(&frame);
04202
04203
04204 if (!(awesome_frame = ast_framehook_list_write_event(chan->framehooks, awesome_frame))
04205 || awesome_frame->frametype != AST_FRAME_CONTROL) {
04206
04207 res = 0;
04208 goto indicate_cleanup;
04209 }
04210
04211 condition = awesome_frame->subclass.integer;
04212 data = awesome_frame->data.ptr;
04213 datalen = awesome_frame->datalen;
04214 }
04215
04216 switch (condition) {
04217 case AST_CONTROL_CONNECTED_LINE:
04218 {
04219 struct ast_party_connected_line connected;
04220
04221 ast_party_connected_line_set_init(&connected, &chan->connected);
04222 res = ast_connected_line_parse_data(data, datalen, &connected);
04223 if (!res) {
04224 ast_channel_set_connected_line(chan, &connected, NULL);
04225 }
04226 ast_party_connected_line_free(&connected);
04227 }
04228 break;
04229
04230 case AST_CONTROL_REDIRECTING:
04231 {
04232 struct ast_party_redirecting redirecting;
04233
04234 ast_party_redirecting_set_init(&redirecting, &chan->redirecting);
04235 res = ast_redirecting_parse_data(data, datalen, &redirecting);
04236 if (!res) {
04237 ast_channel_set_redirecting(chan, &redirecting, NULL);
04238 }
04239 ast_party_redirecting_free(&redirecting);
04240 }
04241 break;
04242
04243 default:
04244 break;
04245 }
04246
04247 if (is_visible_indication(condition)) {
04248
04249 chan->visible_indication = condition;
04250 } else if (condition == AST_CONTROL_UNHOLD || _condition < 0) {
04251
04252 chan->visible_indication = 0;
04253 }
04254
04255 if (chan->tech->indicate) {
04256
04257 res = chan->tech->indicate(chan, condition, data, datalen);
04258 } else {
04259 res = -1;
04260 }
04261
04262 if (!res) {
04263
04264 res = 0;
04265 goto indicate_cleanup;
04266 }
04267
04268
04269
04270
04271
04272
04273
04274 if (_condition < 0) {
04275
04276 ast_playtones_stop(chan);
04277 res = 0;
04278 goto indicate_cleanup;
04279 }
04280
04281
04282 switch (condition) {
04283 case _XXX_AST_CONTROL_T38:
04284
04285 res = -1;
04286 goto indicate_cleanup;
04287 case AST_CONTROL_T38_PARAMETERS:
04288
04289
04290
04291
04292
04293
04294
04295 goto indicate_cleanup;
04296 case AST_CONTROL_RINGING:
04297 ts = ast_get_indication_tone(chan->zone, "ring");
04298
04299
04300
04301
04302
04303
04304
04305 if (chan->_state == AST_STATE_UP) {
04306 res = 0;
04307 }
04308 break;
04309 case AST_CONTROL_BUSY:
04310 ts = ast_get_indication_tone(chan->zone, "busy");
04311 break;
04312 case AST_CONTROL_INCOMPLETE:
04313 case AST_CONTROL_CONGESTION:
04314 ts = ast_get_indication_tone(chan->zone, "congestion");
04315 break;
04316 case AST_CONTROL_PROGRESS:
04317 case AST_CONTROL_PROCEEDING:
04318 case AST_CONTROL_VIDUPDATE:
04319 case AST_CONTROL_SRCUPDATE:
04320 case AST_CONTROL_SRCCHANGE:
04321 case AST_CONTROL_RADIO_KEY:
04322 case AST_CONTROL_RADIO_UNKEY:
04323 case AST_CONTROL_OPTION:
04324 case AST_CONTROL_WINK:
04325 case AST_CONTROL_FLASH:
04326 case AST_CONTROL_OFFHOOK:
04327 case AST_CONTROL_TAKEOFFHOOK:
04328 case AST_CONTROL_ANSWER:
04329 case AST_CONTROL_HANGUP:
04330 case AST_CONTROL_RING:
04331 case AST_CONTROL_HOLD:
04332 case AST_CONTROL_UNHOLD:
04333 case AST_CONTROL_TRANSFER:
04334 case AST_CONTROL_CONNECTED_LINE:
04335 case AST_CONTROL_REDIRECTING:
04336 case AST_CONTROL_CC:
04337 case AST_CONTROL_READ_ACTION:
04338 case AST_CONTROL_AOC:
04339 case AST_CONTROL_END_OF_Q:
04340 case AST_CONTROL_MCID:
04341 case AST_CONTROL_UPDATE_RTP_PEER:
04342
04343 res = 0;
04344 break;
04345 }
04346
04347 if (ts) {
04348
04349 ast_debug(1, "Driver for channel '%s' does not support indication %d, emulating it\n", ast_channel_name(chan), condition);
04350 res = ast_playtones_start(chan, 0, ts->data, 1);
04351 ts = ast_tone_zone_sound_unref(ts);
04352 }
04353
04354 if (res) {
04355
04356 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, ast_channel_name(chan));
04357 }
04358
04359 indicate_cleanup:
04360 ast_channel_unlock(chan);
04361 if (awesome_frame) {
04362 ast_frfree(awesome_frame);
04363 }
04364
04365 return res;
04366 }
04367
04368 int ast_recvchar(struct ast_channel *chan, int timeout)
04369 {
04370 int c;
04371 char *buf = ast_recvtext(chan, timeout);
04372 if (buf == NULL)
04373 return -1;
04374 c = *(unsigned char *)buf;
04375 ast_free(buf);
04376 return c;
04377 }
04378
04379 char *ast_recvtext(struct ast_channel *chan, int timeout)
04380 {
04381 int res, done = 0;
04382 char *buf = NULL;
04383
04384 while (!done) {
04385 struct ast_frame *f;
04386 if (ast_check_hangup(chan))
04387 break;
04388 res = ast_waitfor(chan, timeout);
04389 if (res <= 0)
04390 break;
04391 timeout = res;
04392 f = ast_read(chan);
04393 if (f == NULL)
04394 break;
04395 if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_HANGUP)
04396 done = 1;
04397 else if (f->frametype == AST_FRAME_TEXT) {
04398 buf = ast_strndup((char *) f->data.ptr, f->datalen);
04399 done = 1;
04400 }
04401 ast_frfree(f);
04402 }
04403 return buf;
04404 }
04405
04406 int ast_sendtext(struct ast_channel *chan, const char *text)
04407 {
04408 int res = 0;
04409
04410 ast_channel_lock(chan);
04411
04412 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
04413 ast_channel_unlock(chan);
04414 return -1;
04415 }
04416
04417 if (ast_strlen_zero(text)) {
04418 ast_channel_unlock(chan);
04419 return 0;
04420 }
04421
04422 CHECK_BLOCKING(chan);
04423 if (chan->tech->write_text && (ast_format_cap_has_type(chan->nativeformats, AST_FORMAT_TYPE_TEXT))) {
04424 struct ast_frame f;
04425
04426 f.frametype = AST_FRAME_TEXT;
04427 f.src = "DIALPLAN";
04428 f.mallocd = AST_MALLOCD_DATA;
04429 f.datalen = strlen(text);
04430 f.data.ptr = ast_strdup(text);
04431 f.offset = 0;
04432 f.seqno = 0;
04433
04434 ast_format_set(&f.subclass.format, AST_FORMAT_T140, 0);
04435 res = chan->tech->write_text(chan, &f);
04436 } else if (chan->tech->send_text) {
04437 res = chan->tech->send_text(chan, text);
04438 }
04439 ast_clear_flag(chan, AST_FLAG_BLOCKING);
04440 ast_channel_unlock(chan);
04441 return res;
04442 }
04443
04444 int ast_senddigit_begin(struct ast_channel *chan, char digit)
04445 {
04446
04447
04448 static const char * const dtmf_tones[] = {
04449 "941+1336",
04450 "697+1209",
04451 "697+1336",
04452 "697+1477",
04453 "770+1209",
04454 "770+1336",
04455 "770+1477",
04456 "852+1209",
04457 "852+1336",
04458 "852+1477",
04459 "697+1633",
04460 "770+1633",
04461 "852+1633",
04462 "941+1633",
04463 "941+1209",
04464 "941+1477"
04465 };
04466
04467 if (!chan->tech->send_digit_begin)
04468 return 0;
04469
04470 if (!chan->tech->send_digit_begin(chan, digit))
04471 return 0;
04472
04473 if (digit >= '0' && digit <='9')
04474 ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0);
04475 else if (digit >= 'A' && digit <= 'D')
04476 ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0);
04477 else if (digit == '*')
04478 ast_playtones_start(chan, 0, dtmf_tones[14], 0);
04479 else if (digit == '#')
04480 ast_playtones_start(chan, 0, dtmf_tones[15], 0);
04481 else {
04482
04483 ast_debug(1, "Unable to generate DTMF tone '%c' for '%s'\n", digit, ast_channel_name(chan));
04484 }
04485
04486 return 0;
04487 }
04488
04489 int ast_senddigit_end(struct ast_channel *chan, char digit, unsigned int duration)
04490 {
04491 int res = -1;
04492
04493 if (chan->tech->send_digit_end)
04494 res = chan->tech->send_digit_end(chan, digit, duration);
04495
04496 if (res && chan->generator)
04497 ast_playtones_stop(chan);
04498
04499 return 0;
04500 }
04501
04502 int ast_senddigit(struct ast_channel *chan, char digit, unsigned int duration)
04503 {
04504 if (chan->tech->send_digit_begin) {
04505 ast_senddigit_begin(chan, digit);
04506 ast_safe_sleep(chan, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION));
04507 }
04508
04509 return ast_senddigit_end(chan, digit, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION));
04510 }
04511
04512 int ast_prod(struct ast_channel *chan)
04513 {
04514 struct ast_frame a = { AST_FRAME_VOICE };
04515 char nothing[128];
04516
04517
04518 if (chan->_state != AST_STATE_UP) {
04519 ast_debug(1, "Prodding channel '%s'\n", ast_channel_name(chan));
04520 ast_format_copy(&a.subclass.format, &chan->rawwriteformat);
04521 a.data.ptr = nothing + AST_FRIENDLY_OFFSET;
04522 a.src = "ast_prod";
04523 if (ast_write(chan, &a))
04524 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", ast_channel_name(chan));
04525 }
04526 return 0;
04527 }
04528
04529 int ast_write_video(struct ast_channel *chan, struct ast_frame *fr)
04530 {
04531 int res;
04532 if (!chan->tech->write_video)
04533 return 0;
04534 res = ast_write(chan, fr);
04535 if (!res)
04536 res = 1;
04537 return res;
04538 }
04539
04540 struct plc_ds {
04541
04542
04543
04544
04545 int16_t *samples_buf;
04546
04547
04548
04549 size_t num_samples;
04550 plc_state_t plc_state;
04551 };
04552
04553 static void plc_ds_destroy(void *data)
04554 {
04555 struct plc_ds *plc = data;
04556 ast_free(plc->samples_buf);
04557 ast_free(plc);
04558 }
04559
04560 static struct ast_datastore_info plc_ds_info = {
04561 .type = "plc",
04562 .destroy = plc_ds_destroy,
04563 };
04564
04565 static void adjust_frame_for_plc(struct ast_channel *chan, struct ast_frame *frame, struct ast_datastore *datastore)
04566 {
04567 int num_new_samples = frame->samples;
04568 struct plc_ds *plc = datastore->data;
04569
04570
04571
04572
04573
04574
04575
04576
04577
04578
04579
04580
04581
04582
04583
04584
04585
04586
04587
04588
04589 if (!num_new_samples) {
04590 return;
04591 }
04592
04593
04594
04595
04596
04597 if (plc->num_samples < num_new_samples) {
04598 ast_free(plc->samples_buf);
04599 plc->samples_buf = ast_calloc(1, (num_new_samples * sizeof(*plc->samples_buf)) + (AST_FRIENDLY_OFFSET * 2));
04600 if (!plc->samples_buf) {
04601 ast_channel_datastore_remove(chan, datastore);
04602 ast_datastore_free(datastore);
04603 return;
04604 }
04605 plc->num_samples = num_new_samples;
04606 }
04607
04608 if (frame->datalen == 0) {
04609 plc_fillin(&plc->plc_state, plc->samples_buf + AST_FRIENDLY_OFFSET, frame->samples);
04610 frame->data.ptr = plc->samples_buf + AST_FRIENDLY_OFFSET;
04611 frame->datalen = num_new_samples * 2;
04612 frame->offset = AST_FRIENDLY_OFFSET * 2;
04613 } else {
04614 plc_rx(&plc->plc_state, frame->data.ptr, frame->samples);
04615 }
04616 }
04617
04618 static void apply_plc(struct ast_channel *chan, struct ast_frame *frame)
04619 {
04620 struct ast_datastore *datastore;
04621 struct plc_ds *plc;
04622
04623 datastore = ast_channel_datastore_find(chan, &plc_ds_info, NULL);
04624 if (datastore) {
04625 plc = datastore->data;
04626 adjust_frame_for_plc(chan, frame, datastore);
04627 return;
04628 }
04629
04630 datastore = ast_datastore_alloc(&plc_ds_info, NULL);
04631 if (!datastore) {
04632 return;
04633 }
04634 plc = ast_calloc(1, sizeof(*plc));
04635 if (!plc) {
04636 ast_datastore_free(datastore);
04637 return;
04638 }
04639 datastore->data = plc;
04640 ast_channel_datastore_add(chan, datastore);
04641 adjust_frame_for_plc(chan, frame, datastore);
04642 }
04643
04644 int ast_write(struct ast_channel *chan, struct ast_frame *fr)
04645 {
04646 int res = -1;
04647 struct ast_frame *f = NULL;
04648 int count = 0;
04649
04650
04651 while(ast_channel_trylock(chan)) {
04652
04653 if(count++ > 10) {
04654 ast_debug(1, "Deadlock avoided for write to channel '%s'\n", ast_channel_name(chan));
04655 return 0;
04656 }
04657 usleep(1);
04658 }
04659
04660 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
04661 goto done;
04662
04663
04664 if (chan->masq) {
04665 ast_channel_unlock(chan);
04666 if (ast_do_masquerade(chan)) {
04667 ast_log(LOG_WARNING, "Failed to perform masquerade\n");
04668 return res;
04669 }
04670 ast_channel_lock(chan);
04671 }
04672 if (chan->masqr) {
04673 res = 0;
04674 goto done;
04675 }
04676
04677
04678
04679 if (!(fr = ast_framehook_list_write_event(chan->framehooks, fr))) {
04680 res = 0;
04681 goto done;
04682 }
04683
04684 if (chan->generatordata && (!fr->src || strcasecmp(fr->src, "ast_prod"))) {
04685 if (ast_test_flag(chan, AST_FLAG_WRITE_INT)) {
04686 ast_deactivate_generator(chan);
04687 } else {
04688 if (fr->frametype == AST_FRAME_DTMF_END) {
04689
04690
04691
04692 ast_clear_flag(chan, AST_FLAG_BLOCKING);
04693 ast_channel_unlock(chan);
04694 res = ast_senddigit_end(chan, fr->subclass.integer, fr->len);
04695 ast_channel_lock(chan);
04696 CHECK_BLOCKING(chan);
04697 } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_UNHOLD) {
04698
04699 res = (chan->tech->indicate == NULL) ? 0 :
04700 chan->tech->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen);
04701 }
04702 res = 0;
04703 goto done;
04704 }
04705 }
04706
04707 if (chan->fout & DEBUGCHAN_FLAG)
04708 ast_frame_dump(ast_channel_name(chan), fr, ">>");
04709 CHECK_BLOCKING(chan);
04710 switch (fr->frametype) {
04711 case AST_FRAME_CONTROL:
04712 res = (chan->tech->indicate == NULL) ? 0 :
04713 chan->tech->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen);
04714 break;
04715 case AST_FRAME_DTMF_BEGIN:
04716 if (chan->audiohooks) {
04717 struct ast_frame *old_frame = fr;
04718 fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
04719 if (old_frame != fr)
04720 f = fr;
04721 }
04722 send_dtmf_event(chan, "Sent", fr->subclass.integer, "Yes", "No");
04723 ast_clear_flag(chan, AST_FLAG_BLOCKING);
04724 ast_channel_unlock(chan);
04725 res = ast_senddigit_begin(chan, fr->subclass.integer);
04726 ast_channel_lock(chan);
04727 CHECK_BLOCKING(chan);
04728 break;
04729 case AST_FRAME_DTMF_END:
04730 if (chan->audiohooks) {
04731 struct ast_frame *new_frame = fr;
04732
04733 new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
04734 if (new_frame != fr) {
04735 ast_frfree(new_frame);
04736 }
04737 }
04738 send_dtmf_event(chan, "Sent", fr->subclass.integer, "No", "Yes");
04739 ast_clear_flag(chan, AST_FLAG_BLOCKING);
04740 ast_channel_unlock(chan);
04741 res = ast_senddigit_end(chan, fr->subclass.integer, fr->len);
04742 ast_channel_lock(chan);
04743 CHECK_BLOCKING(chan);
04744 break;
04745 case AST_FRAME_TEXT:
04746 if (fr->subclass.integer == AST_FORMAT_T140) {
04747 res = (chan->tech->write_text == NULL) ? 0 :
04748 chan->tech->write_text(chan, fr);
04749 } else {
04750 res = (chan->tech->send_text == NULL) ? 0 :
04751 chan->tech->send_text(chan, (char *) fr->data.ptr);
04752 }
04753 break;
04754 case AST_FRAME_HTML:
04755 res = (chan->tech->send_html == NULL) ? 0 :
04756 chan->tech->send_html(chan, fr->subclass.integer, (char *) fr->data.ptr, fr->datalen);
04757 break;
04758 case AST_FRAME_VIDEO:
04759
04760 res = (chan->tech->write_video == NULL) ? 0 :
04761 chan->tech->write_video(chan, fr);
04762 break;
04763 case AST_FRAME_MODEM:
04764 res = (chan->tech->write == NULL) ? 0 :
04765 chan->tech->write(chan, fr);
04766 break;
04767 case AST_FRAME_VOICE:
04768 if (chan->tech->write == NULL)
04769 break;
04770
04771 if (ast_opt_generic_plc && fr->subclass.format.id == AST_FORMAT_SLINEAR) {
04772 apply_plc(chan, fr);
04773 }
04774
04775
04776 if (ast_format_cmp(&fr->subclass.format, &chan->rawwriteformat) != AST_FORMAT_CMP_NOT_EQUAL) {
04777 f = fr;
04778 } else {
04779
04780
04781
04782
04783
04784
04785 if ((!ast_format_cap_iscompatible(chan->nativeformats, &fr->subclass.format)) &&
04786 (ast_format_cmp(&chan->writeformat, &fr->subclass.format) != AST_FORMAT_CMP_EQUAL)) {
04787 char nf[512];
04788 ast_log(LOG_WARNING, "Codec mismatch on channel %s setting write format to %s from %s native formats %s\n",
04789 ast_channel_name(chan), ast_getformatname(&fr->subclass.format), ast_getformatname(&chan->writeformat),
04790 ast_getformatname_multiple(nf, sizeof(nf), chan->nativeformats));
04791 ast_set_write_format_by_id(chan, fr->subclass.format.id);
04792 }
04793
04794 f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
04795 }
04796
04797 if (!f) {
04798 res = 0;
04799 break;
04800 }
04801
04802 if (chan->audiohooks) {
04803 struct ast_frame *prev = NULL, *new_frame, *cur, *dup;
04804 int freeoldlist = 0;
04805
04806 if (f != fr) {
04807 freeoldlist = 1;
04808 }
04809
04810
04811
04812
04813 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
04814 new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, cur);
04815
04816
04817
04818 if (new_frame != cur) {
04819
04820
04821
04822
04823 if ((dup = ast_frisolate(new_frame))) {
04824 AST_LIST_NEXT(dup, frame_list) = AST_LIST_NEXT(cur, frame_list);
04825 if (freeoldlist) {
04826 AST_LIST_NEXT(cur, frame_list) = NULL;
04827 ast_frfree(cur);
04828 }
04829 if (new_frame != dup) {
04830 ast_frfree(new_frame);
04831 }
04832 cur = dup;
04833 }
04834 }
04835
04836
04837
04838 if (prev) {
04839 AST_LIST_NEXT(prev, frame_list) = cur;
04840 } else {
04841 f = cur;
04842 }
04843 prev = cur;
04844 }
04845 }
04846
04847
04848
04849
04850
04851 if (chan->monitor && chan->monitor->write_stream) {
04852 struct ast_frame *cur;
04853
04854 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
04855
04856 #ifndef MONITOR_CONSTANT_DELAY
04857 int jump = chan->insmpl - chan->outsmpl - 4 * cur->samples;
04858 if (jump >= 0) {
04859 jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(&f->subclass.format), ast_format_rate(&chan->monitor->read_stream->fmt->format));
04860 if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1)
04861 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
04862 chan->outsmpl += (chan->insmpl - chan->outsmpl) + cur->samples;
04863 } else {
04864 chan->outsmpl += cur->samples;
04865 }
04866 #else
04867 int jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format));
04868 if (jump - MONITOR_DELAY >= 0) {
04869 if (ast_seekstream(chan->monitor->write_stream, jump - cur->samples, SEEK_FORCECUR) == -1)
04870 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
04871 chan->outsmpl += chan->insmpl - chan->outsmpl;
04872 } else {
04873 chan->outsmpl += cur->samples;
04874 }
04875 #endif
04876 if (chan->monitor->state == AST_MONITOR_RUNNING) {
04877 if (ast_writestream(chan->monitor->write_stream, cur) < 0)
04878 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
04879 }
04880 }
04881 }
04882
04883
04884
04885
04886 if ((f != fr) && AST_LIST_NEXT(f, frame_list)) {
04887 struct ast_frame *cur, *next = NULL;
04888 unsigned int skip = 0;
04889
04890 cur = f;
04891 while (cur) {
04892 next = AST_LIST_NEXT(cur, frame_list);
04893 AST_LIST_NEXT(cur, frame_list) = NULL;
04894 if (!skip) {
04895 if ((res = chan->tech->write(chan, cur)) < 0) {
04896 chan->_softhangup |= AST_SOFTHANGUP_DEV;
04897 skip = 1;
04898 } else if (next) {
04899
04900
04901
04902 chan->fout = FRAMECOUNT_INC(chan->fout);
04903 }
04904 }
04905 ast_frfree(cur);
04906 cur = next;
04907 }
04908
04909
04910 f = NULL;
04911 } else {
04912 res = chan->tech->write(chan, f);
04913 }
04914 break;
04915 case AST_FRAME_NULL:
04916 case AST_FRAME_IAX:
04917
04918 res = 0;
04919 break;
04920 default:
04921
04922
04923
04924 res = chan->tech->write(chan, fr);
04925 break;
04926 }
04927
04928 if (f && f != fr)
04929 ast_frfree(f);
04930 ast_clear_flag(chan, AST_FLAG_BLOCKING);
04931
04932
04933 if (res < 0) {
04934 chan->_softhangup |= AST_SOFTHANGUP_DEV;
04935 } else {
04936 chan->fout = FRAMECOUNT_INC(chan->fout);
04937 }
04938 done:
04939 if (chan->audiohooks && ast_audiohook_write_list_empty(chan->audiohooks)) {
04940
04941 ast_audiohook_detach_list(chan->audiohooks);
04942 chan->audiohooks = NULL;
04943 }
04944 ast_channel_unlock(chan);
04945 return res;
04946 }
04947
04948 static int set_format(struct ast_channel *chan,
04949 struct ast_format_cap *cap_set,
04950 struct ast_format *rawformat,
04951 struct ast_format *format,
04952 struct ast_trans_pvt **trans,
04953 const int direction)
04954 {
04955 struct ast_format_cap *cap_native = chan->nativeformats;
04956 struct ast_format best_set_fmt;
04957 struct ast_format best_native_fmt;
04958 int res;
04959 char from[200], to[200];
04960
04961 ast_best_codec(cap_set, &best_set_fmt);
04962
04963
04964 if (!ast_channel_setoption(chan, direction ? AST_OPTION_FORMAT_WRITE : AST_OPTION_FORMAT_READ, &best_set_fmt, sizeof(best_set_fmt), 0)) {
04965 ast_debug(1, "Channel driver natively set channel %s to %s format %s\n", ast_channel_name(chan),
04966 direction ? "write" : "read", ast_getformatname(&best_set_fmt));
04967
04968 ast_channel_lock(chan);
04969 ast_format_copy(format, &best_set_fmt);
04970 ast_format_copy(rawformat, &best_set_fmt);
04971 ast_format_cap_set(chan->nativeformats, &best_set_fmt);
04972 ast_channel_unlock(chan);
04973
04974 if (*trans) {
04975 ast_translator_free_path(*trans);
04976 }
04977 *trans = NULL;
04978
04979
04980 if (direction && chan->generatordata) {
04981 generator_write_format_change(chan);
04982 }
04983 return 0;
04984 }
04985
04986
04987 if (!direction) {
04988
04989 res = ast_translator_best_choice(cap_set, cap_native, &best_set_fmt, &best_native_fmt);
04990 } else {
04991
04992 res = ast_translator_best_choice(cap_native, cap_set, &best_native_fmt, &best_set_fmt);
04993 }
04994
04995 if (res < 0) {
04996 ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n",
04997 ast_getformatname_multiple(from, sizeof(from), cap_native),
04998 ast_getformatname_multiple(to, sizeof(to), cap_set));
04999 return -1;
05000 }
05001
05002
05003 ast_channel_lock(chan);
05004
05005 if ((ast_format_cmp(rawformat, &best_native_fmt) != AST_FORMAT_CMP_NOT_EQUAL) &&
05006 (ast_format_cmp(format, &best_set_fmt) != AST_FORMAT_CMP_NOT_EQUAL) &&
05007 ((ast_format_cmp(rawformat, format) != AST_FORMAT_CMP_NOT_EQUAL) || (*trans))) {
05008
05009 ast_channel_unlock(chan);
05010 return 0;
05011 }
05012
05013 ast_format_copy(rawformat, &best_native_fmt);
05014
05015 ast_format_copy(format, &best_set_fmt);
05016
05017
05018 if (*trans) {
05019 ast_translator_free_path(*trans);
05020 *trans = NULL;
05021 }
05022
05023
05024 if (ast_format_cmp(format, rawformat) != AST_FORMAT_CMP_NOT_EQUAL) {
05025
05026
05027
05028
05029
05030 res = 0;
05031 } else {
05032 if (!direction) {
05033
05034 *trans = ast_translator_build_path(format, rawformat);
05035 } else {
05036
05037 *trans = ast_translator_build_path(rawformat, format);
05038 }
05039 res = *trans ? 0 : -1;
05040 }
05041 ast_channel_unlock(chan);
05042
05043 ast_debug(1, "Set channel %s to %s format %s\n",
05044 ast_channel_name(chan),
05045 direction ? "write" : "read",
05046 ast_getformatname(&best_set_fmt));
05047
05048
05049
05050 if (direction && chan->generatordata) {
05051 generator_write_format_change(chan);
05052 }
05053 return res;
05054 }
05055
05056 int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
05057 {
05058 struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
05059 int res;
05060 if (!cap) {
05061 return -1;
05062 }
05063 ast_format_cap_add(cap, format);
05064
05065 res = set_format(chan,
05066 cap,
05067 &chan->rawreadformat,
05068 &chan->readformat,
05069 &chan->readtrans,
05070 0);
05071
05072 ast_format_cap_destroy(cap);
05073 return res;
05074 }
05075
05076 int ast_set_read_format_by_id(struct ast_channel *chan, enum ast_format_id id)
05077 {
05078 struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
05079 struct ast_format tmp_format;
05080 int res;
05081 if (!cap) {
05082 return -1;
05083 }
05084 ast_format_cap_add(cap, ast_format_set(&tmp_format, id, 0));
05085
05086 res = set_format(chan,
05087 cap,
05088 &chan->rawreadformat,
05089 &chan->readformat,
05090 &chan->readtrans,
05091 0);
05092
05093 ast_format_cap_destroy(cap);
05094 return res;
05095 }
05096
05097 int ast_set_read_format_from_cap(struct ast_channel *chan, struct ast_format_cap *cap)
05098 {
05099 return set_format(chan,
05100 cap,
05101 &chan->rawreadformat,
05102 &chan->readformat,
05103 &chan->readtrans,
05104 0);
05105 }
05106
05107 int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
05108 {
05109 struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
05110 int res;
05111 if (!cap) {
05112 return -1;
05113 }
05114 ast_format_cap_add(cap, format);
05115
05116 res = set_format(chan,
05117 cap,
05118 &chan->rawwriteformat,
05119 &chan->writeformat,
05120 &chan->writetrans,
05121 1);
05122
05123 ast_format_cap_destroy(cap);
05124 return res;
05125 }
05126
05127 int ast_set_write_format_by_id(struct ast_channel *chan, enum ast_format_id id)
05128 {
05129 struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
05130 struct ast_format tmp_format;
05131 int res;
05132 if (!cap) {
05133 return -1;
05134 }
05135 ast_format_cap_add(cap, ast_format_set(&tmp_format, id, 0));
05136
05137 res = set_format(chan,
05138 cap,
05139 &chan->rawwriteformat,
05140 &chan->writeformat,
05141 &chan->writetrans,
05142 1);
05143
05144 ast_format_cap_destroy(cap);
05145 return res;
05146 }
05147
05148 int ast_set_write_format_from_cap(struct ast_channel *chan, struct ast_format_cap *cap)
05149 {
05150 return set_format(chan,
05151 cap,
05152 &chan->rawwriteformat,
05153 &chan->writeformat,
05154 &chan->writetrans,
05155 1);
05156 }
05157
05158 const char *ast_channel_reason2str(int reason)
05159 {
05160 switch (reason)
05161 {
05162 case 0:
05163 return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)";
05164 case AST_CONTROL_HANGUP:
05165 return "Hangup";
05166 case AST_CONTROL_RING:
05167 return "Local Ring";
05168 case AST_CONTROL_RINGING:
05169 return "Remote end Ringing";
05170 case AST_CONTROL_ANSWER:
05171 return "Remote end has Answered";
05172 case AST_CONTROL_BUSY:
05173 return "Remote end is Busy";
05174 case AST_CONTROL_CONGESTION:
05175 return "Congestion (circuits busy)";
05176 default:
05177 return "Unknown Reason!!";
05178 }
05179 }
05180
05181 static void handle_cause(int cause, int *outstate)
05182 {
05183 if (outstate) {
05184
05185 if (cause == AST_CAUSE_BUSY)
05186 *outstate = AST_CONTROL_BUSY;
05187 else if (cause == AST_CAUSE_CONGESTION)
05188 *outstate = AST_CONTROL_CONGESTION;
05189 else
05190 *outstate = 0;
05191 }
05192 }
05193
05194
05195
05196
05197
05198
05199
05200
05201
05202
05203
05204 static void call_forward_inherit(struct ast_channel *new_chan, struct ast_channel *parent, struct ast_channel *orig)
05205 {
05206 if (!ast_test_flag(parent, AST_FLAG_ZOMBIE) && !ast_check_hangup(parent)) {
05207 struct ast_party_redirecting redirecting;
05208
05209
05210
05211
05212
05213 ast_party_redirecting_init(&redirecting);
05214 ast_channel_lock(orig);
05215 ast_party_redirecting_copy(&redirecting, &orig->redirecting);
05216 ast_channel_unlock(orig);
05217 if (ast_channel_redirecting_macro(orig, parent, &redirecting, 1, 0)) {
05218 ast_channel_update_redirecting(parent, &redirecting, NULL);
05219 }
05220 ast_party_redirecting_free(&redirecting);
05221 }
05222
05223
05224 ast_channel_lock_both(parent, new_chan);
05225 ast_channel_inherit_variables(parent, new_chan);
05226 ast_channel_datastore_inherit(parent, new_chan);
05227 ast_channel_unlock(new_chan);
05228 ast_channel_unlock(parent);
05229 }
05230
05231 struct ast_channel *ast_call_forward(struct ast_channel *caller, struct ast_channel *orig, int *timeout, struct ast_format_cap *cap, struct outgoing_helper *oh, int *outstate)
05232 {
05233 char tmpchan[256];
05234 struct ast_channel *new_chan = NULL;
05235 char *data, *type;
05236 int cause = 0;
05237 int res;
05238
05239
05240 ast_copy_string(tmpchan, ast_channel_call_forward(orig), sizeof(tmpchan));
05241 if ((data = strchr(tmpchan, '/'))) {
05242 *data++ = '\0';
05243 type = tmpchan;
05244 } else {
05245 const char *forward_context;
05246 ast_channel_lock(orig);
05247 forward_context = pbx_builtin_getvar_helper(orig, "FORWARD_CONTEXT");
05248 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", ast_channel_call_forward(orig), S_OR(forward_context, orig->context));
05249 ast_channel_unlock(orig);
05250 data = tmpchan;
05251 type = "Local";
05252 }
05253 if (!(new_chan = ast_request(type, cap, orig, data, &cause))) {
05254 ast_log(LOG_NOTICE, "Unable to create channel for call forward to '%s/%s' (cause = %d)\n", type, data, cause);
05255 handle_cause(cause, outstate);
05256 ast_hangup(orig);
05257 return NULL;
05258 }
05259
05260
05261 if (oh) {
05262 if (oh->vars) {
05263 ast_set_variables(new_chan, oh->vars);
05264 }
05265 if (oh->parent_channel) {
05266 call_forward_inherit(new_chan, oh->parent_channel, orig);
05267 }
05268 if (oh->account) {
05269 ast_channel_lock(new_chan);
05270 ast_cdr_setaccount(new_chan, oh->account);
05271 ast_channel_unlock(new_chan);
05272 }
05273 } else if (caller) {
05274 call_forward_inherit(new_chan, caller, orig);
05275 }
05276
05277 ast_channel_lock_both(orig, new_chan);
05278 ast_copy_flags(new_chan->cdr, orig->cdr, AST_CDR_FLAG_ORIGINATED);
05279 ast_channel_accountcode_set(new_chan, ast_channel_accountcode(orig));
05280 ast_party_connected_line_copy(&new_chan->connected, &orig->connected);
05281 ast_party_redirecting_copy(&new_chan->redirecting, &orig->redirecting);
05282 ast_channel_unlock(new_chan);
05283 ast_channel_unlock(orig);
05284
05285
05286 res = ast_call(new_chan, data, 0);
05287 if (timeout) {
05288 *timeout = res;
05289 }
05290 if (res) {
05291 ast_log(LOG_NOTICE, "Unable to call forward to channel %s/%s\n", type, (char *)data);
05292 ast_hangup(orig);
05293 ast_hangup(new_chan);
05294 return NULL;
05295 }
05296 ast_hangup(orig);
05297
05298 return new_chan;
05299 }
05300
05301 struct ast_channel *__ast_request_and_dial(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *addr, int timeout, int *outstate, const char *cid_num, const char *cid_name, struct outgoing_helper *oh)
05302 {
05303 int dummy_outstate;
05304 int cause = 0;
05305 struct ast_channel *chan;
05306 int res = 0;
05307 int last_subclass = 0;
05308 struct ast_party_connected_line connected;
05309
05310 if (outstate)
05311 *outstate = 0;
05312 else
05313 outstate = &dummy_outstate;
05314
05315 chan = ast_request(type, cap, requestor, addr, &cause);
05316 if (!chan) {
05317 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, addr);
05318 handle_cause(cause, outstate);
05319 return NULL;
05320 }
05321
05322 if (oh) {
05323 if (oh->vars) {
05324 ast_set_variables(chan, oh->vars);
05325 }
05326 if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) {
05327
05328
05329
05330
05331 cid_num = oh->cid_num;
05332 cid_name = oh->cid_name;
05333 }
05334 if (oh->parent_channel) {
05335
05336 ast_channel_lock_both(oh->parent_channel, chan);
05337 ast_channel_inherit_variables(oh->parent_channel, chan);
05338 ast_channel_datastore_inherit(oh->parent_channel, chan);
05339 ast_channel_unlock(oh->parent_channel);
05340 ast_channel_unlock(chan);
05341 }
05342 if (oh->account) {
05343 ast_channel_lock(chan);
05344 ast_cdr_setaccount(chan, oh->account);
05345 ast_channel_unlock(chan);
05346 }
05347 }
05348
05349 ast_set_flag(chan->cdr, AST_CDR_FLAG_ORIGINATED);
05350 ast_party_connected_line_set_init(&connected, &chan->connected);
05351 if (cid_num) {
05352 connected.id.number.valid = 1;
05353 connected.id.number.str = (char *) cid_num;
05354 connected.id.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
05355 }
05356 if (cid_name) {
05357 connected.id.name.valid = 1;
05358 connected.id.name.str = (char *) cid_name;
05359 connected.id.name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
05360 }
05361 ast_channel_set_connected_line(chan, &connected, NULL);
05362
05363 if (ast_call(chan, addr, 0)) {
05364 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, addr);
05365 } else {
05366 res = 1;
05367 while (timeout && chan->_state != AST_STATE_UP) {
05368 struct ast_frame *f;
05369 res = ast_waitfor(chan, timeout);
05370 if (res == 0) {
05371 *outstate = AST_CONTROL_RINGING;
05372 break;
05373 }
05374 if (res < 0)
05375 break;
05376 if (timeout > -1)
05377 timeout = res;
05378 if (!ast_strlen_zero(ast_channel_call_forward(chan))) {
05379 if (!(chan = ast_call_forward(NULL, chan, NULL, cap, oh, outstate))) {
05380 return NULL;
05381 }
05382 continue;
05383 }
05384
05385 f = ast_read(chan);
05386 if (!f) {
05387 *outstate = AST_CONTROL_HANGUP;
05388 res = 0;
05389 break;
05390 }
05391 if (f->frametype == AST_FRAME_CONTROL) {
05392 switch (f->subclass.integer) {
05393 case AST_CONTROL_RINGING:
05394 *outstate = f->subclass.integer;
05395 break;
05396
05397 case AST_CONTROL_BUSY:
05398 ast_cdr_busy(chan->cdr);
05399 *outstate = f->subclass.integer;
05400 timeout = 0;
05401 break;
05402
05403 case AST_CONTROL_INCOMPLETE:
05404 ast_cdr_failed(chan->cdr);
05405 *outstate = AST_CONTROL_CONGESTION;
05406 timeout = 0;
05407 break;
05408
05409 case AST_CONTROL_CONGESTION:
05410 ast_cdr_failed(chan->cdr);
05411 *outstate = f->subclass.integer;
05412 timeout = 0;
05413 break;
05414
05415 case AST_CONTROL_ANSWER:
05416 ast_cdr_answer(chan->cdr);
05417 *outstate = f->subclass.integer;
05418 timeout = 0;
05419 break;
05420
05421
05422 case AST_CONTROL_PROGRESS:
05423 case AST_CONTROL_PROCEEDING:
05424 case AST_CONTROL_HOLD:
05425 case AST_CONTROL_UNHOLD:
05426 case AST_CONTROL_VIDUPDATE:
05427 case AST_CONTROL_SRCUPDATE:
05428 case AST_CONTROL_SRCCHANGE:
05429 case AST_CONTROL_CONNECTED_LINE:
05430 case AST_CONTROL_REDIRECTING:
05431 case AST_CONTROL_CC:
05432 case -1:
05433 break;
05434
05435 default:
05436 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass.integer);
05437 }
05438 last_subclass = f->subclass.integer;
05439 }
05440 ast_frfree(f);
05441 }
05442 }
05443
05444
05445 if (oh) {
05446 if (!ast_strlen_zero(oh->context))
05447 ast_copy_string(chan->context, oh->context, sizeof(chan->context));
05448 if (!ast_strlen_zero(oh->exten))
05449 ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten));
05450 if (oh->priority)
05451 chan->priority = oh->priority;
05452 }
05453 if (chan->_state == AST_STATE_UP)
05454 *outstate = AST_CONTROL_ANSWER;
05455
05456 if (res <= 0) {
05457 ast_channel_lock(chan);
05458 if (AST_CONTROL_RINGING == last_subclass) {
05459 chan->hangupcause = AST_CAUSE_NO_ANSWER;
05460 }
05461 if (!chan->cdr && (chan->cdr = ast_cdr_alloc())) {
05462 ast_cdr_init(chan->cdr, chan);
05463 }
05464 if (chan->cdr) {
05465 char tmp[256];
05466
05467 snprintf(tmp, sizeof(tmp), "%s/%s", type, addr);
05468 ast_cdr_setapp(chan->cdr, "Dial", tmp);
05469 ast_cdr_update(chan);
05470 ast_cdr_start(chan->cdr);
05471 ast_cdr_end(chan->cdr);
05472
05473 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) {
05474 ast_cdr_failed(chan->cdr);
05475 }
05476 }
05477 ast_channel_unlock(chan);
05478 ast_hangup(chan);
05479 chan = NULL;
05480 }
05481 return chan;
05482 }
05483
05484 struct ast_channel *ast_request_and_dial(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *addr, int timeout, int *outstate, const char *cidnum, const char *cidname)
05485 {
05486 return __ast_request_and_dial(type, cap, requestor, addr, timeout, outstate, cidnum, cidname, NULL);
05487 }
05488
05489 static int set_security_requirements(const struct ast_channel *requestor, struct ast_channel *out)
05490 {
05491 int ops[2][2] = {
05492 {AST_OPTION_SECURE_SIGNALING, 0},
05493 {AST_OPTION_SECURE_MEDIA, 0},
05494 };
05495 int i;
05496 struct ast_channel *r = (struct ast_channel *) requestor;
05497 struct ast_datastore *ds;
05498
05499 if (!requestor || !out) {
05500 return 0;
05501 }
05502
05503 ast_channel_lock(r);
05504 if ((ds = ast_channel_datastore_find(r, &secure_call_info, NULL))) {
05505 struct ast_secure_call_store *encrypt = ds->data;
05506 ops[0][1] = encrypt->signaling;
05507 ops[1][1] = encrypt->media;
05508 } else {
05509 ast_channel_unlock(r);
05510 return 0;
05511 }
05512 ast_channel_unlock(r);
05513
05514 for (i = 0; i < 2; i++) {
05515 if (ops[i][1]) {
05516 if (ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0)) {
05517
05518 return -1;
05519 }
05520 } else {
05521
05522 ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0);
05523 }
05524 }
05525
05526 return 0;
05527 }
05528
05529 struct ast_channel *ast_request(const char *type, struct ast_format_cap *request_cap, const struct ast_channel *requestor, const char *addr, int *cause)
05530 {
05531 struct chanlist *chan;
05532 struct ast_channel *c;
05533 int res;
05534 int foo;
05535
05536 if (!cause)
05537 cause = &foo;
05538 *cause = AST_CAUSE_NOTDEFINED;
05539
05540 if (AST_RWLIST_RDLOCK(&backends)) {
05541 ast_log(LOG_WARNING, "Unable to lock technology backend list\n");
05542 return NULL;
05543 }
05544
05545 AST_RWLIST_TRAVERSE(&backends, chan, list) {
05546 struct ast_format_cap *tmp_cap;
05547 struct ast_format tmp_fmt;
05548 struct ast_format best_audio_fmt;
05549 struct ast_format_cap *joint_cap;
05550
05551 if (strcasecmp(type, chan->tech->type))
05552 continue;
05553
05554 ast_format_clear(&best_audio_fmt);
05555
05556 if ((tmp_cap = ast_format_cap_get_type(request_cap, AST_FORMAT_TYPE_AUDIO))) {
05557
05558
05559
05560 res = ast_translator_best_choice(tmp_cap, chan->tech->capabilities, &tmp_fmt, &best_audio_fmt);
05561 ast_format_cap_destroy(tmp_cap);
05562 if (res < 0) {
05563 char tmp1[256], tmp2[256];
05564 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %s) to %s\n", type,
05565 ast_getformatname_multiple(tmp1, sizeof(tmp1), chan->tech->capabilities),
05566 ast_getformatname_multiple(tmp2, sizeof(tmp2), request_cap));
05567 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05568 AST_RWLIST_UNLOCK(&backends);
05569 return NULL;
05570 }
05571 }
05572 AST_RWLIST_UNLOCK(&backends);
05573 if (!chan->tech->requester)
05574 return NULL;
05575
05576
05577
05578
05579
05580 if (!(joint_cap = ast_format_cap_dup(request_cap))) {
05581 return NULL;
05582 }
05583 ast_format_cap_remove_bytype(joint_cap, AST_FORMAT_TYPE_AUDIO);
05584 ast_format_cap_add(joint_cap, &best_audio_fmt);
05585
05586 if (!(c = chan->tech->requester(type, joint_cap, requestor, addr, cause))) {
05587 ast_format_cap_destroy(joint_cap);
05588 return NULL;
05589 }
05590 joint_cap = ast_format_cap_destroy(joint_cap);
05591
05592 if (set_security_requirements(requestor, c)) {
05593 ast_log(LOG_WARNING, "Setting security requirements failed\n");
05594 c = ast_channel_release(c);
05595 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05596 return NULL;
05597 }
05598
05599
05600 return c;
05601 }
05602
05603 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
05604 *cause = AST_CAUSE_NOSUCHDRIVER;
05605 AST_RWLIST_UNLOCK(&backends);
05606
05607 return NULL;
05608 }
05609
05610 int ast_call(struct ast_channel *chan, const char *addr, int timeout)
05611 {
05612
05613
05614
05615 int res = -1;
05616
05617 ast_channel_lock(chan);
05618 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
05619 if (chan->cdr) {
05620 ast_set_flag(chan->cdr, AST_CDR_FLAG_DIALED);
05621 }
05622 if (chan->tech->call)
05623 res = chan->tech->call(chan, addr, timeout);
05624 ast_set_flag(chan, AST_FLAG_OUTGOING);
05625 }
05626 ast_channel_unlock(chan);
05627 return res;
05628 }
05629
05630
05631
05632
05633
05634
05635
05636
05637 int ast_transfer(struct ast_channel *chan, char *dest)
05638 {
05639 int res = -1;
05640
05641
05642 ast_channel_lock(chan);
05643 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
05644 if (chan->tech->transfer) {
05645 res = chan->tech->transfer(chan, dest);
05646 if (!res)
05647 res = 1;
05648 } else
05649 res = 0;
05650 }
05651 ast_channel_unlock(chan);
05652
05653 if (res <= 0) {
05654 return res;
05655 }
05656
05657 for (;;) {
05658 struct ast_frame *fr;
05659
05660 res = ast_waitfor(chan, -1);
05661
05662 if (res < 0 || !(fr = ast_read(chan))) {
05663 res = -1;
05664 break;
05665 }
05666
05667 if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_TRANSFER) {
05668 enum ast_control_transfer *message = fr->data.ptr;
05669
05670 if (*message == AST_TRANSFER_SUCCESS) {
05671 res = 1;
05672 } else {
05673 res = -1;
05674 }
05675
05676 ast_frfree(fr);
05677 break;
05678 }
05679
05680 ast_frfree(fr);
05681 }
05682
05683 return res;
05684 }
05685
05686 int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders)
05687 {
05688 return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1);
05689 }
05690
05691 int ast_readstring_full(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders, int audiofd, int ctrlfd)
05692 {
05693 int pos = 0;
05694 int to = ftimeout;
05695
05696 struct ast_silence_generator *silgen = NULL;
05697
05698
05699 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
05700 return -1;
05701 if (!len)
05702 return -1;
05703 for (;;) {
05704 int d;
05705 if (c->stream) {
05706 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
05707 ast_stopstream(c);
05708 if (!silgen && ast_opt_transmit_silence)
05709 silgen = ast_channel_start_silence_generator(c);
05710 usleep(1000);
05711 if (!d)
05712 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
05713 } else {
05714 if (!silgen && ast_opt_transmit_silence)
05715 silgen = ast_channel_start_silence_generator(c);
05716 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
05717 }
05718 if (d < 0) {
05719 ast_channel_stop_silence_generator(c, silgen);
05720 return AST_GETDATA_FAILED;
05721 }
05722 if (d == 0) {
05723 s[pos] = '\0';
05724 ast_channel_stop_silence_generator(c, silgen);
05725 return AST_GETDATA_TIMEOUT;
05726 }
05727 if (d == 1) {
05728 s[pos] = '\0';
05729 ast_channel_stop_silence_generator(c, silgen);
05730 return AST_GETDATA_INTERRUPTED;
05731 }
05732 if (strchr(enders, d) && (pos == 0)) {
05733 s[pos] = '\0';
05734 ast_channel_stop_silence_generator(c, silgen);
05735 return AST_GETDATA_EMPTY_END_TERMINATED;
05736 }
05737 if (!strchr(enders, d)) {
05738 s[pos++] = d;
05739 }
05740 if (strchr(enders, d) || (pos >= len)) {
05741 s[pos] = '\0';
05742 ast_channel_stop_silence_generator(c, silgen);
05743 return AST_GETDATA_COMPLETE;
05744 }
05745 to = timeout;
05746 }
05747
05748 return 0;
05749 }
05750
05751 int ast_channel_supports_html(struct ast_channel *chan)
05752 {
05753 return (chan->tech->send_html) ? 1 : 0;
05754 }
05755
05756 int ast_channel_sendhtml(struct ast_channel *chan, int subclass, const char *data, int datalen)
05757 {
05758 if (chan->tech->send_html)
05759 return chan->tech->send_html(chan, subclass, data, datalen);
05760 return -1;
05761 }
05762
05763 int ast_channel_sendurl(struct ast_channel *chan, const char *url)
05764 {
05765 return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1);
05766 }
05767
05768
05769 static int ast_channel_make_compatible_helper(struct ast_channel *from, struct ast_channel *to)
05770 {
05771 struct ast_format_cap *src_cap = from->nativeformats;
05772 struct ast_format_cap *dst_cap = to->nativeformats;
05773 struct ast_format best_src_fmt;
05774 struct ast_format best_dst_fmt;
05775 int use_slin;
05776
05777
05778 if (from->tech->bridge && from->tech->bridge == to->tech->bridge &&
05779 !ast_channel_setoption(from, AST_OPTION_MAKE_COMPATIBLE, to, sizeof(struct ast_channel *), 0)) {
05780 return 0;
05781 }
05782
05783 if ((ast_format_cmp(&from->readformat, &to->writeformat) != AST_FORMAT_CMP_NOT_EQUAL) &&
05784 (ast_format_cmp(&to->readformat, &from->writeformat) != AST_FORMAT_CMP_NOT_EQUAL)) {
05785
05786 return 0;
05787 }
05788
05789
05790 if (!ast_format_cap_has_type(src_cap, AST_FORMAT_TYPE_AUDIO) || !ast_format_cap_has_type(dst_cap, AST_FORMAT_TYPE_AUDIO))
05791 return 0;
05792
05793 if (ast_translator_best_choice(dst_cap, src_cap, &best_src_fmt, &best_dst_fmt) < 0) {
05794 ast_log(LOG_WARNING, "No path to translate from %s to %s\n", ast_channel_name(from), ast_channel_name(to));
05795 return -1;
05796 }
05797
05798
05799
05800
05801
05802
05803
05804 use_slin = ast_format_is_slinear(&best_src_fmt) || ast_format_is_slinear(&best_dst_fmt) ? 1 : 0;
05805 if ((ast_format_cmp(&best_src_fmt, &best_dst_fmt) == AST_FORMAT_CMP_NOT_EQUAL) &&
05806 (ast_opt_generic_plc || ast_opt_transcode_via_slin) &&
05807 (ast_translate_path_steps(&best_dst_fmt, &best_src_fmt) != 1 || use_slin)) {
05808
05809 int best_sample_rate = ast_format_rate(&best_src_fmt) > ast_format_rate(&best_dst_fmt) ?
05810 ast_format_rate(&best_src_fmt) : ast_format_rate(&best_dst_fmt);
05811
05812
05813 ast_format_set(&best_dst_fmt, ast_format_slin_by_rate(best_sample_rate), 0);
05814 }
05815
05816 if (ast_set_read_format(from, &best_dst_fmt) < 0) {
05817 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %s\n", ast_channel_name(from), ast_getformatname(&best_dst_fmt));
05818 return -1;
05819 }
05820 if (ast_set_write_format(to, &best_dst_fmt) < 0) {
05821 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %s\n", ast_channel_name(to), ast_getformatname(&best_dst_fmt));
05822 return -1;
05823 }
05824 return 0;
05825 }
05826
05827 int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
05828 {
05829
05830 int rc = 0;
05831
05832
05833 rc = ast_channel_make_compatible_helper(chan, peer);
05834
05835 if (rc < 0)
05836 return rc;
05837
05838
05839 rc = ast_channel_make_compatible_helper(peer, chan);
05840
05841 return rc;
05842 }
05843
05844 static int __ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clonechan, struct ast_datastore *xfer_ds)
05845 {
05846 int res = -1;
05847 struct ast_channel *final_orig, *final_clone, *base;
05848
05849 for (;;) {
05850 final_orig = original;
05851 final_clone = clonechan;
05852
05853 ast_channel_lock_both(original, clonechan);
05854
05855 if (ast_test_flag(original, AST_FLAG_ZOMBIE)
05856 || ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) {
05857
05858 ast_log(LOG_WARNING,
05859 "Can't setup masquerade. One or both channels is dead. (%s <-- %s)\n",
05860 ast_channel_name(original), ast_channel_name(clonechan));
05861 ast_channel_unlock(clonechan);
05862 ast_channel_unlock(original);
05863 return -1;
05864 }
05865
05866
05867
05868
05869
05870
05871 if (original->_bridge
05872 && (original->_bridge != ast_bridged_channel(original))
05873 && (original->_bridge->_bridge != original)) {
05874 final_orig = original->_bridge;
05875 }
05876 if (clonechan->_bridge
05877 && (clonechan->_bridge != ast_bridged_channel(clonechan))
05878 && (clonechan->_bridge->_bridge != clonechan)) {
05879 final_clone = clonechan->_bridge;
05880 }
05881 if (final_clone->tech->get_base_channel
05882 && (base = final_clone->tech->get_base_channel(final_clone))) {
05883 final_clone = base;
05884 }
05885
05886 if ((final_orig != original) || (final_clone != clonechan)) {
05887
05888
05889
05890
05891
05892 if (ast_channel_trylock(final_orig)) {
05893 ast_channel_unlock(clonechan);
05894 ast_channel_unlock(original);
05895
05896
05897 continue;
05898 }
05899 if (ast_channel_trylock(final_clone)) {
05900 ast_channel_unlock(final_orig);
05901 ast_channel_unlock(clonechan);
05902 ast_channel_unlock(original);
05903
05904
05905 continue;
05906 }
05907 ast_channel_unlock(clonechan);
05908 ast_channel_unlock(original);
05909 original = final_orig;
05910 clonechan = final_clone;
05911
05912 if (ast_test_flag(original, AST_FLAG_ZOMBIE)
05913 || ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) {
05914
05915 ast_log(LOG_WARNING,
05916 "Can't setup masquerade. One or both channels is dead. (%s <-- %s)\n",
05917 ast_channel_name(original), ast_channel_name(clonechan));
05918 ast_channel_unlock(clonechan);
05919 ast_channel_unlock(original);
05920 return -1;
05921 }
05922 }
05923 break;
05924 }
05925
05926 if (original == clonechan) {
05927 ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", ast_channel_name(original));
05928 ast_channel_unlock(clonechan);
05929 ast_channel_unlock(original);
05930 return -1;
05931 }
05932
05933 ast_debug(1, "Planning to masquerade channel %s into the structure of %s\n",
05934 ast_channel_name(clonechan), ast_channel_name(original));
05935
05936 if (!original->masqr && !original->masq && !clonechan->masq && !clonechan->masqr) {
05937 original->masq = clonechan;
05938 clonechan->masqr = original;
05939 if (xfer_ds) {
05940 ast_channel_datastore_add(original, xfer_ds);
05941 }
05942 ast_queue_frame(original, &ast_null_frame);
05943 ast_queue_frame(clonechan, &ast_null_frame);
05944 ast_debug(1, "Done planning to masquerade channel %s into the structure of %s\n", ast_channel_name(clonechan), ast_channel_name(original));
05945 res = 0;
05946 } else if (original->masq) {
05947 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
05948 ast_channel_name(original->masq), ast_channel_name(original));
05949 } else if (original->masqr) {
05950
05951 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
05952 ast_channel_name(original), ast_channel_name(original->masqr));
05953 } else if (clonechan->masq) {
05954 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
05955 ast_channel_name(clonechan->masq), ast_channel_name(clonechan));
05956 } else {
05957 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
05958 ast_channel_name(clonechan), ast_channel_name(clonechan->masqr));
05959 }
05960
05961 ast_channel_unlock(clonechan);
05962 ast_channel_unlock(original);
05963
05964 return res;
05965 }
05966
05967 int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone)
05968 {
05969 return __ast_channel_masquerade(original, clone, NULL);
05970 }
05971
05972
05973
05974
05975
05976
05977
05978
05979
05980
05981
05982 static void party_connected_line_copy_transfer(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src)
05983 {
05984 struct ast_party_connected_line connected;
05985
05986 connected = *((struct ast_party_connected_line *) src);
05987 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
05988
05989
05990 if (!connected.id.name.str) {
05991 connected.id.name.str = "";
05992 }
05993 if (!connected.id.number.str) {
05994 connected.id.number.str = "";
05995 }
05996 if (!connected.id.subaddress.str) {
05997 connected.id.subaddress.str = "";
05998 }
05999 if (!connected.id.tag) {
06000 connected.id.tag = "";
06001 }
06002
06003 ast_party_connected_line_copy(dest, &connected);
06004 }
06005
06006
06007 struct xfer_masquerade_ds {
06008
06009 struct ast_party_connected_line target_id;
06010
06011 struct ast_party_connected_line transferee_id;
06012
06013 int target_held;
06014
06015 int transferee_held;
06016 };
06017
06018
06019
06020
06021
06022
06023
06024
06025
06026
06027 static void xfer_ds_destroy(void *data)
06028 {
06029 struct xfer_masquerade_ds *ds = data;
06030
06031 ast_party_connected_line_free(&ds->target_id);
06032 ast_party_connected_line_free(&ds->transferee_id);
06033 ast_free(ds);
06034 }
06035
06036 static const struct ast_datastore_info xfer_ds_info = {
06037 .type = "xfer_colp",
06038 .destroy = xfer_ds_destroy,
06039 };
06040
06041 int ast_channel_transfer_masquerade(
06042 struct ast_channel *target_chan,
06043 const struct ast_party_connected_line *target_id,
06044 int target_held,
06045 struct ast_channel *transferee_chan,
06046 const struct ast_party_connected_line *transferee_id,
06047 int transferee_held)
06048 {
06049 struct ast_datastore *xfer_ds;
06050 struct xfer_masquerade_ds *xfer_colp;
06051 int res;
06052
06053 xfer_ds = ast_datastore_alloc(&xfer_ds_info, NULL);
06054 if (!xfer_ds) {
06055 return -1;
06056 }
06057
06058 xfer_colp = ast_calloc(1, sizeof(*xfer_colp));
06059 if (!xfer_colp) {
06060 ast_datastore_free(xfer_ds);
06061 return -1;
06062 }
06063 party_connected_line_copy_transfer(&xfer_colp->target_id, target_id);
06064 xfer_colp->target_held = target_held;
06065 party_connected_line_copy_transfer(&xfer_colp->transferee_id, transferee_id);
06066 xfer_colp->transferee_held = transferee_held;
06067 xfer_ds->data = xfer_colp;
06068
06069 res = __ast_channel_masquerade(target_chan, transferee_chan, xfer_ds);
06070 if (res) {
06071 ast_datastore_free(xfer_ds);
06072 }
06073 return res;
06074 }
06075
06076
06077
06078
06079
06080 static void __ast_change_name_nolink(struct ast_channel *chan, const char *newname)
06081 {
06082 ast_manager_event(chan, EVENT_FLAG_CALL, "Rename", "Channel: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", ast_channel_name(chan), newname, ast_channel_uniqueid(chan));
06083 ast_channel_name_set(chan, newname);
06084 }
06085
06086 void ast_change_name(struct ast_channel *chan, const char *newname)
06087 {
06088
06089 ao2_unlink(channels, chan);
06090 ast_channel_lock(chan);
06091 __ast_change_name_nolink(chan, newname);
06092 ast_channel_unlock(chan);
06093 ao2_link(channels, chan);
06094 }
06095
06096 void ast_channel_inherit_variables(const struct ast_channel *parent, struct ast_channel *child)
06097 {
06098 struct ast_var_t *current, *newvar;
06099 const char *varname;
06100
06101 AST_LIST_TRAVERSE(&parent->varshead, current, entries) {
06102 int vartype = 0;
06103
06104 varname = ast_var_full_name(current);
06105 if (!varname)
06106 continue;
06107
06108 if (varname[0] == '_') {
06109 vartype = 1;
06110 if (varname[1] == '_')
06111 vartype = 2;
06112 }
06113
06114 switch (vartype) {
06115 case 1:
06116 newvar = ast_var_assign(&varname[1], ast_var_value(current));
06117 if (newvar) {
06118 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
06119 ast_debug(1, "Copying soft-transferable variable %s.\n", ast_var_name(newvar));
06120 }
06121 break;
06122 case 2:
06123 newvar = ast_var_assign(varname, ast_var_value(current));
06124 if (newvar) {
06125 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
06126 ast_debug(1, "Copying hard-transferable variable %s.\n", ast_var_name(newvar));
06127 }
06128 break;
06129 default:
06130 ast_debug(1, "Not copying variable %s.\n", ast_var_name(current));
06131 break;
06132 }
06133 }
06134 }
06135
06136
06137
06138
06139
06140
06141
06142
06143
06144
06145 static void clone_variables(struct ast_channel *original, struct ast_channel *clonechan)
06146 {
06147 struct ast_var_t *current, *newvar;
06148
06149
06150 if (AST_LIST_FIRST(&clonechan->varshead))
06151 AST_LIST_APPEND_LIST(&original->varshead, &clonechan->varshead, entries);
06152
06153
06154
06155 AST_LIST_TRAVERSE(&original->varshead, current, entries) {
06156 newvar = ast_var_assign(current->name, current->value);
06157 if (newvar)
06158 AST_LIST_INSERT_TAIL(&clonechan->varshead, newvar, entries);
06159 }
06160 }
06161
06162
06163
06164
06165
06166
06167
06168
06169
06170
06171
06172
06173
06174
06175 static const char *oldest_linkedid(const char *a, const char *b)
06176 {
06177 const char *satime, *saseq;
06178 const char *sbtime, *sbseq;
06179 const char *dash;
06180
06181 unsigned int atime, aseq, btime, bseq;
06182
06183 if (ast_strlen_zero(a))
06184 return b;
06185
06186 if (ast_strlen_zero(b))
06187 return a;
06188
06189 satime = a;
06190 sbtime = b;
06191
06192
06193 if ((dash = strrchr(satime, '-'))) {
06194 satime = dash+1;
06195 }
06196 if ((dash = strrchr(sbtime, '-'))) {
06197 sbtime = dash+1;
06198 }
06199
06200
06201 saseq = strchr(satime, '.');
06202 sbseq = strchr(sbtime, '.');
06203 if (!saseq || !sbseq)
06204 return NULL;
06205 saseq++;
06206 sbseq++;
06207
06208
06209 atime = atoi(satime);
06210 btime = atoi(sbtime);
06211 aseq = atoi(saseq);
06212 bseq = atoi(sbseq);
06213
06214
06215 if (atime == btime) {
06216 return (aseq < bseq) ? a : b;
06217 }
06218 else {
06219 return (atime < btime) ? a : b;
06220 }
06221 }
06222
06223
06224
06225 static void ast_channel_change_linkedid(struct ast_channel *chan, const char *linkedid)
06226 {
06227
06228 if (!ast_strlen_zero(ast_channel_linkedid(chan)) && 0 != strcmp(ast_channel_linkedid(chan), linkedid)) {
06229 ast_cel_check_retire_linkedid(chan);
06230 }
06231
06232 ast_channel_linkedid_set(chan, linkedid);
06233 }
06234
06235
06236
06237
06238
06239
06240 void ast_channel_set_linkgroup(struct ast_channel *chan, struct ast_channel *peer)
06241 {
06242 const char* linkedid=NULL;
06243 struct ast_channel *bridged;
06244
06245 linkedid = oldest_linkedid(ast_channel_linkedid(chan), ast_channel_linkedid(peer));
06246 linkedid = oldest_linkedid(linkedid, ast_channel_uniqueid(chan));
06247 linkedid = oldest_linkedid(linkedid, ast_channel_uniqueid(peer));
06248 if (chan->_bridge) {
06249 bridged = ast_bridged_channel(chan);
06250 if (bridged != peer) {
06251 linkedid = oldest_linkedid(linkedid, ast_channel_linkedid(bridged));
06252 linkedid = oldest_linkedid(linkedid, ast_channel_uniqueid(bridged));
06253 }
06254 }
06255 if (peer->_bridge) {
06256 bridged = ast_bridged_channel(peer);
06257 if (bridged != chan) {
06258 linkedid = oldest_linkedid(linkedid, ast_channel_linkedid(bridged));
06259 linkedid = oldest_linkedid(linkedid, ast_channel_uniqueid(bridged));
06260 }
06261 }
06262
06263
06264 linkedid = ast_strdupa(linkedid);
06265
06266 ast_channel_change_linkedid(chan, linkedid);
06267 ast_channel_change_linkedid(peer, linkedid);
06268 if (chan->_bridge) {
06269 bridged = ast_bridged_channel(chan);
06270 if (bridged != peer) {
06271 ast_channel_change_linkedid(bridged, linkedid);
06272 }
06273 }
06274 if (peer->_bridge) {
06275 bridged = ast_bridged_channel(peer);
06276 if (bridged != chan) {
06277 ast_channel_change_linkedid(bridged, linkedid);
06278 }
06279 }
06280 }
06281
06282
06283 static void ast_set_owners_and_peers(struct ast_channel *chan1,
06284 struct ast_channel *chan2)
06285 {
06286 if (!ast_strlen_zero(ast_channel_accountcode(chan1)) && ast_strlen_zero(ast_channel_peeraccount(chan2))) {
06287 ast_debug(1, "setting peeraccount to %s for %s from data on channel %s\n",
06288 ast_channel_accountcode(chan1), ast_channel_name(chan2), ast_channel_name(chan1));
06289 ast_channel_peeraccount_set(chan2, ast_channel_accountcode(chan1));
06290 }
06291 if (!ast_strlen_zero(ast_channel_accountcode(chan2)) && ast_strlen_zero(ast_channel_peeraccount(chan1))) {
06292 ast_debug(1, "setting peeraccount to %s for %s from data on channel %s\n",
06293 ast_channel_accountcode(chan2), ast_channel_name(chan1), ast_channel_name(chan2));
06294 ast_channel_peeraccount_set(chan1, ast_channel_accountcode(chan2));
06295 }
06296 if (!ast_strlen_zero(ast_channel_peeraccount(chan1)) && ast_strlen_zero(ast_channel_accountcode(chan2))) {
06297 ast_debug(1, "setting accountcode to %s for %s from data on channel %s\n",
06298 ast_channel_peeraccount(chan1), ast_channel_name(chan2), ast_channel_name(chan1));
06299 ast_channel_accountcode_set(chan2, ast_channel_peeraccount(chan1));
06300 }
06301 if (!ast_strlen_zero(ast_channel_peeraccount(chan2)) && ast_strlen_zero(ast_channel_accountcode(chan1))) {
06302 ast_debug(1, "setting accountcode to %s for %s from data on channel %s\n",
06303 ast_channel_peeraccount(chan2), ast_channel_name(chan1), ast_channel_name(chan2));
06304 ast_channel_accountcode_set(chan1, ast_channel_peeraccount(chan2));
06305 }
06306 if (0 != strcmp(ast_channel_accountcode(chan1), ast_channel_peeraccount(chan2))) {
06307 ast_debug(1, "changing peeraccount from %s to %s on %s to match channel %s\n",
06308 ast_channel_peeraccount(chan2), ast_channel_peeraccount(chan1), ast_channel_name(chan2), ast_channel_name(chan1));
06309 ast_channel_peeraccount_set(chan2, ast_channel_accountcode(chan1));
06310 }
06311 if (0 != strcmp(ast_channel_accountcode(chan2), ast_channel_peeraccount(chan1))) {
06312 ast_debug(1, "changing peeraccount from %s to %s on %s to match channel %s\n",
06313 ast_channel_peeraccount(chan1), ast_channel_peeraccount(chan2), ast_channel_name(chan1), ast_channel_name(chan2));
06314 ast_channel_peeraccount_set(chan1, ast_channel_accountcode(chan2));
06315 }
06316 }
06317
06318
06319
06320
06321 static void report_new_callerid(struct ast_channel *chan)
06322 {
06323 int pres;
06324
06325 pres = ast_party_id_presentation(&chan->caller.id);
06326 ast_manager_event(chan, EVENT_FLAG_CALL, "NewCallerid",
06327 "Channel: %s\r\n"
06328 "CallerIDNum: %s\r\n"
06329 "CallerIDName: %s\r\n"
06330 "Uniqueid: %s\r\n"
06331 "CID-CallingPres: %d (%s)\r\n",
06332 ast_channel_name(chan),
06333 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
06334 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""),
06335 ast_channel_uniqueid(chan),
06336 pres,
06337 ast_describe_caller_presentation(pres)
06338 );
06339 }
06340
06341
06342
06343
06344
06345
06346
06347
06348
06349
06350
06351 static void masquerade_colp_transfer(struct ast_channel *transferee, struct xfer_masquerade_ds *colp)
06352 {
06353 struct ast_control_read_action_payload *frame_payload;
06354 int payload_size;
06355 int frame_size;
06356 unsigned char connected_line_data[1024];
06357
06358
06359 if (colp->target_held) {
06360 ast_queue_control(transferee, AST_CONTROL_UNHOLD);
06361 }
06362
06363
06364
06365
06366
06367
06368
06369
06370
06371
06372 payload_size = ast_connected_line_build_data(connected_line_data,
06373 sizeof(connected_line_data), &colp->target_id, NULL);
06374 if (payload_size != -1) {
06375 frame_size = payload_size + sizeof(*frame_payload);
06376 frame_payload = alloca(frame_size);
06377 frame_payload->action = AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO;
06378 frame_payload->payload_size = payload_size;
06379 memcpy(frame_payload->payload, connected_line_data, payload_size);
06380 ast_queue_control_data(transferee, AST_CONTROL_READ_ACTION, frame_payload,
06381 frame_size);
06382 }
06383
06384
06385
06386
06387
06388
06389 ast_channel_queue_connected_line_update(transferee, &colp->transferee_id, NULL);
06390 }
06391
06392
06393
06394
06395
06396
06397
06398
06399 int ast_do_masquerade(struct ast_channel *original)
06400 {
06401 int x, i;
06402 int res=0;
06403 int origstate;
06404 int visible_indication;
06405 struct ast_frame *current;
06406 const struct ast_channel_tech *t;
06407 void *t_pvt;
06408 union {
06409 struct ast_party_dialed dialed;
06410 struct ast_party_caller caller;
06411 struct ast_party_connected_line connected;
06412 struct ast_party_redirecting redirecting;
06413 } exchange;
06414 struct ast_channel *clonechan, *chans[2];
06415 struct ast_channel *bridged;
06416 struct ast_cdr *cdr;
06417 struct ast_datastore *xfer_ds;
06418 struct xfer_masquerade_ds *xfer_colp;
06419 struct ast_format rformat;
06420 struct ast_format wformat;
06421 struct ast_format tmp_format;
06422 char newn[AST_CHANNEL_NAME];
06423 char orig[AST_CHANNEL_NAME];
06424 char masqn[AST_CHANNEL_NAME];
06425 char zombn[AST_CHANNEL_NAME];
06426
06427 ast_format_copy(&rformat, &original->readformat);
06428 ast_format_copy(&wformat, &original->writeformat);
06429
06430
06431
06432
06433
06434
06435
06436
06437
06438
06439
06440
06441
06442
06443
06444 ao2_lock(channels);
06445
06446
06447 ast_channel_lock(original);
06448
06449
06450
06451
06452
06453
06454
06455
06456
06457
06458 while ((clonechan = original->masq) && ast_channel_trylock(clonechan)) {
06459
06460
06461
06462
06463
06464
06465
06466
06467 CHANNEL_DEADLOCK_AVOIDANCE(original);
06468 }
06469
06470
06471
06472
06473
06474
06475 if (!clonechan) {
06476
06477 ast_channel_unlock(original);
06478 ao2_unlock(channels);
06479 return 0;
06480 }
06481
06482
06483 xfer_ds = ast_channel_datastore_find(original, &xfer_ds_info, NULL);
06484 if (xfer_ds) {
06485 ast_channel_datastore_remove(original, xfer_ds);
06486 xfer_colp = xfer_ds->data;
06487 } else {
06488 xfer_colp = NULL;
06489 }
06490
06491
06492
06493
06494
06495 if (xfer_colp && xfer_colp->transferee_held) {
06496 ast_indicate(clonechan, AST_CONTROL_UNHOLD);
06497 }
06498
06499
06500 original->masq = NULL;
06501 clonechan->masqr = NULL;
06502
06503
06504 ao2_unlink(channels, original);
06505 ao2_unlink(channels, clonechan);
06506
06507 ast_debug(4, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",
06508 ast_channel_name(clonechan), clonechan->_state, ast_channel_name(original), original->_state);
06509
06510
06511
06512
06513
06514 visible_indication = original->visible_indication;
06515 ast_indicate(original, -1);
06516
06517 chans[0] = clonechan;
06518 chans[1] = original;
06519 ast_manager_event_multichan(EVENT_FLAG_CALL, "Masquerade", 2, chans,
06520 "Clone: %s\r\n"
06521 "CloneState: %s\r\n"
06522 "Original: %s\r\n"
06523 "OriginalState: %s\r\n",
06524 ast_channel_name(clonechan), ast_state2str(clonechan->_state), ast_channel_name(original), ast_state2str(original->_state));
06525
06526
06527
06528 free_translation(clonechan);
06529 free_translation(original);
06530
06531
06532 ast_copy_string(orig, ast_channel_name(original), sizeof(orig));
06533
06534 ast_copy_string(newn, ast_channel_name(clonechan), sizeof(newn));
06535
06536 snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn);
06537
06538
06539 __ast_change_name_nolink(clonechan, masqn);
06540
06541
06542 __ast_change_name_nolink(original, newn);
06543
06544
06545 ast_channel_set_linkgroup(original, clonechan);
06546
06547
06548 t = original->tech;
06549 original->tech = clonechan->tech;
06550 clonechan->tech = t;
06551
06552
06553 cdr = original->cdr;
06554 original->cdr = clonechan->cdr;
06555 clonechan->cdr = cdr;
06556
06557 t_pvt = original->tech_pvt;
06558 original->tech_pvt = clonechan->tech_pvt;
06559 clonechan->tech_pvt = t_pvt;
06560
06561
06562 for (i = 0; i < 2; i++) {
06563 x = original->alertpipe[i];
06564 original->alertpipe[i] = clonechan->alertpipe[i];
06565 clonechan->alertpipe[i] = x;
06566 }
06567
06568
06569
06570
06571
06572
06573
06574
06575
06576
06577
06578
06579 {
06580 AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq;
06581 AST_LIST_HEAD_SET_NOLOCK(&tmp_readq, NULL);
06582
06583 AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list);
06584 AST_LIST_APPEND_LIST(&original->readq, &clonechan->readq, frame_list);
06585
06586 while ((current = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) {
06587 AST_LIST_INSERT_TAIL(&original->readq, current, frame_list);
06588 if (original->alertpipe[1] > -1) {
06589 int poke = 0;
06590
06591 if (write(original->alertpipe[1], &poke, sizeof(poke)) < 0) {
06592 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
06593 }
06594 }
06595 }
06596 }
06597
06598
06599 ast_format_copy(&tmp_format, &original->rawreadformat);
06600 ast_format_copy(&original->rawreadformat, &clonechan->rawreadformat);
06601 ast_format_copy(&clonechan->rawreadformat, &tmp_format);
06602
06603 ast_format_copy(&tmp_format, &original->rawwriteformat);
06604 ast_format_copy(&original->rawwriteformat, &clonechan->rawwriteformat);
06605 ast_format_copy(&clonechan->rawwriteformat, &tmp_format);
06606
06607 clonechan->_softhangup = AST_SOFTHANGUP_DEV;
06608
06609
06610
06611
06612
06613 origstate = original->_state;
06614 original->_state = clonechan->_state;
06615 clonechan->_state = origstate;
06616
06617 if (clonechan->tech->fixup && clonechan->tech->fixup(original, clonechan)) {
06618 ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", ast_channel_name(clonechan));
06619 }
06620
06621
06622 if (clonechan->tech->hangup && clonechan->tech->hangup(clonechan)) {
06623 ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n");
06624 res = -1;
06625 goto done;
06626 }
06627
06628
06629
06630
06631
06632 clonechan->tech = &ast_kill_tech;
06633
06634
06635 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig);
06636 __ast_change_name_nolink(clonechan, zombn);
06637
06638
06639 t_pvt = original->monitor;
06640 original->monitor = clonechan->monitor;
06641 clonechan->monitor = t_pvt;
06642
06643
06644 ast_channel_language_set(original, ast_channel_language(clonechan));
06645
06646 for (x = 0; x < AST_MAX_FDS; x++) {
06647 if (x != AST_GENERATOR_FD)
06648 ast_channel_set_fd(original, x, clonechan->fds[x]);
06649 }
06650
06651 ast_app_group_update(clonechan, original);
06652
06653
06654 if (AST_LIST_FIRST(&clonechan->datastores)) {
06655 struct ast_datastore *ds;
06656
06657
06658
06659 AST_LIST_TRAVERSE_SAFE_BEGIN(&clonechan->datastores, ds, entry) {
06660 if (ds->info->chan_fixup)
06661 ds->info->chan_fixup(ds->data, clonechan, original);
06662 }
06663 AST_LIST_TRAVERSE_SAFE_END;
06664 AST_LIST_APPEND_LIST(&original->datastores, &clonechan->datastores, entry);
06665 }
06666
06667 ast_autochan_new_channel(clonechan, original);
06668
06669 clone_variables(original, clonechan);
06670
06671 original->adsicpe = clonechan->adsicpe;
06672
06673
06674
06675
06676
06677 ast_set_flag(original, ast_test_flag(clonechan, AST_FLAG_EXCEPTION | AST_FLAG_OUTGOING));
06678 original->fdno = clonechan->fdno;
06679
06680
06681
06682
06683
06684
06685
06686
06687 exchange.dialed = original->dialed;
06688 original->dialed = clonechan->dialed;
06689 clonechan->dialed = exchange.dialed;
06690
06691 exchange.caller = original->caller;
06692 original->caller = clonechan->caller;
06693 clonechan->caller = exchange.caller;
06694
06695 exchange.connected = original->connected;
06696 original->connected = clonechan->connected;
06697 clonechan->connected = exchange.connected;
06698
06699 exchange.redirecting = original->redirecting;
06700 original->redirecting = clonechan->redirecting;
06701 clonechan->redirecting = exchange.redirecting;
06702
06703 report_new_callerid(original);
06704
06705
06706 ast_channel_set_fd(original, AST_TIMING_FD, original->timingfd);
06707
06708
06709 ast_format_cap_copy(original->nativeformats, clonechan->nativeformats);
06710
06711
06712
06713
06714
06715 ast_set_write_format(original, &wformat);
06716
06717
06718 ast_set_read_format(original, &rformat);
06719
06720
06721 ast_channel_musicclass_set(original, ast_channel_musicclass(clonechan));
06722
06723
06724 ast_channel_accountcode_set(original, S_OR(ast_channel_accountcode(clonechan), ""));
06725 if (original->_bridge) {
06726
06727 ast_channel_peeraccount_set(original->_bridge, S_OR(ast_channel_accountcode(clonechan), ""));
06728 ast_cel_report_event(original, AST_CEL_BRIDGE_UPDATE, NULL, NULL, NULL);
06729 }
06730
06731 ast_debug(1, "Putting channel %s in %s/%s formats\n", ast_channel_name(original),
06732 ast_getformatname(&wformat), ast_getformatname(&rformat));
06733
06734
06735
06736 if (original->tech->fixup) {
06737 if (original->tech->fixup(clonechan, original)) {
06738 ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n",
06739 original->tech->type, ast_channel_name(original));
06740 res = -1;
06741 goto done;
06742 }
06743 } else
06744 ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)! Bad things may happen.\n",
06745 original->tech->type, ast_channel_name(original));
06746
06747
06748
06749
06750
06751
06752
06753
06754
06755 if (visible_indication) {
06756 ast_indicate(original, visible_indication);
06757 }
06758
06759
06760
06761
06762 if (ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) {
06763 ast_debug(1, "Destroying channel clone '%s'\n", ast_channel_name(clonechan));
06764 ast_channel_unlock(clonechan);
06765 ast_manager_event(clonechan, EVENT_FLAG_CALL, "Hangup",
06766 "Channel: %s\r\n"
06767 "Uniqueid: %s\r\n"
06768 "Cause: %d\r\n"
06769 "Cause-txt: %s\r\n",
06770 ast_channel_name(clonechan),
06771 ast_channel_uniqueid(clonechan),
06772 clonechan->hangupcause,
06773 ast_cause2str(clonechan->hangupcause)
06774 );
06775 clonechan = ast_channel_release(clonechan);
06776 } else {
06777 ast_debug(1, "Released clone lock on '%s'\n", ast_channel_name(clonechan));
06778 ast_set_flag(clonechan, AST_FLAG_ZOMBIE);
06779 ast_queue_frame(clonechan, &ast_null_frame);
06780 }
06781
06782
06783 if (ast_test_flag(original, AST_FLAG_BLOCKING))
06784 pthread_kill(original->blocker, SIGURG);
06785 ast_debug(1, "Done Masquerading %s (%d)\n", ast_channel_name(original), original->_state);
06786
06787 if ((bridged = ast_bridged_channel(original))) {
06788 ast_channel_lock(bridged);
06789 ast_indicate(bridged, AST_CONTROL_SRCCHANGE);
06790 ast_channel_unlock(bridged);
06791 }
06792 ast_indicate(original, AST_CONTROL_SRCCHANGE);
06793
06794 if (xfer_colp) {
06795
06796
06797
06798
06799
06800 masquerade_colp_transfer(original, xfer_colp);
06801 }
06802
06803 done:
06804 if (xfer_ds) {
06805 ast_datastore_free(xfer_ds);
06806 }
06807
06808 if (clonechan) {
06809 ast_channel_unlock(original);
06810 ast_channel_unlock(clonechan);
06811 ao2_link(channels, clonechan);
06812 ao2_link(channels, original);
06813 } else {
06814 ast_channel_unlock(original);
06815 ao2_link(channels, original);
06816 }
06817
06818 ao2_unlock(channels);
06819
06820 return res;
06821 }
06822
06823 void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani)
06824 {
06825 ast_channel_lock(chan);
06826
06827 if (cid_num) {
06828 chan->caller.id.number.valid = 1;
06829 ast_free(chan->caller.id.number.str);
06830 chan->caller.id.number.str = ast_strdup(cid_num);
06831 }
06832 if (cid_name) {
06833 chan->caller.id.name.valid = 1;
06834 ast_free(chan->caller.id.name.str);
06835 chan->caller.id.name.str = ast_strdup(cid_name);
06836 }
06837 if (cid_ani) {
06838 chan->caller.ani.number.valid = 1;
06839 ast_free(chan->caller.ani.number.str);
06840 chan->caller.ani.number.str = ast_strdup(cid_ani);
06841 }
06842 if (chan->cdr) {
06843 ast_cdr_setcid(chan->cdr, chan);
06844 }
06845
06846 report_new_callerid(chan);
06847
06848 ast_channel_unlock(chan);
06849 }
06850
06851 void ast_channel_set_caller(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
06852 {
06853 if (&chan->caller == caller) {
06854
06855 return;
06856 }
06857
06858 ast_channel_lock(chan);
06859 ast_party_caller_set(&chan->caller, caller, update);
06860 ast_channel_unlock(chan);
06861 }
06862
06863 void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
06864 {
06865 const char *pre_set_number;
06866 const char *pre_set_name;
06867
06868 if (&chan->caller == caller) {
06869
06870 return;
06871 }
06872
06873 ast_channel_lock(chan);
06874 pre_set_number =
06875 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL);
06876 pre_set_name = S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL);
06877 ast_party_caller_set(&chan->caller, caller, update);
06878 if (S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL)
06879 != pre_set_number
06880 || S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL)
06881 != pre_set_name) {
06882
06883 report_new_callerid(chan);
06884 }
06885 if (chan->cdr) {
06886 ast_cdr_setcid(chan->cdr, chan);
06887 }
06888 ast_channel_unlock(chan);
06889 }
06890
06891 int ast_setstate(struct ast_channel *chan, enum ast_channel_state state)
06892 {
06893 int oldstate = chan->_state;
06894 char name[AST_CHANNEL_NAME], *dashptr;
06895
06896 if (oldstate == state)
06897 return 0;
06898
06899 ast_copy_string(name, ast_channel_name(chan), sizeof(name));
06900 if ((dashptr = strrchr(name, '-'))) {
06901 *dashptr = '\0';
06902 }
06903
06904 chan->_state = state;
06905
06906
06907
06908
06909 ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, name);
06910
06911
06912 ast_manager_event(chan, EVENT_FLAG_CALL, "Newstate",
06913 "Channel: %s\r\n"
06914 "ChannelState: %d\r\n"
06915 "ChannelStateDesc: %s\r\n"
06916 "CallerIDNum: %s\r\n"
06917 "CallerIDName: %s\r\n"
06918 "ConnectedLineNum: %s\r\n"
06919 "ConnectedLineName: %s\r\n"
06920 "Uniqueid: %s\r\n",
06921 ast_channel_name(chan), chan->_state, ast_state2str(chan->_state),
06922 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
06923 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""),
06924 S_COR(chan->connected.id.number.valid, chan->connected.id.number.str, ""),
06925 S_COR(chan->connected.id.name.valid, chan->connected.id.name.str, ""),
06926 ast_channel_uniqueid(chan));
06927
06928 return 0;
06929 }
06930
06931
06932 struct ast_channel *ast_bridged_channel(struct ast_channel *chan)
06933 {
06934 struct ast_channel *bridged;
06935 bridged = chan->_bridge;
06936 if (bridged && bridged->tech->bridged_channel)
06937 bridged = bridged->tech->bridged_channel(chan, bridged);
06938 return bridged;
06939 }
06940
06941 static void bridge_playfile(struct ast_channel *chan, struct ast_channel *peer, const char *sound, int remain)
06942 {
06943 int min = 0, sec = 0, check;
06944
06945 check = ast_autoservice_start(peer);
06946 if (check)
06947 return;
06948
06949 if (remain > 0) {
06950 if (remain / 60 > 1) {
06951 min = remain / 60;
06952 sec = remain % 60;
06953 } else {
06954 sec = remain;
06955 }
06956 }
06957
06958 if (!strcmp(sound,"timeleft")) {
06959 ast_stream_and_wait(chan, "vm-youhave", "");
06960 if (min) {
06961 ast_say_number(chan, min, AST_DIGIT_ANY, ast_channel_language(chan), NULL);
06962 ast_stream_and_wait(chan, "queue-minutes", "");
06963 }
06964 if (sec) {
06965 ast_say_number(chan, sec, AST_DIGIT_ANY, ast_channel_language(chan), NULL);
06966 ast_stream_and_wait(chan, "queue-seconds", "");
06967 }
06968 } else {
06969 ast_stream_and_wait(chan, sound, "");
06970 }
06971
06972 ast_autoservice_stop(peer);
06973 }
06974
06975 static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct ast_channel *c1,
06976 struct ast_bridge_config *config, struct ast_frame **fo,
06977 struct ast_channel **rc)
06978 {
06979
06980 struct ast_channel *cs[3];
06981 struct ast_frame *f;
06982 enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
06983 struct ast_format_cap *o0nativeformats;
06984 struct ast_format_cap *o1nativeformats;
06985 int watch_c0_dtmf;
06986 int watch_c1_dtmf;
06987 void *pvt0, *pvt1;
06988
06989 int frame_put_in_jb = 0;
06990 int jb_in_use;
06991 int to;
06992
06993 o0nativeformats = ast_format_cap_dup(c0->nativeformats);
06994 o1nativeformats = ast_format_cap_dup(c1->nativeformats);
06995
06996 if (!o0nativeformats || !o1nativeformats) {
06997 ast_format_cap_destroy(o0nativeformats);
06998 ast_format_cap_destroy(o1nativeformats);
06999 return AST_BRIDGE_FAILED;
07000 }
07001
07002 cs[0] = c0;
07003 cs[1] = c1;
07004 pvt0 = c0->tech_pvt;
07005 pvt1 = c1->tech_pvt;
07006 watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0;
07007 watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1;
07008
07009
07010 jb_in_use = ast_jb_do_usecheck(c0, c1);
07011 if (jb_in_use)
07012 ast_jb_empty_and_reset(c0, c1);
07013
07014 ast_poll_channel_add(c0, c1);
07015
07016 if (config->feature_timer > 0 && ast_tvzero(config->nexteventts)) {
07017
07018
07019
07020 config->nexteventts = ast_tvadd(ast_tvnow(), ast_samp2tv(config->feature_timer, 1000));
07021 }
07022
07023 for (;;) {
07024 struct ast_channel *who, *other;
07025
07026 if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) ||
07027 (!ast_format_cap_identical(o0nativeformats, c0->nativeformats)) ||
07028 (!ast_format_cap_identical(o1nativeformats, c1->nativeformats))) {
07029
07030 res = AST_BRIDGE_RETRY;
07031 break;
07032 }
07033 if (config->nexteventts.tv_sec) {
07034 to = ast_tvdiff_ms(config->nexteventts, ast_tvnow());
07035 if (to <= 0) {
07036 if (config->timelimit && !config->feature_timer && !ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) {
07037 res = AST_BRIDGE_RETRY;
07038
07039 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
07040 } else if (config->feature_timer) {
07041
07042 ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE);
07043 res = AST_BRIDGE_RETRY;
07044 } else {
07045 res = AST_BRIDGE_COMPLETE;
07046 }
07047 break;
07048 }
07049 } else {
07050
07051
07052
07053
07054 if (!ast_tvzero(config->nexteventts)) {
07055 int diff = ast_tvdiff_ms(config->nexteventts, ast_tvnow());
07056 if (diff <= 0) {
07057 res = AST_BRIDGE_RETRY;
07058 break;
07059 }
07060 }
07061 to = -1;
07062 }
07063
07064
07065 if (jb_in_use)
07066 to = ast_jb_get_when_to_wakeup(c0, c1, to);
07067 who = ast_waitfor_n(cs, 2, &to);
07068 if (!who) {
07069
07070 if (jb_in_use)
07071 ast_jb_get_and_deliver(c0, c1);
07072 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {
07073 if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
07074 ast_channel_clear_softhangup(c0, AST_SOFTHANGUP_UNBRIDGE);
07075 }
07076 if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
07077 ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE);
07078 }
07079 c0->_bridge = c1;
07080 c1->_bridge = c0;
07081 }
07082 continue;
07083 }
07084 f = ast_read(who);
07085 if (!f) {
07086 *fo = NULL;
07087 *rc = who;
07088 ast_debug(1, "Didn't get a frame from channel: %s\n", ast_channel_name(who));
07089 break;
07090 }
07091
07092 other = (who == c0) ? c1 : c0;
07093
07094 if (jb_in_use)
07095 frame_put_in_jb = !ast_jb_put(other, f);
07096
07097 if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) {
07098 int bridge_exit = 0;
07099
07100 switch (f->subclass.integer) {
07101 case AST_CONTROL_AOC:
07102 case AST_CONTROL_MCID:
07103 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
07104 break;
07105 case AST_CONTROL_REDIRECTING:
07106 if (ast_channel_redirecting_macro(who, other, f, other == c0, 1)) {
07107 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
07108 }
07109 break;
07110 case AST_CONTROL_CONNECTED_LINE:
07111 if (ast_channel_connected_line_macro(who, other, f, other == c0, 1)) {
07112 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
07113 }
07114 break;
07115 case AST_CONTROL_HOLD:
07116 case AST_CONTROL_UNHOLD:
07117 case AST_CONTROL_VIDUPDATE:
07118 case AST_CONTROL_SRCUPDATE:
07119 case AST_CONTROL_SRCCHANGE:
07120 case AST_CONTROL_T38_PARAMETERS:
07121 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
07122 if (jb_in_use) {
07123 ast_jb_empty_and_reset(c0, c1);
07124 }
07125 break;
07126 default:
07127 *fo = f;
07128 *rc = who;
07129 bridge_exit = 1;
07130 ast_debug(1, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass.integer, ast_channel_name(who));
07131 break;
07132 }
07133 if (bridge_exit)
07134 break;
07135 }
07136 if ((f->frametype == AST_FRAME_VOICE) ||
07137 (f->frametype == AST_FRAME_DTMF_BEGIN) ||
07138 (f->frametype == AST_FRAME_DTMF) ||
07139 (f->frametype == AST_FRAME_VIDEO) ||
07140 (f->frametype == AST_FRAME_IMAGE) ||
07141 (f->frametype == AST_FRAME_HTML) ||
07142 (f->frametype == AST_FRAME_MODEM) ||
07143 (f->frametype == AST_FRAME_TEXT)) {
07144
07145 int monitored_source = (who == c0) ? watch_c0_dtmf : watch_c1_dtmf;
07146
07147 if (monitored_source &&
07148 (f->frametype == AST_FRAME_DTMF_END ||
07149 f->frametype == AST_FRAME_DTMF_BEGIN)) {
07150 *fo = f;
07151 *rc = who;
07152 ast_debug(1, "Got DTMF %s on channel (%s)\n",
07153 f->frametype == AST_FRAME_DTMF_END ? "end" : "begin",
07154 ast_channel_name(who));
07155
07156 break;
07157 }
07158
07159 if (!frame_put_in_jb)
07160 ast_write(other, f);
07161
07162
07163 if (jb_in_use)
07164 ast_jb_get_and_deliver(c0, c1);
07165 }
07166
07167 ast_frfree(f);
07168
07169 #ifndef HAVE_EPOLL
07170
07171 cs[2] = cs[0];
07172 cs[0] = cs[1];
07173 cs[1] = cs[2];
07174 #endif
07175 }
07176
07177 ast_poll_channel_del(c0, c1);
07178
07179 ast_format_cap_destroy(o0nativeformats);
07180 ast_format_cap_destroy(o1nativeformats);
07181
07182 return res;
07183 }
07184
07185
07186 int ast_channel_early_bridge(struct ast_channel *c0, struct ast_channel *c1)
07187 {
07188
07189 if (!c0->tech->early_bridge || (c1 && (!c1->tech->early_bridge || c0->tech->early_bridge != c1->tech->early_bridge)))
07190 return -1;
07191
07192 return c0->tech->early_bridge(c0, c1);
07193 }
07194
07195
07196
07197
07198
07199
07200
07201 static void manager_bridge_event(int onoff, int type, struct ast_channel *c0, struct ast_channel *c1)
07202 {
07203 struct ast_channel *chans[2] = { c0, c1 };
07204 ast_manager_event_multichan(EVENT_FLAG_CALL, "Bridge", 2, chans,
07205 "Bridgestate: %s\r\n"
07206 "Bridgetype: %s\r\n"
07207 "Channel1: %s\r\n"
07208 "Channel2: %s\r\n"
07209 "Uniqueid1: %s\r\n"
07210 "Uniqueid2: %s\r\n"
07211 "CallerID1: %s\r\n"
07212 "CallerID2: %s\r\n",
07213 onoff ? "Link" : "Unlink",
07214 type == 1 ? "core" : "native",
07215 ast_channel_name(c0), ast_channel_name(c1),
07216 ast_channel_uniqueid(c0), ast_channel_uniqueid(c1),
07217 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, ""),
07218 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, ""));
07219 }
07220
07221 static void update_bridge_vars(struct ast_channel *c0, struct ast_channel *c1)
07222 {
07223 const char *c0_name;
07224 const char *c1_name;
07225 const char *c0_pvtid = NULL;
07226 const char *c1_pvtid = NULL;
07227
07228 ast_channel_lock(c1);
07229 c1_name = ast_strdupa(ast_channel_name(c1));
07230 if (c1->tech->get_pvt_uniqueid) {
07231 c1_pvtid = ast_strdupa(c1->tech->get_pvt_uniqueid(c1));
07232 }
07233 ast_channel_unlock(c1);
07234
07235 ast_channel_lock(c0);
07236 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER"))) {
07237 pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1_name);
07238 }
07239 if (c1_pvtid) {
07240 pbx_builtin_setvar_helper(c0, "BRIDGEPVTCALLID", c1_pvtid);
07241 }
07242 c0_name = ast_strdupa(ast_channel_name(c0));
07243 if (c0->tech->get_pvt_uniqueid) {
07244 c0_pvtid = ast_strdupa(c0->tech->get_pvt_uniqueid(c0));
07245 }
07246 ast_channel_unlock(c0);
07247
07248 ast_channel_lock(c1);
07249 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER"))) {
07250 pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0_name);
07251 }
07252 if (c0_pvtid) {
07253 pbx_builtin_setvar_helper(c1, "BRIDGEPVTCALLID", c0_pvtid);
07254 }
07255 ast_channel_unlock(c1);
07256 }
07257
07258 static void bridge_play_sounds(struct ast_channel *c0, struct ast_channel *c1)
07259 {
07260 const char *s, *sound;
07261
07262
07263
07264 ast_channel_lock(c0);
07265 if ((s = pbx_builtin_getvar_helper(c0, "BRIDGE_PLAY_SOUND"))) {
07266 sound = ast_strdupa(s);
07267 ast_channel_unlock(c0);
07268 bridge_playfile(c0, c1, sound, 0);
07269 pbx_builtin_setvar_helper(c0, "BRIDGE_PLAY_SOUND", NULL);
07270 } else {
07271 ast_channel_unlock(c0);
07272 }
07273
07274 ast_channel_lock(c1);
07275 if ((s = pbx_builtin_getvar_helper(c1, "BRIDGE_PLAY_SOUND"))) {
07276 sound = ast_strdupa(s);
07277 ast_channel_unlock(c1);
07278 bridge_playfile(c1, c0, sound, 0);
07279 pbx_builtin_setvar_helper(c1, "BRIDGE_PLAY_SOUND", NULL);
07280 } else {
07281 ast_channel_unlock(c1);
07282 }
07283 }
07284
07285
07286 enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1,
07287 struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc)
07288 {
07289 enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
07290 struct ast_format_cap *o0nativeformats;
07291 struct ast_format_cap *o1nativeformats;
07292 long time_left_ms=0;
07293 char caller_warning = 0;
07294 char callee_warning = 0;
07295
07296 *fo = NULL;
07297
07298 if (c0->_bridge) {
07299 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
07300 ast_channel_name(c0), ast_channel_name(c0->_bridge));
07301 return -1;
07302 }
07303 if (c1->_bridge) {
07304 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
07305 ast_channel_name(c1), ast_channel_name(c1->_bridge));
07306 return -1;
07307 }
07308
07309
07310 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
07311 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1))
07312 return -1;
07313
07314 o0nativeformats = ast_format_cap_dup(c0->nativeformats);
07315 o1nativeformats = ast_format_cap_dup(c1->nativeformats);
07316 if (!o0nativeformats || !o1nativeformats) {
07317 ast_format_cap_destroy(o0nativeformats);
07318 ast_format_cap_destroy(o1nativeformats);
07319 ast_log(LOG_WARNING, "failed to copy native formats\n");
07320 return -1;
07321 }
07322
07323 caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING);
07324 callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING);
07325
07326 if (ast_tvzero(config->start_time)) {
07327 config->start_time = ast_tvnow();
07328 if (config->start_sound) {
07329 if (caller_warning) {
07330 bridge_playfile(c0, c1, config->start_sound, config->timelimit / 1000);
07331 }
07332 if (callee_warning) {
07333 bridge_playfile(c1, c0, config->start_sound, config->timelimit / 1000);
07334 }
07335 }
07336 }
07337
07338
07339 c0->_bridge = c1;
07340 c1->_bridge = c0;
07341
07342 ast_set_owners_and_peers(c0, c1);
07343
07344 if (config->feature_timer && !ast_tvzero(config->nexteventts)) {
07345 config->nexteventts = ast_tvadd(config->feature_start_time, ast_samp2tv(config->feature_timer, 1000));
07346 } else if (config->timelimit) {
07347 time_left_ms = config->timelimit - ast_tvdiff_ms(ast_tvnow(), config->start_time);
07348 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
07349 if ((caller_warning || callee_warning) && config->play_warning) {
07350 long next_warn = config->play_warning;
07351 if (time_left_ms < config->play_warning && config->warning_freq > 0) {
07352
07353 long warns_passed = (config->play_warning - time_left_ms) / config->warning_freq;
07354
07355
07356 next_warn = config->play_warning - warns_passed * config->warning_freq;
07357 }
07358 config->nexteventts = ast_tvsub(config->nexteventts, ast_samp2tv(next_warn, 1000));
07359 }
07360 } else {
07361 config->nexteventts.tv_sec = 0;
07362 config->nexteventts.tv_usec = 0;
07363 }
07364
07365 if (!c0->tech->send_digit_begin)
07366 ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY);
07367 if (!c1->tech->send_digit_begin)
07368 ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY);
07369 manager_bridge_event(1, 1, c0, c1);
07370
07371
07372 ast_indicate(c0, AST_CONTROL_SRCUPDATE);
07373 ast_indicate(c1, AST_CONTROL_SRCUPDATE);
07374
07375 for (;;) {
07376 struct timeval now = { 0, };
07377 int to;
07378
07379 to = -1;
07380
07381 if (!ast_tvzero(config->nexteventts)) {
07382 now = ast_tvnow();
07383 to = ast_tvdiff_ms(config->nexteventts, now);
07384 if (to <= 0) {
07385 if (!config->timelimit) {
07386 res = AST_BRIDGE_COMPLETE;
07387 break;
07388 }
07389 to = 0;
07390 }
07391 }
07392
07393 if (config->timelimit) {
07394 time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time);
07395 if (time_left_ms < to)
07396 to = time_left_ms;
07397
07398 if (time_left_ms <= 0) {
07399 if (caller_warning && config->end_sound)
07400 bridge_playfile(c0, c1, config->end_sound, 0);
07401 if (callee_warning && config->end_sound)
07402 bridge_playfile(c1, c0, config->end_sound, 0);
07403 *fo = NULL;
07404 res = 0;
07405 break;
07406 }
07407
07408 if (!to) {
07409 if (time_left_ms >= 5000 && config->warning_sound && config->play_warning && ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) {
07410 int t = (time_left_ms + 500) / 1000;
07411 if (caller_warning)
07412 bridge_playfile(c0, c1, config->warning_sound, t);
07413 if (callee_warning)
07414 bridge_playfile(c1, c0, config->warning_sound, t);
07415 }
07416
07417 if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000))) {
07418 config->nexteventts = ast_tvadd(config->nexteventts, ast_samp2tv(config->warning_freq, 1000));
07419 } else {
07420 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
07421 }
07422 }
07423 ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE);
07424 }
07425
07426 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {
07427 if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
07428 ast_channel_clear_softhangup(c0, AST_SOFTHANGUP_UNBRIDGE);
07429 }
07430 if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
07431 ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE);
07432 }
07433 c0->_bridge = c1;
07434 c1->_bridge = c0;
07435 ast_debug(1, "Unbridge signal received. Ending native bridge.\n");
07436 continue;
07437 }
07438
07439
07440 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
07441 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) {
07442 *fo = NULL;
07443 res = 0;
07444 ast_debug(1, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n",
07445 ast_channel_name(c0), ast_channel_name(c1),
07446 ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No",
07447 ast_check_hangup(c0) ? "Yes" : "No",
07448 ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No",
07449 ast_check_hangup(c1) ? "Yes" : "No");
07450 break;
07451 }
07452
07453 update_bridge_vars(c0, c1);
07454
07455 bridge_play_sounds(c0, c1);
07456
07457 if (c0->tech->bridge &&
07458
07459 (!config->timelimit || to > 1000 || to == 0) &&
07460 (c0->tech->bridge == c1->tech->bridge) &&
07461 !c0->monitor && !c1->monitor &&
07462 !c0->audiohooks && !c1->audiohooks &&
07463 ast_framehook_list_is_empty(c0->framehooks) && ast_framehook_list_is_empty(c1->framehooks) &&
07464 !c0->masq && !c0->masqr && !c1->masq && !c1->masqr) {
07465 int timeoutms = to - 1000 > 0 ? to - 1000 : to;
07466
07467 ast_set_flag(c0, AST_FLAG_NBRIDGE);
07468 ast_set_flag(c1, AST_FLAG_NBRIDGE);
07469 if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, timeoutms)) == AST_BRIDGE_COMPLETE) {
07470 manager_bridge_event(0, 1, c0, c1);
07471 ast_debug(1, "Returning from native bridge, channels: %s, %s\n", ast_channel_name(c0), ast_channel_name(c1));
07472
07473 ast_clear_flag(c0, AST_FLAG_NBRIDGE);
07474 ast_clear_flag(c1, AST_FLAG_NBRIDGE);
07475
07476 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {
07477 continue;
07478 }
07479
07480 c0->_bridge = NULL;
07481 c1->_bridge = NULL;
07482 ast_format_cap_destroy(o0nativeformats);
07483 ast_format_cap_destroy(o1nativeformats);
07484 return res;
07485 } else {
07486 ast_clear_flag(c0, AST_FLAG_NBRIDGE);
07487 ast_clear_flag(c1, AST_FLAG_NBRIDGE);
07488 }
07489 switch (res) {
07490 case AST_BRIDGE_RETRY:
07491 if (config->play_warning) {
07492 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
07493 }
07494 continue;
07495 default:
07496 ast_verb(3, "Native bridging %s and %s ended\n", ast_channel_name(c0), ast_channel_name(c1));
07497
07498 case AST_BRIDGE_FAILED_NOWARN:
07499 break;
07500 }
07501 }
07502
07503 if (((ast_format_cmp(&c1->readformat, &c0->writeformat) == AST_FORMAT_CMP_NOT_EQUAL) ||
07504 (ast_format_cmp(&c0->readformat, &c1->writeformat) == AST_FORMAT_CMP_NOT_EQUAL) ||
07505 !ast_format_cap_identical(c0->nativeformats, o0nativeformats) ||
07506 !ast_format_cap_identical(c1->nativeformats, o1nativeformats)) &&
07507 !(c0->generator || c1->generator)) {
07508 if (ast_channel_make_compatible(c0, c1)) {
07509 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", ast_channel_name(c0), ast_channel_name(c1));
07510 manager_bridge_event(0, 1, c0, c1);
07511 ast_format_cap_destroy(o0nativeformats);
07512 ast_format_cap_destroy(o1nativeformats);
07513 return AST_BRIDGE_FAILED;
07514 }
07515
07516 ast_format_cap_copy(o0nativeformats, c0->nativeformats);
07517 ast_format_cap_copy(o1nativeformats, c1->nativeformats);
07518 }
07519
07520 update_bridge_vars(c0, c1);
07521
07522 res = ast_generic_bridge(c0, c1, config, fo, rc);
07523 if (res != AST_BRIDGE_RETRY) {
07524 break;
07525 } else if (config->feature_timer) {
07526
07527 break;
07528 }
07529 }
07530
07531 ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY);
07532 ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY);
07533
07534
07535 ast_indicate(c0, AST_CONTROL_SRCUPDATE);
07536 ast_indicate(c1, AST_CONTROL_SRCUPDATE);
07537
07538 c0->_bridge = NULL;
07539 c1->_bridge = NULL;
07540
07541 manager_bridge_event(0, 1, c0, c1);
07542 ast_debug(1, "Bridge stops bridging channels %s and %s\n", ast_channel_name(c0), ast_channel_name(c1));
07543
07544 ast_format_cap_destroy(o0nativeformats);
07545 ast_format_cap_destroy(o1nativeformats);
07546 return res;
07547 }
07548
07549
07550 int ast_channel_setoption(struct ast_channel *chan, int option, void *data, int datalen, int block)
07551 {
07552 int res;
07553
07554 ast_channel_lock(chan);
07555 if (!chan->tech->setoption) {
07556 errno = ENOSYS;
07557 ast_channel_unlock(chan);
07558 return -1;
07559 }
07560
07561 if (block)
07562 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
07563
07564 res = chan->tech->setoption(chan, option, data, datalen);
07565 ast_channel_unlock(chan);
07566
07567 return res;
07568 }
07569
07570 int ast_channel_queryoption(struct ast_channel *chan, int option, void *data, int *datalen, int block)
07571 {
07572 int res;
07573
07574 ast_channel_lock(chan);
07575 if (!chan->tech->queryoption) {
07576 errno = ENOSYS;
07577 ast_channel_unlock(chan);
07578 return -1;
07579 }
07580
07581 if (block)
07582 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
07583
07584 res = chan->tech->queryoption(chan, option, data, datalen);
07585 ast_channel_unlock(chan);
07586
07587 return res;
07588 }
07589
07590 struct tonepair_def {
07591 int freq1;
07592 int freq2;
07593 int duration;
07594 int vol;
07595 };
07596
07597 struct tonepair_state {
07598 int fac1;
07599 int fac2;
07600 int v1_1;
07601 int v2_1;
07602 int v3_1;
07603 int v1_2;
07604 int v2_2;
07605 int v3_2;
07606 struct ast_format origwfmt;
07607 int pos;
07608 int duration;
07609 int modulate;
07610 struct ast_frame f;
07611 unsigned char offset[AST_FRIENDLY_OFFSET];
07612 short data[4000];
07613 };
07614
07615 static void tonepair_release(struct ast_channel *chan, void *params)
07616 {
07617 struct tonepair_state *ts = params;
07618
07619 if (chan)
07620 ast_set_write_format(chan, &ts->origwfmt);
07621 ast_free(ts);
07622 }
07623
07624 static void *tonepair_alloc(struct ast_channel *chan, void *params)
07625 {
07626 struct tonepair_state *ts;
07627 struct tonepair_def *td = params;
07628
07629 if (!(ts = ast_calloc(1, sizeof(*ts))))
07630 return NULL;
07631 ast_format_copy(&ts->origwfmt, &chan->writeformat);
07632 if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR)) {
07633 ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", ast_channel_name(chan));
07634 tonepair_release(NULL, ts);
07635 ts = NULL;
07636 } else {
07637 ts->fac1 = 2.0 * cos(2.0 * M_PI * (td->freq1 / 8000.0)) * 32768.0;
07638 ts->v1_1 = 0;
07639 ts->v2_1 = sin(-4.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
07640 ts->v3_1 = sin(-2.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
07641 ts->v2_1 = 0;
07642 ts->fac2 = 2.0 * cos(2.0 * M_PI * (td->freq2 / 8000.0)) * 32768.0;
07643 ts->v2_2 = sin(-4.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
07644 ts->v3_2 = sin(-2.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
07645 ts->duration = td->duration;
07646 ts->modulate = 0;
07647 }
07648
07649 ast_set_flag(chan, AST_FLAG_WRITE_INT);
07650 return ts;
07651 }
07652
07653 static int tonepair_generator(struct ast_channel *chan, void *data, int len, int samples)
07654 {
07655 struct tonepair_state *ts = data;
07656 int x;
07657
07658
07659
07660
07661 len = samples * 2;
07662
07663 if (len > sizeof(ts->data) / 2 - 1) {
07664 ast_log(LOG_WARNING, "Can't generate that much data!\n");
07665 return -1;
07666 }
07667 memset(&ts->f, 0, sizeof(ts->f));
07668 for (x=0;x<len/2;x++) {
07669 ts->v1_1 = ts->v2_1;
07670 ts->v2_1 = ts->v3_1;
07671 ts->v3_1 = (ts->fac1 * ts->v2_1 >> 15) - ts->v1_1;
07672
07673 ts->v1_2 = ts->v2_2;
07674 ts->v2_2 = ts->v3_2;
07675 ts->v3_2 = (ts->fac2 * ts->v2_2 >> 15) - ts->v1_2;
07676 if (ts->modulate) {
07677 int p;
07678 p = ts->v3_2 - 32768;
07679 if (p < 0) p = -p;
07680 p = ((p * 9) / 10) + 1;
07681 ts->data[x] = (ts->v3_1 * p) >> 15;
07682 } else
07683 ts->data[x] = ts->v3_1 + ts->v3_2;
07684 }
07685 ts->f.frametype = AST_FRAME_VOICE;
07686 ast_format_set(&ts->f.subclass.format, AST_FORMAT_SLINEAR, 0);
07687 ts->f.datalen = len;
07688 ts->f.samples = samples;
07689 ts->f.offset = AST_FRIENDLY_OFFSET;
07690 ts->f.data.ptr = ts->data;
07691 ast_write(chan, &ts->f);
07692 ts->pos += x;
07693 if (ts->duration > 0) {
07694 if (ts->pos >= ts->duration * 8)
07695 return -1;
07696 }
07697 return 0;
07698 }
07699
07700 static struct ast_generator tonepair = {
07701 alloc: tonepair_alloc,
07702 release: tonepair_release,
07703 generate: tonepair_generator,
07704 };
07705
07706 int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
07707 {
07708 struct tonepair_def d = { 0, };
07709
07710 d.freq1 = freq1;
07711 d.freq2 = freq2;
07712 d.duration = duration;
07713 d.vol = (vol < 1) ? 8192 : vol;
07714 if (ast_activate_generator(chan, &tonepair, &d))
07715 return -1;
07716 return 0;
07717 }
07718
07719 void ast_tonepair_stop(struct ast_channel *chan)
07720 {
07721 ast_deactivate_generator(chan);
07722 }
07723
07724 int ast_tonepair(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
07725 {
07726 int res;
07727
07728 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
07729 return res;
07730
07731
07732 while (chan->generatordata && ast_waitfor(chan, 100) >= 0) {
07733 struct ast_frame *f = ast_read(chan);
07734 if (f)
07735 ast_frfree(f);
07736 else
07737 return -1;
07738 }
07739 return 0;
07740 }
07741
07742 ast_group_t ast_get_group(const char *s)
07743 {
07744 char *piece;
07745 char *c;
07746 int start=0, finish=0, x;
07747 ast_group_t group = 0;
07748
07749 if (ast_strlen_zero(s))
07750 return 0;
07751
07752 c = ast_strdupa(s);
07753
07754 while ((piece = strsep(&c, ","))) {
07755 if (sscanf(piece, "%30d-%30d", &start, &finish) == 2) {
07756
07757 } else if (sscanf(piece, "%30d", &start)) {
07758
07759 finish = start;
07760 } else {
07761 ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece);
07762 continue;
07763 }
07764 for (x = start; x <= finish; x++) {
07765 if ((x > 63) || (x < 0)) {
07766 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x);
07767 } else
07768 group |= ((ast_group_t) 1 << x);
07769 }
07770 }
07771 return group;
07772 }
07773
07774 static int (*ast_moh_start_ptr)(struct ast_channel *, const char *, const char *) = NULL;
07775 static void (*ast_moh_stop_ptr)(struct ast_channel *) = NULL;
07776 static void (*ast_moh_cleanup_ptr)(struct ast_channel *) = NULL;
07777
07778 void ast_install_music_functions(int (*start_ptr)(struct ast_channel *, const char *, const char *),
07779 void (*stop_ptr)(struct ast_channel *),
07780 void (*cleanup_ptr)(struct ast_channel *))
07781 {
07782 ast_moh_start_ptr = start_ptr;
07783 ast_moh_stop_ptr = stop_ptr;
07784 ast_moh_cleanup_ptr = cleanup_ptr;
07785 }
07786
07787 void ast_uninstall_music_functions(void)
07788 {
07789 ast_moh_start_ptr = NULL;
07790 ast_moh_stop_ptr = NULL;
07791 ast_moh_cleanup_ptr = NULL;
07792 }
07793
07794
07795 int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
07796 {
07797 if (ast_moh_start_ptr)
07798 return ast_moh_start_ptr(chan, mclass, interpclass);
07799
07800 ast_verb(3, "Music class %s requested but no musiconhold loaded.\n", mclass ? mclass : (interpclass ? interpclass : "default"));
07801
07802 return 0;
07803 }
07804
07805
07806 void ast_moh_stop(struct ast_channel *chan)
07807 {
07808 if (ast_moh_stop_ptr)
07809 ast_moh_stop_ptr(chan);
07810 }
07811
07812 void ast_moh_cleanup(struct ast_channel *chan)
07813 {
07814 if (ast_moh_cleanup_ptr)
07815 ast_moh_cleanup_ptr(chan);
07816 }
07817
07818 static int ast_channel_hash_cb(const void *obj, const int flags)
07819 {
07820 const char *name = (flags & OBJ_KEY) ? obj : ast_channel_name((struct ast_channel *) obj);
07821
07822
07823
07824 if (ast_strlen_zero(name)) {
07825 return 0;
07826 }
07827
07828 return ast_str_case_hash(name);
07829 }
07830
07831 int ast_plc_reload(void)
07832 {
07833 struct ast_variable *var;
07834 struct ast_flags config_flags = { 0 };
07835 struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
07836 if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID)
07837 return 0;
07838 for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
07839 if (!strcasecmp(var->name, "genericplc")) {
07840 ast_set2_flag(&ast_options, ast_true(var->value), AST_OPT_FLAG_GENERIC_PLC);
07841 }
07842 }
07843 ast_config_destroy(cfg);
07844 return 0;
07845 }
07846
07847
07848
07849
07850
07851 static int data_channels_provider_handler(const struct ast_data_search *search,
07852 struct ast_data *root)
07853 {
07854 struct ast_channel *c;
07855 struct ast_channel_iterator *iter = NULL;
07856 struct ast_data *data_channel;
07857
07858 for (iter = ast_channel_iterator_all_new();
07859 iter && (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) {
07860 ast_channel_lock(c);
07861
07862 data_channel = ast_data_add_node(root, "channel");
07863 if (!data_channel) {
07864 ast_channel_unlock(c);
07865 continue;
07866 }
07867
07868 if (ast_channel_data_add_structure(data_channel, c, 1) < 0) {
07869 ast_log(LOG_ERROR, "Unable to add channel structure for channel: %s\n", ast_channel_name(c));
07870 }
07871
07872 ast_channel_unlock(c);
07873
07874 if (!ast_data_search_match(search, data_channel)) {
07875 ast_data_remove_node(root, data_channel);
07876 }
07877 }
07878 if (iter) {
07879 ast_channel_iterator_destroy(iter);
07880 }
07881
07882 return 0;
07883 }
07884
07885
07886
07887
07888
07889 static int data_channeltypes_provider_handler(const struct ast_data_search *search,
07890 struct ast_data *data_root)
07891 {
07892 struct chanlist *cl;
07893 struct ast_data *data_type;
07894
07895 AST_RWLIST_RDLOCK(&backends);
07896 AST_RWLIST_TRAVERSE(&backends, cl, list) {
07897 data_type = ast_data_add_node(data_root, "type");
07898 if (!data_type) {
07899 continue;
07900 }
07901 ast_data_add_str(data_type, "name", cl->tech->type);
07902 ast_data_add_str(data_type, "description", cl->tech->description);
07903 ast_data_add_bool(data_type, "devicestate", cl->tech->devicestate ? 1 : 0);
07904 ast_data_add_bool(data_type, "indications", cl->tech->indicate ? 1 : 0);
07905 ast_data_add_bool(data_type, "transfer", cl->tech->transfer ? 1 : 0);
07906 ast_data_add_bool(data_type, "send_digit_begin", cl->tech->send_digit_begin ? 1 : 0);
07907 ast_data_add_bool(data_type, "send_digit_end", cl->tech->send_digit_end ? 1 : 0);
07908 ast_data_add_bool(data_type, "call", cl->tech->call ? 1 : 0);
07909 ast_data_add_bool(data_type, "hangup", cl->tech->hangup ? 1 : 0);
07910 ast_data_add_bool(data_type, "answer", cl->tech->answer ? 1 : 0);
07911 ast_data_add_bool(data_type, "read", cl->tech->read ? 1 : 0);
07912 ast_data_add_bool(data_type, "write", cl->tech->write ? 1 : 0);
07913 ast_data_add_bool(data_type, "send_text", cl->tech->send_text ? 1 : 0);
07914 ast_data_add_bool(data_type, "send_image", cl->tech->send_image ? 1 : 0);
07915 ast_data_add_bool(data_type, "send_html", cl->tech->send_html ? 1 : 0);
07916 ast_data_add_bool(data_type, "exception", cl->tech->exception ? 1 : 0);
07917 ast_data_add_bool(data_type, "bridge", cl->tech->bridge ? 1 : 0);
07918 ast_data_add_bool(data_type, "early_bridge", cl->tech->early_bridge ? 1 : 0);
07919 ast_data_add_bool(data_type, "fixup", cl->tech->fixup ? 1 : 0);
07920 ast_data_add_bool(data_type, "setoption", cl->tech->setoption ? 1 : 0);
07921 ast_data_add_bool(data_type, "queryoption", cl->tech->queryoption ? 1 : 0);
07922 ast_data_add_bool(data_type, "write_video", cl->tech->write_video ? 1 : 0);
07923 ast_data_add_bool(data_type, "write_text", cl->tech->write_text ? 1 : 0);
07924 ast_data_add_bool(data_type, "bridged_channel", cl->tech->bridged_channel ? 1 : 0);
07925 ast_data_add_bool(data_type, "func_channel_read", cl->tech->func_channel_read ? 1 : 0);
07926 ast_data_add_bool(data_type, "func_channel_write", cl->tech->func_channel_write ? 1 : 0);
07927 ast_data_add_bool(data_type, "get_base_channel", cl->tech->get_base_channel ? 1 : 0);
07928 ast_data_add_bool(data_type, "set_base_channel", cl->tech->set_base_channel ? 1 : 0);
07929 ast_data_add_bool(data_type, "get_pvt_uniqueid", cl->tech->get_pvt_uniqueid ? 1 : 0);
07930 ast_data_add_bool(data_type, "cc_callback", cl->tech->cc_callback ? 1 : 0);
07931
07932 ast_data_add_codecs(data_type, "capabilities", cl->tech->capabilities);
07933
07934 if (!ast_data_search_match(search, data_type)) {
07935 ast_data_remove_node(data_root, data_type);
07936 }
07937 }
07938 AST_RWLIST_UNLOCK(&backends);
07939
07940 return 0;
07941 }
07942
07943
07944
07945
07946
07947 static const struct ast_data_handler channels_provider = {
07948 .version = AST_DATA_HANDLER_VERSION,
07949 .get = data_channels_provider_handler
07950 };
07951
07952
07953
07954
07955
07956 static const struct ast_data_handler channeltypes_provider = {
07957 .version = AST_DATA_HANDLER_VERSION,
07958 .get = data_channeltypes_provider_handler
07959 };
07960
07961 static const struct ast_data_entry channel_providers[] = {
07962 AST_DATA_ENTRY("/asterisk/core/channels", &channels_provider),
07963 AST_DATA_ENTRY("/asterisk/core/channeltypes", &channeltypes_provider),
07964 };
07965
07966 void ast_channels_init(void)
07967 {
07968 channels = ao2_container_alloc(NUM_CHANNEL_BUCKETS,
07969 ast_channel_hash_cb, ast_channel_cmp_cb);
07970
07971 ast_cli_register_multiple(cli_channel, ARRAY_LEN(cli_channel));
07972
07973 ast_data_register_multiple_core(channel_providers, ARRAY_LEN(channel_providers));
07974
07975 ast_plc_reload();
07976 }
07977
07978
07979 char *ast_print_group(char *buf, int buflen, ast_group_t group)
07980 {
07981 unsigned int i;
07982 int first = 1;
07983 char num[3];
07984
07985 buf[0] = '\0';
07986
07987 if (!group)
07988 return buf;
07989
07990 for (i = 0; i <= 63; i++) {
07991 if (group & ((ast_group_t) 1 << i)) {
07992 if (!first) {
07993 strncat(buf, ", ", buflen - strlen(buf) - 1);
07994 } else {
07995 first = 0;
07996 }
07997 snprintf(num, sizeof(num), "%u", i);
07998 strncat(buf, num, buflen - strlen(buf) - 1);
07999 }
08000 }
08001 return buf;
08002 }
08003
08004 void ast_set_variables(struct ast_channel *chan, struct ast_variable *vars)
08005 {
08006 struct ast_variable *cur;
08007
08008 for (cur = vars; cur; cur = cur->next)
08009 pbx_builtin_setvar_helper(chan, cur->name, cur->value);
08010 }
08011
08012 static void *silence_generator_alloc(struct ast_channel *chan, void *data)
08013 {
08014
08015 return data;
08016 }
08017
08018 static void silence_generator_release(struct ast_channel *chan, void *data)
08019 {
08020
08021 }
08022
08023 static int silence_generator_generate(struct ast_channel *chan, void *data, int len, int samples)
08024 {
08025 short buf[samples];
08026 struct ast_frame frame = {
08027 .frametype = AST_FRAME_VOICE,
08028 .data.ptr = buf,
08029 .samples = samples,
08030 .datalen = sizeof(buf),
08031 };
08032 ast_format_set(&frame.subclass.format, AST_FORMAT_SLINEAR, 0);
08033
08034 memset(buf, 0, sizeof(buf));
08035
08036 if (ast_write(chan, &frame))
08037 return -1;
08038
08039 return 0;
08040 }
08041
08042 static struct ast_generator silence_generator = {
08043 .alloc = silence_generator_alloc,
08044 .release = silence_generator_release,
08045 .generate = silence_generator_generate,
08046 };
08047
08048 struct ast_silence_generator {
08049 struct ast_format old_write_format;
08050 };
08051
08052 struct ast_silence_generator *ast_channel_start_silence_generator(struct ast_channel *chan)
08053 {
08054 struct ast_silence_generator *state;
08055
08056 if (!(state = ast_calloc(1, sizeof(*state)))) {
08057 return NULL;
08058 }
08059
08060 ast_format_copy(&state->old_write_format, &chan->writeformat);
08061
08062 if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR) < 0) {
08063 ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
08064 ast_free(state);
08065 return NULL;
08066 }
08067
08068 ast_activate_generator(chan, &silence_generator, state);
08069
08070 ast_debug(1, "Started silence generator on '%s'\n", ast_channel_name(chan));
08071
08072 return state;
08073 }
08074
08075 void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_silence_generator *state)
08076 {
08077 if (!state)
08078 return;
08079
08080 ast_deactivate_generator(chan);
08081
08082 ast_debug(1, "Stopped silence generator on '%s'\n", ast_channel_name(chan));
08083
08084 if (ast_set_write_format(chan, &state->old_write_format) < 0)
08085 ast_log(LOG_ERROR, "Could not return write format to its original state\n");
08086
08087 ast_free(state);
08088 }
08089
08090
08091
08092 const char *channelreloadreason2txt(enum channelreloadreason reason)
08093 {
08094 switch (reason) {
08095 case CHANNEL_MODULE_LOAD:
08096 return "LOAD (Channel module load)";
08097
08098 case CHANNEL_MODULE_RELOAD:
08099 return "RELOAD (Channel module reload)";
08100
08101 case CHANNEL_CLI_RELOAD:
08102 return "CLIRELOAD (Channel module reload by CLI command)";
08103
08104 default:
08105 return "MANAGERRELOAD (Channel module reload by manager)";
08106 }
08107 };
08108
08109
08110
08111
08112
08113
08114
08115
08116
08117 int ast_say_number(struct ast_channel *chan, int num,
08118 const char *ints, const char *language, const char *options)
08119 {
08120 return ast_say_number_full(chan, num, ints, language, options, -1, -1);
08121 }
08122
08123 int ast_say_enumeration(struct ast_channel *chan, int num,
08124 const char *ints, const char *language, const char *options)
08125 {
08126 return ast_say_enumeration_full(chan, num, ints, language, options, -1, -1);
08127 }
08128
08129 int ast_say_digits(struct ast_channel *chan, int num,
08130 const char *ints, const char *lang)
08131 {
08132 return ast_say_digits_full(chan, num, ints, lang, -1, -1);
08133 }
08134
08135 int ast_say_digit_str(struct ast_channel *chan, const char *str,
08136 const char *ints, const char *lang)
08137 {
08138 return ast_say_digit_str_full(chan, str, ints, lang, -1, -1);
08139 }
08140
08141 int ast_say_character_str(struct ast_channel *chan, const char *str,
08142 const char *ints, const char *lang)
08143 {
08144 return ast_say_character_str_full(chan, str, ints, lang, -1, -1);
08145 }
08146
08147 int ast_say_phonetic_str(struct ast_channel *chan, const char *str,
08148 const char *ints, const char *lang)
08149 {
08150 return ast_say_phonetic_str_full(chan, str, ints, lang, -1, -1);
08151 }
08152
08153 int ast_say_digits_full(struct ast_channel *chan, int num,
08154 const char *ints, const char *lang, int audiofd, int ctrlfd)
08155 {
08156 char buf[256];
08157
08158 snprintf(buf, sizeof(buf), "%d", num);
08159
08160 return ast_say_digit_str_full(chan, buf, ints, lang, audiofd, ctrlfd);
08161 }
08162
08163 void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_party_caller *src)
08164 {
08165 ast_party_id_copy(&dest->id, &src->id);
08166 ast_party_id_copy(&dest->ani, &src->ani);
08167 dest->ani2 = src->ani2;
08168 }
08169
08170 void ast_connected_line_copy_to_caller(struct ast_party_caller *dest, const struct ast_party_connected_line *src)
08171 {
08172 ast_party_id_copy(&dest->id, &src->id);
08173 ast_party_id_copy(&dest->ani, &src->ani);
08174
08175 dest->ani2 = src->ani2;
08176 }
08177
08178 void ast_channel_set_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
08179 {
08180 if (&chan->connected == connected) {
08181
08182 return;
08183 }
08184
08185 ast_channel_lock(chan);
08186 ast_party_connected_line_set(&chan->connected, connected, update);
08187 ast_channel_unlock(chan);
08188 }
08189
08190
08191 struct ast_party_name_ies {
08192
08193 int str;
08194
08195 int char_set;
08196
08197 int presentation;
08198
08199 int valid;
08200 };
08201
08202
08203
08204
08205
08206
08207
08208
08209
08210
08211
08212
08213
08214
08215
08216 static int party_name_build_data(unsigned char *data, size_t datalen, const struct ast_party_name *name, const char *label, const struct ast_party_name_ies *ies)
08217 {
08218 size_t length;
08219 size_t pos = 0;
08220
08221
08222
08223
08224
08225 if (name->str) {
08226 length = strlen(name->str);
08227 if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08228 ast_log(LOG_WARNING, "No space left for %s name\n", label);
08229 return -1;
08230 }
08231 data[pos++] = ies->str;
08232 data[pos++] = length;
08233 memcpy(data + pos, name->str, length);
08234 pos += length;
08235 }
08236
08237 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08238 ast_log(LOG_WARNING, "No space left for %s name char set\n", label);
08239 return -1;
08240 }
08241 data[pos++] = ies->char_set;
08242 data[pos++] = 1;
08243 data[pos++] = name->char_set;
08244
08245 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08246 ast_log(LOG_WARNING, "No space left for %s name presentation\n", label);
08247 return -1;
08248 }
08249 data[pos++] = ies->presentation;
08250 data[pos++] = 1;
08251 data[pos++] = name->presentation;
08252
08253 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08254 ast_log(LOG_WARNING, "No space left for %s name valid\n", label);
08255 return -1;
08256 }
08257 data[pos++] = ies->valid;
08258 data[pos++] = 1;
08259 data[pos++] = name->valid;
08260
08261 return pos;
08262 }
08263
08264
08265 struct ast_party_number_ies {
08266
08267 int str;
08268
08269 int plan;
08270
08271 int presentation;
08272
08273 int valid;
08274 };
08275
08276
08277
08278
08279
08280
08281
08282
08283
08284
08285
08286
08287
08288
08289
08290 static int party_number_build_data(unsigned char *data, size_t datalen, const struct ast_party_number *number, const char *label, const struct ast_party_number_ies *ies)
08291 {
08292 size_t length;
08293 size_t pos = 0;
08294
08295
08296
08297
08298
08299 if (number->str) {
08300 length = strlen(number->str);
08301 if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08302 ast_log(LOG_WARNING, "No space left for %s number\n", label);
08303 return -1;
08304 }
08305 data[pos++] = ies->str;
08306 data[pos++] = length;
08307 memcpy(data + pos, number->str, length);
08308 pos += length;
08309 }
08310
08311 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08312 ast_log(LOG_WARNING, "No space left for %s numbering plan\n", label);
08313 return -1;
08314 }
08315 data[pos++] = ies->plan;
08316 data[pos++] = 1;
08317 data[pos++] = number->plan;
08318
08319 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08320 ast_log(LOG_WARNING, "No space left for %s number presentation\n", label);
08321 return -1;
08322 }
08323 data[pos++] = ies->presentation;
08324 data[pos++] = 1;
08325 data[pos++] = number->presentation;
08326
08327 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08328 ast_log(LOG_WARNING, "No space left for %s number valid\n", label);
08329 return -1;
08330 }
08331 data[pos++] = ies->valid;
08332 data[pos++] = 1;
08333 data[pos++] = number->valid;
08334
08335 return pos;
08336 }
08337
08338
08339 struct ast_party_subaddress_ies {
08340
08341 int str;
08342
08343 int type;
08344
08345 int odd_even_indicator;
08346
08347 int valid;
08348 };
08349
08350
08351
08352
08353
08354
08355
08356
08357
08358
08359
08360
08361
08362
08363
08364 static int party_subaddress_build_data(unsigned char *data, size_t datalen, const struct ast_party_subaddress *subaddress, const char *label, const struct ast_party_subaddress_ies *ies)
08365 {
08366 size_t length;
08367 size_t pos = 0;
08368
08369
08370
08371
08372
08373 if (subaddress->str) {
08374 length = strlen(subaddress->str);
08375 if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08376 ast_log(LOG_WARNING, "No space left for %s subaddress\n", label);
08377 return -1;
08378 }
08379 data[pos++] = ies->str;
08380 data[pos++] = length;
08381 memcpy(data + pos, subaddress->str, length);
08382 pos += length;
08383 }
08384
08385 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08386 ast_log(LOG_WARNING, "No space left for %s type of subaddress\n", label);
08387 return -1;
08388 }
08389 data[pos++] = ies->type;
08390 data[pos++] = 1;
08391 data[pos++] = subaddress->type;
08392
08393 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08394 ast_log(LOG_WARNING,
08395 "No space left for %s subaddress odd-even indicator\n", label);
08396 return -1;
08397 }
08398 data[pos++] = ies->odd_even_indicator;
08399 data[pos++] = 1;
08400 data[pos++] = subaddress->odd_even_indicator;
08401
08402 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08403 ast_log(LOG_WARNING, "No space left for %s subaddress valid\n", label);
08404 return -1;
08405 }
08406 data[pos++] = ies->valid;
08407 data[pos++] = 1;
08408 data[pos++] = subaddress->valid;
08409
08410 return pos;
08411 }
08412
08413
08414 struct ast_party_id_ies {
08415
08416 struct ast_party_name_ies name;
08417
08418 struct ast_party_number_ies number;
08419
08420 struct ast_party_subaddress_ies subaddress;
08421
08422 int tag;
08423
08424 int combined_presentation;
08425 };
08426
08427
08428
08429
08430
08431
08432
08433
08434
08435
08436
08437
08438
08439
08440
08441
08442 static int party_id_build_data(unsigned char *data, size_t datalen,
08443 const struct ast_party_id *id, const char *label, const struct ast_party_id_ies *ies,
08444 const struct ast_set_party_id *update)
08445 {
08446 size_t length;
08447 size_t pos = 0;
08448 int res;
08449
08450
08451
08452
08453
08454
08455 if (!update || update->name) {
08456 res = party_name_build_data(data + pos, datalen - pos, &id->name, label,
08457 &ies->name);
08458 if (res < 0) {
08459 return -1;
08460 }
08461 pos += res;
08462 }
08463
08464 if (!update || update->number) {
08465 res = party_number_build_data(data + pos, datalen - pos, &id->number, label,
08466 &ies->number);
08467 if (res < 0) {
08468 return -1;
08469 }
08470 pos += res;
08471 }
08472
08473 if (!update || update->subaddress) {
08474 res = party_subaddress_build_data(data + pos, datalen - pos, &id->subaddress,
08475 label, &ies->subaddress);
08476 if (res < 0) {
08477 return -1;
08478 }
08479 pos += res;
08480 }
08481
08482
08483 if (id->tag) {
08484 length = strlen(id->tag);
08485 if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08486 ast_log(LOG_WARNING, "No space left for %s tag\n", label);
08487 return -1;
08488 }
08489 data[pos++] = ies->tag;
08490 data[pos++] = length;
08491 memcpy(data + pos, id->tag, length);
08492 pos += length;
08493 }
08494
08495
08496 if (!update || update->number) {
08497 int presentation;
08498
08499 if (!update || update->name) {
08500 presentation = ast_party_id_presentation(id);
08501 } else {
08502
08503
08504
08505
08506
08507 presentation = id->number.presentation;
08508 }
08509
08510 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08511 ast_log(LOG_WARNING, "No space left for %s combined presentation\n", label);
08512 return -1;
08513 }
08514 data[pos++] = ies->combined_presentation;
08515 data[pos++] = 1;
08516 data[pos++] = presentation;
08517 }
08518
08519 return pos;
08520 }
08521
08522
08523
08524
08525
08526 enum {
08527 AST_CONNECTED_LINE_NUMBER,
08528 AST_CONNECTED_LINE_NAME,
08529 AST_CONNECTED_LINE_NUMBER_PLAN,
08530 AST_CONNECTED_LINE_ID_PRESENTATION,
08531 AST_CONNECTED_LINE_SOURCE,
08532 AST_CONNECTED_LINE_SUBADDRESS,
08533 AST_CONNECTED_LINE_SUBADDRESS_TYPE,
08534 AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN,
08535 AST_CONNECTED_LINE_SUBADDRESS_VALID,
08536 AST_CONNECTED_LINE_TAG,
08537 AST_CONNECTED_LINE_VERSION,
08538 AST_CONNECTED_LINE_NAME_VALID,
08539 AST_CONNECTED_LINE_NAME_CHAR_SET,
08540 AST_CONNECTED_LINE_NAME_PRESENTATION,
08541 AST_CONNECTED_LINE_NUMBER_VALID,
08542 AST_CONNECTED_LINE_NUMBER_PRESENTATION,
08543 };
08544
08545 int ast_connected_line_build_data(unsigned char *data, size_t datalen, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
08546 {
08547 int32_t value;
08548 size_t pos = 0;
08549 int res;
08550
08551 static const struct ast_party_id_ies ies = {
08552 .name.str = AST_CONNECTED_LINE_NAME,
08553 .name.char_set = AST_CONNECTED_LINE_NAME_CHAR_SET,
08554 .name.presentation = AST_CONNECTED_LINE_NAME_PRESENTATION,
08555 .name.valid = AST_CONNECTED_LINE_NAME_VALID,
08556
08557 .number.str = AST_CONNECTED_LINE_NUMBER,
08558 .number.plan = AST_CONNECTED_LINE_NUMBER_PLAN,
08559 .number.presentation = AST_CONNECTED_LINE_NUMBER_PRESENTATION,
08560 .number.valid = AST_CONNECTED_LINE_NUMBER_VALID,
08561
08562 .subaddress.str = AST_CONNECTED_LINE_SUBADDRESS,
08563 .subaddress.type = AST_CONNECTED_LINE_SUBADDRESS_TYPE,
08564 .subaddress.odd_even_indicator = AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN,
08565 .subaddress.valid = AST_CONNECTED_LINE_SUBADDRESS_VALID,
08566
08567 .tag = AST_CONNECTED_LINE_TAG,
08568 .combined_presentation = AST_CONNECTED_LINE_ID_PRESENTATION,
08569 };
08570
08571
08572
08573
08574
08575
08576
08577 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08578 ast_log(LOG_WARNING, "No space left for connected line frame version\n");
08579 return -1;
08580 }
08581 data[pos++] = AST_CONNECTED_LINE_VERSION;
08582 data[pos++] = 1;
08583 data[pos++] = 2;
08584
08585 res = party_id_build_data(data + pos, datalen - pos, &connected->id,
08586 "connected line", &ies, update ? &update->id : NULL);
08587 if (res < 0) {
08588 return -1;
08589 }
08590 pos += res;
08591
08592
08593 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
08594 ast_log(LOG_WARNING, "No space left for connected line source\n");
08595 return -1;
08596 }
08597 data[pos++] = AST_CONNECTED_LINE_SOURCE;
08598 data[pos++] = sizeof(value);
08599 value = htonl(connected->source);
08600 memcpy(data + pos, &value, sizeof(value));
08601 pos += sizeof(value);
08602
08603 return pos;
08604 }
08605
08606 int ast_connected_line_parse_data(const unsigned char *data, size_t datalen, struct ast_party_connected_line *connected)
08607 {
08608 size_t pos;
08609 unsigned char ie_len;
08610 unsigned char ie_id;
08611 int32_t value;
08612 int frame_version = 1;
08613 int combined_presentation = 0;
08614 int got_combined_presentation = 0;
08615
08616 for (pos = 0; pos < datalen; pos += ie_len) {
08617 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) {
08618 ast_log(LOG_WARNING, "Invalid connected line update\n");
08619 return -1;
08620 }
08621 ie_id = data[pos++];
08622 ie_len = data[pos++];
08623 if (datalen < pos + ie_len) {
08624 ast_log(LOG_WARNING, "Invalid connected line update\n");
08625 return -1;
08626 }
08627
08628 switch (ie_id) {
08629
08630 case AST_CONNECTED_LINE_VERSION:
08631 if (ie_len != 1) {
08632 ast_log(LOG_WARNING, "Invalid connected line frame version (%u)\n",
08633 (unsigned) ie_len);
08634 break;
08635 }
08636 frame_version = data[pos];
08637 break;
08638
08639 case AST_CONNECTED_LINE_NAME:
08640 ast_free(connected->id.name.str);
08641 connected->id.name.str = ast_malloc(ie_len + 1);
08642 if (connected->id.name.str) {
08643 memcpy(connected->id.name.str, data + pos, ie_len);
08644 connected->id.name.str[ie_len] = 0;
08645 }
08646 break;
08647 case AST_CONNECTED_LINE_NAME_CHAR_SET:
08648 if (ie_len != 1) {
08649 ast_log(LOG_WARNING, "Invalid connected line name char set (%u)\n",
08650 (unsigned) ie_len);
08651 break;
08652 }
08653 connected->id.name.char_set = data[pos];
08654 break;
08655 case AST_CONNECTED_LINE_NAME_PRESENTATION:
08656 if (ie_len != 1) {
08657 ast_log(LOG_WARNING, "Invalid connected line name presentation (%u)\n",
08658 (unsigned) ie_len);
08659 break;
08660 }
08661 connected->id.name.presentation = data[pos];
08662 break;
08663 case AST_CONNECTED_LINE_NAME_VALID:
08664 if (ie_len != 1) {
08665 ast_log(LOG_WARNING, "Invalid connected line name valid (%u)\n",
08666 (unsigned) ie_len);
08667 break;
08668 }
08669 connected->id.name.valid = data[pos];
08670 break;
08671
08672 case AST_CONNECTED_LINE_NUMBER:
08673 ast_free(connected->id.number.str);
08674 connected->id.number.str = ast_malloc(ie_len + 1);
08675 if (connected->id.number.str) {
08676 memcpy(connected->id.number.str, data + pos, ie_len);
08677 connected->id.number.str[ie_len] = 0;
08678 }
08679 break;
08680 case AST_CONNECTED_LINE_NUMBER_PLAN:
08681 if (ie_len != 1) {
08682 ast_log(LOG_WARNING, "Invalid connected line numbering plan (%u)\n",
08683 (unsigned) ie_len);
08684 break;
08685 }
08686 connected->id.number.plan = data[pos];
08687 break;
08688 case AST_CONNECTED_LINE_NUMBER_PRESENTATION:
08689 if (ie_len != 1) {
08690 ast_log(LOG_WARNING, "Invalid connected line number presentation (%u)\n",
08691 (unsigned) ie_len);
08692 break;
08693 }
08694 connected->id.number.presentation = data[pos];
08695 break;
08696 case AST_CONNECTED_LINE_NUMBER_VALID:
08697 if (ie_len != 1) {
08698 ast_log(LOG_WARNING, "Invalid connected line number valid (%u)\n",
08699 (unsigned) ie_len);
08700 break;
08701 }
08702 connected->id.number.valid = data[pos];
08703 break;
08704
08705 case AST_CONNECTED_LINE_ID_PRESENTATION:
08706 if (ie_len != 1) {
08707 ast_log(LOG_WARNING, "Invalid connected line combined presentation (%u)\n",
08708 (unsigned) ie_len);
08709 break;
08710 }
08711 combined_presentation = data[pos];
08712 got_combined_presentation = 1;
08713 break;
08714
08715 case AST_CONNECTED_LINE_SUBADDRESS:
08716 ast_free(connected->id.subaddress.str);
08717 connected->id.subaddress.str = ast_malloc(ie_len + 1);
08718 if (connected->id.subaddress.str) {
08719 memcpy(connected->id.subaddress.str, data + pos, ie_len);
08720 connected->id.subaddress.str[ie_len] = 0;
08721 }
08722 break;
08723 case AST_CONNECTED_LINE_SUBADDRESS_TYPE:
08724 if (ie_len != 1) {
08725 ast_log(LOG_WARNING, "Invalid connected line type of subaddress (%u)\n",
08726 (unsigned) ie_len);
08727 break;
08728 }
08729 connected->id.subaddress.type = data[pos];
08730 break;
08731 case AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN:
08732 if (ie_len != 1) {
08733 ast_log(LOG_WARNING,
08734 "Invalid connected line subaddress odd-even indicator (%u)\n",
08735 (unsigned) ie_len);
08736 break;
08737 }
08738 connected->id.subaddress.odd_even_indicator = data[pos];
08739 break;
08740 case AST_CONNECTED_LINE_SUBADDRESS_VALID:
08741 if (ie_len != 1) {
08742 ast_log(LOG_WARNING, "Invalid connected line subaddress valid (%u)\n",
08743 (unsigned) ie_len);
08744 break;
08745 }
08746 connected->id.subaddress.valid = data[pos];
08747 break;
08748
08749 case AST_CONNECTED_LINE_TAG:
08750 ast_free(connected->id.tag);
08751 connected->id.tag = ast_malloc(ie_len + 1);
08752 if (connected->id.tag) {
08753 memcpy(connected->id.tag, data + pos, ie_len);
08754 connected->id.tag[ie_len] = 0;
08755 }
08756 break;
08757
08758 case AST_CONNECTED_LINE_SOURCE:
08759 if (ie_len != sizeof(value)) {
08760 ast_log(LOG_WARNING, "Invalid connected line source (%u)\n",
08761 (unsigned) ie_len);
08762 break;
08763 }
08764 memcpy(&value, data + pos, sizeof(value));
08765 connected->source = ntohl(value);
08766 break;
08767
08768 default:
08769 ast_debug(1, "Unknown connected line element: %u (%u)\n",
08770 (unsigned) ie_id, (unsigned) ie_len);
08771 break;
08772 }
08773 }
08774
08775 switch (frame_version) {
08776 case 1:
08777
08778
08779
08780
08781 connected->id.name.valid = 1;
08782 connected->id.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
08783 connected->id.number.valid = 1;
08784 if (got_combined_presentation) {
08785 connected->id.name.presentation = combined_presentation;
08786 connected->id.number.presentation = combined_presentation;
08787 }
08788 break;
08789 case 2:
08790
08791 break;
08792 default:
08793
08794
08795
08796
08797 ast_debug(1, "Connected line frame has newer version: %u\n",
08798 (unsigned) frame_version);
08799 break;
08800 }
08801
08802 return 0;
08803 }
08804
08805 void ast_channel_update_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
08806 {
08807 unsigned char data[1024];
08808 size_t datalen;
08809
08810 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update);
08811 if (datalen == (size_t) -1) {
08812 return;
08813 }
08814
08815 ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen);
08816 }
08817
08818 void ast_channel_queue_connected_line_update(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
08819 {
08820 unsigned char data[1024];
08821 size_t datalen;
08822
08823 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update);
08824 if (datalen == (size_t) -1) {
08825 return;
08826 }
08827
08828 ast_queue_control_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen);
08829 }
08830
08831 void ast_channel_set_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
08832 {
08833 if (&chan->redirecting == redirecting) {
08834
08835 return;
08836 }
08837
08838 ast_channel_lock(chan);
08839 ast_party_redirecting_set(&chan->redirecting, redirecting, update);
08840 ast_channel_unlock(chan);
08841 }
08842
08843
08844
08845
08846
08847 enum {
08848 AST_REDIRECTING_FROM_NUMBER,
08849 AST_REDIRECTING_FROM_NAME,
08850 AST_REDIRECTING_FROM_NUMBER_PLAN,
08851 AST_REDIRECTING_FROM_ID_PRESENTATION,
08852 AST_REDIRECTING_TO_NUMBER,
08853 AST_REDIRECTING_TO_NAME,
08854 AST_REDIRECTING_TO_NUMBER_PLAN,
08855 AST_REDIRECTING_TO_ID_PRESENTATION,
08856 AST_REDIRECTING_REASON,
08857 AST_REDIRECTING_COUNT,
08858 AST_REDIRECTING_FROM_SUBADDRESS,
08859 AST_REDIRECTING_FROM_SUBADDRESS_TYPE,
08860 AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN,
08861 AST_REDIRECTING_FROM_SUBADDRESS_VALID,
08862 AST_REDIRECTING_TO_SUBADDRESS,
08863 AST_REDIRECTING_TO_SUBADDRESS_TYPE,
08864 AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN,
08865 AST_REDIRECTING_TO_SUBADDRESS_VALID,
08866 AST_REDIRECTING_FROM_TAG,
08867 AST_REDIRECTING_TO_TAG,
08868 AST_REDIRECTING_VERSION,
08869 AST_REDIRECTING_FROM_NAME_VALID,
08870 AST_REDIRECTING_FROM_NAME_CHAR_SET,
08871 AST_REDIRECTING_FROM_NAME_PRESENTATION,
08872 AST_REDIRECTING_FROM_NUMBER_VALID,
08873 AST_REDIRECTING_FROM_NUMBER_PRESENTATION,
08874 AST_REDIRECTING_TO_NAME_VALID,
08875 AST_REDIRECTING_TO_NAME_CHAR_SET,
08876 AST_REDIRECTING_TO_NAME_PRESENTATION,
08877 AST_REDIRECTING_TO_NUMBER_VALID,
08878 AST_REDIRECTING_TO_NUMBER_PRESENTATION,
08879 };
08880
08881 int ast_redirecting_build_data(unsigned char *data, size_t datalen, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
08882 {
08883 int32_t value;
08884 size_t pos = 0;
08885 int res;
08886
08887 static const struct ast_party_id_ies from_ies = {
08888 .name.str = AST_REDIRECTING_FROM_NAME,
08889 .name.char_set = AST_REDIRECTING_FROM_NAME_CHAR_SET,
08890 .name.presentation = AST_REDIRECTING_FROM_NAME_PRESENTATION,
08891 .name.valid = AST_REDIRECTING_FROM_NAME_VALID,
08892
08893 .number.str = AST_REDIRECTING_FROM_NUMBER,
08894 .number.plan = AST_REDIRECTING_FROM_NUMBER_PLAN,
08895 .number.presentation = AST_REDIRECTING_FROM_NUMBER_PRESENTATION,
08896 .number.valid = AST_REDIRECTING_FROM_NUMBER_VALID,
08897
08898 .subaddress.str = AST_REDIRECTING_FROM_SUBADDRESS,
08899 .subaddress.type = AST_REDIRECTING_FROM_SUBADDRESS_TYPE,
08900 .subaddress.odd_even_indicator = AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN,
08901 .subaddress.valid = AST_REDIRECTING_FROM_SUBADDRESS_VALID,
08902
08903 .tag = AST_REDIRECTING_FROM_TAG,
08904 .combined_presentation = AST_REDIRECTING_FROM_ID_PRESENTATION,
08905 };
08906 static const struct ast_party_id_ies to_ies = {
08907 .name.str = AST_REDIRECTING_TO_NAME,
08908 .name.char_set = AST_REDIRECTING_TO_NAME_CHAR_SET,
08909 .name.presentation = AST_REDIRECTING_TO_NAME_PRESENTATION,
08910 .name.valid = AST_REDIRECTING_TO_NAME_VALID,
08911
08912 .number.str = AST_REDIRECTING_TO_NUMBER,
08913 .number.plan = AST_REDIRECTING_TO_NUMBER_PLAN,
08914 .number.presentation = AST_REDIRECTING_TO_NUMBER_PRESENTATION,
08915 .number.valid = AST_REDIRECTING_TO_NUMBER_VALID,
08916
08917 .subaddress.str = AST_REDIRECTING_TO_SUBADDRESS,
08918 .subaddress.type = AST_REDIRECTING_TO_SUBADDRESS_TYPE,
08919 .subaddress.odd_even_indicator = AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN,
08920 .subaddress.valid = AST_REDIRECTING_TO_SUBADDRESS_VALID,
08921
08922 .tag = AST_REDIRECTING_TO_TAG,
08923 .combined_presentation = AST_REDIRECTING_TO_ID_PRESENTATION,
08924 };
08925
08926
08927 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
08928 ast_log(LOG_WARNING, "No space left for redirecting frame version\n");
08929 return -1;
08930 }
08931 data[pos++] = AST_REDIRECTING_VERSION;
08932 data[pos++] = 1;
08933 data[pos++] = 2;
08934
08935 res = party_id_build_data(data + pos, datalen - pos, &redirecting->from,
08936 "redirecting-from", &from_ies, update ? &update->from : NULL);
08937 if (res < 0) {
08938 return -1;
08939 }
08940 pos += res;
08941
08942 res = party_id_build_data(data + pos, datalen - pos, &redirecting->to,
08943 "redirecting-to", &to_ies, update ? &update->to : NULL);
08944 if (res < 0) {
08945 return -1;
08946 }
08947 pos += res;
08948
08949
08950 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
08951 ast_log(LOG_WARNING, "No space left for redirecting reason\n");
08952 return -1;
08953 }
08954 data[pos++] = AST_REDIRECTING_REASON;
08955 data[pos++] = sizeof(value);
08956 value = htonl(redirecting->reason);
08957 memcpy(data + pos, &value, sizeof(value));
08958 pos += sizeof(value);
08959
08960
08961 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
08962 ast_log(LOG_WARNING, "No space left for redirecting count\n");
08963 return -1;
08964 }
08965 data[pos++] = AST_REDIRECTING_COUNT;
08966 data[pos++] = sizeof(value);
08967 value = htonl(redirecting->count);
08968 memcpy(data + pos, &value, sizeof(value));
08969 pos += sizeof(value);
08970
08971 return pos;
08972 }
08973
08974 int ast_redirecting_parse_data(const unsigned char *data, size_t datalen, struct ast_party_redirecting *redirecting)
08975 {
08976 size_t pos;
08977 unsigned char ie_len;
08978 unsigned char ie_id;
08979 int32_t value;
08980 int frame_version = 1;
08981 int from_combined_presentation = 0;
08982 int got_from_combined_presentation = 0;
08983 int to_combined_presentation = 0;
08984 int got_to_combined_presentation = 0;
08985
08986 for (pos = 0; pos < datalen; pos += ie_len) {
08987 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) {
08988 ast_log(LOG_WARNING, "Invalid redirecting update\n");
08989 return -1;
08990 }
08991 ie_id = data[pos++];
08992 ie_len = data[pos++];
08993 if (datalen < pos + ie_len) {
08994 ast_log(LOG_WARNING, "Invalid redirecting update\n");
08995 return -1;
08996 }
08997
08998 switch (ie_id) {
08999
09000 case AST_REDIRECTING_VERSION:
09001 if (ie_len != 1) {
09002 ast_log(LOG_WARNING, "Invalid redirecting frame version (%u)\n",
09003 (unsigned) ie_len);
09004 break;
09005 }
09006 frame_version = data[pos];
09007 break;
09008
09009 case AST_REDIRECTING_FROM_NAME:
09010 ast_free(redirecting->from.name.str);
09011 redirecting->from.name.str = ast_malloc(ie_len + 1);
09012 if (redirecting->from.name.str) {
09013 memcpy(redirecting->from.name.str, data + pos, ie_len);
09014 redirecting->from.name.str[ie_len] = 0;
09015 }
09016 break;
09017 case AST_REDIRECTING_FROM_NAME_CHAR_SET:
09018 if (ie_len != 1) {
09019 ast_log(LOG_WARNING, "Invalid redirecting-from name char set (%u)\n",
09020 (unsigned) ie_len);
09021 break;
09022 }
09023 redirecting->from.name.char_set = data[pos];
09024 break;
09025 case AST_REDIRECTING_FROM_NAME_PRESENTATION:
09026 if (ie_len != 1) {
09027 ast_log(LOG_WARNING, "Invalid redirecting-from name presentation (%u)\n",
09028 (unsigned) ie_len);
09029 break;
09030 }
09031 redirecting->from.name.presentation = data[pos];
09032 break;
09033 case AST_REDIRECTING_FROM_NAME_VALID:
09034 if (ie_len != 1) {
09035 ast_log(LOG_WARNING, "Invalid redirecting-from name valid (%u)\n",
09036 (unsigned) ie_len);
09037 break;
09038 }
09039 redirecting->from.name.valid = data[pos];
09040 break;
09041
09042 case AST_REDIRECTING_FROM_NUMBER:
09043 ast_free(redirecting->from.number.str);
09044 redirecting->from.number.str = ast_malloc(ie_len + 1);
09045 if (redirecting->from.number.str) {
09046 memcpy(redirecting->from.number.str, data + pos, ie_len);
09047 redirecting->from.number.str[ie_len] = 0;
09048 }
09049 break;
09050 case AST_REDIRECTING_FROM_NUMBER_PLAN:
09051 if (ie_len != 1) {
09052 ast_log(LOG_WARNING, "Invalid redirecting-from numbering plan (%u)\n",
09053 (unsigned) ie_len);
09054 break;
09055 }
09056 redirecting->from.number.plan = data[pos];
09057 break;
09058 case AST_REDIRECTING_FROM_NUMBER_PRESENTATION:
09059 if (ie_len != 1) {
09060 ast_log(LOG_WARNING, "Invalid redirecting-from number presentation (%u)\n",
09061 (unsigned) ie_len);
09062 break;
09063 }
09064 redirecting->from.number.presentation = data[pos];
09065 break;
09066 case AST_REDIRECTING_FROM_NUMBER_VALID:
09067 if (ie_len != 1) {
09068 ast_log(LOG_WARNING, "Invalid redirecting-from number valid (%u)\n",
09069 (unsigned) ie_len);
09070 break;
09071 }
09072 redirecting->from.number.valid = data[pos];
09073 break;
09074
09075 case AST_REDIRECTING_FROM_ID_PRESENTATION:
09076 if (ie_len != 1) {
09077 ast_log(LOG_WARNING, "Invalid redirecting-from combined presentation (%u)\n",
09078 (unsigned) ie_len);
09079 break;
09080 }
09081 from_combined_presentation = data[pos];
09082 got_from_combined_presentation = 1;
09083 break;
09084
09085 case AST_REDIRECTING_FROM_SUBADDRESS:
09086 ast_free(redirecting->from.subaddress.str);
09087 redirecting->from.subaddress.str = ast_malloc(ie_len + 1);
09088 if (redirecting->from.subaddress.str) {
09089 memcpy(redirecting->from.subaddress.str, data + pos, ie_len);
09090 redirecting->from.subaddress.str[ie_len] = 0;
09091 }
09092 break;
09093 case AST_REDIRECTING_FROM_SUBADDRESS_TYPE:
09094 if (ie_len != 1) {
09095 ast_log(LOG_WARNING, "Invalid redirecting-from type of subaddress (%u)\n",
09096 (unsigned) ie_len);
09097 break;
09098 }
09099 redirecting->from.subaddress.type = data[pos];
09100 break;
09101 case AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN:
09102 if (ie_len != 1) {
09103 ast_log(LOG_WARNING,
09104 "Invalid redirecting-from subaddress odd-even indicator (%u)\n",
09105 (unsigned) ie_len);
09106 break;
09107 }
09108 redirecting->from.subaddress.odd_even_indicator = data[pos];
09109 break;
09110 case AST_REDIRECTING_FROM_SUBADDRESS_VALID:
09111 if (ie_len != 1) {
09112 ast_log(LOG_WARNING, "Invalid redirecting-from subaddress valid (%u)\n",
09113 (unsigned) ie_len);
09114 break;
09115 }
09116 redirecting->from.subaddress.valid = data[pos];
09117 break;
09118
09119 case AST_REDIRECTING_FROM_TAG:
09120 ast_free(redirecting->from.tag);
09121 redirecting->from.tag = ast_malloc(ie_len + 1);
09122 if (redirecting->from.tag) {
09123 memcpy(redirecting->from.tag, data + pos, ie_len);
09124 redirecting->from.tag[ie_len] = 0;
09125 }
09126 break;
09127
09128 case AST_REDIRECTING_TO_NAME:
09129 ast_free(redirecting->to.name.str);
09130 redirecting->to.name.str = ast_malloc(ie_len + 1);
09131 if (redirecting->to.name.str) {
09132 memcpy(redirecting->to.name.str, data + pos, ie_len);
09133 redirecting->to.name.str[ie_len] = 0;
09134 }
09135 break;
09136 case AST_REDIRECTING_TO_NAME_CHAR_SET:
09137 if (ie_len != 1) {
09138 ast_log(LOG_WARNING, "Invalid redirecting-to name char set (%u)\n",
09139 (unsigned) ie_len);
09140 break;
09141 }
09142 redirecting->to.name.char_set = data[pos];
09143 break;
09144 case AST_REDIRECTING_TO_NAME_PRESENTATION:
09145 if (ie_len != 1) {
09146 ast_log(LOG_WARNING, "Invalid redirecting-to name presentation (%u)\n",
09147 (unsigned) ie_len);
09148 break;
09149 }
09150 redirecting->to.name.presentation = data[pos];
09151 break;
09152 case AST_REDIRECTING_TO_NAME_VALID:
09153 if (ie_len != 1) {
09154 ast_log(LOG_WARNING, "Invalid redirecting-to name valid (%u)\n",
09155 (unsigned) ie_len);
09156 break;
09157 }
09158 redirecting->to.name.valid = data[pos];
09159 break;
09160
09161 case AST_REDIRECTING_TO_NUMBER:
09162 ast_free(redirecting->to.number.str);
09163 redirecting->to.number.str = ast_malloc(ie_len + 1);
09164 if (redirecting->to.number.str) {
09165 memcpy(redirecting->to.number.str, data + pos, ie_len);
09166 redirecting->to.number.str[ie_len] = 0;
09167 }
09168 break;
09169 case AST_REDIRECTING_TO_NUMBER_PLAN:
09170 if (ie_len != 1) {
09171 ast_log(LOG_WARNING, "Invalid redirecting-to numbering plan (%u)\n",
09172 (unsigned) ie_len);
09173 break;
09174 }
09175 redirecting->to.number.plan = data[pos];
09176 break;
09177 case AST_REDIRECTING_TO_NUMBER_PRESENTATION:
09178 if (ie_len != 1) {
09179 ast_log(LOG_WARNING, "Invalid redirecting-to number presentation (%u)\n",
09180 (unsigned) ie_len);
09181 break;
09182 }
09183 redirecting->to.number.presentation = data[pos];
09184 break;
09185 case AST_REDIRECTING_TO_NUMBER_VALID:
09186 if (ie_len != 1) {
09187 ast_log(LOG_WARNING, "Invalid redirecting-to number valid (%u)\n",
09188 (unsigned) ie_len);
09189 break;
09190 }
09191 redirecting->to.number.valid = data[pos];
09192 break;
09193
09194 case AST_REDIRECTING_TO_ID_PRESENTATION:
09195 if (ie_len != 1) {
09196 ast_log(LOG_WARNING, "Invalid redirecting-to combined presentation (%u)\n",
09197 (unsigned) ie_len);
09198 break;
09199 }
09200 to_combined_presentation = data[pos];
09201 got_to_combined_presentation = 1;
09202 break;
09203
09204 case AST_REDIRECTING_TO_SUBADDRESS:
09205 ast_free(redirecting->to.subaddress.str);
09206 redirecting->to.subaddress.str = ast_malloc(ie_len + 1);
09207 if (redirecting->to.subaddress.str) {
09208 memcpy(redirecting->to.subaddress.str, data + pos, ie_len);
09209 redirecting->to.subaddress.str[ie_len] = 0;
09210 }
09211 break;
09212 case AST_REDIRECTING_TO_SUBADDRESS_TYPE:
09213 if (ie_len != 1) {
09214 ast_log(LOG_WARNING, "Invalid redirecting-to type of subaddress (%u)\n",
09215 (unsigned) ie_len);
09216 break;
09217 }
09218 redirecting->to.subaddress.type = data[pos];
09219 break;
09220 case AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN:
09221 if (ie_len != 1) {
09222 ast_log(LOG_WARNING,
09223 "Invalid redirecting-to subaddress odd-even indicator (%u)\n",
09224 (unsigned) ie_len);
09225 break;
09226 }
09227 redirecting->to.subaddress.odd_even_indicator = data[pos];
09228 break;
09229 case AST_REDIRECTING_TO_SUBADDRESS_VALID:
09230 if (ie_len != 1) {
09231 ast_log(LOG_WARNING, "Invalid redirecting-to subaddress valid (%u)\n",
09232 (unsigned) ie_len);
09233 break;
09234 }
09235 redirecting->to.subaddress.valid = data[pos];
09236 break;
09237
09238 case AST_REDIRECTING_TO_TAG:
09239 ast_free(redirecting->to.tag);
09240 redirecting->to.tag = ast_malloc(ie_len + 1);
09241 if (redirecting->to.tag) {
09242 memcpy(redirecting->to.tag, data + pos, ie_len);
09243 redirecting->to.tag[ie_len] = 0;
09244 }
09245 break;
09246
09247 case AST_REDIRECTING_REASON:
09248 if (ie_len != sizeof(value)) {
09249 ast_log(LOG_WARNING, "Invalid redirecting reason (%u)\n",
09250 (unsigned) ie_len);
09251 break;
09252 }
09253 memcpy(&value, data + pos, sizeof(value));
09254 redirecting->reason = ntohl(value);
09255 break;
09256
09257 case AST_REDIRECTING_COUNT:
09258 if (ie_len != sizeof(value)) {
09259 ast_log(LOG_WARNING, "Invalid redirecting count (%u)\n",
09260 (unsigned) ie_len);
09261 break;
09262 }
09263 memcpy(&value, data + pos, sizeof(value));
09264 redirecting->count = ntohl(value);
09265 break;
09266
09267 default:
09268 ast_debug(1, "Unknown redirecting element: %u (%u)\n",
09269 (unsigned) ie_id, (unsigned) ie_len);
09270 break;
09271 }
09272 }
09273
09274 switch (frame_version) {
09275 case 1:
09276
09277
09278
09279
09280 redirecting->from.name.valid = 1;
09281 redirecting->from.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
09282 redirecting->from.number.valid = 1;
09283 if (got_from_combined_presentation) {
09284 redirecting->from.name.presentation = from_combined_presentation;
09285 redirecting->from.number.presentation = from_combined_presentation;
09286 }
09287
09288 redirecting->to.name.valid = 1;
09289 redirecting->to.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
09290 redirecting->to.number.valid = 1;
09291 if (got_to_combined_presentation) {
09292 redirecting->to.name.presentation = to_combined_presentation;
09293 redirecting->to.number.presentation = to_combined_presentation;
09294 }
09295 break;
09296 case 2:
09297
09298 break;
09299 default:
09300
09301
09302
09303
09304 ast_debug(1, "Redirecting frame has newer version: %u\n",
09305 (unsigned) frame_version);
09306 break;
09307 }
09308
09309 return 0;
09310 }
09311
09312 void ast_channel_update_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
09313 {
09314 unsigned char data[1024];
09315 size_t datalen;
09316
09317 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update);
09318 if (datalen == (size_t) -1) {
09319 return;
09320 }
09321
09322 ast_indicate_data(chan, AST_CONTROL_REDIRECTING, data, datalen);
09323 }
09324
09325 void ast_channel_queue_redirecting_update(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
09326 {
09327 unsigned char data[1024];
09328 size_t datalen;
09329
09330 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update);
09331 if (datalen == (size_t) -1) {
09332 return;
09333 }
09334
09335 ast_queue_control_data(chan, AST_CONTROL_REDIRECTING, data, datalen);
09336 }
09337
09338 int ast_channel_connected_line_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *connected_info, int is_caller, int is_frame)
09339 {
09340 const char *macro;
09341 const char *macro_args;
09342 int retval;
09343
09344 ast_channel_lock(macro_chan);
09345 macro = pbx_builtin_getvar_helper(macro_chan, is_caller
09346 ? "CONNECTED_LINE_CALLER_SEND_MACRO" : "CONNECTED_LINE_CALLEE_SEND_MACRO");
09347 macro = ast_strdupa(S_OR(macro, ""));
09348 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller
09349 ? "CONNECTED_LINE_CALLER_SEND_MACRO_ARGS" : "CONNECTED_LINE_CALLEE_SEND_MACRO_ARGS");
09350 macro_args = ast_strdupa(S_OR(macro_args, ""));
09351
09352 if (ast_strlen_zero(macro)) {
09353 ast_channel_unlock(macro_chan);
09354 return -1;
09355 }
09356
09357 if (is_frame) {
09358 const struct ast_frame *frame = connected_info;
09359
09360 ast_connected_line_parse_data(frame->data.ptr, frame->datalen, ¯o_chan->connected);
09361 } else {
09362 const struct ast_party_connected_line *connected = connected_info;
09363
09364 ast_party_connected_line_copy(¯o_chan->connected, connected);
09365 }
09366 ast_channel_unlock(macro_chan);
09367
09368 if (!(retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args))) {
09369 ast_channel_lock(macro_chan);
09370 ast_channel_update_connected_line(macro_chan, ¯o_chan->connected, NULL);
09371 ast_channel_unlock(macro_chan);
09372 }
09373
09374 return retval;
09375 }
09376
09377 int ast_channel_redirecting_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *redirecting_info, int is_caller, int is_frame)
09378 {
09379 const char *macro;
09380 const char *macro_args;
09381 int retval;
09382
09383 ast_channel_lock(macro_chan);
09384 macro = pbx_builtin_getvar_helper(macro_chan, is_caller
09385 ? "REDIRECTING_CALLER_SEND_MACRO" : "REDIRECTING_CALLEE_SEND_MACRO");
09386 macro = ast_strdupa(S_OR(macro, ""));
09387 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller
09388 ? "REDIRECTING_CALLER_SEND_MACRO_ARGS" : "REDIRECTING_CALLEE_SEND_MACRO_ARGS");
09389 macro_args = ast_strdupa(S_OR(macro_args, ""));
09390
09391 if (ast_strlen_zero(macro)) {
09392 ast_channel_unlock(macro_chan);
09393 return -1;
09394 }
09395
09396 if (is_frame) {
09397 const struct ast_frame *frame = redirecting_info;
09398
09399 ast_redirecting_parse_data(frame->data.ptr, frame->datalen, ¯o_chan->redirecting);
09400 } else {
09401 const struct ast_party_redirecting *redirecting = redirecting_info;
09402
09403 ast_party_redirecting_copy(¯o_chan->redirecting, redirecting);
09404 }
09405 ast_channel_unlock(macro_chan);
09406
09407 retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args);
09408 if (!retval) {
09409 ast_channel_lock(macro_chan);
09410 ast_channel_update_redirecting(macro_chan, ¯o_chan->redirecting, NULL);
09411 ast_channel_unlock(macro_chan);
09412 }
09413
09414 return retval;
09415 }
09416
09417 static void *channel_cc_params_copy(void *data)
09418 {
09419 const struct ast_cc_config_params *src = data;
09420 struct ast_cc_config_params *dest = ast_cc_config_params_init();
09421 if (!dest) {
09422 return NULL;
09423 }
09424 ast_cc_copy_config_params(dest, src);
09425 return dest;
09426 }
09427
09428 static void channel_cc_params_destroy(void *data)
09429 {
09430 struct ast_cc_config_params *cc_params = data;
09431 ast_cc_config_params_destroy(cc_params);
09432 }
09433
09434 static const struct ast_datastore_info cc_channel_datastore_info = {
09435 .type = "Call Completion",
09436 .duplicate = channel_cc_params_copy,
09437 .destroy = channel_cc_params_destroy,
09438 };
09439
09440 int ast_channel_cc_params_init(struct ast_channel *chan,
09441 const struct ast_cc_config_params *base_params)
09442 {
09443 struct ast_cc_config_params *cc_params;
09444 struct ast_datastore *cc_datastore;
09445
09446 if (!(cc_params = ast_cc_config_params_init())) {
09447 return -1;
09448 }
09449
09450 if (!(cc_datastore = ast_datastore_alloc(&cc_channel_datastore_info, NULL))) {
09451 ast_cc_config_params_destroy(cc_params);
09452 return -1;
09453 }
09454
09455 if (base_params) {
09456 ast_cc_copy_config_params(cc_params, base_params);
09457 }
09458 cc_datastore->data = cc_params;
09459 ast_channel_datastore_add(chan, cc_datastore);
09460 return 0;
09461 }
09462
09463 struct ast_cc_config_params *ast_channel_get_cc_config_params(struct ast_channel *chan)
09464 {
09465 struct ast_datastore *cc_datastore;
09466
09467 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) {
09468
09469
09470
09471
09472 if (ast_channel_cc_params_init(chan, NULL)) {
09473 return NULL;
09474 }
09475 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) {
09476
09477 return NULL;
09478 }
09479 }
09480
09481 ast_assert(cc_datastore->data != NULL);
09482 return cc_datastore->data;
09483 }
09484
09485 int ast_channel_get_device_name(struct ast_channel *chan, char *device_name, size_t name_buffer_length)
09486 {
09487 int len = name_buffer_length;
09488 char *dash;
09489 if (!ast_channel_queryoption(chan, AST_OPTION_DEVICE_NAME, device_name, &len, 0)) {
09490 return 0;
09491 }
09492
09493
09494 ast_copy_string(device_name, ast_channel_name(chan), name_buffer_length);
09495 if ((dash = strrchr(device_name, '-'))) {
09496 *dash = '\0';
09497 }
09498
09499 return 0;
09500 }
09501
09502 int ast_channel_get_cc_agent_type(struct ast_channel *chan, char *agent_type, size_t size)
09503 {
09504 int len = size;
09505 char *slash;
09506
09507 if (!ast_channel_queryoption(chan, AST_OPTION_CC_AGENT_TYPE, agent_type, &len, 0)) {
09508 return 0;
09509 }
09510
09511 ast_copy_string(agent_type, ast_channel_name(chan), size);
09512 if ((slash = strchr(agent_type, '/'))) {
09513 *slash = '\0';
09514 }
09515 return 0;
09516 }
09517
09518
09519
09520
09521
09522
09523
09524
09525
09526
09527 #undef ast_channel_alloc
09528 struct ast_channel __attribute__((format(printf, 10, 11)))
09529 *ast_channel_alloc(int needqueue, int state, const char *cid_num,
09530 const char *cid_name, const char *acctcode,
09531 const char *exten, const char *context,
09532 const char *linkedid, const int amaflag,
09533 const char *name_fmt, ...);
09534 struct ast_channel *ast_channel_alloc(int needqueue, int state, const char *cid_num,
09535 const char *cid_name, const char *acctcode,
09536 const char *exten, const char *context,
09537 const char *linkedid, const int amaflag,
09538 const char *name_fmt, ...)
09539 {
09540 va_list ap;
09541 struct ast_channel *result;
09542
09543
09544 va_start(ap, name_fmt);
09545 result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context,
09546 linkedid, amaflag, __FILE__, __LINE__, __FUNCTION__, name_fmt, ap);
09547 va_end(ap);
09548
09549 return result;
09550 }
09551
09552 void ast_channel_unlink(struct ast_channel *chan)
09553 {
09554 ao2_unlink(channels, chan);
09555 }