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