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: 413587 $")
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 (%u)", 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 = %u): %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 %u 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 static void deactivate_generator_nolock(struct ast_channel *chan)
03059 {
03060 if (ast_channel_generatordata(chan)) {
03061 struct ast_generator *generator = ast_channel_generator(chan);
03062
03063 if (generator && generator->release) {
03064 generator->release(chan, ast_channel_generatordata(chan));
03065 }
03066 ast_channel_generatordata_set(chan, NULL);
03067 ast_channel_generator_set(chan, NULL);
03068 ast_channel_set_fd(chan, AST_GENERATOR_FD, -1);
03069 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_WRITE_INT);
03070 ast_settimeout(chan, 0, NULL, NULL);
03071 }
03072 }
03073
03074 void ast_deactivate_generator(struct ast_channel *chan)
03075 {
03076 ast_channel_lock(chan);
03077 deactivate_generator_nolock(chan);
03078 ast_channel_unlock(chan);
03079 }
03080
03081 static void generator_write_format_change(struct ast_channel *chan)
03082 {
03083 struct ast_generator *generator;
03084
03085 ast_channel_lock(chan);
03086 generator = ast_channel_generator(chan);
03087 if (generator && generator->write_format_change) {
03088 generator->write_format_change(chan, ast_channel_generatordata(chan));
03089 }
03090 ast_channel_unlock(chan);
03091 }
03092
03093 static int generator_force(const void *data)
03094 {
03095
03096 void *tmp;
03097 int res;
03098 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = NULL;
03099 struct ast_channel *chan = (struct ast_channel *)data;
03100
03101 ast_channel_lock(chan);
03102 tmp = ast_channel_generatordata(chan);
03103 ast_channel_generatordata_set(chan, NULL);
03104 if (ast_channel_generator(chan))
03105 generate = ast_channel_generator(chan)->generate;
03106 ast_channel_unlock(chan);
03107
03108 if (!tmp || !generate)
03109 return 0;
03110
03111 res = generate(chan, tmp, 0, ast_format_rate(ast_channel_writeformat(chan)) / 50);
03112
03113 ast_channel_lock(chan);
03114 if (ast_channel_generator(chan) && generate == ast_channel_generator(chan)->generate) {
03115 ast_channel_generatordata_set(chan, tmp);
03116 }
03117 ast_channel_unlock(chan);
03118
03119 if (res) {
03120 ast_debug(1, "Auto-deactivating generator\n");
03121 ast_deactivate_generator(chan);
03122 }
03123
03124 return 0;
03125 }
03126
03127 int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, void *params)
03128 {
03129 int res = 0;
03130 void *generatordata = NULL;
03131
03132 ast_channel_lock(chan);
03133 if (ast_channel_generatordata(chan)) {
03134 struct ast_generator *generator_old = ast_channel_generator(chan);
03135
03136 if (generator_old && generator_old->release) {
03137 generator_old->release(chan, ast_channel_generatordata(chan));
03138 }
03139 }
03140 if (gen->alloc && !(generatordata = gen->alloc(chan, params))) {
03141 res = -1;
03142 }
03143 ast_channel_generatordata_set(chan, generatordata);
03144 if (!res) {
03145 ast_settimeout(chan, 50, generator_force, chan);
03146 ast_channel_generator_set(chan, gen);
03147 }
03148 ast_channel_unlock(chan);
03149
03150 ast_prod(chan);
03151
03152 return res;
03153 }
03154
03155
03156 int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception)
03157 {
03158 int winner = -1;
03159 ast_waitfor_nandfds(NULL, 0, fds, n, exception, &winner, ms);
03160 return winner;
03161 }
03162
03163
03164 #ifdef HAVE_EPOLL
03165 static struct ast_channel *ast_waitfor_nandfds_classic(struct ast_channel **c, int n, int *fds, int nfds,
03166 int *exception, int *outfd, int *ms)
03167 #else
03168 struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds, int nfds,
03169 int *exception, int *outfd, int *ms)
03170 #endif
03171 {
03172 struct timeval start = { 0 , 0 };
03173 struct pollfd *pfds = NULL;
03174 int res;
03175 long rms;
03176 int x, y, max;
03177 int sz;
03178 struct timeval now = { 0, 0 };
03179 struct timeval whentohangup = { 0, 0 }, diff;
03180 struct ast_channel *winner = NULL;
03181 struct fdmap {
03182 int chan;
03183 int fdno;
03184 } *fdmap = NULL;
03185
03186 if (outfd) {
03187 *outfd = -99999;
03188 }
03189 if (exception) {
03190 *exception = 0;
03191 }
03192
03193 if ((sz = n * AST_MAX_FDS + nfds)) {
03194 pfds = ast_alloca(sizeof(*pfds) * sz);
03195 fdmap = ast_alloca(sizeof(*fdmap) * sz);
03196 } else {
03197
03198 return NULL;
03199 }
03200
03201
03202 for (x = 0; x < n; x++) {
03203 while (ast_channel_masq(c[x])) {
03204 ast_do_masquerade(c[x]);
03205 }
03206
03207 ast_channel_lock(c[x]);
03208 if (!ast_tvzero(*ast_channel_whentohangup(c[x]))) {
03209 if (ast_tvzero(whentohangup))
03210 now = ast_tvnow();
03211 diff = ast_tvsub(*ast_channel_whentohangup(c[x]), now);
03212 if (diff.tv_sec < 0 || ast_tvzero(diff)) {
03213 ast_test_suite_event_notify("HANGUP_TIME", "Channel: %s", ast_channel_name(c[x]));
03214
03215 ast_channel_softhangup_internal_flag_add(c[x], AST_SOFTHANGUP_TIMEOUT);
03216 ast_channel_unlock(c[x]);
03217 return c[x];
03218 }
03219 if (ast_tvzero(whentohangup) || ast_tvcmp(diff, whentohangup) < 0)
03220 whentohangup = diff;
03221 }
03222 ast_channel_unlock(c[x]);
03223 }
03224
03225 rms = *ms;
03226
03227 if (!ast_tvzero(whentohangup) && whentohangup.tv_sec < INT_MAX / 1000) {
03228 rms = whentohangup.tv_sec * 1000 + whentohangup.tv_usec / 1000;
03229 if (*ms >= 0 && *ms < rms) {
03230 rms = *ms;
03231 }
03232 } else if (!ast_tvzero(whentohangup) && rms < 0) {
03233
03234 rms = INT_MAX;
03235 }
03236
03237
03238
03239
03240
03241 max = 0;
03242 for (x = 0; x < n; x++) {
03243 for (y = 0; y < AST_MAX_FDS; y++) {
03244 fdmap[max].fdno = y;
03245 fdmap[max].chan = x;
03246 max += ast_add_fd(&pfds[max], ast_channel_fd(c[x], y));
03247 }
03248 CHECK_BLOCKING(c[x]);
03249 }
03250
03251 for (x = 0; x < nfds; x++) {
03252 fdmap[max].chan = -1;
03253 max += ast_add_fd(&pfds[max], fds[x]);
03254 }
03255
03256 if (*ms > 0) {
03257 start = ast_tvnow();
03258 }
03259
03260 if (sizeof(int) == 4) {
03261 do {
03262 int kbrms = rms;
03263 if (kbrms > 600000) {
03264 kbrms = 600000;
03265 }
03266 res = ast_poll(pfds, max, kbrms);
03267 if (!res) {
03268 rms -= kbrms;
03269 }
03270 } while (!res && (rms > 0));
03271 } else {
03272 res = ast_poll(pfds, max, rms);
03273 }
03274 for (x = 0; x < n; x++) {
03275 ast_clear_flag(ast_channel_flags(c[x]), AST_FLAG_BLOCKING);
03276 }
03277 if (res < 0) {
03278 if (errno != EINTR) {
03279 *ms = -1;
03280 }
03281 return NULL;
03282 }
03283 if (!ast_tvzero(whentohangup)) {
03284 now = ast_tvnow();
03285 for (x = 0; x < n; x++) {
03286 if (!ast_tvzero(*ast_channel_whentohangup(c[x])) && ast_tvcmp(*ast_channel_whentohangup(c[x]), now) <= 0) {
03287 ast_test_suite_event_notify("HANGUP_TIME", "Channel: %s", ast_channel_name(c[x]));
03288 ast_channel_softhangup_internal_flag_add(c[x], AST_SOFTHANGUP_TIMEOUT);
03289 if (winner == NULL) {
03290 winner = c[x];
03291 }
03292 }
03293 }
03294 }
03295 if (res == 0) {
03296 *ms = 0;
03297 return winner;
03298 }
03299
03300
03301
03302
03303
03304 for (x = 0; x < max; x++) {
03305 res = pfds[x].revents;
03306 if (res == 0) {
03307 continue;
03308 }
03309 if (fdmap[x].chan >= 0) {
03310 winner = c[fdmap[x].chan];
03311 if (res & POLLPRI) {
03312 ast_set_flag(ast_channel_flags(winner), AST_FLAG_EXCEPTION);
03313 } else {
03314 ast_clear_flag(ast_channel_flags(winner), AST_FLAG_EXCEPTION);
03315 }
03316 ast_channel_fdno_set(winner, fdmap[x].fdno);
03317 } else {
03318 if (outfd) {
03319 *outfd = pfds[x].fd;
03320 }
03321 if (exception) {
03322 *exception = (res & POLLPRI) ? -1 : 0;
03323 }
03324 winner = NULL;
03325 }
03326 }
03327 if (*ms > 0) {
03328 *ms -= ast_tvdiff_ms(ast_tvnow(), start);
03329 if (*ms < 0) {
03330 *ms = 0;
03331 }
03332 }
03333 return winner;
03334 }
03335
03336 #ifdef HAVE_EPOLL
03337 static struct ast_channel *ast_waitfor_nandfds_simple(struct ast_channel *chan, int *ms)
03338 {
03339 struct timeval start = { 0 , 0 };
03340 int res = 0;
03341 struct epoll_event ev[1];
03342 long diff, rms = *ms;
03343 struct ast_channel *winner = NULL;
03344 struct ast_epoll_data *aed = NULL;
03345
03346
03347
03348 while (ast_channel_masq(chan)) {
03349 ast_do_masquerade(chan);
03350 }
03351
03352 ast_channel_lock(chan);
03353
03354 if (!ast_tvzero(*ast_channel_whentohangup(chan))) {
03355 if ((diff = ast_tvdiff_ms(*ast_channel_whentohangup(chan), ast_tvnow())) < 0) {
03356
03357 ast_channel_softhangup_internal_flag_add(chan, AST_SOFTHANGUP_TIMEOUT);
03358 ast_channel_unlock(chan);
03359 return NULL;
03360 }
03361
03362 if (rms > diff) {
03363 rms = diff;
03364 }
03365 }
03366
03367 ast_channel_unlock(chan);
03368
03369
03370 CHECK_BLOCKING(chan);
03371
03372 if (*ms > 0) {
03373 start = ast_tvnow();
03374 }
03375
03376
03377 res = epoll_wait(ast_channel_epfd(chan), ev, 1, rms);
03378
03379
03380 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_BLOCKING);
03381
03382
03383 if (res < 0) {
03384 if (errno != EINTR) {
03385 *ms = -1;
03386 }
03387 return NULL;
03388 }
03389
03390
03391 if (!ast_tvzero(*ast_channel_whentohangup(chan))) {
03392 if (ast_tvdiff_ms(ast_tvnow(), *ast_channel_whentohangup(chan)) >= 0) {
03393 ast_channel_softhangup_internal_flag_add(chan, AST_SOFTHANGUP_TIMEOUT);
03394 winner = chan;
03395 }
03396 }
03397
03398
03399 if (!res) {
03400 *ms = 0;
03401 return winner;
03402 }
03403
03404
03405 aed = ev[0].data.ptr;
03406 ast_channel_fdno_set(chan, aed->which);
03407 if (ev[0].events & EPOLLPRI) {
03408 ast_set_flag(ast_channel_flags(chan), AST_FLAG_EXCEPTION);
03409 } else {
03410 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_EXCEPTION);
03411 }
03412
03413 if (*ms > 0) {
03414 *ms -= ast_tvdiff_ms(ast_tvnow(), start);
03415 if (*ms < 0) {
03416 *ms = 0;
03417 }
03418 }
03419
03420 return chan;
03421 }
03422
03423 static struct ast_channel *ast_waitfor_nandfds_complex(struct ast_channel **c, int n, int *ms)
03424 {
03425 struct timeval start = { 0 , 0 };
03426 int res = 0, i;
03427 struct epoll_event ev[25] = { { 0, } };
03428 struct timeval now = { 0, 0 };
03429 long whentohangup = 0, diff = 0, rms = *ms;
03430 struct ast_channel *winner = NULL;
03431
03432 for (i = 0; i < n; i++) {
03433 while (ast_channel_masq(c[i])) {
03434 ast_do_masquerade(c[i]);
03435 }
03436
03437 ast_channel_lock(c[i]);
03438 if (!ast_tvzero(*ast_channel_whentohangup(c[i]))) {
03439 if (whentohangup == 0) {
03440 now = ast_tvnow();
03441 }
03442 if ((diff = ast_tvdiff_ms(*ast_channel_whentohangup(c[i]), now)) < 0) {
03443 ast_channel_softhangup_internal_flag_add(c[i], AST_SOFTHANGUP_TIMEOUT);
03444 ast_channel_unlock(c[i]);
03445 return c[i];
03446 }
03447 if (!whentohangup || whentohangup > diff) {
03448 whentohangup = diff;
03449 }
03450 }
03451 ast_channel_unlock(c[i]);
03452 CHECK_BLOCKING(c[i]);
03453 }
03454
03455 rms = *ms;
03456 if (whentohangup) {
03457 rms = whentohangup;
03458 if (*ms >= 0 && *ms < rms) {
03459 rms = *ms;
03460 }
03461 }
03462
03463 if (*ms > 0) {
03464 start = ast_tvnow();
03465 }
03466
03467 res = epoll_wait(ast_channel_epfd(c[0]), ev, 25, rms);
03468
03469 for (i = 0; i < n; i++) {
03470 ast_clear_flag(ast_channel_flags(c[i]), AST_FLAG_BLOCKING);
03471 }
03472
03473 if (res < 0) {
03474 if (errno != EINTR) {
03475 *ms = -1;
03476 }
03477 return NULL;
03478 }
03479
03480 if (whentohangup) {
03481 now = ast_tvnow();
03482 for (i = 0; i < n; i++) {
03483 if (!ast_tvzero(*ast_channel_whentohangup(c[i])) && ast_tvdiff_ms(now, *ast_channel_whentohangup(c[i])) >= 0) {
03484 ast_channel_softhangup_internal_flag_add(c[i], AST_SOFTHANGUP_TIMEOUT);
03485 if (!winner) {
03486 winner = c[i];
03487 }
03488 }
03489 }
03490 }
03491
03492 if (!res) {
03493 *ms = 0;
03494 return winner;
03495 }
03496
03497 for (i = 0; i < res; i++) {
03498 struct ast_epoll_data *aed = ev[i].data.ptr;
03499
03500 if (!ev[i].events || !aed) {
03501 continue;
03502 }
03503
03504 winner = aed->chan;
03505 if (ev[i].events & EPOLLPRI) {
03506 ast_set_flag(ast_channel_flags(winner), AST_FLAG_EXCEPTION);
03507 } else {
03508 ast_clear_flag(ast_channel_flags(winner), AST_FLAG_EXCEPTION);
03509 }
03510 ast_channel_fdno_set(winner, aed->which);
03511 }
03512
03513 if (*ms > 0) {
03514 *ms -= ast_tvdiff_ms(ast_tvnow(), start);
03515 if (*ms < 0) {
03516 *ms = 0;
03517 }
03518 }
03519
03520 return winner;
03521 }
03522
03523 struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds, int nfds,
03524 int *exception, int *outfd, int *ms)
03525 {
03526
03527 if (outfd) {
03528 *outfd = -99999;
03529 }
03530 if (exception) {
03531 *exception = 0;
03532 }
03533
03534
03535 if (!n || nfds || ast_channel_epfd(c[0]) == -1) {
03536 return ast_waitfor_nandfds_classic(c, n, fds, nfds, exception, outfd, ms);
03537 } else if (!nfds && n == 1) {
03538 return ast_waitfor_nandfds_simple(c[0], ms);
03539 } else {
03540 return ast_waitfor_nandfds_complex(c, n, ms);
03541 }
03542 }
03543 #endif
03544
03545 struct ast_channel *ast_waitfor_n(struct ast_channel **c, int n, int *ms)
03546 {
03547 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
03548 }
03549
03550 int ast_waitfor(struct ast_channel *c, int ms)
03551 {
03552 if (ms < 0) {
03553 do {
03554 ms = 100000;
03555 ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms);
03556 } while (!ms);
03557 } else {
03558 ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms);
03559 }
03560 return ms;
03561 }
03562
03563 int ast_waitfordigit(struct ast_channel *c, int ms)
03564 {
03565 return ast_waitfordigit_full(c, ms, -1, -1);
03566 }
03567
03568 int ast_settimeout(struct ast_channel *c, unsigned int rate, int (*func)(const void *data), void *data)
03569 {
03570 return ast_settimeout_full(c, rate, func, data, 0);
03571 }
03572
03573 int ast_settimeout_full(struct ast_channel *c, unsigned int rate, int (*func)(const void *data), void *data, unsigned int is_ao2_obj)
03574 {
03575 int res;
03576 unsigned int real_rate = rate, max_rate;
03577
03578 ast_channel_lock(c);
03579
03580 if (ast_channel_timingfd(c) == -1) {
03581 ast_channel_unlock(c);
03582 return -1;
03583 }
03584
03585 if (!func) {
03586 rate = 0;
03587 data = NULL;
03588 }
03589
03590 if (rate && rate > (max_rate = ast_timer_get_max_rate(ast_channel_timer(c)))) {
03591 real_rate = max_rate;
03592 }
03593
03594 ast_debug(1, "Scheduling timer at (%u requested / %u actual) timer ticks per second\n", rate, real_rate);
03595
03596 res = ast_timer_set_rate(ast_channel_timer(c), real_rate);
03597
03598 if (ast_channel_timingdata(c) && ast_test_flag(ast_channel_flags(c), AST_FLAG_TIMINGDATA_IS_AO2_OBJ)) {
03599 ao2_ref(ast_channel_timingdata(c), -1);
03600 }
03601
03602 ast_channel_timingfunc_set(c, func);
03603 ast_channel_timingdata_set(c, data);
03604
03605 if (data && is_ao2_obj) {
03606 ao2_ref(data, 1);
03607 ast_set_flag(ast_channel_flags(c), AST_FLAG_TIMINGDATA_IS_AO2_OBJ);
03608 } else {
03609 ast_clear_flag(ast_channel_flags(c), AST_FLAG_TIMINGDATA_IS_AO2_OBJ);
03610 }
03611
03612 if (func == NULL && rate == 0 && ast_channel_fdno(c) == AST_TIMING_FD) {
03613
03614
03615
03616
03617
03618
03619 ast_channel_fdno_set(c, -1);
03620 }
03621
03622 ast_channel_unlock(c);
03623
03624 return res;
03625 }
03626
03627 int ast_waitfordigit_full(struct ast_channel *c, int timeout_ms, int audiofd, int cmdfd)
03628 {
03629 struct timeval start = ast_tvnow();
03630 int ms;
03631
03632
03633 if (ast_test_flag(ast_channel_flags(c), AST_FLAG_ZOMBIE) || ast_check_hangup(c))
03634 return -1;
03635
03636
03637 ast_set_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
03638
03639
03640
03641
03642 while ((ms = ast_remaining_ms(start, timeout_ms))) {
03643 struct ast_channel *rchan;
03644 int outfd = -1;
03645
03646 errno = 0;
03647
03648
03649
03650 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
03651
03652 if (!rchan && outfd < 0 && ms) {
03653 if (errno == 0 || errno == EINTR)
03654 continue;
03655 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
03656 ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
03657 return -1;
03658 } else if (outfd > -1) {
03659
03660 ast_log(LOG_WARNING, "The FD we were waiting for has something waiting. Waitfordigit returning numeric 1\n");
03661 ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
03662 return 1;
03663 } else if (rchan) {
03664 int res;
03665 struct ast_frame *f = ast_read(c);
03666 if (!f)
03667 return -1;
03668
03669 switch (f->frametype) {
03670 case AST_FRAME_DTMF_BEGIN:
03671 break;
03672 case AST_FRAME_DTMF_END:
03673 res = f->subclass.integer;
03674 ast_frfree(f);
03675 ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
03676 return res;
03677 case AST_FRAME_CONTROL:
03678 switch (f->subclass.integer) {
03679 case AST_CONTROL_HANGUP:
03680 ast_frfree(f);
03681 ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
03682 return -1;
03683 case AST_CONTROL_PVT_CAUSE_CODE:
03684 case AST_CONTROL_RINGING:
03685 case AST_CONTROL_ANSWER:
03686 case AST_CONTROL_SRCUPDATE:
03687 case AST_CONTROL_SRCCHANGE:
03688 case AST_CONTROL_CONNECTED_LINE:
03689 case AST_CONTROL_REDIRECTING:
03690 case AST_CONTROL_UPDATE_RTP_PEER:
03691 case AST_CONTROL_HOLD:
03692 case AST_CONTROL_UNHOLD:
03693 case -1:
03694
03695 break;
03696 default:
03697 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass.integer);
03698 break;
03699 }
03700 break;
03701 case AST_FRAME_VOICE:
03702
03703 if (audiofd > -1) {
03704 if (write(audiofd, f->data.ptr, f->datalen) < 0) {
03705 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
03706 }
03707 }
03708 default:
03709
03710 break;
03711 }
03712 ast_frfree(f);
03713 }
03714 }
03715
03716 ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
03717
03718 return 0;
03719 }
03720
03721 static void send_dtmf_event(struct ast_channel *chan, const char *direction, const char digit, const char *begin, const char *end)
03722 {
03723
03724
03725
03726
03727
03728
03729
03730
03731
03732
03733
03734
03735
03736
03737
03738
03739
03740
03741
03742
03743
03744
03745
03746
03747
03748 ast_manager_event(chan, EVENT_FLAG_DTMF,
03749 "DTMF",
03750 "Channel: %s\r\n"
03751 "Uniqueid: %s\r\n"
03752 "Digit: %c\r\n"
03753 "Direction: %s\r\n"
03754 "Begin: %s\r\n"
03755 "End: %s\r\n",
03756 ast_channel_name(chan), ast_channel_uniqueid(chan), digit, direction, begin, end);
03757 }
03758
03759 static void ast_read_generator_actions(struct ast_channel *chan, struct ast_frame *f)
03760 {
03761 struct ast_generator *generator;
03762 void *gendata;
03763 int res;
03764 int samples;
03765
03766 generator = ast_channel_generator(chan);
03767 if (!generator
03768 || !generator->generate
03769 || f->frametype != AST_FRAME_VOICE
03770 || !ast_channel_generatordata(chan)
03771 || ast_channel_timingfunc(chan)) {
03772 return;
03773 }
03774
03775
03776
03777
03778
03779
03780 if (ast_format_cmp(&f->subclass.format, ast_channel_writeformat(chan)) == AST_FORMAT_CMP_NOT_EQUAL) {
03781 float factor;
03782
03783 factor = ((float) ast_format_rate(ast_channel_writeformat(chan))) / ((float) ast_format_rate(&f->subclass.format));
03784 samples = (int) (((float) f->samples) * factor);
03785 } else {
03786 samples = f->samples;
03787 }
03788
03789 gendata = ast_channel_generatordata(chan);
03790 ast_channel_generatordata_set(chan, NULL);
03791
03792
03793
03794
03795
03796
03797
03798
03799
03800
03801
03802
03803 ast_channel_unlock(chan);
03804 res = generator->generate(chan, gendata, f->datalen, samples);
03805 ast_channel_lock(chan);
03806 if (generator == ast_channel_generator(chan)) {
03807 ast_channel_generatordata_set(chan, gendata);
03808 if (res) {
03809 ast_debug(1, "Auto-deactivating generator\n");
03810 ast_deactivate_generator(chan);
03811 }
03812 }
03813 }
03814
03815 static inline void queue_dtmf_readq(struct ast_channel *chan, struct ast_frame *f)
03816 {
03817 struct ast_frame *fr = ast_channel_dtmff(chan);
03818
03819 fr->frametype = AST_FRAME_DTMF_END;
03820 fr->subclass.integer = f->subclass.integer;
03821 fr->len = f->len;
03822
03823
03824
03825
03826
03827 ast_queue_frame(chan, fr);
03828 }
03829
03830
03831
03832
03833 static inline int should_skip_dtmf(struct ast_channel *chan)
03834 {
03835 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF)) {
03836
03837
03838 return 1;
03839 }
03840
03841 if (!ast_tvzero(*ast_channel_dtmf_tv(chan)) &&
03842 ast_tvdiff_ms(ast_tvnow(), *ast_channel_dtmf_tv(chan)) < AST_MIN_DTMF_GAP) {
03843
03844
03845 return 1;
03846 }
03847
03848 return 0;
03849 }
03850
03851
03852
03853
03854
03855
03856
03857
03858
03859
03860 static inline int calc_monitor_jump(int samples, int sample_rate, int seek_rate)
03861 {
03862 int diff = sample_rate - seek_rate;
03863
03864 if (diff > 0) {
03865 samples = samples / (float) (sample_rate / seek_rate);
03866 } else if (diff < 0) {
03867 samples = samples * (float) (seek_rate / sample_rate);
03868 }
03869
03870 return samples;
03871 }
03872
03873 static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
03874 {
03875 struct ast_frame *f = NULL;
03876 int prestate;
03877 int cause = 0;
03878
03879
03880
03881
03882
03883 if (ast_channel_masq(chan)) {
03884 ast_do_masquerade(chan);
03885 return &ast_null_frame;
03886 }
03887
03888
03889 ast_channel_lock(chan);
03890
03891
03892 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
03893 if (ast_channel_generator(chan))
03894 ast_deactivate_generator(chan);
03895
03896
03897
03898
03899
03900
03901
03902
03903
03904
03905 if (ast_channel_softhangup_internal_flag(chan)) {
03906 ast_queue_control(chan, AST_CONTROL_END_OF_Q);
03907 } else {
03908 goto done;
03909 }
03910 } else {
03911 #ifdef AST_DEVMODE
03912
03913
03914
03915
03916
03917
03918
03919
03920
03921
03922
03923
03924 if (ast_channel_fdno(chan) == -1) {
03925 ast_log(LOG_ERROR,
03926 "ast_read() on chan '%s' called with no recorded file descriptor.\n",
03927 ast_channel_name(chan));
03928 }
03929 #endif
03930 }
03931
03932 prestate = ast_channel_state(chan);
03933
03934 if (ast_channel_timingfd(chan) > -1 && ast_channel_fdno(chan) == AST_TIMING_FD) {
03935 enum ast_timer_event res;
03936
03937 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_EXCEPTION);
03938
03939 res = ast_timer_get_event(ast_channel_timer(chan));
03940
03941 switch (res) {
03942 case AST_TIMING_EVENT_EXPIRED:
03943 if (ast_timer_ack(ast_channel_timer(chan), 1) < 0) {
03944 ast_log(LOG_ERROR, "Failed to acknoweldge timer in ast_read\n");
03945 goto done;
03946 }
03947
03948 if (ast_channel_timingfunc(chan)) {
03949
03950 ast_timing_func_t func = ast_channel_timingfunc(chan);
03951 void *data = ast_channel_timingdata(chan);
03952 int got_ref = 0;
03953 if (data && ast_test_flag(ast_channel_flags(chan), AST_FLAG_TIMINGDATA_IS_AO2_OBJ)) {
03954 ao2_ref(data, 1);
03955 got_ref = 1;
03956 }
03957 ast_channel_fdno_set(chan, -1);
03958 ast_channel_unlock(chan);
03959 func(data);
03960 if (got_ref) {
03961 ao2_ref(data, -1);
03962 }
03963 } else {
03964 ast_timer_set_rate(ast_channel_timer(chan), 0);
03965 ast_channel_fdno_set(chan, -1);
03966 ast_channel_unlock(chan);
03967 }
03968
03969
03970 return &ast_null_frame;
03971
03972 case AST_TIMING_EVENT_CONTINUOUS:
03973 if (AST_LIST_EMPTY(ast_channel_readq(chan)) ||
03974 !AST_LIST_NEXT(AST_LIST_FIRST(ast_channel_readq(chan)), frame_list)) {
03975 ast_timer_disable_continuous(ast_channel_timer(chan));
03976 }
03977 break;
03978 }
03979
03980 } else if (ast_channel_fd_isset(chan, AST_GENERATOR_FD) && ast_channel_fdno(chan) == AST_GENERATOR_FD) {
03981
03982
03983
03984 void *tmp = ast_channel_generatordata(chan);
03985 ast_channel_generatordata_set(chan, NULL);
03986 ast_channel_generator(chan)->generate(chan, tmp, -1, -1);
03987 ast_channel_generatordata_set(chan, tmp);
03988 f = &ast_null_frame;
03989 ast_channel_fdno_set(chan, -1);
03990 goto done;
03991 } else if (ast_channel_fd_isset(chan, AST_JITTERBUFFER_FD) && ast_channel_fdno(chan) == AST_JITTERBUFFER_FD) {
03992 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_EXCEPTION);
03993 }
03994
03995
03996
03997 if (ast_channel_internal_alert_read(chan) == AST_ALERT_READ_FATAL) {
03998 f = &ast_null_frame;
03999 goto done;
04000 }
04001
04002
04003 if (!AST_LIST_EMPTY(ast_channel_readq(chan))) {
04004 int skip_dtmf = should_skip_dtmf(chan);
04005
04006 AST_LIST_TRAVERSE_SAFE_BEGIN(ast_channel_readq(chan), f, frame_list) {
04007
04008
04009
04010
04011 if ( (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && skip_dtmf) {
04012 continue;
04013 }
04014
04015 AST_LIST_REMOVE_CURRENT(frame_list);
04016 break;
04017 }
04018 AST_LIST_TRAVERSE_SAFE_END;
04019
04020 if (!f) {
04021
04022 f = &ast_null_frame;
04023 ast_channel_alert_write(chan);
04024 }
04025
04026
04027
04028 if (f->frametype == AST_FRAME_CONTROL) {
04029 switch (f->subclass.integer) {
04030 case AST_CONTROL_HANGUP:
04031 ast_channel_softhangup_internal_flag_add(chan, AST_SOFTHANGUP_DEV);
04032 cause = f->data.uint32;
04033
04034 case AST_CONTROL_END_OF_Q:
04035 ast_frfree(f);
04036 f = NULL;
04037 break;
04038 default:
04039 break;
04040 }
04041 }
04042 } else {
04043 ast_channel_blocker_set(chan, pthread_self());
04044 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_EXCEPTION)) {
04045 if (ast_channel_tech(chan)->exception)
04046 f = ast_channel_tech(chan)->exception(chan);
04047 else {
04048 ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", ast_channel_name(chan));
04049 f = &ast_null_frame;
04050 }
04051
04052 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_EXCEPTION);
04053 } else if (ast_channel_tech(chan) && ast_channel_tech(chan)->read)
04054 f = ast_channel_tech(chan)->read(chan);
04055 else
04056 ast_log(LOG_WARNING, "No read routine on channel %s\n", ast_channel_name(chan));
04057 }
04058
04059
04060
04061 f = ast_framehook_list_read_event(ast_channel_framehooks(chan), f);
04062
04063
04064
04065
04066
04067 ast_channel_fdno_set(chan, -1);
04068
04069 if (f) {
04070 struct ast_frame *readq_tail = AST_LIST_LAST(ast_channel_readq(chan));
04071 struct ast_control_read_action_payload *read_action_payload;
04072 struct ast_party_connected_line connected;
04073
04074
04075
04076
04077 if (AST_LIST_NEXT(f, frame_list)) {
04078 ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list));
04079 ast_frfree(AST_LIST_NEXT(f, frame_list));
04080 AST_LIST_NEXT(f, frame_list) = NULL;
04081 }
04082
04083 switch (f->frametype) {
04084 case AST_FRAME_CONTROL:
04085 if (f->subclass.integer == AST_CONTROL_ANSWER) {
04086 if (!ast_test_flag(ast_channel_flags(chan), AST_FLAG_OUTGOING)) {
04087 ast_debug(1, "Ignoring answer on an inbound call!\n");
04088 ast_frfree(f);
04089 f = &ast_null_frame;
04090 } else if (prestate == AST_STATE_UP && ast_bridged_channel(chan)) {
04091 ast_debug(1, "Dropping duplicate answer!\n");
04092 ast_frfree(f);
04093 f = &ast_null_frame;
04094 } else {
04095
04096 ast_setstate(chan, AST_STATE_UP);
04097
04098 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL);
04099 }
04100 } else if (f->subclass.integer == AST_CONTROL_READ_ACTION) {
04101 read_action_payload = f->data.ptr;
04102 switch (read_action_payload->action) {
04103 case AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO:
04104 ast_party_connected_line_init(&connected);
04105 ast_party_connected_line_copy(&connected, ast_channel_connected(chan));
04106 if (ast_connected_line_parse_data(read_action_payload->payload,
04107 read_action_payload->payload_size, &connected)) {
04108 ast_party_connected_line_free(&connected);
04109 break;
04110 }
04111 ast_channel_unlock(chan);
04112 if (ast_channel_connected_line_sub(NULL, chan, &connected, 0) &&
04113 ast_channel_connected_line_macro(NULL, chan, &connected, 1, 0)) {
04114 ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE,
04115 read_action_payload->payload,
04116 read_action_payload->payload_size);
04117 }
04118 ast_party_connected_line_free(&connected);
04119 ast_channel_lock(chan);
04120 break;
04121 }
04122 ast_frfree(f);
04123 f = &ast_null_frame;
04124 }
04125 break;
04126 case AST_FRAME_DTMF_END:
04127 send_dtmf_event(chan, "Received", f->subclass.integer, "No", "Yes");
04128 ast_log(LOG_DTMF, "DTMF end '%c' received on %s, duration %ld ms\n", f->subclass.integer, ast_channel_name(chan), f->len);
04129
04130 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_DEFER_DTMF) || ast_test_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF)) {
04131 queue_dtmf_readq(chan, f);
04132 ast_frfree(f);
04133 f = &ast_null_frame;
04134 } else if (!ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_DTMF | AST_FLAG_END_DTMF_ONLY)) {
04135 if (!ast_tvzero(*ast_channel_dtmf_tv(chan)) &&
04136 ast_tvdiff_ms(ast_tvnow(), *ast_channel_dtmf_tv(chan)) < AST_MIN_DTMF_GAP) {
04137
04138 queue_dtmf_readq(chan, f);
04139 ast_frfree(f);
04140 f = &ast_null_frame;
04141 } else {
04142
04143 struct timeval tv = ast_tvnow();
04144 f->frametype = AST_FRAME_DTMF_BEGIN;
04145 ast_set_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF);
04146 ast_channel_dtmf_digit_to_emulate_set(chan, f->subclass.integer);
04147 ast_channel_dtmf_tv_set(chan, &tv);
04148 if (f->len) {
04149 if (f->len > option_dtmfminduration)
04150 ast_channel_emulate_dtmf_duration_set(chan, f->len);
04151 else
04152 ast_channel_emulate_dtmf_duration_set(chan, option_dtmfminduration);
04153 } else
04154 ast_channel_emulate_dtmf_duration_set(chan, AST_DEFAULT_EMULATE_DTMF_DURATION);
04155 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));
04156 }
04157 if (ast_channel_audiohooks(chan)) {
04158 struct ast_frame *old_frame = f;
04159
04160
04161
04162 f = ast_audiohook_write_list(chan, ast_channel_audiohooks(chan), AST_AUDIOHOOK_DIRECTION_READ, f);
04163 if (old_frame != f)
04164 ast_frfree(old_frame);
04165 }
04166 } else {
04167 struct timeval now = ast_tvnow();
04168 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_DTMF)) {
04169 ast_log(LOG_DTMF, "DTMF end accepted with begin '%c' on %s\n", f->subclass.integer, ast_channel_name(chan));
04170 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_IN_DTMF);
04171 if (!f->len)
04172 f->len = ast_tvdiff_ms(now, *ast_channel_dtmf_tv(chan));
04173
04174
04175
04176
04177
04178
04179
04180
04181
04182 if (ast_tvdiff_ms(now, *ast_channel_dtmf_tv(chan)) < option_dtmfminduration) {
04183 f->len = ast_tvdiff_ms(now, *ast_channel_dtmf_tv(chan));
04184 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));
04185 }
04186 } else if (!f->len) {
04187 ast_log(LOG_DTMF, "DTMF end accepted without begin '%c' on %s\n", f->subclass.integer, ast_channel_name(chan));
04188 f->len = option_dtmfminduration;
04189 }
04190 if (f->len < option_dtmfminduration && !ast_test_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY)) {
04191 ast_log(LOG_DTMF, "DTMF end '%c' has duration %ld but want minimum %u, emulating on %s\n", f->subclass.integer, f->len, option_dtmfminduration, ast_channel_name(chan));
04192 ast_set_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF);
04193 ast_channel_dtmf_digit_to_emulate_set(chan, f->subclass.integer);
04194 ast_channel_emulate_dtmf_duration_set(chan, option_dtmfminduration - f->len);
04195 ast_frfree(f);
04196 f = &ast_null_frame;
04197 } else {
04198 ast_log(LOG_DTMF, "DTMF end passthrough '%c' on %s\n", f->subclass.integer, ast_channel_name(chan));
04199 if (f->len < option_dtmfminduration) {
04200 f->len = option_dtmfminduration;
04201 }
04202 ast_channel_dtmf_tv_set(chan, &now);
04203 }
04204 if (ast_channel_audiohooks(chan)) {
04205 struct ast_frame *old_frame = f;
04206 f = ast_audiohook_write_list(chan, ast_channel_audiohooks(chan), AST_AUDIOHOOK_DIRECTION_READ, f);
04207 if (old_frame != f)
04208 ast_frfree(old_frame);
04209 }
04210 }
04211 break;
04212 case AST_FRAME_DTMF_BEGIN:
04213 send_dtmf_event(chan, "Received", f->subclass.integer, "Yes", "No");
04214 ast_log(LOG_DTMF, "DTMF begin '%c' received on %s\n", f->subclass.integer, ast_channel_name(chan));
04215 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_DEFER_DTMF | AST_FLAG_END_DTMF_ONLY | AST_FLAG_EMULATE_DTMF) ||
04216 (!ast_tvzero(*ast_channel_dtmf_tv(chan)) &&
04217 ast_tvdiff_ms(ast_tvnow(), *ast_channel_dtmf_tv(chan)) < AST_MIN_DTMF_GAP) ) {
04218 ast_log(LOG_DTMF, "DTMF begin ignored '%c' on %s\n", f->subclass.integer, ast_channel_name(chan));
04219 ast_frfree(f);
04220 f = &ast_null_frame;
04221 } else {
04222 struct timeval now = ast_tvnow();
04223 ast_set_flag(ast_channel_flags(chan), AST_FLAG_IN_DTMF);
04224 ast_channel_dtmf_tv_set(chan, &now);
04225 ast_log(LOG_DTMF, "DTMF begin passthrough '%c' on %s\n", f->subclass.integer, ast_channel_name(chan));
04226 }
04227 break;
04228 case AST_FRAME_NULL:
04229
04230
04231
04232
04233 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF)) {
04234 struct timeval now = ast_tvnow();
04235 if (!ast_channel_emulate_dtmf_duration(chan)) {
04236 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF);
04237 ast_channel_dtmf_digit_to_emulate_set(chan, 0);
04238 } else if (ast_tvdiff_ms(now, *ast_channel_dtmf_tv(chan)) >= ast_channel_emulate_dtmf_duration(chan)) {
04239 ast_channel_emulate_dtmf_duration_set(chan, 0);
04240 ast_frfree(f);
04241 f = ast_channel_dtmff(chan);
04242 f->frametype = AST_FRAME_DTMF_END;
04243 f->subclass.integer = ast_channel_dtmf_digit_to_emulate(chan);
04244 f->len = ast_tvdiff_ms(now, *ast_channel_dtmf_tv(chan));
04245 ast_channel_dtmf_tv_set(chan, &now);
04246 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF);
04247 ast_channel_dtmf_digit_to_emulate_set(chan, 0);
04248 ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass.integer, ast_channel_name(chan));
04249 if (ast_channel_audiohooks(chan)) {
04250 struct ast_frame *old_frame = f;
04251 f = ast_audiohook_write_list(chan, ast_channel_audiohooks(chan), AST_AUDIOHOOK_DIRECTION_READ, f);
04252 if (old_frame != f) {
04253 ast_frfree(old_frame);
04254 }
04255 }
04256 }
04257 }
04258 break;
04259 case AST_FRAME_VOICE:
04260
04261
04262
04263
04264 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF) && !ast_channel_emulate_dtmf_duration(chan)) {
04265 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF);
04266 ast_channel_dtmf_digit_to_emulate_set(chan, 0);
04267 }
04268
04269 if (dropaudio || ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_DTMF)) {
04270 if (dropaudio)
04271 ast_read_generator_actions(chan, f);
04272 ast_frfree(f);
04273 f = &ast_null_frame;
04274 }
04275
04276 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF) && !ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_DTMF)) {
04277 struct timeval now = ast_tvnow();
04278 if (ast_tvdiff_ms(now, *ast_channel_dtmf_tv(chan)) >= ast_channel_emulate_dtmf_duration(chan)) {
04279 ast_channel_emulate_dtmf_duration_set(chan, 0);
04280 ast_frfree(f);
04281 f = ast_channel_dtmff(chan);
04282 f->frametype = AST_FRAME_DTMF_END;
04283 f->subclass.integer = ast_channel_dtmf_digit_to_emulate(chan);
04284 f->len = ast_tvdiff_ms(now, *ast_channel_dtmf_tv(chan));
04285 ast_channel_dtmf_tv_set(chan, &now);
04286 if (ast_channel_audiohooks(chan)) {
04287 struct ast_frame *old_frame = f;
04288 f = ast_audiohook_write_list(chan, ast_channel_audiohooks(chan), AST_AUDIOHOOK_DIRECTION_READ, f);
04289 if (old_frame != f)
04290 ast_frfree(old_frame);
04291 }
04292 ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass.integer, ast_channel_name(chan));
04293 } else {
04294
04295 ast_frfree(f);
04296 f = &ast_null_frame;
04297 }
04298 } else if ((f->frametype == AST_FRAME_VOICE) && !ast_format_cap_iscompatible(ast_channel_nativeformats(chan), &f->subclass.format)) {
04299
04300 char to[200];
04301 ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n",
04302 ast_channel_name(chan), ast_getformatname(&f->subclass.format), ast_getformatname_multiple(to, sizeof(to), ast_channel_nativeformats(chan)));
04303 ast_frfree(f);
04304 f = &ast_null_frame;
04305 } else if ((f->frametype == AST_FRAME_VOICE)) {
04306
04307 if (ast_channel_audiohooks(chan)) {
04308 struct ast_frame *old_frame = f;
04309 f = ast_audiohook_write_list(chan, ast_channel_audiohooks(chan), AST_AUDIOHOOK_DIRECTION_READ, f);
04310 if (old_frame != f)
04311 ast_frfree(old_frame);
04312 }
04313 if (ast_channel_monitor(chan) && ast_channel_monitor(chan)->read_stream ) {
04314
04315 #ifndef MONITOR_CONSTANT_DELAY
04316 int jump = ast_channel_outsmpl(chan) - ast_channel_insmpl(chan) - 4 * f->samples;
04317 if (jump >= 0) {
04318 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));
04319 if (ast_seekstream(ast_channel_monitor(chan)->read_stream, jump, SEEK_FORCECUR) == -1) {
04320 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
04321 }
04322 ast_channel_insmpl_set(chan, ast_channel_insmpl(chan) + (ast_channel_outsmpl(chan) - ast_channel_insmpl(chan)) + f->samples);
04323 } else {
04324 ast_channel_insmpl_set(chan, ast_channel_insmpl(chan) + f->samples);
04325 }
04326 #else
04327 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));
04328 if (jump - MONITOR_DELAY >= 0) {
04329 if (ast_seekstream(ast_channel_monitor(chan)->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
04330 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
04331 ast_channel_insmpl(chan) += ast_channel_outsmpl(chan) - ast_channel_insmpl(chan);
04332 } else
04333 ast_channel_insmpl(chan) += f->samples;
04334 #endif
04335 if (ast_channel_monitor(chan)->state == AST_MONITOR_RUNNING) {
04336 if (ast_writestream(ast_channel_monitor(chan)->read_stream, f) < 0)
04337 ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
04338 }
04339 }
04340
04341 if (ast_channel_readtrans(chan) && (f = ast_translate(ast_channel_readtrans(chan), f, 1)) == NULL) {
04342 f = &ast_null_frame;
04343 }
04344
04345
04346
04347
04348
04349
04350
04351
04352 if (AST_LIST_NEXT(f, frame_list)) {
04353 if (!readq_tail) {
04354 ast_queue_frame_head(chan, AST_LIST_NEXT(f, frame_list));
04355 } else {
04356 __ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list), 0, readq_tail);
04357 }
04358 ast_frfree(AST_LIST_NEXT(f, frame_list));
04359 AST_LIST_NEXT(f, frame_list) = NULL;
04360 }
04361
04362
04363
04364 ast_read_generator_actions(chan, f);
04365 }
04366 break;
04367 default:
04368
04369 break;
04370 }
04371 } else {
04372
04373 if (!ast_channel_softhangup_internal_flag(chan)) {
04374 ast_channel_softhangup_internal_flag_add(chan, AST_SOFTHANGUP_DEV);
04375 }
04376 if (cause)
04377 ast_channel_hangupcause_set(chan, cause);
04378 if (ast_channel_generator(chan))
04379 ast_deactivate_generator(chan);
04380
04381 }
04382
04383
04384 if (ast_channel_fin(chan) & DEBUGCHAN_FLAG)
04385 ast_frame_dump(ast_channel_name(chan), f, "<<");
04386 ast_channel_fin_set(chan, FRAMECOUNT_INC(ast_channel_fin(chan)));
04387
04388 done:
04389 if (ast_channel_music_state(chan) && ast_channel_generator(chan) && ast_channel_generator(chan)->digit && f && f->frametype == AST_FRAME_DTMF_END)
04390 ast_channel_generator(chan)->digit(chan, f->subclass.integer);
04391
04392 if (ast_channel_audiohooks(chan) && ast_audiohook_write_list_empty(ast_channel_audiohooks(chan))) {
04393
04394 ast_audiohook_detach_list(ast_channel_audiohooks(chan));
04395 ast_channel_audiohooks_set(chan, NULL);
04396 }
04397 ast_channel_unlock(chan);
04398 return f;
04399 }
04400
04401 int ast_internal_timing_enabled(struct ast_channel *chan)
04402 {
04403 return ast_channel_timingfd(chan) > -1;
04404 }
04405
04406 struct ast_frame *ast_read(struct ast_channel *chan)
04407 {
04408 return __ast_read(chan, 0);
04409 }
04410
04411 struct ast_frame *ast_read_noaudio(struct ast_channel *chan)
04412 {
04413 return __ast_read(chan, 1);
04414 }
04415
04416 int ast_indicate(struct ast_channel *chan, int condition)
04417 {
04418 return ast_indicate_data(chan, condition, NULL, 0);
04419 }
04420
04421 static int attribute_const is_visible_indication(enum ast_control_frame_type condition)
04422 {
04423
04424
04425
04426 switch (condition) {
04427 case AST_CONTROL_PROGRESS:
04428 case AST_CONTROL_PROCEEDING:
04429 case AST_CONTROL_VIDUPDATE:
04430 case AST_CONTROL_SRCUPDATE:
04431 case AST_CONTROL_SRCCHANGE:
04432 case AST_CONTROL_RADIO_KEY:
04433 case AST_CONTROL_RADIO_UNKEY:
04434 case AST_CONTROL_OPTION:
04435 case AST_CONTROL_WINK:
04436 case AST_CONTROL_FLASH:
04437 case AST_CONTROL_OFFHOOK:
04438 case AST_CONTROL_TAKEOFFHOOK:
04439 case AST_CONTROL_ANSWER:
04440 case AST_CONTROL_HANGUP:
04441 case AST_CONTROL_CONNECTED_LINE:
04442 case AST_CONTROL_REDIRECTING:
04443 case AST_CONTROL_TRANSFER:
04444 case AST_CONTROL_T38_PARAMETERS:
04445 case _XXX_AST_CONTROL_T38:
04446 case AST_CONTROL_CC:
04447 case AST_CONTROL_READ_ACTION:
04448 case AST_CONTROL_AOC:
04449 case AST_CONTROL_END_OF_Q:
04450 case AST_CONTROL_MCID:
04451 case AST_CONTROL_UPDATE_RTP_PEER:
04452 case AST_CONTROL_PVT_CAUSE_CODE:
04453 break;
04454
04455 case AST_CONTROL_INCOMPLETE:
04456 case AST_CONTROL_CONGESTION:
04457 case AST_CONTROL_BUSY:
04458 case AST_CONTROL_RINGING:
04459 case AST_CONTROL_RING:
04460 case AST_CONTROL_HOLD:
04461
04462 return 1;
04463
04464 case AST_CONTROL_UNHOLD:
04465
04466 break;
04467 }
04468
04469 return 0;
04470 }
04471
04472 void ast_channel_hangupcause_hash_set(struct ast_channel *chan, const struct ast_control_pvt_cause_code *cause_code, int datalen)
04473 {
04474 char causevar[256];
04475
04476 if (ast_channel_dialed_causes_add(chan, cause_code, datalen)) {
04477 ast_log(LOG_WARNING, "Unable to store hangup cause for %s on %s\n", cause_code->chan_name, ast_channel_name(chan));
04478 }
04479
04480 if (cause_code->emulate_sip_cause) {
04481 snprintf(causevar, sizeof(causevar), "HASH(SIP_CAUSE,%s)", cause_code->chan_name);
04482 ast_func_write(chan, causevar, cause_code->code);
04483 }
04484 }
04485
04486 int ast_indicate_data(struct ast_channel *chan, int _condition,
04487 const void *data, size_t datalen)
04488 {
04489
04490
04491 enum ast_control_frame_type condition = _condition;
04492 struct ast_tone_zone_sound *ts = NULL;
04493 int res;
04494
04495 struct ast_frame *awesome_frame = NULL;
04496
04497 ast_channel_lock(chan);
04498
04499
04500 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
04501 res = -1;
04502 goto indicate_cleanup;
04503 }
04504
04505 if (!ast_framehook_list_is_empty(ast_channel_framehooks(chan))) {
04506
04507 struct ast_frame frame = {
04508 .frametype = AST_FRAME_CONTROL,
04509 .subclass.integer = condition,
04510 .data.ptr = (void *) data,
04511 .datalen = datalen
04512 };
04513
04514
04515 awesome_frame = ast_frdup(&frame);
04516
04517
04518 if (!(awesome_frame = ast_framehook_list_write_event(ast_channel_framehooks(chan), awesome_frame))
04519 || awesome_frame->frametype != AST_FRAME_CONTROL) {
04520
04521 res = 0;
04522 goto indicate_cleanup;
04523 }
04524
04525 condition = awesome_frame->subclass.integer;
04526 data = awesome_frame->data.ptr;
04527 datalen = awesome_frame->datalen;
04528 }
04529
04530 switch (condition) {
04531 case AST_CONTROL_CONNECTED_LINE:
04532 {
04533 struct ast_party_connected_line connected;
04534
04535 ast_party_connected_line_set_init(&connected, ast_channel_connected(chan));
04536 res = ast_connected_line_parse_data(data, datalen, &connected);
04537 if (!res) {
04538 ast_channel_set_connected_line(chan, &connected, NULL);
04539 }
04540 ast_party_connected_line_free(&connected);
04541 }
04542 break;
04543
04544 case AST_CONTROL_REDIRECTING:
04545 {
04546 struct ast_party_redirecting redirecting;
04547
04548 ast_party_redirecting_set_init(&redirecting, ast_channel_redirecting(chan));
04549 res = ast_redirecting_parse_data(data, datalen, &redirecting);
04550 if (!res) {
04551 ast_channel_set_redirecting(chan, &redirecting, NULL);
04552 }
04553 ast_party_redirecting_free(&redirecting);
04554 }
04555 break;
04556
04557 default:
04558 break;
04559 }
04560
04561 if (is_visible_indication(condition)) {
04562
04563 ast_channel_visible_indication_set(chan, condition);
04564 } else if (condition == AST_CONTROL_UNHOLD || _condition < 0) {
04565
04566 ast_channel_visible_indication_set(chan, 0);
04567 }
04568
04569 if (ast_channel_tech(chan)->indicate) {
04570
04571 res = ast_channel_tech(chan)->indicate(chan, condition, data, datalen);
04572 } else {
04573 res = -1;
04574 }
04575
04576 if (!res) {
04577
04578 res = 0;
04579 goto indicate_cleanup;
04580 }
04581
04582
04583
04584
04585
04586
04587
04588 if (_condition < 0) {
04589
04590 ast_playtones_stop(chan);
04591 res = 0;
04592 goto indicate_cleanup;
04593 }
04594
04595
04596 switch (condition) {
04597 case _XXX_AST_CONTROL_T38:
04598
04599 res = -1;
04600 goto indicate_cleanup;
04601 case AST_CONTROL_T38_PARAMETERS:
04602
04603
04604
04605
04606
04607
04608
04609 goto indicate_cleanup;
04610 case AST_CONTROL_RINGING:
04611 ts = ast_get_indication_tone(ast_channel_zone(chan), "ring");
04612
04613
04614
04615
04616
04617
04618
04619 if (ast_channel_state(chan) == AST_STATE_UP) {
04620 res = 0;
04621 }
04622 break;
04623 case AST_CONTROL_BUSY:
04624 ts = ast_get_indication_tone(ast_channel_zone(chan), "busy");
04625 break;
04626 case AST_CONTROL_INCOMPLETE:
04627 case AST_CONTROL_CONGESTION:
04628 ts = ast_get_indication_tone(ast_channel_zone(chan), "congestion");
04629 break;
04630 case AST_CONTROL_PVT_CAUSE_CODE:
04631 ast_channel_hangupcause_hash_set(chan, data, datalen);
04632 res = 0;
04633 break;
04634 case AST_CONTROL_PROGRESS:
04635 case AST_CONTROL_PROCEEDING:
04636 case AST_CONTROL_VIDUPDATE:
04637 case AST_CONTROL_SRCUPDATE:
04638 case AST_CONTROL_SRCCHANGE:
04639 case AST_CONTROL_RADIO_KEY:
04640 case AST_CONTROL_RADIO_UNKEY:
04641 case AST_CONTROL_OPTION:
04642 case AST_CONTROL_WINK:
04643 case AST_CONTROL_FLASH:
04644 case AST_CONTROL_OFFHOOK:
04645 case AST_CONTROL_TAKEOFFHOOK:
04646 case AST_CONTROL_ANSWER:
04647 case AST_CONTROL_HANGUP:
04648 case AST_CONTROL_RING:
04649 case AST_CONTROL_HOLD:
04650 case AST_CONTROL_UNHOLD:
04651 case AST_CONTROL_TRANSFER:
04652 case AST_CONTROL_CONNECTED_LINE:
04653 case AST_CONTROL_REDIRECTING:
04654 case AST_CONTROL_CC:
04655 case AST_CONTROL_READ_ACTION:
04656 case AST_CONTROL_AOC:
04657 case AST_CONTROL_END_OF_Q:
04658 case AST_CONTROL_MCID:
04659 case AST_CONTROL_UPDATE_RTP_PEER:
04660
04661 res = 0;
04662 break;
04663 }
04664
04665 if (ts) {
04666
04667 ast_debug(1, "Driver for channel '%s' does not support indication %u, emulating it\n", ast_channel_name(chan), condition);
04668 res = ast_playtones_start(chan, 0, ts->data, 1);
04669 ts = ast_tone_zone_sound_unref(ts);
04670 }
04671
04672 if (res) {
04673
04674 ast_log(LOG_WARNING, "Unable to handle indication %u for '%s'\n", condition, ast_channel_name(chan));
04675 }
04676
04677 indicate_cleanup:
04678 ast_channel_unlock(chan);
04679 if (awesome_frame) {
04680 ast_frfree(awesome_frame);
04681 }
04682
04683 return res;
04684 }
04685
04686 int ast_recvchar(struct ast_channel *chan, int timeout)
04687 {
04688 int c;
04689 char *buf = ast_recvtext(chan, timeout);
04690 if (buf == NULL)
04691 return -1;
04692 c = *(unsigned char *)buf;
04693 ast_free(buf);
04694 return c;
04695 }
04696
04697 char *ast_recvtext(struct ast_channel *chan, int timeout)
04698 {
04699 int res;
04700 char *buf = NULL;
04701 struct timeval start = ast_tvnow();
04702 int ms;
04703
04704 while ((ms = ast_remaining_ms(start, timeout))) {
04705 struct ast_frame *f;
04706
04707 if (ast_check_hangup(chan)) {
04708 break;
04709 }
04710 res = ast_waitfor(chan, ms);
04711 if (res <= 0) {
04712 break;
04713 }
04714 f = ast_read(chan);
04715 if (f == NULL) {
04716 break;
04717 }
04718 if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_HANGUP) {
04719 ast_frfree(f);
04720 break;
04721 } else if (f->frametype == AST_FRAME_TEXT) {
04722 buf = ast_strndup((char *) f->data.ptr, f->datalen);
04723 ast_frfree(f);
04724 break;
04725 }
04726 ast_frfree(f);
04727 }
04728 return buf;
04729 }
04730
04731 int ast_sendtext(struct ast_channel *chan, const char *text)
04732 {
04733 int res = 0;
04734
04735 ast_channel_lock(chan);
04736
04737 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
04738 ast_channel_unlock(chan);
04739 return -1;
04740 }
04741
04742 if (ast_strlen_zero(text)) {
04743 ast_channel_unlock(chan);
04744 return 0;
04745 }
04746
04747 CHECK_BLOCKING(chan);
04748 if (ast_channel_tech(chan)->write_text && (ast_format_cap_has_type(ast_channel_nativeformats(chan), AST_FORMAT_TYPE_TEXT))) {
04749 struct ast_frame f;
04750
04751 f.frametype = AST_FRAME_TEXT;
04752 f.src = "DIALPLAN";
04753 f.mallocd = AST_MALLOCD_DATA;
04754 f.datalen = strlen(text);
04755 f.data.ptr = ast_strdup(text);
04756 f.offset = 0;
04757 f.seqno = 0;
04758
04759 ast_format_set(&f.subclass.format, AST_FORMAT_T140, 0);
04760 res = ast_channel_tech(chan)->write_text(chan, &f);
04761 } else if (ast_channel_tech(chan)->send_text) {
04762 res = ast_channel_tech(chan)->send_text(chan, text);
04763 }
04764 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_BLOCKING);
04765 ast_channel_unlock(chan);
04766 return res;
04767 }
04768
04769 int ast_senddigit_begin(struct ast_channel *chan, char digit)
04770 {
04771
04772
04773 static const char * const dtmf_tones[] = {
04774 "941+1336",
04775 "697+1209",
04776 "697+1336",
04777 "697+1477",
04778 "770+1209",
04779 "770+1336",
04780 "770+1477",
04781 "852+1209",
04782 "852+1336",
04783 "852+1477",
04784 "697+1633",
04785 "770+1633",
04786 "852+1633",
04787 "941+1633",
04788 "941+1209",
04789 "941+1477"
04790 };
04791
04792 if (!ast_channel_tech(chan)->send_digit_begin)
04793 return 0;
04794
04795 ast_channel_lock(chan);
04796 ast_channel_sending_dtmf_digit_set(chan, digit);
04797 ast_channel_sending_dtmf_tv_set(chan, ast_tvnow());
04798 ast_channel_unlock(chan);
04799
04800 if (!ast_channel_tech(chan)->send_digit_begin(chan, digit))
04801 return 0;
04802
04803 if (digit >= '0' && digit <='9')
04804 ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0);
04805 else if (digit >= 'A' && digit <= 'D')
04806 ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0);
04807 else if (digit == '*')
04808 ast_playtones_start(chan, 0, dtmf_tones[14], 0);
04809 else if (digit == '#')
04810 ast_playtones_start(chan, 0, dtmf_tones[15], 0);
04811 else {
04812
04813 ast_debug(1, "Unable to generate DTMF tone '%c' for '%s'\n", digit, ast_channel_name(chan));
04814 }
04815
04816 return 0;
04817 }
04818
04819 int ast_senddigit_end(struct ast_channel *chan, char digit, unsigned int duration)
04820 {
04821 int res = -1;
04822
04823 if (ast_channel_tech(chan)->send_digit_end)
04824 res = ast_channel_tech(chan)->send_digit_end(chan, digit, duration);
04825
04826 ast_channel_lock(chan);
04827 if (ast_channel_sending_dtmf_digit(chan) == digit) {
04828 ast_channel_sending_dtmf_digit_set(chan, 0);
04829 }
04830 ast_channel_unlock(chan);
04831
04832 if (res && ast_channel_generator(chan))
04833 ast_playtones_stop(chan);
04834
04835 return 0;
04836 }
04837
04838 int ast_senddigit(struct ast_channel *chan, char digit, unsigned int duration)
04839 {
04840 if (ast_channel_tech(chan)->send_digit_begin) {
04841 ast_senddigit_begin(chan, digit);
04842 ast_safe_sleep(chan, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION));
04843 }
04844
04845 return ast_senddigit_end(chan, digit, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION));
04846 }
04847
04848 int ast_prod(struct ast_channel *chan)
04849 {
04850 struct ast_frame a = { AST_FRAME_VOICE };
04851 char nothing[128];
04852
04853
04854 if (ast_channel_state(chan) != AST_STATE_UP) {
04855 ast_debug(1, "Prodding channel '%s'\n", ast_channel_name(chan));
04856 ast_format_copy(&a.subclass.format, ast_channel_rawwriteformat(chan));
04857 a.data.ptr = nothing + AST_FRIENDLY_OFFSET;
04858 a.src = "ast_prod";
04859 if (ast_write(chan, &a))
04860 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", ast_channel_name(chan));
04861 }
04862 return 0;
04863 }
04864
04865 int ast_write_video(struct ast_channel *chan, struct ast_frame *fr)
04866 {
04867 int res;
04868 if (!ast_channel_tech(chan)->write_video)
04869 return 0;
04870 res = ast_write(chan, fr);
04871 if (!res)
04872 res = 1;
04873 return res;
04874 }
04875
04876 struct plc_ds {
04877
04878
04879
04880
04881 int16_t *samples_buf;
04882
04883
04884
04885 size_t num_samples;
04886 plc_state_t plc_state;
04887 };
04888
04889 static void plc_ds_destroy(void *data)
04890 {
04891 struct plc_ds *plc = data;
04892 ast_free(plc->samples_buf);
04893 ast_free(plc);
04894 }
04895
04896 static const struct ast_datastore_info plc_ds_info = {
04897 .type = "plc",
04898 .destroy = plc_ds_destroy,
04899 };
04900
04901 static void adjust_frame_for_plc(struct ast_channel *chan, struct ast_frame *frame, struct ast_datastore *datastore)
04902 {
04903 int num_new_samples = frame->samples;
04904 struct plc_ds *plc = datastore->data;
04905
04906
04907
04908
04909
04910
04911
04912
04913
04914
04915
04916
04917
04918
04919
04920
04921
04922
04923
04924
04925 if (!num_new_samples) {
04926 return;
04927 }
04928
04929
04930
04931
04932
04933 if (plc->num_samples < num_new_samples) {
04934 ast_free(plc->samples_buf);
04935 plc->samples_buf = ast_calloc(1, (num_new_samples * sizeof(*plc->samples_buf)) + (AST_FRIENDLY_OFFSET * 2));
04936 if (!plc->samples_buf) {
04937 ast_channel_datastore_remove(chan, datastore);
04938 ast_datastore_free(datastore);
04939 return;
04940 }
04941 plc->num_samples = num_new_samples;
04942 }
04943
04944 if (frame->datalen == 0) {
04945 plc_fillin(&plc->plc_state, plc->samples_buf + AST_FRIENDLY_OFFSET, frame->samples);
04946 frame->data.ptr = plc->samples_buf + AST_FRIENDLY_OFFSET;
04947 frame->datalen = num_new_samples * 2;
04948 frame->offset = AST_FRIENDLY_OFFSET * 2;
04949 } else {
04950 plc_rx(&plc->plc_state, frame->data.ptr, frame->samples);
04951 }
04952 }
04953
04954 static void apply_plc(struct ast_channel *chan, struct ast_frame *frame)
04955 {
04956 struct ast_datastore *datastore;
04957 struct plc_ds *plc;
04958
04959 datastore = ast_channel_datastore_find(chan, &plc_ds_info, NULL);
04960 if (datastore) {
04961 plc = datastore->data;
04962 adjust_frame_for_plc(chan, frame, datastore);
04963 return;
04964 }
04965
04966 datastore = ast_datastore_alloc(&plc_ds_info, NULL);
04967 if (!datastore) {
04968 return;
04969 }
04970 plc = ast_calloc(1, sizeof(*plc));
04971 if (!plc) {
04972 ast_datastore_free(datastore);
04973 return;
04974 }
04975 datastore->data = plc;
04976 ast_channel_datastore_add(chan, datastore);
04977 adjust_frame_for_plc(chan, frame, datastore);
04978 }
04979
04980 int ast_write(struct ast_channel *chan, struct ast_frame *fr)
04981 {
04982 int res = -1;
04983 struct ast_frame *f = NULL;
04984 int count = 0;
04985
04986
04987 while(ast_channel_trylock(chan)) {
04988
04989 if(count++ > 10) {
04990 ast_debug(1, "Deadlock avoided for write to channel '%s'\n", ast_channel_name(chan));
04991 return 0;
04992 }
04993 usleep(1);
04994 }
04995
04996 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
04997 goto done;
04998
04999
05000 while (ast_channel_masq(chan)) {
05001 ast_channel_unlock(chan);
05002 ast_do_masquerade(chan);
05003 ast_channel_lock(chan);
05004 }
05005 if (ast_channel_masqr(chan)) {
05006 res = 0;
05007 goto done;
05008 }
05009
05010
05011
05012 if (!(fr = ast_framehook_list_write_event(ast_channel_framehooks(chan), fr))) {
05013 res = 0;
05014 goto done;
05015 }
05016
05017 if (ast_channel_generatordata(chan) && (!fr->src || strcasecmp(fr->src, "ast_prod"))) {
05018 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_WRITE_INT)) {
05019 ast_deactivate_generator(chan);
05020 } else {
05021 if (fr->frametype == AST_FRAME_DTMF_END) {
05022
05023
05024
05025 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_BLOCKING);
05026 ast_channel_unlock(chan);
05027 res = ast_senddigit_end(chan, fr->subclass.integer, fr->len);
05028 ast_channel_lock(chan);
05029 CHECK_BLOCKING(chan);
05030 } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_UNHOLD) {
05031
05032 res = (ast_channel_tech(chan)->indicate == NULL) ? 0 :
05033 ast_channel_tech(chan)->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen);
05034 }
05035 res = 0;
05036 goto done;
05037 }
05038 }
05039
05040 if (ast_channel_fout(chan) & DEBUGCHAN_FLAG)
05041 ast_frame_dump(ast_channel_name(chan), fr, ">>");
05042 CHECK_BLOCKING(chan);
05043 switch (fr->frametype) {
05044 case AST_FRAME_CONTROL:
05045 res = (ast_channel_tech(chan)->indicate == NULL) ? 0 :
05046 ast_channel_tech(chan)->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen);
05047 break;
05048 case AST_FRAME_DTMF_BEGIN:
05049 if (ast_channel_audiohooks(chan)) {
05050 struct ast_frame *old_frame = fr;
05051 fr = ast_audiohook_write_list(chan, ast_channel_audiohooks(chan), AST_AUDIOHOOK_DIRECTION_WRITE, fr);
05052 if (old_frame != fr)
05053 f = fr;
05054 }
05055 send_dtmf_event(chan, "Sent", fr->subclass.integer, "Yes", "No");
05056 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_BLOCKING);
05057 ast_channel_unlock(chan);
05058 res = ast_senddigit_begin(chan, fr->subclass.integer);
05059 ast_channel_lock(chan);
05060 CHECK_BLOCKING(chan);
05061 break;
05062 case AST_FRAME_DTMF_END:
05063 if (ast_channel_audiohooks(chan)) {
05064 struct ast_frame *new_frame = fr;
05065
05066 new_frame = ast_audiohook_write_list(chan, ast_channel_audiohooks(chan), AST_AUDIOHOOK_DIRECTION_WRITE, fr);
05067 if (new_frame != fr) {
05068 ast_frfree(new_frame);
05069 }
05070 }
05071 send_dtmf_event(chan, "Sent", fr->subclass.integer, "No", "Yes");
05072 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_BLOCKING);
05073 ast_channel_unlock(chan);
05074 res = ast_senddigit_end(chan, fr->subclass.integer, fr->len);
05075 ast_channel_lock(chan);
05076 CHECK_BLOCKING(chan);
05077 break;
05078 case AST_FRAME_TEXT:
05079 if (fr->subclass.integer == AST_FORMAT_T140) {
05080 res = (ast_channel_tech(chan)->write_text == NULL) ? 0 :
05081 ast_channel_tech(chan)->write_text(chan, fr);
05082 } else {
05083 res = (ast_channel_tech(chan)->send_text == NULL) ? 0 :
05084 ast_channel_tech(chan)->send_text(chan, (char *) fr->data.ptr);
05085 }
05086 break;
05087 case AST_FRAME_HTML:
05088 res = (ast_channel_tech(chan)->send_html == NULL) ? 0 :
05089 ast_channel_tech(chan)->send_html(chan, fr->subclass.integer, (char *) fr->data.ptr, fr->datalen);
05090 break;
05091 case AST_FRAME_VIDEO:
05092
05093 res = (ast_channel_tech(chan)->write_video == NULL) ? 0 :
05094 ast_channel_tech(chan)->write_video(chan, fr);
05095 break;
05096 case AST_FRAME_MODEM:
05097 res = (ast_channel_tech(chan)->write == NULL) ? 0 :
05098 ast_channel_tech(chan)->write(chan, fr);
05099 break;
05100 case AST_FRAME_VOICE:
05101 if (ast_channel_tech(chan)->write == NULL)
05102 break;
05103
05104 if (ast_opt_generic_plc && fr->subclass.format.id == AST_FORMAT_SLINEAR) {
05105 apply_plc(chan, fr);
05106 }
05107
05108
05109 if (ast_format_cmp(&fr->subclass.format, ast_channel_rawwriteformat(chan)) != AST_FORMAT_CMP_NOT_EQUAL) {
05110 f = fr;
05111 } else {
05112 if ((!ast_format_cap_iscompatible(ast_channel_nativeformats(chan), &fr->subclass.format)) &&
05113 (ast_format_cmp(ast_channel_writeformat(chan), &fr->subclass.format) != AST_FORMAT_CMP_EQUAL)) {
05114 char nf[512];
05115
05116
05117
05118
05119
05120
05121
05122
05123
05124
05125 ast_log(LOG_WARNING, "Codec mismatch on channel %s setting write format to %s from %s native formats %s\n",
05126 ast_channel_name(chan), ast_getformatname(&fr->subclass.format), ast_getformatname(ast_channel_writeformat(chan)),
05127 ast_getformatname_multiple(nf, sizeof(nf), ast_channel_nativeformats(chan)));
05128 ast_set_write_format_by_id(chan, fr->subclass.format.id);
05129 }
05130
05131 f = (ast_channel_writetrans(chan)) ? ast_translate(ast_channel_writetrans(chan), fr, 0) : fr;
05132 }
05133
05134 if (!f) {
05135 res = 0;
05136 break;
05137 }
05138
05139 if (ast_channel_audiohooks(chan)) {
05140 struct ast_frame *prev = NULL, *new_frame, *cur, *dup;
05141 int freeoldlist = 0;
05142
05143 if (f != fr) {
05144 freeoldlist = 1;
05145 }
05146
05147
05148
05149
05150 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
05151 new_frame = ast_audiohook_write_list(chan, ast_channel_audiohooks(chan), AST_AUDIOHOOK_DIRECTION_WRITE, cur);
05152
05153
05154
05155 if (new_frame != cur) {
05156
05157
05158
05159
05160 if ((dup = ast_frisolate(new_frame))) {
05161 AST_LIST_NEXT(dup, frame_list) = AST_LIST_NEXT(cur, frame_list);
05162 if (freeoldlist) {
05163 AST_LIST_NEXT(cur, frame_list) = NULL;
05164 ast_frfree(cur);
05165 }
05166 if (new_frame != dup) {
05167 ast_frfree(new_frame);
05168 }
05169 cur = dup;
05170 }
05171 }
05172
05173
05174
05175 if (prev) {
05176 AST_LIST_NEXT(prev, frame_list) = cur;
05177 } else {
05178 f = cur;
05179 }
05180 prev = cur;
05181 }
05182 }
05183
05184
05185
05186
05187
05188 if (ast_channel_monitor(chan) && ast_channel_monitor(chan)->write_stream) {
05189 struct ast_frame *cur;
05190
05191 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
05192
05193 #ifndef MONITOR_CONSTANT_DELAY
05194 int jump = ast_channel_insmpl(chan) - ast_channel_outsmpl(chan) - 4 * cur->samples;
05195 if (jump >= 0) {
05196 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));
05197 if (ast_seekstream(ast_channel_monitor(chan)->write_stream, jump, SEEK_FORCECUR) == -1) {
05198 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
05199 }
05200 ast_channel_outsmpl_set(chan, ast_channel_outsmpl(chan) + (ast_channel_insmpl(chan) - ast_channel_outsmpl(chan)) + cur->samples);
05201 } else {
05202 ast_channel_outsmpl_set(chan, ast_channel_outsmpl(chan) + cur->samples);
05203 }
05204 #else
05205 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));
05206 if (jump - MONITOR_DELAY >= 0) {
05207 if (ast_seekstream(ast_channel_monitor(chan)->write_stream, jump - cur->samples, SEEK_FORCECUR) == -1) {
05208 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
05209 }
05210 ast_channel_outsmpl_set(chan, ast_channel_outsmpl(chan) + ast_channel_insmpl(chan) - ast_channel_outsmpl(chan));
05211 } else {
05212 ast_channel_outsmpl_set(chan, ast_channel_outsmpl(chan) + cur->samples);
05213 }
05214 #endif
05215 if (ast_channel_monitor(chan)->state == AST_MONITOR_RUNNING) {
05216 if (ast_writestream(ast_channel_monitor(chan)->write_stream, cur) < 0)
05217 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
05218 }
05219 }
05220 }
05221
05222
05223
05224
05225 if ((f != fr) && AST_LIST_NEXT(f, frame_list)) {
05226 struct ast_frame *cur, *next = NULL;
05227 unsigned int skip = 0;
05228
05229 cur = f;
05230 while (cur) {
05231 next = AST_LIST_NEXT(cur, frame_list);
05232 AST_LIST_NEXT(cur, frame_list) = NULL;
05233 if (!skip) {
05234 if ((res = ast_channel_tech(chan)->write(chan, cur)) < 0) {
05235 ast_channel_softhangup_internal_flag_add(chan, AST_SOFTHANGUP_DEV);
05236 skip = 1;
05237 } else if (next) {
05238
05239
05240
05241 ast_channel_fout_set(chan, FRAMECOUNT_INC(ast_channel_fout(chan)));
05242 }
05243 }
05244 ast_frfree(cur);
05245 cur = next;
05246 }
05247
05248
05249 f = NULL;
05250 } else {
05251 res = ast_channel_tech(chan)->write(chan, f);
05252 }
05253 break;
05254 case AST_FRAME_NULL:
05255 case AST_FRAME_IAX:
05256
05257 res = 0;
05258 break;
05259 default:
05260
05261
05262
05263 res = ast_channel_tech(chan)->write(chan, fr);
05264 break;
05265 }
05266
05267 if (f && f != fr)
05268 ast_frfree(f);
05269 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_BLOCKING);
05270
05271
05272 if (res < 0) {
05273 ast_channel_softhangup_internal_flag_add(chan, AST_SOFTHANGUP_DEV);
05274 } else {
05275 ast_channel_fout_set(chan, FRAMECOUNT_INC(ast_channel_fout(chan)));
05276 }
05277 done:
05278 if (ast_channel_audiohooks(chan) && ast_audiohook_write_list_empty(ast_channel_audiohooks(chan))) {
05279
05280 ast_audiohook_detach_list(ast_channel_audiohooks(chan));
05281 ast_channel_audiohooks_set(chan, NULL);
05282 }
05283 ast_channel_unlock(chan);
05284 return res;
05285 }
05286
05287 struct set_format_trans_access {
05288 struct ast_trans_pvt *(*get)(const struct ast_channel *chan);
05289 void (*set)(struct ast_channel *chan, struct ast_trans_pvt *value);
05290 };
05291
05292 static const struct set_format_trans_access set_format_readtrans = {
05293 .get = ast_channel_readtrans,
05294 .set = ast_channel_readtrans_set,
05295 };
05296
05297 static const struct set_format_trans_access set_format_writetrans = {
05298 .get = ast_channel_writetrans,
05299 .set = ast_channel_writetrans_set,
05300 };
05301
05302 static int set_format(struct ast_channel *chan,
05303 struct ast_format_cap *cap_set,
05304 struct ast_format *rawformat,
05305 struct ast_format *format,
05306 const struct set_format_trans_access *trans,
05307 const int direction)
05308 {
05309 struct ast_trans_pvt *trans_pvt;
05310 struct ast_format_cap *cap_native = ast_channel_nativeformats(chan);
05311 struct ast_format best_set_fmt;
05312 struct ast_format best_native_fmt;
05313 int res;
05314 char from[200], to[200];
05315
05316 ast_best_codec(cap_set, &best_set_fmt);
05317
05318
05319 if (!ast_channel_setoption(chan, direction ? AST_OPTION_FORMAT_WRITE : AST_OPTION_FORMAT_READ, &best_set_fmt, sizeof(best_set_fmt), 0)) {
05320 ast_debug(1, "Channel driver natively set channel %s to %s format %s\n", ast_channel_name(chan),
05321 direction ? "write" : "read", ast_getformatname(&best_set_fmt));
05322
05323 ast_channel_lock(chan);
05324 ast_format_copy(format, &best_set_fmt);
05325 ast_format_copy(rawformat, &best_set_fmt);
05326 ast_format_cap_set(ast_channel_nativeformats(chan), &best_set_fmt);
05327 ast_channel_unlock(chan);
05328
05329 trans_pvt = trans->get(chan);
05330 if (trans_pvt) {
05331 ast_translator_free_path(trans_pvt);
05332 trans->set(chan, NULL);
05333 }
05334
05335
05336
05337 if (direction && ast_channel_generatordata(chan)) {
05338 generator_write_format_change(chan);
05339 }
05340 return 0;
05341 }
05342
05343
05344 if (!direction) {
05345
05346 res = ast_translator_best_choice(cap_set, cap_native, &best_set_fmt, &best_native_fmt);
05347 } else {
05348
05349 res = ast_translator_best_choice(cap_native, cap_set, &best_native_fmt, &best_set_fmt);
05350 }
05351
05352 if (res < 0) {
05353 ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n",
05354 ast_getformatname_multiple(from, sizeof(from), cap_native),
05355 ast_getformatname_multiple(to, sizeof(to), cap_set));
05356 return -1;
05357 }
05358
05359
05360 ast_channel_lock(chan);
05361
05362 if ((ast_format_cmp(rawformat, &best_native_fmt) != AST_FORMAT_CMP_NOT_EQUAL) &&
05363 (ast_format_cmp(format, &best_set_fmt) != AST_FORMAT_CMP_NOT_EQUAL) &&
05364 ((ast_format_cmp(rawformat, format) != AST_FORMAT_CMP_NOT_EQUAL) || trans->get(chan))) {
05365
05366 ast_channel_unlock(chan);
05367 return 0;
05368 }
05369
05370 ast_format_copy(rawformat, &best_native_fmt);
05371
05372 ast_format_copy(format, &best_set_fmt);
05373
05374
05375 trans_pvt = trans->get(chan);
05376 if (trans_pvt) {
05377 ast_translator_free_path(trans_pvt);
05378 trans->set(chan, NULL);
05379 }
05380
05381
05382 if (ast_format_cmp(format, rawformat) != AST_FORMAT_CMP_NOT_EQUAL) {
05383
05384
05385
05386
05387
05388 res = 0;
05389 } else {
05390 if (!direction) {
05391
05392 trans_pvt = ast_translator_build_path(format, rawformat);
05393 } else {
05394
05395 trans_pvt = ast_translator_build_path(rawformat, format);
05396 }
05397 trans->set(chan, trans_pvt);
05398 res = trans_pvt ? 0 : -1;
05399 }
05400 ast_channel_unlock(chan);
05401
05402 ast_debug(1, "Set channel %s to %s format %s\n",
05403 ast_channel_name(chan),
05404 direction ? "write" : "read",
05405 ast_getformatname(&best_set_fmt));
05406
05407
05408
05409 if (direction && ast_channel_generatordata(chan)) {
05410 generator_write_format_change(chan);
05411 }
05412 return res;
05413 }
05414
05415 int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
05416 {
05417 struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
05418 int res;
05419
05420 if (!cap) {
05421 return -1;
05422 }
05423 ast_format_cap_add(cap, format);
05424
05425 res = set_format(chan,
05426 cap,
05427 ast_channel_rawreadformat(chan),
05428 ast_channel_readformat(chan),
05429 &set_format_readtrans,
05430 0);
05431
05432 ast_format_cap_destroy(cap);
05433 return res;
05434 }
05435
05436 int ast_set_read_format_by_id(struct ast_channel *chan, enum ast_format_id id)
05437 {
05438 struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
05439 struct ast_format tmp_format;
05440 int res;
05441
05442 if (!cap) {
05443 return -1;
05444 }
05445 ast_format_cap_add(cap, ast_format_set(&tmp_format, id, 0));
05446
05447 res = set_format(chan,
05448 cap,
05449 ast_channel_rawreadformat(chan),
05450 ast_channel_readformat(chan),
05451 &set_format_readtrans,
05452 0);
05453
05454 ast_format_cap_destroy(cap);
05455 return res;
05456 }
05457
05458 int ast_set_read_format_from_cap(struct ast_channel *chan, struct ast_format_cap *cap)
05459 {
05460 return set_format(chan,
05461 cap,
05462 ast_channel_rawreadformat(chan),
05463 ast_channel_readformat(chan),
05464 &set_format_readtrans,
05465 0);
05466 }
05467
05468 int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
05469 {
05470 struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
05471 int res;
05472
05473 if (!cap) {
05474 return -1;
05475 }
05476 ast_format_cap_add(cap, format);
05477
05478 res = set_format(chan,
05479 cap,
05480 ast_channel_rawwriteformat(chan),
05481 ast_channel_writeformat(chan),
05482 &set_format_writetrans,
05483 1);
05484
05485 ast_format_cap_destroy(cap);
05486 return res;
05487 }
05488
05489 int ast_set_write_format_by_id(struct ast_channel *chan, enum ast_format_id id)
05490 {
05491 struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
05492 struct ast_format tmp_format;
05493 int res;
05494
05495 if (!cap) {
05496 return -1;
05497 }
05498 ast_format_cap_add(cap, ast_format_set(&tmp_format, id, 0));
05499
05500 res = set_format(chan,
05501 cap,
05502 ast_channel_rawwriteformat(chan),
05503 ast_channel_writeformat(chan),
05504 &set_format_writetrans,
05505 1);
05506
05507 ast_format_cap_destroy(cap);
05508 return res;
05509 }
05510
05511 int ast_set_write_format_from_cap(struct ast_channel *chan, struct ast_format_cap *cap)
05512 {
05513 return set_format(chan,
05514 cap,
05515 ast_channel_rawwriteformat(chan),
05516 ast_channel_writeformat(chan),
05517 &set_format_writetrans,
05518 1);
05519 }
05520
05521 const char *ast_channel_reason2str(int reason)
05522 {
05523 switch (reason)
05524 {
05525 case 0:
05526 return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)";
05527 case AST_CONTROL_HANGUP:
05528 return "Hangup";
05529 case AST_CONTROL_RING:
05530 return "Local Ring";
05531 case AST_CONTROL_RINGING:
05532 return "Remote end Ringing";
05533 case AST_CONTROL_ANSWER:
05534 return "Remote end has Answered";
05535 case AST_CONTROL_BUSY:
05536 return "Remote end is Busy";
05537 case AST_CONTROL_CONGESTION:
05538 return "Congestion (circuits busy)";
05539 default:
05540 return "Unknown Reason!!";
05541 }
05542 }
05543
05544 static void handle_cause(int cause, int *outstate)
05545 {
05546 if (outstate) {
05547
05548 if (cause == AST_CAUSE_BUSY)
05549 *outstate = AST_CONTROL_BUSY;
05550 else if (cause == AST_CAUSE_CONGESTION)
05551 *outstate = AST_CONTROL_CONGESTION;
05552 else
05553 *outstate = 0;
05554 }
05555 }
05556
05557
05558
05559
05560
05561
05562
05563
05564
05565
05566
05567 static void call_forward_inherit(struct ast_channel *new_chan, struct ast_channel *parent, struct ast_channel *orig)
05568 {
05569 if (!ast_test_flag(ast_channel_flags(parent), AST_FLAG_ZOMBIE) && !ast_check_hangup(parent)) {
05570 struct ast_party_redirecting redirecting;
05571
05572
05573
05574
05575
05576 ast_party_redirecting_init(&redirecting);
05577 ast_channel_lock(orig);
05578 ast_party_redirecting_copy(&redirecting, ast_channel_redirecting(orig));
05579 ast_channel_unlock(orig);
05580 if (ast_channel_redirecting_sub(orig, parent, &redirecting, 0) &&
05581 ast_channel_redirecting_macro(orig, parent, &redirecting, 1, 0)) {
05582 ast_channel_update_redirecting(parent, &redirecting, NULL);
05583 }
05584 ast_party_redirecting_free(&redirecting);
05585 }
05586
05587
05588 ast_channel_lock_both(parent, new_chan);
05589 ast_channel_inherit_variables(parent, new_chan);
05590 ast_channel_datastore_inherit(parent, new_chan);
05591 ast_channel_unlock(new_chan);
05592 ast_channel_unlock(parent);
05593 }
05594
05595 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)
05596 {
05597 char tmpchan[256];
05598 struct ast_channel *new_chan = NULL;
05599 char *data, *type;
05600 int cause = 0;
05601 int res;
05602
05603
05604 ast_copy_string(tmpchan, ast_channel_call_forward(orig), sizeof(tmpchan));
05605 if ((data = strchr(tmpchan, '/'))) {
05606 *data++ = '\0';
05607 type = tmpchan;
05608 } else {
05609 const char *forward_context;
05610 ast_channel_lock(orig);
05611 forward_context = pbx_builtin_getvar_helper(orig, "FORWARD_CONTEXT");
05612 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", ast_channel_call_forward(orig), S_OR(forward_context, ast_channel_context(orig)));
05613 ast_channel_unlock(orig);
05614 data = tmpchan;
05615 type = "Local";
05616 }
05617 if (!(new_chan = ast_request(type, cap, orig, data, &cause))) {
05618 ast_log(LOG_NOTICE, "Unable to create channel for call forward to '%s/%s' (cause = %d)\n", type, data, cause);
05619 handle_cause(cause, outstate);
05620 ast_hangup(orig);
05621 return NULL;
05622 }
05623
05624
05625 if (oh) {
05626 if (oh->vars) {
05627 ast_set_variables(new_chan, oh->vars);
05628 }
05629 if (oh->parent_channel) {
05630 call_forward_inherit(new_chan, oh->parent_channel, orig);
05631 }
05632 if (oh->account) {
05633 ast_channel_lock(new_chan);
05634 ast_cdr_setaccount(new_chan, oh->account);
05635 ast_channel_unlock(new_chan);
05636 }
05637 } else if (caller) {
05638 call_forward_inherit(new_chan, caller, orig);
05639 }
05640
05641 ast_channel_lock_both(orig, new_chan);
05642 ast_copy_flags(ast_channel_cdr(new_chan), ast_channel_cdr(orig), AST_CDR_FLAG_ORIGINATED);
05643 ast_channel_accountcode_set(new_chan, ast_channel_accountcode(orig));
05644 ast_party_connected_line_copy(ast_channel_connected(new_chan), ast_channel_connected(orig));
05645 ast_party_redirecting_copy(ast_channel_redirecting(new_chan), ast_channel_redirecting(orig));
05646 ast_channel_unlock(new_chan);
05647 ast_channel_unlock(orig);
05648
05649
05650 res = ast_call(new_chan, data, 0);
05651 if (timeout) {
05652 *timeout = res;
05653 }
05654 if (res) {
05655 ast_log(LOG_NOTICE, "Unable to call forward to channel %s/%s\n", type, (char *)data);
05656 ast_hangup(orig);
05657 ast_hangup(new_chan);
05658 return NULL;
05659 }
05660 ast_hangup(orig);
05661
05662 return new_chan;
05663 }
05664
05665 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)
05666 {
05667 int dummy_outstate;
05668 int cause = 0;
05669 struct ast_channel *chan;
05670 int res = 0;
05671 int last_subclass = 0;
05672 struct ast_party_connected_line connected;
05673
05674 if (outstate)
05675 *outstate = 0;
05676 else
05677 outstate = &dummy_outstate;
05678
05679 chan = ast_request(type, cap, requestor, addr, &cause);
05680 if (!chan) {
05681 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, addr);
05682 handle_cause(cause, outstate);
05683 return NULL;
05684 }
05685
05686 if (oh) {
05687 if (oh->vars) {
05688 ast_set_variables(chan, oh->vars);
05689 }
05690 if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) {
05691
05692
05693
05694
05695 cid_num = oh->cid_num;
05696 cid_name = oh->cid_name;
05697 }
05698 if (oh->parent_channel) {
05699
05700 ast_channel_lock_both(oh->parent_channel, chan);
05701 ast_channel_inherit_variables(oh->parent_channel, chan);
05702 ast_channel_datastore_inherit(oh->parent_channel, chan);
05703 ast_channel_unlock(oh->parent_channel);
05704 ast_channel_unlock(chan);
05705 }
05706 if (oh->account) {
05707 ast_channel_lock(chan);
05708 ast_cdr_setaccount(chan, oh->account);
05709 ast_channel_unlock(chan);
05710 }
05711 }
05712
05713
05714
05715
05716
05717
05718
05719
05720
05721 ast_set_callerid(chan, cid_num, cid_name, cid_num);
05722
05723 ast_set_flag(ast_channel_cdr(chan), AST_CDR_FLAG_ORIGINATED);
05724 ast_party_connected_line_set_init(&connected, ast_channel_connected(chan));
05725 if (cid_num) {
05726 connected.id.number.valid = 1;
05727 connected.id.number.str = (char *) cid_num;
05728 connected.id.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
05729 }
05730 if (cid_name) {
05731 connected.id.name.valid = 1;
05732 connected.id.name.str = (char *) cid_name;
05733 connected.id.name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
05734 }
05735 ast_channel_set_connected_line(chan, &connected, NULL);
05736
05737 if (ast_call(chan, addr, 0)) {
05738 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, addr);
05739 } else {
05740 struct timeval start = ast_tvnow();
05741 res = 1;
05742 while (timeout && ast_channel_state(chan) != AST_STATE_UP) {
05743 struct ast_frame *f;
05744 int ms = ast_remaining_ms(start, timeout);
05745
05746 res = ast_waitfor(chan, ms);
05747 if (res == 0) {
05748 *outstate = AST_CONTROL_RINGING;
05749 break;
05750 }
05751 if (res < 0)
05752 break;
05753 if (!ast_strlen_zero(ast_channel_call_forward(chan))) {
05754 if (!(chan = ast_call_forward(NULL, chan, NULL, cap, oh, outstate))) {
05755 return NULL;
05756 }
05757 continue;
05758 }
05759
05760 f = ast_read(chan);
05761 if (!f) {
05762 *outstate = AST_CONTROL_HANGUP;
05763 res = 0;
05764 break;
05765 }
05766 if (f->frametype == AST_FRAME_CONTROL) {
05767 switch (f->subclass.integer) {
05768 case AST_CONTROL_RINGING:
05769 *outstate = f->subclass.integer;
05770 break;
05771
05772 case AST_CONTROL_BUSY:
05773 ast_cdr_busy(ast_channel_cdr(chan));
05774 *outstate = f->subclass.integer;
05775 timeout = 0;
05776 break;
05777
05778 case AST_CONTROL_INCOMPLETE:
05779 ast_cdr_failed(ast_channel_cdr(chan));
05780 *outstate = AST_CONTROL_CONGESTION;
05781 timeout = 0;
05782 break;
05783
05784 case AST_CONTROL_CONGESTION:
05785 ast_cdr_failed(ast_channel_cdr(chan));
05786 *outstate = f->subclass.integer;
05787 timeout = 0;
05788 break;
05789
05790 case AST_CONTROL_ANSWER:
05791 ast_cdr_answer(ast_channel_cdr(chan));
05792 *outstate = f->subclass.integer;
05793 timeout = 0;
05794 break;
05795
05796 case AST_CONTROL_PVT_CAUSE_CODE:
05797 ast_channel_hangupcause_hash_set(chan, f->data.ptr, f->datalen);
05798 break;
05799
05800 case AST_CONTROL_PROGRESS:
05801 if (oh && oh->connect_on_early_media) {
05802 *outstate = f->subclass.integer;
05803 timeout = 0;
05804 break;
05805 }
05806
05807
05808 case AST_CONTROL_PROCEEDING:
05809 case AST_CONTROL_HOLD:
05810 case AST_CONTROL_UNHOLD:
05811 case AST_CONTROL_VIDUPDATE:
05812 case AST_CONTROL_SRCUPDATE:
05813 case AST_CONTROL_SRCCHANGE:
05814 case AST_CONTROL_CONNECTED_LINE:
05815 case AST_CONTROL_REDIRECTING:
05816 case AST_CONTROL_CC:
05817 case -1:
05818 break;
05819
05820 default:
05821 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass.integer);
05822 }
05823 last_subclass = f->subclass.integer;
05824 }
05825 ast_frfree(f);
05826 }
05827 }
05828
05829
05830 if (oh) {
05831 if (!ast_strlen_zero(oh->context))
05832 ast_channel_context_set(chan, oh->context);
05833 if (!ast_strlen_zero(oh->exten))
05834 ast_channel_exten_set(chan, oh->exten);
05835 if (oh->priority)
05836 ast_channel_priority_set(chan, oh->priority);
05837 }
05838 if (ast_channel_state(chan) == AST_STATE_UP)
05839 *outstate = AST_CONTROL_ANSWER;
05840
05841 if (res <= 0) {
05842 struct ast_cdr *chancdr;
05843 ast_channel_lock(chan);
05844 if (AST_CONTROL_RINGING == last_subclass) {
05845 ast_channel_hangupcause_set(chan, AST_CAUSE_NO_ANSWER);
05846 }
05847 if (!ast_channel_cdr(chan) && (chancdr = ast_cdr_alloc())) {
05848 ast_channel_cdr_set(chan, chancdr);
05849 ast_cdr_init(ast_channel_cdr(chan), chan);
05850 }
05851 if (ast_channel_cdr(chan)) {
05852 char tmp[256];
05853
05854 snprintf(tmp, sizeof(tmp), "%s/%s", type, addr);
05855 ast_cdr_setapp(ast_channel_cdr(chan), "Dial", tmp);
05856 ast_cdr_update(chan);
05857 ast_cdr_start(ast_channel_cdr(chan));
05858 ast_cdr_end(ast_channel_cdr(chan));
05859
05860 if (ast_cdr_disposition(ast_channel_cdr(chan), ast_channel_hangupcause(chan))) {
05861 ast_cdr_failed(ast_channel_cdr(chan));
05862 }
05863 }
05864 ast_channel_unlock(chan);
05865 ast_hangup(chan);
05866 chan = NULL;
05867 }
05868 return chan;
05869 }
05870
05871 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)
05872 {
05873 return __ast_request_and_dial(type, cap, requestor, addr, timeout, outstate, cidnum, cidname, NULL);
05874 }
05875
05876 static int set_security_requirements(const struct ast_channel *requestor, struct ast_channel *out)
05877 {
05878 int ops[2][2] = {
05879 {AST_OPTION_SECURE_SIGNALING, 0},
05880 {AST_OPTION_SECURE_MEDIA, 0},
05881 };
05882 int i;
05883 struct ast_channel *r = (struct ast_channel *) requestor;
05884 struct ast_datastore *ds;
05885
05886 if (!requestor || !out) {
05887 return 0;
05888 }
05889
05890 ast_channel_lock(r);
05891 if ((ds = ast_channel_datastore_find(r, &secure_call_info, NULL))) {
05892 struct ast_secure_call_store *encrypt = ds->data;
05893 ops[0][1] = encrypt->signaling;
05894 ops[1][1] = encrypt->media;
05895 } else {
05896 ast_channel_unlock(r);
05897 return 0;
05898 }
05899 ast_channel_unlock(r);
05900
05901 for (i = 0; i < 2; i++) {
05902 if (ops[i][1]) {
05903 if (ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0)) {
05904
05905 return -1;
05906 }
05907 } else {
05908
05909 ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0);
05910 }
05911 }
05912
05913 return 0;
05914 }
05915
05916 struct ast_channel *ast_request(const char *type, struct ast_format_cap *request_cap, const struct ast_channel *requestor, const char *addr, int *cause)
05917 {
05918 struct chanlist *chan;
05919 struct ast_channel *c;
05920 int res;
05921 int foo;
05922
05923 if (!cause)
05924 cause = &foo;
05925 *cause = AST_CAUSE_NOTDEFINED;
05926
05927 if (AST_RWLIST_RDLOCK(&backends)) {
05928 ast_log(LOG_WARNING, "Unable to lock technology backend list\n");
05929 return NULL;
05930 }
05931
05932 AST_RWLIST_TRAVERSE(&backends, chan, list) {
05933 struct ast_format_cap *tmp_cap;
05934 struct ast_format tmp_fmt;
05935 struct ast_format best_audio_fmt;
05936 struct ast_format_cap *joint_cap;
05937
05938 if (strcasecmp(type, chan->tech->type))
05939 continue;
05940
05941 ast_format_clear(&best_audio_fmt);
05942
05943 if ((tmp_cap = ast_format_cap_get_type(request_cap, AST_FORMAT_TYPE_AUDIO))) {
05944
05945
05946
05947 res = ast_translator_best_choice(tmp_cap, chan->tech->capabilities, &tmp_fmt, &best_audio_fmt);
05948 ast_format_cap_destroy(tmp_cap);
05949 if (res < 0) {
05950 char tmp1[256], tmp2[256];
05951 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %s) to %s\n", type,
05952 ast_getformatname_multiple(tmp1, sizeof(tmp1), chan->tech->capabilities),
05953 ast_getformatname_multiple(tmp2, sizeof(tmp2), request_cap));
05954 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05955 AST_RWLIST_UNLOCK(&backends);
05956 return NULL;
05957 }
05958 }
05959 AST_RWLIST_UNLOCK(&backends);
05960 if (!chan->tech->requester)
05961 return NULL;
05962
05963
05964
05965
05966
05967 if (!(joint_cap = ast_format_cap_dup(request_cap))) {
05968 return NULL;
05969 }
05970 ast_format_cap_remove_bytype(joint_cap, AST_FORMAT_TYPE_AUDIO);
05971 ast_format_cap_add(joint_cap, &best_audio_fmt);
05972
05973 if (!(c = chan->tech->requester(type, joint_cap, requestor, addr, cause))) {
05974 ast_format_cap_destroy(joint_cap);
05975 return NULL;
05976 }
05977
05978
05979 if (requestor) {
05980 struct ast_callid *callid = ast_channel_callid(requestor);
05981 if (callid) {
05982 ast_channel_callid_set(c, callid);
05983 callid = ast_callid_unref(callid);
05984 }
05985 }
05986
05987 joint_cap = ast_format_cap_destroy(joint_cap);
05988
05989 if (set_security_requirements(requestor, c)) {
05990 ast_log(LOG_WARNING, "Setting security requirements failed\n");
05991 c = ast_channel_release(c);
05992 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05993 return NULL;
05994 }
05995
05996
05997 return c;
05998 }
05999
06000 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
06001 *cause = AST_CAUSE_NOSUCHDRIVER;
06002 AST_RWLIST_UNLOCK(&backends);
06003
06004 return NULL;
06005 }
06006
06007 int ast_pre_call(struct ast_channel *chan, const char *sub_args)
06008 {
06009 int (*pre_call)(struct ast_channel *chan, const char *sub_args);
06010
06011 ast_channel_lock(chan);
06012 pre_call = ast_channel_tech(chan)->pre_call;
06013 if (pre_call) {
06014 int res;
06015
06016 res = pre_call(chan, sub_args);
06017 ast_channel_unlock(chan);
06018 return res;
06019 }
06020 ast_channel_unlock(chan);
06021 return ast_app_exec_sub(NULL, chan, sub_args, 0);
06022 }
06023
06024 int ast_call(struct ast_channel *chan, const char *addr, int timeout)
06025 {
06026
06027
06028
06029 int res = -1;
06030
06031 ast_channel_lock(chan);
06032 if (!ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
06033 if (ast_channel_cdr(chan)) {
06034 ast_set_flag(ast_channel_cdr(chan), AST_CDR_FLAG_DIALED);
06035 }
06036 if (ast_channel_tech(chan)->call)
06037 res = ast_channel_tech(chan)->call(chan, addr, timeout);
06038 ast_set_flag(ast_channel_flags(chan), AST_FLAG_OUTGOING);
06039 }
06040 ast_channel_unlock(chan);
06041 return res;
06042 }
06043
06044
06045
06046
06047
06048
06049
06050
06051 int ast_transfer(struct ast_channel *chan, char *dest)
06052 {
06053 int res = -1;
06054
06055
06056 ast_channel_lock(chan);
06057 if (!ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
06058 if (ast_channel_tech(chan)->transfer) {
06059 res = ast_channel_tech(chan)->transfer(chan, dest);
06060 if (!res)
06061 res = 1;
06062 } else
06063 res = 0;
06064 }
06065 ast_channel_unlock(chan);
06066
06067 if (res <= 0) {
06068 return res;
06069 }
06070
06071 for (;;) {
06072 struct ast_frame *fr;
06073
06074 res = ast_waitfor(chan, -1);
06075
06076 if (res < 0 || !(fr = ast_read(chan))) {
06077 res = -1;
06078 break;
06079 }
06080
06081 if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_TRANSFER) {
06082 enum ast_control_transfer *message = fr->data.ptr;
06083
06084 if (*message == AST_TRANSFER_SUCCESS) {
06085 res = 1;
06086 } else {
06087 res = -1;
06088 }
06089
06090 ast_frfree(fr);
06091 break;
06092 }
06093
06094 ast_frfree(fr);
06095 }
06096
06097 return res;
06098 }
06099
06100 int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders)
06101 {
06102 return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1);
06103 }
06104
06105 int ast_readstring_full(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders, int audiofd, int ctrlfd)
06106 {
06107 int pos = 0;
06108 int to = ftimeout;
06109
06110 struct ast_silence_generator *silgen = NULL;
06111
06112
06113 if (ast_test_flag(ast_channel_flags(c), AST_FLAG_ZOMBIE) || ast_check_hangup(c))
06114 return -1;
06115 if (!len)
06116 return -1;
06117 for (;;) {
06118 int d;
06119 if (ast_channel_stream(c)) {
06120 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
06121 ast_stopstream(c);
06122 if (!silgen && ast_opt_transmit_silence)
06123 silgen = ast_channel_start_silence_generator(c);
06124 usleep(1000);
06125 if (!d)
06126 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
06127 } else {
06128 if (!silgen && ast_opt_transmit_silence)
06129 silgen = ast_channel_start_silence_generator(c);
06130 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
06131 }
06132 if (d < 0) {
06133 ast_channel_stop_silence_generator(c, silgen);
06134 return AST_GETDATA_FAILED;
06135 }
06136 if (d == 0) {
06137 s[pos] = '\0';
06138 ast_channel_stop_silence_generator(c, silgen);
06139 return AST_GETDATA_TIMEOUT;
06140 }
06141 if (d == 1) {
06142 s[pos] = '\0';
06143 ast_channel_stop_silence_generator(c, silgen);
06144 return AST_GETDATA_INTERRUPTED;
06145 }
06146 if (strchr(enders, d) && (pos == 0)) {
06147 s[pos] = '\0';
06148 ast_channel_stop_silence_generator(c, silgen);
06149 return AST_GETDATA_EMPTY_END_TERMINATED;
06150 }
06151 if (!strchr(enders, d)) {
06152 s[pos++] = d;
06153 }
06154 if (strchr(enders, d) || (pos >= len)) {
06155 s[pos] = '\0';
06156 ast_channel_stop_silence_generator(c, silgen);
06157 return AST_GETDATA_COMPLETE;
06158 }
06159 to = timeout;
06160 }
06161
06162 return 0;
06163 }
06164
06165 int ast_channel_supports_html(struct ast_channel *chan)
06166 {
06167 return (ast_channel_tech(chan)->send_html) ? 1 : 0;
06168 }
06169
06170 int ast_channel_sendhtml(struct ast_channel *chan, int subclass, const char *data, int datalen)
06171 {
06172 if (ast_channel_tech(chan)->send_html)
06173 return ast_channel_tech(chan)->send_html(chan, subclass, data, datalen);
06174 return -1;
06175 }
06176
06177 int ast_channel_sendurl(struct ast_channel *chan, const char *url)
06178 {
06179 return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1);
06180 }
06181
06182
06183 static int ast_channel_make_compatible_helper(struct ast_channel *from, struct ast_channel *to)
06184 {
06185 struct ast_format_cap *src_cap = ast_channel_nativeformats(from);
06186 struct ast_format_cap *dst_cap = ast_channel_nativeformats(to);
06187 struct ast_format best_src_fmt;
06188 struct ast_format best_dst_fmt;
06189 int use_slin;
06190
06191
06192 if (ast_channel_tech(from)->bridge && ast_channel_tech(from)->bridge == ast_channel_tech(to)->bridge &&
06193 !ast_channel_setoption(from, AST_OPTION_MAKE_COMPATIBLE, to, sizeof(struct ast_channel *), 0)) {
06194 return 0;
06195 }
06196
06197 if ((ast_format_cmp(ast_channel_readformat(from), ast_channel_writeformat(to)) != AST_FORMAT_CMP_NOT_EQUAL) &&
06198 (ast_format_cmp(ast_channel_readformat(to), ast_channel_writeformat(from)) != AST_FORMAT_CMP_NOT_EQUAL)) {
06199
06200 return 0;
06201 }
06202
06203
06204 if (!ast_format_cap_has_type(src_cap, AST_FORMAT_TYPE_AUDIO) || !ast_format_cap_has_type(dst_cap, AST_FORMAT_TYPE_AUDIO))
06205 return 0;
06206
06207 if (ast_translator_best_choice(dst_cap, src_cap, &best_src_fmt, &best_dst_fmt) < 0) {
06208 ast_log(LOG_WARNING, "No path to translate from %s to %s\n", ast_channel_name(from), ast_channel_name(to));
06209 return -1;
06210 }
06211
06212
06213
06214
06215
06216
06217
06218 use_slin = ast_format_is_slinear(&best_src_fmt) || ast_format_is_slinear(&best_dst_fmt) ? 1 : 0;
06219 if ((ast_format_cmp(&best_src_fmt, &best_dst_fmt) == AST_FORMAT_CMP_NOT_EQUAL) &&
06220 (ast_opt_generic_plc || ast_opt_transcode_via_slin) &&
06221 (ast_translate_path_steps(&best_dst_fmt, &best_src_fmt) != 1 || use_slin)) {
06222
06223 int best_sample_rate = ast_format_rate(&best_src_fmt) > ast_format_rate(&best_dst_fmt) ?
06224 ast_format_rate(&best_src_fmt) : ast_format_rate(&best_dst_fmt);
06225
06226
06227 ast_format_set(&best_dst_fmt, ast_format_slin_by_rate(best_sample_rate), 0);
06228 }
06229
06230 if (ast_set_read_format(from, &best_dst_fmt) < 0) {
06231 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %s\n", ast_channel_name(from), ast_getformatname(&best_dst_fmt));
06232 return -1;
06233 }
06234 if (ast_set_write_format(to, &best_dst_fmt) < 0) {
06235 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %s\n", ast_channel_name(to), ast_getformatname(&best_dst_fmt));
06236 return -1;
06237 }
06238 return 0;
06239 }
06240
06241 int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
06242 {
06243
06244 int rc = 0;
06245
06246
06247 rc = ast_channel_make_compatible_helper(chan, peer);
06248
06249 if (rc < 0)
06250 return rc;
06251
06252
06253 rc = ast_channel_make_compatible_helper(peer, chan);
06254
06255 return rc;
06256 }
06257
06258 static int __ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clonechan, struct ast_datastore *xfer_ds)
06259 {
06260 int res = -1;
06261 struct ast_channel *final_orig, *final_clone, *base;
06262
06263 for (;;) {
06264 final_orig = original;
06265 final_clone = clonechan;
06266
06267 ast_channel_lock_both(original, clonechan);
06268
06269 if (ast_test_flag(ast_channel_flags(original), AST_FLAG_ZOMBIE)
06270 || ast_test_flag(ast_channel_flags(clonechan), AST_FLAG_ZOMBIE)) {
06271
06272 ast_log(LOG_WARNING,
06273 "Can't setup masquerade. One or both channels is dead. (%s <-- %s)\n",
06274 ast_channel_name(original), ast_channel_name(clonechan));
06275 ast_channel_unlock(clonechan);
06276 ast_channel_unlock(original);
06277 return -1;
06278 }
06279
06280
06281
06282
06283
06284
06285 if (ast_channel_internal_bridged_channel(original)
06286 && (ast_channel_internal_bridged_channel(original) != ast_bridged_channel(original))
06287 && (ast_channel_internal_bridged_channel(ast_channel_internal_bridged_channel(original)) != original)) {
06288 final_orig = ast_channel_internal_bridged_channel(original);
06289 }
06290 if (ast_channel_internal_bridged_channel(clonechan)
06291 && (ast_channel_internal_bridged_channel(clonechan) != ast_bridged_channel(clonechan))
06292 && (ast_channel_internal_bridged_channel(ast_channel_internal_bridged_channel(clonechan)) != clonechan)) {
06293 final_clone = ast_channel_internal_bridged_channel(clonechan);
06294 }
06295 if (ast_channel_tech(final_clone)->get_base_channel
06296 && (base = ast_channel_tech(final_clone)->get_base_channel(final_clone))) {
06297 final_clone = base;
06298 }
06299
06300 if ((final_orig != original) || (final_clone != clonechan)) {
06301
06302
06303
06304
06305
06306 if (ast_channel_trylock(final_orig)) {
06307 ast_channel_unlock(clonechan);
06308 ast_channel_unlock(original);
06309
06310
06311 continue;
06312 }
06313 if (ast_channel_trylock(final_clone)) {
06314 ast_channel_unlock(final_orig);
06315 ast_channel_unlock(clonechan);
06316 ast_channel_unlock(original);
06317
06318
06319 continue;
06320 }
06321 ast_channel_unlock(clonechan);
06322 ast_channel_unlock(original);
06323 original = final_orig;
06324 clonechan = final_clone;
06325
06326 if (ast_test_flag(ast_channel_flags(original), AST_FLAG_ZOMBIE)
06327 || ast_test_flag(ast_channel_flags(clonechan), AST_FLAG_ZOMBIE)) {
06328
06329 ast_log(LOG_WARNING,
06330 "Can't setup masquerade. One or both channels is dead. (%s <-- %s)\n",
06331 ast_channel_name(original), ast_channel_name(clonechan));
06332 ast_channel_unlock(clonechan);
06333 ast_channel_unlock(original);
06334 return -1;
06335 }
06336 }
06337 break;
06338 }
06339
06340 if (original == clonechan) {
06341 ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", ast_channel_name(original));
06342 ast_channel_unlock(clonechan);
06343 ast_channel_unlock(original);
06344 return -1;
06345 }
06346
06347 ast_debug(1, "Planning to masquerade channel %s into the structure of %s\n",
06348 ast_channel_name(clonechan), ast_channel_name(original));
06349
06350 if (!ast_channel_masqr(original) && !ast_channel_masq(original) && !ast_channel_masq(clonechan) && !ast_channel_masqr(clonechan)) {
06351 ast_channel_masq_set(original, clonechan);
06352 ast_channel_masqr_set(clonechan, original);
06353 if (xfer_ds) {
06354 ast_channel_datastore_add(original, xfer_ds);
06355 }
06356 ast_queue_frame(original, &ast_null_frame);
06357 ast_queue_frame(clonechan, &ast_null_frame);
06358 ast_debug(1, "Done planning to masquerade channel %s into the structure of %s\n", ast_channel_name(clonechan), ast_channel_name(original));
06359 res = 0;
06360 } else if (ast_channel_masq(original)) {
06361 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
06362 ast_channel_name(ast_channel_masq(original)), ast_channel_name(original));
06363 } else if (ast_channel_masqr(original)) {
06364
06365 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
06366 ast_channel_name(original), ast_channel_name(ast_channel_masqr(original)));
06367 } else if (ast_channel_masq(clonechan)) {
06368 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
06369 ast_channel_name(ast_channel_masq(clonechan)), ast_channel_name(clonechan));
06370 } else {
06371 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
06372 ast_channel_name(clonechan), ast_channel_name(ast_channel_masqr(clonechan)));
06373 }
06374
06375 ast_channel_unlock(clonechan);
06376 ast_channel_unlock(original);
06377
06378 return res;
06379 }
06380
06381 int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone)
06382 {
06383 return __ast_channel_masquerade(original, clone, NULL);
06384 }
06385
06386
06387
06388
06389
06390
06391
06392
06393
06394
06395
06396 static void party_connected_line_copy_transfer(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src)
06397 {
06398 struct ast_party_connected_line connected;
06399
06400 connected = *((struct ast_party_connected_line *) src);
06401 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
06402
06403
06404 if (!connected.id.name.str) {
06405 connected.id.name.str = "";
06406 }
06407 if (!connected.id.number.str) {
06408 connected.id.number.str = "";
06409 }
06410 if (!connected.id.subaddress.str) {
06411 connected.id.subaddress.str = "";
06412 }
06413 if (!connected.id.tag) {
06414 connected.id.tag = "";
06415 }
06416
06417 ast_party_connected_line_copy(dest, &connected);
06418 }
06419
06420
06421 struct xfer_masquerade_ds {
06422
06423 struct ast_party_connected_line target_id;
06424
06425 struct ast_party_connected_line transferee_id;
06426
06427 int target_held;
06428
06429 int transferee_held;
06430 };
06431
06432
06433
06434
06435
06436
06437
06438
06439
06440
06441 static void xfer_ds_destroy(void *data)
06442 {
06443 struct xfer_masquerade_ds *ds = data;
06444
06445 ast_party_connected_line_free(&ds->target_id);
06446 ast_party_connected_line_free(&ds->transferee_id);
06447 ast_free(ds);
06448 }
06449
06450 static const struct ast_datastore_info xfer_ds_info = {
06451 .type = "xfer_colp",
06452 .destroy = xfer_ds_destroy,
06453 };
06454
06455 int ast_channel_transfer_masquerade(
06456 struct ast_channel *target_chan,
06457 const struct ast_party_connected_line *target_id,
06458 int target_held,
06459 struct ast_channel *transferee_chan,
06460 const struct ast_party_connected_line *transferee_id,
06461 int transferee_held)
06462 {
06463 struct ast_datastore *xfer_ds;
06464 struct xfer_masquerade_ds *xfer_colp;
06465 int res;
06466
06467 xfer_ds = ast_datastore_alloc(&xfer_ds_info, NULL);
06468 if (!xfer_ds) {
06469 return -1;
06470 }
06471
06472 xfer_colp = ast_calloc(1, sizeof(*xfer_colp));
06473 if (!xfer_colp) {
06474 ast_datastore_free(xfer_ds);
06475 return -1;
06476 }
06477 party_connected_line_copy_transfer(&xfer_colp->target_id, target_id);
06478 xfer_colp->target_held = target_held;
06479 party_connected_line_copy_transfer(&xfer_colp->transferee_id, transferee_id);
06480 xfer_colp->transferee_held = transferee_held;
06481 xfer_ds->data = xfer_colp;
06482
06483 res = __ast_channel_masquerade(target_chan, transferee_chan, xfer_ds);
06484 if (res) {
06485 ast_datastore_free(xfer_ds);
06486 }
06487 return res;
06488 }
06489
06490
06491
06492
06493
06494 static void __ast_change_name_nolink(struct ast_channel *chan, const char *newname)
06495 {
06496
06497
06498
06499
06500
06501 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));
06502 ast_channel_name_set(chan, newname);
06503 }
06504
06505 void ast_change_name(struct ast_channel *chan, const char *newname)
06506 {
06507
06508 ao2_lock(channels);
06509 ast_channel_lock(chan);
06510 ao2_unlink(channels, chan);
06511 __ast_change_name_nolink(chan, newname);
06512 ao2_link(channels, chan);
06513 ast_channel_unlock(chan);
06514 ao2_unlock(channels);
06515 }
06516
06517 void ast_channel_inherit_variables(const struct ast_channel *parent, struct ast_channel *child)
06518 {
06519 struct ast_var_t *current, *newvar;
06520 const char *varname;
06521
06522 AST_LIST_TRAVERSE(ast_channel_varshead((struct ast_channel *) parent), current, entries) {
06523 int vartype = 0;
06524
06525 varname = ast_var_full_name(current);
06526 if (!varname)
06527 continue;
06528
06529 if (varname[0] == '_') {
06530 vartype = 1;
06531 if (varname[1] == '_')
06532 vartype = 2;
06533 }
06534
06535 switch (vartype) {
06536 case 1:
06537 newvar = ast_var_assign(&varname[1], ast_var_value(current));
06538 if (newvar) {
06539 AST_LIST_INSERT_TAIL(ast_channel_varshead(child), newvar, entries);
06540 ast_debug(1, "Inheriting variable %s from %s to %s.\n",
06541 ast_var_name(newvar), ast_channel_name(parent), ast_channel_name(child));
06542 }
06543 break;
06544 case 2:
06545 newvar = ast_var_assign(varname, ast_var_value(current));
06546 if (newvar) {
06547 AST_LIST_INSERT_TAIL(ast_channel_varshead(child), newvar, entries);
06548 ast_debug(1, "Inheriting variable %s from %s to %s.\n",
06549 ast_var_name(newvar), ast_channel_name(parent), ast_channel_name(child));
06550 }
06551 break;
06552 default:
06553 break;
06554 }
06555 }
06556 }
06557
06558
06559
06560
06561
06562
06563
06564
06565
06566
06567 static void clone_variables(struct ast_channel *original, struct ast_channel *clonechan)
06568 {
06569 struct ast_var_t *current, *newvar;
06570
06571
06572 AST_LIST_APPEND_LIST(ast_channel_varshead(original), ast_channel_varshead(clonechan), entries);
06573
06574
06575
06576 AST_LIST_TRAVERSE(ast_channel_varshead(original), current, entries) {
06577 newvar = ast_var_assign(current->name, current->value);
06578 if (newvar)
06579 AST_LIST_INSERT_TAIL(ast_channel_varshead(clonechan), newvar, entries);
06580 }
06581 }
06582
06583
06584
06585
06586
06587
06588
06589
06590
06591
06592
06593
06594
06595
06596 static const char *oldest_linkedid(const char *a, const char *b)
06597 {
06598 const char *satime, *saseq;
06599 const char *sbtime, *sbseq;
06600 const char *dash;
06601
06602 unsigned int atime, aseq, btime, bseq;
06603
06604 if (ast_strlen_zero(a))
06605 return b;
06606
06607 if (ast_strlen_zero(b))
06608 return a;
06609
06610 satime = a;
06611 sbtime = b;
06612
06613
06614 if ((dash = strrchr(satime, '-'))) {
06615 satime = dash+1;
06616 }
06617 if ((dash = strrchr(sbtime, '-'))) {
06618 sbtime = dash+1;
06619 }
06620
06621
06622 saseq = strchr(satime, '.');
06623 sbseq = strchr(sbtime, '.');
06624 if (!saseq || !sbseq)
06625 return NULL;
06626 saseq++;
06627 sbseq++;
06628
06629
06630 atime = atoi(satime);
06631 btime = atoi(sbtime);
06632 aseq = atoi(saseq);
06633 bseq = atoi(sbseq);
06634
06635
06636 if (atime == btime) {
06637 return (aseq < bseq) ? a : b;
06638 }
06639 else {
06640 return (atime < btime) ? a : b;
06641 }
06642 }
06643
06644
06645
06646 static void ast_channel_change_linkedid(struct ast_channel *chan, const char *linkedid)
06647 {
06648 ast_assert(linkedid != NULL);
06649
06650 if (ast_channel_linkedid(chan) && !strcmp(ast_channel_linkedid(chan), linkedid)) {
06651 return;
06652 }
06653
06654 ast_cel_check_retire_linkedid(chan);
06655 ast_channel_linkedid_set(chan, linkedid);
06656 ast_cel_linkedid_ref(linkedid);
06657 }
06658
06659
06660
06661
06662
06663 void ast_channel_set_linkgroup(struct ast_channel *chan, struct ast_channel *peer)
06664 {
06665 const char* linkedid=NULL;
06666 struct ast_channel *bridged;
06667
06668 linkedid = oldest_linkedid(ast_channel_linkedid(chan), ast_channel_linkedid(peer));
06669 linkedid = oldest_linkedid(linkedid, ast_channel_uniqueid(chan));
06670 linkedid = oldest_linkedid(linkedid, ast_channel_uniqueid(peer));
06671 if (ast_channel_internal_bridged_channel(chan)) {
06672 bridged = ast_bridged_channel(chan);
06673 if (bridged && bridged != peer) {
06674 linkedid = oldest_linkedid(linkedid, ast_channel_linkedid(bridged));
06675 linkedid = oldest_linkedid(linkedid, ast_channel_uniqueid(bridged));
06676 }
06677 }
06678 if (ast_channel_internal_bridged_channel(peer)) {
06679 bridged = ast_bridged_channel(peer);
06680 if (bridged && bridged != chan) {
06681 linkedid = oldest_linkedid(linkedid, ast_channel_linkedid(bridged));
06682 linkedid = oldest_linkedid(linkedid, ast_channel_uniqueid(bridged));
06683 }
06684 }
06685
06686
06687 linkedid = ast_strdupa(linkedid);
06688
06689 ast_channel_change_linkedid(chan, linkedid);
06690 ast_channel_change_linkedid(peer, linkedid);
06691 if (ast_channel_internal_bridged_channel(chan)) {
06692 bridged = ast_bridged_channel(chan);
06693 if (bridged && bridged != peer) {
06694 ast_channel_change_linkedid(bridged, linkedid);
06695 }
06696 }
06697 if (ast_channel_internal_bridged_channel(peer)) {
06698 bridged = ast_bridged_channel(peer);
06699 if (bridged && bridged != chan) {
06700 ast_channel_change_linkedid(bridged, linkedid);
06701 }
06702 }
06703 }
06704
06705
06706 static void ast_set_owners_and_peers(struct ast_channel *chan1,
06707 struct ast_channel *chan2)
06708 {
06709 if (!ast_strlen_zero(ast_channel_accountcode(chan1)) && ast_strlen_zero(ast_channel_peeraccount(chan2))) {
06710 ast_debug(1, "setting peeraccount to %s for %s from data on channel %s\n",
06711 ast_channel_accountcode(chan1), ast_channel_name(chan2), ast_channel_name(chan1));
06712 ast_channel_peeraccount_set(chan2, ast_channel_accountcode(chan1));
06713 }
06714 if (!ast_strlen_zero(ast_channel_accountcode(chan2)) && ast_strlen_zero(ast_channel_peeraccount(chan1))) {
06715 ast_debug(1, "setting peeraccount to %s for %s from data on channel %s\n",
06716 ast_channel_accountcode(chan2), ast_channel_name(chan1), ast_channel_name(chan2));
06717 ast_channel_peeraccount_set(chan1, ast_channel_accountcode(chan2));
06718 }
06719 if (!ast_strlen_zero(ast_channel_peeraccount(chan1)) && ast_strlen_zero(ast_channel_accountcode(chan2))) {
06720 ast_debug(1, "setting accountcode to %s for %s from data on channel %s\n",
06721 ast_channel_peeraccount(chan1), ast_channel_name(chan2), ast_channel_name(chan1));
06722 ast_channel_accountcode_set(chan2, ast_channel_peeraccount(chan1));
06723 }
06724 if (!ast_strlen_zero(ast_channel_peeraccount(chan2)) && ast_strlen_zero(ast_channel_accountcode(chan1))) {
06725 ast_debug(1, "setting accountcode to %s for %s from data on channel %s\n",
06726 ast_channel_peeraccount(chan2), ast_channel_name(chan1), ast_channel_name(chan2));
06727 ast_channel_accountcode_set(chan1, ast_channel_peeraccount(chan2));
06728 }
06729 if (0 != strcmp(ast_channel_accountcode(chan1), ast_channel_peeraccount(chan2))) {
06730 ast_debug(1, "changing peeraccount from %s to %s on %s to match channel %s\n",
06731 ast_channel_peeraccount(chan2), ast_channel_peeraccount(chan1), ast_channel_name(chan2), ast_channel_name(chan1));
06732 ast_channel_peeraccount_set(chan2, ast_channel_accountcode(chan1));
06733 }
06734 if (0 != strcmp(ast_channel_accountcode(chan2), ast_channel_peeraccount(chan1))) {
06735 ast_debug(1, "changing peeraccount from %s to %s on %s to match channel %s\n",
06736 ast_channel_peeraccount(chan1), ast_channel_peeraccount(chan2), ast_channel_name(chan1), ast_channel_name(chan2));
06737 ast_channel_peeraccount_set(chan1, ast_channel_accountcode(chan2));
06738 }
06739 }
06740
06741
06742
06743
06744 static void report_new_callerid(struct ast_channel *chan)
06745 {
06746 int pres;
06747
06748 pres = ast_party_id_presentation(&ast_channel_caller(chan)->id);
06749
06750
06751
06752
06753
06754
06755
06756
06757
06758
06759 ast_manager_event(chan, EVENT_FLAG_CALL, "NewCallerid",
06760 "Channel: %s\r\n"
06761 "CallerIDNum: %s\r\n"
06762 "CallerIDName: %s\r\n"
06763 "Uniqueid: %s\r\n"
06764 "CID-CallingPres: %d (%s)\r\n",
06765 ast_channel_name(chan),
06766 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, ""),
06767 S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, ""),
06768 ast_channel_uniqueid(chan),
06769 pres,
06770 ast_describe_caller_presentation(pres)
06771 );
06772 }
06773
06774
06775
06776
06777
06778
06779
06780
06781
06782
06783
06784 static void masquerade_colp_transfer(struct ast_channel *transferee, struct xfer_masquerade_ds *colp)
06785 {
06786 struct ast_control_read_action_payload *frame_payload;
06787 int payload_size;
06788 int frame_size;
06789 unsigned char connected_line_data[1024];
06790
06791
06792 if (colp->target_held) {
06793 ast_queue_control(transferee, AST_CONTROL_UNHOLD);
06794 }
06795
06796
06797
06798
06799
06800
06801
06802
06803
06804
06805
06806
06807 ast_party_id_reset(&colp->target_id.priv);
06808 ast_party_id_reset(&colp->transferee_id.priv);
06809
06810 payload_size = ast_connected_line_build_data(connected_line_data,
06811 sizeof(connected_line_data), &colp->target_id, NULL);
06812 if (payload_size != -1) {
06813 frame_size = payload_size + sizeof(*frame_payload);
06814 frame_payload = ast_alloca(frame_size);
06815 frame_payload->action = AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO;
06816 frame_payload->payload_size = payload_size;
06817 memcpy(frame_payload->payload, connected_line_data, payload_size);
06818 ast_queue_control_data(transferee, AST_CONTROL_READ_ACTION, frame_payload,
06819 frame_size);
06820 }
06821
06822
06823
06824
06825
06826
06827 ast_channel_queue_connected_line_update(transferee, &colp->transferee_id, NULL);
06828 }
06829
06830
06831
06832
06833
06834
06835
06836
06837 int ast_do_masquerade(struct ast_channel *original)
06838 {
06839 int x;
06840 int origstate;
06841 unsigned int orig_disablestatecache;
06842 unsigned int clone_disablestatecache;
06843 int visible_indication;
06844 int moh_is_playing;
06845 int clone_was_zombie = 0;
06846 struct ast_frame *current;
06847 const struct ast_channel_tech *t;
06848 void *t_pvt;
06849 union {
06850 struct ast_hangup_handler_list handlers;
06851 struct ast_party_dialed dialed;
06852 struct ast_party_caller caller;
06853 struct ast_party_connected_line connected;
06854 struct ast_party_redirecting redirecting;
06855 } exchange;
06856 struct ast_channel *clonechan, *chans[2];
06857 struct ast_channel *bridged;
06858 struct ast_cdr *cdr;
06859 struct ast_datastore *xfer_ds;
06860 struct xfer_masquerade_ds *xfer_colp;
06861 struct ast_format rformat;
06862 struct ast_format wformat;
06863 struct ast_format tmp_format;
06864 char newn[AST_CHANNEL_NAME];
06865 char orig[AST_CHANNEL_NAME];
06866 char masqn[AST_CHANNEL_NAME];
06867 char zombn[AST_CHANNEL_NAME];
06868 char clone_sending_dtmf_digit;
06869 struct timeval clone_sending_dtmf_tv;
06870
06871
06872
06873
06874
06875
06876
06877
06878
06879
06880
06881
06882
06883
06884
06885
06886
06887
06888
06889
06890
06891
06892
06893
06894
06895
06896
06897
06898
06899
06900
06901
06902
06903 ao2_lock(channels);
06904
06905
06906
06907
06908
06909 ast_channel_lock(original);
06910
06911 clonechan = ast_channel_masq(original);
06912 if (!clonechan) {
06913
06914
06915
06916
06917 ast_channel_unlock(original);
06918 ao2_unlock(channels);
06919 return 0;
06920 }
06921
06922
06923 ast_channel_ref(original);
06924 ast_channel_ref(clonechan);
06925
06926
06927 ao2_unlink(channels, original);
06928 ao2_unlink(channels, clonechan);
06929
06930
06931 xfer_ds = ast_channel_datastore_find(original, &xfer_ds_info, NULL);
06932 if (xfer_ds) {
06933 ast_channel_datastore_remove(original, xfer_ds);
06934 xfer_colp = xfer_ds->data;
06935 } else {
06936 xfer_colp = NULL;
06937 }
06938
06939 moh_is_playing = ast_test_flag(ast_channel_flags(original), AST_FLAG_MOH);
06940
06941
06942
06943
06944
06945 visible_indication = ast_channel_visible_indication(original);
06946 ast_channel_unlock(original);
06947 ast_indicate(original, -1);
06948
06949
06950
06951
06952
06953 if (xfer_colp && xfer_colp->transferee_held) {
06954 ast_indicate(clonechan, AST_CONTROL_UNHOLD);
06955 }
06956
06957
06958 ast_channel_lock_both(original, clonechan);
06959
06960 ast_debug(4, "Actually Masquerading %s(%u) into the structure of %s(%u)\n",
06961 ast_channel_name(clonechan), ast_channel_state(clonechan), ast_channel_name(original), ast_channel_state(original));
06962
06963 chans[0] = clonechan;
06964 chans[1] = original;
06965
06966
06967
06968
06969
06970
06971
06972
06973
06974
06975
06976
06977
06978
06979
06980
06981
06982
06983
06984 ast_manager_event_multichan(EVENT_FLAG_CALL, "Masquerade", 2, chans,
06985 "Clone: %s\r\n"
06986 "CloneState: %s\r\n"
06987 "Original: %s\r\n"
06988 "OriginalState: %s\r\n",
06989 ast_channel_name(clonechan), ast_state2str(ast_channel_state(clonechan)), ast_channel_name(original), ast_state2str(ast_channel_state(original)));
06990
06991
06992
06993
06994
06995 ast_format_copy(&rformat, ast_channel_readformat(original));
06996 ast_format_copy(&wformat, ast_channel_writeformat(original));
06997 free_translation(clonechan);
06998 free_translation(original);
06999
07000
07001 clone_sending_dtmf_digit = ast_channel_sending_dtmf_digit(clonechan);
07002 clone_sending_dtmf_tv = ast_channel_sending_dtmf_tv(clonechan);
07003
07004
07005 ast_copy_string(orig, ast_channel_name(original), sizeof(orig));
07006
07007 ast_copy_string(newn, ast_channel_name(clonechan), sizeof(newn));
07008
07009 snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn);
07010
07011
07012 __ast_change_name_nolink(clonechan, masqn);
07013
07014
07015 __ast_change_name_nolink(original, newn);
07016
07017
07018 ast_channel_set_linkgroup(original, clonechan);
07019
07020
07021 t = ast_channel_tech(original);
07022 ast_channel_tech_set(original, ast_channel_tech(clonechan));
07023 ast_channel_tech_set(clonechan, t);
07024
07025 t_pvt = ast_channel_tech_pvt(original);
07026 ast_channel_tech_pvt_set(original, ast_channel_tech_pvt(clonechan));
07027 ast_channel_tech_pvt_set(clonechan, t_pvt);
07028
07029
07030 cdr = ast_channel_cdr(original);
07031 ast_channel_cdr_set(original, ast_channel_cdr(clonechan));
07032 ast_channel_cdr_set(clonechan, cdr);
07033
07034
07035 ast_channel_internal_alertpipe_swap(original, clonechan);
07036
07037
07038
07039
07040
07041
07042
07043
07044
07045
07046
07047
07048 {
07049 AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq;
07050
07051 AST_LIST_HEAD_INIT_NOLOCK(&tmp_readq);
07052 AST_LIST_APPEND_LIST(&tmp_readq, ast_channel_readq(original), frame_list);
07053 AST_LIST_APPEND_LIST(ast_channel_readq(original), ast_channel_readq(clonechan), frame_list);
07054
07055 while ((current = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) {
07056 AST_LIST_INSERT_TAIL(ast_channel_readq(original), current, frame_list);
07057 if (ast_channel_alert_write(original)) {
07058 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
07059 }
07060 }
07061 }
07062
07063
07064 ast_format_copy(&tmp_format, ast_channel_rawreadformat(original));
07065 ast_format_copy(ast_channel_rawreadformat(original), ast_channel_rawreadformat(clonechan));
07066 ast_format_copy(ast_channel_rawreadformat(clonechan), &tmp_format);
07067
07068 ast_format_copy(&tmp_format, ast_channel_rawwriteformat(original));
07069 ast_format_copy(ast_channel_rawwriteformat(original), ast_channel_rawwriteformat(clonechan));
07070 ast_format_copy(ast_channel_rawwriteformat(clonechan), &tmp_format);
07071
07072 ast_channel_softhangup_internal_flag_set(clonechan, AST_SOFTHANGUP_DEV);
07073
07074
07075
07076
07077
07078 origstate = ast_channel_state(original);
07079 ast_channel_state_set(original, ast_channel_state(clonechan));
07080 ast_channel_state_set(clonechan, origstate);
07081
07082
07083
07084 orig_disablestatecache = ast_test_flag(ast_channel_flags(original), AST_FLAG_DISABLE_DEVSTATE_CACHE);
07085 clone_disablestatecache = ast_test_flag(ast_channel_flags(clonechan), AST_FLAG_DISABLE_DEVSTATE_CACHE);
07086 if (orig_disablestatecache != clone_disablestatecache) {
07087 if (orig_disablestatecache) {
07088 ast_clear_flag(ast_channel_flags(original), AST_FLAG_DISABLE_DEVSTATE_CACHE);
07089 ast_set_flag(ast_channel_flags(clonechan), AST_FLAG_DISABLE_DEVSTATE_CACHE);
07090 } else {
07091 ast_set_flag(ast_channel_flags(original), AST_FLAG_DISABLE_DEVSTATE_CACHE);
07092 ast_clear_flag(ast_channel_flags(clonechan), AST_FLAG_DISABLE_DEVSTATE_CACHE);
07093 }
07094 }
07095
07096
07097 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig);
07098 __ast_change_name_nolink(clonechan, zombn);
07099
07100
07101 t_pvt = ast_channel_monitor(original);
07102 ast_channel_monitor_set(original, ast_channel_monitor(clonechan));
07103 ast_channel_monitor_set(clonechan, t_pvt);
07104
07105
07106 ast_channel_language_set(original, ast_channel_language(clonechan));
07107
07108
07109 ast_channel_parkinglot_set(original, ast_channel_parkinglot(clonechan));
07110
07111
07112 for (x = 0; x < AST_MAX_FDS; x++) {
07113 if (x != AST_GENERATOR_FD)
07114 ast_channel_set_fd(original, x, ast_channel_fd(clonechan, x));
07115 }
07116
07117 ast_app_group_update(clonechan, original);
07118
07119
07120 exchange.handlers = *ast_channel_hangup_handlers(original);
07121 *ast_channel_hangup_handlers(original) = *ast_channel_hangup_handlers(clonechan);
07122 *ast_channel_hangup_handlers(clonechan) = exchange.handlers;
07123
07124
07125 if (AST_LIST_FIRST(ast_channel_datastores(clonechan))) {
07126 struct ast_datastore *ds;
07127
07128
07129
07130 AST_LIST_TRAVERSE_SAFE_BEGIN(ast_channel_datastores(clonechan), ds, entry) {
07131 if (ds->info->chan_fixup)
07132 ds->info->chan_fixup(ds->data, clonechan, original);
07133 }
07134 AST_LIST_TRAVERSE_SAFE_END;
07135 AST_LIST_APPEND_LIST(ast_channel_datastores(original), ast_channel_datastores(clonechan), entry);
07136 }
07137
07138 ast_autochan_new_channel(clonechan, original);
07139
07140 clone_variables(original, clonechan);
07141
07142 ast_channel_adsicpe_set(original, ast_channel_adsicpe(clonechan));
07143
07144
07145
07146
07147
07148 ast_set_flag(ast_channel_flags(original), ast_test_flag(ast_channel_flags(clonechan), AST_FLAG_EXCEPTION | AST_FLAG_OUTGOING));
07149 ast_channel_fdno_set(original, ast_channel_fdno(clonechan));
07150
07151
07152
07153
07154
07155
07156
07157
07158 exchange.dialed = *ast_channel_dialed(original);
07159 ast_channel_dialed_set(original, ast_channel_dialed(clonechan));
07160 ast_channel_dialed_set(clonechan, &exchange.dialed);
07161
07162
07163 ast_party_id_reset(&ast_channel_caller(original)->priv);
07164 ast_party_id_reset(&ast_channel_caller(clonechan)->priv);
07165
07166 exchange.caller = *ast_channel_caller(original);
07167 ast_channel_caller_set(original, ast_channel_caller(clonechan));
07168 ast_channel_caller_set(clonechan, &exchange.caller);
07169
07170
07171 ast_party_id_reset(&ast_channel_connected(original)->priv);
07172 ast_party_id_reset(&ast_channel_connected(clonechan)->priv);
07173
07174 exchange.connected = *ast_channel_connected(original);
07175 ast_channel_connected_set(original, ast_channel_connected(clonechan));
07176 ast_channel_connected_set(clonechan, &exchange.connected);
07177
07178
07179 ast_party_id_reset(&ast_channel_redirecting(original)->priv_orig);
07180 ast_party_id_reset(&ast_channel_redirecting(clonechan)->priv_orig);
07181 ast_party_id_reset(&ast_channel_redirecting(original)->priv_from);
07182 ast_party_id_reset(&ast_channel_redirecting(clonechan)->priv_from);
07183 ast_party_id_reset(&ast_channel_redirecting(original)->priv_to);
07184 ast_party_id_reset(&ast_channel_redirecting(clonechan)->priv_to);
07185
07186 exchange.redirecting = *ast_channel_redirecting(original);
07187 ast_channel_redirecting_set(original, ast_channel_redirecting(clonechan));
07188 ast_channel_redirecting_set(clonechan, &exchange.redirecting);
07189
07190 report_new_callerid(original);
07191
07192
07193 ast_channel_set_fd(original, AST_TIMING_FD, ast_channel_timingfd(original));
07194
07195
07196 ast_format_cap_copy(ast_channel_nativeformats(original), ast_channel_nativeformats(clonechan));
07197
07198
07199
07200
07201
07202 ast_set_write_format(original, &wformat);
07203
07204
07205 ast_set_read_format(original, &rformat);
07206
07207
07208 ast_channel_musicclass_set(original, ast_channel_musicclass(clonechan));
07209
07210
07211 ast_channel_accountcode_set(original, S_OR(ast_channel_accountcode(clonechan), ""));
07212 if (ast_channel_internal_bridged_channel(original)) {
07213
07214 ast_channel_peeraccount_set(ast_channel_internal_bridged_channel(original), S_OR(ast_channel_accountcode(clonechan), ""));
07215 ast_cel_report_event(original, AST_CEL_BRIDGE_UPDATE, NULL, NULL, NULL);
07216 }
07217
07218 ast_debug(1, "Putting channel %s in %s/%s formats\n", ast_channel_name(original),
07219 ast_getformatname(&wformat), ast_getformatname(&rformat));
07220
07221
07222 if (ast_channel_tech(original)->fixup && ast_channel_tech(original)->fixup(clonechan, original)) {
07223 ast_log(LOG_WARNING, "Channel type '%s' could not fixup channel %s, strange things may happen. (clonechan)\n",
07224 ast_channel_tech(original)->type, ast_channel_name(original));
07225 }
07226
07227
07228 if (ast_channel_tech(clonechan)->fixup && ast_channel_tech(clonechan)->fixup(original, clonechan)) {
07229 ast_log(LOG_WARNING, "Channel type '%s' could not fixup channel %s, strange things may happen. (original)\n",
07230 ast_channel_tech(clonechan)->type, ast_channel_name(clonechan));
07231 }
07232
07233
07234
07235
07236
07237
07238
07239
07240
07241
07242 if (ast_test_flag(ast_channel_flags(clonechan), AST_FLAG_ZOMBIE)) {
07243 clone_was_zombie = 1;
07244 } else {
07245 ast_set_flag(ast_channel_flags(clonechan), AST_FLAG_ZOMBIE);
07246 ast_queue_frame(clonechan, &ast_null_frame);
07247 }
07248
07249
07250 ast_channel_masq_set(original, NULL);
07251 ast_channel_masqr_set(clonechan, NULL);
07252
07253
07254
07255
07256
07257
07258
07259 ast_channel_unlock(original);
07260 ast_channel_unlock(clonechan);
07261
07262 if (clone_sending_dtmf_digit) {
07263
07264
07265
07266
07267 ast_bridge_end_dtmf(original, clone_sending_dtmf_digit, clone_sending_dtmf_tv,
07268 "masquerade");
07269 }
07270
07271
07272
07273
07274
07275
07276
07277
07278
07279
07280 if (visible_indication) {
07281 ast_indicate(original, visible_indication);
07282 }
07283
07284
07285
07286 if (moh_is_playing) {
07287 ast_moh_start(original, NULL, NULL);
07288 }
07289
07290 ast_channel_lock(original);
07291
07292
07293 if (ast_test_flag(ast_channel_flags(original), AST_FLAG_BLOCKING)) {
07294 pthread_kill(ast_channel_blocker(original), SIGURG);
07295 }
07296
07297 ast_debug(1, "Done Masquerading %s (%u)\n", ast_channel_name(original), ast_channel_state(original));
07298
07299 if ((bridged = ast_bridged_channel(original))) {
07300 ast_channel_ref(bridged);
07301 ast_channel_unlock(original);
07302 ast_indicate(bridged, AST_CONTROL_SRCCHANGE);
07303 ast_channel_unref(bridged);
07304 } else {
07305 ast_channel_unlock(original);
07306 }
07307 ast_indicate(original, AST_CONTROL_SRCCHANGE);
07308
07309 if (xfer_colp) {
07310
07311
07312
07313
07314
07315 masquerade_colp_transfer(original, xfer_colp);
07316 }
07317
07318 if (xfer_ds) {
07319 ast_datastore_free(xfer_ds);
07320 }
07321
07322 if (!clone_was_zombie) {
07323 ao2_link(channels, clonechan);
07324 }
07325 ao2_link(channels, original);
07326 ao2_unlock(channels);
07327
07328 if (clone_was_zombie) {
07329
07330 ast_debug(1, "Destroying channel clone '%s'\n", ast_channel_name(clonechan));
07331 ast_hangup(clonechan);
07332 }
07333
07334
07335 ast_channel_unref(original);
07336 ast_channel_unref(clonechan);
07337
07338 return 0;
07339 }
07340
07341 void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani)
07342 {
07343 ast_channel_lock(chan);
07344
07345 if (cid_num) {
07346 ast_channel_caller(chan)->id.number.valid = 1;
07347 ast_free(ast_channel_caller(chan)->id.number.str);
07348 ast_channel_caller(chan)->id.number.str = ast_strdup(cid_num);
07349 }
07350 if (cid_name) {
07351 ast_channel_caller(chan)->id.name.valid = 1;
07352 ast_free(ast_channel_caller(chan)->id.name.str);
07353 ast_channel_caller(chan)->id.name.str = ast_strdup(cid_name);
07354 }
07355 if (cid_ani) {
07356 ast_channel_caller(chan)->ani.number.valid = 1;
07357 ast_free(ast_channel_caller(chan)->ani.number.str);
07358 ast_channel_caller(chan)->ani.number.str = ast_strdup(cid_ani);
07359 }
07360 if (ast_channel_cdr(chan)) {
07361 ast_cdr_setcid(ast_channel_cdr(chan), chan);
07362 }
07363
07364 report_new_callerid(chan);
07365
07366 ast_channel_unlock(chan);
07367 }
07368
07369 void ast_channel_set_caller(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
07370 {
07371 if (ast_channel_caller(chan) == caller) {
07372
07373 return;
07374 }
07375
07376 ast_channel_lock(chan);
07377 ast_party_caller_set(ast_channel_caller(chan), caller, update);
07378 ast_channel_unlock(chan);
07379 }
07380
07381 void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
07382 {
07383 const char *pre_set_number;
07384 const char *pre_set_name;
07385
07386 if (ast_channel_caller(chan) == caller) {
07387
07388 return;
07389 }
07390
07391 ast_channel_lock(chan);
07392 pre_set_number =
07393 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL);
07394 pre_set_name = S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, NULL);
07395 ast_party_caller_set(ast_channel_caller(chan), caller, update);
07396 if (S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL)
07397 != pre_set_number
07398 || S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, NULL)
07399 != pre_set_name) {
07400
07401 report_new_callerid(chan);
07402 }
07403 if (ast_channel_cdr(chan)) {
07404 ast_cdr_setcid(ast_channel_cdr(chan), chan);
07405 }
07406 ast_channel_unlock(chan);
07407 }
07408
07409 int ast_setstate(struct ast_channel *chan, enum ast_channel_state state)
07410 {
07411 int oldstate = ast_channel_state(chan);
07412 char name[AST_CHANNEL_NAME], *dashptr;
07413
07414 if (oldstate == state)
07415 return 0;
07416
07417 ast_copy_string(name, ast_channel_name(chan), sizeof(name));
07418 if ((dashptr = strrchr(name, '-'))) {
07419 *dashptr = '\0';
07420 }
07421
07422 ast_channel_state_set(chan, state);
07423
07424
07425
07426
07427 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);
07428
07429
07430
07431
07432
07433
07434
07435
07436
07437
07438
07439
07440
07441
07442
07443
07444
07445
07446
07447
07448
07449
07450
07451
07452
07453
07454
07455 ast_manager_event(chan, EVENT_FLAG_CALL, "Newstate",
07456 "Channel: %s\r\n"
07457 "ChannelState: %u\r\n"
07458 "ChannelStateDesc: %s\r\n"
07459 "CallerIDNum: %s\r\n"
07460 "CallerIDName: %s\r\n"
07461 "ConnectedLineNum: %s\r\n"
07462 "ConnectedLineName: %s\r\n"
07463 "Uniqueid: %s\r\n",
07464 ast_channel_name(chan), ast_channel_state(chan), ast_state2str(ast_channel_state(chan)),
07465 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, ""),
07466 S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, ""),
07467 S_COR(ast_channel_connected(chan)->id.number.valid, ast_channel_connected(chan)->id.number.str, ""),
07468 S_COR(ast_channel_connected(chan)->id.name.valid, ast_channel_connected(chan)->id.name.str, ""),
07469 ast_channel_uniqueid(chan));
07470
07471 return 0;
07472 }
07473
07474
07475 struct ast_channel *ast_bridged_channel(struct ast_channel *chan)
07476 {
07477 struct ast_channel *bridged;
07478 bridged = ast_channel_internal_bridged_channel(chan);
07479 if (bridged && ast_channel_tech(bridged)->bridged_channel)
07480 bridged = ast_channel_tech(bridged)->bridged_channel(chan, bridged);
07481 return bridged;
07482 }
07483
07484 static void bridge_playfile(struct ast_channel *chan, struct ast_channel *peer, const char *sound, int remain)
07485 {
07486 int min = 0, sec = 0, check;
07487
07488 check = ast_autoservice_start(peer);
07489 if (check)
07490 return;
07491
07492 if (remain > 0) {
07493 if (remain / 60 > 1) {
07494 min = remain / 60;
07495 sec = remain % 60;
07496 } else {
07497 sec = remain;
07498 }
07499 }
07500
07501 if (!strcmp(sound,"timeleft")) {
07502 ast_stream_and_wait(chan, "vm-youhave", "");
07503 if (min) {
07504 ast_say_number(chan, min, AST_DIGIT_ANY, ast_channel_language(chan), NULL);
07505 ast_stream_and_wait(chan, "queue-minutes", "");
07506 }
07507 if (sec) {
07508 ast_say_number(chan, sec, AST_DIGIT_ANY, ast_channel_language(chan), NULL);
07509 ast_stream_and_wait(chan, "queue-seconds", "");
07510 }
07511 } else {
07512 ast_stream_and_wait(chan, sound, "");
07513 }
07514
07515 ast_autoservice_stop(peer);
07516 }
07517
07518 static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct ast_channel *c1,
07519 struct ast_bridge_config *config, struct ast_frame **fo,
07520 struct ast_channel **rc)
07521 {
07522
07523 struct ast_channel *cs[3];
07524 struct ast_frame *f;
07525 enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
07526 struct ast_format_cap *o0nativeformats;
07527 struct ast_format_cap *o1nativeformats;
07528 int watch_c0_dtmf;
07529 int watch_c1_dtmf;
07530 void *pvt0, *pvt1;
07531
07532 int frame_put_in_jb = 0;
07533 int jb_in_use;
07534 int to;
07535
07536 o0nativeformats = ast_format_cap_dup(ast_channel_nativeformats(c0));
07537 o1nativeformats = ast_format_cap_dup(ast_channel_nativeformats(c1));
07538
07539 if (!o0nativeformats || !o1nativeformats) {
07540 ast_format_cap_destroy(o0nativeformats);
07541 ast_format_cap_destroy(o1nativeformats);
07542 return AST_BRIDGE_FAILED;
07543 }
07544
07545 cs[0] = c0;
07546 cs[1] = c1;
07547 pvt0 = ast_channel_tech_pvt(c0);
07548 pvt1 = ast_channel_tech_pvt(c1);
07549 watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0;
07550 watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1;
07551
07552
07553 jb_in_use = ast_jb_do_usecheck(c0, c1);
07554 if (jb_in_use)
07555 ast_jb_empty_and_reset(c0, c1);
07556
07557 ast_poll_channel_add(c0, c1);
07558
07559 if (config->feature_timer > 0 && ast_tvzero(config->nexteventts)) {
07560
07561
07562
07563 config->nexteventts = ast_tvadd(ast_tvnow(), ast_samp2tv(config->feature_timer, 1000));
07564 }
07565
07566 for (;;) {
07567 struct ast_channel *who, *other;
07568
07569 if ((ast_channel_tech_pvt(c0) != pvt0) || (ast_channel_tech_pvt(c1) != pvt1) ||
07570 (!ast_format_cap_identical(o0nativeformats, ast_channel_nativeformats(c0))) ||
07571 (!ast_format_cap_identical(o1nativeformats, ast_channel_nativeformats(c1)))) {
07572
07573 res = AST_BRIDGE_RETRY;
07574 break;
07575 }
07576 if (config->nexteventts.tv_sec) {
07577 to = ast_tvdiff_ms(config->nexteventts, ast_tvnow());
07578 if (to <= 0) {
07579 if (config->timelimit && !config->feature_timer && !ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) {
07580 res = AST_BRIDGE_RETRY;
07581
07582 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
07583 } else if (config->feature_timer) {
07584
07585 ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE);
07586 res = AST_BRIDGE_RETRY;
07587 } else {
07588 res = AST_BRIDGE_COMPLETE;
07589 }
07590 break;
07591 }
07592 } else {
07593
07594
07595
07596
07597 if (!ast_tvzero(config->nexteventts)) {
07598 int diff = ast_tvdiff_ms(config->nexteventts, ast_tvnow());
07599 if (diff <= 0) {
07600 res = AST_BRIDGE_RETRY;
07601 break;
07602 }
07603 }
07604 to = -1;
07605 }
07606
07607
07608 if (jb_in_use)
07609 to = ast_jb_get_when_to_wakeup(c0, c1, to);
07610 who = ast_waitfor_n(cs, 2, &to);
07611 if (!who) {
07612
07613 if (jb_in_use)
07614 ast_jb_get_and_deliver(c0, c1);
07615 if ((ast_channel_softhangup_internal_flag(c0) | ast_channel_softhangup_internal_flag(c1)) & AST_SOFTHANGUP_UNBRIDGE) {
07616 if (ast_channel_softhangup_internal_flag(c0) & AST_SOFTHANGUP_UNBRIDGE) {
07617 ast_channel_clear_softhangup(c0, AST_SOFTHANGUP_UNBRIDGE);
07618 }
07619 if (ast_channel_softhangup_internal_flag(c1) & AST_SOFTHANGUP_UNBRIDGE) {
07620 ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE);
07621 }
07622 ast_channel_lock_both(c0, c1);
07623 ast_channel_internal_bridged_channel_set(c0, c1);
07624 ast_channel_internal_bridged_channel_set(c1, c0);
07625 ast_channel_unlock(c0);
07626 ast_channel_unlock(c1);
07627 }
07628 continue;
07629 }
07630 f = ast_read(who);
07631 if (!f) {
07632 *fo = NULL;
07633 *rc = who;
07634 ast_debug(1, "Didn't get a frame from channel: %s\n", ast_channel_name(who));
07635 break;
07636 }
07637
07638 other = (who == c0) ? c1 : c0;
07639
07640 if (jb_in_use)
07641 frame_put_in_jb = !ast_jb_put(other, f);
07642
07643 if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) {
07644 int bridge_exit = 0;
07645
07646 switch (f->subclass.integer) {
07647 case AST_CONTROL_PVT_CAUSE_CODE:
07648 case AST_CONTROL_AOC:
07649 case AST_CONTROL_MCID:
07650 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
07651 break;
07652 case AST_CONTROL_REDIRECTING:
07653 if (ast_channel_redirecting_sub(who, other, f, 1) &&
07654 ast_channel_redirecting_macro(who, other, f, other == c0, 1)) {
07655 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
07656 }
07657 break;
07658 case AST_CONTROL_CONNECTED_LINE:
07659 if (ast_channel_connected_line_sub(who, other, f, 1) &&
07660 ast_channel_connected_line_macro(who, other, f, other == c0, 1)) {
07661 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
07662 }
07663 break;
07664 case AST_CONTROL_HOLD:
07665 case AST_CONTROL_UNHOLD:
07666 case AST_CONTROL_VIDUPDATE:
07667 case AST_CONTROL_SRCUPDATE:
07668 case AST_CONTROL_SRCCHANGE:
07669 case AST_CONTROL_T38_PARAMETERS:
07670 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
07671 if (jb_in_use) {
07672 ast_jb_empty_and_reset(c0, c1);
07673 }
07674 break;
07675 default:
07676 *fo = f;
07677 *rc = who;
07678 bridge_exit = 1;
07679 ast_debug(1, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass.integer, ast_channel_name(who));
07680 break;
07681 }
07682 if (bridge_exit)
07683 break;
07684 }
07685 if ((f->frametype == AST_FRAME_VOICE) ||
07686 (f->frametype == AST_FRAME_DTMF_BEGIN) ||
07687 (f->frametype == AST_FRAME_DTMF) ||
07688 (f->frametype == AST_FRAME_VIDEO) ||
07689 (f->frametype == AST_FRAME_IMAGE) ||
07690 (f->frametype == AST_FRAME_HTML) ||
07691 (f->frametype == AST_FRAME_MODEM) ||
07692 (f->frametype == AST_FRAME_TEXT)) {
07693
07694 int monitored_source = (who == c0) ? watch_c0_dtmf : watch_c1_dtmf;
07695
07696 if (monitored_source &&
07697 (f->frametype == AST_FRAME_DTMF_END ||
07698 f->frametype == AST_FRAME_DTMF_BEGIN)) {
07699 *fo = f;
07700 *rc = who;
07701 ast_debug(1, "Got DTMF %s on channel (%s)\n",
07702 f->frametype == AST_FRAME_DTMF_END ? "end" : "begin",
07703 ast_channel_name(who));
07704
07705 break;
07706 }
07707
07708 if (!frame_put_in_jb)
07709 ast_write(other, f);
07710
07711
07712 if (jb_in_use)
07713 ast_jb_get_and_deliver(c0, c1);
07714 }
07715
07716 ast_frfree(f);
07717
07718 #ifndef HAVE_EPOLL
07719
07720 cs[2] = cs[0];
07721 cs[0] = cs[1];
07722 cs[1] = cs[2];
07723 #endif
07724 }
07725
07726 ast_poll_channel_del(c0, c1);
07727
07728 ast_format_cap_destroy(o0nativeformats);
07729 ast_format_cap_destroy(o1nativeformats);
07730
07731 return res;
07732 }
07733
07734
07735 int ast_channel_early_bridge(struct ast_channel *c0, struct ast_channel *c1)
07736 {
07737
07738 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)))
07739 return -1;
07740
07741 return ast_channel_tech(c0)->early_bridge(c0, c1);
07742 }
07743
07744
07745
07746
07747
07748
07749
07750 static void manager_bridge_event(int onoff, int type, struct ast_channel *c0, struct ast_channel *c1)
07751 {
07752 struct ast_channel *chans[2] = { c0, c1 };
07753
07754
07755
07756
07757
07758
07759
07760
07761
07762
07763
07764
07765
07766
07767
07768
07769
07770
07771
07772 ast_manager_event_multichan(EVENT_FLAG_CALL, "Bridge", 2, chans,
07773 "Bridgestate: %s\r\n"
07774 "Bridgetype: %s\r\n"
07775 "Channel1: %s\r\n"
07776 "Channel2: %s\r\n"
07777 "Uniqueid1: %s\r\n"
07778 "Uniqueid2: %s\r\n"
07779 "CallerID1: %s\r\n"
07780 "CallerID2: %s\r\n",
07781 onoff ? "Link" : "Unlink",
07782 type == 1 ? "core" : "native",
07783 ast_channel_name(c0), ast_channel_name(c1),
07784 ast_channel_uniqueid(c0), ast_channel_uniqueid(c1),
07785 S_COR(ast_channel_caller(c0)->id.number.valid, ast_channel_caller(c0)->id.number.str, ""),
07786 S_COR(ast_channel_caller(c1)->id.number.valid, ast_channel_caller(c1)->id.number.str, ""));
07787 }
07788
07789 static void update_bridge_vars(struct ast_channel *c0, struct ast_channel *c1)
07790 {
07791 const char *c0_name;
07792 const char *c1_name;
07793 const char *c0_pvtid = NULL;
07794 const char *c1_pvtid = NULL;
07795
07796 ast_channel_lock(c1);
07797 c1_name = ast_strdupa(ast_channel_name(c1));
07798 if (ast_channel_tech(c1)->get_pvt_uniqueid) {
07799 c1_pvtid = ast_strdupa(ast_channel_tech(c1)->get_pvt_uniqueid(c1));
07800 }
07801 ast_channel_unlock(c1);
07802
07803 ast_channel_lock(c0);
07804 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER"))) {
07805 pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1_name);
07806 }
07807 if (c1_pvtid) {
07808 pbx_builtin_setvar_helper(c0, "BRIDGEPVTCALLID", c1_pvtid);
07809 }
07810 c0_name = ast_strdupa(ast_channel_name(c0));
07811 if (ast_channel_tech(c0)->get_pvt_uniqueid) {
07812 c0_pvtid = ast_strdupa(ast_channel_tech(c0)->get_pvt_uniqueid(c0));
07813 }
07814 ast_channel_unlock(c0);
07815
07816 ast_channel_lock(c1);
07817 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER"))) {
07818 pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0_name);
07819 }
07820 if (c0_pvtid) {
07821 pbx_builtin_setvar_helper(c1, "BRIDGEPVTCALLID", c0_pvtid);
07822 }
07823 ast_channel_unlock(c1);
07824 }
07825
07826 static void bridge_play_sounds(struct ast_channel *c0, struct ast_channel *c1)
07827 {
07828 const char *s, *sound;
07829
07830
07831
07832 ast_channel_lock(c0);
07833 if ((s = pbx_builtin_getvar_helper(c0, "BRIDGE_PLAY_SOUND"))) {
07834 sound = ast_strdupa(s);
07835 ast_channel_unlock(c0);
07836 bridge_playfile(c0, c1, sound, 0);
07837 pbx_builtin_setvar_helper(c0, "BRIDGE_PLAY_SOUND", NULL);
07838 } else {
07839 ast_channel_unlock(c0);
07840 }
07841
07842 ast_channel_lock(c1);
07843 if ((s = pbx_builtin_getvar_helper(c1, "BRIDGE_PLAY_SOUND"))) {
07844 sound = ast_strdupa(s);
07845 ast_channel_unlock(c1);
07846 bridge_playfile(c1, c0, sound, 0);
07847 pbx_builtin_setvar_helper(c1, "BRIDGE_PLAY_SOUND", NULL);
07848 } else {
07849 ast_channel_unlock(c1);
07850 }
07851 }
07852
07853
07854 enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1,
07855 struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc)
07856 {
07857 enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
07858 struct ast_format_cap *o0nativeformats;
07859 struct ast_format_cap *o1nativeformats;
07860 long time_left_ms=0;
07861 char caller_warning = 0;
07862 char callee_warning = 0;
07863
07864 *fo = NULL;
07865
07866 if (ast_channel_internal_bridged_channel(c0)) {
07867 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
07868 ast_channel_name(c0), ast_channel_name(ast_channel_internal_bridged_channel(c0)));
07869 return -1;
07870 }
07871 if (ast_channel_internal_bridged_channel(c1)) {
07872 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
07873 ast_channel_name(c1), ast_channel_name(ast_channel_internal_bridged_channel(c1)));
07874 return -1;
07875 }
07876
07877
07878 if (ast_test_flag(ast_channel_flags(c0), AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
07879 ast_test_flag(ast_channel_flags(c1), AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1))
07880 return -1;
07881
07882 o0nativeformats = ast_format_cap_dup(ast_channel_nativeformats(c0));
07883 o1nativeformats = ast_format_cap_dup(ast_channel_nativeformats(c1));
07884 if (!o0nativeformats || !o1nativeformats) {
07885 ast_format_cap_destroy(o0nativeformats);
07886 ast_format_cap_destroy(o1nativeformats);
07887 ast_log(LOG_WARNING, "failed to copy native formats\n");
07888 return -1;
07889 }
07890
07891 caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING);
07892 callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING);
07893
07894 if (ast_tvzero(config->start_time)) {
07895 config->start_time = ast_tvnow();
07896 if (config->start_sound) {
07897 if (caller_warning) {
07898 bridge_playfile(c0, c1, config->start_sound, config->timelimit / 1000);
07899 }
07900 if (callee_warning) {
07901 bridge_playfile(c1, c0, config->start_sound, config->timelimit / 1000);
07902 }
07903 }
07904 }
07905
07906
07907 ast_channel_lock_both(c0, c1);
07908 ast_channel_internal_bridged_channel_set(c0, c1);
07909 ast_channel_internal_bridged_channel_set(c1, c0);
07910 ast_channel_unlock(c0);
07911 ast_channel_unlock(c1);
07912
07913 ast_set_owners_and_peers(c0, c1);
07914
07915 if (config->feature_timer && !ast_tvzero(config->nexteventts)) {
07916 config->nexteventts = ast_tvadd(config->feature_start_time, ast_samp2tv(config->feature_timer, 1000));
07917 } else if (config->timelimit) {
07918 time_left_ms = config->timelimit - ast_tvdiff_ms(ast_tvnow(), config->start_time);
07919 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
07920 if ((caller_warning || callee_warning) && config->play_warning) {
07921 long next_warn = config->play_warning;
07922 if (time_left_ms < config->play_warning && config->warning_freq > 0) {
07923
07924 long warns_passed = (config->play_warning - time_left_ms) / config->warning_freq;
07925
07926
07927 next_warn = config->play_warning - warns_passed * config->warning_freq;
07928 }
07929 config->nexteventts = ast_tvsub(config->nexteventts, ast_samp2tv(next_warn, 1000));
07930 }
07931 } else {
07932 config->nexteventts.tv_sec = 0;
07933 config->nexteventts.tv_usec = 0;
07934 }
07935
07936 if (!ast_channel_tech(c0)->send_digit_begin)
07937 ast_set_flag(ast_channel_flags(c1), AST_FLAG_END_DTMF_ONLY);
07938 if (!ast_channel_tech(c1)->send_digit_begin)
07939 ast_set_flag(ast_channel_flags(c0), AST_FLAG_END_DTMF_ONLY);
07940 manager_bridge_event(1, 1, c0, c1);
07941
07942
07943 ast_indicate(c0, AST_CONTROL_SRCUPDATE);
07944 ast_indicate(c1, AST_CONTROL_SRCUPDATE);
07945
07946 for (;;) {
07947 struct timeval now = { 0, };
07948 int to;
07949
07950 to = -1;
07951
07952 if (!ast_tvzero(config->nexteventts)) {
07953 now = ast_tvnow();
07954 to = ast_tvdiff_ms(config->nexteventts, now);
07955 if (to <= 0) {
07956 if (!config->timelimit) {
07957 res = AST_BRIDGE_COMPLETE;
07958 break;
07959 }
07960 to = 0;
07961 }
07962 }
07963
07964 if (config->timelimit) {
07965 time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time);
07966 if (time_left_ms < to)
07967 to = time_left_ms;
07968
07969 if (time_left_ms <= 0) {
07970 if (caller_warning && config->end_sound)
07971 bridge_playfile(c0, c1, config->end_sound, 0);
07972 if (callee_warning && config->end_sound)
07973 bridge_playfile(c1, c0, config->end_sound, 0);
07974 *fo = NULL;
07975 res = 0;
07976 ast_test_suite_event_notify("BRIDGE_TIMELIMIT", "Channel1: %s\r\nChannel2: %s", ast_channel_name(c0), ast_channel_name(c1));
07977 break;
07978 }
07979
07980 if (!to) {
07981 if (time_left_ms >= 5000 && config->warning_sound && config->play_warning && ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) {
07982 int t = (time_left_ms + 500) / 1000;
07983 if (caller_warning)
07984 bridge_playfile(c0, c1, config->warning_sound, t);
07985 if (callee_warning)
07986 bridge_playfile(c1, c0, config->warning_sound, t);
07987 }
07988
07989 if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000))) {
07990 config->nexteventts = ast_tvadd(config->nexteventts, ast_samp2tv(config->warning_freq, 1000));
07991 } else {
07992 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
07993 }
07994 }
07995 ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE);
07996 }
07997
07998 if ((ast_channel_softhangup_internal_flag(c0) | ast_channel_softhangup_internal_flag(c1)) & AST_SOFTHANGUP_UNBRIDGE) {
07999 if (ast_channel_softhangup_internal_flag(c0) & AST_SOFTHANGUP_UNBRIDGE) {
08000 ast_channel_clear_softhangup(c0, AST_SOFTHANGUP_UNBRIDGE);
08001 }
08002 if (ast_channel_softhangup_internal_flag(c1) & AST_SOFTHANGUP_UNBRIDGE) {
08003 ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE);
08004 }
08005 ast_channel_lock_both(c0, c1);
08006 ast_channel_internal_bridged_channel_set(c0, c1);
08007 ast_channel_internal_bridged_channel_set(c1, c0);
08008 ast_channel_unlock(c0);
08009 ast_channel_unlock(c1);
08010 ast_debug(1, "Unbridge signal received. Ending native bridge.\n");
08011 continue;
08012 }
08013
08014
08015 if (ast_test_flag(ast_channel_flags(c0), AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
08016 ast_test_flag(ast_channel_flags(c1), AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) {
08017 *fo = NULL;
08018 res = 0;
08019 ast_debug(1, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n",
08020 ast_channel_name(c0), ast_channel_name(c1),
08021 ast_test_flag(ast_channel_flags(c0), AST_FLAG_ZOMBIE) ? "Yes" : "No",
08022 ast_check_hangup(c0) ? "Yes" : "No",
08023 ast_test_flag(ast_channel_flags(c1), AST_FLAG_ZOMBIE) ? "Yes" : "No",
08024 ast_check_hangup(c1) ? "Yes" : "No");
08025 break;
08026 }
08027
08028 update_bridge_vars(c0, c1);
08029
08030 bridge_play_sounds(c0, c1);
08031
08032 if (ast_channel_tech(c0)->bridge &&
08033
08034 (!config->timelimit || to > 1000 || to == 0) &&
08035 (ast_channel_tech(c0)->bridge == ast_channel_tech(c1)->bridge) &&
08036 !ast_channel_monitor(c0) && !ast_channel_monitor(c1) &&
08037 !ast_channel_audiohooks(c0) && !ast_channel_audiohooks(c1) &&
08038 ast_framehook_list_is_empty(ast_channel_framehooks(c0)) && ast_framehook_list_is_empty(ast_channel_framehooks(c1)) &&
08039 !ast_channel_masq(c0) && !ast_channel_masqr(c0) && !ast_channel_masq(c1) && !ast_channel_masqr(c1)) {
08040 int timeoutms = to - 1000 > 0 ? to - 1000 : to;
08041
08042 ast_set_flag(ast_channel_flags(c0), AST_FLAG_NBRIDGE);
08043 ast_set_flag(ast_channel_flags(c1), AST_FLAG_NBRIDGE);
08044 if ((res = ast_channel_tech(c0)->bridge(c0, c1, config->flags, fo, rc, timeoutms)) == AST_BRIDGE_COMPLETE) {
08045 manager_bridge_event(0, 1, c0, c1);
08046 ast_debug(1, "Returning from native bridge, channels: %s, %s\n", ast_channel_name(c0), ast_channel_name(c1));
08047
08048 ast_clear_flag(ast_channel_flags(c0), AST_FLAG_NBRIDGE);
08049 ast_clear_flag(ast_channel_flags(c1), AST_FLAG_NBRIDGE);
08050
08051 if ((ast_channel_softhangup_internal_flag(c0) | ast_channel_softhangup_internal_flag(c1)) & AST_SOFTHANGUP_UNBRIDGE) {
08052 continue;
08053 }
08054
08055 ast_channel_lock_both(c0, c1);
08056 ast_channel_internal_bridged_channel_set(c0, NULL);
08057 ast_channel_internal_bridged_channel_set(c1, NULL);
08058 ast_channel_unlock(c0);
08059 ast_channel_unlock(c1);
08060 ast_format_cap_destroy(o0nativeformats);
08061 ast_format_cap_destroy(o1nativeformats);
08062 return res;
08063 } else {
08064 ast_clear_flag(ast_channel_flags(c0), AST_FLAG_NBRIDGE);
08065 ast_clear_flag(ast_channel_flags(c1), AST_FLAG_NBRIDGE);
08066 }
08067 switch (res) {
08068 case AST_BRIDGE_RETRY:
08069 if (config->play_warning) {
08070 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
08071 }
08072 continue;
08073 default:
08074 ast_verb(3, "Native bridging %s and %s ended\n", ast_channel_name(c0), ast_channel_name(c1));
08075
08076 case AST_BRIDGE_FAILED_NOWARN:
08077 break;
08078 }
08079 }
08080
08081 if (((ast_format_cmp(ast_channel_readformat(c1), ast_channel_writeformat(c0)) == AST_FORMAT_CMP_NOT_EQUAL) ||
08082 (ast_format_cmp(ast_channel_readformat(c0), ast_channel_writeformat(c1)) == AST_FORMAT_CMP_NOT_EQUAL) ||
08083 !ast_format_cap_identical(ast_channel_nativeformats(c0), o0nativeformats) ||
08084 !ast_format_cap_identical(ast_channel_nativeformats(c1), o1nativeformats)) &&
08085 !(ast_channel_generator(c0) || ast_channel_generator(c1))) {
08086 if (ast_channel_make_compatible(c0, c1)) {
08087 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", ast_channel_name(c0), ast_channel_name(c1));
08088 manager_bridge_event(0, 1, c0, c1);
08089 ast_format_cap_destroy(o0nativeformats);
08090 ast_format_cap_destroy(o1nativeformats);
08091 return AST_BRIDGE_FAILED;
08092 }
08093
08094 ast_format_cap_copy(o0nativeformats, ast_channel_nativeformats(c0));
08095 ast_format_cap_copy(o1nativeformats, ast_channel_nativeformats(c1));
08096 }
08097
08098 update_bridge_vars(c0, c1);
08099
08100 res = ast_generic_bridge(c0, c1, config, fo, rc);
08101 if (res != AST_BRIDGE_RETRY) {
08102 break;
08103 } else if (config->feature_timer) {
08104
08105 break;
08106 }
08107 }
08108
08109 ast_clear_flag(ast_channel_flags(c0), AST_FLAG_END_DTMF_ONLY);
08110 ast_clear_flag(ast_channel_flags(c1), AST_FLAG_END_DTMF_ONLY);
08111
08112
08113 ast_indicate(c0, AST_CONTROL_SRCUPDATE);
08114 ast_indicate(c1, AST_CONTROL_SRCUPDATE);
08115
08116 ast_channel_lock_both(c0, c1);
08117 ast_channel_internal_bridged_channel_set(c0, NULL);
08118 ast_channel_internal_bridged_channel_set(c1, NULL);
08119 ast_channel_unlock(c0);
08120 ast_channel_unlock(c1);
08121
08122 manager_bridge_event(0, 1, c0, c1);
08123 ast_debug(1, "Bridge stops bridging channels %s and %s\n", ast_channel_name(c0), ast_channel_name(c1));
08124
08125 ast_format_cap_destroy(o0nativeformats);
08126 ast_format_cap_destroy(o1nativeformats);
08127 return res;
08128 }
08129
08130
08131 int ast_channel_setoption(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)->setoption) {
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)->setoption(chan, option, data, datalen);
08146 ast_channel_unlock(chan);
08147
08148 return res;
08149 }
08150
08151 int ast_channel_queryoption(struct ast_channel *chan, int option, void *data, int *datalen, int block)
08152 {
08153 int res;
08154
08155 ast_channel_lock(chan);
08156 if (!ast_channel_tech(chan)->queryoption) {
08157 errno = ENOSYS;
08158 ast_channel_unlock(chan);
08159 return -1;
08160 }
08161
08162 if (block)
08163 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
08164
08165 res = ast_channel_tech(chan)->queryoption(chan, option, data, datalen);
08166 ast_channel_unlock(chan);
08167
08168 return res;
08169 }
08170
08171 struct tonepair_def {
08172 int freq1;
08173 int freq2;
08174 int duration;
08175 int vol;
08176 };
08177
08178 struct tonepair_state {
08179 int fac1;
08180 int fac2;
08181 int v1_1;
08182 int v2_1;
08183 int v3_1;
08184 int v1_2;
08185 int v2_2;
08186 int v3_2;
08187 struct ast_format origwfmt;
08188 int pos;
08189 int duration;
08190 int modulate;
08191 struct ast_frame f;
08192 unsigned char offset[AST_FRIENDLY_OFFSET];
08193 short data[4000];
08194 };
08195
08196 static void tonepair_release(struct ast_channel *chan, void *params)
08197 {
08198 struct tonepair_state *ts = params;
08199
08200 if (chan)
08201 ast_set_write_format(chan, &ts->origwfmt);
08202 ast_free(ts);
08203 }
08204
08205 static void *tonepair_alloc(struct ast_channel *chan, void *params)
08206 {
08207 struct tonepair_state *ts;
08208 struct tonepair_def *td = params;
08209
08210 if (!(ts = ast_calloc(1, sizeof(*ts))))
08211 return NULL;
08212 ast_format_copy(&ts->origwfmt, ast_channel_writeformat(chan));
08213 if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR)) {
08214 ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", ast_channel_name(chan));
08215 tonepair_release(NULL, ts);
08216 ts = NULL;
08217 } else {
08218 ts->fac1 = 2.0 * cos(2.0 * M_PI * (td->freq1 / 8000.0)) * 32768.0;
08219 ts->v1_1 = 0;
08220 ts->v2_1 = sin(-4.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
08221 ts->v3_1 = sin(-2.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
08222 ts->v2_1 = 0;
08223 ts->fac2 = 2.0 * cos(2.0 * M_PI * (td->freq2 / 8000.0)) * 32768.0;
08224 ts->v2_2 = sin(-4.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
08225 ts->v3_2 = sin(-2.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
08226 ts->duration = td->duration;
08227 ts->modulate = 0;
08228 }
08229
08230 ast_set_flag(ast_channel_flags(chan), AST_FLAG_WRITE_INT);
08231 return ts;
08232 }
08233
08234 static int tonepair_generator(struct ast_channel *chan, void *data, int len, int samples)
08235 {
08236 struct tonepair_state *ts = data;
08237 int x;
08238
08239
08240
08241
08242 len = samples * 2;
08243
08244 if (len > sizeof(ts->data) / 2 - 1) {
08245 ast_log(LOG_WARNING, "Can't generate that much data!\n");
08246 return -1;
08247 }
08248 memset(&ts->f, 0, sizeof(ts->f));
08249 for (x=0;x<len/2;x++) {
08250 ts->v1_1 = ts->v2_1;
08251 ts->v2_1 = ts->v3_1;
08252 ts->v3_1 = (ts->fac1 * ts->v2_1 >> 15) - ts->v1_1;
08253
08254 ts->v1_2 = ts->v2_2;
08255 ts->v2_2 = ts->v3_2;
08256 ts->v3_2 = (ts->fac2 * ts->v2_2 >> 15) - ts->v1_2;
08257 if (ts->modulate) {
08258 int p;
08259 p = ts->v3_2 - 32768;
08260 if (p < 0) p = -p;
08261 p = ((p * 9) / 10) + 1;
08262 ts->data[x] = (ts->v3_1 * p) >> 15;
08263 } else
08264 ts->data[x] = ts->v3_1 + ts->v3_2;
08265 }
08266 ts->f.frametype = AST_FRAME_VOICE;
08267 ast_format_set(&ts->f.subclass.format, AST_FORMAT_SLINEAR, 0);
08268 ts->f.datalen = len;
08269 ts->f.samples = samples;
08270 ts->f.offset = AST_FRIENDLY_OFFSET;
08271 ts->f.data.ptr = ts->data;
08272 ast_write(chan, &ts->f);
08273 ts->pos += x;
08274 if (ts->duration > 0) {
08275 if (ts->pos >= ts->duration * 8)
08276 return -1;
08277 }
08278 return 0;
08279 }
08280
08281 static struct ast_generator tonepair = {
08282 .alloc = tonepair_alloc,
08283 .release = tonepair_release,
08284 .generate = tonepair_generator,
08285 };
08286
08287 int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
08288 {
08289 struct tonepair_def d = { 0, };
08290
08291 d.freq1 = freq1;
08292 d.freq2 = freq2;
08293 d.duration = duration;
08294 d.vol = (vol < 1) ? 8192 : vol;
08295 if (ast_activate_generator(chan, &tonepair, &d))
08296 return -1;
08297 return 0;
08298 }
08299
08300 void ast_tonepair_stop(struct ast_channel *chan)
08301 {
08302 ast_deactivate_generator(chan);
08303 }
08304
08305 int ast_tonepair(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
08306 {
08307 int res;
08308
08309 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
08310 return res;
08311
08312
08313 while (ast_channel_generatordata(chan) && ast_waitfor(chan, 100) >= 0) {
08314 struct ast_frame *f = ast_read(chan);
08315 if (f)
08316 ast_frfree(f);
08317 else
08318 return -1;
08319 }
08320 return 0;
08321 }
08322
08323 ast_group_t ast_get_group(const char *s)
08324 {
08325 char *piece;
08326 char *c;
08327 int start=0, finish=0, x;
08328 ast_group_t group = 0;
08329
08330 if (ast_strlen_zero(s))
08331 return 0;
08332
08333 c = ast_strdupa(s);
08334
08335 while ((piece = strsep(&c, ","))) {
08336 if (sscanf(piece, "%30d-%30d", &start, &finish) == 2) {
08337
08338 } else if (sscanf(piece, "%30d", &start)) {
08339
08340 finish = start;
08341 } else {
08342 ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece);
08343 continue;
08344 }
08345 for (x = start; x <= finish; x++) {
08346 if ((x > 63) || (x < 0)) {
08347 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x);
08348 } else
08349 group |= ((ast_group_t) 1 << x);
08350 }
08351 }
08352 return group;
08353 }
08354
08355
08356 struct namedgroup_member {
08357
08358 unsigned int hash;
08359
08360 char name[1];
08361 };
08362
08363
08364 static int namedgroup_cmp_cb(void *obj, void *arg, int flags)
08365 {
08366 const struct namedgroup_member *an = obj;
08367 const struct namedgroup_member *bn = arg;
08368
08369 return strcmp(an->name, bn->name) ? 0 : CMP_MATCH | CMP_STOP;
08370 }
08371
08372
08373 static int namedgroup_hash_cb(const void *obj, const int flags)
08374 {
08375 const struct namedgroup_member *member = obj;
08376
08377 return member->hash;
08378 }
08379
08380 struct ast_namedgroups *ast_get_namedgroups(const char *s)
08381 {
08382 struct ao2_container *namedgroups;
08383 char *piece;
08384 char *c;
08385
08386 if (!s) {
08387 return NULL;
08388 }
08389
08390
08391 c = ast_trim_blanks(ast_strdupa(ast_skip_blanks(s)));
08392 if (ast_strlen_zero(c)) {
08393 return NULL;
08394 }
08395
08396 namedgroups = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK, 19,
08397 namedgroup_hash_cb, namedgroup_cmp_cb);
08398 if (!namedgroups) {
08399 return NULL;
08400 }
08401
08402 while ((piece = strsep(&c, ","))) {
08403 struct namedgroup_member *member;
08404 size_t len;
08405
08406
08407 piece = ast_strip(piece);
08408
08409 len = strlen(piece);
08410 if (!len) {
08411 continue;
08412 }
08413
08414 member = ao2_alloc_options(sizeof(*member) + len, NULL, AO2_ALLOC_OPT_LOCK_NOLOCK);
08415 if (!member) {
08416 ao2_ref(namedgroups, -1);
08417 return NULL;
08418 }
08419 strcpy(member->name, piece);
08420 member->hash = ast_str_hash(member->name);
08421
08422
08423 ao2_find(namedgroups, member, OBJ_POINTER | OBJ_UNLINK | OBJ_NODATA);
08424 ao2_link(namedgroups, member);
08425 ao2_ref(member, -1);
08426 }
08427
08428 if (!ao2_container_count(namedgroups)) {
08429
08430 ao2_ref(namedgroups, -1);
08431 namedgroups = NULL;
08432 }
08433
08434 return (struct ast_namedgroups *) namedgroups;
08435 }
08436
08437 struct ast_namedgroups *ast_unref_namedgroups(struct ast_namedgroups *groups)
08438 {
08439 ao2_cleanup(groups);
08440 return NULL;
08441 }
08442
08443 struct ast_namedgroups *ast_ref_namedgroups(struct ast_namedgroups *groups)
08444 {
08445 if (groups) {
08446 ao2_ref(groups, 1);
08447 }
08448 return groups;
08449 }
08450
08451 static int (*ast_moh_start_ptr)(struct ast_channel *, const char *, const char *) = NULL;
08452 static void (*ast_moh_stop_ptr)(struct ast_channel *) = NULL;
08453 static void (*ast_moh_cleanup_ptr)(struct ast_channel *) = NULL;
08454
08455 void ast_install_music_functions(int (*start_ptr)(struct ast_channel *, const char *, const char *),
08456 void (*stop_ptr)(struct ast_channel *),
08457 void (*cleanup_ptr)(struct ast_channel *))
08458 {
08459 ast_moh_start_ptr = start_ptr;
08460 ast_moh_stop_ptr = stop_ptr;
08461 ast_moh_cleanup_ptr = cleanup_ptr;
08462 }
08463
08464 void ast_uninstall_music_functions(void)
08465 {
08466 ast_moh_start_ptr = NULL;
08467 ast_moh_stop_ptr = NULL;
08468 ast_moh_cleanup_ptr = NULL;
08469 }
08470
08471
08472 int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
08473 {
08474 if (ast_moh_start_ptr)
08475 return ast_moh_start_ptr(chan, mclass, interpclass);
08476
08477 ast_verb(3, "Music class %s requested but no musiconhold loaded.\n", mclass ? mclass : (interpclass ? interpclass : "default"));
08478
08479 return 0;
08480 }
08481
08482
08483 void ast_moh_stop(struct ast_channel *chan)
08484 {
08485 if (ast_moh_stop_ptr)
08486 ast_moh_stop_ptr(chan);
08487 }
08488
08489 void ast_moh_cleanup(struct ast_channel *chan)
08490 {
08491 if (ast_moh_cleanup_ptr)
08492 ast_moh_cleanup_ptr(chan);
08493 }
08494
08495 static int ast_channel_hash_cb(const void *obj, const int flags)
08496 {
08497 const char *name = (flags & OBJ_KEY) ? obj : ast_channel_name((struct ast_channel *) obj);
08498
08499
08500
08501 if (ast_strlen_zero(name)) {
08502 return 0;
08503 }
08504
08505 return ast_str_case_hash(name);
08506 }
08507
08508 int ast_plc_reload(void)
08509 {
08510 struct ast_variable *var;
08511 struct ast_flags config_flags = { 0 };
08512 struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
08513 if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID)
08514 return 0;
08515 for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
08516 if (!strcasecmp(var->name, "genericplc")) {
08517 ast_set2_flag(&ast_options, ast_true(var->value), AST_OPT_FLAG_GENERIC_PLC);
08518 }
08519 }
08520 ast_config_destroy(cfg);
08521 return 0;
08522 }
08523
08524
08525
08526
08527
08528 static int data_channels_provider_handler(const struct ast_data_search *search,
08529 struct ast_data *root)
08530 {
08531 struct ast_channel *c;
08532 struct ast_channel_iterator *iter = NULL;
08533 struct ast_data *data_channel;
08534
08535 for (iter = ast_channel_iterator_all_new();
08536 iter && (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) {
08537 ast_channel_lock(c);
08538
08539 data_channel = ast_data_add_node(root, "channel");
08540 if (!data_channel) {
08541 ast_channel_unlock(c);
08542 continue;
08543 }
08544
08545 if (ast_channel_data_add_structure(data_channel, c, 1) < 0) {
08546 ast_log(LOG_ERROR, "Unable to add channel structure for channel: %s\n", ast_channel_name(c));
08547 }
08548
08549 ast_channel_unlock(c);
08550
08551 if (!ast_data_search_match(search, data_channel)) {
08552 ast_data_remove_node(root, data_channel);
08553 }
08554 }
08555 if (iter) {
08556 ast_channel_iterator_destroy(iter);
08557 }
08558
08559 return 0;
08560 }
08561
08562
08563
08564
08565
08566 static int data_channeltypes_provider_handler(const struct ast_data_search *search,
08567 struct ast_data *data_root)
08568 {
08569 struct chanlist *cl;
08570 struct ast_data *data_type;
08571
08572 AST_RWLIST_RDLOCK(&backends);
08573 AST_RWLIST_TRAVERSE(&backends, cl, list) {
08574 data_type = ast_data_add_node(data_root, "type");
08575 if (!data_type) {
08576 continue;
08577 }
08578 ast_data_add_str(data_type, "name", cl->tech->type);
08579 ast_data_add_str(data_type, "description", cl->tech->description);
08580 ast_data_add_bool(data_type, "devicestate", cl->tech->devicestate ? 1 : 0);
08581 ast_data_add_bool(data_type, "indications", cl->tech->indicate ? 1 : 0);
08582 ast_data_add_bool(data_type, "transfer", cl->tech->transfer ? 1 : 0);
08583 ast_data_add_bool(data_type, "send_digit_begin", cl->tech->send_digit_begin ? 1 : 0);
08584 ast_data_add_bool(data_type, "send_digit_end", cl->tech->send_digit_end ? 1 : 0);
08585 ast_data_add_bool(data_type, "call", cl->tech->call ? 1 : 0);
08586 ast_data_add_bool(data_type, "hangup", cl->tech->hangup ? 1 : 0);
08587 ast_data_add_bool(data_type, "answer", cl->tech->answer ? 1 : 0);
08588 ast_data_add_bool(data_type, "read", cl->tech->read ? 1 : 0);
08589 ast_data_add_bool(data_type, "write", cl->tech->write ? 1 : 0);
08590 ast_data_add_bool(data_type, "send_text", cl->tech->send_text ? 1 : 0);
08591 ast_data_add_bool(data_type, "send_image", cl->tech->send_image ? 1 : 0);
08592 ast_data_add_bool(data_type, "send_html", cl->tech->send_html ? 1 : 0);
08593 ast_data_add_bool(data_type, "exception", cl->tech->exception ? 1 : 0);
08594 ast_data_add_bool(data_type, "bridge", cl->tech->bridge ? 1 : 0);
08595 ast_data_add_bool(data_type, "early_bridge", cl->tech->early_bridge ? 1 : 0);
08596 ast_data_add_bool(data_type, "fixup", cl->tech->fixup ? 1 : 0);
08597 ast_data_add_bool(data_type, "setoption", cl->tech->setoption ? 1 : 0);
08598 ast_data_add_bool(data_type, "queryoption", cl->tech->queryoption ? 1 : 0);
08599 ast_data_add_bool(data_type, "write_video", cl->tech->write_video ? 1 : 0);
08600 ast_data_add_bool(data_type, "write_text", cl->tech->write_text ? 1 : 0);
08601 ast_data_add_bool(data_type, "bridged_channel", cl->tech->bridged_channel ? 1 : 0);
08602 ast_data_add_bool(data_type, "func_channel_read", cl->tech->func_channel_read ? 1 : 0);
08603 ast_data_add_bool(data_type, "func_channel_write", cl->tech->func_channel_write ? 1 : 0);
08604 ast_data_add_bool(data_type, "get_base_channel", cl->tech->get_base_channel ? 1 : 0);
08605 ast_data_add_bool(data_type, "set_base_channel", cl->tech->set_base_channel ? 1 : 0);
08606 ast_data_add_bool(data_type, "get_pvt_uniqueid", cl->tech->get_pvt_uniqueid ? 1 : 0);
08607 ast_data_add_bool(data_type, "cc_callback", cl->tech->cc_callback ? 1 : 0);
08608
08609 ast_data_add_codecs(data_type, "capabilities", cl->tech->capabilities);
08610
08611 if (!ast_data_search_match(search, data_type)) {
08612 ast_data_remove_node(data_root, data_type);
08613 }
08614 }
08615 AST_RWLIST_UNLOCK(&backends);
08616
08617 return 0;
08618 }
08619
08620
08621
08622
08623
08624 static const struct ast_data_handler channels_provider = {
08625 .version = AST_DATA_HANDLER_VERSION,
08626 .get = data_channels_provider_handler
08627 };
08628
08629
08630
08631
08632
08633 static const struct ast_data_handler channeltypes_provider = {
08634 .version = AST_DATA_HANDLER_VERSION,
08635 .get = data_channeltypes_provider_handler
08636 };
08637
08638 static const struct ast_data_entry channel_providers[] = {
08639 AST_DATA_ENTRY("/asterisk/core/channels", &channels_provider),
08640 AST_DATA_ENTRY("/asterisk/core/channeltypes", &channeltypes_provider),
08641 };
08642
08643 static void channels_shutdown(void)
08644 {
08645 ast_data_unregister(NULL);
08646 ast_cli_unregister_multiple(cli_channel, ARRAY_LEN(cli_channel));
08647 if (channels) {
08648 ao2_ref(channels, -1);
08649 channels = NULL;
08650 }
08651 }
08652
08653 void ast_channels_init(void)
08654 {
08655 channels = ao2_container_alloc(NUM_CHANNEL_BUCKETS,
08656 ast_channel_hash_cb, ast_channel_cmp_cb);
08657
08658 ast_cli_register_multiple(cli_channel, ARRAY_LEN(cli_channel));
08659
08660 ast_data_register_multiple_core(channel_providers, ARRAY_LEN(channel_providers));
08661
08662 ast_plc_reload();
08663
08664 ast_register_atexit(channels_shutdown);
08665 }
08666
08667
08668 char *ast_print_group(char *buf, int buflen, ast_group_t group)
08669 {
08670 unsigned int i;
08671 int first = 1;
08672 char num[3];
08673
08674 buf[0] = '\0';
08675
08676 if (!group)
08677 return buf;
08678
08679 for (i = 0; i <= 63; i++) {
08680 if (group & ((ast_group_t) 1 << i)) {
08681 if (!first) {
08682 strncat(buf, ", ", buflen - strlen(buf) - 1);
08683 } else {
08684 first = 0;
08685 }
08686 snprintf(num, sizeof(num), "%u", i);
08687 strncat(buf, num, buflen - strlen(buf) - 1);
08688 }
08689 }
08690 return buf;
08691 }
08692
08693 char *ast_print_namedgroups(struct ast_str **buf, struct ast_namedgroups *group)
08694 {
08695 struct ao2_container *grp = (struct ao2_container *) group;
08696 struct namedgroup_member *ng;
08697 int first = 1;
08698 struct ao2_iterator it;
08699
08700 if (!grp) {
08701 return ast_str_buffer(*buf);
08702 }
08703
08704 for (it = ao2_iterator_init(grp, 0); (ng = ao2_iterator_next(&it)); ao2_ref(ng, -1)) {
08705 if (!first) {
08706 ast_str_append(buf, 0, ", ");
08707 } else {
08708 first = 0;
08709 }
08710 ast_str_append(buf, 0, "%s", ng->name);
08711 }
08712 ao2_iterator_destroy(&it);
08713
08714 return ast_str_buffer(*buf);
08715 }
08716
08717 static int namedgroup_match(void *obj, void *arg, int flags)
08718 {
08719 void *match;
08720
08721 match = ao2_find(arg, obj, OBJ_POINTER);
08722 ao2_cleanup(match);
08723
08724 return match ? CMP_MATCH | CMP_STOP : 0;
08725 }
08726
08727 int ast_namedgroups_intersect(struct ast_namedgroups *a, struct ast_namedgroups *b)
08728 {
08729 void *match;
08730 struct ao2_container *group_a = (struct ao2_container *) a;
08731 struct ao2_container *group_b = (struct ao2_container *) b;
08732
08733 if (!a || !b) {
08734 return 0;
08735 }
08736
08737
08738
08739
08740
08741
08742 if (ao2_container_count(group_b) < ao2_container_count(group_a)) {
08743
08744 SWAP(group_a, group_b);
08745 }
08746 match = ao2_callback(group_a, 0, namedgroup_match, group_b);
08747 ao2_cleanup(match);
08748
08749 return match != NULL;
08750 }
08751
08752 void ast_set_variables(struct ast_channel *chan, struct ast_variable *vars)
08753 {
08754 struct ast_variable *cur;
08755
08756 for (cur = vars; cur; cur = cur->next)
08757 pbx_builtin_setvar_helper(chan, cur->name, cur->value);
08758 }
08759
08760 static void *silence_generator_alloc(struct ast_channel *chan, void *data)
08761 {
08762
08763 return data;
08764 }
08765
08766 static void silence_generator_release(struct ast_channel *chan, void *data)
08767 {
08768
08769 }
08770
08771 static int silence_generator_generate(struct ast_channel *chan, void *data, int len, int samples)
08772 {
08773 short buf[samples];
08774 struct ast_frame frame = {
08775 .frametype = AST_FRAME_VOICE,
08776 .data.ptr = buf,
08777 .samples = samples,
08778 .datalen = sizeof(buf),
08779 };
08780 ast_format_set(&frame.subclass.format, AST_FORMAT_SLINEAR, 0);
08781
08782 memset(buf, 0, sizeof(buf));
08783
08784 if (ast_write(chan, &frame))
08785 return -1;
08786
08787 return 0;
08788 }
08789
08790 static struct ast_generator silence_generator = {
08791 .alloc = silence_generator_alloc,
08792 .release = silence_generator_release,
08793 .generate = silence_generator_generate,
08794 };
08795
08796 struct ast_silence_generator {
08797 struct ast_format old_write_format;
08798 };
08799
08800 struct ast_silence_generator *ast_channel_start_silence_generator(struct ast_channel *chan)
08801 {
08802 struct ast_silence_generator *state;
08803
08804 if (!(state = ast_calloc(1, sizeof(*state)))) {
08805 return NULL;
08806 }
08807
08808 ast_format_copy(&state->old_write_format, ast_channel_writeformat(chan));
08809
08810 if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR) < 0) {
08811 ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
08812 ast_free(state);
08813 return NULL;
08814 }
08815
08816 ast_activate_generator(chan, &silence_generator, state);
08817
08818 ast_debug(1, "Started silence generator on '%s'\n", ast_channel_name(chan));
08819
08820 return state;
08821 }
08822
08823 static int deactivate_silence_generator(struct ast_channel *chan)
08824 {
08825 ast_channel_lock(chan);
08826
08827 if (!ast_channel_generatordata(chan)) {
08828 ast_debug(1, "Trying to stop silence generator when there is no generator on '%s'\n",
08829 ast_channel_name(chan));
08830 ast_channel_unlock(chan);
08831 return 0;
08832 }
08833 if (ast_channel_generator(chan) != &silence_generator) {
08834 ast_debug(1, "Trying to stop silence generator when it is not the current generator on '%s'\n",
08835 ast_channel_name(chan));
08836 ast_channel_unlock(chan);
08837 return 0;
08838 }
08839 deactivate_generator_nolock(chan);
08840
08841 ast_channel_unlock(chan);
08842
08843 return 1;
08844 }
08845
08846 void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_silence_generator *state)
08847 {
08848 if (!state) {
08849 return;
08850 }
08851
08852 if (deactivate_silence_generator(chan)) {
08853 ast_debug(1, "Stopped silence generator on '%s'\n", ast_channel_name(chan));
08854 if (ast_set_write_format(chan, &state->old_write_format) < 0)
08855 ast_log(LOG_ERROR, "Could not return write format to its original state\n");
08856 }
08857 ast_free(state);
08858 }
08859
08860
08861
08862 const char *channelreloadreason2txt(enum channelreloadreason reason)
08863 {
08864 switch (reason) {
08865 case CHANNEL_MODULE_LOAD:
08866 return "LOAD (Channel module load)";
08867
08868 case CHANNEL_MODULE_RELOAD:
08869 return "RELOAD (Channel module reload)";
08870
08871 case CHANNEL_CLI_RELOAD:
08872 return "CLIRELOAD (Channel module reload by CLI command)";
08873
08874 default:
08875 return "MANAGERRELOAD (Channel module reload by manager)";
08876 }
08877 };
08878
08879
08880
08881
08882
08883
08884
08885
08886
08887 int ast_say_number(struct ast_channel *chan, int num,
08888 const char *ints, const char *language, const char *options)
08889 {
08890 return ast_say_number_full(chan, num, ints, language, options, -1, -1);
08891 }
08892
08893 int ast_say_enumeration(struct ast_channel *chan, int num,
08894 const char *ints, const char *language, const char *options)
08895 {
08896 return ast_say_enumeration_full(chan, num, ints, language, options, -1, -1);
08897 }
08898
08899 int ast_say_digits(struct ast_channel *chan, int num,
08900 const char *ints, const char *lang)
08901 {
08902 return ast_say_digits_full(chan, num, ints, lang, -1, -1);
08903 }
08904
08905 int ast_say_digit_str(struct ast_channel *chan, const char *str,
08906 const char *ints, const char *lang)
08907 {
08908 return ast_say_digit_str_full(chan, str, ints, lang, -1, -1);
08909 }
08910
08911 int ast_say_character_str(struct ast_channel *chan, const char *str,
08912 const char *ints, const char *lang)
08913 {
08914 return ast_say_character_str_full(chan, str, ints, lang, -1, -1);
08915 }
08916
08917 int ast_say_phonetic_str(struct ast_channel *chan, const char *str,
08918 const char *ints, const char *lang)
08919 {
08920 return ast_say_phonetic_str_full(chan, str, ints, lang, -1, -1);
08921 }
08922
08923 int ast_say_digits_full(struct ast_channel *chan, int num,
08924 const char *ints, const char *lang, int audiofd, int ctrlfd)
08925 {
08926 char buf[256];
08927
08928 snprintf(buf, sizeof(buf), "%d", num);
08929
08930 return ast_say_digit_str_full(chan, buf, ints, lang, audiofd, ctrlfd);
08931 }
08932
08933 void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_party_caller *src)
08934 {
08935 ast_party_id_copy(&dest->id, &src->id);
08936 ast_party_id_copy(&dest->ani, &src->ani);
08937 dest->ani2 = src->ani2;
08938 }
08939
08940 void ast_connected_line_copy_to_caller(struct ast_party_caller *dest, const struct ast_party_connected_line *src)
08941 {
08942 ast_party_id_copy(&dest->id, &src->id);
08943 ast_party_id_copy(&dest->ani, &src->ani);
08944
08945 dest->ani2 = src->ani2;
08946 }
08947
08948 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)
08949 {
08950 if (ast_channel_connected(chan) == connected) {
08951
08952 return;
08953 }
08954
08955 ast_channel_lock(chan);
08956 ast_party_connected_line_set(ast_channel_connected(chan), connected, update);
08957 ast_channel_unlock(chan);
08958 }
08959
08960
08961 struct ast_party_name_ies {
08962
08963 int str;
08964
08965 int char_set;
08966
08967 int presentation;
08968
08969 int valid;
08970 };
08971
08972
08973
08974
08975
08976
08977
08978
08979
08980
08981
08982
08983
08984
08985
08986 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)
08987 {
08988 size_t length;
08989 size_t pos = 0;
08990
08991
08992
08993
08994
08995 if (name->str) {
08996 length = strlen(name->str);
08997 if (datalen < pos + (sizeof(data[0]) * 2) + length) {
08998 ast_log(LOG_WARNING, "No space left for %s name\n", label);
08999 return -1;
09000 }
09001 data[pos++] = ies->str;
09002 data[pos++] = length;
09003 memcpy(data + pos, name->str, length);
09004 pos += length;
09005 }
09006
09007 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
09008 ast_log(LOG_WARNING, "No space left for %s name char set\n", label);
09009 return -1;
09010 }
09011 data[pos++] = ies->char_set;
09012 data[pos++] = 1;
09013 data[pos++] = name->char_set;
09014
09015 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
09016 ast_log(LOG_WARNING, "No space left for %s name presentation\n", label);
09017 return -1;
09018 }
09019 data[pos++] = ies->presentation;
09020 data[pos++] = 1;
09021 data[pos++] = name->presentation;
09022
09023 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
09024 ast_log(LOG_WARNING, "No space left for %s name valid\n", label);
09025 return -1;
09026 }
09027 data[pos++] = ies->valid;
09028 data[pos++] = 1;
09029 data[pos++] = name->valid;
09030
09031 return pos;
09032 }
09033
09034
09035 struct ast_party_number_ies {
09036
09037 int str;
09038
09039 int plan;
09040
09041 int presentation;
09042
09043 int valid;
09044 };
09045
09046
09047
09048
09049
09050
09051
09052
09053
09054
09055
09056
09057
09058
09059
09060 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)
09061 {
09062 size_t length;
09063 size_t pos = 0;
09064
09065
09066
09067
09068
09069 if (number->str) {
09070 length = strlen(number->str);
09071 if (datalen < pos + (sizeof(data[0]) * 2) + length) {
09072 ast_log(LOG_WARNING, "No space left for %s number\n", label);
09073 return -1;
09074 }
09075 data[pos++] = ies->str;
09076 data[pos++] = length;
09077 memcpy(data + pos, number->str, length);
09078 pos += length;
09079 }
09080
09081 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
09082 ast_log(LOG_WARNING, "No space left for %s numbering plan\n", label);
09083 return -1;
09084 }
09085 data[pos++] = ies->plan;
09086 data[pos++] = 1;
09087 data[pos++] = number->plan;
09088
09089 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
09090 ast_log(LOG_WARNING, "No space left for %s number presentation\n", label);
09091 return -1;
09092 }
09093 data[pos++] = ies->presentation;
09094 data[pos++] = 1;
09095 data[pos++] = number->presentation;
09096
09097 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
09098 ast_log(LOG_WARNING, "No space left for %s number valid\n", label);
09099 return -1;
09100 }
09101 data[pos++] = ies->valid;
09102 data[pos++] = 1;
09103 data[pos++] = number->valid;
09104
09105 return pos;
09106 }
09107
09108
09109 struct ast_party_subaddress_ies {
09110
09111 int str;
09112
09113 int type;
09114
09115 int odd_even_indicator;
09116
09117 int valid;
09118 };
09119
09120
09121
09122
09123
09124
09125
09126
09127
09128
09129
09130
09131
09132
09133
09134 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)
09135 {
09136 size_t length;
09137 size_t pos = 0;
09138
09139
09140
09141
09142
09143 if (subaddress->str) {
09144 length = strlen(subaddress->str);
09145 if (datalen < pos + (sizeof(data[0]) * 2) + length) {
09146 ast_log(LOG_WARNING, "No space left for %s subaddress\n", label);
09147 return -1;
09148 }
09149 data[pos++] = ies->str;
09150 data[pos++] = length;
09151 memcpy(data + pos, subaddress->str, length);
09152 pos += length;
09153 }
09154
09155 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
09156 ast_log(LOG_WARNING, "No space left for %s type of subaddress\n", label);
09157 return -1;
09158 }
09159 data[pos++] = ies->type;
09160 data[pos++] = 1;
09161 data[pos++] = subaddress->type;
09162
09163 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
09164 ast_log(LOG_WARNING,
09165 "No space left for %s subaddress odd-even indicator\n", label);
09166 return -1;
09167 }
09168 data[pos++] = ies->odd_even_indicator;
09169 data[pos++] = 1;
09170 data[pos++] = subaddress->odd_even_indicator;
09171
09172 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
09173 ast_log(LOG_WARNING, "No space left for %s subaddress valid\n", label);
09174 return -1;
09175 }
09176 data[pos++] = ies->valid;
09177 data[pos++] = 1;
09178 data[pos++] = subaddress->valid;
09179
09180 return pos;
09181 }
09182
09183
09184 struct ast_party_id_ies {
09185
09186 struct ast_party_name_ies name;
09187
09188 struct ast_party_number_ies number;
09189
09190 struct ast_party_subaddress_ies subaddress;
09191
09192 int tag;
09193
09194
09195
09196
09197 int combined_presentation;
09198 };
09199
09200
09201
09202
09203
09204
09205
09206
09207
09208
09209
09210
09211
09212
09213
09214
09215 static int party_id_build_data(unsigned char *data, size_t datalen,
09216 const struct ast_party_id *id, const char *label, const struct ast_party_id_ies *ies,
09217 const struct ast_set_party_id *update)
09218 {
09219 size_t length;
09220 size_t pos = 0;
09221 int res;
09222
09223
09224
09225
09226
09227
09228 if (!update || update->name) {
09229 res = party_name_build_data(data + pos, datalen - pos, &id->name, label,
09230 &ies->name);
09231 if (res < 0) {
09232 return -1;
09233 }
09234 pos += res;
09235 }
09236
09237 if (!update || update->number) {
09238 res = party_number_build_data(data + pos, datalen - pos, &id->number, label,
09239 &ies->number);
09240 if (res < 0) {
09241 return -1;
09242 }
09243 pos += res;
09244 }
09245
09246 if (!update || update->subaddress) {
09247 res = party_subaddress_build_data(data + pos, datalen - pos, &id->subaddress,
09248 label, &ies->subaddress);
09249 if (res < 0) {
09250 return -1;
09251 }
09252 pos += res;
09253 }
09254
09255
09256 if (id->tag) {
09257 length = strlen(id->tag);
09258 if (datalen < pos + (sizeof(data[0]) * 2) + length) {
09259 ast_log(LOG_WARNING, "No space left for %s tag\n", label);
09260 return -1;
09261 }
09262 data[pos++] = ies->tag;
09263 data[pos++] = length;
09264 memcpy(data + pos, id->tag, length);
09265 pos += length;
09266 }
09267
09268
09269 if (ies->combined_presentation && (!update || update->number)) {
09270 int presentation;
09271
09272 if (!update || update->name) {
09273 presentation = ast_party_id_presentation(id);
09274 } else {
09275
09276
09277
09278
09279
09280 presentation = id->number.presentation;
09281 }
09282
09283 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
09284 ast_log(LOG_WARNING, "No space left for %s combined presentation\n", label);
09285 return -1;
09286 }
09287 data[pos++] = ies->combined_presentation;
09288 data[pos++] = 1;
09289 data[pos++] = presentation;
09290 }
09291
09292 return pos;
09293 }
09294
09295
09296
09297
09298
09299 enum {
09300 AST_CONNECTED_LINE_NUMBER,
09301 AST_CONNECTED_LINE_NAME,
09302 AST_CONNECTED_LINE_NUMBER_PLAN,
09303 AST_CONNECTED_LINE_ID_PRESENTATION,
09304 AST_CONNECTED_LINE_SOURCE,
09305 AST_CONNECTED_LINE_SUBADDRESS,
09306 AST_CONNECTED_LINE_SUBADDRESS_TYPE,
09307 AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN,
09308 AST_CONNECTED_LINE_SUBADDRESS_VALID,
09309 AST_CONNECTED_LINE_TAG,
09310 AST_CONNECTED_LINE_VERSION,
09311
09312
09313
09314
09315 AST_CONNECTED_LINE_NAME_VALID,
09316 AST_CONNECTED_LINE_NAME_CHAR_SET,
09317 AST_CONNECTED_LINE_NAME_PRESENTATION,
09318 AST_CONNECTED_LINE_NUMBER_VALID,
09319 AST_CONNECTED_LINE_NUMBER_PRESENTATION,
09320 AST_CONNECTED_LINE_PRIV_NUMBER,
09321 AST_CONNECTED_LINE_PRIV_NUMBER_PLAN,
09322 AST_CONNECTED_LINE_PRIV_NUMBER_VALID,
09323 AST_CONNECTED_LINE_PRIV_NUMBER_PRESENTATION,
09324 AST_CONNECTED_LINE_PRIV_NAME,
09325 AST_CONNECTED_LINE_PRIV_NAME_VALID,
09326 AST_CONNECTED_LINE_PRIV_NAME_CHAR_SET,
09327 AST_CONNECTED_LINE_PRIV_NAME_PRESENTATION,
09328 AST_CONNECTED_LINE_PRIV_SUBADDRESS,
09329 AST_CONNECTED_LINE_PRIV_SUBADDRESS_TYPE,
09330 AST_CONNECTED_LINE_PRIV_SUBADDRESS_ODD_EVEN,
09331 AST_CONNECTED_LINE_PRIV_SUBADDRESS_VALID,
09332 AST_CONNECTED_LINE_PRIV_TAG,
09333 };
09334
09335 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)
09336 {
09337 int32_t value;
09338 size_t pos = 0;
09339 int res;
09340
09341 static const struct ast_party_id_ies ies = {
09342 .name.str = AST_CONNECTED_LINE_NAME,
09343 .name.char_set = AST_CONNECTED_LINE_NAME_CHAR_SET,
09344 .name.presentation = AST_CONNECTED_LINE_NAME_PRESENTATION,
09345 .name.valid = AST_CONNECTED_LINE_NAME_VALID,
09346
09347 .number.str = AST_CONNECTED_LINE_NUMBER,
09348 .number.plan = AST_CONNECTED_LINE_NUMBER_PLAN,
09349 .number.presentation = AST_CONNECTED_LINE_NUMBER_PRESENTATION,
09350 .number.valid = AST_CONNECTED_LINE_NUMBER_VALID,
09351
09352 .subaddress.str = AST_CONNECTED_LINE_SUBADDRESS,
09353 .subaddress.type = AST_CONNECTED_LINE_SUBADDRESS_TYPE,
09354 .subaddress.odd_even_indicator = AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN,
09355 .subaddress.valid = AST_CONNECTED_LINE_SUBADDRESS_VALID,
09356
09357 .tag = AST_CONNECTED_LINE_TAG,
09358 .combined_presentation = AST_CONNECTED_LINE_ID_PRESENTATION,
09359 };
09360
09361 static const struct ast_party_id_ies priv_ies = {
09362 .name.str = AST_CONNECTED_LINE_PRIV_NAME,
09363 .name.char_set = AST_CONNECTED_LINE_PRIV_NAME_CHAR_SET,
09364 .name.presentation = AST_CONNECTED_LINE_PRIV_NAME_PRESENTATION,
09365 .name.valid = AST_CONNECTED_LINE_PRIV_NAME_VALID,
09366
09367 .number.str = AST_CONNECTED_LINE_PRIV_NUMBER,
09368 .number.plan = AST_CONNECTED_LINE_PRIV_NUMBER_PLAN,
09369 .number.presentation = AST_CONNECTED_LINE_PRIV_NUMBER_PRESENTATION,
09370 .number.valid = AST_CONNECTED_LINE_PRIV_NUMBER_VALID,
09371
09372 .subaddress.str = AST_CONNECTED_LINE_PRIV_SUBADDRESS,
09373 .subaddress.type = AST_CONNECTED_LINE_PRIV_SUBADDRESS_TYPE,
09374 .subaddress.odd_even_indicator = AST_CONNECTED_LINE_PRIV_SUBADDRESS_ODD_EVEN,
09375 .subaddress.valid = AST_CONNECTED_LINE_PRIV_SUBADDRESS_VALID,
09376
09377 .tag = AST_CONNECTED_LINE_PRIV_TAG,
09378 .combined_presentation = 0,
09379 };
09380
09381
09382
09383
09384
09385
09386
09387 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
09388 ast_log(LOG_WARNING, "No space left for connected line frame version\n");
09389 return -1;
09390 }
09391 data[pos++] = AST_CONNECTED_LINE_VERSION;
09392 data[pos++] = 1;
09393 data[pos++] = 2;
09394
09395 res = party_id_build_data(data + pos, datalen - pos, &connected->id,
09396 "connected line", &ies, update ? &update->id : NULL);
09397 if (res < 0) {
09398 return -1;
09399 }
09400 pos += res;
09401
09402 res = party_id_build_data(data + pos, datalen - pos, &connected->priv,
09403 "connected line priv", &priv_ies, update ? &update->priv : NULL);
09404 if (res < 0) {
09405 return -1;
09406 }
09407 pos += res;
09408
09409
09410 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
09411 ast_log(LOG_WARNING, "No space left for connected line source\n");
09412 return -1;
09413 }
09414 data[pos++] = AST_CONNECTED_LINE_SOURCE;
09415 data[pos++] = sizeof(value);
09416 value = htonl(connected->source);
09417 memcpy(data + pos, &value, sizeof(value));
09418 pos += sizeof(value);
09419
09420 return pos;
09421 }
09422
09423 int ast_connected_line_parse_data(const unsigned char *data, size_t datalen, struct ast_party_connected_line *connected)
09424 {
09425 size_t pos;
09426 unsigned char ie_len;
09427 unsigned char ie_id;
09428 int32_t value;
09429 int frame_version = 1;
09430 int combined_presentation = 0;
09431 int got_combined_presentation = 0;
09432
09433 for (pos = 0; pos < datalen; pos += ie_len) {
09434 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) {
09435 ast_log(LOG_WARNING, "Invalid connected line update\n");
09436 return -1;
09437 }
09438 ie_id = data[pos++];
09439 ie_len = data[pos++];
09440 if (datalen < pos + ie_len) {
09441 ast_log(LOG_WARNING, "Invalid connected line update\n");
09442 return -1;
09443 }
09444
09445 switch (ie_id) {
09446
09447 case AST_CONNECTED_LINE_VERSION:
09448 if (ie_len != 1) {
09449 ast_log(LOG_WARNING, "Invalid connected line frame version (%u)\n",
09450 (unsigned) ie_len);
09451 break;
09452 }
09453 frame_version = data[pos];
09454 break;
09455
09456 case AST_CONNECTED_LINE_NAME:
09457 ast_free(connected->id.name.str);
09458 connected->id.name.str = ast_malloc(ie_len + 1);
09459 if (connected->id.name.str) {
09460 memcpy(connected->id.name.str, data + pos, ie_len);
09461 connected->id.name.str[ie_len] = 0;
09462 }
09463 break;
09464 case AST_CONNECTED_LINE_NAME_CHAR_SET:
09465 if (ie_len != 1) {
09466 ast_log(LOG_WARNING, "Invalid connected line name char set (%u)\n",
09467 (unsigned) ie_len);
09468 break;
09469 }
09470 connected->id.name.char_set = data[pos];
09471 break;
09472 case AST_CONNECTED_LINE_NAME_PRESENTATION:
09473 if (ie_len != 1) {
09474 ast_log(LOG_WARNING, "Invalid connected line name presentation (%u)\n",
09475 (unsigned) ie_len);
09476 break;
09477 }
09478 connected->id.name.presentation = data[pos];
09479 break;
09480 case AST_CONNECTED_LINE_NAME_VALID:
09481 if (ie_len != 1) {
09482 ast_log(LOG_WARNING, "Invalid connected line name valid (%u)\n",
09483 (unsigned) ie_len);
09484 break;
09485 }
09486 connected->id.name.valid = data[pos];
09487 break;
09488
09489 case AST_CONNECTED_LINE_NUMBER:
09490 ast_free(connected->id.number.str);
09491 connected->id.number.str = ast_malloc(ie_len + 1);
09492 if (connected->id.number.str) {
09493 memcpy(connected->id.number.str, data + pos, ie_len);
09494 connected->id.number.str[ie_len] = 0;
09495 }
09496 break;
09497 case AST_CONNECTED_LINE_NUMBER_PLAN:
09498 if (ie_len != 1) {
09499 ast_log(LOG_WARNING, "Invalid connected line numbering plan (%u)\n",
09500 (unsigned) ie_len);
09501 break;
09502 }
09503 connected->id.number.plan = data[pos];
09504 break;
09505 case AST_CONNECTED_LINE_NUMBER_PRESENTATION:
09506 if (ie_len != 1) {
09507 ast_log(LOG_WARNING, "Invalid connected line number presentation (%u)\n",
09508 (unsigned) ie_len);
09509 break;
09510 }
09511 connected->id.number.presentation = data[pos];
09512 break;
09513 case AST_CONNECTED_LINE_NUMBER_VALID:
09514 if (ie_len != 1) {
09515 ast_log(LOG_WARNING, "Invalid connected line number valid (%u)\n",
09516 (unsigned) ie_len);
09517 break;
09518 }
09519 connected->id.number.valid = data[pos];
09520 break;
09521
09522 case AST_CONNECTED_LINE_SUBADDRESS:
09523 ast_free(connected->id.subaddress.str);
09524 connected->id.subaddress.str = ast_malloc(ie_len + 1);
09525 if (connected->id.subaddress.str) {
09526 memcpy(connected->id.subaddress.str, data + pos, ie_len);
09527 connected->id.subaddress.str[ie_len] = 0;
09528 }
09529 break;
09530 case AST_CONNECTED_LINE_SUBADDRESS_TYPE:
09531 if (ie_len != 1) {
09532 ast_log(LOG_WARNING, "Invalid connected line type of subaddress (%u)\n",
09533 (unsigned) ie_len);
09534 break;
09535 }
09536 connected->id.subaddress.type = data[pos];
09537 break;
09538 case AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN:
09539 if (ie_len != 1) {
09540 ast_log(LOG_WARNING,
09541 "Invalid connected line subaddress odd-even indicator (%u)\n",
09542 (unsigned) ie_len);
09543 break;
09544 }
09545 connected->id.subaddress.odd_even_indicator = data[pos];
09546 break;
09547 case AST_CONNECTED_LINE_SUBADDRESS_VALID:
09548 if (ie_len != 1) {
09549 ast_log(LOG_WARNING, "Invalid connected line subaddress valid (%u)\n",
09550 (unsigned) ie_len);
09551 break;
09552 }
09553 connected->id.subaddress.valid = data[pos];
09554 break;
09555
09556 case AST_CONNECTED_LINE_TAG:
09557 ast_free(connected->id.tag);
09558 connected->id.tag = ast_malloc(ie_len + 1);
09559 if (connected->id.tag) {
09560 memcpy(connected->id.tag, data + pos, ie_len);
09561 connected->id.tag[ie_len] = 0;
09562 }
09563 break;
09564
09565 case AST_CONNECTED_LINE_ID_PRESENTATION:
09566 if (ie_len != 1) {
09567 ast_log(LOG_WARNING, "Invalid connected line combined presentation (%u)\n",
09568 (unsigned) ie_len);
09569 break;
09570 }
09571 combined_presentation = data[pos];
09572 got_combined_presentation = 1;
09573 break;
09574
09575 case AST_CONNECTED_LINE_PRIV_NAME:
09576 ast_free(connected->priv.name.str);
09577 connected->priv.name.str = ast_malloc(ie_len + 1);
09578 if (connected->priv.name.str) {
09579 memcpy(connected->priv.name.str, data + pos, ie_len);
09580 connected->priv.name.str[ie_len] = 0;
09581 }
09582 break;
09583 case AST_CONNECTED_LINE_PRIV_NAME_CHAR_SET:
09584 if (ie_len != 1) {
09585 ast_log(LOG_WARNING, "Invalid connected line private name char set (%u)\n",
09586 (unsigned) ie_len);
09587 break;
09588 }
09589 connected->priv.name.char_set = data[pos];
09590 break;
09591 case AST_CONNECTED_LINE_PRIV_NAME_PRESENTATION:
09592 if (ie_len != 1) {
09593 ast_log(LOG_WARNING, "Invalid connected line private name presentation (%u)\n",
09594 (unsigned) ie_len);
09595 break;
09596 }
09597 connected->priv.name.presentation = data[pos];
09598 break;
09599 case AST_CONNECTED_LINE_PRIV_NAME_VALID:
09600 if (ie_len != 1) {
09601 ast_log(LOG_WARNING, "Invalid connected line private name valid (%u)\n",
09602 (unsigned) ie_len);
09603 break;
09604 }
09605 connected->priv.name.valid = data[pos];
09606 break;
09607
09608 case AST_CONNECTED_LINE_PRIV_NUMBER:
09609 ast_free(connected->priv.number.str);
09610 connected->priv.number.str = ast_malloc(ie_len + 1);
09611 if (connected->priv.number.str) {
09612 memcpy(connected->priv.number.str, data + pos, ie_len);
09613 connected->priv.number.str[ie_len] = 0;
09614 }
09615 break;
09616 case AST_CONNECTED_LINE_PRIV_NUMBER_PLAN:
09617 if (ie_len != 1) {
09618 ast_log(LOG_WARNING, "Invalid connected line private numbering plan (%u)\n",
09619 (unsigned) ie_len);
09620 break;
09621 }
09622 connected->priv.number.plan = data[pos];
09623 break;
09624 case AST_CONNECTED_LINE_PRIV_NUMBER_PRESENTATION:
09625 if (ie_len != 1) {
09626 ast_log(LOG_WARNING, "Invalid connected line private number presentation (%u)\n",
09627 (unsigned) ie_len);
09628 break;
09629 }
09630 connected->priv.number.presentation = data[pos];
09631 break;
09632 case AST_CONNECTED_LINE_PRIV_NUMBER_VALID:
09633 if (ie_len != 1) {
09634 ast_log(LOG_WARNING, "Invalid connected line private number valid (%u)\n",
09635 (unsigned) ie_len);
09636 break;
09637 }
09638 connected->priv.number.valid = data[pos];
09639 break;
09640
09641 case AST_CONNECTED_LINE_PRIV_SUBADDRESS:
09642 ast_free(connected->priv.subaddress.str);
09643 connected->priv.subaddress.str = ast_malloc(ie_len + 1);
09644 if (connected->priv.subaddress.str) {
09645 memcpy(connected->priv.subaddress.str, data + pos, ie_len);
09646 connected->priv.subaddress.str[ie_len] = 0;
09647 }
09648 break;
09649 case AST_CONNECTED_LINE_PRIV_SUBADDRESS_TYPE:
09650 if (ie_len != 1) {
09651 ast_log(LOG_WARNING, "Invalid connected line private type of subaddress (%u)\n",
09652 (unsigned) ie_len);
09653 break;
09654 }
09655 connected->priv.subaddress.type = data[pos];
09656 break;
09657 case AST_CONNECTED_LINE_PRIV_SUBADDRESS_ODD_EVEN:
09658 if (ie_len != 1) {
09659 ast_log(LOG_WARNING,
09660 "Invalid connected line private subaddress odd-even indicator (%u)\n",
09661 (unsigned) ie_len);
09662 break;
09663 }
09664 connected->priv.subaddress.odd_even_indicator = data[pos];
09665 break;
09666 case AST_CONNECTED_LINE_PRIV_SUBADDRESS_VALID:
09667 if (ie_len != 1) {
09668 ast_log(LOG_WARNING, "Invalid connected line private subaddress valid (%u)\n",
09669 (unsigned) ie_len);
09670 break;
09671 }
09672 connected->priv.subaddress.valid = data[pos];
09673 break;
09674
09675 case AST_CONNECTED_LINE_PRIV_TAG:
09676 ast_free(connected->priv.tag);
09677 connected->priv.tag = ast_malloc(ie_len + 1);
09678 if (connected->priv.tag) {
09679 memcpy(connected->priv.tag, data + pos, ie_len);
09680 connected->priv.tag[ie_len] = 0;
09681 }
09682 break;
09683
09684 case AST_CONNECTED_LINE_SOURCE:
09685 if (ie_len != sizeof(value)) {
09686 ast_log(LOG_WARNING, "Invalid connected line source (%u)\n",
09687 (unsigned) ie_len);
09688 break;
09689 }
09690 memcpy(&value, data + pos, sizeof(value));
09691 connected->source = ntohl(value);
09692 break;
09693
09694 default:
09695 ast_debug(1, "Unknown connected line element: %u (%u)\n",
09696 (unsigned) ie_id, (unsigned) ie_len);
09697 break;
09698 }
09699 }
09700
09701 switch (frame_version) {
09702 case 1:
09703
09704
09705
09706
09707 connected->id.name.valid = 1;
09708 connected->id.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
09709 connected->id.number.valid = 1;
09710 if (got_combined_presentation) {
09711 connected->id.name.presentation = combined_presentation;
09712 connected->id.number.presentation = combined_presentation;
09713 }
09714 break;
09715 case 2:
09716
09717 break;
09718 default:
09719
09720
09721
09722
09723 ast_debug(1, "Connected line frame has newer version: %u\n",
09724 (unsigned) frame_version);
09725 break;
09726 }
09727
09728 return 0;
09729 }
09730
09731 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)
09732 {
09733 unsigned char data[1024];
09734 size_t datalen;
09735
09736 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update);
09737 if (datalen == (size_t) -1) {
09738 return;
09739 }
09740
09741 ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen);
09742 }
09743
09744 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)
09745 {
09746 unsigned char data[1024];
09747 size_t datalen;
09748
09749 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update);
09750 if (datalen == (size_t) -1) {
09751 return;
09752 }
09753
09754 ast_queue_control_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen);
09755 }
09756
09757 void ast_channel_set_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
09758 {
09759 if (ast_channel_redirecting(chan) == redirecting) {
09760
09761 return;
09762 }
09763
09764 ast_channel_lock(chan);
09765 ast_party_redirecting_set(ast_channel_redirecting(chan), redirecting, update);
09766 ast_channel_unlock(chan);
09767 }
09768
09769
09770
09771
09772
09773 enum {
09774 AST_REDIRECTING_FROM_NUMBER,
09775 AST_REDIRECTING_FROM_NAME,
09776 AST_REDIRECTING_FROM_NUMBER_PLAN,
09777 AST_REDIRECTING_FROM_ID_PRESENTATION,
09778 AST_REDIRECTING_TO_NUMBER,
09779 AST_REDIRECTING_TO_NAME,
09780 AST_REDIRECTING_TO_NUMBER_PLAN,
09781 AST_REDIRECTING_TO_ID_PRESENTATION,
09782 AST_REDIRECTING_REASON,
09783 AST_REDIRECTING_COUNT,
09784 AST_REDIRECTING_FROM_SUBADDRESS,
09785 AST_REDIRECTING_FROM_SUBADDRESS_TYPE,
09786 AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN,
09787 AST_REDIRECTING_FROM_SUBADDRESS_VALID,
09788 AST_REDIRECTING_TO_SUBADDRESS,
09789 AST_REDIRECTING_TO_SUBADDRESS_TYPE,
09790 AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN,
09791 AST_REDIRECTING_TO_SUBADDRESS_VALID,
09792 AST_REDIRECTING_FROM_TAG,
09793 AST_REDIRECTING_TO_TAG,
09794 AST_REDIRECTING_VERSION,
09795
09796
09797
09798
09799 AST_REDIRECTING_FROM_NAME_VALID,
09800 AST_REDIRECTING_FROM_NAME_CHAR_SET,
09801 AST_REDIRECTING_FROM_NAME_PRESENTATION,
09802 AST_REDIRECTING_FROM_NUMBER_VALID,
09803 AST_REDIRECTING_FROM_NUMBER_PRESENTATION,
09804 AST_REDIRECTING_TO_NAME_VALID,
09805 AST_REDIRECTING_TO_NAME_CHAR_SET,
09806 AST_REDIRECTING_TO_NAME_PRESENTATION,
09807 AST_REDIRECTING_TO_NUMBER_VALID,
09808 AST_REDIRECTING_TO_NUMBER_PRESENTATION,
09809 AST_REDIRECTING_ORIG_NUMBER,
09810 AST_REDIRECTING_ORIG_NUMBER_VALID,
09811 AST_REDIRECTING_ORIG_NUMBER_PLAN,
09812 AST_REDIRECTING_ORIG_NUMBER_PRESENTATION,
09813 AST_REDIRECTING_ORIG_NAME,
09814 AST_REDIRECTING_ORIG_NAME_VALID,
09815 AST_REDIRECTING_ORIG_NAME_CHAR_SET,
09816 AST_REDIRECTING_ORIG_NAME_PRESENTATION,
09817 AST_REDIRECTING_ORIG_SUBADDRESS,
09818 AST_REDIRECTING_ORIG_SUBADDRESS_TYPE,
09819 AST_REDIRECTING_ORIG_SUBADDRESS_ODD_EVEN,
09820 AST_REDIRECTING_ORIG_SUBADDRESS_VALID,
09821 AST_REDIRECTING_ORIG_TAG,
09822 AST_REDIRECTING_ORIG_REASON,
09823 AST_REDIRECTING_PRIV_TO_NUMBER,
09824 AST_REDIRECTING_PRIV_TO_NUMBER_PLAN,
09825 AST_REDIRECTING_PRIV_TO_NUMBER_VALID,
09826 AST_REDIRECTING_PRIV_TO_NUMBER_PRESENTATION,
09827 AST_REDIRECTING_PRIV_TO_NAME,
09828 AST_REDIRECTING_PRIV_TO_NAME_VALID,
09829 AST_REDIRECTING_PRIV_TO_NAME_CHAR_SET,
09830 AST_REDIRECTING_PRIV_TO_NAME_PRESENTATION,
09831 AST_REDIRECTING_PRIV_TO_SUBADDRESS,
09832 AST_REDIRECTING_PRIV_TO_SUBADDRESS_TYPE,
09833 AST_REDIRECTING_PRIV_TO_SUBADDRESS_ODD_EVEN,
09834 AST_REDIRECTING_PRIV_TO_SUBADDRESS_VALID,
09835 AST_REDIRECTING_PRIV_TO_TAG,
09836 AST_REDIRECTING_PRIV_FROM_NUMBER,
09837 AST_REDIRECTING_PRIV_FROM_NUMBER_PLAN,
09838 AST_REDIRECTING_PRIV_FROM_NUMBER_VALID,
09839 AST_REDIRECTING_PRIV_FROM_NUMBER_PRESENTATION,
09840 AST_REDIRECTING_PRIV_FROM_NAME,
09841 AST_REDIRECTING_PRIV_FROM_NAME_VALID,
09842 AST_REDIRECTING_PRIV_FROM_NAME_CHAR_SET,
09843 AST_REDIRECTING_PRIV_FROM_NAME_PRESENTATION,
09844 AST_REDIRECTING_PRIV_FROM_SUBADDRESS,
09845 AST_REDIRECTING_PRIV_FROM_SUBADDRESS_TYPE,
09846 AST_REDIRECTING_PRIV_FROM_SUBADDRESS_ODD_EVEN,
09847 AST_REDIRECTING_PRIV_FROM_SUBADDRESS_VALID,
09848 AST_REDIRECTING_PRIV_FROM_TAG,
09849 AST_REDIRECTING_PRIV_ORIG_NUMBER,
09850 AST_REDIRECTING_PRIV_ORIG_NUMBER_VALID,
09851 AST_REDIRECTING_PRIV_ORIG_NUMBER_PLAN,
09852 AST_REDIRECTING_PRIV_ORIG_NUMBER_PRESENTATION,
09853 AST_REDIRECTING_PRIV_ORIG_NAME,
09854 AST_REDIRECTING_PRIV_ORIG_NAME_VALID,
09855 AST_REDIRECTING_PRIV_ORIG_NAME_CHAR_SET,
09856 AST_REDIRECTING_PRIV_ORIG_NAME_PRESENTATION,
09857 AST_REDIRECTING_PRIV_ORIG_SUBADDRESS,
09858 AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_TYPE,
09859 AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_ODD_EVEN,
09860 AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_VALID,
09861 AST_REDIRECTING_PRIV_ORIG_TAG,
09862 };
09863
09864 int ast_redirecting_build_data(unsigned char *data, size_t datalen, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
09865 {
09866 int32_t value;
09867 size_t pos = 0;
09868 int res;
09869
09870 static const struct ast_party_id_ies orig_ies = {
09871 .name.str = AST_REDIRECTING_ORIG_NAME,
09872 .name.char_set = AST_REDIRECTING_ORIG_NAME_CHAR_SET,
09873 .name.presentation = AST_REDIRECTING_ORIG_NAME_PRESENTATION,
09874 .name.valid = AST_REDIRECTING_ORIG_NAME_VALID,
09875
09876 .number.str = AST_REDIRECTING_ORIG_NUMBER,
09877 .number.plan = AST_REDIRECTING_ORIG_NUMBER_PLAN,
09878 .number.presentation = AST_REDIRECTING_ORIG_NUMBER_PRESENTATION,
09879 .number.valid = AST_REDIRECTING_ORIG_NUMBER_VALID,
09880
09881 .subaddress.str = AST_REDIRECTING_ORIG_SUBADDRESS,
09882 .subaddress.type = AST_REDIRECTING_ORIG_SUBADDRESS_TYPE,
09883 .subaddress.odd_even_indicator = AST_REDIRECTING_ORIG_SUBADDRESS_ODD_EVEN,
09884 .subaddress.valid = AST_REDIRECTING_ORIG_SUBADDRESS_VALID,
09885
09886 .tag = AST_REDIRECTING_ORIG_TAG,
09887 .combined_presentation = 0,
09888 };
09889 static const struct ast_party_id_ies from_ies = {
09890 .name.str = AST_REDIRECTING_FROM_NAME,
09891 .name.char_set = AST_REDIRECTING_FROM_NAME_CHAR_SET,
09892 .name.presentation = AST_REDIRECTING_FROM_NAME_PRESENTATION,
09893 .name.valid = AST_REDIRECTING_FROM_NAME_VALID,
09894
09895 .number.str = AST_REDIRECTING_FROM_NUMBER,
09896 .number.plan = AST_REDIRECTING_FROM_NUMBER_PLAN,
09897 .number.presentation = AST_REDIRECTING_FROM_NUMBER_PRESENTATION,
09898 .number.valid = AST_REDIRECTING_FROM_NUMBER_VALID,
09899
09900 .subaddress.str = AST_REDIRECTING_FROM_SUBADDRESS,
09901 .subaddress.type = AST_REDIRECTING_FROM_SUBADDRESS_TYPE,
09902 .subaddress.odd_even_indicator = AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN,
09903 .subaddress.valid = AST_REDIRECTING_FROM_SUBADDRESS_VALID,
09904
09905 .tag = AST_REDIRECTING_FROM_TAG,
09906 .combined_presentation = AST_REDIRECTING_FROM_ID_PRESENTATION,
09907 };
09908 static const struct ast_party_id_ies to_ies = {
09909 .name.str = AST_REDIRECTING_TO_NAME,
09910 .name.char_set = AST_REDIRECTING_TO_NAME_CHAR_SET,
09911 .name.presentation = AST_REDIRECTING_TO_NAME_PRESENTATION,
09912 .name.valid = AST_REDIRECTING_TO_NAME_VALID,
09913
09914 .number.str = AST_REDIRECTING_TO_NUMBER,
09915 .number.plan = AST_REDIRECTING_TO_NUMBER_PLAN,
09916 .number.presentation = AST_REDIRECTING_TO_NUMBER_PRESENTATION,
09917 .number.valid = AST_REDIRECTING_TO_NUMBER_VALID,
09918
09919 .subaddress.str = AST_REDIRECTING_TO_SUBADDRESS,
09920 .subaddress.type = AST_REDIRECTING_TO_SUBADDRESS_TYPE,
09921 .subaddress.odd_even_indicator = AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN,
09922 .subaddress.valid = AST_REDIRECTING_TO_SUBADDRESS_VALID,
09923
09924 .tag = AST_REDIRECTING_TO_TAG,
09925 .combined_presentation = AST_REDIRECTING_TO_ID_PRESENTATION,
09926 };
09927 static const struct ast_party_id_ies priv_orig_ies = {
09928 .name.str = AST_REDIRECTING_PRIV_ORIG_NAME,
09929 .name.char_set = AST_REDIRECTING_PRIV_ORIG_NAME_CHAR_SET,
09930 .name.presentation = AST_REDIRECTING_PRIV_ORIG_NAME_PRESENTATION,
09931 .name.valid = AST_REDIRECTING_PRIV_ORIG_NAME_VALID,
09932
09933 .number.str = AST_REDIRECTING_PRIV_ORIG_NUMBER,
09934 .number.plan = AST_REDIRECTING_PRIV_ORIG_NUMBER_PLAN,
09935 .number.presentation = AST_REDIRECTING_PRIV_ORIG_NUMBER_PRESENTATION,
09936 .number.valid = AST_REDIRECTING_PRIV_ORIG_NUMBER_VALID,
09937
09938 .subaddress.str = AST_REDIRECTING_PRIV_ORIG_SUBADDRESS,
09939 .subaddress.type = AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_TYPE,
09940 .subaddress.odd_even_indicator = AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_ODD_EVEN,
09941 .subaddress.valid = AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_VALID,
09942
09943 .tag = AST_REDIRECTING_PRIV_ORIG_TAG,
09944 .combined_presentation = 0,
09945 };
09946 static const struct ast_party_id_ies priv_from_ies = {
09947 .name.str = AST_REDIRECTING_PRIV_FROM_NAME,
09948 .name.char_set = AST_REDIRECTING_PRIV_FROM_NAME_CHAR_SET,
09949 .name.presentation = AST_REDIRECTING_PRIV_FROM_NAME_PRESENTATION,
09950 .name.valid = AST_REDIRECTING_PRIV_FROM_NAME_VALID,
09951
09952 .number.str = AST_REDIRECTING_PRIV_FROM_NUMBER,
09953 .number.plan = AST_REDIRECTING_PRIV_FROM_NUMBER_PLAN,
09954 .number.presentation = AST_REDIRECTING_PRIV_FROM_NUMBER_PRESENTATION,
09955 .number.valid = AST_REDIRECTING_PRIV_FROM_NUMBER_VALID,
09956
09957 .subaddress.str = AST_REDIRECTING_PRIV_FROM_SUBADDRESS,
09958 .subaddress.type = AST_REDIRECTING_PRIV_FROM_SUBADDRESS_TYPE,
09959 .subaddress.odd_even_indicator = AST_REDIRECTING_PRIV_FROM_SUBADDRESS_ODD_EVEN,
09960 .subaddress.valid = AST_REDIRECTING_PRIV_FROM_SUBADDRESS_VALID,
09961
09962 .tag = AST_REDIRECTING_PRIV_FROM_TAG,
09963 .combined_presentation = 0,
09964 };
09965 static const struct ast_party_id_ies priv_to_ies = {
09966 .name.str = AST_REDIRECTING_PRIV_TO_NAME,
09967 .name.char_set = AST_REDIRECTING_PRIV_TO_NAME_CHAR_SET,
09968 .name.presentation = AST_REDIRECTING_PRIV_TO_NAME_PRESENTATION,
09969 .name.valid = AST_REDIRECTING_PRIV_TO_NAME_VALID,
09970
09971 .number.str = AST_REDIRECTING_PRIV_TO_NUMBER,
09972 .number.plan = AST_REDIRECTING_PRIV_TO_NUMBER_PLAN,
09973 .number.presentation = AST_REDIRECTING_PRIV_TO_NUMBER_PRESENTATION,
09974 .number.valid = AST_REDIRECTING_PRIV_TO_NUMBER_VALID,
09975
09976 .subaddress.str = AST_REDIRECTING_PRIV_TO_SUBADDRESS,
09977 .subaddress.type = AST_REDIRECTING_PRIV_TO_SUBADDRESS_TYPE,
09978 .subaddress.odd_even_indicator = AST_REDIRECTING_PRIV_TO_SUBADDRESS_ODD_EVEN,
09979 .subaddress.valid = AST_REDIRECTING_PRIV_TO_SUBADDRESS_VALID,
09980
09981 .tag = AST_REDIRECTING_PRIV_TO_TAG,
09982 .combined_presentation = 0,
09983 };
09984
09985
09986 if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
09987 ast_log(LOG_WARNING, "No space left for redirecting frame version\n");
09988 return -1;
09989 }
09990 data[pos++] = AST_REDIRECTING_VERSION;
09991 data[pos++] = 1;
09992 data[pos++] = 2;
09993
09994 res = party_id_build_data(data + pos, datalen - pos, &redirecting->orig,
09995 "redirecting-orig", &orig_ies, update ? &update->orig : NULL);
09996 if (res < 0) {
09997 return -1;
09998 }
09999 pos += res;
10000
10001 res = party_id_build_data(data + pos, datalen - pos, &redirecting->from,
10002 "redirecting-from", &from_ies, update ? &update->from : NULL);
10003 if (res < 0) {
10004 return -1;
10005 }
10006 pos += res;
10007
10008 res = party_id_build_data(data + pos, datalen - pos, &redirecting->to,
10009 "redirecting-to", &to_ies, update ? &update->to : NULL);
10010 if (res < 0) {
10011 return -1;
10012 }
10013 pos += res;
10014
10015 res = party_id_build_data(data + pos, datalen - pos, &redirecting->priv_orig,
10016 "redirecting-priv-orig", &priv_orig_ies, update ? &update->priv_orig : NULL);
10017 if (res < 0) {
10018 return -1;
10019 }
10020 pos += res;
10021
10022 res = party_id_build_data(data + pos, datalen - pos, &redirecting->priv_from,
10023 "redirecting-priv-from", &priv_from_ies, update ? &update->priv_from : NULL);
10024 if (res < 0) {
10025 return -1;
10026 }
10027 pos += res;
10028
10029 res = party_id_build_data(data + pos, datalen - pos, &redirecting->priv_to,
10030 "redirecting-priv-to", &priv_to_ies, update ? &update->priv_to : NULL);
10031 if (res < 0) {
10032 return -1;
10033 }
10034 pos += res;
10035
10036
10037 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
10038 ast_log(LOG_WARNING, "No space left for redirecting reason\n");
10039 return -1;
10040 }
10041 data[pos++] = AST_REDIRECTING_REASON;
10042 data[pos++] = sizeof(value);
10043 value = htonl(redirecting->reason);
10044 memcpy(data + pos, &value, sizeof(value));
10045 pos += sizeof(value);
10046
10047
10048 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
10049 ast_log(LOG_WARNING, "No space left for redirecting original reason\n");
10050 return -1;
10051 }
10052 data[pos++] = AST_REDIRECTING_ORIG_REASON;
10053 data[pos++] = sizeof(value);
10054 value = htonl(redirecting->orig_reason);
10055 memcpy(data + pos, &value, sizeof(value));
10056 pos += sizeof(value);
10057
10058
10059 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
10060 ast_log(LOG_WARNING, "No space left for redirecting count\n");
10061 return -1;
10062 }
10063 data[pos++] = AST_REDIRECTING_COUNT;
10064 data[pos++] = sizeof(value);
10065 value = htonl(redirecting->count);
10066 memcpy(data + pos, &value, sizeof(value));
10067 pos += sizeof(value);
10068
10069 return pos;
10070 }
10071
10072 int ast_redirecting_parse_data(const unsigned char *data, size_t datalen, struct ast_party_redirecting *redirecting)
10073 {
10074 size_t pos;
10075 unsigned char ie_len;
10076 unsigned char ie_id;
10077 int32_t value;
10078 int frame_version = 1;
10079 int from_combined_presentation = 0;
10080 int got_from_combined_presentation = 0;
10081 int to_combined_presentation = 0;
10082 int got_to_combined_presentation = 0;
10083
10084 for (pos = 0; pos < datalen; pos += ie_len) {
10085 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) {
10086 ast_log(LOG_WARNING, "Invalid redirecting update\n");
10087 return -1;
10088 }
10089 ie_id = data[pos++];
10090 ie_len = data[pos++];
10091 if (datalen < pos + ie_len) {
10092 ast_log(LOG_WARNING, "Invalid redirecting update\n");
10093 return -1;
10094 }
10095
10096 switch (ie_id) {
10097
10098 case AST_REDIRECTING_VERSION:
10099 if (ie_len != 1) {
10100 ast_log(LOG_WARNING, "Invalid redirecting frame version (%u)\n",
10101 (unsigned) ie_len);
10102 break;
10103 }
10104 frame_version = data[pos];
10105 break;
10106
10107 case AST_REDIRECTING_ORIG_NAME:
10108 ast_free(redirecting->orig.name.str);
10109 redirecting->orig.name.str = ast_malloc(ie_len + 1);
10110 if (redirecting->orig.name.str) {
10111 memcpy(redirecting->orig.name.str, data + pos, ie_len);
10112 redirecting->orig.name.str[ie_len] = 0;
10113 }
10114 break;
10115 case AST_REDIRECTING_ORIG_NAME_CHAR_SET:
10116 if (ie_len != 1) {
10117 ast_log(LOG_WARNING, "Invalid redirecting-orig name char set (%u)\n",
10118 (unsigned) ie_len);
10119 break;
10120 }
10121 redirecting->orig.name.char_set = data[pos];
10122 break;
10123 case AST_REDIRECTING_ORIG_NAME_PRESENTATION:
10124 if (ie_len != 1) {
10125 ast_log(LOG_WARNING, "Invalid redirecting-orig name presentation (%u)\n",
10126 (unsigned) ie_len);
10127 break;
10128 }
10129 redirecting->orig.name.presentation = data[pos];
10130 break;
10131 case AST_REDIRECTING_ORIG_NAME_VALID:
10132 if (ie_len != 1) {
10133 ast_log(LOG_WARNING, "Invalid redirecting-orig name valid (%u)\n",
10134 (unsigned) ie_len);
10135 break;
10136 }
10137 redirecting->orig.name.valid = data[pos];
10138 break;
10139
10140 case AST_REDIRECTING_ORIG_NUMBER:
10141 ast_free(redirecting->orig.number.str);
10142 redirecting->orig.number.str = ast_malloc(ie_len + 1);
10143 if (redirecting->orig.number.str) {
10144 memcpy(redirecting->orig.number.str, data + pos, ie_len);
10145 redirecting->orig.number.str[ie_len] = 0;
10146 }
10147 break;
10148 case AST_REDIRECTING_ORIG_NUMBER_PLAN:
10149 if (ie_len != 1) {
10150 ast_log(LOG_WARNING, "Invalid redirecting-orig numbering plan (%u)\n",
10151 (unsigned) ie_len);
10152 break;
10153 }
10154 redirecting->orig.number.plan = data[pos];
10155 break;
10156 case AST_REDIRECTING_ORIG_NUMBER_PRESENTATION:
10157 if (ie_len != 1) {
10158 ast_log(LOG_WARNING, "Invalid redirecting-orig number presentation (%u)\n",
10159 (unsigned) ie_len);
10160 break;
10161 }
10162 redirecting->orig.number.presentation = data[pos];
10163 break;
10164 case AST_REDIRECTING_ORIG_NUMBER_VALID:
10165 if (ie_len != 1) {
10166 ast_log(LOG_WARNING, "Invalid redirecting-orig number valid (%u)\n",
10167 (unsigned) ie_len);
10168 break;
10169 }
10170 redirecting->orig.number.valid = data[pos];
10171 break;
10172
10173 case AST_REDIRECTING_ORIG_SUBADDRESS:
10174 ast_free(redirecting->orig.subaddress.str);
10175 redirecting->orig.subaddress.str = ast_malloc(ie_len + 1);
10176 if (redirecting->orig.subaddress.str) {
10177 memcpy(redirecting->orig.subaddress.str, data + pos, ie_len);
10178 redirecting->orig.subaddress.str[ie_len] = 0;
10179 }
10180 break;
10181 case AST_REDIRECTING_ORIG_SUBADDRESS_TYPE:
10182 if (ie_len != 1) {
10183 ast_log(LOG_WARNING, "Invalid redirecting-orig type of subaddress (%u)\n",
10184 (unsigned) ie_len);
10185 break;
10186 }
10187 redirecting->orig.subaddress.type = data[pos];
10188 break;
10189 case AST_REDIRECTING_ORIG_SUBADDRESS_ODD_EVEN:
10190 if (ie_len != 1) {
10191 ast_log(LOG_WARNING,
10192 "Invalid redirecting-orig subaddress odd-even indicator (%u)\n",
10193 (unsigned) ie_len);
10194 break;
10195 }
10196 redirecting->orig.subaddress.odd_even_indicator = data[pos];
10197 break;
10198 case AST_REDIRECTING_ORIG_SUBADDRESS_VALID:
10199 if (ie_len != 1) {
10200 ast_log(LOG_WARNING, "Invalid redirecting-orig subaddress valid (%u)\n",
10201 (unsigned) ie_len);
10202 break;
10203 }
10204 redirecting->orig.subaddress.valid = data[pos];
10205 break;
10206
10207 case AST_REDIRECTING_ORIG_TAG:
10208 ast_free(redirecting->orig.tag);
10209 redirecting->orig.tag = ast_malloc(ie_len + 1);
10210 if (redirecting->orig.tag) {
10211 memcpy(redirecting->orig.tag, data + pos, ie_len);
10212 redirecting->orig.tag[ie_len] = 0;
10213 }
10214 break;
10215
10216 case AST_REDIRECTING_FROM_NAME:
10217 ast_free(redirecting->from.name.str);
10218 redirecting->from.name.str = ast_malloc(ie_len + 1);
10219 if (redirecting->from.name.str) {
10220 memcpy(redirecting->from.name.str, data + pos, ie_len);
10221 redirecting->from.name.str[ie_len] = 0;
10222 }
10223 break;
10224 case AST_REDIRECTING_FROM_NAME_CHAR_SET:
10225 if (ie_len != 1) {
10226 ast_log(LOG_WARNING, "Invalid redirecting-from name char set (%u)\n",
10227 (unsigned) ie_len);
10228 break;
10229 }
10230 redirecting->from.name.char_set = data[pos];
10231 break;
10232 case AST_REDIRECTING_FROM_NAME_PRESENTATION:
10233 if (ie_len != 1) {
10234 ast_log(LOG_WARNING, "Invalid redirecting-from name presentation (%u)\n",
10235 (unsigned) ie_len);
10236 break;
10237 }
10238 redirecting->from.name.presentation = data[pos];
10239 break;
10240 case AST_REDIRECTING_FROM_NAME_VALID:
10241 if (ie_len != 1) {
10242 ast_log(LOG_WARNING, "Invalid redirecting-from name valid (%u)\n",
10243 (unsigned) ie_len);
10244 break;
10245 }
10246 redirecting->from.name.valid = data[pos];
10247 break;
10248
10249 case AST_REDIRECTING_FROM_NUMBER:
10250 ast_free(redirecting->from.number.str);
10251 redirecting->from.number.str = ast_malloc(ie_len + 1);
10252 if (redirecting->from.number.str) {
10253 memcpy(redirecting->from.number.str, data + pos, ie_len);
10254 redirecting->from.number.str[ie_len] = 0;
10255 }
10256 break;
10257 case AST_REDIRECTING_FROM_NUMBER_PLAN:
10258 if (ie_len != 1) {
10259 ast_log(LOG_WARNING, "Invalid redirecting-from numbering plan (%u)\n",
10260 (unsigned) ie_len);
10261 break;
10262 }
10263 redirecting->from.number.plan = data[pos];
10264 break;
10265 case AST_REDIRECTING_FROM_NUMBER_PRESENTATION:
10266 if (ie_len != 1) {
10267 ast_log(LOG_WARNING, "Invalid redirecting-from number presentation (%u)\n",
10268 (unsigned) ie_len);
10269 break;
10270 }
10271 redirecting->from.number.presentation = data[pos];
10272 break;
10273 case AST_REDIRECTING_FROM_NUMBER_VALID:
10274 if (ie_len != 1) {
10275 ast_log(LOG_WARNING, "Invalid redirecting-from number valid (%u)\n",
10276 (unsigned) ie_len);
10277 break;
10278 }
10279 redirecting->from.number.valid = data[pos];
10280 break;
10281
10282 case AST_REDIRECTING_FROM_ID_PRESENTATION:
10283 if (ie_len != 1) {
10284 ast_log(LOG_WARNING, "Invalid redirecting-from combined presentation (%u)\n",
10285 (unsigned) ie_len);
10286 break;
10287 }
10288 from_combined_presentation = data[pos];
10289 got_from_combined_presentation = 1;
10290 break;
10291
10292 case AST_REDIRECTING_FROM_SUBADDRESS:
10293 ast_free(redirecting->from.subaddress.str);
10294 redirecting->from.subaddress.str = ast_malloc(ie_len + 1);
10295 if (redirecting->from.subaddress.str) {
10296 memcpy(redirecting->from.subaddress.str, data + pos, ie_len);
10297 redirecting->from.subaddress.str[ie_len] = 0;
10298 }
10299 break;
10300 case AST_REDIRECTING_FROM_SUBADDRESS_TYPE:
10301 if (ie_len != 1) {
10302 ast_log(LOG_WARNING, "Invalid redirecting-from type of subaddress (%u)\n",
10303 (unsigned) ie_len);
10304 break;
10305 }
10306 redirecting->from.subaddress.type = data[pos];
10307 break;
10308 case AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN:
10309 if (ie_len != 1) {
10310 ast_log(LOG_WARNING,
10311 "Invalid redirecting-from subaddress odd-even indicator (%u)\n",
10312 (unsigned) ie_len);
10313 break;
10314 }
10315 redirecting->from.subaddress.odd_even_indicator = data[pos];
10316 break;
10317 case AST_REDIRECTING_FROM_SUBADDRESS_VALID:
10318 if (ie_len != 1) {
10319 ast_log(LOG_WARNING, "Invalid redirecting-from subaddress valid (%u)\n",
10320 (unsigned) ie_len);
10321 break;
10322 }
10323 redirecting->from.subaddress.valid = data[pos];
10324 break;
10325
10326 case AST_REDIRECTING_FROM_TAG:
10327 ast_free(redirecting->from.tag);
10328 redirecting->from.tag = ast_malloc(ie_len + 1);
10329 if (redirecting->from.tag) {
10330 memcpy(redirecting->from.tag, data + pos, ie_len);
10331 redirecting->from.tag[ie_len] = 0;
10332 }
10333 break;
10334
10335 case AST_REDIRECTING_TO_NAME:
10336 ast_free(redirecting->to.name.str);
10337 redirecting->to.name.str = ast_malloc(ie_len + 1);
10338 if (redirecting->to.name.str) {
10339 memcpy(redirecting->to.name.str, data + pos, ie_len);
10340 redirecting->to.name.str[ie_len] = 0;
10341 }
10342 break;
10343 case AST_REDIRECTING_TO_NAME_CHAR_SET:
10344 if (ie_len != 1) {
10345 ast_log(LOG_WARNING, "Invalid redirecting-to name char set (%u)\n",
10346 (unsigned) ie_len);
10347 break;
10348 }
10349 redirecting->to.name.char_set = data[pos];
10350 break;
10351 case AST_REDIRECTING_TO_NAME_PRESENTATION:
10352 if (ie_len != 1) {
10353 ast_log(LOG_WARNING, "Invalid redirecting-to name presentation (%u)\n",
10354 (unsigned) ie_len);
10355 break;
10356 }
10357 redirecting->to.name.presentation = data[pos];
10358 break;
10359 case AST_REDIRECTING_TO_NAME_VALID:
10360 if (ie_len != 1) {
10361 ast_log(LOG_WARNING, "Invalid redirecting-to name valid (%u)\n",
10362 (unsigned) ie_len);
10363 break;
10364 }
10365 redirecting->to.name.valid = data[pos];
10366 break;
10367
10368 case AST_REDIRECTING_TO_NUMBER:
10369 ast_free(redirecting->to.number.str);
10370 redirecting->to.number.str = ast_malloc(ie_len + 1);
10371 if (redirecting->to.number.str) {
10372 memcpy(redirecting->to.number.str, data + pos, ie_len);
10373 redirecting->to.number.str[ie_len] = 0;
10374 }
10375 break;
10376 case AST_REDIRECTING_TO_NUMBER_PLAN:
10377 if (ie_len != 1) {
10378 ast_log(LOG_WARNING, "Invalid redirecting-to numbering plan (%u)\n",
10379 (unsigned) ie_len);
10380 break;
10381 }
10382 redirecting->to.number.plan = data[pos];
10383 break;
10384 case AST_REDIRECTING_TO_NUMBER_PRESENTATION:
10385 if (ie_len != 1) {
10386 ast_log(LOG_WARNING, "Invalid redirecting-to number presentation (%u)\n",
10387 (unsigned) ie_len);
10388 break;
10389 }
10390 redirecting->to.number.presentation = data[pos];
10391 break;
10392 case AST_REDIRECTING_TO_NUMBER_VALID:
10393 if (ie_len != 1) {
10394 ast_log(LOG_WARNING, "Invalid redirecting-to number valid (%u)\n",
10395 (unsigned) ie_len);
10396 break;
10397 }
10398 redirecting->to.number.valid = data[pos];
10399 break;
10400
10401 case AST_REDIRECTING_TO_ID_PRESENTATION:
10402 if (ie_len != 1) {
10403 ast_log(LOG_WARNING, "Invalid redirecting-to combined presentation (%u)\n",
10404 (unsigned) ie_len);
10405 break;
10406 }
10407 to_combined_presentation = data[pos];
10408 got_to_combined_presentation = 1;
10409 break;
10410
10411 case AST_REDIRECTING_TO_SUBADDRESS:
10412 ast_free(redirecting->to.subaddress.str);
10413 redirecting->to.subaddress.str = ast_malloc(ie_len + 1);
10414 if (redirecting->to.subaddress.str) {
10415 memcpy(redirecting->to.subaddress.str, data + pos, ie_len);
10416 redirecting->to.subaddress.str[ie_len] = 0;
10417 }
10418 break;
10419 case AST_REDIRECTING_TO_SUBADDRESS_TYPE:
10420 if (ie_len != 1) {
10421 ast_log(LOG_WARNING, "Invalid redirecting-to type of subaddress (%u)\n",
10422 (unsigned) ie_len);
10423 break;
10424 }
10425 redirecting->to.subaddress.type = data[pos];
10426 break;
10427 case AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN:
10428 if (ie_len != 1) {
10429 ast_log(LOG_WARNING,
10430 "Invalid redirecting-to subaddress odd-even indicator (%u)\n",
10431 (unsigned) ie_len);
10432 break;
10433 }
10434 redirecting->to.subaddress.odd_even_indicator = data[pos];
10435 break;
10436 case AST_REDIRECTING_TO_SUBADDRESS_VALID:
10437 if (ie_len != 1) {
10438 ast_log(LOG_WARNING, "Invalid redirecting-to subaddress valid (%u)\n",
10439 (unsigned) ie_len);
10440 break;
10441 }
10442 redirecting->to.subaddress.valid = data[pos];
10443 break;
10444
10445 case AST_REDIRECTING_TO_TAG:
10446 ast_free(redirecting->to.tag);
10447 redirecting->to.tag = ast_malloc(ie_len + 1);
10448 if (redirecting->to.tag) {
10449 memcpy(redirecting->to.tag, data + pos, ie_len);
10450 redirecting->to.tag[ie_len] = 0;
10451 }
10452 break;
10453
10454 case AST_REDIRECTING_PRIV_ORIG_NAME:
10455 ast_free(redirecting->priv_orig.name.str);
10456 redirecting->priv_orig.name.str = ast_malloc(ie_len + 1);
10457 if (redirecting->priv_orig.name.str) {
10458 memcpy(redirecting->priv_orig.name.str, data + pos, ie_len);
10459 redirecting->priv_orig.name.str[ie_len] = 0;
10460 }
10461 break;
10462 case AST_REDIRECTING_PRIV_ORIG_NAME_CHAR_SET:
10463 if (ie_len != 1) {
10464 ast_log(LOG_WARNING, "Invalid private redirecting-orig name char set (%u)\n",
10465 (unsigned) ie_len);
10466 break;
10467 }
10468 redirecting->priv_orig.name.char_set = data[pos];
10469 break;
10470 case AST_REDIRECTING_PRIV_ORIG_NAME_PRESENTATION:
10471 if (ie_len != 1) {
10472 ast_log(LOG_WARNING, "Invalid private redirecting-orig name presentation (%u)\n",
10473 (unsigned) ie_len);
10474 break;
10475 }
10476 redirecting->priv_orig.name.presentation = data[pos];
10477 break;
10478 case AST_REDIRECTING_PRIV_ORIG_NAME_VALID:
10479 if (ie_len != 1) {
10480 ast_log(LOG_WARNING, "Invalid private redirecting-orig name valid (%u)\n",
10481 (unsigned) ie_len);
10482 break;
10483 }
10484 redirecting->priv_orig.name.valid = data[pos];
10485 break;
10486
10487 case AST_REDIRECTING_PRIV_ORIG_NUMBER:
10488 ast_free(redirecting->priv_orig.number.str);
10489 redirecting->priv_orig.number.str = ast_malloc(ie_len + 1);
10490 if (redirecting->priv_orig.number.str) {
10491 memcpy(redirecting->priv_orig.number.str, data + pos, ie_len);
10492 redirecting->priv_orig.number.str[ie_len] = 0;
10493 }
10494 break;
10495 case AST_REDIRECTING_PRIV_ORIG_NUMBER_PLAN:
10496 if (ie_len != 1) {
10497 ast_log(LOG_WARNING, "Invalid private redirecting-orig numbering plan (%u)\n",
10498 (unsigned) ie_len);
10499 break;
10500 }
10501 redirecting->priv_orig.number.plan = data[pos];
10502 break;
10503 case AST_REDIRECTING_PRIV_ORIG_NUMBER_PRESENTATION:
10504 if (ie_len != 1) {
10505 ast_log(LOG_WARNING, "Invalid private redirecting-orig number presentation (%u)\n",
10506 (unsigned) ie_len);
10507 break;
10508 }
10509 redirecting->priv_orig.number.presentation = data[pos];
10510 break;
10511 case AST_REDIRECTING_PRIV_ORIG_NUMBER_VALID:
10512 if (ie_len != 1) {
10513 ast_log(LOG_WARNING, "Invalid private redirecting-orig number valid (%u)\n",
10514 (unsigned) ie_len);
10515 break;
10516 }
10517 redirecting->priv_orig.number.valid = data[pos];
10518 break;
10519
10520 case AST_REDIRECTING_PRIV_ORIG_SUBADDRESS:
10521 ast_free(redirecting->priv_orig.subaddress.str);
10522 redirecting->priv_orig.subaddress.str = ast_malloc(ie_len + 1);
10523 if (redirecting->priv_orig.subaddress.str) {
10524 memcpy(redirecting->priv_orig.subaddress.str, data + pos, ie_len);
10525 redirecting->priv_orig.subaddress.str[ie_len] = 0;
10526 }
10527 break;
10528 case AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_TYPE:
10529 if (ie_len != 1) {
10530 ast_log(LOG_WARNING, "Invalid private redirecting-orig type of subaddress (%u)\n",
10531 (unsigned) ie_len);
10532 break;
10533 }
10534 redirecting->priv_orig.subaddress.type = data[pos];
10535 break;
10536 case AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_ODD_EVEN:
10537 if (ie_len != 1) {
10538 ast_log(LOG_WARNING,
10539 "Invalid private redirecting-orig subaddress odd-even indicator (%u)\n",
10540 (unsigned) ie_len);
10541 break;
10542 }
10543 redirecting->priv_orig.subaddress.odd_even_indicator = data[pos];
10544 break;
10545 case AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_VALID:
10546 if (ie_len != 1) {
10547 ast_log(LOG_WARNING, "Invalid private redirecting-orig subaddress valid (%u)\n",
10548 (unsigned) ie_len);
10549 break;
10550 }
10551 redirecting->priv_orig.subaddress.valid = data[pos];
10552 break;
10553
10554 case AST_REDIRECTING_PRIV_ORIG_TAG:
10555 ast_free(redirecting->priv_orig.tag);
10556 redirecting->priv_orig.tag = ast_malloc(ie_len + 1);
10557 if (redirecting->priv_orig.tag) {
10558 memcpy(redirecting->priv_orig.tag, data + pos, ie_len);
10559 redirecting->priv_orig.tag[ie_len] = 0;
10560 }
10561 break;
10562
10563 case AST_REDIRECTING_PRIV_FROM_NAME:
10564 ast_free(redirecting->priv_from.name.str);
10565 redirecting->priv_from.name.str = ast_malloc(ie_len + 1);
10566 if (redirecting->priv_from.name.str) {
10567 memcpy(redirecting->priv_from.name.str, data + pos, ie_len);
10568 redirecting->priv_from.name.str[ie_len] = 0;
10569 }
10570 break;
10571 case AST_REDIRECTING_PRIV_FROM_NAME_CHAR_SET:
10572 if (ie_len != 1) {
10573 ast_log(LOG_WARNING, "Invalid private redirecting-from name char set (%u)\n",
10574 (unsigned) ie_len);
10575 break;
10576 }
10577 redirecting->priv_from.name.char_set = data[pos];
10578 break;
10579 case AST_REDIRECTING_PRIV_FROM_NAME_PRESENTATION:
10580 if (ie_len != 1) {
10581 ast_log(LOG_WARNING, "Invalid private redirecting-from name presentation (%u)\n",
10582 (unsigned) ie_len);
10583 break;
10584 }
10585 redirecting->priv_from.name.presentation = data[pos];
10586 break;
10587 case AST_REDIRECTING_PRIV_FROM_NAME_VALID:
10588 if (ie_len != 1) {
10589 ast_log(LOG_WARNING, "Invalid private redirecting-from name valid (%u)\n",
10590 (unsigned) ie_len);
10591 break;
10592 }
10593 redirecting->priv_from.name.valid = data[pos];
10594 break;
10595
10596 case AST_REDIRECTING_PRIV_FROM_NUMBER:
10597 ast_free(redirecting->priv_from.number.str);
10598 redirecting->priv_from.number.str = ast_malloc(ie_len + 1);
10599 if (redirecting->priv_from.number.str) {
10600 memcpy(redirecting->priv_from.number.str, data + pos, ie_len);
10601 redirecting->priv_from.number.str[ie_len] = 0;
10602 }
10603 break;
10604 case AST_REDIRECTING_PRIV_FROM_NUMBER_PLAN:
10605 if (ie_len != 1) {
10606 ast_log(LOG_WARNING, "Invalid private redirecting-from numbering plan (%u)\n",
10607 (unsigned) ie_len);
10608 break;
10609 }
10610 redirecting->priv_from.number.plan = data[pos];
10611 break;
10612 case AST_REDIRECTING_PRIV_FROM_NUMBER_PRESENTATION:
10613 if (ie_len != 1) {
10614 ast_log(LOG_WARNING, "Invalid private redirecting-from number presentation (%u)\n",
10615 (unsigned) ie_len);
10616 break;
10617 }
10618 redirecting->priv_from.number.presentation = data[pos];
10619 break;
10620 case AST_REDIRECTING_PRIV_FROM_NUMBER_VALID:
10621 if (ie_len != 1) {
10622 ast_log(LOG_WARNING, "Invalid private redirecting-from number valid (%u)\n",
10623 (unsigned) ie_len);
10624 break;
10625 }
10626 redirecting->priv_from.number.valid = data[pos];
10627 break;
10628
10629 case AST_REDIRECTING_PRIV_FROM_SUBADDRESS:
10630 ast_free(redirecting->priv_from.subaddress.str);
10631 redirecting->priv_from.subaddress.str = ast_malloc(ie_len + 1);
10632 if (redirecting->priv_from.subaddress.str) {
10633 memcpy(redirecting->priv_from.subaddress.str, data + pos, ie_len);
10634 redirecting->priv_from.subaddress.str[ie_len] = 0;
10635 }
10636 break;
10637 case AST_REDIRECTING_PRIV_FROM_SUBADDRESS_TYPE:
10638 if (ie_len != 1) {
10639 ast_log(LOG_WARNING, "Invalid private redirecting-from type of subaddress (%u)\n",
10640 (unsigned) ie_len);
10641 break;
10642 }
10643 redirecting->priv_from.subaddress.type = data[pos];
10644 break;
10645 case AST_REDIRECTING_PRIV_FROM_SUBADDRESS_ODD_EVEN:
10646 if (ie_len != 1) {
10647 ast_log(LOG_WARNING,
10648 "Invalid private redirecting-from subaddress odd-even indicator (%u)\n",
10649 (unsigned) ie_len);
10650 break;
10651 }
10652 redirecting->priv_from.subaddress.odd_even_indicator = data[pos];
10653 break;
10654 case AST_REDIRECTING_PRIV_FROM_SUBADDRESS_VALID:
10655 if (ie_len != 1) {
10656 ast_log(LOG_WARNING, "Invalid private redirecting-from subaddress valid (%u)\n",
10657 (unsigned) ie_len);
10658 break;
10659 }
10660 redirecting->priv_from.subaddress.valid = data[pos];
10661 break;
10662
10663 case AST_REDIRECTING_PRIV_FROM_TAG:
10664 ast_free(redirecting->priv_from.tag);
10665 redirecting->priv_from.tag = ast_malloc(ie_len + 1);
10666 if (redirecting->priv_from.tag) {
10667 memcpy(redirecting->priv_from.tag, data + pos, ie_len);
10668 redirecting->priv_from.tag[ie_len] = 0;
10669 }
10670 break;
10671
10672 case AST_REDIRECTING_PRIV_TO_NAME:
10673 ast_free(redirecting->priv_to.name.str);
10674 redirecting->priv_to.name.str = ast_malloc(ie_len + 1);
10675 if (redirecting->priv_to.name.str) {
10676 memcpy(redirecting->priv_to.name.str, data + pos, ie_len);
10677 redirecting->priv_to.name.str[ie_len] = 0;
10678 }
10679 break;
10680 case AST_REDIRECTING_PRIV_TO_NAME_CHAR_SET:
10681 if (ie_len != 1) {
10682 ast_log(LOG_WARNING, "Invalid private redirecting-to name char set (%u)\n",
10683 (unsigned) ie_len);
10684 break;
10685 }
10686 redirecting->priv_to.name.char_set = data[pos];
10687 break;
10688 case AST_REDIRECTING_PRIV_TO_NAME_PRESENTATION:
10689 if (ie_len != 1) {
10690 ast_log(LOG_WARNING, "Invalid private redirecting-to name presentation (%u)\n",
10691 (unsigned) ie_len);
10692 break;
10693 }
10694 redirecting->priv_to.name.presentation = data[pos];
10695 break;
10696 case AST_REDIRECTING_PRIV_TO_NAME_VALID:
10697 if (ie_len != 1) {
10698 ast_log(LOG_WARNING, "Invalid private redirecting-to name valid (%u)\n",
10699 (unsigned) ie_len);
10700 break;
10701 }
10702 redirecting->priv_to.name.valid = data[pos];
10703 break;
10704
10705 case AST_REDIRECTING_PRIV_TO_NUMBER:
10706 ast_free(redirecting->priv_to.number.str);
10707 redirecting->priv_to.number.str = ast_malloc(ie_len + 1);
10708 if (redirecting->priv_to.number.str) {
10709 memcpy(redirecting->priv_to.number.str, data + pos, ie_len);
10710 redirecting->priv_to.number.str[ie_len] = 0;
10711 }
10712 break;
10713 case AST_REDIRECTING_PRIV_TO_NUMBER_PLAN:
10714 if (ie_len != 1) {
10715 ast_log(LOG_WARNING, "Invalid private redirecting-to numbering plan (%u)\n",
10716 (unsigned) ie_len);
10717 break;
10718 }
10719 redirecting->priv_to.number.plan = data[pos];
10720 break;
10721 case AST_REDIRECTING_PRIV_TO_NUMBER_PRESENTATION:
10722 if (ie_len != 1) {
10723 ast_log(LOG_WARNING, "Invalid private redirecting-to number presentation (%u)\n",
10724 (unsigned) ie_len);
10725 break;
10726 }
10727 redirecting->priv_to.number.presentation = data[pos];
10728 break;
10729 case AST_REDIRECTING_PRIV_TO_NUMBER_VALID:
10730 if (ie_len != 1) {
10731 ast_log(LOG_WARNING, "Invalid private redirecting-to number valid (%u)\n",
10732 (unsigned) ie_len);
10733 break;
10734 }
10735 redirecting->priv_to.number.valid = data[pos];
10736 break;
10737
10738 case AST_REDIRECTING_PRIV_TO_SUBADDRESS:
10739 ast_free(redirecting->priv_to.subaddress.str);
10740 redirecting->priv_to.subaddress.str = ast_malloc(ie_len + 1);
10741 if (redirecting->priv_to.subaddress.str) {
10742 memcpy(redirecting->priv_to.subaddress.str, data + pos, ie_len);
10743 redirecting->priv_to.subaddress.str[ie_len] = 0;
10744 }
10745 break;
10746 case AST_REDIRECTING_PRIV_TO_SUBADDRESS_TYPE:
10747 if (ie_len != 1) {
10748 ast_log(LOG_WARNING, "Invalid private redirecting-to type of subaddress (%u)\n",
10749 (unsigned) ie_len);
10750 break;
10751 }
10752 redirecting->priv_to.subaddress.type = data[pos];
10753 break;
10754 case AST_REDIRECTING_PRIV_TO_SUBADDRESS_ODD_EVEN:
10755 if (ie_len != 1) {
10756 ast_log(LOG_WARNING,
10757 "Invalid private redirecting-to subaddress odd-even indicator (%u)\n",
10758 (unsigned) ie_len);
10759 break;
10760 }
10761 redirecting->priv_to.subaddress.odd_even_indicator = data[pos];
10762 break;
10763 case AST_REDIRECTING_PRIV_TO_SUBADDRESS_VALID:
10764 if (ie_len != 1) {
10765 ast_log(LOG_WARNING, "Invalid private redirecting-to subaddress valid (%u)\n",
10766 (unsigned) ie_len);
10767 break;
10768 }
10769 redirecting->priv_to.subaddress.valid = data[pos];
10770 break;
10771
10772 case AST_REDIRECTING_PRIV_TO_TAG:
10773 ast_free(redirecting->priv_to.tag);
10774 redirecting->priv_to.tag = ast_malloc(ie_len + 1);
10775 if (redirecting->priv_to.tag) {
10776 memcpy(redirecting->priv_to.tag, data + pos, ie_len);
10777 redirecting->priv_to.tag[ie_len] = 0;
10778 }
10779 break;
10780
10781 case AST_REDIRECTING_REASON:
10782 if (ie_len != sizeof(value)) {
10783 ast_log(LOG_WARNING, "Invalid redirecting reason (%u)\n",
10784 (unsigned) ie_len);
10785 break;
10786 }
10787 memcpy(&value, data + pos, sizeof(value));
10788 redirecting->reason = ntohl(value);
10789 break;
10790
10791 case AST_REDIRECTING_ORIG_REASON:
10792 if (ie_len != sizeof(value)) {
10793 ast_log(LOG_WARNING, "Invalid redirecting original reason (%u)\n",
10794 (unsigned) ie_len);
10795 break;
10796 }
10797 memcpy(&value, data + pos, sizeof(value));
10798 redirecting->orig_reason = ntohl(value);
10799 break;
10800
10801 case AST_REDIRECTING_COUNT:
10802 if (ie_len != sizeof(value)) {
10803 ast_log(LOG_WARNING, "Invalid redirecting count (%u)\n",
10804 (unsigned) ie_len);
10805 break;
10806 }
10807 memcpy(&value, data + pos, sizeof(value));
10808 redirecting->count = ntohl(value);
10809 break;
10810
10811 default:
10812 ast_debug(1, "Unknown redirecting element: %u (%u)\n",
10813 (unsigned) ie_id, (unsigned) ie_len);
10814 break;
10815 }
10816 }
10817
10818 switch (frame_version) {
10819 case 1:
10820
10821
10822
10823
10824
10825
10826
10827 redirecting->from.name.valid = 1;
10828 redirecting->from.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
10829 redirecting->from.number.valid = 1;
10830 if (got_from_combined_presentation) {
10831 redirecting->from.name.presentation = from_combined_presentation;
10832 redirecting->from.number.presentation = from_combined_presentation;
10833 }
10834
10835 redirecting->to.name.valid = 1;
10836 redirecting->to.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
10837 redirecting->to.number.valid = 1;
10838 if (got_to_combined_presentation) {
10839 redirecting->to.name.presentation = to_combined_presentation;
10840 redirecting->to.number.presentation = to_combined_presentation;
10841 }
10842 break;
10843 case 2:
10844
10845 break;
10846 default:
10847
10848
10849
10850
10851 ast_debug(1, "Redirecting frame has newer version: %u\n",
10852 (unsigned) frame_version);
10853 break;
10854 }
10855
10856 return 0;
10857 }
10858
10859 void ast_channel_update_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
10860 {
10861 unsigned char data[1024];
10862 size_t datalen;
10863
10864 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update);
10865 if (datalen == (size_t) -1) {
10866 return;
10867 }
10868
10869 ast_indicate_data(chan, AST_CONTROL_REDIRECTING, data, datalen);
10870 }
10871
10872 void ast_channel_queue_redirecting_update(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
10873 {
10874 unsigned char data[1024];
10875 size_t datalen;
10876
10877 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update);
10878 if (datalen == (size_t) -1) {
10879 return;
10880 }
10881
10882 ast_queue_control_data(chan, AST_CONTROL_REDIRECTING, data, datalen);
10883 }
10884
10885 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)
10886 {
10887 static int deprecation_warning = 0;
10888 const char *macro;
10889 const char *macro_args;
10890 int retval;
10891
10892 ast_channel_lock(macro_chan);
10893 macro = pbx_builtin_getvar_helper(macro_chan, is_caller
10894 ? "CONNECTED_LINE_CALLER_SEND_MACRO" : "CONNECTED_LINE_CALLEE_SEND_MACRO");
10895 macro = ast_strdupa(S_OR(macro, ""));
10896 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller
10897 ? "CONNECTED_LINE_CALLER_SEND_MACRO_ARGS" : "CONNECTED_LINE_CALLEE_SEND_MACRO_ARGS");
10898 macro_args = ast_strdupa(S_OR(macro_args, ""));
10899
10900 if (ast_strlen_zero(macro)) {
10901 ast_channel_unlock(macro_chan);
10902 return -1;
10903 }
10904
10905 if (!deprecation_warning) {
10906 deprecation_warning = 1;
10907 ast_log(LOG_WARNING, "Usage of CONNECTED_LINE_CALLE[ER]_SEND_MACRO is deprecated. Please use CONNECTED_LINE_SEND_SUB instead.\n");
10908 }
10909 if (is_frame) {
10910 const struct ast_frame *frame = connected_info;
10911
10912 ast_connected_line_parse_data(frame->data.ptr, frame->datalen, ast_channel_connected(macro_chan));
10913 } else {
10914 const struct ast_party_connected_line *connected = connected_info;
10915
10916 ast_party_connected_line_copy(ast_channel_connected(macro_chan), connected);
10917 }
10918 ast_channel_unlock(macro_chan);
10919
10920 retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args);
10921 if (!retval) {
10922 struct ast_party_connected_line saved_connected;
10923
10924 ast_party_connected_line_init(&saved_connected);
10925 ast_channel_lock(macro_chan);
10926 ast_party_connected_line_copy(&saved_connected, ast_channel_connected(macro_chan));
10927 ast_channel_unlock(macro_chan);
10928 ast_channel_update_connected_line(macro_chan, &saved_connected, NULL);
10929 ast_party_connected_line_free(&saved_connected);
10930 }
10931
10932 return retval;
10933 }
10934
10935 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)
10936 {
10937 static int deprecation_warning = 0;
10938 const char *macro;
10939 const char *macro_args;
10940 int retval;
10941
10942 ast_channel_lock(macro_chan);
10943 macro = pbx_builtin_getvar_helper(macro_chan, is_caller
10944 ? "REDIRECTING_CALLER_SEND_MACRO" : "REDIRECTING_CALLEE_SEND_MACRO");
10945 macro = ast_strdupa(S_OR(macro, ""));
10946 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller
10947 ? "REDIRECTING_CALLER_SEND_MACRO_ARGS" : "REDIRECTING_CALLEE_SEND_MACRO_ARGS");
10948 macro_args = ast_strdupa(S_OR(macro_args, ""));
10949
10950 if (ast_strlen_zero(macro)) {
10951 ast_channel_unlock(macro_chan);
10952 return -1;
10953 }
10954
10955 if (!deprecation_warning) {
10956 deprecation_warning = 1;
10957 ast_log(LOG_WARNING, "Usage of REDIRECTING_CALLE[ER]_SEND_MACRO is deprecated. Please use REDIRECTING_SEND_SUB instead.\n");
10958 }
10959 if (is_frame) {
10960 const struct ast_frame *frame = redirecting_info;
10961
10962 ast_redirecting_parse_data(frame->data.ptr, frame->datalen, ast_channel_redirecting(macro_chan));
10963 } else {
10964 const struct ast_party_redirecting *redirecting = redirecting_info;
10965
10966 ast_party_redirecting_copy(ast_channel_redirecting(macro_chan), redirecting);
10967 }
10968 ast_channel_unlock(macro_chan);
10969
10970 retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args);
10971 if (!retval) {
10972 struct ast_party_redirecting saved_redirecting;
10973
10974 ast_party_redirecting_init(&saved_redirecting);
10975 ast_channel_lock(macro_chan);
10976 ast_party_redirecting_copy(&saved_redirecting, ast_channel_redirecting(macro_chan));
10977 ast_channel_unlock(macro_chan);
10978 ast_channel_update_redirecting(macro_chan, &saved_redirecting, NULL);
10979 ast_party_redirecting_free(&saved_redirecting);
10980 }
10981
10982 return retval;
10983 }
10984
10985 int ast_channel_connected_line_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *connected_info, int is_frame)
10986 {
10987 const char *sub;
10988 const char *sub_args;
10989 int retval;
10990
10991 ast_channel_lock(sub_chan);
10992 sub = pbx_builtin_getvar_helper(sub_chan, "CONNECTED_LINE_SEND_SUB");
10993 sub = ast_strdupa(S_OR(sub, ""));
10994 sub_args = pbx_builtin_getvar_helper(sub_chan, "CONNECTED_LINE_SEND_SUB_ARGS");
10995 sub_args = ast_strdupa(S_OR(sub_args, ""));
10996
10997 if (ast_strlen_zero(sub)) {
10998 ast_channel_unlock(sub_chan);
10999 return -1;
11000 }
11001
11002 if (is_frame) {
11003 const struct ast_frame *frame = connected_info;
11004
11005 ast_connected_line_parse_data(frame->data.ptr, frame->datalen, ast_channel_connected(sub_chan));
11006 } else {
11007 const struct ast_party_connected_line *connected = connected_info;
11008
11009 ast_party_connected_line_copy(ast_channel_connected(sub_chan), connected);
11010 }
11011 ast_channel_unlock(sub_chan);
11012
11013 retval = ast_app_run_sub(autoservice_chan, sub_chan, sub, sub_args, 0);
11014 if (!retval) {
11015 struct ast_party_connected_line saved_connected;
11016
11017 ast_party_connected_line_init(&saved_connected);
11018 ast_channel_lock(sub_chan);
11019 ast_party_connected_line_copy(&saved_connected, ast_channel_connected(sub_chan));
11020 ast_channel_unlock(sub_chan);
11021 ast_channel_update_connected_line(sub_chan, &saved_connected, NULL);
11022 ast_party_connected_line_free(&saved_connected);
11023 }
11024
11025 return retval;
11026 }
11027
11028 int ast_channel_redirecting_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *redirecting_info, int is_frame)
11029 {
11030 const char *sub;
11031 const char *sub_args;
11032 int retval;
11033
11034 ast_channel_lock(sub_chan);
11035 sub = pbx_builtin_getvar_helper(sub_chan, "REDIRECTING_SEND_SUB");
11036 sub = ast_strdupa(S_OR(sub, ""));
11037 sub_args = pbx_builtin_getvar_helper(sub_chan, "REDIRECTING_SEND_SUB_ARGS");
11038 sub_args = ast_strdupa(S_OR(sub_args, ""));
11039
11040 if (ast_strlen_zero(sub)) {
11041 ast_channel_unlock(sub_chan);
11042 return -1;
11043 }
11044
11045 if (is_frame) {
11046 const struct ast_frame *frame = redirecting_info;
11047
11048 ast_redirecting_parse_data(frame->data.ptr, frame->datalen, ast_channel_redirecting(sub_chan));
11049 } else {
11050 const struct ast_party_redirecting *redirecting = redirecting_info;
11051
11052 ast_party_redirecting_copy(ast_channel_redirecting(sub_chan), redirecting);
11053 }
11054 ast_channel_unlock(sub_chan);
11055
11056 retval = ast_app_run_sub(autoservice_chan, sub_chan, sub, sub_args, 0);
11057 if (!retval) {
11058 struct ast_party_redirecting saved_redirecting;
11059
11060 ast_party_redirecting_init(&saved_redirecting);
11061 ast_channel_lock(sub_chan);
11062 ast_party_redirecting_copy(&saved_redirecting, ast_channel_redirecting(sub_chan));
11063 ast_channel_unlock(sub_chan);
11064 ast_channel_update_redirecting(sub_chan, &saved_redirecting, NULL);
11065 ast_party_redirecting_free(&saved_redirecting);
11066 }
11067
11068 return retval;
11069 }
11070
11071 static void *channel_cc_params_copy(void *data)
11072 {
11073 const struct ast_cc_config_params *src = data;
11074 struct ast_cc_config_params *dest = ast_cc_config_params_init();
11075 if (!dest) {
11076 return NULL;
11077 }
11078 ast_cc_copy_config_params(dest, src);
11079 return dest;
11080 }
11081
11082 static void channel_cc_params_destroy(void *data)
11083 {
11084 struct ast_cc_config_params *cc_params = data;
11085 ast_cc_config_params_destroy(cc_params);
11086 }
11087
11088 static const struct ast_datastore_info cc_channel_datastore_info = {
11089 .type = "Call Completion",
11090 .duplicate = channel_cc_params_copy,
11091 .destroy = channel_cc_params_destroy,
11092 };
11093
11094 int ast_channel_cc_params_init(struct ast_channel *chan,
11095 const struct ast_cc_config_params *base_params)
11096 {
11097 struct ast_cc_config_params *cc_params;
11098 struct ast_datastore *cc_datastore;
11099
11100 if (!(cc_params = ast_cc_config_params_init())) {
11101 return -1;
11102 }
11103
11104 if (!(cc_datastore = ast_datastore_alloc(&cc_channel_datastore_info, NULL))) {
11105 ast_cc_config_params_destroy(cc_params);
11106 return -1;
11107 }
11108
11109 if (base_params) {
11110 ast_cc_copy_config_params(cc_params, base_params);
11111 }
11112 cc_datastore->data = cc_params;
11113 ast_channel_datastore_add(chan, cc_datastore);
11114 return 0;
11115 }
11116
11117 struct ast_cc_config_params *ast_channel_get_cc_config_params(struct ast_channel *chan)
11118 {
11119 struct ast_datastore *cc_datastore;
11120
11121 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) {
11122
11123
11124
11125
11126 if (ast_channel_cc_params_init(chan, NULL)) {
11127 return NULL;
11128 }
11129 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) {
11130
11131 return NULL;
11132 }
11133 }
11134
11135 ast_assert(cc_datastore->data != NULL);
11136 return cc_datastore->data;
11137 }
11138
11139 int ast_channel_get_device_name(struct ast_channel *chan, char *device_name, size_t name_buffer_length)
11140 {
11141 int len = name_buffer_length;
11142 char *dash;
11143 if (!ast_channel_queryoption(chan, AST_OPTION_DEVICE_NAME, device_name, &len, 0)) {
11144 return 0;
11145 }
11146
11147
11148 ast_copy_string(device_name, ast_channel_name(chan), name_buffer_length);
11149 if ((dash = strrchr(device_name, '-'))) {
11150 *dash = '\0';
11151 }
11152
11153 return 0;
11154 }
11155
11156 int ast_channel_get_cc_agent_type(struct ast_channel *chan, char *agent_type, size_t size)
11157 {
11158 int len = size;
11159 char *slash;
11160
11161 if (!ast_channel_queryoption(chan, AST_OPTION_CC_AGENT_TYPE, agent_type, &len, 0)) {
11162 return 0;
11163 }
11164
11165 ast_copy_string(agent_type, ast_channel_name(chan), size);
11166 if ((slash = strchr(agent_type, '/'))) {
11167 *slash = '\0';
11168 }
11169 return 0;
11170 }
11171
11172
11173
11174
11175
11176
11177
11178
11179
11180
11181 #undef ast_channel_alloc
11182 struct ast_channel __attribute__((format(printf, 10, 11)))
11183 *ast_channel_alloc(int needqueue, int state, const char *cid_num,
11184 const char *cid_name, const char *acctcode,
11185 const char *exten, const char *context,
11186 const char *linkedid, const int amaflag,
11187 const char *name_fmt, ...);
11188 struct ast_channel *ast_channel_alloc(int needqueue, int state, const char *cid_num,
11189 const char *cid_name, const char *acctcode,
11190 const char *exten, const char *context,
11191 const char *linkedid, const int amaflag,
11192 const char *name_fmt, ...)
11193 {
11194 va_list ap;
11195 struct ast_channel *result;
11196
11197
11198 va_start(ap, name_fmt);
11199 result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context,
11200 linkedid, amaflag, __FILE__, __LINE__, __FUNCTION__, name_fmt, ap);
11201 va_end(ap);
11202
11203 return result;
11204 }
11205
11206 void ast_channel_unlink(struct ast_channel *chan)
11207 {
11208 ao2_unlink(channels, chan);
11209 }