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