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