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