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