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