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