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