]> git.ipfire.org Git - thirdparty/freeswitch.git/blame - src/switch_ivr_originate.c
Run dos2unix on mod_expr HTML files
[thirdparty/freeswitch.git] / src / switch_ivr_originate.c
CommitLineData
e6a60a20
AM
1/*
2 * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
6e7d5d08 3 * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
e6a60a20
AM
4 *
5 * Version: MPL 1.1
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18 *
19 * The Initial Developer of the Original Code is
ae220d33 20 * Anthony Minessale II <anthm@freeswitch.org>
e6a60a20
AM
21 * Portions created by the Initial Developer are Copyright (C)
22 * the Initial Developer. All Rights Reserved.
23 *
24 * Contributor(s):
25 *
ae220d33 26 * Anthony Minessale II <anthm@freeswitch.org>
e6a60a20 27 * Michael Jerris <mike@jerris.com>
65c91197 28 * Travis Cross <tc@traviscross.com>
e6a60a20
AM
29 *
30 * switch_ivr_originate.c -- IVR Library (originate)
31 *
32 */
c815c059 33
e6a60a20 34#include <switch.h>
bfe31288
AM
35#define QUOTED_ESC_COMMA 1
36#define UNQUOTED_ESC_COMMA 2
e6a60a20
AM
37
38static const switch_state_handler_table_t originate_state_handlers;
39
4b929592 40static switch_status_t originate_on_consume_media_transmit(switch_core_session_t *session)
a58173d2
AM
41{
42 switch_channel_t *channel = switch_core_session_get_channel(session);
3c349c27 43
4c20b020
AM
44 if (!switch_channel_test_flag(channel, CF_PROXY_MODE) && switch_channel_test_flag(channel, CF_CONSUME_ON_ORIGINATE)) {
45 while (switch_channel_test_flag(channel, CF_ORIGINATING) &&
46 switch_channel_get_state(channel) == CS_CONSUME_MEDIA && !switch_channel_test_flag(channel, CF_TAGGED)) {
abb2691b
AM
47 if (!switch_channel_media_ready(channel)) {
48 switch_yield(10000);
49 } else {
50 switch_ivr_sleep(session, 10, SWITCH_FALSE, NULL);
51 }
ae23edad 52 switch_ivr_parse_all_messages(session);
fda8c44e
BW
53 }
54 }
55
a58173d2
AM
56 switch_channel_clear_state_handler(channel, &originate_state_handlers);
57
58 return SWITCH_STATUS_FALSE;
59}
60
4b929592 61static switch_status_t originate_on_routing(switch_core_session_t *session)
e6a60a20 62{
482badff 63 switch_channel_t *channel = switch_core_session_get_channel(session);
e6a60a20 64
9bcc841b
AM
65 if (switch_channel_get_state(channel) == CS_ROUTING) {
66 /* put the channel in a passive state until it is answered */
67 switch_channel_set_state(channel, CS_CONSUME_MEDIA);
68 }
a58173d2 69
e6a60a20
AM
70 return SWITCH_STATUS_FALSE;
71}
72
73static const switch_state_handler_table_t originate_state_handlers = {
74 /*.on_init */ NULL,
4b929592 75 /*.on_routing */ originate_on_routing,
e6a60a20
AM
76 /*.on_execute */ NULL,
77 /*.on_hangup */ NULL,
4b929592
AM
78 /*.on_exchange_media */ NULL,
79 /*.on_soft_execute */ originate_on_consume_media_transmit,
80 /*.on_consume_media */ originate_on_consume_media_transmit
e6a60a20
AM
81};
82
1dcb3b67
AM
83
84typedef struct {
85 switch_core_session_t *peer_session;
86 switch_channel_t *peer_channel;
87 switch_caller_profile_t *caller_profile;
88 uint8_t ring_ready;
89 uint8_t early_media;
90 uint8_t answered;
daab35e3 91 uint8_t tagged;
29c616b9
AM
92 uint32_t per_channel_timelimit_sec;
93 uint32_t per_channel_progress_timelimit_sec;
d7a12df5 94 uint32_t per_channel_delay_start;
1dcb3b67
AM
95} originate_status_t;
96
97
98typedef struct {
99 switch_core_session_t *session;
100 int32_t idx;
101 uint32_t hups;
329033ee
AM
102 char *file;
103 char *error_file;
2d47baee 104 int confirm_timeout;
1dcb3b67
AM
105 char key[80];
106 uint8_t early_ok;
107 uint8_t ring_ready;
bcb20f7a 108 uint8_t instant_ringback;
1dcb3b67
AM
109 uint8_t sent_ring;
110 uint8_t progress;
111 uint8_t return_ring_ready;
697bb6ec
AM
112 uint8_t monitor_early_media_ring;
113 uint8_t monitor_early_media_fail;
effb166b
AM
114 uint8_t gen_ringback;
115 uint8_t ignore_early_media;
116 uint8_t ignore_ring_ready;
cf4b7672
AM
117 int monitor_early_media_ring_count;
118 int monitor_early_media_ring_total;
bdf8f594 119 int cancel_timeout;
5b6d1cd3 120 int continue_on_timeout;
757aa19e
AM
121 int ringback_ok;
122 int sending_ringback;
8e75f82e 123 int bridge_early_media;
5cc8aebc 124 switch_thread_t *ethread;
cca9c367 125 switch_caller_profile_t *caller_profile_override;
385a92ce 126 switch_bool_t check_vars;
cca9c367 127 switch_memory_pool_t *pool;
1dcb3b67
AM
128} originate_global_t;
129
130
131
e6a60a20 132typedef enum {
70accd9f 133 IDX_XFER = -5,
aaeb69d6 134 IDX_KEY_CANCEL = -4,
eaf6abfb 135 IDX_TIMEOUT = -3,
e6a60a20
AM
136 IDX_CANCEL = -2,
137 IDX_NADA = -1
138} abort_t;
139
140struct key_collect {
141 char *key;
142 char *file;
2d47baee
AM
143 char *error_file;
144 int confirm_timeout;
e6a60a20
AM
145 switch_core_session_t *session;
146};
147
3c349c27 148static void *SWITCH_THREAD_FUNC collect_thread_run(switch_thread_t *thread, void *obj)
e6a60a20
AM
149{
150 struct key_collect *collect = (struct key_collect *) obj;
151 switch_channel_t *channel = switch_core_session_get_channel(collect->session);
ffb989e4 152 char buf[10] = SWITCH_BLANK_STRING;
061a399a 153 switch_application_interface_t *application_interface = NULL;
e6a60a20 154
f9d1c799
AM
155 if (collect->session) {
156 if (switch_core_session_read_lock(collect->session) != SWITCH_STATUS_SUCCESS) {
157 return NULL;
158 }
159 } else {
160 return NULL;
161 }
886e1ddb 162
71054917 163 switch_ivr_sleep(collect->session, 0, SWITCH_TRUE, NULL);
886e1ddb 164
e6a60a20
AM
165 if (!strcasecmp(collect->key, "exec")) {
166 char *data;
e6a60a20 167 char *app_name, *app_data;
2d47baee 168
e6a60a20
AM
169 if (!(data = collect->file)) {
170 goto wbreak;
171 }
172
173 app_name = data;
174
175 if ((app_data = strchr(app_name, ' '))) {
176 *app_data++ = '\0';
177 }
178
179 if ((application_interface = switch_loadable_module_get_application_interface(app_name)) == 0) {
c2d5f970 180 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(collect->session), SWITCH_LOG_ERROR, "Invalid Application %s\n", app_name);
e6a60a20
AM
181 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
182 goto wbreak;
183 }
184
185 if (!application_interface->application_function) {
c2d5f970 186 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(collect->session), SWITCH_LOG_ERROR, "No Function for %s\n", app_name);
e6a60a20
AM
187 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
188 goto wbreak;
189 }
190
7da38730 191 switch_core_session_exec(collect->session, application_interface, app_data);
3c349c27 192
9ecf187d 193 if (switch_channel_up_nosig(channel)) {
e6a60a20 194 switch_channel_set_flag(channel, CF_WINNER);
945d1141 195 switch_channel_set_variable(channel, "group_dial_status", "winner");
e6a60a20
AM
196 }
197 goto wbreak;
198 }
199
9ecf187d 200 if (!switch_channel_up_nosig(channel)) {
e6a60a20
AM
201 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
202 goto wbreak;
203 }
204
205 while (switch_channel_ready(channel)) {
2d47baee
AM
206 switch_size_t len = strlen(collect->key);
207 const char *file = collect->file;
208 switch_status_t status;
209
e6a60a20
AM
210 memset(buf, 0, sizeof(buf));
211
2d47baee
AM
212 if (zstr(file)) {
213 file = "silence";
214 }
215
216 status = switch_ivr_read(collect->session,
084e2450
PO
217 (uint32_t)len,
218 (uint32_t)len,
cfa30468 219 collect->file, NULL, buf, sizeof(buf), collect->confirm_timeout, NULL, 0);
2d47baee
AM
220
221
222 if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK && status != SWITCH_STATUS_TOO_SMALL) {
329033ee 223 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(collect->session), SWITCH_LOG_ERROR, "%s Error Playing File!\n",
2d47baee
AM
224 switch_channel_get_name(channel));
225 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
e6a60a20 226 }
2d47baee
AM
227
228 if (!strcmp(collect->key, buf)) {
229 switch_channel_set_flag(channel, CF_WINNER);
945d1141 230 switch_channel_set_variable(channel, "group_dial_status", "winner");
2d47baee
AM
231 goto wbreak;
232 } else if (collect->error_file) {
233 switch_ivr_play_file(collect->session, NULL, collect->error_file, NULL);
e6a60a20
AM
234 }
235 }
886e1ddb 236 wbreak:
f9d1c799
AM
237
238 switch_core_session_rwunlock(collect->session);
bad5964b 239
886e1ddb 240 UNPROTECT_INTERFACE(application_interface);
bad5964b 241
e6a60a20
AM
242 return NULL;
243}
244
245static void launch_collect_thread(struct key_collect *collect)
246{
247 switch_thread_t *thread;
248 switch_threadattr_t *thd_attr = NULL;
249
250 switch_threadattr_create(&thd_attr, switch_core_session_get_pool(collect->session));
251 switch_threadattr_detach_set(thd_attr, 1);
252 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
debdfb1a 253 switch_thread_create(&thread, thd_attr, collect_thread_run, collect, switch_core_session_get_pool(collect->session));
e6a60a20
AM
254}
255
478efc5f 256static int check_per_channel_timeouts(originate_global_t *oglobals,
886e1ddb 257 originate_status_t *originate_status, int max, time_t start, switch_call_cause_t *force_reason)
4ed389f9 258{
886e1ddb
AM
259 int x = 0, i, delayed_channels = 0, active_channels = 0;
260 uint32_t early_exit_time = 0, delayed_min = 0;
160535da 261
0463541d 262 time_t elapsed = switch_epoch_time_now(NULL) - start;
4ed389f9 263
bdf8f594
AM
264 if (oglobals->cancel_timeout > 0) {
265 return 0;
266 }
160535da 267 for (i = 0; i < max; i++) {
886e1ddb 268 if (originate_status[i].peer_channel && switch_channel_get_state(originate_status[i].peer_channel) != CS_DESTROY &&
757aa19e 269 switch_channel_get_state(originate_status[i].peer_channel) != CS_REPORTING) {
160535da
AM
270 if (originate_status[i].per_channel_delay_start) {
271 delayed_channels++;
272 } else {
273 active_channels++;
274 }
275 }
276 }
bdf8f594 277
160535da
AM
278 if (active_channels == 0 && delayed_channels) {
279 for (i = 0; i < max; i++) {
886e1ddb
AM
280 if (originate_status[i].peer_channel && originate_status[i].per_channel_delay_start &&
281 (!delayed_min || delayed_min > originate_status[i].per_channel_delay_start)) {
160535da
AM
282 delayed_min = originate_status[i].per_channel_delay_start;
283 }
284 }
05d6342f 285 early_exit_time = delayed_min - (uint32_t) elapsed;
160535da 286 }
4ed389f9 287 for (i = 0; i < max; i++) {
886e1ddb
AM
288 if (originate_status[i].peer_channel && originate_status[i].per_channel_delay_start &&
289 (elapsed > originate_status[i].per_channel_delay_start || active_channels == 0)) {
160535da
AM
290 if (active_channels == 0) {
291 if (originate_status[i].per_channel_timelimit_sec) {
757aa19e
AM
292 if (originate_status[i].per_channel_timelimit_sec > early_exit_time) {
293 /* IN theory this check is not needed ( should just be if !0 then -= with no else), if its not 0 it should always be greater.... */
160535da 294 originate_status[i].per_channel_timelimit_sec -= early_exit_time;
757aa19e 295 } else {
160535da 296 originate_status[i].per_channel_timelimit_sec = 1;
757aa19e 297 }
160535da
AM
298 }
299 if (originate_status[i].per_channel_progress_timelimit_sec) {
757aa19e
AM
300 if (originate_status[i].per_channel_progress_timelimit_sec > early_exit_time) {
301 /* IN theory this check is not needed ( should just be if !0 then -= with no else), if its not 0 it should always be greater.... */
160535da 302 originate_status[i].per_channel_progress_timelimit_sec -= early_exit_time;
757aa19e 303 } else {
160535da 304 originate_status[i].per_channel_progress_timelimit_sec = 1;
757aa19e 305 }
160535da
AM
306 }
307 originate_status[i].per_channel_delay_start -= delayed_min;
308 } else {
309 originate_status[i].per_channel_delay_start = 0;
310 }
311
886e1ddb 312 if (!originate_status[i].per_channel_delay_start) {
160535da
AM
313 switch_channel_clear_flag(originate_status[i].peer_channel, CF_BLOCK_STATE);
314 }
d7a12df5
AM
315 }
316
9ecf187d 317 if (originate_status[i].peer_channel && switch_channel_up_nosig(originate_status[i].peer_channel)) {
29c616b9 318 if (originate_status[i].per_channel_progress_timelimit_sec && elapsed > originate_status[i].per_channel_progress_timelimit_sec &&
886e1ddb 319 !(switch_channel_test_flag(originate_status[i].peer_channel, CF_RING_READY) ||
1dcb3b67 320 switch_channel_test_flag(originate_status[i].peer_channel, CF_ANSWERED) ||
478efc5f 321 (!oglobals->monitor_early_media_ring && switch_channel_test_flag(originate_status[i].peer_channel, CF_EARLY_MEDIA))
886e1ddb 322 )
4ed389f9 323 ) {
1dcb3b67 324 switch_channel_hangup(originate_status[i].peer_channel, SWITCH_CAUSE_PROGRESS_TIMEOUT);
25aff5bc 325 *force_reason = SWITCH_CAUSE_PROGRESS_TIMEOUT;
4ed389f9
AM
326 x++;
327 }
29c616b9 328 if (originate_status[i].per_channel_timelimit_sec && elapsed > originate_status[i].per_channel_timelimit_sec) {
1dcb3b67 329 switch_channel_hangup(originate_status[i].peer_channel, SWITCH_CAUSE_ALLOTTED_TIMEOUT);
4ed389f9
AM
330 x++;
331 }
332 }
333 }
334
335 return x;
336}
337
697bb6ec
AM
338static switch_bool_t monitor_callback(switch_core_session_t *session, const char *app, const char *data)
339{
340 if (app) {
341 switch_channel_t *channel = switch_core_session_get_channel(session);
342 if (!strcmp(app, "fail")) {
33a3bcf5
AM
343 const char *bd = switch_channel_get_variable(channel, "monitor_fail_dispo");
344 if (!bd) {
345 bd = "monitor_early_media_fail";
346 }
9d98d49f 347 switch_channel_set_variable(channel, "DIALSTATUS", "BUSY");
33a3bcf5 348 switch_channel_set_variable(channel, "originate_disposition", bd);
697bb6ec
AM
349 switch_channel_hangup(channel, data ? switch_channel_str2cause(data) : SWITCH_CAUSE_USER_BUSY);
350 } else if (!strcmp(app, "ring")) {
351 originate_global_t *oglobals = (originate_global_t *) switch_channel_get_private(channel, "_oglobals_");
33a3bcf5
AM
352 const char *bd = switch_channel_get_variable(channel, "monitor_ring_dispo");
353 if (!bd) {
354 bd = "monitor_early_media_ring";
355 }
356 switch_channel_set_variable(channel, "originate_disposition", bd);
9d98d49f 357 switch_channel_set_variable(channel, "DIALSTATUS", "EARLY");
886e1ddb 358
697bb6ec 359 if (oglobals) {
ba77f232 360 if (oglobals->monitor_early_media_ring_total && ++oglobals->monitor_early_media_ring_count < oglobals->monitor_early_media_ring_total) {
886e1ddb 361 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Ring %d/%d\n",
ba77f232
AM
362 oglobals->monitor_early_media_ring_count, oglobals->monitor_early_media_ring_total);
363 return SWITCH_TRUE;
364 }
886e1ddb 365
697bb6ec 366 switch_channel_set_private(channel, "_oglobals_", NULL);
886e1ddb 367
29d76292
AM
368 if (!oglobals->progress) {
369 oglobals->progress = 1;
370 }
886e1ddb 371
effb166b 372 if (!oglobals->ring_ready && !oglobals->ignore_ring_ready) {
29d76292
AM
373 oglobals->ring_ready = 1;
374 }
886e1ddb 375
effb166b
AM
376 if (!oglobals->ignore_early_media && !oglobals->early_ok) {
377 oglobals->early_ok = 1;
378 }
697bb6ec
AM
379 }
380 }
381 }
382
383 return SWITCH_FALSE;
384}
385
72ec7b59
MR
386static void inherit_codec(switch_channel_t *caller_channel, switch_core_session_t *session)
387{
388 const char *var = switch_channel_get_variable(caller_channel, "inherit_codec");
389 switch_channel_t *channel = switch_core_session_get_channel(session);
f685e4c5
AM
390
391 if (!zstr(var) && !strcasecmp(var, "passthru")) {
392 switch_channel_set_variable(caller_channel, "absolute_codec_string", switch_channel_get_variable(channel, "ep_codec_string"));
393 } else if (switch_true(var)) {
72ec7b59
MR
394 switch_codec_implementation_t impl = { 0 };
395 switch_codec_implementation_t video_impl = { 0 };
396 char tmp[128] = "";
397
72ec7b59 398 if (switch_core_session_get_read_impl(session, &impl) == SWITCH_STATUS_SUCCESS) {
f79f9766
AM
399 const char *ep = switch_channel_get_variable(caller_channel, "ep_codec_string");
400
f41fbbc0 401 if (switch_core_session_get_video_read_impl(session, &video_impl) == SWITCH_STATUS_SUCCESS) {
72ec7b59 402 switch_snprintf(tmp, sizeof(tmp), "%s@%uh@%ui,%s",
dc2c11f1 403 impl.iananame, impl.samples_per_second, (uint32_t)impl.microseconds_per_packet / 1000,
72ec7b59
MR
404 video_impl.iananame);
405 } else {
406 switch_snprintf(tmp, sizeof(tmp), "%s@%uh@%ui",
dc2c11f1 407 impl.iananame, impl.samples_per_second, (uint32_t)impl.microseconds_per_packet / 1000);
72ec7b59 408 }
f79f9766
AM
409
410 if (ep && switch_stristr(impl.iananame, ep)) {
411 switch_channel_set_variable(caller_channel, "absolute_codec_string", tmp);
412 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_DEBUG, "Setting codec string on %s to %s\n",
413 switch_channel_get_name(caller_channel), tmp);
414 } else {
415 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_DEBUG, "Codec string %s not supported on %s, skipping inheritance\n",
416 tmp, switch_channel_get_name(caller_channel));
417 }
72ec7b59
MR
418 } else {
419 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_WARNING,
420 "Error inheriting codec. Channel %s has no read codec yet.\n",
421 switch_channel_get_name(channel));
422 }
423
424 }
425}
426
1400a31c 427static uint8_t check_channel_status(originate_global_t *oglobals, originate_status_t *originate_status, uint32_t len, switch_call_cause_t *force_reason)
e6a60a20
AM
428{
429
430 uint32_t i;
dc2a354c 431 uint8_t rval = 0;
13c4da7b
AM
432 switch_channel_t *caller_channel = NULL;
433 int pindex = -1;
cf4b7672 434 char bug_key[256] = "";
757aa19e 435 int send_ringback = 0;
091952ca 436 uint8_t ring_ready_val = 0;
7f76b67f 437 int pickups = 0;
cf4b7672 438
dc2a354c
MJ
439 oglobals->hups = 0;
440 oglobals->idx = IDX_NADA;
cf4b7672 441
13c4da7b 442
1dcb3b67
AM
443 if (oglobals->session) {
444 caller_channel = switch_core_session_get_channel(oglobals->session);
1cbd982a
AM
445 if (switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE)) {
446 caller_channel = NULL;
447 }
13c4da7b 448 }
886e1ddb 449
3c349c27 450
b43fa945 451 for (i = 0; i < len; i++) {
092a0f8b 452 if (originate_status[i].peer_channel && switch_channel_test_flag(originate_status[i].peer_channel, CF_CHANNEL_SWAP)) {
b43fa945
AM
453 const char *key = switch_channel_get_variable(originate_status[i].peer_channel, "channel_swap_uuid");
454 switch_core_session_t *swap_session, *old_session;
455
456 if ((swap_session = switch_core_session_locate(key))) {
457 switch_channel_clear_flag(originate_status[i].peer_channel, CF_CHANNEL_SWAP);
458 switch_channel_hangup(originate_status[i].peer_channel, SWITCH_CAUSE_PICKED_OFF);
459
460 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(originate_status[i].peer_channel), SWITCH_LOG_DEBUG, "Swapping %s for %s\n",
461 switch_core_session_get_name(swap_session), switch_channel_get_name(originate_status[i].peer_channel));
462
463
464 old_session = originate_status[i].peer_session;
465 originate_status[i].peer_session = swap_session;
466 originate_status[i].peer_channel = switch_core_session_get_channel(originate_status[i].peer_session);
467 originate_status[i].caller_profile = switch_channel_get_caller_profile(originate_status[i].peer_channel);
468 switch_channel_set_flag(originate_status[i].peer_channel, CF_ORIGINATING);
69238450 469
b43fa945 470 switch_channel_answer(originate_status[i].peer_channel);
69238450 471
97d47af8 472 switch_channel_set_variable(originate_status[i].peer_channel, "picked_up_uuid", switch_core_session_get_uuid(old_session));
69238450
AM
473 switch_channel_execute_on(originate_status[i].peer_channel, "execute_on_pickup");
474 switch_channel_api_on(originate_status[i].peer_channel, "api_on_pickup");
475
b43fa945
AM
476 switch_core_session_rwunlock(old_session);
477 break;
478 }
479 }
480 }
481
e6a60a20 482 for (i = 0; i < len; i++) {
69120105 483 switch_channel_state_t state;
daab35e3
AM
484
485 if (originate_status[i].tagged && originate_status[i].peer_session) {
486 switch_channel_t *channel = switch_core_session_get_channel(originate_status[i].peer_session);
a79adcaf 487 uint32_t j;
886e1ddb 488
9ecf187d 489 if (switch_channel_down_nosig(channel)) {
daab35e3 490 switch_call_cause_t cause = switch_channel_get_cause(channel);
886e1ddb 491
daab35e3
AM
492 for (j = 0; j < len; j++) {
493 channel = switch_core_session_get_channel(originate_status[j].peer_session);
494 switch_channel_hangup(channel, cause);
495 }
496 oglobals->hups = len;
497 rval = 0;
498 goto end;
499 }
500 }
886e1ddb 501
7f76b67f
AM
502
503 if (originate_status[i].peer_channel && switch_channel_test_flag(originate_status[i].peer_channel, CF_PICKUP)) {
504 pickups++;
505 }
506
ba77f232 507 if (!(originate_status[i].peer_channel && originate_status[i].peer_session)) {
90c7921f 508 oglobals->hups++;
e6a60a20
AM
509 continue;
510 }
1dcb3b67 511
091952ca 512 if ((ring_ready_val = (uint8_t)switch_channel_test_flag(originate_status[i].peer_channel, CF_RING_READY))) {
1dcb3b67 513 if (!originate_status[i].ring_ready) {
3c688a95 514 originate_status[i].ring_ready = ring_ready_val;
1dcb3b67
AM
515 }
516
757aa19e
AM
517 if (oglobals->sending_ringback == 1) {
518 send_ringback++;
519 pindex = (uint32_t) i;
520 } else {
521 if (!oglobals->ring_ready) {
3c688a95 522 oglobals->ring_ready = ring_ready_val;
757aa19e
AM
523 if (caller_channel && !oglobals->ignore_ring_ready) {
524 if (len == 1) {
525 switch_channel_pass_callee_id(originate_status[0].peer_channel, caller_channel);
526 }
3c688a95
AM
527 switch_channel_ring_ready_value(caller_channel, ring_ready_val);
528 oglobals->sent_ring = ring_ready_val;
4d9f7de2 529 }
59b94dfa 530 }
1dcb3b67 531 }
e6a60a20 532 }
90c7921f 533
1dcb3b67 534 if (switch_channel_test_flag(originate_status[i].peer_channel, CF_EARLY_MEDIA)) {
757aa19e 535
8e75f82e
AM
536 if (oglobals->ignore_early_media == 3 && oglobals->bridge_early_media == -1) {
537 oglobals->bridge_early_media = i;
538 oglobals->ringback_ok = 1;
539 }
540
757aa19e
AM
541 if (oglobals->sending_ringback == 1) {
542 send_ringback++;
543 pindex = (uint32_t) i;
544 } else if (!oglobals->sent_ring && oglobals->ignore_early_media == 2 && len == 1 && caller_channel && !oglobals->ignore_ring_ready) {
e072a609 545 switch_channel_pass_callee_id(originate_status[0].peer_channel, caller_channel);
5b752c54 546 switch_channel_ring_ready(caller_channel);
e072a609
AM
547 oglobals->sent_ring = 1;
548 }
549
1dcb3b67
AM
550 if (!originate_status[i].early_media) {
551 originate_status[i].early_media = 1;
552 if (oglobals->early_ok) {
553 pindex = i;
554 }
886e1ddb 555
697bb6ec
AM
556 if (oglobals->monitor_early_media_fail) {
557 const char *var = switch_channel_get_variable(originate_status[i].peer_channel, "monitor_early_media_fail");
df7637f6 558 if (!zstr(var)) {
886e1ddb 559 char *fail_array[128] = { 0 };
697bb6ec
AM
560 int fail_count = 0;
561 char *fail_data = strdup(var);
562 int fx;
ba77f232
AM
563 int y = 0;
564
697bb6ec
AM
565 switch_assert(fail_data);
566 fail_count = switch_separate_string(fail_data, '!', fail_array, (sizeof(fail_array) / sizeof(fail_array[0])));
886e1ddb
AM
567
568 for (fx = 0; fx < fail_count; fx++) {
697bb6ec
AM
569 char *cause = fail_array[fx];
570 int hits = 2;
571 char *p, *q;
886e1ddb 572
697bb6ec 573 if (!(p = strchr(cause, ':'))) {
c2d5f970 574 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originate_status[i].peer_session), SWITCH_LOG_ERROR, "Parse Error\n");
697bb6ec
AM
575 continue;
576 }
577 *p++ = '\0';
886e1ddb 578
697bb6ec
AM
579
580 if (!p) {
c2d5f970 581 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originate_status[i].peer_session), SWITCH_LOG_ERROR, "Parse Error\n");
697bb6ec
AM
582 continue;
583 }
886e1ddb 584
697bb6ec
AM
585
586 if (!(hits = atoi(p))) {
587 hits = 2;
588 }
886e1ddb 589
697bb6ec
AM
590
591 if (!(p = strchr(p, ':'))) {
c2d5f970 592 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originate_status[i].peer_session), SWITCH_LOG_ERROR, "Parse Error\n");
697bb6ec
AM
593 continue;
594 }
595 *p++ = '\0';
886e1ddb 596
697bb6ec 597 if (!p) {
c2d5f970 598 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originate_status[i].peer_session), SWITCH_LOG_ERROR, "Parse Error\n");
697bb6ec
AM
599 continue;
600 }
601
886e1ddb 602 for (q = p; q && *q; q++) {
697bb6ec
AM
603 if (*q == '+') {
604 *q = ',';
605 }
606 }
ba77f232 607 switch_snprintf(bug_key, sizeof(bug_key), "monitor_early_media_fail_%d", ++y);
886e1ddb
AM
608 switch_ivr_tone_detect_session(originate_status[i].peer_session, bug_key, p, "r", 0, hits, "fail", cause, monitor_callback);
609
697bb6ec 610 }
886e1ddb 611
697bb6ec 612 switch_safe_free(fail_data);
886e1ddb 613
697bb6ec
AM
614 }
615 }
886e1ddb 616
697bb6ec
AM
617 if (oglobals->monitor_early_media_ring) {
618 const char *var = switch_channel_get_variable(originate_status[i].peer_channel, "monitor_early_media_ring");
ba77f232 619 const char *var_total = switch_channel_get_variable(originate_status[i].peer_channel, "monitor_early_media_ring_total");
df7637f6 620 if (!zstr(var)) {
886e1ddb 621 char *ring_array[128] = { 0 };
697bb6ec
AM
622 int ring_count = 0;
623 char *ring_data = strdup(var);
624 int fx;
ba77f232
AM
625 int y = 0;
626
697bb6ec
AM
627 switch_assert(ring_data);
628 ring_count = switch_separate_string(ring_data, '!', ring_array, (sizeof(ring_array) / sizeof(ring_array[0])));
886e1ddb
AM
629
630 for (fx = 0; fx < ring_count; fx++) {
697bb6ec
AM
631 int hits = 2;
632 char *p = ring_array[fx], *q;
886e1ddb 633
dbeb3aa4 634 if (!p) {
c2d5f970 635 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originate_status[i].peer_session), SWITCH_LOG_ERROR, "Parse Error\n");
dbeb3aa4
MJ
636 continue;
637 }
638
697bb6ec
AM
639 if (!(hits = atoi(p))) {
640 hits = 2;
641 }
886e1ddb 642
697bb6ec 643 if (!(p = strchr(p, ':'))) {
c2d5f970 644 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originate_status[i].peer_session), SWITCH_LOG_ERROR, "Parse Error\n");
697bb6ec
AM
645 continue;
646 }
647 *p++ = '\0';
886e1ddb 648
697bb6ec 649 if (!p) {
c2d5f970 650 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originate_status[i].peer_session), SWITCH_LOG_ERROR, "Parse Error\n");
697bb6ec
AM
651 continue;
652 }
653
886e1ddb 654 for (q = p; q && *q; q++) {
697bb6ec
AM
655 if (*q == '+') {
656 *q = ',';
657 }
658 }
886e1ddb 659
697bb6ec 660 switch_channel_set_private(originate_status[i].peer_channel, "_oglobals_", oglobals);
ba77f232 661 switch_snprintf(bug_key, sizeof(bug_key), "monitor_early_media_ring_%d", ++y);
886e1ddb
AM
662 switch_ivr_tone_detect_session(originate_status[i].peer_session, bug_key, p, "r", 0, hits, "ring", NULL, monitor_callback);
663
697bb6ec 664 }
886e1ddb 665
ba77f232
AM
666 if (var_total) {
667 int tmp = atoi(var_total);
668 if (tmp > 0 && tmp < 100) {
886e1ddb
AM
669 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originate_status[i].peer_session), SWITCH_LOG_DEBUG,
670 "%s setting ring total to %d\n", switch_channel_get_name(originate_status[i].peer_channel), tmp);
ba77f232
AM
671 oglobals->monitor_early_media_ring_total = tmp;
672 }
673 }
886e1ddb 674
697bb6ec 675 switch_safe_free(ring_data);
886e1ddb 676
697bb6ec
AM
677 }
678 }
1dcb3b67 679 }
886e1ddb 680
29d76292
AM
681 if (!oglobals->monitor_early_media_ring) {
682
683 if (!oglobals->progress) {
684 oglobals->progress = 1;
685 }
886e1ddb 686
effb166b 687 if (!oglobals->ring_ready && !oglobals->ignore_ring_ready) {
29d76292 688 oglobals->ring_ready = 1;
886e1ddb 689
29d76292 690 }
1dcb3b67 691 }
f33aa021 692 }
ed5266d3
AM
693
694 if (!switch_channel_test_flag(originate_status[i].peer_channel, CF_PARK) &&
695 !switch_channel_test_flag(originate_status[i].peer_channel, CF_CONSUME_ON_ORIGINATE)) {
8b0421ff
AM
696 if (switch_core_session_messages_waiting(originate_status[i].peer_session)) {
697 if (switch_channel_test_flag(originate_status[i].peer_channel, CF_THREAD_SLEEPING)) {
698 switch_core_session_wake_session_thread(originate_status[i].peer_session);
699 } else {
700 switch_ivr_parse_all_events(originate_status[i].peer_session);
701 }
ed5266d3
AM
702 }
703 }
8b1ad09d 704
a8ce9ac2
AM
705 if (switch_channel_test_flag(originate_status[i].peer_channel, CF_EARLY_OK)) {
706 if (!oglobals->early_ok) {
707 oglobals->early_ok = 1;
708 }
709 switch_channel_clear_flag(originate_status[i].peer_channel, CF_EARLY_OK);
35f0e2ff
AM
710 }
711
b0197694
AM
712 if (caller_channel && switch_channel_test_flag(caller_channel, CF_EARLY_OK)) {
713 if (!oglobals->early_ok) {
714 oglobals->early_ok = 1;
715 }
716 switch_channel_clear_flag(caller_channel, CF_EARLY_OK);
717 }
718
1dcb3b67
AM
719 state = switch_channel_get_state(originate_status[i].peer_channel);
720 if (state >= CS_HANGUP || state == CS_RESET || switch_channel_test_flag(originate_status[i].peer_channel, CF_TRANSFER) ||
721 switch_channel_test_flag(originate_status[i].peer_channel, CF_REDIRECT) ||
886e1ddb 722 switch_channel_test_flag(originate_status[i].peer_channel, CF_BRIDGED) ||
1dcb3b67 723 !switch_channel_test_flag(originate_status[i].peer_channel, CF_ORIGINATING)
3c349c27 724 ) {
1dcb3b67 725 (oglobals->hups)++;
4f7122c8
AM
726 if (switch_channel_test_flag(originate_status[i].peer_channel, CF_PICKUP)) {
727 pickups--;
728 }
1dcb3b67
AM
729 } else if ((switch_channel_test_flag(originate_status[i].peer_channel, CF_ANSWERED) ||
730 (oglobals->early_ok && switch_channel_test_flag(originate_status[i].peer_channel, CF_EARLY_MEDIA)) ||
886e1ddb 731 (oglobals->ring_ready && oglobals->return_ring_ready && len == 1 &&
1dcb3b67 732 switch_channel_test_flag(originate_status[i].peer_channel, CF_RING_READY))
886e1ddb 733 )
1dcb3b67 734 && !switch_channel_test_flag(originate_status[i].peer_channel, CF_TAGGED)
886e1ddb
AM
735 ) {
736
df7637f6 737 if (!zstr(oglobals->key)) {
e6a60a20
AM
738 struct key_collect *collect;
739
bdf8f594
AM
740 if (oglobals->cancel_timeout < 0) {
741 oglobals->cancel_timeout = 1;
742 }
743
1dcb3b67
AM
744 if ((collect = switch_core_session_alloc(originate_status[i].peer_session, sizeof(*collect)))) {
745 switch_channel_set_flag(originate_status[i].peer_channel, CF_TAGGED);
df7637f6 746 if (!zstr(oglobals->key)) {
1dcb3b67
AM
747 collect->key = switch_core_session_strdup(originate_status[i].peer_session, oglobals->key);
748 }
df7637f6 749 if (!zstr(oglobals->file)) {
1dcb3b67 750 collect->file = switch_core_session_strdup(originate_status[i].peer_session, oglobals->file);
e6a60a20 751 }
2d47baee
AM
752 if (!zstr(oglobals->error_file)) {
753 collect->error_file = switch_core_session_strdup(originate_status[i].peer_session, oglobals->error_file);
754 }
755
756 if (oglobals->confirm_timeout) {
757 collect->confirm_timeout = oglobals->confirm_timeout;
758 } else {
759 collect->confirm_timeout = 5000;
760 }
761
32bcc886 762 switch_channel_audio_sync(originate_status[i].peer_channel);
1dcb3b67 763 collect->session = originate_status[i].peer_session;
e6a60a20
AM
764 launch_collect_thread(collect);
765 }
766 } else {
1dcb3b67 767 oglobals->idx = i;
13c4da7b
AM
768 pindex = (uint32_t) i;
769 rval = 0;
770 goto end;
e6a60a20
AM
771
772 }
1dcb3b67
AM
773 } else if (switch_channel_test_flag(originate_status[i].peer_channel, CF_WINNER)) {
774 oglobals->idx = i;
13c4da7b
AM
775 rval = 0;
776 pindex = (uint32_t) i;
777 goto end;
e6a60a20
AM
778 }
779 }
780
a0eef6a1 781 if (oglobals->hups > 0 && oglobals->hups + pickups == len) {
13c4da7b 782 rval = 0;
e6a60a20 783 } else {
13c4da7b
AM
784 rval = 1;
785 }
786
886e1ddb 787 end:
13c4da7b 788
f71b67e0
AM
789 if (rval == 0 && pickups) {
790 for (i = 0; i < len; i++) {
791 if (originate_status[i].peer_channel && switch_channel_test_flag(originate_status[i].peer_channel, CF_PICKUP) &&
792 switch_channel_up(originate_status[i].peer_channel)) {
631c976f 793 switch_channel_hangup(originate_status[i].peer_channel, SWITCH_CAUSE_NO_PICKUP);
f71b67e0
AM
794 }
795 }
796 }
797
798
dfa54399
AM
799 if (pindex > -1 && caller_channel && switch_channel_ready(caller_channel) && !switch_channel_media_ready(caller_channel) &&
800 switch_channel_media_ready(originate_status[pindex].peer_channel)) {
72ec7b59 801 inherit_codec(caller_channel, originate_status[pindex].peer_session);
e6a60a20 802 }
757aa19e
AM
803
804 if (send_ringback) {
886e1ddb 805 oglobals->sending_ringback++;
757aa19e 806 }
13c4da7b
AM
807
808 return rval;
809
e6a60a20
AM
810}
811
812struct ringback {
813 switch_buffer_t *audio_buffer;
e6a60a20
AM
814 teletone_generation_session_t ts;
815 switch_file_handle_t fhb;
816 switch_file_handle_t *fh;
1136fcec 817 int silence;
e6a60a20
AM
818 uint8_t asis;
819};
820
821typedef struct ringback ringback_t;
822
3c349c27 823static int teletone_handler(teletone_generation_session_t *ts, teletone_tone_map_t *map)
e6a60a20
AM
824{
825 ringback_t *tto = ts->user_data;
826 int wrote;
827
828 if (!tto) {
829 return -1;
830 }
831 wrote = teletone_mux_tones(ts, map);
832 switch_buffer_write(tto->audio_buffer, ts->buffer, wrote * 2);
833
834 return 0;
835}
836
69120105
AM
837
838SWITCH_DECLARE(switch_status_t) switch_ivr_wait_for_answer(switch_core_session_t *session, switch_core_session_t *peer_session)
839{
047e3dd7 840 switch_channel_t *caller_channel = NULL;
482badff 841 switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session);
3c349c27 842 const char *ringback_data = NULL;
69120105
AM
843 switch_frame_t write_frame = { 0 };
844 switch_codec_t write_codec = { 0 };
482badff 845 switch_codec_t *read_codec = switch_core_session_get_read_codec(session);
69120105
AM
846 uint8_t pass = 0;
847 ringback_t ringback = { 0 };
69120105
AM
848 switch_frame_t *read_frame = NULL;
849 switch_status_t status = SWITCH_STATUS_SUCCESS;
69120105 850 int timelimit = 60;
ee44d83b 851 const char *var;
69120105 852 switch_time_t start = 0;
f8b442da 853 const char *cancel_key = NULL;
aaeb69d6 854 switch_channel_state_t wait_state = 0;
3c349c27 855
ee44d83b 856 switch_assert(peer_channel);
886e1ddb 857
aaeb69d6
AM
858 if (switch_channel_get_state(peer_channel) == CS_RESET) {
859 switch_channel_set_state(peer_channel, CS_SOFT_EXECUTE);
860 }
861
047e3dd7
AM
862 if (session) {
863 caller_channel = switch_core_session_get_channel(session);
864 }
865
ede7970f 866 if ((switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA))) {
74e21a82 867 goto end;
ede7970f
MJ
868 }
869
a8023642 870 switch_zmalloc(write_frame.data, SWITCH_RECOMMENDED_BUFFER_SIZE);
3608c834 871 write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
69120105 872
bcfccaee 873 if (caller_channel && (var = switch_channel_get_variable(caller_channel, SWITCH_CALL_TIMEOUT_VARIABLE))) {
69120105
AM
874 timelimit = atoi(var);
875 if (timelimit < 0) {
876 timelimit = 60;
877 }
878 }
879
880 timelimit *= 1000000;
0463541d 881 start = switch_micro_time_now();
69120105 882
047e3dd7 883 if (caller_channel) {
f8b442da
AM
884 cancel_key = switch_channel_get_variable(caller_channel, "origination_cancel_key");
885
047e3dd7
AM
886 if (switch_channel_test_flag(caller_channel, CF_ANSWERED)) {
887 ringback_data = switch_channel_get_variable(caller_channel, "transfer_ringback");
888 }
886e1ddb 889
047e3dd7
AM
890 if (!ringback_data) {
891 ringback_data = switch_channel_get_variable(caller_channel, "ringback");
892 }
893
047e3dd7
AM
894 if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE) || switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA)) {
895 ringback_data = NULL;
df7637f6 896 } else if (zstr(ringback_data)) {
1136fcec
AM
897 if ((var = switch_channel_get_variable(caller_channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE))) {
898 int sval = atoi(var);
899
900 if (sval) {
fc1de32f 901 ringback_data = switch_core_session_sprintf(session, "silence:%d", sval);
1136fcec
AM
902 }
903 }
047e3dd7 904 }
69120105 905 }
3c349c27
AM
906
907
047e3dd7 908 if (read_codec && ringback_data) {
a9936c09
AM
909 if (switch_is_file_path(ringback_data)) {
910 if (!(strrchr(ringback_data, '.') || strstr(ringback_data, SWITCH_URL_SEPARATOR))) {
911 ringback.asis++;
912 }
913 }
914
915
886e1ddb 916
a9936c09 917 if (!ringback.asis) {
84090fe2 918 if ((pass = (uint8_t) switch_test_flag(read_codec, SWITCH_CODEC_FLAG_PASSTHROUGH))) {
a9936c09
AM
919 goto no_ringback;
920 }
921
69120105
AM
922 if (switch_core_codec_init(&write_codec,
923 "L16",
924 NULL,
925 read_codec->implementation->actual_samples_per_second,
30c318b9 926 read_codec->implementation->microseconds_per_packet / 1000,
3c349c27 927 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
a9936c09
AM
928 switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
929 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Error!\n");
930 if (caller_channel) {
99c681f3 931 switch_channel_hangup(caller_channel, SWITCH_CAUSE_BEARERCAPABILITY_NOTIMPL);
a9936c09
AM
932 }
933 read_codec = NULL;
934 goto done;
935 } else {
c2d5f970 936 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
69120105 937 "Raw Codec Activation Success L16@%uhz 1 channel %dms\n",
30c318b9 938 read_codec->implementation->actual_samples_per_second, read_codec->implementation->microseconds_per_packet / 1000);
886e1ddb 939
69120105 940 write_frame.codec = &write_codec;
30c318b9 941 write_frame.datalen = read_codec->implementation->decoded_bytes_per_packet;
69120105
AM
942 write_frame.samples = write_frame.datalen / 2;
943 memset(write_frame.data, 255, write_frame.datalen);
a9936c09
AM
944 switch_core_session_set_read_codec(session, &write_codec);
945 }
946 }
886e1ddb 947
e072a609
AM
948 if (switch_channel_test_flag(caller_channel, CF_DISABLE_RINGBACK)) {
949 ringback_data = NULL;
950 }
951
a9936c09
AM
952 if (ringback_data) {
953 char *tmp_data = NULL;
69120105 954
a9936c09
AM
955 if (switch_is_file_path(ringback_data)) {
956 char *ext;
3c349c27 957
a9936c09
AM
958 if (ringback.asis) {
959 write_frame.codec = read_codec;
960 ext = read_codec->implementation->iananame;
961 tmp_data = switch_mprintf("%s.%s", ringback_data, ext);
962 ringback_data = tmp_data;
963 }
69120105 964
a9936c09 965 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Play Ringback File [%s]\n", ringback_data);
69120105 966
a9936c09
AM
967 ringback.fhb.channels = read_codec->implementation->number_of_channels;
968 ringback.fhb.samplerate = read_codec->implementation->actual_samples_per_second;
969 if (switch_core_file_open(&ringback.fhb,
970 ringback_data,
971 read_codec->implementation->number_of_channels,
972 read_codec->implementation->actual_samples_per_second,
973 SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
974 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error Playing File\n");
69120105 975 switch_safe_free(tmp_data);
a9936c09 976 goto done;
69120105 977 }
a9936c09 978 ringback.fh = &ringback.fhb;
69120105 979 } else {
a9936c09
AM
980 if (!strncasecmp(ringback_data, "silence", 7)) {
981 const char *p = ringback_data + 7;
982 if (*p == ':') {
983 p++;
984 if (p) {
985 ringback.silence = atoi(p);
986 }
987 }
294a57fb 988 SWITCH_IVR_VERIFY_SILENCE_DIVISOR(ringback.silence);
a9936c09
AM
989 } else {
990 switch_buffer_create_dynamic(&ringback.audio_buffer, 512, 1024, 0);
991 switch_buffer_set_loops(ringback.audio_buffer, -1);
886e1ddb 992
a9936c09
AM
993 teletone_init_session(&ringback.ts, 0, teletone_handler, &ringback);
994 ringback.ts.rate = read_codec->implementation->actual_samples_per_second;
995 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Play Ringback Tone [%s]\n", ringback_data);
996 if (teletone_run(&ringback.ts, ringback_data)) {
997 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error Playing Tone\n");
998 teletone_destroy_session(&ringback.ts);
999 switch_buffer_destroy(&ringback.audio_buffer);
1000 ringback_data = NULL;
1001 }
047e3dd7 1002 }
69120105 1003 }
a9936c09 1004 switch_safe_free(tmp_data);
69120105
AM
1005 }
1006 }
1007
886e1ddb 1008 no_ringback:
a9936c09 1009
aaeb69d6
AM
1010 if (caller_channel) {
1011 wait_state = switch_channel_get_state(caller_channel);
1012 }
1013
1014 while (switch_channel_ready(peer_channel) && !switch_channel_media_ready(peer_channel)) {
0463541d 1015 int diff = (int) (switch_micro_time_now() - start);
3c349c27 1016
ae23edad
AM
1017 switch_ivr_parse_all_messages(session);
1018
f8b442da
AM
1019 if (caller_channel && cancel_key) {
1020 if (switch_channel_has_dtmf(caller_channel)) {
1021 switch_dtmf_t dtmf = { 0, 0 };
1022 if (switch_channel_dequeue_dtmf(caller_channel, &dtmf) == SWITCH_STATUS_SUCCESS) {
1023 if (dtmf.digit == *cancel_key) {
1024 status = SWITCH_STATUS_FALSE;
1025 goto done;
1026 }
1027 }
1028 }
1029 }
1030
aaeb69d6
AM
1031 if (caller_channel && switch_channel_get_state(caller_channel) != wait_state) {
1032 goto done;
1033 }
1034
69120105
AM
1035 if (diff > timelimit) {
1036 status = SWITCH_STATUS_TIMEOUT;
1037 goto done;
1038 }
1039
2e46528e
AM
1040 if (switch_channel_media_ready(caller_channel)) {
1041 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
1042 if (!SWITCH_READ_ACCEPTABLE(status)) {
1043 break;
1044 }
1045 } else {
1046 read_frame = NULL;
1047 }
886e1ddb 1048
69120105 1049 if (read_frame && !pass) {
0b0ce769 1050
69120105 1051 if (ringback.fh) {
69120105
AM
1052 switch_size_t mlen, olen;
1053 unsigned int pos = 0;
886e1ddb 1054
69120105 1055 if (ringback.asis) {
30c318b9 1056 mlen = write_frame.codec->implementation->encoded_bytes_per_packet;
69120105 1057 } else {
30c318b9 1058 mlen = write_frame.codec->implementation->samples_per_packet;
69120105
AM
1059 }
1060
1061 olen = mlen;
ea5c3852
AM
1062 //if (ringback.fh->resampler && ringback.fh->resampler->rfactor > 1) {
1063 //olen = (switch_size_t) (olen * ringback.fh->resampler->rfactor);
1064 //}
3608c834 1065 switch_core_file_read(ringback.fh, write_frame.data, &olen);
69120105
AM
1066
1067 if (olen == 0) {
1068 olen = mlen;
1069 ringback.fh->speed = 0;
1070 switch_core_file_seek(ringback.fh, &pos, 0, SEEK_SET);
3608c834 1071 switch_core_file_read(ringback.fh, write_frame.data, &olen);
69120105 1072 if (olen == 0) {
d4116bb6
AM
1073 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_ERROR,
1074 "Failure to read or re-read after seeking to beginning on file [%s]\n", ringback.fh->file_path);
69120105
AM
1075 break;
1076 }
1077 }
ed7264b6 1078 write_frame.datalen = (uint32_t) (ringback.asis ? olen : olen * 2 * ringback.fh->channels);
69120105
AM
1079 } else if (ringback.audio_buffer) {
1080 if ((write_frame.datalen = (uint32_t) switch_buffer_read_loop(ringback.audio_buffer,
1081 write_frame.data,
30c318b9 1082 write_frame.codec->implementation->decoded_bytes_per_packet)) <= 0) {
69120105
AM
1083 break;
1084 }
1136fcec
AM
1085 } else if (ringback.silence) {
1086 write_frame.datalen = write_frame.codec->implementation->decoded_bytes_per_packet;
579a0518
AM
1087 switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.datalen / 2,
1088 write_frame.codec->implementation->number_of_channels, ringback.silence);
69120105
AM
1089 }
1090
1136fcec 1091 if ((ringback.fh || ringback.silence || ringback.audio_buffer) && write_frame.codec && write_frame.datalen) {
2e46528e
AM
1092 if (switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
1093 break;
1094 }
69120105
AM
1095 }
1096 } else {
2ed601f9 1097 switch_cond_next();
69120105
AM
1098 }
1099 }
1100
886e1ddb 1101 done:
3c349c27 1102
69120105
AM
1103 if (ringback.fh) {
1104 switch_core_file_close(ringback.fh);
1105 ringback.fh = NULL;
1106 } else if (ringback.audio_buffer) {
1107 teletone_destroy_session(&ringback.ts);
1108 switch_buffer_destroy(&ringback.audio_buffer);
1109 }
1110
d43af04e
AM
1111
1112 switch_ivr_parse_all_events(session);
1113
ea5c3852 1114 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
bc2fc3fa 1115
68b0359c 1116 if (switch_core_codec_ready(&write_codec)) {
69120105
AM
1117 switch_core_codec_destroy(&write_codec);
1118 }
3608c834
AM
1119
1120 switch_safe_free(write_frame.data);
69120105 1121
886e1ddb 1122 end:
74e21a82 1123
aaeb69d6 1124 if (!switch_channel_media_ready(peer_channel)) {
9ecf187d 1125 if (switch_channel_up_nosig(peer_channel)) {
aaeb69d6
AM
1126 switch_channel_hangup(peer_channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
1127 }
1128 status = SWITCH_STATUS_FALSE;
1129 }
886e1ddb 1130
d9b096b4
AM
1131 if (switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE)) {
1132 switch_channel_state_t peer_state = switch_channel_get_state(peer_channel);
1133
1134 while (switch_channel_ready(peer_channel) && switch_channel_get_state(peer_channel) == peer_state) {
ae23edad 1135 switch_ivr_parse_all_messages(session);
d9b096b4
AM
1136 switch_channel_ready(caller_channel);
1137 switch_yield(20000);
1138 }
1139 }
1140
9ecf187d 1141 if (caller_channel && !switch_channel_up_nosig(caller_channel)) {
aaeb69d6
AM
1142 status = SWITCH_STATUS_FALSE;
1143 }
1144
1145 return status;
69120105
AM
1146}
1147
e0c37c1f 1148SWITCH_DECLARE(void) switch_process_import(switch_core_session_t *session, switch_channel_t *peer_channel, const char *varname, const char *prefix)
3d136b26
AM
1149{
1150 const char *import, *val;
1151 switch_channel_t *caller_channel;
1152
1153 switch_assert(session && peer_channel);
1154 caller_channel = switch_core_session_get_channel(session);
886e1ddb 1155
a000f0bc 1156 if ((import = switch_channel_get_variable(caller_channel, varname))) {
3d136b26
AM
1157 char *mydata = switch_core_session_strdup(session, import);
1158 int i, argc;
1159 char *argv[64] = { 0 };
1160
1161 if ((argc = switch_separate_string(mydata, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) {
886e1ddb 1162 for (i = 0; i < argc; i++) {
3d136b26 1163 if ((val = switch_channel_get_variable(peer_channel, argv[i]))) {
e0c37c1f
AM
1164 if (prefix) {
1165 char *var = switch_mprintf("%s%s", prefix, argv[i]);
1166 switch_channel_set_variable(caller_channel, var, val);
1167 free(var);
1168 } else {
1169 switch_channel_set_variable(caller_channel, argv[i], val);
1170 }
3d136b26
AM
1171 }
1172 }
1173 }
1174 }
1175}
1176
1dcb3b67 1177
72ec7b59 1178static switch_status_t setup_ringback(originate_global_t *oglobals, originate_status_t *originate_status, int len,
886e1ddb 1179 const char *ringback_data, ringback_t *ringback, switch_frame_t *write_frame, switch_codec_t *write_codec)
757aa19e
AM
1180{
1181 switch_status_t status = SWITCH_STATUS_SUCCESS;
1182 switch_channel_t *caller_channel = switch_core_session_get_channel(oglobals->session);
1183 switch_codec_t *read_codec = NULL;
1184 char *tmp_data = NULL;
1185
757aa19e
AM
1186 if (!switch_channel_test_flag(caller_channel, CF_ANSWERED)
1187 && !switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA)) {
72ec7b59
MR
1188 if (oglobals->bridge_early_media > -1 && len == 1 && originate_status[0].peer_session &&
1189 switch_channel_media_ready(originate_status[0].peer_channel)) {
1190 inherit_codec(caller_channel, originate_status[0].peer_session);
1191 }
757aa19e 1192 if ((status = switch_channel_pre_answer(caller_channel)) != SWITCH_STATUS_SUCCESS) {
886e1ddb 1193 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_DEBUG, "%s Media Establishment Failed.\n",
757aa19e
AM
1194 switch_channel_get_name(caller_channel));
1195 switch_goto_status(SWITCH_STATUS_BREAK, end);
1196 }
1197 }
1198
1199 if (oglobals->session && (read_codec = switch_core_session_get_read_codec(oglobals->session))) {
8e75f82e 1200 if (ringback_data && switch_is_file_path(ringback_data)) {
757aa19e
AM
1201 if (!(strrchr(ringback_data, '.') || strstr(ringback_data, SWITCH_URL_SEPARATOR))) {
1202 ringback->asis++;
1203 }
72ec7b59
MR
1204 } else if (oglobals->bridge_early_media > -1 && zstr(ringback_data) && len == 1 && originate_status[0].peer_session) {
1205 switch_codec_implementation_t read_impl = { 0 }, write_impl = { 0 };
1206
1207 if (switch_channel_ready(originate_status[0].peer_channel)
1208 && switch_core_session_get_read_impl(originate_status[0].peer_session, &read_impl) == SWITCH_STATUS_SUCCESS
1209 && switch_core_session_get_write_impl(oglobals->session, &write_impl) == SWITCH_STATUS_SUCCESS) {
1210 if (read_impl.impl_id == write_impl.impl_id &&
1211 read_impl.microseconds_per_packet == write_impl.microseconds_per_packet &&
1212 read_impl.actual_samples_per_second == write_impl.actual_samples_per_second) {
1213 ringback->asis++;
1214 write_frame->codec = switch_core_session_get_write_codec(originate_status[0].peer_session);
1215 write_frame->datalen = write_frame->codec->implementation->decoded_bytes_per_packet;
1216 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_DEBUG, "bridge_early_media: passthrough enabled\n");
1217 } else {
1218 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_DEBUG, "bridge_early_media: codecs don't match (%s@%uh@%di / %s@%uh@%di)\n",
1219 read_impl.iananame, read_impl.actual_samples_per_second, read_impl.microseconds_per_packet / 1000,
1220 write_impl.iananame, write_impl.actual_samples_per_second, write_impl.microseconds_per_packet / 1000);
1221 }
1222 }
757aa19e 1223 }
886e1ddb 1224
757aa19e 1225 if (!ringback->asis) {
ef9af7dc
AM
1226 switch_codec_implementation_t peer_read_impl = { 0 };
1227
757aa19e 1228 if (switch_test_flag(read_codec, SWITCH_CODEC_FLAG_PASSTHROUGH)) {
886e1ddb 1229 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_WARNING, "%s Ringback not supported in passthrough codec mode.\n",
757aa19e
AM
1230 switch_channel_get_name(caller_channel));
1231 switch_goto_status(SWITCH_STATUS_GENERR, end);
1232 }
1233
155ecd96
AM
1234 if (oglobals->bridge_early_media > -1 && zstr(ringback_data) && len == 1 && originate_status[0].peer_session) {
1235 switch_core_session_get_read_impl(originate_status[0].peer_session, &peer_read_impl);
1236 } else {
1237 switch_core_session_get_read_impl(oglobals->session, &peer_read_impl);
1238 }
aa8f7c97 1239
757aa19e
AM
1240 if (switch_core_codec_init(write_codec,
1241 "L16",
1242 NULL,
ef9af7dc
AM
1243 peer_read_impl.actual_samples_per_second,
1244 peer_read_impl.microseconds_per_packet / 1000,
757aa19e
AM
1245 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
1246 switch_core_session_get_pool(oglobals->session)) == SWITCH_STATUS_SUCCESS) {
1247
1248
1249 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals->session), SWITCH_LOG_DEBUG,
1250 "Raw Codec Activation Success L16@%uhz 1 channel %dms\n",
ef9af7dc 1251 peer_read_impl.actual_samples_per_second, peer_read_impl.microseconds_per_packet / 1000);
757aa19e
AM
1252 write_frame->codec = write_codec;
1253 write_frame->datalen = read_codec->implementation->decoded_bytes_per_packet;
1254 write_frame->samples = write_frame->datalen / 2;
1255 memset(write_frame->data, 255, write_frame->datalen);
1256 switch_core_session_set_read_codec(oglobals->session, write_codec);
1257 } else {
1258 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_ERROR, "Codec Error!\n");
99c681f3 1259 switch_channel_hangup(caller_channel, SWITCH_CAUSE_BEARERCAPABILITY_NOTIMPL);
757aa19e
AM
1260 read_codec = NULL;
1261 switch_goto_status(SWITCH_STATUS_BREAK, end);
1262 }
886e1ddb 1263 }
757aa19e
AM
1264
1265 oglobals->gen_ringback = 1;
886e1ddb 1266
8e75f82e
AM
1267 if (zstr(ringback_data)) {
1268 switch_goto_status(SWITCH_STATUS_SUCCESS, end);
1269 }
757aa19e
AM
1270
1271 if (switch_is_file_path(ringback_data)) {
1272 char *ext;
1273
1274 if (ringback->asis) {
1275 write_frame->codec = read_codec;
1276 ext = read_codec->implementation->iananame;
1277 tmp_data = switch_mprintf("%s.%s", ringback_data, ext);
1278 ringback_data = tmp_data;
1279 }
1280
1281 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals->session), SWITCH_LOG_DEBUG, "Play Ringback File [%s]\n", ringback_data);
886e1ddb 1282
86c1dbee
AM
1283 if (switch_test_flag((&ringback->fhb), SWITCH_FILE_OPEN)) {
1284 switch_core_file_close(&ringback->fhb);
1285 }
1286
1287
757aa19e
AM
1288 ringback->fhb.channels = read_codec->implementation->number_of_channels;
1289 ringback->fhb.samplerate = read_codec->implementation->actual_samples_per_second;
1290 if (switch_core_file_open(&ringback->fhb,
1291 ringback_data,
1292 read_codec->implementation->number_of_channels,
1293 read_codec->implementation->actual_samples_per_second,
1294 SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
995ae262 1295 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals->session), SWITCH_LOG_ERROR, "Error Playing File\n");
757aa19e
AM
1296 switch_safe_free(tmp_data);
1297 switch_goto_status(SWITCH_STATUS_GENERR, end);
1298 //switch_goto_status(SWITCH_STATUS_FALSE, end);
1299 }
1300 ringback->fh = &ringback->fhb;
1301
1302 } else if (!strncasecmp(ringback_data, "silence", 7)) {
1303 const char *c = ringback_data + 7;
1304 if (*c == ':') {
1305 c++;
1306 if (c) {
1307 ringback->silence = atoi(c);
1308 }
1309 }
ba76388c 1310 SWITCH_IVR_VERIFY_SILENCE_DIVISOR(ringback->silence);
757aa19e
AM
1311 } else {
1312 switch_buffer_create_dynamic(&ringback->audio_buffer, 512, 1024, 0);
1313 switch_buffer_set_loops(ringback->audio_buffer, -1);
1314
1315 teletone_init_session(&ringback->ts, 0, teletone_handler, ringback);
1316 ringback->ts.rate = read_codec->implementation->actual_samples_per_second;
995ae262 1317 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals->session), SWITCH_LOG_DEBUG, "Play Ringback Tone [%s]\n", ringback_data);
757aa19e
AM
1318 /* ringback->ts.debug = 1;
1319 ringback->ts.debug_stream = switch_core_get_console(); */
886e1ddb 1320
757aa19e 1321 if (teletone_run(&ringback->ts, ringback_data)) {
995ae262 1322 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals->session), SWITCH_LOG_ERROR, "Error Playing Tone\n");
757aa19e
AM
1323 teletone_destroy_session(&ringback->ts);
1324 switch_buffer_destroy(&ringback->audio_buffer);
1325 switch_goto_status(SWITCH_STATUS_GENERR, end);
1326 }
1327 }
1328 }
886e1ddb
AM
1329
1330 end:
757aa19e
AM
1331
1332 switch_safe_free(tmp_data);
1333
1334 return status;
886e1ddb 1335
757aa19e
AM
1336}
1337
bc72d990 1338
06a68fce
AM
1339#define MAX_PEERS 128
1340
1341typedef struct {
1342 switch_core_session_t *session;
1343 switch_core_session_t *bleg;
1344 switch_call_cause_t cause;
2fa0c491 1345 switch_call_cause_t cancel_cause;
06a68fce
AM
1346 const char *bridgeto;
1347 uint32_t timelimit_sec;
1348 const switch_state_handler_table_t *table;
1349 const char *cid_name_override;
1350 const char *cid_num_override;
886e1ddb 1351 switch_caller_profile_t *caller_profile_override;
06a68fce
AM
1352 switch_event_t *ovars;
1353 switch_originate_flag_t flags;
1354 switch_status_t status;
1355 int done;
1356 switch_thread_t *thread;
2fa0c491 1357 switch_mutex_t *mutex;
06a68fce
AM
1358} enterprise_originate_handle_t;
1359
1360
ddc66126
AM
1361struct ent_originate_ringback {
1362 switch_core_session_t *session;
1363 int running;
1364 const char *ringback_data;
1365 switch_thread_t *thread;
1366};
1367
06a68fce
AM
1368static void *SWITCH_THREAD_FUNC enterprise_originate_thread(switch_thread_t *thread, void *obj)
1369{
1370 enterprise_originate_handle_t *handle = (enterprise_originate_handle_t *) obj;
886e1ddb 1371
06a68fce 1372 handle->done = 0;
973a39e0 1373 handle->status = switch_ivr_originate(NULL, &handle->bleg, &handle->cause,
06a68fce
AM
1374 handle->bridgeto, handle->timelimit_sec,
1375 handle->table,
1376 handle->cid_name_override,
886e1ddb 1377 handle->cid_num_override, handle->caller_profile_override, handle->ovars, handle->flags, &handle->cancel_cause);
06a68fce
AM
1378
1379
1380 handle->done = 1;
2fa0c491
AM
1381 switch_mutex_lock(handle->mutex);
1382 switch_mutex_unlock(handle->mutex);
886e1ddb 1383
2fa0c491 1384 if (handle->done != 2) {
7ec78e90 1385 if (handle->status == SWITCH_STATUS_SUCCESS && handle->bleg) {
945d1141
AM
1386 switch_channel_t *channel = switch_core_session_get_channel(handle->bleg);
1387
1388 switch_channel_set_variable(channel, "group_dial_status", "loser");
1389 switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE);
2fa0c491
AM
1390 switch_core_session_rwunlock(handle->bleg);
1391 }
1392 }
1393
06a68fce
AM
1394 return NULL;
1395}
1396
ddc66126
AM
1397static void *SWITCH_THREAD_FUNC enterprise_originate_ringback_thread(switch_thread_t *thread, void *obj)
1398{
1399 struct ent_originate_ringback *rb_data = (struct ent_originate_ringback *) obj;
1400 switch_core_session_t *session = rb_data->session;
1401 switch_channel_t *channel = switch_core_session_get_channel(rb_data->session);
1402 switch_status_t status = SWITCH_STATUS_FALSE;
1403
1404 switch_core_session_read_lock(session);
886e1ddb
AM
1405
1406 while (rb_data->running && switch_channel_ready(channel)) {
ae23edad 1407 switch_ivr_parse_all_messages(session);
ddc66126
AM
1408 if (status != SWITCH_STATUS_BREAK) {
1409 if (zstr(rb_data->ringback_data) || !strcasecmp(rb_data->ringback_data, "silence")) {
1410 status = switch_ivr_collect_digits_callback(session, NULL, 0, 0);
1411 } else if (switch_is_file_path(rb_data->ringback_data)) {
1412 status = switch_ivr_play_file(session, NULL, rb_data->ringback_data, NULL);
1413 } else {
1414 status = switch_ivr_gentones(session, rb_data->ringback_data, 0, NULL);
1415 }
1416 }
1417
1418 if (status == SWITCH_STATUS_BREAK) {
1419 switch_channel_set_flag(channel, CF_NOT_READY);
1420 }
1421 }
1422 switch_core_session_rwunlock(session);
1423
1424 rb_data->running = 0;
1425 return NULL;
1426}
1427
1428
06a68fce 1429SWITCH_DECLARE(switch_status_t) switch_ivr_enterprise_originate(switch_core_session_t *session,
ddc66126
AM
1430 switch_core_session_t **bleg,
1431 switch_call_cause_t *cause,
1432 const char *bridgeto,
1433 uint32_t timelimit_sec,
1434 const switch_state_handler_table_t *table,
1435 const char *cid_name_override,
1436 const char *cid_num_override,
886e1ddb 1437 switch_caller_profile_t *caller_profile_override,
2e9724d2
AM
1438 switch_event_t *ovars, switch_originate_flag_t flags,
1439 switch_call_cause_t *cancel_cause)
06a68fce 1440{
f882d83c 1441 int x_argc = 0;
06a68fce 1442 char *x_argv[MAX_PEERS] = { 0 };
886e1ddb 1443 enterprise_originate_handle_t *hp = NULL, handles[MAX_PEERS] = { {0} };
06a68fce
AM
1444 int i;
1445 switch_caller_profile_t *cp = NULL;
1446 switch_channel_t *channel = NULL;
1447 char *data;
1448 switch_status_t status = SWITCH_STATUS_FALSE;
1449 switch_threadattr_t *thd_attr = NULL;
2fa0c491 1450 int running = 0, over = 0;
06a68fce
AM
1451 switch_status_t tstatus = SWITCH_STATUS_FALSE;
1452 switch_memory_pool_t *pool;
1453 switch_event_header_t *hi = NULL;
ddc66126
AM
1454 struct ent_originate_ringback rb_data = { 0 };
1455 const char *ringback_data = NULL;
f882d83c 1456 switch_event_t *var_event = NULL;
02c24da0
AM
1457 int getcause = 1;
1458
1459 *cause = SWITCH_CAUSE_SUCCESS;
06a68fce
AM
1460
1461 switch_core_new_memory_pool(&pool);
1462
1463 if (zstr(bridgeto)) {
1464 *cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
02c24da0 1465 getcause = 0;
06a68fce
AM
1466 switch_goto_status(SWITCH_STATUS_FALSE, end);
1467 }
1468
1469 data = switch_core_strdup(pool, bridgeto);
1470
025c82e7
MOC
1471 if (session) {
1472 switch_caller_profile_t *cpp = NULL;
1473 channel = switch_core_session_get_channel(session);
1474 if ((cpp = switch_channel_get_caller_profile(channel))) {
1475 cp = switch_caller_profile_dup(pool, cpp);
1476 }
1477 }
1478
f882d83c
AM
1479 if (ovars) {
1480 var_event = ovars;
1481 } else {
1482 if (switch_event_create_plain(&var_event, SWITCH_EVENT_CHANNEL_DATA) != SWITCH_STATUS_SUCCESS) {
1483 abort();
1484 }
1485 }
1486
8cb2bad0
MR
1487 if (session) {
1488 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "ent_originate_aleg_uuid", switch_core_session_get_uuid(session));
1489 }
1490
4aa9a838 1491 if (channel) {
b1a3a106 1492 const char *tmp_var = NULL;
f8c029a1 1493
4aa9a838 1494 switch_channel_process_export(channel, NULL, var_event, SWITCH_EXPORT_VARS_VARIABLE);
f8c029a1 1495
b1a3a106
AM
1496 if ((tmp_var = switch_channel_get_variable(channel, "effective_ani"))) {
1497 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "origination_ani", tmp_var);
f8c029a1
AM
1498 }
1499
b1a3a106
AM
1500 if ((tmp_var = switch_channel_get_variable(channel, "effective_aniii"))) {
1501 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "origination_aniii", tmp_var);
1502 }
1503
1504 if ((tmp_var = switch_channel_get_variable(channel, "effective_caller_id_name"))) {
1505 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "origination_caller_id_name", tmp_var);
1506 }
1507
1508 if ((tmp_var = switch_channel_get_variable(channel, "effective_caller_id_number"))) {
1509 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "origination_caller_id_number", tmp_var);
f8c029a1 1510 }
4aa9a838 1511 }
4c4bf59e
AM
1512
1513 /* strip leading spaces */
1514 while (data && *data && *data == ' ') {
1515 data++;
1516 }
1517
1518 /* extract channel variables, allowing multiple sets of braces */
995ae262 1519 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Parsing ultra-global variables\n");
4c4bf59e
AM
1520 while (*data == '<') {
1521 char *parsed = NULL;
1522
1523 if (switch_event_create_brackets(data, '<', '>', ',', &var_event, &parsed, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS || !parsed) {
1524 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Parse Error!\n");
1525 switch_goto_status(SWITCH_STATUS_GENERR, done);
f882d83c 1526 }
4c4bf59e
AM
1527
1528 data = parsed;
1529 }
1530
1531 /* strip leading spaces (again) */
1532 while (data && *data && *data == ' ') {
1533 data++;
f882d83c
AM
1534 }
1535
cb6f5f39 1536 if (ovars && ovars != var_event) {
f882d83c
AM
1537 for (hi = ovars->headers; hi; hi = hi->next) {
1538 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, hi->name, hi->value);
1539 }
1540 }
1541
2fa0c491 1542 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "ignore_early_media", "true");
f882d83c 1543
bc72d990 1544 if (!(x_argc = switch_separate_string_string(data, SWITCH_ENT_ORIGINATE_DELIM, x_argv, MAX_PEERS))) {
06a68fce 1545 *cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
02c24da0 1546 getcause = 0;
06a68fce
AM
1547 switch_goto_status(SWITCH_STATUS_FALSE, end);
1548 }
1549
06a68fce
AM
1550 switch_threadattr_create(&thd_attr, pool);
1551 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
1552
886e1ddb 1553 for (i = 0; i < x_argc; i++) {
06a68fce
AM
1554 handles[i].session = session;
1555 handles[i].bleg = NULL;
1556 handles[i].cause = 0;
2fa0c491 1557 handles[i].cancel_cause = 0;
06a68fce
AM
1558 handles[i].bridgeto = x_argv[i];
1559 handles[i].timelimit_sec = timelimit_sec;
1560 handles[i].table = table;
1561 handles[i].cid_name_override = cid_name_override;
1562 handles[i].cid_num_override = cid_num_override;
1563 handles[i].caller_profile_override = cp;
886e1ddb 1564 switch_event_dup(&handles[i].ovars, var_event);
06a68fce 1565 handles[i].flags = flags;
2fa0c491
AM
1566 switch_mutex_init(&handles[i].mutex, SWITCH_MUTEX_NESTED, pool);
1567 switch_mutex_lock(handles[i].mutex);
06a68fce
AM
1568 switch_thread_create(&handles[i].thread, thd_attr, enterprise_originate_thread, &handles[i], pool);
1569 }
886e1ddb 1570
ddc66126
AM
1571 if (channel && !switch_channel_test_flag(channel, CF_PROXY_MODE) && !switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
1572 if (switch_channel_test_flag(channel, CF_ANSWERED)) {
1573 ringback_data = switch_channel_get_variable(channel, "transfer_ringback");
1574 }
886e1ddb 1575
ddc66126
AM
1576 if (!ringback_data) {
1577 ringback_data = switch_channel_get_variable(channel, "ringback");
1578 }
1579
1580 if (ringback_data || switch_channel_media_ready(channel)) {
1581 rb_data.ringback_data = ringback_data;
1582 rb_data.session = session;
1583 rb_data.running = 1;
1584 if (!switch_channel_media_ready(channel)) {
1585 if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
1586 goto done;
1587 }
1588 }
1589 switch_thread_create(&rb_data.thread, thd_attr, enterprise_originate_ringback_thread, &rb_data, pool);
1590 }
1591 }
1592
06a68fce 1593
886e1ddb 1594 for (;;) {
06a68fce 1595 running = 0;
2fa0c491 1596 over = 0;
886e1ddb 1597
ddc66126
AM
1598 if (channel && !switch_channel_ready(channel)) {
1599 break;
1600 }
06a68fce 1601
2e9724d2
AM
1602 if (cancel_cause && *cancel_cause > 0) {
1603 break;
1604 }
1605
886e1ddb 1606 for (i = 0; i < x_argc; i++) {
2fa0c491
AM
1607
1608
06a68fce
AM
1609 if (handles[i].done == 0) {
1610 running++;
1611 } else if (handles[i].done == 1) {
1612 if (handles[i].status == SWITCH_STATUS_SUCCESS) {
2fa0c491 1613 handles[i].done = 2;
06a68fce
AM
1614 hp = &handles[i];
1615 goto done;
1616 } else {
2fa0c491 1617 handles[i].done = -1;
06a68fce 1618 }
2fa0c491
AM
1619 } else {
1620 over++;
06a68fce 1621 }
2fa0c491
AM
1622
1623 switch_yield(10000);
06a68fce
AM
1624 }
1625
2fa0c491 1626 if (!running || over == x_argc) {
06a68fce
AM
1627 break;
1628 }
1629 }
1630
886e1ddb
AM
1631
1632 done:
06a68fce 1633
2fa0c491
AM
1634 if (hp) {
1635 *cause = hp->cause;
02c24da0 1636 getcause = 0;
2fa0c491
AM
1637 status = hp->status;
1638 *bleg = hp->bleg;
1639 switch_mutex_unlock(hp->mutex);
1640 switch_thread_join(&tstatus, hp->thread);
1641 switch_event_destroy(&hp->ovars);
ddc66126
AM
1642 }
1643
886e1ddb 1644 for (i = 0; i < x_argc; i++) {
2fa0c491 1645 if (hp == &handles[i]) {
06a68fce
AM
1646 continue;
1647 }
2e9724d2
AM
1648
1649 if (cancel_cause && *cancel_cause > 0) {
1650 handles[i].cancel_cause = *cancel_cause;
1651 } else {
1652 handles[i].cancel_cause = SWITCH_CAUSE_LOSE_RACE;
1653 }
2fa0c491 1654 }
06a68fce 1655
886e1ddb 1656 for (i = 0; i < x_argc; i++) {
6cdb4688
AM
1657
1658 if (channel) {
1659 switch_channel_handle_cause(channel, handles[i].cause);
1660 }
1661
2fa0c491
AM
1662 if (hp == &handles[i]) {
1663 continue;
1664 }
1665 switch_mutex_unlock(handles[i].mutex);
02c24da0 1666
631c976f 1667 if (getcause && *cause != handles[i].cause && handles[i].cause != SWITCH_CAUSE_LOSE_RACE && handles[i].cause != SWITCH_CAUSE_NO_PICKUP) {
02c24da0
AM
1668 *cause = handles[i].cause;
1669 getcause++;
1670 }
1671
06a68fce
AM
1672 switch_thread_join(&tstatus, handles[i].thread);
1673 switch_event_destroy(&handles[i].ovars);
1674 }
886e1ddb 1675
2fa0c491
AM
1676 if (channel && rb_data.thread) {
1677 switch_channel_set_flag(channel, CF_NOT_READY);
1678 switch_thread_join(&tstatus, rb_data.thread);
1679 switch_channel_clear_flag(channel, CF_NOT_READY);
06a68fce
AM
1680 }
1681
2fa0c491 1682
886e1ddb 1683 end:
06a68fce 1684
02c24da0
AM
1685 if (getcause == 1 && *cause == SWITCH_CAUSE_SUCCESS) {
1686 *cause = SWITCH_CAUSE_NO_ANSWER;
1687 }
1688
ef28a88c
AM
1689 if (channel) {
1690 if (*cause == SWITCH_CAUSE_SUCCESS) {
1691 switch_channel_set_variable(channel, "originate_disposition", "success");
1692 } else {
1693 switch_channel_set_variable(channel, "originate_disposition", "failure");
1694 switch_channel_set_variable(channel, "hangup_cause", switch_channel_cause2str(*cause));
1695 }
1696 }
1697
1698
f882d83c
AM
1699 if (var_event && var_event != ovars) {
1700 switch_event_destroy(&var_event);
1701 }
1702
06a68fce
AM
1703 switch_core_destroy_memory_pool(&pool);
1704
1705 return status;
1706
1707}
757aa19e 1708
5cc8aebc
AM
1709struct early_state {
1710 originate_global_t *oglobals;
1711 originate_status_t *originate_status;
1712 switch_mutex_t *mutex;
1713 switch_buffer_t *buffer;
1714 int ready;
72ec7b59 1715 ringback_t *ringback;
392c687f 1716 int ttl;
5cc8aebc
AM
1717};
1718typedef struct early_state early_state_t;
1719
1720
1721static void *SWITCH_THREAD_FUNC early_thread_run(switch_thread_t *thread, void *obj)
1722{
1723 early_state_t *state = (early_state_t *) obj;
886e1ddb
AM
1724 originate_status_t originate_status[MAX_PEERS] = { {0} };
1725 int16_t mux_data[SWITCH_RECOMMENDED_BUFFER_SIZE / 2] = { 0 };
5cc8aebc 1726 int32_t sample;
aa8f7c97 1727 switch_codec_t read_codecs[MAX_PEERS] = { {0} };
86c1dbee 1728 int i, x, ready = 0, answered = 0, ring_ready = 0;
5cc8aebc
AM
1729 int16_t *data;
1730 uint32_t datalen = 0;
1731 switch_status_t status;
ef723643 1732 switch_frame_t *read_frame = NULL;
aa8f7c97 1733 switch_codec_implementation_t read_impl = { 0 };
886e1ddb 1734
392c687f
AM
1735 for (i = 0; i < MAX_PEERS && i < state->ttl; i++) {
1736 if (switch_core_session_read_lock(state->originate_status[i].peer_session) == SWITCH_STATUS_SUCCESS) {
1737 originate_status[i].peer_session = state->originate_status[i].peer_session;
1738 originate_status[i].peer_channel = switch_core_session_get_channel(state->originate_status[i].peer_session);
1739 }
1740 }
1741
aa8f7c97
AM
1742 if (state->oglobals->session) {
1743 switch_core_session_get_read_impl(state->oglobals->session, &read_impl);
1744 }
886e1ddb 1745
5cc8aebc
AM
1746 while (state->ready) {
1747 datalen = 0;
1748 memset(mux_data, 0, sizeof(mux_data));
daab35e3
AM
1749 ready = 0;
1750 answered = 0;
1751
392c687f
AM
1752 for (i = 0; i < MAX_PEERS && i < state->ttl; i++) {
1753 switch_core_session_t *session = originate_status[i].peer_session;
1754 switch_channel_t *channel = originate_status[i].peer_channel;
1755
1756 if (!session) {
1757 break;
1758 }
1759
1760 if (!channel || !switch_channel_up(channel)) {
1761 continue;
1762 }
1763
5cc8aebc 1764 if (switch_channel_media_ready(channel)) {
daab35e3
AM
1765 ready++;
1766
86c1dbee
AM
1767 if (switch_channel_test_flag(channel, CF_RING_READY)) {
1768 ring_ready = 1;
1769 state->oglobals->bridge_early_media = -1;
1770 state->oglobals->ignore_early_media = 1;
1771 }
1772
daab35e3
AM
1773 if (switch_channel_test_flag(channel, CF_ANSWERED)) {
1774 answered++;
1775 }
886e1ddb 1776
72ec7b59
MR
1777 if (!state->ringback->asis) {
1778 if (!switch_core_codec_ready((&read_codecs[i]))) {
72ec7b59
MR
1779 if (switch_core_codec_init(&read_codecs[i],
1780 "L16",
1781 NULL,
aa8f7c97
AM
1782 read_impl.actual_samples_per_second,
1783 read_impl.microseconds_per_packet / 1000,
72ec7b59
MR
1784 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
1785 switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
1786 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Error!\n");
72ec7b59 1787 }
aa8f7c97
AM
1788 switch_core_session_set_read_codec(session, NULL);
1789 switch_core_session_set_read_codec(session, &read_codecs[i]);
5cc8aebc 1790 }
72ec7b59
MR
1791 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
1792 if (SWITCH_READ_ACCEPTABLE(status)) {
1793 data = (int16_t *) read_frame->data;
1794 if (datalen < read_frame->datalen) {
1795 datalen = read_frame->datalen;
1796 }
1797 for (x = 0; x < (int) read_frame->datalen / 2; x++) {
1798 sample = data[x] + mux_data[x];
1799 switch_normalize_to_16bit(sample);
1800 mux_data[x] = (int16_t) sample;
1801 }
5cc8aebc 1802 }
72ec7b59
MR
1803 } else {
1804 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
1805 if (SWITCH_READ_ACCEPTABLE(status)) {
1806 datalen = read_frame->datalen;
5cc8aebc 1807 }
72ec7b59 1808 break;
5cc8aebc
AM
1809 }
1810 }
1811 }
392c687f
AM
1812
1813 if (!ready || answered || ring_ready) {
1814 break;
1815 }
1816
1817 if (!datalen) {
1818 continue;
1819 }
1820
1821 if (state->ringback->asis) {
a110ae95 1822 uint16_t flen = (uint16_t)datalen;
72ec7b59
MR
1823 switch_mutex_lock(state->mutex);
1824 switch_buffer_write(state->buffer, &flen, sizeof(uint16_t));
1825 switch_buffer_write(state->buffer, read_frame->data, datalen);
1826 switch_mutex_unlock(state->mutex);
392c687f 1827 } else {
5cc8aebc
AM
1828 switch_mutex_lock(state->mutex);
1829 switch_buffer_write(state->buffer, mux_data, datalen);
1830 switch_mutex_unlock(state->mutex);
1831 }
1832 }
1833
1834
392c687f
AM
1835 for (i = 0; i < MAX_PEERS && i < state->ttl; i++) {
1836 switch_core_session_t *session = originate_status[i].peer_session;
1837 switch_channel_t *channel = originate_status[i].peer_channel;
1838
1839 if (!session) break;
1840
5cc8aebc
AM
1841 if (switch_core_codec_ready((&read_codecs[i]))) {
1842 switch_core_codec_destroy(&read_codecs[i]);
1843 }
392c687f
AM
1844
1845 if (switch_channel_up_nosig(channel)) {
1846 switch_core_session_reset(session, SWITCH_FALSE, SWITCH_TRUE);
1847 }
1848
5cc8aebc
AM
1849 switch_core_session_rwunlock(session);
1850 }
1851
86c1dbee
AM
1852 if (!ring_ready) {
1853 state->oglobals->early_ok = 1;
1854 }
daab35e3 1855
5cc8aebc
AM
1856 return NULL;
1857}
1858
aaeb69d6
AM
1859#define peer_eligible(_peer) (_peer && !(switch_channel_test_flag(_peer, CF_TRANSFER) || \
1860 switch_channel_test_flag(_peer, CF_REDIRECT) || \
1861 switch_channel_test_flag(_peer, CF_BRIDGED) || \
1862 switch_channel_get_state(_peer) == CS_RESET || \
1863 !switch_channel_test_flag(_peer, CF_ORIGINATING)))
1864
cc06fdb5
AM
1865static void wait_for_cause(switch_channel_t *channel)
1866{
1867 int sanity = 5;
1868
1869 while (--sanity > 0 && peer_eligible(channel) && switch_channel_get_cause(channel) == SWITCH_CAUSE_NONE) {
1870 switch_yield(10000);
1871 }
1872}
1873
1874
06a68fce 1875
e6a60a20
AM
1876SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *session,
1877 switch_core_session_t **bleg,
1878 switch_call_cause_t *cause,
622a2733 1879 const char *bridgeto,
e6a60a20
AM
1880 uint32_t timelimit_sec,
1881 const switch_state_handler_table_t *table,
3c349c27
AM
1882 const char *cid_name_override,
1883 const char *cid_num_override,
886e1ddb
AM
1884 switch_caller_profile_t *caller_profile_override,
1885 switch_event_t *ovars, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
e6a60a20 1886{
886e1ddb 1887 originate_status_t originate_status[MAX_PEERS] = { {0} };
1bb00325 1888 switch_originate_flag_t dftflags = SOF_NONE, myflags = dftflags;
e6a60a20
AM
1889 char *pipe_names[MAX_PEERS] = { 0 };
1890 char *data = NULL;
1891 switch_status_t status = SWITCH_STATUS_SUCCESS;
1892 switch_channel_t *caller_channel = NULL;
1893 char *peer_names[MAX_PEERS] = { 0 };
1dcb3b67
AM
1894 switch_core_session_t *new_session = NULL, *peer_session;
1895 switch_caller_profile_t *new_profile = NULL, *caller_caller_profile;
e6a60a20 1896 char *chan_type = NULL, *chan_data;
1dcb3b67 1897 switch_channel_t *peer_channel = NULL;
e6a60a20
AM
1898 ringback_t ringback = { 0 };
1899 time_t start;
1900 switch_frame_t *read_frame = NULL;
e6a60a20 1901 int r = 0, i, and_argc = 0, or_argc = 0;
1dcb3b67 1902 int32_t sleep_ms = 1000, try = 0, retries = 1;
e6a60a20
AM
1903 switch_codec_t write_codec = { 0 };
1904 switch_frame_t write_frame = { 0 };
1dcb3b67 1905 char *odata, *var;
98479fa6 1906 switch_call_cause_t reason = SWITCH_CAUSE_NONE;
aaeb69d6 1907 switch_call_cause_t force_reason = SWITCH_CAUSE_NONE;
e6a60a20 1908 uint8_t to = 0;
4c4bf59e 1909 char *var_val;
622a2733 1910 const char *ringback_data = NULL;
e6a60a20 1911 switch_event_t *var_event = NULL;
be43052c 1912 int8_t fail_on_single_reject = 0;
6cdb4688 1913 int8_t hangup_on_single_reject = 0;
4ed389f9 1914 char *fail_on_single_reject_var = NULL;
e6a60a20 1915 char *loop_data = NULL;
f33aa021 1916 uint32_t progress_timelimit_sec = 0;
f9642e96 1917 const char *cid_tmp, *lc;
1dcb3b67 1918 originate_global_t oglobals = { 0 };
2c0fe2dc 1919 int cdr_total = 0;
f9642e96 1920 int local_clobber = 0;
f8b442da 1921 const char *cancel_key = NULL;
aaeb69d6 1922 const char *holding = NULL;
450e63c0 1923 const char *soft_holding = NULL;
5cc8aebc 1924 early_state_t early_state = { 0 };
dfa54399 1925 int read_packet = 0;
cd736a1c 1926 int check_reject = 1;
00046ee0 1927 switch_codec_implementation_t read_impl = { 0 };
b1a3a106
AM
1928 const char *ani_override = NULL;
1929 const char *aniii_override = NULL;
e6758021
AM
1930 const char *ent_aleg_uuid = NULL;
1931 switch_core_session_t *a_session = session, *l_session = NULL;
3099445a
AM
1932
1933 if (session) {
e6758021
AM
1934 caller_channel = switch_core_session_get_channel(session);
1935
1936 if (switch_false(switch_channel_get_variable(caller_channel, "preserve_originated_vars"))) {
1937 switch_channel_set_variable(caller_channel, "originated_legs", NULL);
1938 switch_channel_set_variable(caller_channel, "originate_causes", NULL);
1939 }
3099445a
AM
1940 }
1941
dfa54399 1942
bc72d990 1943 if (strstr(bridgeto, SWITCH_ENT_ORIGINATE_DELIM)) {
06a68fce 1944 return switch_ivr_enterprise_originate(session, bleg, cause, bridgeto, timelimit_sec, table, cid_name_override, cid_num_override,
2e9724d2 1945 caller_profile_override, ovars, flags, cancel_cause);
06a68fce
AM
1946 }
1947
385a92ce 1948 oglobals.check_vars = SWITCH_TRUE;
757aa19e 1949 oglobals.ringback_ok = 1;
8e75f82e 1950 oglobals.bridge_early_media = -1;
329033ee
AM
1951 oglobals.file = NULL;
1952 oglobals.error_file = NULL;
cca9c367
AM
1953 switch_core_new_memory_pool(&oglobals.pool);
1954
1955 if (caller_profile_override) {
1956 oglobals.caller_profile_override = switch_caller_profile_dup(oglobals.pool, caller_profile_override);
1957 } else if (session) {
e6758021 1958 switch_caller_profile_t *cp = switch_channel_get_caller_profile(caller_channel);
cca9c367
AM
1959
1960 if (cp) {
1961 oglobals.caller_profile_override = switch_caller_profile_dup(oglobals.pool, cp);
1962 }
1963 }
757aa19e 1964
d9fb89d2 1965 if (session) {
23f8967c 1966 const char *to_var, *bypass_media = NULL, *proxy_media = NULL, *zrtp_passthru = NULL;
aaeb69d6 1967 switch_channel_set_flag(caller_channel, CF_ORIGINATOR);
d9fb89d2
AM
1968 oglobals.session = session;
1969
4baec065
AM
1970 switch_channel_execute_on(caller_channel, SWITCH_CHANNEL_EXECUTE_ON_PRE_ORIGINATE_VARIABLE);
1971 switch_channel_api_on(caller_channel, SWITCH_CHANNEL_API_ON_PRE_ORIGINATE_VARIABLE);
1972
00046ee0 1973 switch_core_session_get_read_impl(session, &read_impl);
5b6d1cd3
AM
1974
1975 if ((to_var = switch_channel_get_variable(caller_channel, SWITCH_CALL_TIMEOUT_VARIABLE))) {
1976 timelimit_sec = atoi(to_var);
1977 }
1978
6151c4aa
AM
1979 proxy_media = switch_channel_get_variable(caller_channel, SWITCH_PROXY_MEDIA_VARIABLE);
1980 bypass_media = switch_channel_get_variable(caller_channel, SWITCH_BYPASS_MEDIA_VARIABLE);
23f8967c 1981 zrtp_passthru = switch_channel_get_variable(caller_channel, SWITCH_ZRTP_PASSTHRU_VARIABLE);
6151c4aa 1982
98edcdb3
AM
1983 if (!zstr(proxy_media)) {
1984 if (switch_true(proxy_media)) {
1985 switch_channel_set_flag(caller_channel, CF_PROXY_MEDIA);
1986 } else if (switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA)) {
1987 switch_channel_clear_flag(caller_channel, CF_PROXY_MEDIA);
1988 }
6151c4aa 1989 }
98edcdb3 1990
23f8967c
TC
1991 if (!zstr(zrtp_passthru)) {
1992 if (switch_true(zrtp_passthru)) {
1993 switch_channel_set_flag(caller_channel, CF_ZRTP_PASSTHRU_REQ);
1994 } else if (switch_channel_test_flag(caller_channel, CF_ZRTP_PASSTHRU_REQ)) {
1995 switch_channel_clear_flag(caller_channel, CF_ZRTP_PASSTHRU_REQ);
1996 }
1997 }
1998
a0c641ae
AM
1999 if (bypass_media && switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA) && !switch_channel_test_flag(caller_channel, CF_ANSWERED)) {
2000 switch_core_session_message_t msg = { 0 };
2001
2002 msg.message_id = SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS;
2003 msg.from = __FILE__;
2004 switch_core_session_receive_message(session, &msg);
2005 }
2006
2007
468956e1 2008 if (!zstr(bypass_media) && !switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA)) {
98edcdb3
AM
2009 if (switch_true(bypass_media)) {
2010 switch_channel_set_flag(caller_channel, CF_PROXY_MODE);
2011 } else if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE)) {
468956e1
AM
2012 if (!switch_channel_test_flag(caller_channel, CF_ANSWERED) && switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA)) {
2013 switch_channel_set_variable(caller_channel, SWITCH_B_SDP_VARIABLE, NULL);
2014 switch_channel_answer(caller_channel);
2015 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
2016 "Must answer channel %s due to SIP PARADOX\n", switch_channel_get_name(caller_channel));
2017 }
2018 switch_channel_set_variable(caller_channel, SWITCH_B_SDP_VARIABLE, NULL);
98edcdb3
AM
2019 switch_ivr_media(switch_core_session_get_uuid(session), SMF_NONE);
2020 }
d9fb89d2 2021 }
2cc59f1e
AM
2022
2023 if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE) && switch_channel_test_flag(caller_channel, CF_ANSWERED)) {
886e1ddb 2024 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
6151c4aa
AM
2025 "Channel is already up, delaying proxy mode 'till both legs are answered.\n");
2026 switch_channel_set_variable(caller_channel, "bypass_media_after_bridge", "true");
2027 switch_channel_set_variable(caller_channel, SWITCH_BYPASS_MEDIA_VARIABLE, NULL);
2028 switch_channel_clear_flag(caller_channel, CF_PROXY_MODE);
d9fb89d2
AM
2029 }
2030 }
2031
5b6d1cd3
AM
2032 if (timelimit_sec <= 0) {
2033 timelimit_sec = 60;
2034 }
2035
886e1ddb 2036
1dcb3b67
AM
2037 oglobals.idx = IDX_NADA;
2038 oglobals.early_ok = 1;
d9fb89d2 2039
4f670da1
AM
2040 *bleg = NULL;
2041
a8023642 2042 switch_zmalloc(write_frame.data, SWITCH_RECOMMENDED_BUFFER_SIZE);
3608c834 2043 write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
e6a60a20 2044
e6a60a20 2045 odata = strdup(bridgeto);
577afaf6
MJ
2046
2047 if (!odata) {
c2d5f970 2048 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Memory Error!\n");
577afaf6
MJ
2049 status = SWITCH_STATUS_MEMERR;
2050 goto done;
2051 }
2052
e6a60a20
AM
2053 data = odata;
2054
e6a60a20
AM
2055
2056 /* Some channel are created from an originating channel and some aren't so not all outgoing calls have a way to get params
2057 so we will normalize dialstring params and channel variables (when there is an originator) into an event that we
2058 will use as a pseudo hash to consult for params as needed.
886e1ddb 2059 */
a579a283
AM
2060
2061 if (ovars) {
2062 var_event = ovars;
2063 } else {
cdd0bcfd 2064 if (switch_event_create_plain(&var_event, SWITCH_EVENT_CHANNEL_DATA) != SWITCH_STATUS_SUCCESS) {
a579a283
AM
2065 abort();
2066 }
e6a60a20
AM
2067 }
2068
e6758021
AM
2069 ent_aleg_uuid = switch_event_get_header(var_event, "ent_originate_aleg_uuid");
2070
38e3f5fe
MOC
2071 if (caller_channel) {
2072 switch_channel_process_export(caller_channel, NULL, var_event, SWITCH_EXPORT_VARS_VARIABLE);
2073 }
2074
4c4bf59e
AM
2075 /* strip leading spaces */
2076 while (data && *data && *data == ' ') {
2077 data++;
2078 }
2079
385a92ce
AM
2080 if ((ovars && switch_true(switch_event_get_header(ovars,"origination_nested_vars"))) ||
2081 (caller_channel && switch_true(switch_channel_get_variable(caller_channel, "origination_nested_vars")))
2082 || switch_true(switch_core_get_variable("origination_nested_vars")) || switch_stristr("origination_nested_vars=true", data)) {
2083 oglobals.check_vars = SWITCH_FALSE;
2084 }
2085
456b07eb
AM
2086
2087 /* extract channel variables, allowing multiple sets of braces */
2088 if (*data == '<') {
2089 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Parsing ultra-global variables\n");
2090 while (*data == '<') {
2091 char *parsed = NULL;
2092
2093 if (switch_event_create_brackets(data, '<', '>', ',', &var_event, &parsed, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS || !parsed) {
2094 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Parse Error!\n");
2095 switch_goto_status(SWITCH_STATUS_GENERR, done);
2096 }
2097
2098 data = parsed;
2099 }
2100 }
2101
4c4bf59e 2102 /* extract channel variables, allowing multiple sets of braces */
995ae262 2103 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Parsing global variables\n");
4c4bf59e
AM
2104 while (*data == '{') {
2105 char *parsed = NULL;
2106
2107 if (switch_event_create_brackets(data, '{', '}', ',', &var_event, &parsed, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS || !parsed) {
2108 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Parse Error!\n");
2109 switch_goto_status(SWITCH_STATUS_GENERR, done);
418d6027 2110 }
4c4bf59e
AM
2111
2112 data = parsed;
418d6027
MR
2113 }
2114
4c4bf59e
AM
2115
2116 /* strip leading spaces (again) */
2117 while (data && *data && *data == ' ') {
2118 data++;
2119 }
2120
2121 if (zstr(data)) {
2122 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "No origination URL specified!\n");
2123 status = SWITCH_STATUS_GENERR;
2124 goto done;
2125 }
2126
9aaaeb72 2127 if (!(flags & SOF_NOBLOCK) && var_event && (var = switch_event_get_header(var_event, "originate_delay_start"))) {
032761c0
AM
2128 int tmp = atoi(var);
2129 if (tmp > 0) {
2130 while (tmp && (!cancel_cause || *cancel_cause == 0)) {
2131 switch_cond_next();
2132 tmp--;
2133 }
2134 }
2135 }
2136
1dcb3b67 2137 if (oglobals.session) {
ffb989e4 2138 switch_event_header_t *hi;
2c0fe2dc 2139 const char *cdr_total_var;
f6954530 2140 const char *cdr_var;
864598ca 2141 const char *json_cdr_var;
f6954530 2142
a3960e9a 2143 if ((cdr_var = switch_channel_get_variable(caller_channel, "failed_xml_cdr_prefix"))) {
f6954530
AM
2144 char buf[128] = "";
2145 switch_snprintf(buf, sizeof(buf), "%s_total", cdr_var);
2146 if ((cdr_total_var = switch_channel_get_variable(caller_channel, buf))) {
2147 int tmp = atoi(cdr_total_var);
2148 if (tmp > 0) {
2149 cdr_total = tmp;
2150 }
2c0fe2dc
AM
2151 }
2152 }
886e1ddb 2153
864598ca
AM
2154 if ((json_cdr_var = switch_channel_get_variable(caller_channel, "failed_json_cdr_prefix"))) {
2155 char buf[128] = "";
2156 switch_snprintf(buf, sizeof(buf), "%s_total", json_cdr_var);
2157 if ((cdr_total_var = switch_channel_get_variable(caller_channel, buf))) {
2158 int tmp = atoi(cdr_total_var);
2159 if (tmp > 0) {
2160 cdr_total = tmp;
2161 }
2162 }
2163 }
2c0fe2dc 2164
418d6027 2165 /* Copy all the missing applicable channel variables from A-leg into the event */
ffb989e4
AM
2166 if ((hi = switch_channel_variable_first(caller_channel))) {
2167 for (; hi; hi = hi->next) {
98d9028b 2168 int ok = 0;
3c349c27 2169 if (!strcasecmp((char *) hi->name, "group_confirm_key")) {
98d9028b 2170 ok = 1;
3c349c27 2171 } else if (!strcasecmp((char *) hi->name, "group_confirm_file")) {
98d9028b 2172 ok = 1;
0b992a2b
AM
2173 } else if (!strcasecmp((char *) hi->name, "group_confirm_read_timeout")) {
2174 ok = 1;
d8793904 2175 } else if (!strcasecmp((char *) hi->name, "group_confirm_cancel_timeout")) {
bdf8f594 2176 ok = 1;
3c349c27 2177 } else if (!strcasecmp((char *) hi->name, "forked_dial")) {
21da7429 2178 ok = 1;
3c349c27 2179 } else if (!strcasecmp((char *) hi->name, "fail_on_single_reject")) {
98d9028b 2180 ok = 1;
6cdb4688
AM
2181 } else if (!strcasecmp((char *) hi->name, "hangup_on_single_reject")) {
2182 ok = 1;
3c349c27 2183 } else if (!strcasecmp((char *) hi->name, "ignore_early_media")) {
98d9028b 2184 ok = 1;
8e75f82e
AM
2185 } else if (!strcasecmp((char *) hi->name, "bridge_early_media")) {
2186 ok = 1;
5b6d1cd3
AM
2187 } else if (!strcasecmp((char *) hi->name, "originate_continue_on_timeout")) {
2188 ok = 1;
effb166b
AM
2189 } else if (!strcasecmp((char *) hi->name, "ignore_ring_ready")) {
2190 ok = 1;
697bb6ec
AM
2191 } else if (!strcasecmp((char *) hi->name, "monitor_early_media_ring")) {
2192 ok = 1;
ba77f232
AM
2193 } else if (!strcasecmp((char *) hi->name, "monitor_early_media_ring_total")) {
2194 ok = 1;
697bb6ec
AM
2195 } else if (!strcasecmp((char *) hi->name, "monitor_early_media_fail")) {
2196 ok = 1;
3c349c27 2197 } else if (!strcasecmp((char *) hi->name, "return_ring_ready")) {
d6f0cec8 2198 ok = 1;
c01e6fe6
AM
2199 } else if (!strcasecmp((char *) hi->name, "ring_ready")) {
2200 ok = 1;
bcb20f7a
AM
2201 } else if (!strcasecmp((char *) hi->name, "instant_ringback")) {
2202 ok = 1;
f33aa021
AM
2203 } else if (!strcasecmp((char *) hi->name, "progress_timeout")) {
2204 ok = 1;
3daaaf0c
MR
2205 } else if (!strcasecmp((char *) hi->name, "language")) {
2206 ok = 1;
98d9028b
AM
2207 }
2208
418d6027 2209 if (ok && !switch_event_get_header(var_event, hi->name)) {
f9213890 2210 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, (char *) hi->name, (char *) hi->value);
98d9028b 2211 }
ffb989e4
AM
2212 }
2213 switch_channel_variable_last(caller_channel);
2214 }
2215 /*
886e1ddb 2216 if ((hi = switch_channel_variable_first(caller_channel))) {
5c0cff70 2217 for (; hi; hi = switch_core_hash_next(&hi)) {
804ef770 2218 switch_core_hash_this(hi, &vvar, NULL, &vval);
886e1ddb
AM
2219 if (vvar && vval) {
2220 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, (void *) vvar, (char *) vval);
2221 }
2222 }
2223 switch_channel_variable_last(caller_channel);
2224 }
2225 */
e6a60a20
AM
2226 }
2227
e6a60a20 2228 if (caller_channel) { /* ringback is only useful when there is an originator */
8433c7e0 2229 ringback_data = NULL;
f8b442da 2230 cancel_key = switch_channel_get_variable(caller_channel, "origination_cancel_key");
8433c7e0 2231
50fc2ffa 2232 if (switch_channel_test_flag(caller_channel, CF_ANSWERED)) {
8433c7e0 2233 ringback_data = switch_channel_get_variable(caller_channel, "transfer_ringback");
3c349c27
AM
2234 }
2235
8433c7e0
AM
2236 if (!ringback_data) {
2237 ringback_data = switch_channel_get_variable(caller_channel, "ringback");
2238 }
3c349c27 2239
e6a60a20 2240 switch_channel_set_variable(caller_channel, "originate_disposition", "failure");
9d98d49f 2241 switch_channel_set_variable(caller_channel, "DIALSTATUS", "INVALIDARGS");
f29513f3
AM
2242
2243 if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE) || switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA)) {
2244 ringback_data = NULL;
2245 }
2246 }
78bc4172
AM
2247#if 0
2248 /* changing behaviour ignore_early_media=true must also be explicitly set for previous behaviour */
f29513f3 2249 if (ringback_data) {
1dcb3b67 2250 oglobals.early_ok = 0;
e6a60a20 2251 }
78bc4172 2252#endif
e6a60a20 2253
bdf8f594
AM
2254 if (switch_true(switch_event_get_header(var_event, "group_confirm_cancel_timeout"))) {
2255 oglobals.cancel_timeout = -1;
2256 }
2257
e6a60a20 2258 if ((var = switch_event_get_header(var_event, "group_confirm_key"))) {
1dcb3b67 2259 switch_copy_string(oglobals.key, var, sizeof(oglobals.key));
e6a60a20 2260 if ((var = switch_event_get_header(var_event, "group_confirm_file"))) {
329033ee 2261 oglobals.file = strdup(var);
e6a60a20 2262 }
2d47baee 2263 if ((var = switch_event_get_header(var_event, "group_confirm_error_file"))) {
329033ee 2264 oglobals.error_file = strdup(var);
2d47baee
AM
2265 }
2266 if ((var = switch_event_get_header(var_event, "group_confirm_read_timeout"))) {
2267 int tmp = atoi(var);
2268
2269 if (tmp >= 0) {
2270 oglobals.confirm_timeout = tmp;
2271 }
2272
2273 }
e6a60a20 2274 }
edc3f650 2275 /* When using the AND operator, the fail_on_single_reject flag may be set in order to indicate that a single
4ed389f9
AM
2276 rejections should terminate the attempt rather than a timeout, answer, or rejection by all.
2277 If the value is set to 'true' any fail cause will end the attempt otherwise it can contain a comma (,) separated
2278 list of cause names which should be considered fatal
886e1ddb 2279 */
6cdb4688
AM
2280 if ((var = switch_event_get_header(var_event, "hangup_on_single_reject"))) {
2281 hangup_on_single_reject = 1;
2282 }
2283
2284 if (hangup_on_single_reject || (var = switch_event_get_header(var_event, "fail_on_single_reject"))) {
4ed389f9 2285 fail_on_single_reject_var = strdup(var);
cd736a1c
AM
2286 if (switch_true(var)) {
2287 fail_on_single_reject = 1;
2288 } else {
2289 fail_on_single_reject = -1;
2290 }
e6a60a20
AM
2291 }
2292
329033ee
AM
2293 if ((!zstr(oglobals.file)) && (!strcmp(oglobals.file, "undef"))) {
2294 switch_safe_free(oglobals.file);
2295 oglobals.file = NULL;
e6a60a20 2296 }
329033ee
AM
2297 if ((!zstr(oglobals.error_file)) && (!strcmp(oglobals.error_file, "undef"))) {
2298 switch_safe_free(oglobals.error_file);
2299 oglobals.error_file = NULL;
2d47baee
AM
2300 }
2301
8e75f82e
AM
2302 if ((var_val = switch_event_get_header(var_event, "bridge_early_media"))) {
2303 if (switch_true(var_val)) {
2304 oglobals.early_ok = 0;
2305 oglobals.ignore_early_media = 3;
2306 }
2307 }
2308
e072a609
AM
2309 if ((var_val = switch_event_get_header(var_event, "ignore_early_media"))) {
2310 if (switch_true(var_val)) {
2311 oglobals.early_ok = 0;
2312 oglobals.ignore_early_media = 1;
fea44bb2
AM
2313 } else if (!strcmp(var_val, "consume")) {
2314 oglobals.early_ok = 0;
2315 oglobals.ignore_early_media = 4;
e072a609
AM
2316 } else if (!strcmp(var_val, "ring_ready")) {
2317 oglobals.early_ok = 0;
2318 oglobals.ignore_early_media = 2;
2319 }
effb166b
AM
2320 }
2321
5b6d1cd3
AM
2322 if ((var_val = switch_event_get_header(var_event, "originate_continue_on_timeout")) && switch_true(var_val)) {
2323 oglobals.continue_on_timeout = 1;
2324 }
2325
effb166b
AM
2326 if ((var_val = switch_event_get_header(var_event, "ignore_ring_ready")) && switch_true(var_val)) {
2327 oglobals.ignore_ring_ready = 1;
e6a60a20
AM
2328 }
2329
697bb6ec
AM
2330 if ((var_val = switch_event_get_header(var_event, "monitor_early_media_ring"))) {
2331 oglobals.early_ok = 0;
2332 oglobals.monitor_early_media_ring = 1;
2333 }
2334
2335 if ((var_val = switch_event_get_header(var_event, "monitor_early_media_fail"))) {
2336 oglobals.early_ok = 0;
2337 oglobals.monitor_early_media_fail = 1;
2338 }
2339
d6f0cec8 2340 if ((var_val = switch_event_get_header(var_event, "return_ring_ready")) && switch_true(var_val)) {
1dcb3b67 2341 oglobals.return_ring_ready = 1;
d6f0cec8
AM
2342 }
2343
c01e6fe6 2344 if ((var_val = switch_event_get_header(var_event, "ring_ready")) && switch_true(var_val)) {
0b0ce769 2345 oglobals.ring_ready = 1;
c01e6fe6
AM
2346 }
2347
bcb20f7a
AM
2348 if ((var_val = switch_event_get_header(var_event, "instant_ringback")) && switch_true(var_val)) {
2349 oglobals.instant_ringback = 1;
2350 }
2351
f33aa021 2352 if ((var_val = switch_event_get_header(var_event, "originate_timeout"))) {
8da5afec
AM
2353 int tmp = atoi(var_val);
2354 if (tmp > 0) {
2355 timelimit_sec = (uint32_t) tmp;
2356 }
2357 }
2358
f33aa021
AM
2359 if ((var_val = switch_event_get_header(var_event, "progress_timeout"))) {
2360 int tmp = atoi(var_val);
2361 if (tmp > 0) {
2362 progress_timelimit_sec = (uint32_t) tmp;
2363 }
2364 }
2365
e6a60a20
AM
2366 if ((var_val = switch_event_get_header(var_event, "originate_retries")) && switch_true(var_val)) {
2367 int32_t tmp;
2368 tmp = atoi(var_val);
2369 if (tmp > 0 && tmp < 101) {
2370 retries = tmp;
2371 } else {
c2d5f970 2372 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
debdfb1a 2373 "Invalid originate_retries setting of %d ignored, value must be between 1 and 100\n", tmp);
e6a60a20
AM
2374 }
2375 }
2376
2377 if ((var_val = switch_event_get_header(var_event, "originate_retry_sleep_ms")) && switch_true(var_val)) {
2378 int32_t tmp;
2379 tmp = atoi(var_val);
8e7bbff3 2380 if (tmp >= 500 && tmp <= 60000) {
e6a60a20
AM
2381 sleep_ms = tmp;
2382 } else {
c2d5f970 2383 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
debdfb1a 2384 "Invalid originate_retry_sleep_ms setting of %d ignored, value must be between 500 and 60000\n", tmp);
e6a60a20
AM
2385 }
2386 }
2387
b1a3a106
AM
2388 /* variable to force ANI / ANIII */
2389 ani_override = switch_event_get_header(var_event, "origination_ani");
2390 aniii_override = switch_event_get_header(var_event, "origination_aniii");
2391
1bb00325
AM
2392 if ((cid_tmp = switch_event_get_header(var_event, "origination_caller_id_name"))) {
2393 cid_name_override = cid_tmp;
2394 }
2395
f045bb9a 2396 if (cid_name_override) {
9c7fb0d4
AM
2397 if (!cid_tmp) {
2398 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "origination_caller_id_name", cid_name_override);
2399 }
f045bb9a 2400 } else {
e6a60a20
AM
2401 cid_name_override = switch_event_get_header(var_event, "origination_caller_id_name");
2402 }
2403
1bb00325
AM
2404 if ((cid_tmp = switch_event_get_header(var_event, "origination_caller_id_number"))) {
2405 cid_num_override = cid_tmp;
2406 }
2407
f045bb9a 2408 if (cid_num_override) {
9c7fb0d4
AM
2409 if (!cid_tmp) {
2410 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "origination_caller_id_number", cid_num_override);
2411 }
f045bb9a 2412 } else {
e6a60a20
AM
2413 cid_num_override = switch_event_get_header(var_event, "origination_caller_id_number");
2414 }
2415
46c6650a
AM
2416 if (flags & SOF_NO_LIMITS) {
2417 dftflags |= SOF_NO_LIMITS;
2418 }
2419
b1a3a106
AM
2420 if (ani_override) {
2421 dftflags |= SOF_NO_EFFECTIVE_ANI;
2422 }
2423
2424 if (aniii_override) {
2425 dftflags |= SOF_NO_EFFECTIVE_ANIII;
2426 }
2427
1bb00325
AM
2428 if (cid_num_override) {
2429 dftflags |= SOF_NO_EFFECTIVE_CID_NUM;
2430 }
46c6650a 2431
1bb00325
AM
2432 if (cid_name_override) {
2433 dftflags |= SOF_NO_EFFECTIVE_CID_NAME;
2434 }
2435
f33aa021
AM
2436 if (!progress_timelimit_sec) {
2437 progress_timelimit_sec = timelimit_sec;
2438 }
2439
e6a60a20
AM
2440 for (try = 0; try < retries; try++) {
2441 switch_safe_free(loop_data);
76bdd0b3 2442 loop_data = strdup(data);
55a194e5 2443 switch_assert(loop_data);
e6a60a20
AM
2444 or_argc = switch_separate_string(loop_data, '|', pipe_names, (sizeof(pipe_names) / sizeof(pipe_names[0])));
2445
8433c7e0 2446 if ((flags & SOF_NOBLOCK) && or_argc > 1) {
c2d5f970 2447 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Only calling the first element in the list in this mode.\n");
8433c7e0
AM
2448 or_argc = 1;
2449 }
886e1ddb 2450
de9714d7 2451 for (r = 0; r < or_argc && (!cancel_cause || *cancel_cause == 0); r++) {
2d764cc0 2452 char *p, *end = NULL;
4c4bf59e
AM
2453 int q = 0, alt = 0;
2454
cd736a1c
AM
2455 check_reject = 1;
2456
dc2a354c 2457 oglobals.hups = 0;
886e1ddb 2458
98479fa6 2459 reason = SWITCH_CAUSE_NONE;
e6a60a20
AM
2460 memset(peer_names, 0, sizeof(peer_names));
2461 peer_session = NULL;
1dcb3b67 2462 memset(originate_status, 0, sizeof(originate_status));
bf7144b2
AM
2463 new_profile = NULL;
2464 new_session = NULL;
e6a60a20
AM
2465 chan_type = NULL;
2466 chan_data = NULL;
2467 peer_channel = NULL;
2468 start = 0;
2469 read_frame = NULL;
757aa19e 2470 oglobals.ringback_ok = 1;
e6a60a20
AM
2471 var = NULL;
2472 to = 0;
1dcb3b67
AM
2473 oglobals.sent_ring = 0;
2474 oglobals.progress = 0;
1bb00325 2475 myflags = dftflags;
bfe31288 2476
886e1ddb 2477
e6a60a20 2478 if (try > 0) {
886e1ddb
AM
2479 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Originate attempt %d/%d in %d ms\n", try + 1, retries,
2480 sleep_ms);
4c44541e 2481 if (caller_channel) {
1dcb3b67 2482 switch_ivr_sleep(oglobals.session, sleep_ms, SWITCH_TRUE, NULL);
4a750282
AM
2483 if (!switch_channel_ready(caller_channel)) {
2484 status = SWITCH_STATUS_FALSE;
79de78a0
BW
2485 /* set try and retries to 0 */
2486 try = 0;
2487 retries = 0;
4a750282
AM
2488 goto done;
2489 }
4c44541e
AM
2490 } else {
2491 switch_yield(sleep_ms * 1000);
2492 }
e6a60a20 2493 }
4c4bf59e 2494
6eebc864 2495 p = pipe_names[r];
4c4bf59e 2496
886e1ddb 2497 while (p && *p) {
6eebc864 2498 if (*p == '[') {
2d764cc0 2499 end = switch_find_end_paren(p, '[', ']');
4c4bf59e
AM
2500 if (*(p+1) == '^' && *(p + 2) == '^') {
2501 alt = 1;
2502 } else {
2503 alt = 0;
2504 }
2505 q = 0;
6eebc864 2506 }
4c4bf59e 2507
bfe31288
AM
2508 if (*p == '\'') {
2509 q = !q;
2510 }
2511
dca6e2bb 2512 if (end && p < end && *p == ',' && *(p-1) != '\\') {
4c4bf59e
AM
2513
2514 if (q || alt) {
bfe31288
AM
2515 *p = QUOTED_ESC_COMMA;
2516 } else {
2517 *p = UNQUOTED_ESC_COMMA;
2518 }
6eebc864 2519 }
e6a60a20 2520
2d764cc0 2521 if (p == end) {
1fba6548 2522 end = switch_strchr_strict(p, '[', " ");
6eebc864
AM
2523 }
2524
2525 p++;
2526 }
886e1ddb 2527
debdfb1a 2528 and_argc = switch_separate_string(pipe_names[r], ',', peer_names, (sizeof(peer_names) / sizeof(peer_names[0])));
e6a60a20 2529
8433c7e0 2530 if ((flags & SOF_NOBLOCK) && and_argc > 1) {
c2d5f970 2531 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Only calling the first element in the list in this mode.\n");
8433c7e0
AM
2532 and_argc = 1;
2533 }
3c349c27 2534
e6a60a20 2535 for (i = 0; i < and_argc; i++) {
dfda1d8f 2536 const char *current_variable;
4b5cdd87 2537 switch_event_t *local_var_event = NULL, *originate_var_event = NULL;
3fbd9e21 2538
863e1c70 2539 end = NULL;
9c7fb0d4 2540
863e1c70 2541 chan_type = peer_names[i];
3fbd9e21 2542
4c4bf59e
AM
2543
2544 /* strip leading spaces */
5c5c3251
AM
2545 while (chan_type && *chan_type && *chan_type == ' ') {
2546 chan_type++;
2547 }
4c4bf59e
AM
2548
2549 /* extract channel variables, allowing multiple sets of braces */
2550
2551 if (*chan_type == '[') {
2552 switch_event_create_plain(&local_var_event, SWITCH_EVENT_CHANNEL_DATA);
995ae262 2553 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Parsing session specific variables\n");
4c4bf59e 2554 }
5c5c3251 2555
4c4bf59e
AM
2556 while (*chan_type == '[') {
2557 char *parsed = NULL;
6ec4514c
AM
2558 char *bend = switch_find_end_paren(chan_type, '[', ']');
2559
2560 for (p = chan_type + 1; p && p < bend && *p; p++) {
4c4bf59e
AM
2561 if (*p == QUOTED_ESC_COMMA) {
2562 *p = ',';
2563 }
2564 }
2565
2566 if (switch_event_create_brackets(chan_type, '[', ']', UNQUOTED_ESC_COMMA,
2567 &local_var_event, &parsed, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS || !parsed) {
2568 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Parse Error!\n");
2569 switch_goto_status(SWITCH_STATUS_GENERR, done);
9c7fb0d4 2570 }
6ec4514c
AM
2571
2572 if (chan_type == parsed) {
2573 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Parse Error!\n");
2574 switch_goto_status(SWITCH_STATUS_GENERR, done);
2575 } else {
2576 chan_type = parsed;
2577 }
9c7fb0d4 2578 }
4c4bf59e
AM
2579
2580
2581 /* strip leading spaces (again) */
2582 while (chan_type && *chan_type && *chan_type == ' ') {
2583 chan_type++;
2584 }
2585
e6a60a20
AM
2586 if ((chan_data = strchr(chan_type, '/')) != 0) {
2587 *chan_data = '\0';
2588 chan_data++;
2589 }
2590
1dcb3b67 2591 if (oglobals.session) {
e6a60a20
AM
2592 if (!switch_channel_ready(caller_channel)) {
2593 status = SWITCH_STATUS_FALSE;
2594 goto done;
2595 }
cca9c367
AM
2596
2597 if ((caller_caller_profile = oglobals.caller_profile_override)) {
2598 new_profile = switch_caller_profile_dup(oglobals.pool, caller_caller_profile);
2599 } else {
2600 new_profile = switch_caller_profile_new(oglobals.pool,
2601 NULL,
2602 NULL,
b1a3a106 2603 cid_name_override, cid_num_override, NULL, ani_override, aniii_override, NULL, __FILE__, NULL, chan_data);
cca9c367 2604 }
e6a60a20 2605
ffb989e4
AM
2606 new_profile->uuid = SWITCH_BLANK_STRING;
2607 new_profile->chan_name = SWITCH_BLANK_STRING;
2608 new_profile->destination_number = switch_core_strdup(new_profile->pool, chan_data);
886e1ddb 2609
b1a3a106
AM
2610 if (ani_override) {
2611 new_profile->ani = switch_core_strdup(new_profile->pool, ani_override);
2612 }
2613 if (aniii_override) {
2614 new_profile->aniii = switch_core_strdup(new_profile->pool, aniii_override);
2615 }
d264ed5a 2616 if (cid_name_override) {
ffb989e4 2617 new_profile->caller_id_name = switch_core_strdup(new_profile->pool, cid_name_override);
e6a60a20 2618 }
d264ed5a 2619 if (cid_num_override) {
ffb989e4 2620 new_profile->caller_id_number = switch_core_strdup(new_profile->pool, cid_num_override);
e6a60a20 2621 }
e6a60a20 2622 } else {
cca9c367 2623 if (oglobals.caller_profile_override) {
cae9129f 2624 new_profile = switch_caller_profile_dup(oglobals.pool, oglobals.caller_profile_override);
2847d1c0 2625 new_profile->destination_number = switch_core_strdup(new_profile->pool, switch_str_nil(chan_data));
ffb989e4
AM
2626 new_profile->uuid = SWITCH_BLANK_STRING;
2627 new_profile->chan_name = SWITCH_BLANK_STRING;
e6a60a20 2628 } else {
d264ed5a 2629 if (!cid_name_override) {
4ae072d5 2630 cid_name_override = SWITCH_DEFAULT_CLID_NAME;
d264ed5a
MJ
2631 }
2632 if (!cid_num_override) {
416f026f 2633 cid_num_override = SWITCH_DEFAULT_CLID_NUMBER;
d264ed5a
MJ
2634 }
2635
cca9c367 2636 new_profile = switch_caller_profile_new(oglobals.pool,
30ffb593
MJ
2637 NULL,
2638 NULL,
b1a3a106 2639 cid_name_override, cid_num_override, NULL, ani_override, aniii_override, NULL, __FILE__, NULL, chan_data);
e6a60a20
AM
2640 }
2641 }
3c349c27 2642
21482f01 2643 if (zstr(new_profile->destination_number)) {
c3ceebf0 2644 new_profile->destination_number = switch_core_strdup(new_profile->pool, "service");
21482f01
AM
2645 }
2646
1b1dea02 2647 new_profile->callee_id_name = switch_core_strdup(new_profile->pool, "Outbound Call");
dee0f540 2648 new_profile->callee_id_number = switch_sanitize_number(switch_core_strdup(new_profile->pool, new_profile->destination_number));
1b1dea02 2649
1dcb3b67
AM
2650 originate_status[i].caller_profile = NULL;
2651 originate_status[i].peer_channel = NULL;
2652 originate_status[i].peer_session = NULL;
bf7144b2 2653 new_session = NULL;
3c349c27 2654
8433c7e0
AM
2655 if (and_argc > 1 || or_argc > 1) {
2656 myflags |= SOF_FORKED_DIAL;
46c6650a 2657 }
4c4bf59e 2658
46c6650a 2659 if (var_event) {
21da7429
AM
2660 const char *vvar;
2661 if ((vvar = switch_event_get_header(var_event, "forked_dial")) && switch_true(vvar)) {
2662 myflags |= SOF_FORKED_DIAL;
2663 }
46c6650a
AM
2664 if ((vvar = switch_event_get_header(var_event, "no_throttle_limits")) && switch_true(vvar)) {
2665 myflags |= SOF_NO_LIMITS;
2666 }
8433c7e0 2667 }
886e1ddb 2668
4c4bf59e
AM
2669
2670 /* Valid in both {} and [] with [] taking precedence */
dfda1d8f 2671
4c4bf59e
AM
2672 /* make a special var event with mixture of the {} and the [] vars to pass down as global vars to the outgoing channel
2673 so if something like the user channel does another originate our options will be passed down properly
2674 */
2675
2676 switch_event_dup(&originate_var_event, var_event);
dfda1d8f 2677
4c4bf59e
AM
2678 if (local_var_event) {
2679 switch_event_merge(originate_var_event, local_var_event);
dfda1d8f 2680 }
886e1ddb 2681
b1a3a106
AM
2682 if ((current_variable = switch_event_get_header(originate_var_event, "origination_ani"))) {
2683 new_profile->ani = switch_core_strdup(new_profile->pool, current_variable);
2684 myflags |= SOF_NO_EFFECTIVE_ANI;
2685 }
2686
2687 if ((current_variable = switch_event_get_header(originate_var_event, "origination_aniii"))) {
2688 new_profile->aniii = switch_core_strdup(new_profile->pool, current_variable);
2689 myflags |= SOF_NO_EFFECTIVE_ANIII;
2690 }
2691
4c4bf59e 2692 if ((current_variable = switch_event_get_header(originate_var_event, "origination_caller_id_number"))) {
dfda1d8f
BW
2693 new_profile->caller_id_number = switch_core_strdup(new_profile->pool, current_variable);
2694 myflags |= SOF_NO_EFFECTIVE_CID_NUM;
3720a64e
AM
2695 }
2696
4c4bf59e 2697 if ((current_variable = switch_event_get_header(originate_var_event, "origination_caller_id_name"))) {
9694ce04 2698 new_profile->caller_id_name = switch_core_strdup(new_profile->pool, current_variable);
dfda1d8f
BW
2699 myflags |= SOF_NO_EFFECTIVE_CID_NAME;
2700 }
886e1ddb 2701
4c4bf59e 2702 if ((current_variable = switch_event_get_header(originate_var_event, "origination_privacy"))) {
674a18f9 2703 new_profile->flags = SWITCH_CPF_NONE;
886e1ddb 2704
dfda1d8f 2705 if (switch_stristr("screen", current_variable)) {
674a18f9
AM
2706 switch_set_flag(new_profile, SWITCH_CPF_SCREEN);
2707 }
2708
dfda1d8f 2709 if (switch_stristr("hide_name", current_variable)) {
674a18f9
AM
2710 switch_set_flag(new_profile, SWITCH_CPF_HIDE_NAME);
2711 }
2712
dfda1d8f 2713 if (switch_stristr("hide_number", current_variable)) {
674a18f9
AM
2714 switch_set_flag(new_profile, SWITCH_CPF_HIDE_NUMBER);
2715 }
674a18f9 2716 }
cca9c367 2717
dfda1d8f
BW
2718 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "originate_early_media", oglobals.early_ok ? "true" : "false");
2719
3fbd9e21 2720
138fdc83
AM
2721 if (caller_channel && switch_true(switch_channel_get_variable(caller_channel, "push_channel_name"))) {
2722 char *new_name = switch_core_session_sprintf(session, "%s__B", switch_channel_get_name(caller_channel));
138fdc83
AM
2723 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "origination_channel_name", new_name);
2724 new_name = switch_core_session_sprintf(session, "_%s", switch_channel_get_name(caller_channel));
1b91f811 2725 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "sip_h_X-FS-Channel-Name", new_name);
138fdc83 2726 }
3fbd9e21 2727
973a39e0 2728
80b18bb2 2729 reason = switch_core_session_outgoing_channel(oglobals.session, originate_var_event, chan_type,
3fbd9e21
AM
2730 new_profile, &new_session, NULL, myflags, cancel_cause);
2731
2732 switch_event_destroy(&originate_var_event);
2733
2734 if (reason != SWITCH_CAUSE_SUCCESS) {
f25085e0 2735 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Cannot create outgoing channel of type [%s] cause: [%s]\n",
4ed389f9 2736 chan_type, switch_channel_cause2str(reason));
3fbd9e21 2737 if (local_var_event) switch_event_destroy(&local_var_event);
cd736a1c
AM
2738
2739 if (fail_on_single_reject_var) {
2740 const char *cause_str = switch_channel_cause2str(reason);
522c0d53
AM
2741 int neg = *fail_on_single_reject_var == '!';
2742 int pos = !!switch_stristr(cause_str, fail_on_single_reject_var);
2743
2744 if (neg) {
2745 pos = !pos;
2746 }
2747
cd736a1c
AM
2748 check_reject = 0;
2749
522c0d53 2750 if (fail_on_single_reject == 1 || pos) {
08d2ea9d 2751 force_reason = reason;
fae95433 2752 status = SWITCH_STATUS_FALSE;
cd736a1c
AM
2753 goto outer_for;
2754 }
2755 }
e6a60a20
AM
2756 continue;
2757 }
2758
ea5c3852
AM
2759 if (switch_core_session_read_lock(new_session) != SWITCH_STATUS_SUCCESS) {
2760 status = SWITCH_STATUS_FALSE;
3fbd9e21 2761 if (local_var_event) switch_event_destroy(&local_var_event);
ea5c3852
AM
2762 goto done;
2763 }
e6a60a20 2764
1dcb3b67 2765 originate_status[i].peer_channel = switch_core_session_get_channel(new_session);
cca9c367
AM
2766 originate_status[i].caller_profile = switch_channel_get_caller_profile(originate_status[i].peer_channel);
2767 originate_status[i].peer_session = new_session;
2768
1dcb3b67 2769 switch_channel_set_flag(originate_status[i].peer_channel, CF_ORIGINATING);
b946ee94
AM
2770
2771 if (caller_channel) {
2772 switch_channel_set_variable(originate_status[i].peer_channel, "call_uuid", switch_channel_get_variable(caller_channel, "call_uuid"));
2773 }
2774
3c349c27 2775
4240526c
AM
2776 if (local_var_event) {
2777 const char *device_id = switch_event_get_header(local_var_event, "device_id");
2778 switch_channel_set_profile_var(originate_status[i].peer_channel, "device_id", device_id);
2779 }
2780
f9642e96
AM
2781 if ((lc = switch_event_get_header(var_event, "local_var_clobber"))) {
2782 local_clobber = switch_true(lc);
2783 }
2784
42f296de
AM
2785 if (switch_channel_test_flag(originate_status[i].peer_channel, CF_NO_PRESENCE)) {
2786 if (var_event) {
2787 switch_event_del_header(var_event, "presence_id");
2788 }
2789 if (local_var_event) {
2790 switch_event_del_header(local_var_event, "presence_id");
2791 }
2792 }
2793
2794
cdd0bcfd 2795 if (local_clobber) {
f9642e96 2796 if (var_event) {
f9642e96
AM
2797 switch_event_header_t *header;
2798 /* install the vars from the {} params */
2799 for (header = var_event->headers; header; header = header->next) {
385a92ce 2800 switch_channel_set_variable_var_check(originate_status[i].peer_channel, header->name, header->value, oglobals.check_vars);
f9642e96 2801 }
f9642e96
AM
2802 }
2803 }
2804
3fbd9e21
AM
2805 /* copy local originate vars to the channel */
2806 if (local_var_event) {
2807 switch_event_header_t *header;
2808 for (header = local_var_event->headers; header; header = header->next) {
385a92ce 2809 switch_channel_set_variable_var_check(originate_status[i].peer_channel, header->name, header->value, oglobals.check_vars);
5c5c3251 2810 }
3fbd9e21 2811 switch_event_destroy(&local_var_event);
5c5c3251 2812 }
3c349c27 2813
cdd0bcfd 2814 if (!local_clobber) {
f9642e96 2815 if (var_event) {
f9642e96
AM
2816 switch_event_header_t *header;
2817 /* install the vars from the {} params */
2818 for (header = var_event->headers; header; header = header->next) {
385a92ce 2819 switch_channel_set_variable_var_check(originate_status[i].peer_channel, header->name, header->value, oglobals.check_vars);
f9642e96 2820 }
466bbe70 2821 }
466bbe70
AM
2822 }
2823
1dcb3b67 2824 if (originate_status[i].peer_channel) {
4ed389f9 2825 const char *vvar;
daab35e3
AM
2826
2827 if (switch_true(switch_channel_get_variable(originate_status[i].peer_channel, "leg_required"))) {
2828 originate_status[i].tagged = 1;
2829 }
138fdc83 2830
a10125b8
AM
2831 if ((vvar = switch_channel_get_variable(originate_status[i].peer_channel, "origination_channel_name"))) {
2832 switch_channel_set_name(originate_status[i].peer_channel, vvar);
2833 }
2834
3dfe6780
AM
2835 if ((vvar = switch_channel_get_variable(originate_status[i].peer_channel, "origination_callee_id_name"))) {
2836 switch_channel_set_profile_var(originate_status[i].peer_channel, "callee_id_name", vvar);
2837 }
2838
2839 if ((vvar = switch_channel_get_variable(originate_status[i].peer_channel, "origination_callee_id_number"))) {
2840 switch_channel_set_profile_var(originate_status[i].peer_channel, "callee_id_number", vvar);
2841 }
2842
1dcb3b67 2843 if ((vvar = switch_channel_get_variable(originate_status[i].peer_channel, "leg_timeout"))) {
4ed389f9 2844 int val = atoi(vvar);
3fbd9e21 2845
4ed389f9 2846 if (val > 0) {
886e1ddb 2847 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Setting leg timeout to %d\n",
e071f1a6 2848 switch_channel_get_name(originate_status[i].peer_channel), val);
29c616b9 2849 originate_status[i].per_channel_timelimit_sec = (uint32_t) val;
4ed389f9
AM
2850 }
2851 }
3fbd9e21 2852
1dcb3b67 2853 if ((vvar = switch_channel_get_variable(originate_status[i].peer_channel, "leg_progress_timeout"))) {
4ed389f9
AM
2854 int val = atoi(vvar);
2855 if (val > 0) {
886e1ddb 2856 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Setting leg progress timeout to %d\n",
e071f1a6 2857 switch_channel_get_name(originate_status[i].peer_channel), val);
29c616b9 2858 originate_status[i].per_channel_progress_timelimit_sec = (uint32_t) val;
4ed389f9
AM
2859 }
2860 }
d7a12df5
AM
2861
2862 if ((vvar = switch_channel_get_variable(originate_status[i].peer_channel, "leg_delay_start"))) {
2863 int val = atoi(vvar);
2864 if (val > 0) {
886e1ddb 2865 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Setting leg delay start to %d\n",
e071f1a6 2866 switch_channel_get_name(originate_status[i].peer_channel), val);
d7a12df5 2867 originate_status[i].per_channel_delay_start = (uint32_t) val;
160535da
AM
2868
2869 if (originate_status[i].per_channel_progress_timelimit_sec != 0) {
2870 originate_status[i].per_channel_progress_timelimit_sec += originate_status[i].per_channel_delay_start;
2871 }
2872
2873 if (originate_status[i].per_channel_timelimit_sec != 0) {
2874 originate_status[i].per_channel_timelimit_sec += originate_status[i].per_channel_delay_start;
2875 }
d7a12df5
AM
2876 }
2877 }
70700617 2878
e6758021
AM
2879 if (!zstr(ent_aleg_uuid)) {
2880 l_session = switch_core_session_locate(ent_aleg_uuid);
2881 a_session = l_session;
2882 }
2883
2884 if (a_session) {
2885 switch_channel_t *channel = switch_core_session_get_channel(a_session);
3099445a 2886 char *val =
e6758021 2887 switch_core_session_sprintf(a_session, "%s;%s;%s",
3099445a
AM
2888 switch_core_session_get_uuid(originate_status[i].peer_session),
2889 switch_str_nil(switch_channel_get_variable(originate_status[i].peer_channel, "callee_id_name")),
2890 switch_str_nil(switch_channel_get_variable(originate_status[i].peer_channel, "callee_id_number")));
2891
2892
e6758021 2893 switch_channel_set_variable(originate_status[i].peer_channel, "originating_leg_uuid", switch_core_session_get_uuid(a_session));
3099445a
AM
2894
2895 switch_channel_add_variable_var_check(channel, "originated_legs", val, SWITCH_FALSE, SWITCH_STACK_PUSH);
2896
70700617
AM
2897 }
2898
e6758021
AM
2899 if (l_session) {
2900 switch_core_session_rwunlock(l_session);
2901 l_session = NULL;
2902 }
2903
850f2e3c
AM
2904 switch_channel_execute_on(originate_status[i].peer_channel, SWITCH_CHANNEL_EXECUTE_ON_ORIGINATE_VARIABLE);
2905 switch_channel_api_on(originate_status[i].peer_channel, SWITCH_CHANNEL_API_ON_ORIGINATE_VARIABLE);
4ed389f9 2906 }
27c6d111 2907
e6a60a20 2908 if (table) {
1dcb3b67 2909 switch_channel_add_state_handler(originate_status[i].peer_channel, table);
e6a60a20 2910 }
4c20b020 2911
fea44bb2 2912 if (oglobals.monitor_early_media_ring || oglobals.monitor_early_media_fail || oglobals.ignore_early_media == 4) {
4c20b020
AM
2913 switch_channel_set_flag(originate_status[i].peer_channel, CF_CONSUME_ON_ORIGINATE);
2914 }
e6a60a20 2915
d2bf2022
AM
2916 switch_channel_add_state_handler(originate_status[i].peer_channel, &originate_state_handlers);
2917
1dcb3b67 2918 if ((flags & SOF_NOBLOCK) && originate_status[i].peer_session) {
8433c7e0 2919 status = SWITCH_STATUS_SUCCESS;
1dcb3b67 2920 *bleg = originate_status[i].peer_session;
8433c7e0
AM
2921 *cause = SWITCH_CAUSE_SUCCESS;
2922 goto outer_for;
2923 }
70700617 2924
1dcb3b67 2925 if (!switch_core_session_running(originate_status[i].peer_session)) {
d7a12df5
AM
2926 if (originate_status[i].per_channel_delay_start) {
2927 switch_channel_set_flag(originate_status[i].peer_channel, CF_BLOCK_STATE);
2928 }
1dcb3b67 2929 switch_core_session_thread_launch(originate_status[i].peer_session);
e6a60a20 2930 }
3c349c27 2931 }
e6a60a20 2932
0463541d 2933 switch_epoch_time_now(&start);
e6a60a20
AM
2934
2935 for (;;) {
2936 uint32_t valid_channels = 0;
2937 for (i = 0; i < and_argc; i++) {
2938 int state;
4ed389f9 2939 time_t elapsed;
e6a60a20 2940
1dcb3b67 2941 if (!originate_status[i].peer_channel) {
e6a60a20
AM
2942 continue;
2943 }
d57e0387 2944
1dcb3b67 2945 state = switch_channel_get_state(originate_status[i].peer_channel);
e6a60a20 2946
d57e0387
AM
2947 if (state < CS_HANGUP) {
2948 valid_channels++;
2949 } else {
2950 continue;
2951 }
2952
4b929592 2953 if (state >= CS_ROUTING) {
e6a60a20
AM
2954 goto endfor1;
2955 }
2956
2957 if (caller_channel && !switch_channel_ready(caller_channel)) {
2958 goto notready;
2959 }
886e1ddb 2960
0463541d 2961 elapsed = switch_epoch_time_now(NULL) - start;
886e1ddb 2962
4ed389f9 2963 if (elapsed > (time_t) timelimit_sec) {
e6a60a20 2964 to++;
1dcb3b67 2965 oglobals.idx = IDX_TIMEOUT;
e6a60a20
AM
2966 goto notready;
2967 }
e6a60a20 2968
886e1ddb 2969 if (!oglobals.sent_ring && !oglobals.ignore_ring_ready &&
6cf98363 2970 !oglobals.progress && (progress_timelimit_sec && elapsed > (time_t) progress_timelimit_sec)) {
f33aa021 2971 to++;
1dcb3b67 2972 oglobals.idx = IDX_TIMEOUT;
50cc7ab0
AM
2973 if (force_reason == SWITCH_CAUSE_NONE) {
2974 force_reason = SWITCH_CAUSE_PROGRESS_TIMEOUT;
2975 }
f33aa021
AM
2976 goto notready;
2977 }
886e1ddb 2978
292ed6ee 2979 switch_cond_next();
d57e0387 2980 }
3c349c27 2981
25aff5bc 2982 check_per_channel_timeouts(&oglobals, originate_status, and_argc, start, &force_reason);
4ed389f9
AM
2983
2984
e6a60a20
AM
2985 if (valid_channels == 0) {
2986 status = SWITCH_STATUS_GENERR;
2987 goto done;
2988 }
2989
2990 }
d57e0387 2991
886e1ddb 2992 endfor1:
e6a60a20 2993
047e3dd7 2994 if (caller_channel) {
886e1ddb 2995 if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE) ||
e072a609 2996 switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA) || switch_channel_test_flag(caller_channel, CF_DISABLE_RINGBACK)) {
047e3dd7
AM
2997 ringback_data = NULL;
2998 }
2999 }
3000
e6a60a20 3001
78bc4172
AM
3002#if 0
3003 /* changing behaviour ignore_early_media=true must also be explicitly set for previous behaviour */
e6a60a20 3004 if (ringback_data) {
1dcb3b67 3005 oglobals.early_ok = 0;
e6a60a20 3006 }
78bc4172 3007#endif
aaeb69d6 3008
757aa19e
AM
3009 if (ringback_data) {
3010 oglobals.sending_ringback = 1;
3011 } else {
3012 oglobals.ringback_ok = 0;
3013 }
2f4fcf9a 3014
1ae5b7cb
AM
3015 if (caller_channel) {
3016 soft_holding = switch_channel_get_variable(caller_channel, SWITCH_SOFT_HOLDING_UUID_VARIABLE);
3017 }
2f4fcf9a 3018
2fa0c491 3019 while ((!caller_channel || switch_channel_ready(caller_channel) || switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE)) &&
1400a31c 3020 check_channel_status(&oglobals, originate_status, and_argc, &force_reason)) {
0463541d 3021 time_t elapsed = switch_epoch_time_now(NULL) - start;
dfa54399
AM
3022
3023 read_packet = 0;
886e1ddb 3024
2fa0c491 3025 if (cancel_cause && *cancel_cause > 0) {
50cc7ab0
AM
3026 if (force_reason == SWITCH_CAUSE_NONE) {
3027 force_reason = *cancel_cause;
3028 }
2fa0c491
AM
3029 oglobals.idx = IDX_CANCEL;
3030 goto notready;
3031 }
3032
25aff5bc 3033 check_per_channel_timeouts(&oglobals, originate_status, and_argc, start, &force_reason);
4ed389f9 3034
59b94dfa 3035 if (oglobals.session) {
1dcb3b67 3036 switch_ivr_parse_all_events(oglobals.session);
8b1ad09d
AM
3037 }
3038
1dcb3b67
AM
3039 if (!oglobals.sent_ring && !oglobals.progress && (progress_timelimit_sec && elapsed > (time_t) progress_timelimit_sec)) {
3040 oglobals.idx = IDX_TIMEOUT;
50cc7ab0
AM
3041 if (force_reason == SWITCH_CAUSE_NONE) {
3042 force_reason = SWITCH_CAUSE_PROGRESS_TIMEOUT;
3043 }
e6a60a20
AM
3044 goto notready;
3045 }
cd736a1c 3046
1dcb3b67 3047 if ((to = (uint8_t) (elapsed >= (time_t) timelimit_sec)) || (fail_on_single_reject && oglobals.hups)) {
4ed389f9 3048 int ok = 0;
886e1ddb 3049
cd736a1c
AM
3050 if (fail_on_single_reject_var) {
3051 if (!switch_true(fail_on_single_reject_var)) {
3052 ok = 1;
886e1ddb 3053
cd736a1c
AM
3054 for (i = 0; i < and_argc; i++) {
3055 switch_channel_t *pchannel;
3056 const char *cause_str;
3057
3058 if (!originate_status[i].peer_session) {
3059 continue;
3060 }
3061 pchannel = switch_core_session_get_channel(originate_status[i].peer_session);
886e1ddb 3062
9ecf187d 3063 if (switch_channel_down_nosig(pchannel)) {
522c0d53 3064 int neg, pos;
cd736a1c 3065 cause_str = switch_channel_cause2str(switch_channel_get_cause(pchannel));
522c0d53
AM
3066 neg = *fail_on_single_reject_var == '!';
3067 pos = !!switch_stristr(cause_str, fail_on_single_reject_var);
3068
3069 if (neg) {
3070 pos = !pos;
3071 }
3072
3073 if (pos) {
cd736a1c
AM
3074 ok = 0;
3075 break;
3076 }
4ed389f9
AM
3077 }
3078 }
3079 }
3080 }
3081 if (!ok) {
1dcb3b67 3082 oglobals.idx = IDX_TIMEOUT;
4ed389f9
AM
3083 goto notready;
3084 }
3085 }
befbd6dd 3086
3c349c27 3087 /* read from the channel while we wait if the audio is up on it */
1dcb3b67 3088 if (oglobals.session &&
3c349c27
AM
3089 !switch_channel_test_flag(caller_channel, CF_PROXY_MODE) &&
3090 !switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA) &&
aaeb69d6 3091 !switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE) &&
757aa19e 3092 (oglobals.ringback_ok
3c349c27 3093 || (switch_channel_test_flag(caller_channel, CF_ANSWERED) || switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA)))) {
886e1ddb 3094
2e46528e 3095 switch_status_t tstatus = SWITCH_STATUS_SUCCESS;
fc1de32f 3096 int silence = 0;
3c349c27 3097
f8b442da
AM
3098 if (caller_channel && cancel_key) {
3099 if (switch_channel_has_dtmf(caller_channel)) {
3100 switch_dtmf_t dtmf = { 0, 0 };
3101 if (switch_channel_dequeue_dtmf(caller_channel, &dtmf) == SWITCH_STATUS_SUCCESS) {
3102 if (dtmf.digit == *cancel_key) {
aaeb69d6 3103 oglobals.idx = IDX_KEY_CANCEL;
f8b442da
AM
3104 goto notready;
3105 }
3106 }
3107 }
3108 }
3109
2e46528e 3110 if (switch_channel_media_ready(caller_channel)) {
1dcb3b67 3111 tstatus = switch_core_session_read_frame(oglobals.session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
2e46528e 3112 if (!SWITCH_READ_ACCEPTABLE(tstatus)) {
2f4fcf9a
AM
3113 if (soft_holding) {
3114 switch_channel_set_flag(caller_channel, CF_XFER_ZOMBIE);
3115 }
3116
7681f944 3117 if (switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE)) {
dfa54399 3118 goto do_continue;
7681f944 3119 }
2e46528e
AM
3120 break;
3121 }
dfa54399
AM
3122
3123 read_packet++;
2e46528e
AM
3124 } else {
3125 read_frame = NULL;
e6a60a20 3126 }
8e75f82e 3127
886e1ddb
AM
3128
3129 if (oglobals.ringback_ok && (oglobals.ring_ready || oglobals.instant_ringback ||
8e75f82e 3130 oglobals.sending_ringback > 1 || oglobals.bridge_early_media > -1)) {
757aa19e 3131 if (oglobals.ringback_ok == 1) {
72ec7b59 3132 switch_status_t rst;
66ba2822 3133
72ec7b59
MR
3134 rst = setup_ringback(&oglobals, originate_status, and_argc, ringback_data, &ringback, &write_frame, &write_codec);
3135
5cc8aebc
AM
3136 if (oglobals.bridge_early_media > -1) {
3137 switch_threadattr_t *thd_attr = NULL;
3138 switch_threadattr_create(&thd_attr, switch_core_session_get_pool(session));
3139 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
3140 early_state.oglobals = &oglobals;
3141 early_state.originate_status = originate_status;
3142 early_state.ready = 1;
72ec7b59 3143 early_state.ringback = &ringback;
392c687f 3144 early_state.ttl = and_argc;
5cc8aebc
AM
3145 switch_mutex_init(&early_state.mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
3146 switch_buffer_create_dynamic(&early_state.buffer, 1024, 1024, 0);
3147 switch_thread_create(&oglobals.ethread, thd_attr, early_thread_run, &early_state, switch_core_session_get_pool(session));
3148 }
886e1ddb
AM
3149
3150
757aa19e
AM
3151 switch (rst) {
3152 case SWITCH_STATUS_SUCCESS:
3153 oglobals.ringback_ok++;
3154 break;
3155 case SWITCH_STATUS_FALSE:
3156 goto notready;
3157 break;
3158 case SWITCH_STATUS_BREAK:
4fe24be7 3159 status = SWITCH_STATUS_FALSE;
757aa19e
AM
3160 goto done;
3161 break;
3162 default:
3163 ringback_data = NULL;
3164 oglobals.ringback_ok = 0;
3165 oglobals.sending_ringback = 0;
3166 break;
3167 }
3168
dfa54399 3169 goto do_continue;
757aa19e 3170 }
886e1ddb 3171
72ec7b59 3172 if (oglobals.bridge_early_media > -1) {
5cc8aebc
AM
3173 write_frame.datalen = 0;
3174 switch_mutex_lock(early_state.mutex);
72ec7b59
MR
3175 if (ringback.asis) {
3176 uint16_t mlen;
3177 switch_size_t buflen = switch_buffer_inuse(early_state.buffer);
3178 if (buflen > sizeof(uint16_t)) {
3179 switch_buffer_peek(early_state.buffer, &mlen, sizeof(uint16_t));
3180 if (buflen >= (mlen + sizeof(uint16_t))) {
3181 switch_buffer_toss(early_state.buffer, sizeof(uint16_t));
084e2450 3182 write_frame.datalen = (uint32_t)switch_buffer_read(early_state.buffer, write_frame.data, mlen);
72ec7b59
MR
3183 }
3184 }
3185 } else {
3186 if (switch_buffer_inuse(early_state.buffer) >= write_frame.codec->implementation->decoded_bytes_per_packet) {
084e2450 3187 write_frame.datalen = (uint32_t)switch_buffer_read(early_state.buffer, write_frame.data,
72ec7b59
MR
3188 write_frame.codec->implementation->decoded_bytes_per_packet);
3189 }
8e75f82e 3190 }
5cc8aebc 3191 switch_mutex_unlock(early_state.mutex);
8e75f82e 3192 } else if (ringback.fh) {
e6a60a20
AM
3193 switch_size_t mlen, olen;
3194 unsigned int pos = 0;
3c349c27 3195
e6a60a20 3196 if (ringback.asis) {
30c318b9 3197 mlen = write_frame.codec->implementation->encoded_bytes_per_packet;
e6a60a20 3198 } else {
30c318b9 3199 mlen = write_frame.codec->implementation->samples_per_packet;
e6a60a20
AM
3200 }
3201
3202 olen = mlen;
886e1ddb 3203
ea5c3852
AM
3204 //if (ringback.fh->resampler && ringback.fh->resampler->rfactor > 1) {
3205 //olen = (switch_size_t) (olen * ringback.fh->resampler->rfactor);
3206 //}
886e1ddb 3207
3608c834 3208 switch_core_file_read(ringback.fh, write_frame.data, &olen);
e6a60a20
AM
3209
3210 if (olen == 0) {
3211 olen = mlen;
3212 ringback.fh->speed = 0;
3213 switch_core_file_seek(ringback.fh, &pos, 0, SEEK_SET);
3608c834 3214 switch_core_file_read(ringback.fh, write_frame.data, &olen);
e6a60a20
AM
3215 if (olen == 0) {
3216 break;
3217 }
3218 }
ed7264b6 3219 write_frame.datalen = (uint32_t) (ringback.asis ? olen : olen * 2 * ringback.fh->channels);
86c1dbee 3220 write_frame.samples = (uint32_t) olen;
3bc87574 3221
e6a60a20 3222 } else if (ringback.audio_buffer) {
ceb98915
AM
3223 if ((write_frame.datalen = (uint32_t) switch_buffer_read_loop(ringback.audio_buffer,
3224 write_frame.data,
886e1ddb
AM
3225 write_frame.codec->implementation->decoded_bytes_per_packet)) <=
3226 0) {
2f4fcf9a
AM
3227
3228 if (soft_holding) {
3229 switch_channel_set_flag(caller_channel, CF_XFER_ZOMBIE);
dfa54399 3230 goto do_continue;
2f4fcf9a
AM
3231 }
3232
ceb98915 3233 break;
e6a60a20 3234 }
1136fcec 3235 } else if (ringback.silence) {
fc1de32f 3236 silence = ringback.silence;
e6a60a20 3237 }
fc1de32f 3238 } else {
f5d97f2f 3239 silence = 600;
fc1de32f 3240 }
886e1ddb 3241
5cc8aebc 3242 if ((ringback.fh || silence || ringback.audio_buffer || oglobals.bridge_early_media > -1) && write_frame.codec && write_frame.datalen) {
e276f5fe 3243 if (silence) {
00046ee0 3244 write_frame.datalen = read_impl.decoded_bytes_per_packet;
579a0518 3245 switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.datalen / 2, write_frame.codec->implementation->number_of_channels, silence);
e276f5fe 3246 }
886e1ddb 3247
1dcb3b67 3248 if (switch_core_session_write_frame(oglobals.session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
2f4fcf9a
AM
3249 if (soft_holding) {
3250 switch_channel_set_flag(caller_channel, CF_XFER_ZOMBIE);
3251 }
7681f944 3252 if (switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE)) {
dfa54399 3253 goto do_continue;
7681f944 3254 }
fc1de32f 3255 break;
e6a60a20 3256 }
e6a60a20 3257 }
886e1ddb 3258
dfa54399
AM
3259 }
3260
3261 do_continue:
3262
3263 if (!read_packet) {
d4f8a792 3264 switch_yield(20000);
e6a60a20 3265 }
e6a60a20 3266 }
886e1ddb 3267
e6a60a20
AM
3268 notready:
3269
aaeb69d6 3270 if (caller_channel) {
aaeb69d6
AM
3271 holding = switch_channel_get_variable(caller_channel, SWITCH_HOLDING_UUID_VARIABLE);
3272 switch_channel_set_variable(caller_channel, SWITCH_HOLDING_UUID_VARIABLE, NULL);
3273
3274 if (soft_holding && switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE)) {
3275 holding = soft_holding;
2f4fcf9a 3276 soft_holding = NULL;
aaeb69d6
AM
3277 switch_channel_set_variable(caller_channel, SWITCH_SOFT_HOLDING_UUID_VARIABLE, NULL);
3278 }
3279 }
886e1ddb 3280
7681f944 3281 if (caller_channel && !switch_channel_ready(caller_channel) && !switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE)) {
1dcb3b67 3282 oglobals.idx = IDX_CANCEL;
e6a60a20
AM
3283 }
3284
bf789527 3285 if (oglobals.session && (ringback_data || !(switch_channel_test_flag(caller_channel, CF_PROXY_MODE) ||
886e1ddb 3286 switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA)))) {
1dcb3b67 3287 switch_core_session_reset(oglobals.session, SWITCH_FALSE, SWITCH_TRUE);
e6a60a20 3288 }
3c349c27 3289
aaeb69d6
AM
3290 if (holding) {
3291 if (oglobals.idx > IDX_NADA) {
3292 peer_session = originate_status[oglobals.idx].peer_session;
3293 peer_channel = originate_status[oglobals.idx].peer_channel;
3294 originate_status[oglobals.idx].peer_channel = NULL;
3295 } else if (and_argc == 1) {
3296 peer_session = originate_status[0].peer_session;
3297 peer_channel = originate_status[0].peer_channel;
3298 originate_status[0].peer_channel = NULL;
3299 } else {
3300 for (i = 0; i < and_argc; i++) {
3301 if (!peer_eligible(originate_status[i].peer_channel)) {
3302 continue;
3303 }
3304 if (switch_channel_media_ready(originate_status[i].peer_channel)) {
3305 peer_session = originate_status[i].peer_session;
3306 peer_channel = originate_status[i].peer_channel;
3307 originate_status[i].peer_channel = NULL;
3308 goto end_search;
3309 }
3310 }
3311 for (i = 0; i < and_argc; i++) {
3312 if (!peer_eligible(originate_status[i].peer_channel)) {
3313 continue;
3314 }
9ecf187d 3315 if (switch_channel_up_nosig(originate_status[i].peer_channel)) {
aaeb69d6
AM
3316 peer_session = originate_status[i].peer_session;
3317 peer_channel = originate_status[i].peer_channel;
3318 originate_status[i].peer_channel = NULL;
3319 break;
3320 }
3321 }
e6a60a20 3322 }
886e1ddb
AM
3323
3324 end_search:
d7a12df5 3325
9ecf187d 3326 if (peer_channel && switch_channel_down_nosig(peer_channel)) {
06c1349b
AM
3327 switch_core_session_rwunlock(peer_session);
3328 peer_session = NULL;
3329 peer_channel = NULL;
3330
3331 }
886e1ddb
AM
3332
3333 if (oglobals.idx == IDX_TIMEOUT || to || oglobals.idx == IDX_KEY_CANCEL || oglobals.idx == IDX_CANCEL ||
06c1349b
AM
3334 (!peer_session && oglobals.idx == IDX_NADA)) {
3335 const char *dest = NULL;
3336 const char *context = NULL;
3337 const char *dialplan = NULL;
1cbd982a 3338 switch_core_session_t *holding_session;
befbd6dd 3339
aaeb69d6 3340 if (caller_channel) {
df7637f6 3341 if (zstr(context)) {
886e1ddb 3342 context = switch_channel_get_variable(caller_channel, "context");
1cbd982a 3343 }
df7637f6 3344 if (zstr(dialplan)) {
886e1ddb 3345 dialplan = switch_channel_get_variable(caller_channel, "dialplan");
1cbd982a
AM
3346 }
3347 }
886e1ddb 3348
df7637f6 3349 if (zstr(context)) {
1cbd982a
AM
3350 context = "default";
3351 }
3352
df7637f6 3353 if (zstr(context)) {
1cbd982a
AM
3354 dialplan = "XML";
3355 }
3356
3357 if ((holding_session = switch_core_session_locate(holding))) {
7681f944
AM
3358 switch_channel_t *holding_channel = switch_core_session_get_channel(holding_session);
3359 switch_status_t mstatus = SWITCH_STATUS_FALSE;
befbd6dd 3360
7681f944 3361 if (caller_channel) {
9a3a7f3e 3362 if ((mstatus = switch_channel_caller_extension_masquerade(caller_channel, holding_channel, 0)) == SWITCH_STATUS_SUCCESS) {
06c1349b 3363 switch_channel_restart(holding_channel);
7681f944
AM
3364 }
3365 }
3366
3367 if (mstatus != SWITCH_STATUS_SUCCESS) {
06c1349b
AM
3368 if (peer_channel) {
3369 dest = switch_channel_get_variable(peer_channel, "destination_number");
3370 context = switch_channel_get_variable(peer_channel, "context");
3371 dialplan = switch_channel_get_variable(peer_channel, "dialplan");
3372 } else if (caller_channel) {
3373 dest = switch_channel_get_variable(caller_channel, "destination_number");
3374 }
3375 if (dest) {
3376 switch_ivr_session_transfer(holding_session, dest, dialplan, context);
3377 }
7681f944
AM
3378 }
3379
1cbd982a
AM
3380 switch_core_session_rwunlock(holding_session);
3381 holding = NULL;
3382 holding_session = NULL;
aaeb69d6 3383 }
1cbd982a 3384
06c1349b
AM
3385 if (peer_channel) {
3386 switch_channel_hangup(peer_channel, SWITCH_CAUSE_ATTENDED_TRANSFER);
3387 switch_core_session_rwunlock(peer_session);
3388 }
50cc7ab0
AM
3389 if (force_reason == SWITCH_CAUSE_NONE) {
3390 force_reason = SWITCH_CAUSE_ATTENDED_TRANSFER;
3391 }
450e63c0 3392 } else if (zstr(soft_holding)) {
befbd6dd 3393
1cbd982a 3394 if (peer_channel && switch_channel_ready(peer_channel)) {
befbd6dd
AM
3395 switch_core_session_t *holding_session;
3396
50cc7ab0
AM
3397 if (force_reason == SWITCH_CAUSE_NONE) {
3398 force_reason = SWITCH_CAUSE_ATTENDED_TRANSFER;
3399 }
befbd6dd
AM
3400
3401 if ((holding_session = switch_core_session_locate(holding))) {
f5b0b8e2 3402 switch_channel_set_variable(switch_core_session_get_channel(holding_session), SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE, "true");
befbd6dd
AM
3403 switch_core_session_rwunlock(holding_session);
3404 }
24a97292 3405 switch_channel_set_flag(peer_channel, CF_LAZY_ATTENDED_TRANSFER);
1cbd982a 3406 switch_ivr_uuid_bridge(holding, switch_core_session_get_uuid(peer_session));
befbd6dd 3407 holding = NULL;
70accd9f 3408 oglobals.idx = IDX_XFER;
94063658 3409 if (caller_channel && switch_channel_up_nosig(caller_channel) && !switch_channel_test_flag(caller_channel, CF_INTERCEPTED)) {
1cbd982a
AM
3410 switch_channel_hangup(caller_channel, SWITCH_CAUSE_ATTENDED_TRANSFER);
3411 }
3412 caller_channel = NULL;
3413 oglobals.session = NULL;
3414 session = NULL;
3415 switch_core_session_rwunlock(peer_session);
3416 } else {
3417 switch_core_session_t *holding_session;
aaeb69d6 3418
1cbd982a
AM
3419 if ((holding_session = switch_core_session_locate(holding))) {
3420 switch_channel_t *holding_channel = switch_core_session_get_channel(holding_session);
befbd6dd 3421
1cbd982a 3422 if (caller_channel && switch_channel_ready(caller_channel)) {
f5b0b8e2 3423 switch_channel_set_variable(holding_channel, SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE, "true");
1cbd982a 3424 switch_ivr_uuid_bridge(holding, switch_core_session_get_uuid(session));
befbd6dd 3425 holding = NULL;
1cbd982a
AM
3426 } else {
3427 switch_channel_hangup(holding_channel, SWITCH_CAUSE_NORMAL_UNSPECIFIED);
3428 }
3429 switch_core_session_rwunlock(holding_session);
aaeb69d6 3430 }
aaeb69d6 3431 }
69120105
AM
3432 }
3433
aaeb69d6
AM
3434 peer_session = NULL;
3435 peer_channel = NULL;
aaeb69d6 3436 }
886e1ddb 3437
aaeb69d6
AM
3438 for (i = 0; i < and_argc; i++) {
3439 if (!peer_eligible(originate_status[i].peer_channel)) {
3440 continue;
3441 }
886e1ddb 3442
1dcb3b67 3443 if (i != oglobals.idx) {
aaeb69d6 3444 holding = NULL;
cc06fdb5 3445
7681f944 3446 if (oglobals.idx == IDX_TIMEOUT || to) {
eaf6abfb 3447 reason = SWITCH_CAUSE_NO_ANSWER;
e6a60a20 3448 } else {
1dcb3b67 3449 if (oglobals.idx == IDX_CANCEL) {
eaf6abfb 3450 reason = SWITCH_CAUSE_ORIGINATOR_CANCEL;
e6a60a20 3451 } else {
eaf6abfb
AM
3452 if (and_argc > 1) {
3453 reason = SWITCH_CAUSE_LOSE_RACE;
cc06fdb5
AM
3454 } else if (!switch_channel_ready(originate_status[i].peer_channel)) {
3455 wait_for_cause(originate_status[i].peer_channel);
9ecf187d 3456 if (switch_channel_down_nosig(originate_status[i].peer_channel)) {
cc06fdb5
AM
3457 reason = switch_channel_get_cause(originate_status[i].peer_channel);
3458 }
eaf6abfb
AM
3459 } else {
3460 reason = SWITCH_CAUSE_NO_ANSWER;
3461 }
e6a60a20
AM
3462 }
3463 }
9ecf187d 3464 if (switch_channel_up_nosig(originate_status[i].peer_channel)) {
117c0315 3465 if (caller_channel && i == 0) {
886e1ddb
AM
3466 holding = switch_channel_get_variable(caller_channel, SWITCH_SOFT_HOLDING_UUID_VARIABLE);
3467 switch_channel_set_variable(caller_channel, SWITCH_SOFT_HOLDING_UUID_VARIABLE, NULL);
3468 }
3469
b43fa945 3470 if (holding && oglobals.idx != IDX_TIMEOUT && oglobals.idx != IDX_KEY_CANCEL && oglobals.idx < 0) {
f5b0b8e2
AM
3471 switch_core_session_t *holding_session;
3472
3473 if ((holding_session = switch_core_session_locate(holding))) {
7bbbb9cc
AM
3474 switch_channel_t *holding_channel = switch_core_session_get_channel(holding_session);
3475
3476 switch_channel_set_variable(holding_channel, SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE, "true");
3477
3478 if (caller_channel && switch_true(switch_channel_get_variable(caller_channel, "recording_follow_transfer"))) {
3479 switch_core_media_bug_transfer_recordings(session, originate_status[i].peer_session);
3480 }
3481
3482 if (switch_true(switch_channel_get_variable(holding_channel, "recording_follow_transfer"))) {
3483 switch_core_media_bug_transfer_recordings(holding_session, originate_status[i].peer_session);
3484 }
3485
f5b0b8e2
AM
3486 switch_core_session_rwunlock(holding_session);
3487 }
24a97292 3488 switch_channel_set_flag(originate_status[i].peer_channel, CF_LAZY_ATTENDED_TRANSFER);
886e1ddb 3489 switch_ivr_uuid_bridge(holding, switch_core_session_get_uuid(originate_status[i].peer_session));
f5b0b8e2 3490 holding = NULL;
886e1ddb 3491 } else {
945d1141
AM
3492 if (force_reason == SWITCH_CAUSE_LOSE_RACE || reason == SWITCH_CAUSE_LOSE_RACE) {
3493 switch_channel_set_variable(originate_status[i].peer_channel, "group_dial_status", "loser");
3494 }
2fa0c491 3495 switch_channel_hangup(originate_status[i].peer_channel, force_reason ? force_reason : reason);
117c0315 3496 }
dc3a6538 3497 }
e6a60a20
AM
3498 }
3499 }
886e1ddb 3500
450e63c0
AM
3501
3502
1dcb3b67 3503 if (oglobals.idx > IDX_NADA) {
450e63c0
AM
3504 if ((peer_session = originate_status[oglobals.idx].peer_session)) {
3505 peer_channel = switch_core_session_get_channel(originate_status[oglobals.idx].peer_session);
3506 }
e6a60a20
AM
3507 } else {
3508 status = SWITCH_STATUS_FALSE;
7c9ffb42 3509 if (caller_channel && peer_channel) {
e0c37c1f 3510 switch_process_import(oglobals.session, peer_channel, "import", NULL);
3d136b26 3511 }
69120105 3512 peer_channel = NULL;
e6a60a20
AM
3513 goto done;
3514 }
3515
3516 if (caller_channel) {
3517 if (switch_channel_test_flag(peer_channel, CF_ANSWERED)) {
4d9f7de2 3518 switch_channel_pass_callee_id(peer_channel, caller_channel);
d43af04e
AM
3519 if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE)) {
3520 status = SWITCH_STATUS_SUCCESS;
3521 } else {
d4f8a792 3522 status = switch_channel_answer(caller_channel);
d43af04e 3523 }
e6a60a20 3524 } else if (switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) {
d43af04e
AM
3525 if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE)) {
3526 status = SWITCH_STATUS_SUCCESS;
3527 } else {
882b82aa 3528 switch_channel_pass_callee_id(peer_channel, caller_channel);
d4f8a792 3529 status = switch_channel_pre_answer(caller_channel);
d43af04e 3530 }
5d47a937
AM
3531 } else {
3532 status = SWITCH_STATUS_SUCCESS;
3533 }
3534
3535 if (status != SWITCH_STATUS_SUCCESS) {
886e1ddb 3536 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(peer_channel), SWITCH_LOG_DEBUG, "%s Media Establishment Failed.\n",
757aa19e 3537 switch_channel_get_name(caller_channel));
5d47a937 3538 switch_channel_hangup(peer_channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
e6a60a20
AM
3539 }
3540 }
3541
3c349c27 3542 if (switch_channel_test_flag(peer_channel, CF_ANSWERED) ||
1dcb3b67
AM
3543 (oglobals.early_ok && switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) ||
3544 (oglobals.return_ring_ready && switch_channel_test_flag(peer_channel, CF_RING_READY))
50fc2ffa 3545 ) {
e6a60a20 3546 *bleg = peer_session;
697bb6ec
AM
3547
3548 if (oglobals.monitor_early_media_ring || oglobals.monitor_early_media_fail) {
3549 switch_ivr_stop_tone_detect_session(peer_session);
3550 switch_channel_set_private(peer_channel, "_oglobals_", NULL);
3551 }
3552
e6a60a20
AM
3553 status = SWITCH_STATUS_SUCCESS;
3554 } else {
3555 status = SWITCH_STATUS_FALSE;
3556 }
3557
3558 done:
886e1ddb 3559
98479fa6 3560 *cause = SWITCH_CAUSE_NONE;
e6a60a20 3561
a188af1c
AM
3562 if (caller_channel && !switch_channel_ready(caller_channel)) {
3563 status = SWITCH_STATUS_FALSE;
3564 }
3565
e6a60a20
AM
3566 if (status == SWITCH_STATUS_SUCCESS) {
3567 if (caller_channel) {
3568 switch_channel_set_variable(caller_channel, "originate_disposition", "call accepted");
7c9ffb42 3569 if (peer_channel) {
e0c37c1f 3570 switch_process_import(oglobals.session, peer_channel, "import", NULL);
9d98d49f
AM
3571
3572 if (switch_channel_test_flag(peer_channel, CF_ANSWERED)) {
3573 switch_channel_set_variable(caller_channel, "DIALSTATUS", "EARLY");
3574 } else {
3575 switch_channel_set_variable(caller_channel, "DIALSTATUS", "ANSWER");
3576 }
3577
7c9ffb42 3578 }
e6a60a20 3579 }
886e1ddb 3580 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals.session), SWITCH_LOG_DEBUG, "Originate Resulted in Success: [%s]\n",
757aa19e 3581 switch_channel_get_name(peer_channel));
e6a60a20
AM
3582 *cause = SWITCH_CAUSE_SUCCESS;
3583
3584 } else {
690d5b25 3585 const char *cdr_var = NULL;
864598ca
AM
3586 const char *json_cdr_var = NULL;
3587
21edf395 3588 switch_xml_t cdr = NULL;
864598ca
AM
3589 cJSON *json_cdr = NULL;
3590
3591 char *json_text;
690d5b25
AM
3592 char *xml_text;
3593 char buf[128] = "", buf2[128] = "";
3594
3595 if (caller_channel) {
3596 cdr_var = switch_channel_get_variable(caller_channel, "failed_xml_cdr_prefix");
3597 }
3598
864598ca
AM
3599 if (caller_channel) {
3600 json_cdr_var = switch_channel_get_variable(caller_channel, "failed_json_cdr_prefix");
3601 }
3602
e6a60a20 3603 if (peer_channel) {
cc06fdb5 3604 wait_for_cause(peer_channel);
886e1ddb 3605 *cause = switch_channel_get_cause(peer_channel);
e6a60a20
AM
3606 } else {
3607 for (i = 0; i < and_argc; i++) {
1dcb3b67 3608 if (!originate_status[i].peer_channel) {
e6a60a20
AM
3609 continue;
3610 }
1dcb3b67 3611 *cause = switch_channel_get_cause(originate_status[i].peer_channel);
e6a60a20
AM
3612 break;
3613 }
3614 }
886e1ddb 3615
690d5b25
AM
3616 if (cdr_var) {
3617 for (i = 0; i < and_argc; i++) {
bf4dbe09
AM
3618 switch_channel_t *channel;
3619
1dcb3b67 3620 if (!originate_status[i].peer_session) {
886e1ddb
AM
3621 continue;
3622 }
bf4dbe09
AM
3623
3624 channel = switch_core_session_get_channel(originate_status[i].peer_session);
886e1ddb 3625
8286dedd 3626 switch_channel_wait_for_state_timeout(channel, CS_REPORTING, 5000);
886e1ddb 3627
8286dedd
AM
3628 if (!switch_channel_test_flag(channel, CF_TIMESTAMP_SET)) {
3629 switch_channel_set_timestamps(channel);
bf4dbe09 3630 }
886e1ddb 3631
1dcb3b67 3632 if (switch_ivr_generate_xml_cdr(originate_status[i].peer_session, &cdr) == SWITCH_STATUS_SUCCESS) {
690d5b25
AM
3633 if ((xml_text = switch_xml_toxml(cdr, SWITCH_FALSE))) {
3634 switch_snprintf(buf, sizeof(buf), "%s_%d", cdr_var, ++cdr_total);
3635 switch_channel_set_variable(caller_channel, buf, xml_text);
3636 switch_safe_free(xml_text);
3637 }
3638 switch_xml_free(cdr);
3639 cdr = NULL;
3640 }
3641
3642 }
3643 switch_snprintf(buf, sizeof(buf), "%s_total", cdr_var);
3644 switch_snprintf(buf2, sizeof(buf2), "%d", cdr_total ? cdr_total : 0);
3645 switch_channel_set_variable(caller_channel, buf, buf2);
864598ca
AM
3646 }
3647
3648 if (json_cdr_var) {
3649 for (i = 0; i < and_argc; i++) {
3650 switch_channel_t *channel;
3651
3652 if (!originate_status[i].peer_session) {
3653 continue;
3654 }
3655
3656 channel = switch_core_session_get_channel(originate_status[i].peer_session);
3657
3658 switch_channel_wait_for_state_timeout(channel, CS_REPORTING, 5000);
3659
3660 if (!switch_channel_test_flag(channel, CF_TIMESTAMP_SET)) {
3661 switch_channel_set_timestamps(channel);
3662 }
3663
3664 if (switch_ivr_generate_json_cdr(originate_status[i].peer_session, &json_cdr, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) {
3665 json_text = cJSON_PrintUnformatted(json_cdr);
3666 switch_snprintf(buf, sizeof(buf), "%s_%d", json_cdr_var, ++cdr_total);
3667 switch_channel_set_variable(caller_channel, buf, json_text);
3668 // switch_safe_free(json_text);
3669 cJSON_Delete(json_cdr);
3670 json_cdr = NULL;
3671 }
3672
3673 }
3674 switch_snprintf(buf, sizeof(buf), "%s_total", json_cdr_var);
3675 switch_snprintf(buf2, sizeof(buf2), "%d", cdr_total ? cdr_total : 0);
3676 switch_channel_set_variable(caller_channel, buf, buf2);
690d5b25 3677 }
e6a60a20 3678
43ca3ee8
AM
3679 if (caller_channel && switch_channel_test_flag(caller_channel, CF_INTERCEPTED)) {
3680 *cause = SWITCH_CAUSE_PICKED_OFF;
3681 }
3682
e6a60a20
AM
3683 if (!*cause) {
3684 if (reason) {
3685 *cause = reason;
3686 } else if (caller_channel) {
3687 *cause = switch_channel_get_cause(caller_channel);
3688 } else {
3689 *cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
cc06fdb5
AM
3690 for (i = 0; i < and_argc; i++) {
3691 if (!peer_eligible(originate_status[i].peer_channel)) {
3692 continue;
3693 }
3694
3695 wait_for_cause(originate_status[i].peer_channel);
3696
9ecf187d 3697 if (switch_channel_down_nosig(originate_status[i].peer_channel)) {
cc06fdb5
AM
3698 *cause = switch_channel_get_cause(originate_status[i].peer_channel);
3699 break;
3700 }
3701
3702 }
e6a60a20
AM
3703 }
3704 }
3705
98479fa6 3706 if (*cause == SWITCH_CAUSE_SUCCESS || *cause == SWITCH_CAUSE_NONE) {
69120105
AM
3707 *cause = SWITCH_CAUSE_ORIGINATOR_CANCEL;
3708 }
3709
1dcb3b67 3710 if (oglobals.idx == IDX_CANCEL) {
d57e0387 3711 *cause = SWITCH_CAUSE_ORIGINATOR_CANCEL;
c2d5f970 3712 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals.session), SWITCH_LOG_DEBUG,
debdfb1a 3713 "Originate Cancelled by originator termination Cause: %d [%s]\n", *cause, switch_channel_cause2str(*cause));
e6a60a20 3714
7681f944
AM
3715 } else if (oglobals.idx == IDX_TIMEOUT) {
3716 *cause = SWITCH_CAUSE_NO_ANSWER;
e6a60a20 3717 } else {
70accd9f
AM
3718 if (oglobals.idx == IDX_XFER) {
3719 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals.session), SWITCH_LOG_DEBUG,
3720 "Originate Resulted in Attended Transfer Cause: %d [%s]\n", *cause, switch_channel_cause2str(*cause));
70accd9f
AM
3721 } else {
3722
3723 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals.session), SWITCH_LOG_DEBUG,
3724 "Originate Resulted in Error Cause: %d [%s]\n", *cause, switch_channel_cause2str(*cause));
3725 }
e6a60a20
AM
3726 }
3727 }
3728
3729 if (caller_channel) {
3730 switch_channel_set_variable(caller_channel, "originate_disposition", switch_channel_cause2str(*cause));
9d98d49f
AM
3731
3732 switch (*cause) {
3733 case SWITCH_CAUSE_ORIGINATOR_CANCEL:
3734 switch_channel_set_variable(caller_channel, "DIALSTATUS", "CANCEL");
3735 break;
3736 case SWITCH_CAUSE_USER_BUSY:
3737 switch_channel_set_variable(caller_channel, "DIALSTATUS", "BUSY");
3738 break;
3739 case SWITCH_CAUSE_NO_ANSWER:
3740 switch_channel_set_variable(caller_channel, "DIALSTATUS", "NOANSWER");
3741 break;
3742 case SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER:
e081e804 3743 case SWITCH_CAUSE_INVALID_PROFILE:
9d98d49f
AM
3744 switch_channel_set_variable(caller_channel, "DIALSTATUS", "INVALIDARGS");
3745 break;
3746 case SWITCH_CAUSE_CALL_REJECTED:
3747 switch_channel_set_variable(caller_channel, "DIALSTATUS", "DONTCALL");
3748 break;
3749 default:
3750 switch_channel_set_variable(caller_channel, "DIALSTATUS", switch_channel_cause2str(*cause));
3751 break;
3752 }
e6a60a20
AM
3753 }
3754
5cc8aebc 3755 early_state.ready = 0;
886e1ddb 3756
5cc8aebc
AM
3757 if (oglobals.ethread) {
3758 switch_status_t st;
3759 switch_thread_join(&st, oglobals.ethread);
3760 }
3761
3762 if (early_state.buffer) {
3763 switch_buffer_destroy(&early_state.buffer);
3764 }
3765
e6a60a20
AM
3766 if (ringback.fh) {
3767 switch_core_file_close(ringback.fh);
3768 ringback.fh = NULL;
69120105
AM
3769 } else if (ringback.audio_buffer) {
3770 teletone_destroy_session(&ringback.ts);
3771 switch_buffer_destroy(&ringback.audio_buffer);
3772 }
3773
1dcb3b67
AM
3774 if (oglobals.session) {
3775 switch_core_session_reset(oglobals.session, SWITCH_FALSE, SWITCH_TRUE);
ac1119e6 3776 }
bc2fc3fa 3777
68b0359c 3778 if (switch_core_codec_ready(&write_codec)) {
59ea2d2f 3779 switch_core_codec_destroy(&write_codec);
e6a60a20 3780 }
3c349c27 3781
e6a60a20 3782 for (i = 0; i < and_argc; i++) {
1af037cf 3783 switch_channel_state_t state;
392c687f 3784 switch_core_session_t *peer_session;
3099445a 3785 char *val;
1af037cf 3786
1dcb3b67 3787 if (!originate_status[i].peer_channel) {
e6a60a20
AM
3788 continue;
3789 }
3099445a
AM
3790
3791 if (session) {
3792 val = switch_core_session_sprintf(originate_status[i].peer_session, "%s;%s",
3793 switch_core_session_get_uuid(originate_status[i].peer_session),
3794 switch_channel_cause2str(switch_channel_get_cause(originate_status[i].peer_channel)));
3795
3796 switch_channel_add_variable_var_check(switch_core_session_get_channel(session), "originate_causes", val, SWITCH_FALSE, SWITCH_STACK_PUSH);
3797 }
886e1ddb
AM
3798
3799 if (status == SWITCH_STATUS_SUCCESS) {
1dcb3b67
AM
3800 switch_channel_clear_flag(originate_status[i].peer_channel, CF_ORIGINATING);
3801 if (bleg && *bleg && *bleg == originate_status[i].peer_session) {
50e9411c
AM
3802 continue;
3803 }
886e1ddb 3804 } else if ((state = switch_channel_get_state(originate_status[i].peer_channel)) < CS_HANGUP &&
1dcb3b67 3805 switch_channel_test_flag(originate_status[i].peer_channel, CF_ORIGINATING)) {
886e1ddb 3806 if (!(state == CS_RESET || switch_channel_test_flag(originate_status[i].peer_channel, CF_TRANSFER) ||
1dcb3b67
AM
3807 switch_channel_test_flag(originate_status[i].peer_channel, CF_REDIRECT) ||
3808 switch_channel_test_flag(originate_status[i].peer_channel, CF_BRIDGED))) {
43ca3ee8
AM
3809 if (caller_channel && switch_channel_test_flag(caller_channel, CF_INTERCEPTED)) {
3810 switch_channel_set_flag(originate_status[i].peer_channel, CF_INTERCEPT);
3811 }
1dcb3b67 3812 switch_channel_hangup(originate_status[i].peer_channel, *cause);
1af037cf 3813 }
eb2124ae 3814 }
1dcb3b67 3815 switch_channel_clear_flag(originate_status[i].peer_channel, CF_ORIGINATING);
50e9411c 3816
392c687f
AM
3817 peer_session = originate_status[i].peer_session;
3818 originate_status[i].peer_session = NULL;
3819 originate_status[i].peer_channel = NULL;
3820 switch_core_session_rwunlock(peer_session);
e6a60a20 3821 }
3c349c27 3822
2bc28110 3823 if (status == SWITCH_STATUS_SUCCESS || oglobals.idx == IDX_XFER) {
e6a60a20 3824 goto outer_for;
feb46019 3825 } else {
3a121a1b 3826 int ok = 1;
feb46019 3827
3a121a1b
AM
3828 if (fail_on_single_reject && check_reject && !switch_true(fail_on_single_reject_var)) {
3829 for (i = 0; i < and_argc; i++) {
3830 switch_channel_t *pchannel;
3831 const char *cause_str;
cd736a1c 3832
3a121a1b
AM
3833 if (!originate_status[i].peer_session) {
3834 continue;
3835 }
3836
3837 pchannel = switch_core_session_get_channel(originate_status[i].peer_session);
3838 wait_for_cause(pchannel);
3839
9ecf187d 3840 if (switch_channel_down_nosig(pchannel)) {
3a121a1b 3841 int neg, pos;
522c0d53 3842
3a121a1b 3843 cause_str = switch_channel_cause2str(switch_channel_get_cause(pchannel));
522c0d53 3844
3a121a1b
AM
3845 neg = *fail_on_single_reject_var == '!';
3846 pos = !!switch_stristr(cause_str, fail_on_single_reject_var);
522c0d53 3847
3a121a1b
AM
3848 if (neg) {
3849 pos = !pos;
3850 }
522c0d53
AM
3851
3852
3a121a1b
AM
3853 if (pos) {
3854 ok = 0;
3855 break;
feb46019
AM
3856 }
3857 }
3858 }
3859 }
3a121a1b
AM
3860
3861 if (!ok) {
feb46019
AM
3862 goto outer_for;
3863 }
5b6d1cd3
AM
3864
3865 if (to && !oglobals.continue_on_timeout) {
3866 goto outer_for;
3867 }
e6a60a20
AM
3868 }
3869 }
3870 }
3871 outer_for:
3872 switch_safe_free(loop_data);
3873 switch_safe_free(odata);
329033ee
AM
3874 switch_safe_free(oglobals.file);
3875 switch_safe_free(oglobals.error_file);
eb2124ae
AM
3876
3877 if (bleg && status != SWITCH_STATUS_SUCCESS) {
3878 *bleg = NULL;
3879 }
3880
b15ac311
MJ
3881 if (bleg && !*bleg && status == SWITCH_STATUS_SUCCESS) {
3882 status = SWITCH_STATUS_FALSE;
3883 }
3884
dc2c11f1 3885 if (bleg && *bleg) {
233d3164
AM
3886 switch_channel_t *bchan = switch_core_session_get_channel(*bleg);
3887
3963930e 3888 if (session && caller_channel) {
45110ff3 3889 switch_caller_profile_t *cloned_profile, *peer_profile = switch_channel_get_caller_profile(switch_core_session_get_channel(*bleg));
886e1ddb 3890
45110ff3 3891 if (peer_profile) {
b7db7531 3892 if ((cloned_profile = switch_caller_profile_clone(session, peer_profile)) != 0) {
45110ff3
AM
3893 switch_channel_set_originatee_caller_profile(caller_channel, cloned_profile);
3894 }
3895 }
2eae19e6
AM
3896
3897 switch_channel_set_variable(caller_channel, SWITCH_SIGNAL_BOND_VARIABLE, switch_core_session_get_uuid(*bleg));
e31a35a7 3898 // Now main SWITCH_SIGNAL_BOND_VARIABLE is populated, don't need this one anymore...
8bb55ed4 3899 switch_channel_set_variable(caller_channel, SWITCH_ORIGINATE_SIGNAL_BOND_VARIABLE, NULL);
45110ff3 3900 }
233d3164 3901
88a6ac2f 3902
bf20f524
AM
3903 switch_channel_execute_on(bchan, SWITCH_CHANNEL_EXECUTE_ON_POST_ORIGINATE_VARIABLE);
3904 switch_channel_api_on(bchan, SWITCH_CHANNEL_API_ON_POST_ORIGINATE_VARIABLE);
3905
3906
88a6ac2f
AM
3907 while(switch_channel_state_change_pending(bchan)) {
3908 switch_cond_next();
3909 }
3910
924c5241 3911 switch_channel_audio_sync(bchan);
45110ff3 3912
924c5241
AM
3913 if (caller_channel) {
3914 switch_channel_audio_sync(caller_channel);
3915 }
cb5096db
AM
3916 }
3917
d43af04e
AM
3918 if (oglobals.session) {
3919 switch_ivr_parse_all_events(oglobals.session);
3920 }
3921
8187f4a3 3922 if (oglobals.session && status == SWITCH_STATUS_SUCCESS) {
1dcb3b67 3923 switch_ivr_sleep(oglobals.session, 0, SWITCH_TRUE, NULL);
cb5096db 3924 }
3c349c27 3925
a579a283 3926 if (var_event && var_event != ovars) {
9ec90012
AM
3927 switch_event_destroy(&var_event);
3928 }
feb46019 3929
3608c834 3930 switch_safe_free(write_frame.data);
feb46019 3931 switch_safe_free(fail_on_single_reject_var);
886e1ddb 3932
6cdb4688
AM
3933 if (force_reason != SWITCH_CAUSE_NONE) {
3934 *cause = force_reason;
3935 }
3936
aaeb69d6 3937 if (caller_channel) {
c9d6b801
AM
3938
3939 switch_channel_execute_on(caller_channel, SWITCH_CHANNEL_EXECUTE_ON_POST_ORIGINATE_VARIABLE);
3940 switch_channel_api_on(caller_channel, SWITCH_CHANNEL_API_ON_POST_ORIGINATE_VARIABLE);
3941
aaeb69d6
AM
3942 switch_channel_clear_flag(caller_channel, CF_ORIGINATOR);
3943 switch_channel_clear_flag(caller_channel, CF_XFER_ZOMBIE);
7681f944 3944
6cdb4688
AM
3945 if (hangup_on_single_reject) {
3946 switch_channel_hangup(caller_channel, *cause);
3947 }
78c31eaa 3948 }
1239e32d 3949
6cdb4688 3950
cca9c367
AM
3951 switch_core_destroy_memory_pool(&oglobals.pool);
3952
e6a60a20
AM
3953 return status;
3954}
aab6766e
BW
3955
3956/* For Emacs:
3957 * Local Variables:
3958 * mode:c
b0ad7ab5 3959 * indent-tabs-mode:t
aab6766e
BW
3960 * tab-width:4
3961 * c-basic-offset:4
3962 * End:
3963 * For VIM:
32adc789 3964 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
aab6766e 3965 */