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