]> git.ipfire.org Git - thirdparty/freeswitch.git/blame - src/switch_ivr_originate.c
save history when stoping now
[thirdparty/freeswitch.git] / src / switch_ivr_originate.c
CommitLineData
e6a60a20
AM
1/*
2 * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
babb2f83 3 * Copyright (C) 2005-2009, 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
AM
34#include <switch.h>
35
36static const switch_state_handler_table_t originate_state_handlers;
37
4b929592 38static switch_status_t originate_on_consume_media_transmit(switch_core_session_t *session)
a58173d2
AM
39{
40 switch_channel_t *channel = switch_core_session_get_channel(session);
3c349c27 41
32bcc886
AM
42 /* testing out not using this, we probably don't need it anymore now that we have audio sync */
43#if 0
fda8c44e
BW
44 if (!switch_channel_test_flag(channel, CF_PROXY_MODE)) {
45 while (switch_channel_get_state(channel) == CS_CONSUME_MEDIA && !switch_channel_test_flag(channel, CF_TAGGED)) {
abb2691b
AM
46 if (!switch_channel_media_ready(channel)) {
47 switch_yield(10000);
48 } else {
49 switch_ivr_sleep(session, 10, SWITCH_FALSE, NULL);
50 }
fda8c44e
BW
51 }
52 }
32bcc886 53#endif
fda8c44e 54
a58173d2
AM
55 switch_channel_clear_state_handler(channel, &originate_state_handlers);
56
57 return SWITCH_STATUS_FALSE;
58}
59
4b929592 60static switch_status_t originate_on_routing(switch_core_session_t *session)
e6a60a20 61{
482badff 62 switch_channel_t *channel = switch_core_session_get_channel(session);
e6a60a20 63
9bcc841b
AM
64 if (switch_channel_get_state(channel) == CS_ROUTING) {
65 /* put the channel in a passive state until it is answered */
66 switch_channel_set_state(channel, CS_CONSUME_MEDIA);
67 }
a58173d2 68
e6a60a20
AM
69 return SWITCH_STATUS_FALSE;
70}
71
72static const switch_state_handler_table_t originate_state_handlers = {
73 /*.on_init */ NULL,
4b929592 74 /*.on_routing */ originate_on_routing,
e6a60a20
AM
75 /*.on_execute */ NULL,
76 /*.on_hangup */ NULL,
4b929592
AM
77 /*.on_exchange_media */ NULL,
78 /*.on_soft_execute */ originate_on_consume_media_transmit,
79 /*.on_consume_media */ originate_on_consume_media_transmit
e6a60a20
AM
80};
81
1dcb3b67
AM
82
83typedef struct {
84 switch_core_session_t *peer_session;
85 switch_channel_t *peer_channel;
86 switch_caller_profile_t *caller_profile;
87 uint8_t ring_ready;
88 uint8_t early_media;
89 uint8_t answered;
29c616b9
AM
90 uint32_t per_channel_timelimit_sec;
91 uint32_t per_channel_progress_timelimit_sec;
d7a12df5 92 uint32_t per_channel_delay_start;
1dcb3b67
AM
93} originate_status_t;
94
95
96typedef struct {
97 switch_core_session_t *session;
98 int32_t idx;
99 uint32_t hups;
100 char file[512];
101 char key[80];
102 uint8_t early_ok;
103 uint8_t ring_ready;
bcb20f7a 104 uint8_t instant_ringback;
1dcb3b67
AM
105 uint8_t sent_ring;
106 uint8_t progress;
107 uint8_t return_ring_ready;
697bb6ec
AM
108 uint8_t monitor_early_media_ring;
109 uint8_t monitor_early_media_fail;
effb166b
AM
110 uint8_t gen_ringback;
111 uint8_t ignore_early_media;
112 uint8_t ignore_ring_ready;
cf4b7672
AM
113 int monitor_early_media_ring_count;
114 int monitor_early_media_ring_total;
bdf8f594 115 int cancel_timeout;
5b6d1cd3 116 int continue_on_timeout;
757aa19e
AM
117 int ringback_ok;
118 int sending_ringback;
1dcb3b67
AM
119} originate_global_t;
120
121
122
e6a60a20 123typedef enum {
aaeb69d6 124 IDX_KEY_CANCEL = -4,
eaf6abfb 125 IDX_TIMEOUT = -3,
e6a60a20
AM
126 IDX_CANCEL = -2,
127 IDX_NADA = -1
128} abort_t;
129
130struct key_collect {
131 char *key;
132 char *file;
133 switch_core_session_t *session;
134};
135
3c349c27 136static void *SWITCH_THREAD_FUNC collect_thread_run(switch_thread_t *thread, void *obj)
e6a60a20
AM
137{
138 struct key_collect *collect = (struct key_collect *) obj;
139 switch_channel_t *channel = switch_core_session_get_channel(collect->session);
ffb989e4 140 char buf[10] = SWITCH_BLANK_STRING;
e6a60a20
AM
141 char *p, term;
142
f9d1c799
AM
143 if (collect->session) {
144 if (switch_core_session_read_lock(collect->session) != SWITCH_STATUS_SUCCESS) {
145 return NULL;
146 }
147 } else {
148 return NULL;
149 }
150
71054917 151 switch_ivr_sleep(collect->session, 0, SWITCH_TRUE, NULL);
cb5096db 152
e6a60a20
AM
153 if (!strcasecmp(collect->key, "exec")) {
154 char *data;
1d74ab74 155 switch_application_interface_t *application_interface;
e6a60a20
AM
156 char *app_name, *app_data;
157
158 if (!(data = collect->file)) {
159 goto wbreak;
160 }
161
162 app_name = data;
163
164 if ((app_data = strchr(app_name, ' '))) {
165 *app_data++ = '\0';
166 }
167
168 if ((application_interface = switch_loadable_module_get_application_interface(app_name)) == 0) {
c2d5f970 169 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(collect->session), SWITCH_LOG_ERROR, "Invalid Application %s\n", app_name);
e6a60a20 170 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
722b8306 171 UNPROTECT_INTERFACE(application_interface);
e6a60a20
AM
172 goto wbreak;
173 }
174
175 if (!application_interface->application_function) {
c2d5f970 176 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(collect->session), SWITCH_LOG_ERROR, "No Function for %s\n", app_name);
e6a60a20
AM
177 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
178 goto wbreak;
179 }
180
7da38730 181 switch_core_session_exec(collect->session, application_interface, app_data);
3c349c27 182
9556be51 183 if (switch_channel_up(channel)) {
e6a60a20
AM
184 switch_channel_set_flag(channel, CF_WINNER);
185 }
186 goto wbreak;
187 }
188
c0d1ce24 189 if (!switch_channel_up(channel)) {
e6a60a20
AM
190 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
191 goto wbreak;
192 }
193
194 while (switch_channel_ready(channel)) {
195 memset(buf, 0, sizeof(buf));
196
197 if (collect->file) {
198 switch_input_args_t args = { 0 };
199 args.buf = buf;
200 args.buflen = sizeof(buf);
4fe4848a
AM
201 if (switch_ivr_play_file(collect->session, NULL, collect->file, &args) != SWITCH_STATUS_SUCCESS) {
202 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(collect->session), SWITCH_LOG_ERROR, "%s Error Playing File!", switch_channel_get_name(channel));
203 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
204 }
e6a60a20 205 } else {
df749a42 206 switch_ivr_collect_digits_count(collect->session, buf, sizeof(buf), 1, SWITCH_BLANK_STRING, &term, 0, 0, 0);
e6a60a20
AM
207 }
208
209 for (p = buf; *p; p++) {
210 if (*collect->key == *p) {
211 switch_channel_set_flag(channel, CF_WINNER);
212 goto wbreak;
213 }
214 }
215 }
f9d1c799
AM
216 wbreak:
217
218 switch_core_session_rwunlock(collect->session);
e6a60a20
AM
219
220 return NULL;
221}
222
223static void launch_collect_thread(struct key_collect *collect)
224{
225 switch_thread_t *thread;
226 switch_threadattr_t *thd_attr = NULL;
227
228 switch_threadattr_create(&thd_attr, switch_core_session_get_pool(collect->session));
229 switch_threadattr_detach_set(thd_attr, 1);
230 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
debdfb1a 231 switch_thread_create(&thread, thd_attr, collect_thread_run, collect, switch_core_session_get_pool(collect->session));
e6a60a20
AM
232}
233
478efc5f
AM
234static int check_per_channel_timeouts(originate_global_t *oglobals,
235 originate_status_t *originate_status,
4ed389f9
AM
236 int max,
237 time_t start)
238{
160535da
AM
239 int x = 0,i,delayed_channels=0,active_channels=0;
240 uint32_t early_exit_time=0, delayed_min=0;
241
0463541d 242 time_t elapsed = switch_epoch_time_now(NULL) - start;
4ed389f9 243
bdf8f594
AM
244 if (oglobals->cancel_timeout > 0) {
245 return 0;
246 }
160535da 247 for (i = 0; i < max; i++) {
757aa19e
AM
248 if (originate_status[i].peer_channel && switch_channel_get_state(originate_status[i].peer_channel) != CS_DESTROY &&
249 switch_channel_get_state(originate_status[i].peer_channel) != CS_REPORTING) {
160535da
AM
250 if (originate_status[i].per_channel_delay_start) {
251 delayed_channels++;
252 } else {
253 active_channels++;
254 }
255 }
256 }
bdf8f594 257
160535da
AM
258 if (active_channels == 0 && delayed_channels) {
259 for (i = 0; i < max; i++) {
757aa19e
AM
260 if ( originate_status[i].peer_channel && originate_status[i].per_channel_delay_start &&
261 (! delayed_min || delayed_min > originate_status[i].per_channel_delay_start) ) {
160535da
AM
262 delayed_min = originate_status[i].per_channel_delay_start;
263 }
264 }
05d6342f 265 early_exit_time = delayed_min - (uint32_t) elapsed;
160535da 266 }
4ed389f9 267 for (i = 0; i < max; i++) {
757aa19e
AM
268 if (originate_status[i].peer_channel && originate_status[i].per_channel_delay_start &&
269 (elapsed > originate_status[i].per_channel_delay_start || active_channels == 0) ) {
160535da
AM
270 if (active_channels == 0) {
271 if (originate_status[i].per_channel_timelimit_sec) {
757aa19e
AM
272 if (originate_status[i].per_channel_timelimit_sec > early_exit_time) {
273 /* 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 274 originate_status[i].per_channel_timelimit_sec -= early_exit_time;
757aa19e 275 } else {
160535da 276 originate_status[i].per_channel_timelimit_sec = 1;
757aa19e 277 }
160535da
AM
278 }
279 if (originate_status[i].per_channel_progress_timelimit_sec) {
757aa19e
AM
280 if (originate_status[i].per_channel_progress_timelimit_sec > early_exit_time) {
281 /* 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 282 originate_status[i].per_channel_progress_timelimit_sec -= early_exit_time;
757aa19e 283 } else {
160535da 284 originate_status[i].per_channel_progress_timelimit_sec = 1;
757aa19e 285 }
160535da
AM
286 }
287 originate_status[i].per_channel_delay_start -= delayed_min;
288 } else {
289 originate_status[i].per_channel_delay_start = 0;
290 }
291
292 if (! originate_status[i].per_channel_delay_start) {
293 switch_channel_clear_flag(originate_status[i].peer_channel, CF_BLOCK_STATE);
294 }
d7a12df5
AM
295 }
296
9556be51 297 if (originate_status[i].peer_channel && switch_channel_up(originate_status[i].peer_channel)) {
29c616b9 298 if (originate_status[i].per_channel_progress_timelimit_sec && elapsed > originate_status[i].per_channel_progress_timelimit_sec &&
4ed389f9 299 !(
1dcb3b67
AM
300 switch_channel_test_flag(originate_status[i].peer_channel, CF_RING_READY) ||
301 switch_channel_test_flag(originate_status[i].peer_channel, CF_ANSWERED) ||
478efc5f 302 (!oglobals->monitor_early_media_ring && switch_channel_test_flag(originate_status[i].peer_channel, CF_EARLY_MEDIA))
4ed389f9
AM
303 )
304 ) {
1dcb3b67 305 switch_channel_hangup(originate_status[i].peer_channel, SWITCH_CAUSE_PROGRESS_TIMEOUT);
4ed389f9
AM
306 x++;
307 }
29c616b9 308 if (originate_status[i].per_channel_timelimit_sec && elapsed > originate_status[i].per_channel_timelimit_sec) {
1dcb3b67 309 switch_channel_hangup(originate_status[i].peer_channel, SWITCH_CAUSE_ALLOTTED_TIMEOUT);
4ed389f9
AM
310 x++;
311 }
312 }
313 }
314
315 return x;
316}
317
697bb6ec
AM
318static switch_bool_t monitor_callback(switch_core_session_t *session, const char *app, const char *data)
319{
320 if (app) {
321 switch_channel_t *channel = switch_core_session_get_channel(session);
322 if (!strcmp(app, "fail")) {
33a3bcf5
AM
323 const char *bd = switch_channel_get_variable(channel, "monitor_fail_dispo");
324 if (!bd) {
325 bd = "monitor_early_media_fail";
326 }
327 switch_channel_set_variable(channel, "originate_disposition", bd);
697bb6ec
AM
328 switch_channel_hangup(channel, data ? switch_channel_str2cause(data) : SWITCH_CAUSE_USER_BUSY);
329 } else if (!strcmp(app, "ring")) {
330 originate_global_t *oglobals = (originate_global_t *) switch_channel_get_private(channel, "_oglobals_");
33a3bcf5
AM
331 const char *bd = switch_channel_get_variable(channel, "monitor_ring_dispo");
332 if (!bd) {
333 bd = "monitor_early_media_ring";
334 }
335 switch_channel_set_variable(channel, "originate_disposition", bd);
ba77f232 336
697bb6ec 337 if (oglobals) {
ba77f232 338 if (oglobals->monitor_early_media_ring_total && ++oglobals->monitor_early_media_ring_count < oglobals->monitor_early_media_ring_total) {
c2d5f970 339 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Ring %d/%d\n",
ba77f232
AM
340 oglobals->monitor_early_media_ring_count, oglobals->monitor_early_media_ring_total);
341 return SWITCH_TRUE;
342 }
343
697bb6ec 344 switch_channel_set_private(channel, "_oglobals_", NULL);
29d76292
AM
345
346 if (!oglobals->progress) {
347 oglobals->progress = 1;
348 }
349
effb166b 350 if (!oglobals->ring_ready && !oglobals->ignore_ring_ready) {
29d76292
AM
351 oglobals->ring_ready = 1;
352 }
effb166b
AM
353
354 if (!oglobals->ignore_early_media && !oglobals->early_ok) {
355 oglobals->early_ok = 1;
356 }
697bb6ec
AM
357 }
358 }
359 }
360
361 return SWITCH_FALSE;
362}
363
dc2a354c 364static uint8_t check_channel_status(originate_global_t *oglobals, originate_status_t *originate_status, uint32_t len)
e6a60a20
AM
365{
366
367 uint32_t i;
dc2a354c 368 uint8_t rval = 0;
13c4da7b
AM
369 switch_channel_t *caller_channel = NULL;
370 int pindex = -1;
cf4b7672 371 char bug_key[256] = "";
757aa19e 372 int send_ringback = 0;
cf4b7672 373
dc2a354c
MJ
374 oglobals->hups = 0;
375 oglobals->idx = IDX_NADA;
cf4b7672 376
13c4da7b 377
1dcb3b67
AM
378 if (oglobals->session) {
379 caller_channel = switch_core_session_get_channel(oglobals->session);
1cbd982a
AM
380 if (switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE)) {
381 caller_channel = NULL;
382 }
13c4da7b 383 }
1dcb3b67 384
3c349c27 385
e6a60a20 386 for (i = 0; i < len; i++) {
69120105 387 switch_channel_state_t state;
ba77f232 388 if (!(originate_status[i].peer_channel && originate_status[i].peer_session)) {
90c7921f 389 oglobals->hups++;
e6a60a20
AM
390 continue;
391 }
1dcb3b67
AM
392
393 if (switch_channel_test_flag(originate_status[i].peer_channel, CF_RING_READY)) {
394 if (!originate_status[i].ring_ready) {
395 originate_status[i].ring_ready = 1;
396 }
397
757aa19e
AM
398 if (oglobals->sending_ringback == 1) {
399 send_ringback++;
400 pindex = (uint32_t) i;
401 } else {
402 if (!oglobals->ring_ready) {
403 oglobals->ring_ready = 1;
404 if (caller_channel && !oglobals->ignore_ring_ready) {
405 if (len == 1) {
406 switch_channel_pass_callee_id(originate_status[0].peer_channel, caller_channel);
407 }
408 switch_channel_ring_ready(caller_channel);
409 oglobals->sent_ring = 1;
4d9f7de2 410 }
59b94dfa 411 }
1dcb3b67 412 }
e6a60a20 413 }
90c7921f 414
1dcb3b67 415 if (switch_channel_test_flag(originate_status[i].peer_channel, CF_EARLY_MEDIA)) {
757aa19e
AM
416
417 if (oglobals->sending_ringback == 1) {
418 send_ringback++;
419 pindex = (uint32_t) i;
420 } else if (!oglobals->sent_ring && oglobals->ignore_early_media == 2 && len == 1 && caller_channel && !oglobals->ignore_ring_ready) {
e072a609
AM
421 switch_channel_pass_callee_id(originate_status[0].peer_channel, caller_channel);
422 switch_channel_ring_ready(caller_channel);
423 oglobals->sent_ring = 1;
424 }
425
1dcb3b67
AM
426 if (!originate_status[i].early_media) {
427 originate_status[i].early_media = 1;
428 if (oglobals->early_ok) {
429 pindex = i;
430 }
697bb6ec
AM
431
432 if (oglobals->monitor_early_media_fail) {
433 const char *var = switch_channel_get_variable(originate_status[i].peer_channel, "monitor_early_media_fail");
df7637f6 434 if (!zstr(var)) {
697bb6ec
AM
435 char *fail_array[128] = {0};
436 int fail_count = 0;
437 char *fail_data = strdup(var);
438 int fx;
ba77f232
AM
439 int y = 0;
440
697bb6ec
AM
441 switch_assert(fail_data);
442 fail_count = switch_separate_string(fail_data, '!', fail_array, (sizeof(fail_array) / sizeof(fail_array[0])));
443
444 for(fx = 0; fx < fail_count; fx++) {
445 char *cause = fail_array[fx];
446 int hits = 2;
447 char *p, *q;
448
449 if (!(p = strchr(cause, ':'))) {
c2d5f970 450 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originate_status[i].peer_session), SWITCH_LOG_ERROR, "Parse Error\n");
697bb6ec
AM
451 continue;
452 }
453 *p++ = '\0';
454
455
456 if (!p) {
c2d5f970 457 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originate_status[i].peer_session), SWITCH_LOG_ERROR, "Parse Error\n");
697bb6ec
AM
458 continue;
459 }
460
461
462 if (!(hits = atoi(p))) {
463 hits = 2;
464 }
465
466
467 if (!(p = strchr(p, ':'))) {
c2d5f970 468 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originate_status[i].peer_session), SWITCH_LOG_ERROR, "Parse Error\n");
697bb6ec
AM
469 continue;
470 }
471 *p++ = '\0';
472
473 if (!p) {
c2d5f970 474 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originate_status[i].peer_session), SWITCH_LOG_ERROR, "Parse Error\n");
697bb6ec
AM
475 continue;
476 }
477
478 for(q = p; q && *q; q++) {
479 if (*q == '+') {
480 *q = ',';
481 }
482 }
ba77f232 483 switch_snprintf(bug_key, sizeof(bug_key), "monitor_early_media_fail_%d", ++y);
697bb6ec 484 switch_ivr_tone_detect_session(originate_status[i].peer_session,
ba77f232
AM
485 bug_key,
486 p, "r", 0,
487 hits,
488 "fail",
489 cause, monitor_callback);
697bb6ec
AM
490
491 }
492
493 switch_safe_free(fail_data);
494
495 }
496 }
497
498 if (oglobals->monitor_early_media_ring) {
499 const char *var = switch_channel_get_variable(originate_status[i].peer_channel, "monitor_early_media_ring");
ba77f232 500 const char *var_total = switch_channel_get_variable(originate_status[i].peer_channel, "monitor_early_media_ring_total");
df7637f6 501 if (!zstr(var)) {
697bb6ec
AM
502 char *ring_array[128] = {0};
503 int ring_count = 0;
504 char *ring_data = strdup(var);
505 int fx;
ba77f232
AM
506 int y = 0;
507
697bb6ec
AM
508 switch_assert(ring_data);
509 ring_count = switch_separate_string(ring_data, '!', ring_array, (sizeof(ring_array) / sizeof(ring_array[0])));
510
511 for(fx = 0; fx < ring_count; fx++) {
512 int hits = 2;
513 char *p = ring_array[fx], *q;
514
dbeb3aa4 515 if (!p) {
c2d5f970 516 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originate_status[i].peer_session), SWITCH_LOG_ERROR, "Parse Error\n");
dbeb3aa4
MJ
517 continue;
518 }
519
697bb6ec
AM
520 if (!(hits = atoi(p))) {
521 hits = 2;
522 }
523
524 if (!(p = strchr(p, ':'))) {
c2d5f970 525 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originate_status[i].peer_session), SWITCH_LOG_ERROR, "Parse Error\n");
697bb6ec
AM
526 continue;
527 }
528 *p++ = '\0';
529
530 if (!p) {
c2d5f970 531 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originate_status[i].peer_session), SWITCH_LOG_ERROR, "Parse Error\n");
697bb6ec
AM
532 continue;
533 }
534
535 for(q = p; q && *q; q++) {
536 if (*q == '+') {
537 *q = ',';
538 }
539 }
540
541 switch_channel_set_private(originate_status[i].peer_channel, "_oglobals_", oglobals);
ba77f232 542 switch_snprintf(bug_key, sizeof(bug_key), "monitor_early_media_ring_%d", ++y);
697bb6ec 543 switch_ivr_tone_detect_session(originate_status[i].peer_session,
ba77f232 544 bug_key,
697bb6ec
AM
545 p, "r", 0, hits, "ring", NULL, monitor_callback);
546
547 }
548
ba77f232
AM
549 if (var_total) {
550 int tmp = atoi(var_total);
551 if (tmp > 0 && tmp < 100) {
757aa19e
AM
552 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originate_status[i].peer_session), SWITCH_LOG_DEBUG,
553 "%s setting ring total to %d\n",
ba77f232
AM
554 switch_channel_get_name(originate_status[i].peer_channel), tmp);
555 oglobals->monitor_early_media_ring_total = tmp;
556 }
557 }
757aa19e 558
697bb6ec
AM
559 switch_safe_free(ring_data);
560
561 }
562 }
1dcb3b67 563 }
effb166b 564
29d76292
AM
565 if (!oglobals->monitor_early_media_ring) {
566
567 if (!oglobals->progress) {
568 oglobals->progress = 1;
569 }
478efc5f 570
effb166b 571 if (!oglobals->ring_ready && !oglobals->ignore_ring_ready) {
29d76292 572 oglobals->ring_ready = 1;
59b94dfa 573
29d76292 574 }
1dcb3b67 575 }
f33aa021 576 }
1dcb3b67 577
59b94dfa 578 switch_ivr_parse_all_events(originate_status[i].peer_session);
8b1ad09d 579
1dcb3b67
AM
580 state = switch_channel_get_state(originate_status[i].peer_channel);
581 if (state >= CS_HANGUP || state == CS_RESET || switch_channel_test_flag(originate_status[i].peer_channel, CF_TRANSFER) ||
582 switch_channel_test_flag(originate_status[i].peer_channel, CF_REDIRECT) ||
583 switch_channel_test_flag(originate_status[i].peer_channel, CF_BRIDGED) ||
584 !switch_channel_test_flag(originate_status[i].peer_channel, CF_ORIGINATING)
3c349c27 585 ) {
1dcb3b67
AM
586 (oglobals->hups)++;
587 } else if ((switch_channel_test_flag(originate_status[i].peer_channel, CF_ANSWERED) ||
588 (oglobals->early_ok && switch_channel_test_flag(originate_status[i].peer_channel, CF_EARLY_MEDIA)) ||
589 (oglobals->ring_ready && oglobals->return_ring_ready && len == 1 &&
590 switch_channel_test_flag(originate_status[i].peer_channel, CF_RING_READY))
591 )
592 && !switch_channel_test_flag(originate_status[i].peer_channel, CF_TAGGED)
593 ) {
13c4da7b 594
df7637f6 595 if (!zstr(oglobals->key)) {
e6a60a20
AM
596 struct key_collect *collect;
597
bdf8f594
AM
598 if (oglobals->cancel_timeout < 0) {
599 oglobals->cancel_timeout = 1;
600 }
601
1dcb3b67
AM
602 if ((collect = switch_core_session_alloc(originate_status[i].peer_session, sizeof(*collect)))) {
603 switch_channel_set_flag(originate_status[i].peer_channel, CF_TAGGED);
df7637f6 604 if (!zstr(oglobals->key)) {
1dcb3b67
AM
605 collect->key = switch_core_session_strdup(originate_status[i].peer_session, oglobals->key);
606 }
df7637f6 607 if (!zstr(oglobals->file)) {
1dcb3b67 608 collect->file = switch_core_session_strdup(originate_status[i].peer_session, oglobals->file);
e6a60a20 609 }
32bcc886 610 switch_channel_audio_sync(originate_status[i].peer_channel);
1dcb3b67 611 collect->session = originate_status[i].peer_session;
e6a60a20
AM
612 launch_collect_thread(collect);
613 }
614 } else {
1dcb3b67 615 oglobals->idx = i;
13c4da7b
AM
616 pindex = (uint32_t) i;
617 rval = 0;
618 goto end;
e6a60a20
AM
619
620 }
1dcb3b67
AM
621 } else if (switch_channel_test_flag(originate_status[i].peer_channel, CF_WINNER)) {
622 oglobals->idx = i;
13c4da7b
AM
623 rval = 0;
624 pindex = (uint32_t) i;
625 goto end;
e6a60a20
AM
626 }
627 }
628
1dcb3b67 629 if (oglobals->hups == len) {
13c4da7b 630 rval = 0;
e6a60a20 631 } else {
13c4da7b
AM
632 rval = 1;
633 }
634
635 end:
636
637 if (pindex > -1 && caller_channel && switch_channel_ready(caller_channel) && !switch_channel_media_ready(caller_channel)) {
638 const char *var = switch_channel_get_variable(caller_channel, "inherit_codec");
639 if (switch_true(var)) {
7865668e 640 switch_codec_implementation_t impl = { 0 };
29cff9c6 641 char tmp[128] = "";
13c4da7b 642
29cff9c6 643
7865668e
AM
644 if (switch_core_session_get_read_impl(originate_status[pindex].peer_session, &impl) == SWITCH_STATUS_SUCCESS) {
645 switch_snprintf(tmp, sizeof(tmp), "%s@%uh@%ui", impl.iananame, impl.samples_per_second, impl.microseconds_per_packet / 1000);
646 switch_channel_set_variable(caller_channel, "absolute_codec_string", tmp);
757aa19e
AM
647 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_DEBUG, "Setting codec string on %s to %s\n",
648 switch_channel_get_name(caller_channel), tmp);
7865668e 649 } else {
757aa19e
AM
650 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(originate_status[pindex].peer_channel), SWITCH_LOG_WARNING,
651 "Error inheriting codec. Channel %s has no read codec yet.\n",
7865668e
AM
652 switch_channel_get_name(originate_status[pindex].peer_channel));
653 }
29cff9c6 654
13c4da7b 655 }
e6a60a20 656 }
757aa19e
AM
657
658 if (send_ringback) {
659 oglobals->sending_ringback++;
660 }
13c4da7b
AM
661
662 return rval;
663
e6a60a20
AM
664}
665
666struct ringback {
667 switch_buffer_t *audio_buffer;
e6a60a20
AM
668 teletone_generation_session_t ts;
669 switch_file_handle_t fhb;
670 switch_file_handle_t *fh;
1136fcec 671 int silence;
e6a60a20
AM
672 uint8_t asis;
673};
674
675typedef struct ringback ringback_t;
676
3c349c27 677static int teletone_handler(teletone_generation_session_t *ts, teletone_tone_map_t *map)
e6a60a20
AM
678{
679 ringback_t *tto = ts->user_data;
680 int wrote;
681
682 if (!tto) {
683 return -1;
684 }
685 wrote = teletone_mux_tones(ts, map);
686 switch_buffer_write(tto->audio_buffer, ts->buffer, wrote * 2);
687
688 return 0;
689}
690
69120105
AM
691
692SWITCH_DECLARE(switch_status_t) switch_ivr_wait_for_answer(switch_core_session_t *session, switch_core_session_t *peer_session)
693{
047e3dd7 694 switch_channel_t *caller_channel = NULL;
482badff 695 switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session);
3c349c27 696 const char *ringback_data = NULL;
69120105
AM
697 switch_frame_t write_frame = { 0 };
698 switch_codec_t write_codec = { 0 };
482badff 699 switch_codec_t *read_codec = switch_core_session_get_read_codec(session);
69120105
AM
700 uint8_t pass = 0;
701 ringback_t ringback = { 0 };
69120105
AM
702 switch_frame_t *read_frame = NULL;
703 switch_status_t status = SWITCH_STATUS_SUCCESS;
69120105 704 int timelimit = 60;
ee44d83b 705 const char *var;
69120105 706 switch_time_t start = 0;
f8b442da 707 const char *cancel_key = NULL;
aaeb69d6 708 switch_channel_state_t wait_state = 0;
3c349c27 709
ee44d83b
AM
710 switch_assert(peer_channel);
711
aaeb69d6
AM
712 if (switch_channel_get_state(peer_channel) == CS_RESET) {
713 switch_channel_set_state(peer_channel, CS_SOFT_EXECUTE);
714 }
715
047e3dd7
AM
716 if (session) {
717 caller_channel = switch_core_session_get_channel(session);
718 }
719
ede7970f 720 if ((switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA))) {
74e21a82 721 goto end;
ede7970f
MJ
722 }
723
a8023642 724 switch_zmalloc(write_frame.data, SWITCH_RECOMMENDED_BUFFER_SIZE);
3608c834 725 write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
69120105 726
bcfccaee 727 if (caller_channel && (var = switch_channel_get_variable(caller_channel, SWITCH_CALL_TIMEOUT_VARIABLE))) {
69120105
AM
728 timelimit = atoi(var);
729 if (timelimit < 0) {
730 timelimit = 60;
731 }
732 }
733
734 timelimit *= 1000000;
0463541d 735 start = switch_micro_time_now();
69120105 736
047e3dd7 737 if (caller_channel) {
f8b442da
AM
738 cancel_key = switch_channel_get_variable(caller_channel, "origination_cancel_key");
739
047e3dd7
AM
740 if (switch_channel_test_flag(caller_channel, CF_ANSWERED)) {
741 ringback_data = switch_channel_get_variable(caller_channel, "transfer_ringback");
742 }
743
744 if (!ringback_data) {
745 ringback_data = switch_channel_get_variable(caller_channel, "ringback");
746 }
747
047e3dd7
AM
748 if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE) || switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA)) {
749 ringback_data = NULL;
df7637f6 750 } else if (zstr(ringback_data)) {
1136fcec
AM
751 if ((var = switch_channel_get_variable(caller_channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE))) {
752 int sval = atoi(var);
753
754 if (sval) {
fc1de32f 755 ringback_data = switch_core_session_sprintf(session, "silence:%d", sval);
1136fcec
AM
756 }
757 }
047e3dd7 758 }
69120105 759 }
3c349c27
AM
760
761
047e3dd7 762 if (read_codec && ringback_data) {
a9936c09
AM
763 if (switch_is_file_path(ringback_data)) {
764 if (!(strrchr(ringback_data, '.') || strstr(ringback_data, SWITCH_URL_SEPARATOR))) {
765 ringback.asis++;
766 }
767 }
768
769
770
771 if (!ringback.asis) {
84090fe2 772 if ((pass = (uint8_t) switch_test_flag(read_codec, SWITCH_CODEC_FLAG_PASSTHROUGH))) {
a9936c09
AM
773 goto no_ringback;
774 }
775
69120105
AM
776 if (switch_core_codec_init(&write_codec,
777 "L16",
778 NULL,
779 read_codec->implementation->actual_samples_per_second,
30c318b9 780 read_codec->implementation->microseconds_per_packet / 1000,
3c349c27 781 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
a9936c09
AM
782 switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
783 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Error!\n");
784 if (caller_channel) {
785 switch_channel_hangup(caller_channel, SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE);
786 }
787 read_codec = NULL;
788 goto done;
789 } else {
c2d5f970 790 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
69120105 791 "Raw Codec Activation Success L16@%uhz 1 channel %dms\n",
30c318b9 792 read_codec->implementation->actual_samples_per_second, read_codec->implementation->microseconds_per_packet / 1000);
a9936c09 793
69120105 794 write_frame.codec = &write_codec;
30c318b9 795 write_frame.datalen = read_codec->implementation->decoded_bytes_per_packet;
69120105
AM
796 write_frame.samples = write_frame.datalen / 2;
797 memset(write_frame.data, 255, write_frame.datalen);
a9936c09
AM
798 switch_core_session_set_read_codec(session, &write_codec);
799 }
800 }
5b6d1cd3 801
e072a609
AM
802 if (switch_channel_test_flag(caller_channel, CF_DISABLE_RINGBACK)) {
803 ringback_data = NULL;
804 }
805
a9936c09
AM
806 if (ringback_data) {
807 char *tmp_data = NULL;
69120105 808
a9936c09
AM
809 if (switch_is_file_path(ringback_data)) {
810 char *ext;
3c349c27 811
a9936c09
AM
812 if (ringback.asis) {
813 write_frame.codec = read_codec;
814 ext = read_codec->implementation->iananame;
815 tmp_data = switch_mprintf("%s.%s", ringback_data, ext);
816 ringback_data = tmp_data;
817 }
69120105 818
a9936c09 819 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Play Ringback File [%s]\n", ringback_data);
69120105 820
a9936c09
AM
821 ringback.fhb.channels = read_codec->implementation->number_of_channels;
822 ringback.fhb.samplerate = read_codec->implementation->actual_samples_per_second;
823 if (switch_core_file_open(&ringback.fhb,
824 ringback_data,
825 read_codec->implementation->number_of_channels,
826 read_codec->implementation->actual_samples_per_second,
827 SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
828 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error Playing File\n");
69120105 829 switch_safe_free(tmp_data);
a9936c09 830 goto done;
69120105 831 }
a9936c09 832 ringback.fh = &ringback.fhb;
69120105 833 } else {
a9936c09
AM
834 if (!strncasecmp(ringback_data, "silence", 7)) {
835 const char *p = ringback_data + 7;
836 if (*p == ':') {
837 p++;
838 if (p) {
839 ringback.silence = atoi(p);
840 }
841 }
842 if (ringback.silence <= 0) {
843 ringback.silence = 400;
844 }
845 } else {
846 switch_buffer_create_dynamic(&ringback.audio_buffer, 512, 1024, 0);
847 switch_buffer_set_loops(ringback.audio_buffer, -1);
848
849 teletone_init_session(&ringback.ts, 0, teletone_handler, &ringback);
850 ringback.ts.rate = read_codec->implementation->actual_samples_per_second;
851 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Play Ringback Tone [%s]\n", ringback_data);
852 if (teletone_run(&ringback.ts, ringback_data)) {
853 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error Playing Tone\n");
854 teletone_destroy_session(&ringback.ts);
855 switch_buffer_destroy(&ringback.audio_buffer);
856 ringback_data = NULL;
857 }
047e3dd7 858 }
69120105 859 }
a9936c09 860 switch_safe_free(tmp_data);
69120105
AM
861 }
862 }
863
a9936c09
AM
864 no_ringback:
865
aaeb69d6
AM
866 if (caller_channel) {
867 wait_state = switch_channel_get_state(caller_channel);
868 }
869
870 while (switch_channel_ready(peer_channel) && !switch_channel_media_ready(peer_channel)) {
0463541d 871 int diff = (int) (switch_micro_time_now() - start);
3c349c27 872
f8b442da
AM
873 if (caller_channel && cancel_key) {
874 if (switch_channel_has_dtmf(caller_channel)) {
875 switch_dtmf_t dtmf = { 0, 0 };
876 if (switch_channel_dequeue_dtmf(caller_channel, &dtmf) == SWITCH_STATUS_SUCCESS) {
877 if (dtmf.digit == *cancel_key) {
878 status = SWITCH_STATUS_FALSE;
879 goto done;
880 }
881 }
882 }
883 }
884
aaeb69d6
AM
885 if (caller_channel && switch_channel_get_state(caller_channel) != wait_state) {
886 goto done;
887 }
888
69120105
AM
889 if (diff > timelimit) {
890 status = SWITCH_STATUS_TIMEOUT;
891 goto done;
892 }
893
2e46528e
AM
894 if (switch_channel_media_ready(caller_channel)) {
895 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
896 if (!SWITCH_READ_ACCEPTABLE(status)) {
897 break;
898 }
899 } else {
900 read_frame = NULL;
901 }
0b0ce769 902
69120105 903 if (read_frame && !pass) {
0b0ce769 904
69120105 905 if (ringback.fh) {
69120105
AM
906 switch_size_t mlen, olen;
907 unsigned int pos = 0;
2e46528e 908
69120105 909 if (ringback.asis) {
30c318b9 910 mlen = write_frame.codec->implementation->encoded_bytes_per_packet;
69120105 911 } else {
30c318b9 912 mlen = write_frame.codec->implementation->samples_per_packet;
69120105
AM
913 }
914
915 olen = mlen;
ea5c3852
AM
916 //if (ringback.fh->resampler && ringback.fh->resampler->rfactor > 1) {
917 //olen = (switch_size_t) (olen * ringback.fh->resampler->rfactor);
918 //}
3608c834 919 switch_core_file_read(ringback.fh, write_frame.data, &olen);
69120105
AM
920
921 if (olen == 0) {
922 olen = mlen;
923 ringback.fh->speed = 0;
924 switch_core_file_seek(ringback.fh, &pos, 0, SEEK_SET);
3608c834 925 switch_core_file_read(ringback.fh, write_frame.data, &olen);
69120105
AM
926 if (olen == 0) {
927 break;
928 }
929 }
69120105
AM
930 write_frame.datalen = (uint32_t) (ringback.asis ? olen : olen * 2);
931 } else if (ringback.audio_buffer) {
932 if ((write_frame.datalen = (uint32_t) switch_buffer_read_loop(ringback.audio_buffer,
933 write_frame.data,
30c318b9 934 write_frame.codec->implementation->decoded_bytes_per_packet)) <= 0) {
69120105
AM
935 break;
936 }
1136fcec
AM
937 } else if (ringback.silence) {
938 write_frame.datalen = write_frame.codec->implementation->decoded_bytes_per_packet;
939 switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.datalen / 2, ringback.silence);
69120105
AM
940 }
941
1136fcec 942 if ((ringback.fh || ringback.silence || ringback.audio_buffer) && write_frame.codec && write_frame.datalen) {
2e46528e
AM
943 if (switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
944 break;
945 }
69120105
AM
946 }
947 } else {
2ed601f9 948 switch_cond_next();
69120105
AM
949 }
950 }
951
697bb6ec 952 done:
3c349c27 953
69120105
AM
954 if (ringback.fh) {
955 switch_core_file_close(ringback.fh);
956 ringback.fh = NULL;
957 } else if (ringback.audio_buffer) {
958 teletone_destroy_session(&ringback.ts);
959 switch_buffer_destroy(&ringback.audio_buffer);
960 }
961
ea5c3852 962 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
bc2fc3fa 963
68b0359c 964 if (switch_core_codec_ready(&write_codec)) {
69120105
AM
965 switch_core_codec_destroy(&write_codec);
966 }
3608c834
AM
967
968 switch_safe_free(write_frame.data);
69120105 969
74e21a82
AM
970 end:
971
aaeb69d6
AM
972 if (!switch_channel_media_ready(peer_channel)) {
973 if (switch_channel_up(peer_channel)) {
974 switch_channel_hangup(peer_channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
975 }
976 status = SWITCH_STATUS_FALSE;
977 }
978
979 if (caller_channel && !switch_channel_ready(caller_channel)) {
980 status = SWITCH_STATUS_FALSE;
981 }
982
983 return status;
69120105
AM
984}
985
a000f0bc 986SWITCH_DECLARE(void) switch_process_import(switch_core_session_t *session, switch_channel_t *peer_channel, const char *varname)
3d136b26
AM
987{
988 const char *import, *val;
989 switch_channel_t *caller_channel;
990
991 switch_assert(session && peer_channel);
992 caller_channel = switch_core_session_get_channel(session);
993
a000f0bc 994 if ((import = switch_channel_get_variable(caller_channel, varname))) {
3d136b26
AM
995 char *mydata = switch_core_session_strdup(session, import);
996 int i, argc;
997 char *argv[64] = { 0 };
998
999 if ((argc = switch_separate_string(mydata, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) {
1000 for(i = 0; i < argc; i++) {
1001 if ((val = switch_channel_get_variable(peer_channel, argv[i]))) {
1002 switch_channel_set_variable(caller_channel, argv[i], val);
1003 }
1004 }
1005 }
1006 }
1007}
1008
1dcb3b67 1009
757aa19e
AM
1010static switch_status_t setup_ringback(originate_global_t *oglobals,
1011 const char *ringback_data,
1012 ringback_t *ringback,
1013 switch_frame_t *write_frame,
1014 switch_codec_t *write_codec)
1015{
1016 switch_status_t status = SWITCH_STATUS_SUCCESS;
1017 switch_channel_t *caller_channel = switch_core_session_get_channel(oglobals->session);
1018 switch_codec_t *read_codec = NULL;
1019 char *tmp_data = NULL;
1020
1021 if (!ringback_data) {
1022 switch_goto_status(SWITCH_STATUS_GENERR, end);
1023 }
1024
1025 if (!switch_channel_test_flag(caller_channel, CF_ANSWERED)
1026 && !switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA)) {
1027 if ((status = switch_channel_pre_answer(caller_channel)) != SWITCH_STATUS_SUCCESS) {
1028 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_DEBUG, "%s Media Establishment Failed.\n",
1029 switch_channel_get_name(caller_channel));
1030 switch_goto_status(SWITCH_STATUS_BREAK, end);
1031 }
1032 }
1033
1034 if (oglobals->session && (read_codec = switch_core_session_get_read_codec(oglobals->session))) {
1035 if (switch_is_file_path(ringback_data)) {
1036 if (!(strrchr(ringback_data, '.') || strstr(ringback_data, SWITCH_URL_SEPARATOR))) {
1037 ringback->asis++;
1038 }
1039 }
1040
1041 if (!ringback->asis) {
1042 if (switch_test_flag(read_codec, SWITCH_CODEC_FLAG_PASSTHROUGH)) {
1043 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_WARNING, "%s Ringback not supported in passthrough codec mode.\n",
1044 switch_channel_get_name(caller_channel));
1045 switch_goto_status(SWITCH_STATUS_GENERR, end);
1046 }
1047
1048 if (switch_core_codec_init(write_codec,
1049 "L16",
1050 NULL,
1051 read_codec->implementation->actual_samples_per_second,
1052 read_codec->implementation->microseconds_per_packet / 1000,
1053 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
1054 switch_core_session_get_pool(oglobals->session)) == SWITCH_STATUS_SUCCESS) {
1055
1056
1057 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals->session), SWITCH_LOG_DEBUG,
1058 "Raw Codec Activation Success L16@%uhz 1 channel %dms\n",
1059 read_codec->implementation->actual_samples_per_second,
1060 read_codec->implementation->microseconds_per_packet / 1000);
1061 write_frame->codec = write_codec;
1062 write_frame->datalen = read_codec->implementation->decoded_bytes_per_packet;
1063 write_frame->samples = write_frame->datalen / 2;
1064 memset(write_frame->data, 255, write_frame->datalen);
1065 switch_core_session_set_read_codec(oglobals->session, write_codec);
1066 } else {
1067 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_ERROR, "Codec Error!\n");
1068 switch_channel_hangup(caller_channel, SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE);
1069 read_codec = NULL;
1070 switch_goto_status(SWITCH_STATUS_BREAK, end);
1071 }
1072 }
1073
1074 oglobals->gen_ringback = 1;
1075
1076 if (switch_is_file_path(ringback_data)) {
1077 char *ext;
1078
1079 if (ringback->asis) {
1080 write_frame->codec = read_codec;
1081 ext = read_codec->implementation->iananame;
1082 tmp_data = switch_mprintf("%s.%s", ringback_data, ext);
1083 ringback_data = tmp_data;
1084 }
1085
1086 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals->session), SWITCH_LOG_DEBUG, "Play Ringback File [%s]\n", ringback_data);
1087
1088 ringback->fhb.channels = read_codec->implementation->number_of_channels;
1089 ringback->fhb.samplerate = read_codec->implementation->actual_samples_per_second;
1090 if (switch_core_file_open(&ringback->fhb,
1091 ringback_data,
1092 read_codec->implementation->number_of_channels,
1093 read_codec->implementation->actual_samples_per_second,
1094 SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
1095 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Playing File\n");
1096 switch_safe_free(tmp_data);
1097 switch_goto_status(SWITCH_STATUS_GENERR, end);
1098 //switch_goto_status(SWITCH_STATUS_FALSE, end);
1099 }
1100 ringback->fh = &ringback->fhb;
1101
1102 } else if (!strncasecmp(ringback_data, "silence", 7)) {
1103 const char *c = ringback_data + 7;
1104 if (*c == ':') {
1105 c++;
1106 if (c) {
1107 ringback->silence = atoi(c);
1108 }
1109 }
1110 if (ringback->silence <= 0) {
1111 ringback->silence = 400;
1112 }
1113 } else {
1114 switch_buffer_create_dynamic(&ringback->audio_buffer, 512, 1024, 0);
1115 switch_buffer_set_loops(ringback->audio_buffer, -1);
1116
1117 teletone_init_session(&ringback->ts, 0, teletone_handler, ringback);
1118 ringback->ts.rate = read_codec->implementation->actual_samples_per_second;
1119 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Play Ringback Tone [%s]\n", ringback_data);
1120 /* ringback->ts.debug = 1;
1121 ringback->ts.debug_stream = switch_core_get_console(); */
1122
1123 if (teletone_run(&ringback->ts, ringback_data)) {
1124 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Playing Tone\n");
1125 teletone_destroy_session(&ringback->ts);
1126 switch_buffer_destroy(&ringback->audio_buffer);
1127 switch_goto_status(SWITCH_STATUS_GENERR, end);
1128 }
1129 }
1130 }
1131
1132 end:
1133
1134 switch_safe_free(tmp_data);
1135
1136 return status;
1137
1138}
1139
bc72d990 1140
06a68fce
AM
1141#define MAX_PEERS 128
1142
1143typedef struct {
1144 switch_core_session_t *session;
1145 switch_core_session_t *bleg;
1146 switch_call_cause_t cause;
2fa0c491 1147 switch_call_cause_t cancel_cause;
06a68fce
AM
1148 const char *bridgeto;
1149 uint32_t timelimit_sec;
1150 const switch_state_handler_table_t *table;
1151 const char *cid_name_override;
1152 const char *cid_num_override;
1153 switch_caller_profile_t *caller_profile_override;
1154 switch_event_t *ovars;
1155 switch_originate_flag_t flags;
1156 switch_status_t status;
1157 int done;
1158 switch_thread_t *thread;
2fa0c491 1159 switch_mutex_t *mutex;
06a68fce
AM
1160} enterprise_originate_handle_t;
1161
1162
ddc66126
AM
1163struct ent_originate_ringback {
1164 switch_core_session_t *session;
1165 int running;
1166 const char *ringback_data;
1167 switch_thread_t *thread;
1168};
1169
06a68fce
AM
1170static void *SWITCH_THREAD_FUNC enterprise_originate_thread(switch_thread_t *thread, void *obj)
1171{
1172 enterprise_originate_handle_t *handle = (enterprise_originate_handle_t *) obj;
1173
1174 handle->done = 0;
1175 handle->status = switch_ivr_originate(NULL, &handle->bleg, &handle->cause,
1176 handle->bridgeto, handle->timelimit_sec,
1177 handle->table,
1178 handle->cid_name_override,
1179 handle->cid_num_override,
1180 handle->caller_profile_override,
1181 handle->ovars,
2fa0c491
AM
1182 handle->flags,
1183 &handle->cancel_cause
06a68fce
AM
1184 );
1185
1186
1187 handle->done = 1;
2fa0c491
AM
1188 switch_mutex_lock(handle->mutex);
1189 switch_mutex_unlock(handle->mutex);
06a68fce 1190
2fa0c491
AM
1191 if (handle->done != 2) {
1192 if (handle->status == SWITCH_STATUS_SUCCESS) {
1193 switch_channel_hangup(switch_core_session_get_channel(handle->bleg), SWITCH_CAUSE_LOSE_RACE);
1194 switch_core_session_rwunlock(handle->bleg);
1195 }
1196 }
1197
06a68fce
AM
1198 return NULL;
1199}
1200
ddc66126
AM
1201static void *SWITCH_THREAD_FUNC enterprise_originate_ringback_thread(switch_thread_t *thread, void *obj)
1202{
1203 struct ent_originate_ringback *rb_data = (struct ent_originate_ringback *) obj;
1204 switch_core_session_t *session = rb_data->session;
1205 switch_channel_t *channel = switch_core_session_get_channel(rb_data->session);
1206 switch_status_t status = SWITCH_STATUS_FALSE;
1207
1208 switch_core_session_read_lock(session);
1209
1210 while(rb_data->running && switch_channel_ready(channel)) {
1211 if (status != SWITCH_STATUS_BREAK) {
1212 if (zstr(rb_data->ringback_data) || !strcasecmp(rb_data->ringback_data, "silence")) {
1213 status = switch_ivr_collect_digits_callback(session, NULL, 0, 0);
1214 } else if (switch_is_file_path(rb_data->ringback_data)) {
1215 status = switch_ivr_play_file(session, NULL, rb_data->ringback_data, NULL);
1216 } else {
1217 status = switch_ivr_gentones(session, rb_data->ringback_data, 0, NULL);
1218 }
1219 }
1220
1221 if (status == SWITCH_STATUS_BREAK) {
1222 switch_channel_set_flag(channel, CF_NOT_READY);
1223 }
1224 }
1225 switch_core_session_rwunlock(session);
1226
1227 rb_data->running = 0;
1228 return NULL;
1229}
1230
1231
06a68fce 1232SWITCH_DECLARE(switch_status_t) switch_ivr_enterprise_originate(switch_core_session_t *session,
ddc66126
AM
1233 switch_core_session_t **bleg,
1234 switch_call_cause_t *cause,
1235 const char *bridgeto,
1236 uint32_t timelimit_sec,
1237 const switch_state_handler_table_t *table,
1238 const char *cid_name_override,
1239 const char *cid_num_override,
1240 switch_caller_profile_t *caller_profile_override,
1241 switch_event_t *ovars,
1242 switch_originate_flag_t flags
1243 )
06a68fce 1244{
f882d83c 1245 int x_argc = 0;
06a68fce
AM
1246 char *x_argv[MAX_PEERS] = { 0 };
1247 enterprise_originate_handle_t *hp = NULL, handles[MAX_PEERS] = { { 0 } };
1248 int i;
1249 switch_caller_profile_t *cp = NULL;
1250 switch_channel_t *channel = NULL;
1251 char *data;
1252 switch_status_t status = SWITCH_STATUS_FALSE;
1253 switch_threadattr_t *thd_attr = NULL;
2fa0c491 1254 int running = 0, over = 0;
06a68fce
AM
1255 switch_status_t tstatus = SWITCH_STATUS_FALSE;
1256 switch_memory_pool_t *pool;
1257 switch_event_header_t *hi = NULL;
ddc66126
AM
1258 struct ent_originate_ringback rb_data = { 0 };
1259 const char *ringback_data = NULL;
f882d83c
AM
1260 char *vars = NULL;
1261 int var_block_count = 0;
1262 char *e = NULL;
1263 switch_event_t *var_event = NULL;
1264 const char *export_vars = NULL;
06a68fce
AM
1265
1266 switch_core_new_memory_pool(&pool);
1267
1268 if (zstr(bridgeto)) {
1269 *cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
1270 switch_goto_status(SWITCH_STATUS_FALSE, end);
1271 }
1272
1273 data = switch_core_strdup(pool, bridgeto);
1274
f882d83c
AM
1275 /* strip leading spaces */
1276 while (data && *data && *data == ' ') {
1277 data++;
1278 }
1279
1280 /* extract channel variables, allowing multiple sets of braces */
1281 while (*data == '<') {
1282 if (!var_block_count) {
1283 e = switch_find_end_paren(data, '<', '>');
1284 if (!e || !*e) {
1285 goto var_extract_error;
1286 }
1287 vars = data + 1;
1288 *e = '\0';
1289 data = e + 1;
1290 } else {
1291 int j = 0, k = 0;
1292 if (e) {
1293 *e = ',';
1294 }
1295 e = switch_find_end_paren(data, '<', '>');
1296 if (!e || !*e) {
1297 goto var_extract_error;
1298 }
1299 /* swallow the opening bracket */
1300 while ((data + k) && *(data + k)) {
1301 j = k; k++;
1302 /* note that this affects vars[] */
1303 data[j] = data[k];
1304 }
1305 *(--e) = '\0';
1306 data = e + 1;
1307 }
1308 var_block_count++;
1309 continue;
1310
1311 var_extract_error:
1312 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Parse Error!\n");
1313 switch_goto_status(SWITCH_STATUS_GENERR, done);
1314 }
1315
1316 /* strip leading spaces (again) */
1317 while (data && *data && *data == ' ') {
1318 data++;
1319 }
1320
1321 if (ovars) {
1322 var_event = ovars;
1323 } else {
1324 if (switch_event_create_plain(&var_event, SWITCH_EVENT_CHANNEL_DATA) != SWITCH_STATUS_SUCCESS) {
1325 abort();
1326 }
1327 }
1328
1329 /* A comma (,) separated list of variable names that should ne propagated from originator to originatee */
1330 if (channel && (export_vars = switch_channel_get_variable(channel, SWITCH_EXPORT_VARS_VARIABLE))) {
1331 char *cptmp = switch_core_session_strdup(session, export_vars);
1332 int argc;
1333 char *argv[256];
1334
1335 if ((argc = switch_separate_string(cptmp, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) {
1336 int x;
1337
1338 for (x = 0; x < argc; x++) {
1339 const char *vval;
1340 if ((vval = switch_channel_get_variable(channel, argv[x]))) {
1341 char *vvar = argv[x];
1342 if (!strncasecmp(vvar, "nolocal:", 8)) {
1343 vvar += 8;
1344 }
1345 switch_event_del_header(var_event, vvar);
1346 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, vvar, vval);
1347 }
1348 }
1349 }
1350 }
1351
1352 if (vars) { /* Parse parameters specified from the dialstring */
1353 char *var_array[1024] = { 0 };
1354 int var_count = 0;
1355 if ((var_count = switch_separate_string(vars, ',', var_array, (sizeof(var_array) / sizeof(var_array[0]))))) {
1356 int x = 0;
1357 for (x = 0; x < var_count; x++) {
1358 char *inner_var_array[2] = { 0 };
1359 int inner_var_count;
1360 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "variable string %d = [%s]\n", x, var_array[x]);
1361 if ((inner_var_count =
1362 switch_separate_string(var_array[x], '=', inner_var_array, (sizeof(inner_var_array) / sizeof(inner_var_array[0])))) == 2) {
1363 switch_event_del_header(var_event, inner_var_array[0]);
1364 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, inner_var_array[0], inner_var_array[1]);
1365 }
1366 }
1367 }
1368 }
1369
1370 if (ovars) {
1371 for (hi = ovars->headers; hi; hi = hi->next) {
1372 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, hi->name, hi->value);
1373 }
1374 }
1375
2fa0c491 1376 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "ignore_early_media", "true");
f882d83c 1377
bc72d990 1378 if (!(x_argc = switch_separate_string_string(data, SWITCH_ENT_ORIGINATE_DELIM, x_argv, MAX_PEERS))) {
06a68fce
AM
1379 *cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
1380 switch_goto_status(SWITCH_STATUS_FALSE, end);
1381 }
1382
1383 if (session) {
1384 channel = switch_core_session_get_channel(session);
1385 cp = switch_channel_get_caller_profile(channel);
1386 }
1387
1388 switch_threadattr_create(&thd_attr, pool);
1389 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
1390
1391 for(i = 0; i < x_argc; i++) {
1392 handles[i].session = session;
1393 handles[i].bleg = NULL;
1394 handles[i].cause = 0;
2fa0c491 1395 handles[i].cancel_cause = 0;
06a68fce
AM
1396 handles[i].bridgeto = x_argv[i];
1397 handles[i].timelimit_sec = timelimit_sec;
1398 handles[i].table = table;
1399 handles[i].cid_name_override = cid_name_override;
1400 handles[i].cid_num_override = cid_num_override;
1401 handles[i].caller_profile_override = cp;
f882d83c 1402 switch_event_dup(&handles[i].ovars, var_event);
06a68fce 1403 handles[i].flags = flags;
2fa0c491
AM
1404 switch_mutex_init(&handles[i].mutex, SWITCH_MUTEX_NESTED, pool);
1405 switch_mutex_lock(handles[i].mutex);
06a68fce
AM
1406 switch_thread_create(&handles[i].thread, thd_attr, enterprise_originate_thread, &handles[i], pool);
1407 }
ddc66126
AM
1408
1409 if (channel && !switch_channel_test_flag(channel, CF_PROXY_MODE) && !switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
1410 if (switch_channel_test_flag(channel, CF_ANSWERED)) {
1411 ringback_data = switch_channel_get_variable(channel, "transfer_ringback");
1412 }
1413
1414 if (!ringback_data) {
1415 ringback_data = switch_channel_get_variable(channel, "ringback");
1416 }
1417
1418 if (ringback_data || switch_channel_media_ready(channel)) {
1419 rb_data.ringback_data = ringback_data;
1420 rb_data.session = session;
1421 rb_data.running = 1;
1422 if (!switch_channel_media_ready(channel)) {
1423 if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
1424 goto done;
1425 }
1426 }
1427 switch_thread_create(&rb_data.thread, thd_attr, enterprise_originate_ringback_thread, &rb_data, pool);
1428 }
1429 }
1430
06a68fce
AM
1431
1432 for(;;) {
1433 running = 0;
2fa0c491 1434 over = 0;
ddc66126
AM
1435
1436 if (channel && !switch_channel_ready(channel)) {
1437 break;
1438 }
06a68fce
AM
1439
1440 for(i = 0; i < x_argc; i++) {
2fa0c491
AM
1441
1442
06a68fce
AM
1443 if (handles[i].done == 0) {
1444 running++;
1445 } else if (handles[i].done == 1) {
1446 if (handles[i].status == SWITCH_STATUS_SUCCESS) {
2fa0c491 1447 handles[i].done = 2;
06a68fce
AM
1448 hp = &handles[i];
1449 goto done;
1450 } else {
2fa0c491 1451 handles[i].done = -1;
06a68fce 1452 }
2fa0c491
AM
1453 } else {
1454 over++;
06a68fce 1455 }
2fa0c491
AM
1456
1457 switch_yield(10000);
06a68fce
AM
1458 }
1459
2fa0c491 1460 if (!running || over == x_argc) {
06a68fce
AM
1461 break;
1462 }
1463 }
ddc66126 1464
06a68fce
AM
1465
1466 done:
1467
2fa0c491
AM
1468 if (hp) {
1469 *cause = hp->cause;
1470 status = hp->status;
1471 *bleg = hp->bleg;
1472 switch_mutex_unlock(hp->mutex);
1473 switch_thread_join(&tstatus, hp->thread);
1474 switch_event_destroy(&hp->ovars);
ddc66126
AM
1475 }
1476
06a68fce 1477 for(i = 0; i < x_argc; i++) {
2fa0c491 1478 if (hp == &handles[i]) {
06a68fce
AM
1479 continue;
1480 }
2fa0c491
AM
1481 handles[i].cancel_cause = SWITCH_CAUSE_LOSE_RACE;
1482 }
06a68fce 1483
2fa0c491
AM
1484 for(i = 0; i < x_argc; i++) {
1485 if (hp == &handles[i]) {
1486 continue;
1487 }
1488 switch_mutex_unlock(handles[i].mutex);
06a68fce
AM
1489 switch_thread_join(&tstatus, handles[i].thread);
1490 switch_event_destroy(&handles[i].ovars);
1491 }
1492
1493
2fa0c491
AM
1494 if (channel && rb_data.thread) {
1495 switch_channel_set_flag(channel, CF_NOT_READY);
1496 switch_thread_join(&tstatus, rb_data.thread);
1497 switch_channel_clear_flag(channel, CF_NOT_READY);
06a68fce
AM
1498 }
1499
2fa0c491 1500
06a68fce
AM
1501 end:
1502
f882d83c
AM
1503 if (var_event && var_event != ovars) {
1504 switch_event_destroy(&var_event);
1505 }
1506
06a68fce
AM
1507 switch_core_destroy_memory_pool(&pool);
1508
1509 return status;
1510
1511}
757aa19e 1512
aaeb69d6
AM
1513#define peer_eligible(_peer) (_peer && !(switch_channel_test_flag(_peer, CF_TRANSFER) || \
1514 switch_channel_test_flag(_peer, CF_REDIRECT) || \
1515 switch_channel_test_flag(_peer, CF_BRIDGED) || \
1516 switch_channel_get_state(_peer) == CS_RESET || \
1517 !switch_channel_test_flag(_peer, CF_ORIGINATING)))
1518
06a68fce 1519
e6a60a20
AM
1520SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *session,
1521 switch_core_session_t **bleg,
1522 switch_call_cause_t *cause,
622a2733 1523 const char *bridgeto,
e6a60a20
AM
1524 uint32_t timelimit_sec,
1525 const switch_state_handler_table_t *table,
3c349c27
AM
1526 const char *cid_name_override,
1527 const char *cid_num_override,
a579a283
AM
1528 switch_caller_profile_t *caller_profile_override,
1529 switch_event_t *ovars,
2fa0c491
AM
1530 switch_originate_flag_t flags,
1531 switch_call_cause_t *cancel_cause
a579a283 1532 )
e6a60a20 1533{
1dcb3b67 1534 originate_status_t originate_status[MAX_PEERS] = { { 0 } };
1bb00325 1535 switch_originate_flag_t dftflags = SOF_NONE, myflags = dftflags;
e6a60a20
AM
1536 char *pipe_names[MAX_PEERS] = { 0 };
1537 char *data = NULL;
1538 switch_status_t status = SWITCH_STATUS_SUCCESS;
1539 switch_channel_t *caller_channel = NULL;
1540 char *peer_names[MAX_PEERS] = { 0 };
1dcb3b67
AM
1541 switch_core_session_t *new_session = NULL, *peer_session;
1542 switch_caller_profile_t *new_profile = NULL, *caller_caller_profile;
e6a60a20 1543 char *chan_type = NULL, *chan_data;
1dcb3b67 1544 switch_channel_t *peer_channel = NULL;
e6a60a20
AM
1545 ringback_t ringback = { 0 };
1546 time_t start;
1547 switch_frame_t *read_frame = NULL;
1548 switch_memory_pool_t *pool = NULL;
1549 int r = 0, i, and_argc = 0, or_argc = 0;
1dcb3b67 1550 int32_t sleep_ms = 1000, try = 0, retries = 1;
e6a60a20
AM
1551 switch_codec_t write_codec = { 0 };
1552 switch_frame_t write_frame = { 0 };
1dcb3b67 1553 char *odata, *var;
98479fa6 1554 switch_call_cause_t reason = SWITCH_CAUSE_NONE;
aaeb69d6 1555 switch_call_cause_t force_reason = SWITCH_CAUSE_NONE;
e6a60a20 1556 uint8_t to = 0;
622a2733 1557 char *var_val, *vars = NULL;
65c91197
AM
1558 int var_block_count = 0;
1559 char *e = NULL;
622a2733 1560 const char *ringback_data = NULL;
e6a60a20
AM
1561 switch_event_t *var_event = NULL;
1562 uint8_t fail_on_single_reject = 0;
4ed389f9 1563 char *fail_on_single_reject_var = NULL;
e6a60a20 1564 char *loop_data = NULL;
f33aa021 1565 uint32_t progress_timelimit_sec = 0;
f9642e96 1566 const char *cid_tmp, *lc;
1dcb3b67 1567 originate_global_t oglobals = { 0 };
2c0fe2dc 1568 int cdr_total = 0;
f9642e96 1569 int local_clobber = 0;
f8b442da 1570 const char *cancel_key = NULL;
aaeb69d6 1571 const char *holding = NULL;
450e63c0 1572 const char *soft_holding = NULL;
64482b06 1573 const char *export_vars = NULL;
f8b442da 1574
06a68fce 1575
bc72d990 1576 if (strstr(bridgeto, SWITCH_ENT_ORIGINATE_DELIM)) {
06a68fce
AM
1577 return switch_ivr_enterprise_originate(session, bleg, cause, bridgeto, timelimit_sec, table, cid_name_override, cid_num_override,
1578 caller_profile_override, ovars, flags);
1579 }
1580
757aa19e
AM
1581 oglobals.ringback_ok = 1;
1582
d9fb89d2 1583 if (session) {
5b6d1cd3 1584 const char *to_var;
d9fb89d2 1585 caller_channel = switch_core_session_get_channel(session);
aaeb69d6 1586 switch_channel_set_flag(caller_channel, CF_ORIGINATOR);
d9fb89d2
AM
1587 oglobals.session = session;
1588
5b6d1cd3
AM
1589
1590 if ((to_var = switch_channel_get_variable(caller_channel, SWITCH_CALL_TIMEOUT_VARIABLE))) {
1591 timelimit_sec = atoi(to_var);
1592 }
1593
d9fb89d2
AM
1594 if (switch_true(switch_channel_get_variable(caller_channel, SWITCH_PROXY_MEDIA_VARIABLE))) {
1595 switch_channel_set_flag(caller_channel, CF_PROXY_MEDIA);
1596 }
1597
1598 if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE)
1599 || (switch_true(switch_channel_get_variable(caller_channel, SWITCH_BYPASS_MEDIA_VARIABLE)))) {
1600 if (!switch_channel_test_flag(caller_channel, CF_ANSWERED)
1601 && !switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA)) {
1602 switch_channel_set_flag(caller_channel, CF_PROXY_MODE);
1603 } else {
1604 if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE)) {
99b45eb1 1605 switch_channel_set_variable(caller_channel, SWITCH_B_SDP_VARIABLE, NULL);
d9fb89d2 1606 } else {
757aa19e
AM
1607 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
1608 "Channel is already up, delaying proxy mode 'till both legs are answered.\n");
d9fb89d2
AM
1609 switch_channel_set_variable(caller_channel, "bypass_media_after_bridge", "true");
1610 switch_channel_set_variable(caller_channel, SWITCH_BYPASS_MEDIA_VARIABLE, NULL);
1611 switch_channel_clear_flag(caller_channel, CF_PROXY_MODE);
1612 }
1613 }
1614 }
1615 }
1616
5b6d1cd3
AM
1617 if (timelimit_sec <= 0) {
1618 timelimit_sec = 60;
1619 }
1620
d9fb89d2 1621
1dcb3b67
AM
1622 oglobals.idx = IDX_NADA;
1623 oglobals.early_ok = 1;
d9fb89d2 1624
4f670da1
AM
1625 *bleg = NULL;
1626
a8023642 1627 switch_zmalloc(write_frame.data, SWITCH_RECOMMENDED_BUFFER_SIZE);
3608c834 1628 write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
e6a60a20 1629
e6a60a20 1630 odata = strdup(bridgeto);
577afaf6
MJ
1631
1632 if (!odata) {
c2d5f970 1633 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Memory Error!\n");
577afaf6
MJ
1634 status = SWITCH_STATUS_MEMERR;
1635 goto done;
1636 }
1637
e6a60a20
AM
1638 data = odata;
1639
1640 /* strip leading spaces */
1641 while (data && *data && *data == ' ') {
1642 data++;
1643 }
3c349c27 1644
65c91197
AM
1645 /* extract channel variables, allowing multiple sets of braces */
1646 while (*data == '{') {
1647 if (!var_block_count) {
1648 e = switch_find_end_paren(data, '{', '}');
1649 if (!e || !*e) {
1650 goto var_extract_error;
1651 }
5c5c3251 1652 vars = data + 1;
65c91197
AM
1653 *e = '\0';
1654 data = e + 1;
5c5c3251 1655 } else {
885c1e61 1656 int j = 0, k = 0;
65c91197
AM
1657 if (e) {
1658 *e = ',';
1659 }
1660 e = switch_find_end_paren(data, '{', '}');
1661 if (!e || !*e) {
1662 goto var_extract_error;
1663 }
1664 /* swallow the opening bracket */
885c1e61
MJ
1665 while ((data + k) && *(data + k)) {
1666 j = k; k++;
65c91197 1667 /* note that this affects vars[] */
885c1e61 1668 data[j] = data[k];
65c91197
AM
1669 }
1670 *(--e) = '\0';
1671 data = e + 1;
e6a60a20 1672 }
65c91197
AM
1673 var_block_count++;
1674 continue;
1675
1676 var_extract_error:
c2d5f970 1677 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Parse Error!\n");
65c91197
AM
1678 status = SWITCH_STATUS_GENERR;
1679 goto done;
e6a60a20
AM
1680 }
1681
1682 /* strip leading spaces (again) */
1683 while (data && *data && *data == ' ') {
1684 data++;
1685 }
1686
df7637f6 1687 if (zstr(data)) {
c2d5f970 1688 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "No origination URL specified!\n");
e6a60a20
AM
1689 status = SWITCH_STATUS_GENERR;
1690 goto done;
1691 }
1692
1693 /* Some channel are created from an originating channel and some aren't so not all outgoing calls have a way to get params
1694 so we will normalize dialstring params and channel variables (when there is an originator) into an event that we
1695 will use as a pseudo hash to consult for params as needed.
697bb6ec 1696 */
a579a283
AM
1697
1698 if (ovars) {
1699 var_event = ovars;
1700 } else {
cdd0bcfd 1701 if (switch_event_create_plain(&var_event, SWITCH_EVENT_CHANNEL_DATA) != SWITCH_STATUS_SUCCESS) {
a579a283
AM
1702 abort();
1703 }
e6a60a20
AM
1704 }
1705
64482b06 1706 /* A comma (,) separated list of variable names that should ne propagated from originator to originatee */
f62dc00b 1707 if (caller_channel && (export_vars = switch_channel_get_variable(caller_channel, SWITCH_EXPORT_VARS_VARIABLE))) {
64482b06
AM
1708 char *cptmp = switch_core_session_strdup(session, export_vars);
1709 int argc;
1710 char *argv[256];
1711
1712 if ((argc = switch_separate_string(cptmp, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) {
1713 int x;
1714
1715 for (x = 0; x < argc; x++) {
1716 const char *vval;
1717 if ((vval = switch_channel_get_variable(caller_channel, argv[x]))) {
1718 char *vvar = argv[x];
1719 if (!strncasecmp(vvar, "nolocal:", 8)) {
1720 vvar += 8;
1721 }
1722 switch_event_del_header(var_event, vvar);
1723 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, vvar, vval);
1724 }
1725 }
1726 }
1727 }
1728
418d6027
MR
1729 if (vars) { /* Parse parameters specified from the dialstring */
1730 char *var_array[1024] = { 0 };
1731 int var_count = 0;
1732 if ((var_count = switch_separate_string(vars, ',', var_array, (sizeof(var_array) / sizeof(var_array[0]))))) {
1733 int x = 0;
1734 for (x = 0; x < var_count; x++) {
1735 char *inner_var_array[2] = { 0 };
1736 int inner_var_count;
c2d5f970 1737 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "variable string %d = [%s]\n", x, var_array[x]);
418d6027
MR
1738 if ((inner_var_count =
1739 switch_separate_string(var_array[x], '=', inner_var_array, (sizeof(inner_var_array) / sizeof(inner_var_array[0])))) == 2) {
1740 switch_event_del_header(var_event, inner_var_array[0]);
1741 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, inner_var_array[0], inner_var_array[1]);
1742 }
1743 }
1744 }
1745 }
1746
1dcb3b67 1747 if (oglobals.session) {
ffb989e4 1748 switch_event_header_t *hi;
2c0fe2dc
AM
1749 const char *cdr_total_var;
1750
2c0fe2dc
AM
1751 if ((cdr_total_var = switch_channel_get_variable(caller_channel, "failed_xml_cdr_total"))) {
1752 int tmp = atoi(cdr_total_var);
1753 if (tmp > 0) {
1754 cdr_total = tmp;
1755 }
1756 }
1757
1758
418d6027 1759 /* Copy all the missing applicable channel variables from A-leg into the event */
ffb989e4
AM
1760 if ((hi = switch_channel_variable_first(caller_channel))) {
1761 for (; hi; hi = hi->next) {
98d9028b 1762 int ok = 0;
3c349c27 1763 if (!strcasecmp((char *) hi->name, "group_confirm_key")) {
98d9028b 1764 ok = 1;
3c349c27 1765 } else if (!strcasecmp((char *) hi->name, "group_confirm_file")) {
98d9028b 1766 ok = 1;
d8793904 1767 } else if (!strcasecmp((char *) hi->name, "group_confirm_cancel_timeout")) {
bdf8f594 1768 ok = 1;
3c349c27 1769 } else if (!strcasecmp((char *) hi->name, "forked_dial")) {
21da7429 1770 ok = 1;
3c349c27 1771 } else if (!strcasecmp((char *) hi->name, "fail_on_single_reject")) {
98d9028b 1772 ok = 1;
3c349c27 1773 } else if (!strcasecmp((char *) hi->name, "ignore_early_media")) {
98d9028b 1774 ok = 1;
5b6d1cd3
AM
1775 } else if (!strcasecmp((char *) hi->name, "originate_continue_on_timeout")) {
1776 ok = 1;
effb166b
AM
1777 } else if (!strcasecmp((char *) hi->name, "ignore_ring_ready")) {
1778 ok = 1;
697bb6ec
AM
1779 } else if (!strcasecmp((char *) hi->name, "monitor_early_media_ring")) {
1780 ok = 1;
ba77f232
AM
1781 } else if (!strcasecmp((char *) hi->name, "monitor_early_media_ring_total")) {
1782 ok = 1;
697bb6ec
AM
1783 } else if (!strcasecmp((char *) hi->name, "monitor_early_media_fail")) {
1784 ok = 1;
3c349c27 1785 } else if (!strcasecmp((char *) hi->name, "return_ring_ready")) {
d6f0cec8 1786 ok = 1;
c01e6fe6
AM
1787 } else if (!strcasecmp((char *) hi->name, "ring_ready")) {
1788 ok = 1;
bcb20f7a
AM
1789 } else if (!strcasecmp((char *) hi->name, "instant_ringback")) {
1790 ok = 1;
f33aa021
AM
1791 } else if (!strcasecmp((char *) hi->name, "progress_timeout")) {
1792 ok = 1;
98d9028b
AM
1793 }
1794
418d6027 1795 if (ok && !switch_event_get_header(var_event, hi->name)) {
f9213890 1796 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, (char *) hi->name, (char *) hi->value);
98d9028b 1797 }
ffb989e4
AM
1798 }
1799 switch_channel_variable_last(caller_channel);
1800 }
1801 /*
697bb6ec
AM
1802 if ((hi = switch_channel_variable_first(caller_channel))) {
1803 for (; hi; hi = switch_hash_next(hi)) {
1804 switch_hash_this(hi, &vvar, NULL, &vval);
1805 if (vvar && vval) {
1806 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, (void *) vvar, (char *) vval);
1807 }
1808 }
1809 switch_channel_variable_last(caller_channel);
1810 }
1811 */
e6a60a20
AM
1812 }
1813
e6a60a20 1814 if (caller_channel) { /* ringback is only useful when there is an originator */
8433c7e0 1815 ringback_data = NULL;
f8b442da 1816 cancel_key = switch_channel_get_variable(caller_channel, "origination_cancel_key");
8433c7e0 1817
50fc2ffa 1818 if (switch_channel_test_flag(caller_channel, CF_ANSWERED)) {
8433c7e0 1819 ringback_data = switch_channel_get_variable(caller_channel, "transfer_ringback");
3c349c27
AM
1820 }
1821
8433c7e0
AM
1822 if (!ringback_data) {
1823 ringback_data = switch_channel_get_variable(caller_channel, "ringback");
1824 }
3c349c27 1825
e6a60a20 1826 switch_channel_set_variable(caller_channel, "originate_disposition", "failure");
f29513f3
AM
1827
1828 if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE) || switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA)) {
1829 ringback_data = NULL;
df7637f6 1830 } else if (zstr(ringback_data)) {
1136fcec
AM
1831 const char *vvar;
1832
1833 if ((vvar = switch_channel_get_variable(caller_channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE))) {
1834 int sval = atoi(vvar);
1835
1836 if (sval) {
1dcb3b67 1837 ringback_data = switch_core_session_sprintf(oglobals.session, "silence:%d", sval);
1136fcec
AM
1838 }
1839
1840 }
f29513f3
AM
1841 }
1842 }
1843
78bc4172
AM
1844#if 0
1845 /* changing behaviour ignore_early_media=true must also be explicitly set for previous behaviour */
f29513f3 1846 if (ringback_data) {
1dcb3b67 1847 oglobals.early_ok = 0;
e6a60a20 1848 }
78bc4172 1849#endif
e6a60a20 1850
bdf8f594
AM
1851 if (switch_true(switch_event_get_header(var_event, "group_confirm_cancel_timeout"))) {
1852 oglobals.cancel_timeout = -1;
1853 }
1854
e6a60a20 1855 if ((var = switch_event_get_header(var_event, "group_confirm_key"))) {
1dcb3b67 1856 switch_copy_string(oglobals.key, var, sizeof(oglobals.key));
e6a60a20 1857 if ((var = switch_event_get_header(var_event, "group_confirm_file"))) {
1dcb3b67 1858 switch_copy_string(oglobals.file, var, sizeof(oglobals.file));
e6a60a20
AM
1859 }
1860 }
edc3f650 1861 /* When using the AND operator, the fail_on_single_reject flag may be set in order to indicate that a single
4ed389f9
AM
1862 rejections should terminate the attempt rather than a timeout, answer, or rejection by all.
1863 If the value is set to 'true' any fail cause will end the attempt otherwise it can contain a comma (,) separated
1864 list of cause names which should be considered fatal
1865 */
e6a60a20 1866 if ((var = switch_event_get_header(var_event, "fail_on_single_reject")) && switch_true(var)) {
4ed389f9 1867 fail_on_single_reject_var = strdup(var);
e6a60a20
AM
1868 fail_on_single_reject = 1;
1869 }
1870
1dcb3b67
AM
1871 if ((*oglobals.file != '\0') && (!strcmp(oglobals.file, "undef"))) {
1872 *oglobals.file = '\0';
e6a60a20
AM
1873 }
1874
e072a609
AM
1875 if ((var_val = switch_event_get_header(var_event, "ignore_early_media"))) {
1876 if (switch_true(var_val)) {
1877 oglobals.early_ok = 0;
1878 oglobals.ignore_early_media = 1;
1879 } else if (!strcmp(var_val, "ring_ready")) {
1880 oglobals.early_ok = 0;
1881 oglobals.ignore_early_media = 2;
1882 }
effb166b
AM
1883 }
1884
5b6d1cd3
AM
1885 if ((var_val = switch_event_get_header(var_event, "originate_continue_on_timeout")) && switch_true(var_val)) {
1886 oglobals.continue_on_timeout = 1;
1887 }
1888
effb166b
AM
1889 if ((var_val = switch_event_get_header(var_event, "ignore_ring_ready")) && switch_true(var_val)) {
1890 oglobals.ignore_ring_ready = 1;
e6a60a20
AM
1891 }
1892
697bb6ec
AM
1893 if ((var_val = switch_event_get_header(var_event, "monitor_early_media_ring"))) {
1894 oglobals.early_ok = 0;
1895 oglobals.monitor_early_media_ring = 1;
1896 }
1897
1898 if ((var_val = switch_event_get_header(var_event, "monitor_early_media_fail"))) {
1899 oglobals.early_ok = 0;
1900 oglobals.monitor_early_media_fail = 1;
1901 }
1902
d6f0cec8 1903 if ((var_val = switch_event_get_header(var_event, "return_ring_ready")) && switch_true(var_val)) {
1dcb3b67 1904 oglobals.return_ring_ready = 1;
d6f0cec8
AM
1905 }
1906
c01e6fe6 1907 if ((var_val = switch_event_get_header(var_event, "ring_ready")) && switch_true(var_val)) {
0b0ce769 1908 oglobals.ring_ready = 1;
c01e6fe6
AM
1909 }
1910
bcb20f7a
AM
1911 if ((var_val = switch_event_get_header(var_event, "instant_ringback")) && switch_true(var_val)) {
1912 oglobals.instant_ringback = 1;
1913 }
1914
f33aa021 1915 if ((var_val = switch_event_get_header(var_event, "originate_timeout"))) {
8da5afec
AM
1916 int tmp = atoi(var_val);
1917 if (tmp > 0) {
1918 timelimit_sec = (uint32_t) tmp;
1919 }
1920 }
1921
f33aa021
AM
1922 if ((var_val = switch_event_get_header(var_event, "progress_timeout"))) {
1923 int tmp = atoi(var_val);
1924 if (tmp > 0) {
1925 progress_timelimit_sec = (uint32_t) tmp;
1926 }
1927 }
1928
e6a60a20
AM
1929 if ((var_val = switch_event_get_header(var_event, "originate_retries")) && switch_true(var_val)) {
1930 int32_t tmp;
1931 tmp = atoi(var_val);
1932 if (tmp > 0 && tmp < 101) {
1933 retries = tmp;
1934 } else {
c2d5f970 1935 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
debdfb1a 1936 "Invalid originate_retries setting of %d ignored, value must be between 1 and 100\n", tmp);
e6a60a20
AM
1937 }
1938 }
1939
1940 if ((var_val = switch_event_get_header(var_event, "originate_retry_sleep_ms")) && switch_true(var_val)) {
1941 int32_t tmp;
1942 tmp = atoi(var_val);
8e7bbff3 1943 if (tmp >= 500 && tmp <= 60000) {
e6a60a20
AM
1944 sleep_ms = tmp;
1945 } else {
c2d5f970 1946 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
debdfb1a 1947 "Invalid originate_retry_sleep_ms setting of %d ignored, value must be between 500 and 60000\n", tmp);
e6a60a20
AM
1948 }
1949 }
1950
1bb00325
AM
1951 if ((cid_tmp = switch_event_get_header(var_event, "origination_caller_id_name"))) {
1952 cid_name_override = cid_tmp;
1953 }
1954
f045bb9a
AM
1955 if (cid_name_override) {
1956 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "origination_caller_id_name", cid_name_override);
1957 } else {
e6a60a20
AM
1958 cid_name_override = switch_event_get_header(var_event, "origination_caller_id_name");
1959 }
1960
1bb00325
AM
1961 if ((cid_tmp = switch_event_get_header(var_event, "origination_caller_id_number"))) {
1962 cid_num_override = cid_tmp;
1963 }
1964
f045bb9a
AM
1965 if (cid_num_override) {
1966 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "origination_caller_id_number", cid_num_override);
1967 } else {
e6a60a20
AM
1968 cid_num_override = switch_event_get_header(var_event, "origination_caller_id_number");
1969 }
1970
1bb00325
AM
1971 if (cid_num_override) {
1972 dftflags |= SOF_NO_EFFECTIVE_CID_NUM;
1973 }
1974
1975 if (cid_name_override) {
1976 dftflags |= SOF_NO_EFFECTIVE_CID_NAME;
1977 }
1978
f33aa021
AM
1979 if (!progress_timelimit_sec) {
1980 progress_timelimit_sec = timelimit_sec;
1981 }
1982
e6a60a20
AM
1983 for (try = 0; try < retries; try++) {
1984 switch_safe_free(loop_data);
76bdd0b3 1985 loop_data = strdup(data);
55a194e5 1986 switch_assert(loop_data);
e6a60a20
AM
1987 or_argc = switch_separate_string(loop_data, '|', pipe_names, (sizeof(pipe_names) / sizeof(pipe_names[0])));
1988
8433c7e0 1989 if ((flags & SOF_NOBLOCK) && or_argc > 1) {
c2d5f970 1990 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
1991 or_argc = 1;
1992 }
feb46019 1993
e6a60a20 1994 for (r = 0; r < or_argc; r++) {
2d764cc0 1995 char *p, *end = NULL;
3720a64e 1996 const char *var_begin, *var_end;
dc2a354c 1997 oglobals.hups = 0;
3720a64e 1998
98479fa6 1999 reason = SWITCH_CAUSE_NONE;
e6a60a20
AM
2000 memset(peer_names, 0, sizeof(peer_names));
2001 peer_session = NULL;
1dcb3b67 2002 memset(originate_status, 0, sizeof(originate_status));
bf7144b2
AM
2003 new_profile = NULL;
2004 new_session = NULL;
e6a60a20
AM
2005 chan_type = NULL;
2006 chan_data = NULL;
2007 peer_channel = NULL;
2008 start = 0;
2009 read_frame = NULL;
2010 pool = NULL;
757aa19e 2011 oglobals.ringback_ok = 1;
e6a60a20
AM
2012 var = NULL;
2013 to = 0;
1dcb3b67
AM
2014 oglobals.sent_ring = 0;
2015 oglobals.progress = 0;
1bb00325
AM
2016 myflags = dftflags;
2017
e6a60a20 2018 if (try > 0) {
c2d5f970 2019 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Originate attempt %d/%d in %d ms\n", try + 1, retries, sleep_ms);
4c44541e 2020 if (caller_channel) {
1dcb3b67 2021 switch_ivr_sleep(oglobals.session, sleep_ms, SWITCH_TRUE, NULL);
4a750282
AM
2022 if (!switch_channel_ready(caller_channel)) {
2023 status = SWITCH_STATUS_FALSE;
2024 goto done;
2025 }
4c44541e
AM
2026 } else {
2027 switch_yield(sleep_ms * 1000);
2028 }
e6a60a20 2029 }
6eebc864
AM
2030
2031 p = pipe_names[r];
2032 while(p && *p) {
2033 if (*p == '[') {
2d764cc0 2034 end = switch_find_end_paren(p, '[', ']');
6eebc864
AM
2035 }
2036
f95887b1 2037 if (end && p < end && *p == ',') {
6eebc864
AM
2038 *p = '|';
2039 }
e6a60a20 2040
2d764cc0 2041 if (p == end) {
f95887b1 2042 end = NULL;
6eebc864
AM
2043 }
2044
2045 p++;
2046 }
2047
debdfb1a 2048 and_argc = switch_separate_string(pipe_names[r], ',', peer_names, (sizeof(peer_names) / sizeof(peer_names[0])));
e6a60a20 2049
8433c7e0 2050 if ((flags & SOF_NOBLOCK) && and_argc > 1) {
c2d5f970 2051 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
2052 and_argc = 1;
2053 }
3c349c27 2054
e6a60a20 2055 for (i = 0; i < and_argc; i++) {
5c5c3251 2056 char *vdata;
dfda1d8f
BW
2057 const char *current_variable;
2058 char variable_buffer[512] = "";
863e1c70
MJ
2059 end = NULL;
2060 chan_type = peer_names[i];
8b6aeebd 2061
5c5c3251
AM
2062 while (chan_type && *chan_type && *chan_type == ' ') {
2063 chan_type++;
2064 }
2065
2066 vdata = chan_type;
2d764cc0 2067 end = switch_find_end_paren(vdata, '[', ']');
3c349c27 2068
2d764cc0 2069 if (end) {
5c5c3251 2070 vdata++;
2d764cc0
MJ
2071 *end++ = '\0';
2072 chan_type = end;
5c5c3251
AM
2073 } else {
2074 vdata = NULL;
2075 }
3c349c27 2076
e6a60a20
AM
2077 if ((chan_data = strchr(chan_type, '/')) != 0) {
2078 *chan_data = '\0';
2079 chan_data++;
2080 }
2081
1dcb3b67 2082 if (oglobals.session) {
e6a60a20
AM
2083 if (!switch_channel_ready(caller_channel)) {
2084 status = SWITCH_STATUS_FALSE;
2085 goto done;
2086 }
2087
debdfb1a 2088 caller_caller_profile = caller_profile_override ? caller_profile_override : switch_channel_get_caller_profile(caller_channel);
1dcb3b67 2089 new_profile = switch_caller_profile_clone(oglobals.session, caller_caller_profile);
ffb989e4
AM
2090 new_profile->uuid = SWITCH_BLANK_STRING;
2091 new_profile->chan_name = SWITCH_BLANK_STRING;
2092 new_profile->destination_number = switch_core_strdup(new_profile->pool, chan_data);
742bc4dd
AM
2093
2094 if (switch_channel_direction(caller_channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
2095 const char *callee_id_name = new_profile->callee_id_name;
2096 const char *callee_id_number = new_profile->callee_id_number;
2097
2098 if (zstr(callee_id_number)) {
2099 callee_id_number = new_profile->destination_number;
2100 }
2101
2102 if (zstr(callee_id_name)) {
2103 callee_id_name = callee_id_number;
2104 }
2105
2106 new_profile->caller_id_name = callee_id_name;
2107 new_profile->caller_id_number = callee_id_number;
2108 new_profile->callee_id_name = SWITCH_BLANK_STRING;
2109 new_profile->callee_id_number = SWITCH_BLANK_STRING;
2110 }
e6a60a20 2111
d264ed5a 2112 if (cid_name_override) {
ffb989e4 2113 new_profile->caller_id_name = switch_core_strdup(new_profile->pool, cid_name_override);
e6a60a20 2114 }
d264ed5a 2115 if (cid_num_override) {
ffb989e4 2116 new_profile->caller_id_number = switch_core_strdup(new_profile->pool, cid_num_override);
e6a60a20
AM
2117 }
2118
e6a60a20
AM
2119 pool = NULL;
2120 } else {
ffb989e4 2121 switch_core_new_memory_pool(&pool);
e6a60a20
AM
2122
2123 if (caller_profile_override) {
d264ed5a 2124 new_profile = switch_caller_profile_dup(pool, caller_profile_override);
2847d1c0 2125 new_profile->destination_number = switch_core_strdup(new_profile->pool, switch_str_nil(chan_data));
ffb989e4
AM
2126 new_profile->uuid = SWITCH_BLANK_STRING;
2127 new_profile->chan_name = SWITCH_BLANK_STRING;
e6a60a20 2128 } else {
d264ed5a
MJ
2129 if (!cid_name_override) {
2130 cid_name_override = "FreeSWITCH";
2131 }
2132 if (!cid_num_override) {
2133 cid_num_override = "0000000000";
2134 }
2135
bf7144b2 2136 new_profile = switch_caller_profile_new(pool,
30ffb593
MJ
2137 NULL,
2138 NULL,
3c349c27 2139 cid_name_override, cid_num_override, NULL, NULL, NULL, NULL, __FILE__, NULL, chan_data);
e6a60a20
AM
2140 }
2141 }
3c349c27 2142
1dcb3b67
AM
2143 originate_status[i].caller_profile = NULL;
2144 originate_status[i].peer_channel = NULL;
2145 originate_status[i].peer_session = NULL;
bf7144b2 2146 new_session = NULL;
3c349c27 2147
8433c7e0
AM
2148 if (and_argc > 1 || or_argc > 1) {
2149 myflags |= SOF_FORKED_DIAL;
21da7429
AM
2150 } else if (var_event) {
2151 const char *vvar;
2152 if ((vvar = switch_event_get_header(var_event, "forked_dial")) && switch_true(vvar)) {
2153 myflags |= SOF_FORKED_DIAL;
2154 }
8433c7e0 2155 }
dfda1d8f
BW
2156
2157 /* only valid in [] since it's unique to each channel leg */
3720a64e 2158
dfda1d8f 2159 if (vdata && (var_begin = switch_stristr("origination_uuid=", vdata))) {
3720a64e 2160 char tmp[512] = "";
dfda1d8f 2161 var_begin += strlen("origination_uuid=");
3720a64e 2162 var_end = strchr(var_begin, '|');
dfda1d8f 2163
3720a64e
AM
2164 if (var_end) {
2165 strncpy(tmp, var_begin, var_end-var_begin);
2166 } else {
2167 strncpy(tmp, var_begin, strlen(var_begin));
2168 }
dfda1d8f 2169
dfda1d8f 2170 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "origination_uuid", tmp);
3720a64e
AM
2171 }
2172
dfda1d8f
BW
2173 /* The rest are valid in both {} and [] with [] taking precedence */
2174
2175 current_variable = NULL;
2176
2177 if (vdata && (var_begin = switch_stristr("origination_caller_id_number=", vdata))) {
2178 var_begin += strlen("origination_caller_id_number=");
3720a64e 2179 var_end = strchr(var_begin, '|');
dfda1d8f 2180
3720a64e 2181 if (var_end) {
dfda1d8f 2182 strncpy(variable_buffer, var_begin, var_end-var_begin);
3720a64e 2183 } else {
dfda1d8f 2184 strncpy(variable_buffer, var_begin, strlen(var_begin));
3720a64e 2185 }
dfda1d8f
BW
2186
2187 current_variable = variable_buffer;
2188 }
2189
2190 if (current_variable || (current_variable = switch_event_get_header(var_event, "origination_caller_id_number"))) {
2191 new_profile->caller_id_number = switch_core_strdup(new_profile->pool, current_variable);
2192 myflags |= SOF_NO_EFFECTIVE_CID_NUM;
3720a64e
AM
2193 }
2194
dfda1d8f
BW
2195 current_variable = NULL;
2196
2197 if (vdata && (var_begin = switch_stristr("origination_caller_id_name=", vdata))) {
2198 var_begin += strlen("origination_caller_id_name=");
c9a24dd3 2199 var_end = strchr(var_begin, '|');
dfda1d8f 2200
c9a24dd3 2201 if (var_end) {
dfda1d8f 2202 strncpy(variable_buffer, var_begin, var_end-var_begin);
c9a24dd3 2203 } else {
dfda1d8f 2204 strncpy(variable_buffer, var_begin, strlen(var_begin));
c9a24dd3 2205 }
674a18f9 2206
dfda1d8f
BW
2207 current_variable = variable_buffer;
2208 }
2209
2210 if (current_variable || (current_variable = switch_event_get_header(var_event, "origination_caller_id_name"))) {
9694ce04 2211 new_profile->caller_id_name = switch_core_strdup(new_profile->pool, current_variable);
dfda1d8f
BW
2212 myflags |= SOF_NO_EFFECTIVE_CID_NAME;
2213 }
2214
2215 current_variable = NULL;
2216
674a18f9 2217 if (vdata && (var_begin = switch_stristr("origination_privacy=", vdata))) {
674a18f9
AM
2218 var_begin += strlen("origination_privacy=");
2219 var_end = strchr(var_begin, '|');
dfda1d8f 2220
674a18f9 2221 if (var_end) {
dfda1d8f 2222 strncpy(variable_buffer, var_begin, var_end-var_begin);
674a18f9 2223 } else {
dfda1d8f 2224 strncpy(variable_buffer, var_begin, strlen(var_begin));
674a18f9 2225 }
dfda1d8f
BW
2226
2227 current_variable = variable_buffer;
8b6aeebd
AM
2228 }
2229
dfda1d8f 2230 if (current_variable || (current_variable = switch_event_get_header(var_event, "origination_privacy"))) {
674a18f9 2231 new_profile->flags = SWITCH_CPF_NONE;
8b6aeebd 2232
dfda1d8f 2233 if (switch_stristr("screen", current_variable)) {
674a18f9
AM
2234 switch_set_flag(new_profile, SWITCH_CPF_SCREEN);
2235 }
2236
dfda1d8f 2237 if (switch_stristr("hide_name", current_variable)) {
674a18f9
AM
2238 switch_set_flag(new_profile, SWITCH_CPF_HIDE_NAME);
2239 }
2240
dfda1d8f 2241 if (switch_stristr("hide_number", current_variable)) {
674a18f9
AM
2242 switch_set_flag(new_profile, SWITCH_CPF_HIDE_NUMBER);
2243 }
674a18f9 2244 }
dfda1d8f
BW
2245
2246 current_variable = NULL;
2247 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "originate_early_media", oglobals.early_ok ? "true" : "false");
2248
1dcb3b67 2249 if ((reason = switch_core_session_outgoing_channel(oglobals.session, var_event, chan_type,
2fa0c491 2250 new_profile, &new_session, &pool, myflags, cancel_cause)) != SWITCH_CAUSE_SUCCESS) {
c2d5f970 2251 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot create outgoing channel of type [%s] cause: [%s]\n",
4ed389f9
AM
2252 chan_type, switch_channel_cause2str(reason));
2253
e6a60a20
AM
2254 if (pool) {
2255 switch_core_destroy_memory_pool(&pool);
2256 }
e6a60a20
AM
2257 continue;
2258 }
2259
ea5c3852
AM
2260 if (switch_core_session_read_lock(new_session) != SWITCH_STATUS_SUCCESS) {
2261 status = SWITCH_STATUS_FALSE;
2262 goto done;
2263 }
e6a60a20
AM
2264 pool = NULL;
2265
1dcb3b67
AM
2266 originate_status[i].caller_profile = new_profile;
2267 originate_status[i].peer_session = new_session;
2268 originate_status[i].peer_channel = switch_core_session_get_channel(new_session);
2269 switch_channel_set_flag(originate_status[i].peer_channel, CF_ORIGINATING);
3c349c27 2270
f9642e96
AM
2271 if ((lc = switch_event_get_header(var_event, "local_var_clobber"))) {
2272 local_clobber = switch_true(lc);
2273 }
2274
cdd0bcfd 2275 if (local_clobber) {
f9642e96
AM
2276 if (var_event) {
2277 switch_event_t *event;
2278 switch_event_header_t *header;
2279 /* install the vars from the {} params */
2280 for (header = var_event->headers; header; header = header->next) {
2281 switch_channel_set_variable(originate_status[i].peer_channel, header->name, header->value);
2282 }
2283 switch_event_create(&event, SWITCH_EVENT_CHANNEL_ORIGINATE);
2284 switch_assert(event);
2285 switch_channel_event_set_data(originate_status[i].peer_channel, event);
2286 switch_event_fire(&event);
2287 }
2288 }
2289
5c5c3251
AM
2290 if (vdata) {
2291 char *var_array[1024] = { 0 };
2292 int var_count = 0;
6eebc864 2293 if ((var_count = switch_separate_string(vdata, '|', var_array, (sizeof(var_array) / sizeof(var_array[0]))))) {
5c5c3251
AM
2294 int x = 0;
2295 for (x = 0; x < var_count; x++) {
00265fe6 2296 char *inner_var_array[2] = { 0 };
5c5c3251
AM
2297 int inner_var_count;
2298 if ((inner_var_count =
3c349c27 2299 switch_separate_string(var_array[x], '=',
5c5c3251 2300 inner_var_array, (sizeof(inner_var_array) / sizeof(inner_var_array[0])))) == 2) {
3c349c27 2301
1dcb3b67 2302 switch_channel_set_variable(originate_status[i].peer_channel, inner_var_array[0], inner_var_array[1]);
5c5c3251
AM
2303 }
2304 }
2305 }
2306 }
3c349c27 2307
cdd0bcfd 2308 if (!local_clobber) {
f9642e96
AM
2309 if (var_event) {
2310 switch_event_t *event;
2311 switch_event_header_t *header;
2312 /* install the vars from the {} params */
2313 for (header = var_event->headers; header; header = header->next) {
2314 switch_channel_set_variable(originate_status[i].peer_channel, header->name, header->value);
2315 }
2316 switch_event_create(&event, SWITCH_EVENT_CHANNEL_ORIGINATE);
2317 switch_assert(event);
2318 switch_channel_event_set_data(originate_status[i].peer_channel, event);
2319 switch_event_fire(&event);
466bbe70 2320 }
466bbe70
AM
2321 }
2322
1dcb3b67 2323 if (originate_status[i].peer_channel) {
4ed389f9 2324 const char *vvar;
e5e95242 2325
3dfe6780
AM
2326 if ((vvar = switch_channel_get_variable(originate_status[i].peer_channel, "origination_callee_id_name"))) {
2327 switch_channel_set_profile_var(originate_status[i].peer_channel, "callee_id_name", vvar);
2328 }
2329
2330 if ((vvar = switch_channel_get_variable(originate_status[i].peer_channel, "origination_callee_id_number"))) {
2331 switch_channel_set_profile_var(originate_status[i].peer_channel, "callee_id_number", vvar);
2332 }
2333
1dcb3b67 2334 if ((vvar = switch_channel_get_variable(originate_status[i].peer_channel, "leg_timeout"))) {
4ed389f9
AM
2335 int val = atoi(vvar);
2336 if (val > 0) {
c2d5f970 2337 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Setting leg timeout to %d\n",
e071f1a6 2338 switch_channel_get_name(originate_status[i].peer_channel), val);
29c616b9 2339 originate_status[i].per_channel_timelimit_sec = (uint32_t) val;
4ed389f9
AM
2340 }
2341 }
2342
1dcb3b67 2343 if ((vvar = switch_channel_get_variable(originate_status[i].peer_channel, "leg_progress_timeout"))) {
4ed389f9
AM
2344 int val = atoi(vvar);
2345 if (val > 0) {
c2d5f970 2346 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Setting leg progress timeout to %d\n",
e071f1a6 2347 switch_channel_get_name(originate_status[i].peer_channel), val);
29c616b9 2348 originate_status[i].per_channel_progress_timelimit_sec = (uint32_t) val;
4ed389f9
AM
2349 }
2350 }
d7a12df5
AM
2351
2352 if ((vvar = switch_channel_get_variable(originate_status[i].peer_channel, "leg_delay_start"))) {
2353 int val = atoi(vvar);
2354 if (val > 0) {
c2d5f970 2355 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Setting leg delay start to %d\n",
e071f1a6 2356 switch_channel_get_name(originate_status[i].peer_channel), val);
d7a12df5 2357 originate_status[i].per_channel_delay_start = (uint32_t) val;
160535da
AM
2358
2359 if (originate_status[i].per_channel_progress_timelimit_sec != 0) {
2360 originate_status[i].per_channel_progress_timelimit_sec += originate_status[i].per_channel_delay_start;
2361 }
2362
2363 if (originate_status[i].per_channel_timelimit_sec != 0) {
2364 originate_status[i].per_channel_timelimit_sec += originate_status[i].per_channel_delay_start;
2365 }
d7a12df5
AM
2366 }
2367 }
4ed389f9
AM
2368 }
2369
e6a60a20 2370 if (table) {
1dcb3b67 2371 switch_channel_add_state_handler(originate_status[i].peer_channel, table);
e6a60a20
AM
2372 }
2373
d2bf2022
AM
2374 switch_channel_add_state_handler(originate_status[i].peer_channel, &originate_state_handlers);
2375
1dcb3b67 2376 if ((flags & SOF_NOBLOCK) && originate_status[i].peer_session) {
8433c7e0 2377 status = SWITCH_STATUS_SUCCESS;
1dcb3b67 2378 *bleg = originate_status[i].peer_session;
8433c7e0
AM
2379 *cause = SWITCH_CAUSE_SUCCESS;
2380 goto outer_for;
2381 }
3c349c27 2382
1dcb3b67 2383 if (!switch_core_session_running(originate_status[i].peer_session)) {
d7a12df5
AM
2384 if (originate_status[i].per_channel_delay_start) {
2385 switch_channel_set_flag(originate_status[i].peer_channel, CF_BLOCK_STATE);
2386 }
1dcb3b67 2387 switch_core_session_thread_launch(originate_status[i].peer_session);
e6a60a20 2388 }
3c349c27 2389 }
e6a60a20 2390
0463541d 2391 switch_epoch_time_now(&start);
e6a60a20
AM
2392
2393 for (;;) {
2394 uint32_t valid_channels = 0;
2395 for (i = 0; i < and_argc; i++) {
2396 int state;
4ed389f9 2397 time_t elapsed;
e6a60a20 2398
1dcb3b67 2399 if (!originate_status[i].peer_channel) {
e6a60a20
AM
2400 continue;
2401 }
d57e0387 2402
1dcb3b67 2403 state = switch_channel_get_state(originate_status[i].peer_channel);
e6a60a20 2404
d57e0387
AM
2405 if (state < CS_HANGUP) {
2406 valid_channels++;
2407 } else {
2408 continue;
2409 }
2410
4b929592 2411 if (state >= CS_ROUTING) {
e6a60a20
AM
2412 goto endfor1;
2413 }
2414
2415 if (caller_channel && !switch_channel_ready(caller_channel)) {
2416 goto notready;
2417 }
4ed389f9 2418
0463541d 2419 elapsed = switch_epoch_time_now(NULL) - start;
4ed389f9
AM
2420
2421 if (elapsed > (time_t) timelimit_sec) {
e6a60a20 2422 to++;
1dcb3b67 2423 oglobals.idx = IDX_TIMEOUT;
e6a60a20
AM
2424 goto notready;
2425 }
e6a60a20 2426
6cf98363
AM
2427 if (!oglobals.sent_ring && !oglobals.ignore_ring_ready &&
2428 !oglobals.progress && (progress_timelimit_sec && elapsed > (time_t) progress_timelimit_sec)) {
f33aa021 2429 to++;
1dcb3b67 2430 oglobals.idx = IDX_TIMEOUT;
f33aa021
AM
2431 goto notready;
2432 }
4ed389f9 2433
292ed6ee 2434 switch_cond_next();
d57e0387 2435 }
3c349c27 2436
478efc5f 2437 check_per_channel_timeouts(&oglobals, originate_status, and_argc, start);
4ed389f9
AM
2438
2439
e6a60a20
AM
2440 if (valid_channels == 0) {
2441 status = SWITCH_STATUS_GENERR;
2442 goto done;
2443 }
2444
2445 }
d57e0387 2446
697bb6ec 2447 endfor1:
e6a60a20 2448
047e3dd7 2449 if (caller_channel) {
e072a609
AM
2450 if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE) ||
2451 switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA) || switch_channel_test_flag(caller_channel, CF_DISABLE_RINGBACK)) {
047e3dd7
AM
2452 ringback_data = NULL;
2453 }
2454 }
2455
a9936c09 2456
e6a60a20 2457
78bc4172
AM
2458#if 0
2459 /* changing behaviour ignore_early_media=true must also be explicitly set for previous behaviour */
e6a60a20 2460 if (ringback_data) {
1dcb3b67 2461 oglobals.early_ok = 0;
e6a60a20 2462 }
78bc4172 2463#endif
aaeb69d6 2464
757aa19e
AM
2465 if (ringback_data) {
2466 oglobals.sending_ringback = 1;
2467 } else {
2468 oglobals.ringback_ok = 0;
2469 }
2f4fcf9a 2470
1ae5b7cb
AM
2471 if (caller_channel) {
2472 soft_holding = switch_channel_get_variable(caller_channel, SWITCH_SOFT_HOLDING_UUID_VARIABLE);
2473 }
2f4fcf9a 2474
2fa0c491
AM
2475 while ((!caller_channel || switch_channel_ready(caller_channel) || switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE)) &&
2476 check_channel_status(&oglobals, originate_status, and_argc)) {
0463541d 2477 time_t elapsed = switch_epoch_time_now(NULL) - start;
584669c2 2478
2fa0c491
AM
2479 if (cancel_cause && *cancel_cause > 0) {
2480 force_reason = *cancel_cause;
2481 oglobals.idx = IDX_CANCEL;
2482 goto notready;
2483 }
2484
478efc5f 2485 check_per_channel_timeouts(&oglobals, originate_status, and_argc, start);
4ed389f9 2486
59b94dfa 2487 if (oglobals.session) {
1dcb3b67 2488 switch_ivr_parse_all_events(oglobals.session);
8b1ad09d
AM
2489 }
2490
1dcb3b67
AM
2491 if (!oglobals.sent_ring && !oglobals.progress && (progress_timelimit_sec && elapsed > (time_t) progress_timelimit_sec)) {
2492 oglobals.idx = IDX_TIMEOUT;
e6a60a20
AM
2493 goto notready;
2494 }
2495
1dcb3b67 2496 if ((to = (uint8_t) (elapsed >= (time_t) timelimit_sec)) || (fail_on_single_reject && oglobals.hups)) {
4ed389f9
AM
2497 int ok = 0;
2498
2499 if (fail_on_single_reject_var && !switch_true(fail_on_single_reject_var)) {
2500 ok = 1;
2501 for (i = 0; i < and_argc; i++) {
2502 switch_channel_t *pchannel;
4ed389f9
AM
2503 const char *cause_str;
2504
1dcb3b67 2505 if (!originate_status[i].peer_session) {
4ed389f9
AM
2506 continue;
2507 }
1dcb3b67 2508 pchannel = switch_core_session_get_channel(originate_status[i].peer_session);
757aa19e 2509
9556be51 2510 if (switch_channel_down(pchannel)) {
cb970d8f 2511 cause_str = switch_channel_cause2str(switch_channel_get_cause(pchannel));
4ed389f9
AM
2512 if (switch_stristr(cause_str, fail_on_single_reject_var)) {
2513 ok = 0;
2514 break;
2515 }
2516 }
2517 }
2518 }
2519 if (!ok) {
1dcb3b67 2520 oglobals.idx = IDX_TIMEOUT;
4ed389f9
AM
2521 goto notready;
2522 }
2523 }
befbd6dd 2524
3c349c27 2525 /* read from the channel while we wait if the audio is up on it */
1dcb3b67 2526 if (oglobals.session &&
3c349c27
AM
2527 !switch_channel_test_flag(caller_channel, CF_PROXY_MODE) &&
2528 !switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA) &&
aaeb69d6 2529 !switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE) &&
757aa19e 2530 (oglobals.ringback_ok
3c349c27 2531 || (switch_channel_test_flag(caller_channel, CF_ANSWERED) || switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA)))) {
aaeb69d6 2532
2e46528e 2533 switch_status_t tstatus = SWITCH_STATUS_SUCCESS;
fc1de32f 2534 int silence = 0;
3c349c27 2535
f8b442da
AM
2536 if (caller_channel && cancel_key) {
2537 if (switch_channel_has_dtmf(caller_channel)) {
2538 switch_dtmf_t dtmf = { 0, 0 };
2539 if (switch_channel_dequeue_dtmf(caller_channel, &dtmf) == SWITCH_STATUS_SUCCESS) {
2540 if (dtmf.digit == *cancel_key) {
aaeb69d6 2541 oglobals.idx = IDX_KEY_CANCEL;
f8b442da
AM
2542 goto notready;
2543 }
2544 }
2545 }
2546 }
2547
2e46528e 2548 if (switch_channel_media_ready(caller_channel)) {
1dcb3b67 2549 tstatus = switch_core_session_read_frame(oglobals.session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
2e46528e 2550 if (!SWITCH_READ_ACCEPTABLE(tstatus)) {
2f4fcf9a
AM
2551 if (soft_holding) {
2552 switch_channel_set_flag(caller_channel, CF_XFER_ZOMBIE);
2553 }
2554
7681f944
AM
2555 if (switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE)) {
2556 continue;
2557 }
2e46528e
AM
2558 break;
2559 }
2560 } else {
2561 read_frame = NULL;
e6a60a20 2562 }
0b0ce769 2563
757aa19e
AM
2564 if (oglobals.ringback_ok && (oglobals.ring_ready || oglobals.instant_ringback || oglobals.sending_ringback > 1)) {
2565 if (oglobals.ringback_ok == 1) {
2566 switch_status_t rst = setup_ringback(&oglobals, ringback_data, &ringback, &write_frame, &write_codec);
2567
2568 switch (rst) {
2569 case SWITCH_STATUS_SUCCESS:
2570 oglobals.ringback_ok++;
2571 break;
2572 case SWITCH_STATUS_FALSE:
2573 goto notready;
2574 break;
2575 case SWITCH_STATUS_BREAK:
2576 goto done;
2577 break;
2578 default:
2579 ringback_data = NULL;
2580 oglobals.ringback_ok = 0;
2581 oglobals.sending_ringback = 0;
2582 break;
2583 }
2584
2585 continue;
2586 }
2587
e6a60a20 2588 if (ringback.fh) {
e6a60a20
AM
2589 switch_size_t mlen, olen;
2590 unsigned int pos = 0;
3c349c27 2591
e6a60a20 2592 if (ringback.asis) {
30c318b9 2593 mlen = write_frame.codec->implementation->encoded_bytes_per_packet;
e6a60a20 2594 } else {
30c318b9 2595 mlen = write_frame.codec->implementation->samples_per_packet;
e6a60a20
AM
2596 }
2597
2598 olen = mlen;
ea5c3852
AM
2599
2600 //if (ringback.fh->resampler && ringback.fh->resampler->rfactor > 1) {
2601 //olen = (switch_size_t) (olen * ringback.fh->resampler->rfactor);
2602 //}
468a3c6f 2603
3608c834 2604 switch_core_file_read(ringback.fh, write_frame.data, &olen);
e6a60a20
AM
2605
2606 if (olen == 0) {
2607 olen = mlen;
2608 ringback.fh->speed = 0;
2609 switch_core_file_seek(ringback.fh, &pos, 0, SEEK_SET);
3608c834 2610 switch_core_file_read(ringback.fh, write_frame.data, &olen);
e6a60a20
AM
2611 if (olen == 0) {
2612 break;
2613 }
2614 }
e6a60a20 2615 write_frame.datalen = (uint32_t) (ringback.asis ? olen : olen * 2);
e6a60a20 2616 } else if (ringback.audio_buffer) {
ceb98915
AM
2617 if ((write_frame.datalen = (uint32_t) switch_buffer_read_loop(ringback.audio_buffer,
2618 write_frame.data,
30c318b9 2619 write_frame.codec->implementation->decoded_bytes_per_packet)) <= 0) {
2f4fcf9a
AM
2620
2621 if (soft_holding) {
2622 switch_channel_set_flag(caller_channel, CF_XFER_ZOMBIE);
2623 continue;
2624 }
2625
ceb98915 2626 break;
e6a60a20 2627 }
1136fcec 2628 } else if (ringback.silence) {
fc1de32f 2629 silence = ringback.silence;
e6a60a20 2630 }
fc1de32f 2631 } else {
f5d97f2f 2632 silence = 600;
fc1de32f
AM
2633 }
2634
fc1de32f 2635 if ((ringback.fh || silence || ringback.audio_buffer) && write_frame.codec && write_frame.datalen) {
e276f5fe
AM
2636 if (silence) {
2637 write_frame.datalen = write_frame.codec->implementation->decoded_bytes_per_packet;
2638 switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.datalen / 2, silence);
2639 }
2640
1dcb3b67 2641 if (switch_core_session_write_frame(oglobals.session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
2f4fcf9a
AM
2642 if (soft_holding) {
2643 switch_channel_set_flag(caller_channel, CF_XFER_ZOMBIE);
2644 }
7681f944
AM
2645 if (switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE)) {
2646 continue;
2647 }
fc1de32f 2648 break;
e6a60a20 2649 }
e6a60a20 2650 }
fc1de32f 2651
e6a60a20 2652 } else {
292ed6ee 2653 switch_cond_next();
e6a60a20 2654 }
584669c2 2655
e6a60a20 2656 }
2fa0c491 2657
e6a60a20
AM
2658 notready:
2659
aaeb69d6 2660 if (caller_channel) {
aaeb69d6
AM
2661 holding = switch_channel_get_variable(caller_channel, SWITCH_HOLDING_UUID_VARIABLE);
2662 switch_channel_set_variable(caller_channel, SWITCH_HOLDING_UUID_VARIABLE, NULL);
2663
2664 if (soft_holding && switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE)) {
2665 holding = soft_holding;
2f4fcf9a 2666 soft_holding = NULL;
aaeb69d6
AM
2667 switch_channel_set_variable(caller_channel, SWITCH_SOFT_HOLDING_UUID_VARIABLE, NULL);
2668 }
2669 }
2670
7681f944 2671 if (caller_channel && !switch_channel_ready(caller_channel) && !switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE)) {
1dcb3b67 2672 oglobals.idx = IDX_CANCEL;
e6a60a20
AM
2673 }
2674
1dcb3b67 2675 if (oglobals.session && (ringback_data || !(switch_channel_test_flag(caller_channel, CF_PROXY_MODE) &&
cb12f3cf 2676 switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA)))) {
1dcb3b67 2677 switch_core_session_reset(oglobals.session, SWITCH_FALSE, SWITCH_TRUE);
e6a60a20 2678 }
3c349c27 2679
aaeb69d6
AM
2680 if (holding) {
2681 if (oglobals.idx > IDX_NADA) {
2682 peer_session = originate_status[oglobals.idx].peer_session;
2683 peer_channel = originate_status[oglobals.idx].peer_channel;
2684 originate_status[oglobals.idx].peer_channel = NULL;
2685 } else if (and_argc == 1) {
2686 peer_session = originate_status[0].peer_session;
2687 peer_channel = originate_status[0].peer_channel;
2688 originate_status[0].peer_channel = NULL;
2689 } else {
2690 for (i = 0; i < and_argc; i++) {
2691 if (!peer_eligible(originate_status[i].peer_channel)) {
2692 continue;
2693 }
2694 if (switch_channel_media_ready(originate_status[i].peer_channel)) {
2695 peer_session = originate_status[i].peer_session;
2696 peer_channel = originate_status[i].peer_channel;
2697 originate_status[i].peer_channel = NULL;
2698 goto end_search;
2699 }
2700 }
2701 for (i = 0; i < and_argc; i++) {
2702 if (!peer_eligible(originate_status[i].peer_channel)) {
2703 continue;
2704 }
2705 if (switch_channel_up(originate_status[i].peer_channel)) {
2706 peer_session = originate_status[i].peer_session;
2707 peer_channel = originate_status[i].peer_channel;
2708 originate_status[i].peer_channel = NULL;
2709 break;
2710 }
2711 }
e6a60a20 2712 }
06c1349b 2713
aaeb69d6 2714 end_search:
d7a12df5 2715
06c1349b
AM
2716 if (peer_channel && switch_channel_down(peer_channel)) {
2717 switch_core_session_rwunlock(peer_session);
2718 peer_session = NULL;
2719 peer_channel = NULL;
2720
2721 }
2722
2723 if (oglobals.idx == IDX_TIMEOUT || to || oglobals.idx == IDX_KEY_CANCEL || oglobals.idx == IDX_CANCEL ||
2724 (!peer_session && oglobals.idx == IDX_NADA)) {
2725 const char *dest = NULL;
2726 const char *context = NULL;
2727 const char *dialplan = NULL;
1cbd982a 2728 switch_core_session_t *holding_session;
befbd6dd 2729
aaeb69d6 2730 if (caller_channel) {
df7637f6 2731 if (zstr(context)) {
1cbd982a
AM
2732 context = switch_channel_get_variable(caller_channel, "context");
2733 }
df7637f6 2734 if (zstr(dialplan)) {
1cbd982a
AM
2735 dialplan = switch_channel_get_variable(caller_channel, "dialplan");
2736 }
2737 }
2738
df7637f6 2739 if (zstr(context)) {
1cbd982a
AM
2740 context = "default";
2741 }
2742
df7637f6 2743 if (zstr(context)) {
1cbd982a
AM
2744 dialplan = "XML";
2745 }
2746
2747 if ((holding_session = switch_core_session_locate(holding))) {
7681f944
AM
2748 switch_channel_t *holding_channel = switch_core_session_get_channel(holding_session);
2749 switch_status_t mstatus = SWITCH_STATUS_FALSE;
befbd6dd 2750
7681f944
AM
2751 if (caller_channel) {
2752 if ((mstatus = switch_channel_caller_extension_masquerade(caller_channel, holding_channel, 1)) == SWITCH_STATUS_SUCCESS) {
06c1349b 2753 switch_channel_restart(holding_channel);
7681f944
AM
2754 }
2755 }
2756
2757 if (mstatus != SWITCH_STATUS_SUCCESS) {
06c1349b
AM
2758 if (peer_channel) {
2759 dest = switch_channel_get_variable(peer_channel, "destination_number");
2760 context = switch_channel_get_variable(peer_channel, "context");
2761 dialplan = switch_channel_get_variable(peer_channel, "dialplan");
2762 } else if (caller_channel) {
2763 dest = switch_channel_get_variable(caller_channel, "destination_number");
2764 }
2765 if (dest) {
2766 switch_ivr_session_transfer(holding_session, dest, dialplan, context);
2767 }
7681f944
AM
2768 }
2769
1cbd982a
AM
2770 switch_core_session_rwunlock(holding_session);
2771 holding = NULL;
2772 holding_session = NULL;
aaeb69d6 2773 }
1cbd982a 2774
06c1349b
AM
2775 if (peer_channel) {
2776 switch_channel_hangup(peer_channel, SWITCH_CAUSE_ATTENDED_TRANSFER);
2777 switch_core_session_rwunlock(peer_session);
2778 }
7681f944 2779 force_reason = SWITCH_CAUSE_ATTENDED_TRANSFER;
450e63c0 2780 } else if (zstr(soft_holding)) {
befbd6dd 2781
1cbd982a 2782 if (peer_channel && switch_channel_ready(peer_channel)) {
befbd6dd
AM
2783 switch_core_session_t *holding_session;
2784
1cbd982a 2785 force_reason = SWITCH_CAUSE_ATTENDED_TRANSFER;
befbd6dd
AM
2786
2787 if ((holding_session = switch_core_session_locate(holding))) {
f5b0b8e2 2788 switch_channel_set_variable(switch_core_session_get_channel(holding_session), SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE, "true");
befbd6dd
AM
2789 switch_core_session_rwunlock(holding_session);
2790 }
2791
1cbd982a 2792 switch_ivr_uuid_bridge(holding, switch_core_session_get_uuid(peer_session));
befbd6dd 2793 holding = NULL;
1cbd982a
AM
2794 oglobals.idx = IDX_NADA;
2795 if (caller_channel && switch_channel_up(caller_channel)) {
2796 switch_channel_hangup(caller_channel, SWITCH_CAUSE_ATTENDED_TRANSFER);
2797 }
2798 caller_channel = NULL;
2799 oglobals.session = NULL;
2800 session = NULL;
2801 switch_core_session_rwunlock(peer_session);
2802 } else {
2803 switch_core_session_t *holding_session;
aaeb69d6 2804
1cbd982a
AM
2805 if ((holding_session = switch_core_session_locate(holding))) {
2806 switch_channel_t *holding_channel = switch_core_session_get_channel(holding_session);
befbd6dd 2807
1cbd982a 2808 if (caller_channel && switch_channel_ready(caller_channel)) {
f5b0b8e2 2809 switch_channel_set_variable(holding_channel, SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE, "true");
1cbd982a 2810 switch_ivr_uuid_bridge(holding, switch_core_session_get_uuid(session));
befbd6dd 2811 holding = NULL;
1cbd982a
AM
2812 } else {
2813 switch_channel_hangup(holding_channel, SWITCH_CAUSE_NORMAL_UNSPECIFIED);
2814 }
2815 switch_core_session_rwunlock(holding_session);
aaeb69d6 2816 }
aaeb69d6 2817 }
69120105
AM
2818 }
2819
aaeb69d6
AM
2820 peer_session = NULL;
2821 peer_channel = NULL;
aaeb69d6 2822 }
1cbd982a 2823
aaeb69d6
AM
2824 for (i = 0; i < and_argc; i++) {
2825 if (!peer_eligible(originate_status[i].peer_channel)) {
2826 continue;
2827 }
2828
1dcb3b67 2829 if (i != oglobals.idx) {
aaeb69d6 2830 holding = NULL;
eaf6abfb 2831
7681f944 2832 if (oglobals.idx == IDX_TIMEOUT || to) {
eaf6abfb 2833 reason = SWITCH_CAUSE_NO_ANSWER;
e6a60a20 2834 } else {
1dcb3b67 2835 if (oglobals.idx == IDX_CANCEL) {
eaf6abfb 2836 reason = SWITCH_CAUSE_ORIGINATOR_CANCEL;
e6a60a20 2837 } else {
eaf6abfb
AM
2838 if (and_argc > 1) {
2839 reason = SWITCH_CAUSE_LOSE_RACE;
2840 } else {
2841 reason = SWITCH_CAUSE_NO_ANSWER;
2842 }
e6a60a20
AM
2843 }
2844 }
d7a12df5 2845 if (switch_channel_up(originate_status[i].peer_channel)) {
117c0315 2846 if (caller_channel && i == 0) {
aaeb69d6
AM
2847 holding = switch_channel_get_variable(caller_channel, SWITCH_SOFT_HOLDING_UUID_VARIABLE);
2848 switch_channel_set_variable(caller_channel, SWITCH_SOFT_HOLDING_UUID_VARIABLE, NULL);
2849 }
2850
2851 if (holding && oglobals.idx != IDX_TIMEOUT && oglobals.idx != IDX_KEY_CANCEL) {
f5b0b8e2
AM
2852 switch_core_session_t *holding_session;
2853
2854 if ((holding_session = switch_core_session_locate(holding))) {
2855 switch_channel_set_variable(switch_core_session_get_channel(holding_session), SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE, "true");
2856 switch_core_session_rwunlock(holding_session);
2857 }
2858
aaeb69d6 2859 switch_ivr_uuid_bridge(holding, switch_core_session_get_uuid(originate_status[i].peer_session));
f5b0b8e2 2860 holding = NULL;
aaeb69d6 2861 } else {
2fa0c491 2862 switch_channel_hangup(originate_status[i].peer_channel, force_reason ? force_reason : reason);
117c0315 2863 }
dc3a6538 2864 }
e6a60a20
AM
2865 }
2866 }
aaeb69d6 2867
450e63c0
AM
2868
2869
1dcb3b67 2870 if (oglobals.idx > IDX_NADA) {
450e63c0
AM
2871 if ((peer_session = originate_status[oglobals.idx].peer_session)) {
2872 peer_channel = switch_core_session_get_channel(originate_status[oglobals.idx].peer_session);
2873 }
e6a60a20
AM
2874 } else {
2875 status = SWITCH_STATUS_FALSE;
7c9ffb42 2876 if (caller_channel && peer_channel) {
a000f0bc 2877 switch_process_import(oglobals.session, peer_channel, "import");
3d136b26 2878 }
69120105 2879 peer_channel = NULL;
e6a60a20
AM
2880 goto done;
2881 }
2882
2883 if (caller_channel) {
2884 if (switch_channel_test_flag(peer_channel, CF_ANSWERED)) {
4d9f7de2 2885 switch_channel_pass_callee_id(peer_channel, caller_channel);
5d47a937 2886 status = switch_channel_answer(caller_channel);
e6a60a20 2887 } else if (switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) {
5d47a937
AM
2888 status = switch_channel_pre_answer(caller_channel);
2889 } else {
2890 status = SWITCH_STATUS_SUCCESS;
2891 }
2892
2893 if (status != SWITCH_STATUS_SUCCESS) {
757aa19e
AM
2894 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(peer_channel), SWITCH_LOG_DEBUG, "%s Media Establishment Failed.\n",
2895 switch_channel_get_name(caller_channel));
5d47a937 2896 switch_channel_hangup(peer_channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
e6a60a20
AM
2897 }
2898 }
2899
3c349c27 2900 if (switch_channel_test_flag(peer_channel, CF_ANSWERED) ||
1dcb3b67
AM
2901 (oglobals.early_ok && switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) ||
2902 (oglobals.return_ring_ready && switch_channel_test_flag(peer_channel, CF_RING_READY))
50fc2ffa 2903 ) {
e6a60a20 2904 *bleg = peer_session;
697bb6ec
AM
2905
2906 if (oglobals.monitor_early_media_ring || oglobals.monitor_early_media_fail) {
2907 switch_ivr_stop_tone_detect_session(peer_session);
2908 switch_channel_set_private(peer_channel, "_oglobals_", NULL);
2909 }
2910
e6a60a20
AM
2911 status = SWITCH_STATUS_SUCCESS;
2912 } else {
2913 status = SWITCH_STATUS_FALSE;
2914 }
2915
2916 done:
feb46019 2917
98479fa6 2918 *cause = SWITCH_CAUSE_NONE;
e6a60a20 2919
a188af1c
AM
2920 if (caller_channel && !switch_channel_ready(caller_channel)) {
2921 status = SWITCH_STATUS_FALSE;
2922 }
2923
e6a60a20
AM
2924 if (status == SWITCH_STATUS_SUCCESS) {
2925 if (caller_channel) {
2926 switch_channel_set_variable(caller_channel, "originate_disposition", "call accepted");
7c9ffb42 2927 if (peer_channel) {
a000f0bc 2928 switch_process_import(oglobals.session, peer_channel, "import");
7c9ffb42 2929 }
e6a60a20 2930 }
757aa19e
AM
2931 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals.session), SWITCH_LOG_DEBUG, "Originate Resulted in Success: [%s]\n",
2932 switch_channel_get_name(peer_channel));
e6a60a20
AM
2933 *cause = SWITCH_CAUSE_SUCCESS;
2934
2935 } else {
690d5b25 2936 const char *cdr_var = NULL;
690d5b25
AM
2937 switch_xml_t cdr;
2938 char *xml_text;
2939 char buf[128] = "", buf2[128] = "";
2940
2941 if (caller_channel) {
2942 cdr_var = switch_channel_get_variable(caller_channel, "failed_xml_cdr_prefix");
2943 }
2944
e6a60a20 2945 if (peer_channel) {
690d5b25 2946 *cause = switch_channel_get_cause(peer_channel);
e6a60a20
AM
2947 } else {
2948 for (i = 0; i < and_argc; i++) {
1dcb3b67 2949 if (!originate_status[i].peer_channel) {
e6a60a20
AM
2950 continue;
2951 }
1dcb3b67 2952 *cause = switch_channel_get_cause(originate_status[i].peer_channel);
e6a60a20
AM
2953 break;
2954 }
2955 }
690d5b25
AM
2956
2957 if (cdr_var) {
2958 for (i = 0; i < and_argc; i++) {
bf4dbe09
AM
2959 switch_channel_t *channel;
2960
1dcb3b67 2961 if (!originate_status[i].peer_session) {
690d5b25
AM
2962 continue;
2963 }
bf4dbe09
AM
2964
2965 channel = switch_core_session_get_channel(originate_status[i].peer_session);
690d5b25 2966
8286dedd
AM
2967 switch_channel_wait_for_state_timeout(channel, CS_REPORTING, 5000);
2968
2969 if (!switch_channel_test_flag(channel, CF_TIMESTAMP_SET)) {
2970 switch_channel_set_timestamps(channel);
bf4dbe09 2971 }
8286dedd 2972
1dcb3b67 2973 if (switch_ivr_generate_xml_cdr(originate_status[i].peer_session, &cdr) == SWITCH_STATUS_SUCCESS) {
690d5b25
AM
2974 if ((xml_text = switch_xml_toxml(cdr, SWITCH_FALSE))) {
2975 switch_snprintf(buf, sizeof(buf), "%s_%d", cdr_var, ++cdr_total);
2976 switch_channel_set_variable(caller_channel, buf, xml_text);
2977 switch_safe_free(xml_text);
2978 }
2979 switch_xml_free(cdr);
2980 cdr = NULL;
2981 }
2982
2983 }
2984 switch_snprintf(buf, sizeof(buf), "%s_total", cdr_var);
2985 switch_snprintf(buf2, sizeof(buf2), "%d", cdr_total ? cdr_total : 0);
2986 switch_channel_set_variable(caller_channel, buf, buf2);
2987 }
e6a60a20
AM
2988
2989 if (!*cause) {
2990 if (reason) {
2991 *cause = reason;
2992 } else if (caller_channel) {
2993 *cause = switch_channel_get_cause(caller_channel);
2994 } else {
2995 *cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
2996 }
2997 }
2998
98479fa6 2999 if (*cause == SWITCH_CAUSE_SUCCESS || *cause == SWITCH_CAUSE_NONE) {
69120105
AM
3000 *cause = SWITCH_CAUSE_ORIGINATOR_CANCEL;
3001 }
3002
1dcb3b67 3003 if (oglobals.idx == IDX_CANCEL) {
d57e0387 3004 *cause = SWITCH_CAUSE_ORIGINATOR_CANCEL;
c2d5f970 3005 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals.session), SWITCH_LOG_DEBUG,
debdfb1a 3006 "Originate Cancelled by originator termination Cause: %d [%s]\n", *cause, switch_channel_cause2str(*cause));
e6a60a20 3007
7681f944
AM
3008 } else if (oglobals.idx == IDX_TIMEOUT) {
3009 *cause = SWITCH_CAUSE_NO_ANSWER;
e6a60a20 3010 } else {
c2d5f970 3011 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals.session), SWITCH_LOG_DEBUG,
debdfb1a 3012 "Originate Resulted in Error Cause: %d [%s]\n", *cause, switch_channel_cause2str(*cause));
e6a60a20
AM
3013 }
3014 }
3015
3016 if (caller_channel) {
3017 switch_channel_set_variable(caller_channel, "originate_disposition", switch_channel_cause2str(*cause));
3018 }
3019
e6a60a20
AM
3020 if (ringback.fh) {
3021 switch_core_file_close(ringback.fh);
3022 ringback.fh = NULL;
69120105
AM
3023 } else if (ringback.audio_buffer) {
3024 teletone_destroy_session(&ringback.ts);
3025 switch_buffer_destroy(&ringback.audio_buffer);
3026 }
3027
1dcb3b67
AM
3028 if (oglobals.session) {
3029 switch_core_session_reset(oglobals.session, SWITCH_FALSE, SWITCH_TRUE);
ac1119e6 3030 }
bc2fc3fa 3031
68b0359c 3032 if (switch_core_codec_ready(&write_codec)) {
59ea2d2f 3033 switch_core_codec_destroy(&write_codec);
e6a60a20 3034 }
3c349c27 3035
e6a60a20 3036 for (i = 0; i < and_argc; i++) {
1af037cf
AM
3037 switch_channel_state_t state;
3038
1dcb3b67 3039 if (!originate_status[i].peer_channel) {
e6a60a20
AM
3040 continue;
3041 }
1af037cf 3042
50e9411c 3043 if (status == SWITCH_STATUS_SUCCESS) {
1dcb3b67
AM
3044 switch_channel_clear_flag(originate_status[i].peer_channel, CF_ORIGINATING);
3045 if (bleg && *bleg && *bleg == originate_status[i].peer_session) {
50e9411c
AM
3046 continue;
3047 }
1dcb3b67
AM
3048 } else if ((state=switch_channel_get_state(originate_status[i].peer_channel)) < CS_HANGUP &&
3049 switch_channel_test_flag(originate_status[i].peer_channel, CF_ORIGINATING)) {
3050 if (!(state == CS_RESET || switch_channel_test_flag(originate_status[i].peer_channel, CF_TRANSFER) ||
3051 switch_channel_test_flag(originate_status[i].peer_channel, CF_REDIRECT) ||
3052 switch_channel_test_flag(originate_status[i].peer_channel, CF_BRIDGED))) {
3053 switch_channel_hangup(originate_status[i].peer_channel, *cause);
1af037cf 3054 }
eb2124ae 3055 }
1dcb3b67 3056 switch_channel_clear_flag(originate_status[i].peer_channel, CF_ORIGINATING);
50e9411c 3057
1dcb3b67 3058 switch_core_session_rwunlock(originate_status[i].peer_session);
e6a60a20 3059 }
3c349c27 3060
e6a60a20
AM
3061 if (status == SWITCH_STATUS_SUCCESS) {
3062 goto outer_for;
feb46019
AM
3063 } else {
3064 int ok = 0;
3065
3066 if (fail_on_single_reject_var && !switch_true(fail_on_single_reject_var)) {
3067 ok = 1;
3068 for (i = 0; i < and_argc; i++) {
3069 switch_channel_t *pchannel;
3070 const char *cause_str;
3071
3072 if (!originate_status[i].peer_session) {
3073 continue;
3074 }
3075 pchannel = switch_core_session_get_channel(originate_status[i].peer_session);
3076
3077 if (switch_channel_down(pchannel)) {
3078 cause_str = switch_channel_cause2str(switch_channel_get_cause(pchannel));
3079 if (switch_stristr(cause_str, fail_on_single_reject_var)) {
3080 ok = 0;
3081 break;
3082 }
3083 }
3084 }
3085 }
5dd46353 3086 if (ok) {
feb46019
AM
3087 goto outer_for;
3088 }
5b6d1cd3
AM
3089
3090 if (to && !oglobals.continue_on_timeout) {
3091 goto outer_for;
3092 }
e6a60a20
AM
3093 }
3094 }
3095 }
3096 outer_for:
3097 switch_safe_free(loop_data);
3098 switch_safe_free(odata);
eb2124ae
AM
3099
3100 if (bleg && status != SWITCH_STATUS_SUCCESS) {
3101 *bleg = NULL;
3102 }
3103
cb5096db 3104 if (*bleg) {
3963930e 3105 if (session && caller_channel) {
45110ff3
AM
3106 switch_caller_profile_t *cloned_profile, *peer_profile = switch_channel_get_caller_profile(switch_core_session_get_channel(*bleg));
3107
3108 if (peer_profile) {
b7db7531 3109 if ((cloned_profile = switch_caller_profile_clone(session, peer_profile)) != 0) {
45110ff3
AM
3110 switch_channel_set_originatee_caller_profile(caller_channel, cloned_profile);
3111 }
3112 }
3113 }
3114
71054917 3115 switch_ivr_sleep(*bleg, 0, SWITCH_TRUE, NULL);
cb5096db
AM
3116 }
3117
8187f4a3 3118 if (oglobals.session && status == SWITCH_STATUS_SUCCESS) {
1dcb3b67 3119 switch_ivr_sleep(oglobals.session, 0, SWITCH_TRUE, NULL);
cb5096db 3120 }
3c349c27 3121
a579a283 3122 if (var_event && var_event != ovars) {
9ec90012
AM
3123 switch_event_destroy(&var_event);
3124 }
feb46019 3125
3608c834 3126 switch_safe_free(write_frame.data);
feb46019 3127 switch_safe_free(fail_on_single_reject_var);
4d9f7de2 3128
aaeb69d6
AM
3129 if (caller_channel) {
3130 switch_channel_clear_flag(caller_channel, CF_ORIGINATOR);
3131 switch_channel_clear_flag(caller_channel, CF_XFER_ZOMBIE);
3132 }
3133
7681f944
AM
3134 if (force_reason != SWITCH_CAUSE_NONE) {
3135 *cause = force_reason;
3136 }
3137
e6a60a20
AM
3138 return status;
3139}
aab6766e
BW
3140
3141/* For Emacs:
3142 * Local Variables:
3143 * mode:c
b0ad7ab5 3144 * indent-tabs-mode:t
aab6766e
BW
3145 * tab-width:4
3146 * c-basic-offset:4
3147 * End:
3148 * For VIM:
64997c4d 3149 * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
aab6766e 3150 */