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