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