Bug Summary

File:src/switch_ivr.c
Location:line 2174, column 16
Description:Potential leak of memory pointed to by '__retval'

Annotated Source Code

1/*
2 * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3 * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
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
20 * Anthony Minessale II <anthm@freeswitch.org>
21 * Portions created by the Initial Developer are Copyright (C)
22 * the Initial Developer. All Rights Reserved.
23 *
24 * Contributor(s):
25 *
26 * Anthony Minessale II <anthm@freeswitch.org>
27 * Paul D. Tinsley <pdt at jackhammer.org>
28 * Neal Horman <neal at wanlink dot com>
29 * Matt Klein <mklein@nmedia.net>
30 * Michael Jerris <mike@jerris.com>
31 * Ken Rice <krice at suspicious dot org>
32 * Marc Olivier Chouinard <mochouinard@moctel.com>
33 *
34 * switch_ivr.c -- IVR Library
35 *
36 */
37
38#include <switch.h>
39#include <switch_ivr.h>
40
41SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_sound_test(switch_core_session_t *session)
42{
43
44 switch_codec_implementation_t imp = { 0 };
45 switch_codec_t codec = { 0 };
46 int16_t peak = 0;
47 int16_t *data;
48 switch_frame_t *read_frame = NULL((void*)0);
49 uint32_t i;
50 switch_channel_t *channel = switch_core_session_get_channel(session);
51 switch_status_t status = SWITCH_STATUS_SUCCESS;
52 int64_t global_total = 0, global_sum = 0, period_sum = 0;
53 int period_total = 0;
54 int period_avg = 0, global_avg = 0;
55 int avg = 0;
56 int period_len;
57
58 switch_core_session_get_read_impl(session, &imp);
59
60 period_len = imp.actual_samples_per_second / imp.samples_per_packet;
61
62 if (switch_core_codec_init(&codec,switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.samples_per_second, imp.microseconds_per_packet / 1000
, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
63 "L16",switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.samples_per_second, imp.microseconds_per_packet / 1000
, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
64 NULL,switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.samples_per_second, imp.microseconds_per_packet / 1000
, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
65 imp.samples_per_second,switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.samples_per_second, imp.microseconds_per_packet / 1000
, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
66 imp.microseconds_per_packet / 1000,switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.samples_per_second, imp.microseconds_per_packet / 1000
, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
67 imp.number_of_channels,switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.samples_per_second, imp.microseconds_per_packet / 1000
, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
68 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.samples_per_second, imp.microseconds_per_packet / 1000
, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
69 switch_core_session_get_pool(session))switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.samples_per_second, imp.microseconds_per_packet / 1000
, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
!= SWITCH_STATUS_SUCCESS) {
70 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 70, (const char*)(session)
, SWITCH_LOG_ERROR, "Codec Error L16@%uhz %u channels %dms\n",
71 imp.samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000);
72 return SWITCH_STATUS_FALSE;
73 }
74
75 while (switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE)) {
76 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
77
78 if (!SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK
|| status == SWITCH_STATUS_INUSE)
) {
79 break;
80 }
81
82 if (switch_test_flag(read_frame, SFF_CNG)((read_frame)->flags & SFF_CNG) || !read_frame->samples) {
83 continue;
84 }
85
86
87 data = (int16_t *) read_frame->data;
88 peak = 0;
89 avg = 0;
90 for (i = 0; i < read_frame->samples; i++) {
91 const int16_t s = (int16_t) abs(data[i]);
92 if (s > peak) {
93 peak = s;
94 }
95 avg += s;
96 }
97
98 avg /= read_frame->samples;
99
100 period_sum += peak;
101 global_sum += peak;
102
103 global_total++;
104 period_total++;
105
106 period_avg = (int) (period_sum / period_total);
107
108 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 108, (const char*)(session)
, SWITCH_LOG_CONSOLE,
109 "\npacket_avg=%d packet_peak=%d period_avg=%d global_avg=%d\n\n", avg, peak, period_avg, global_avg);
110
111 if (period_total >= period_len) {
112 global_avg = (int) (global_sum / global_total);
113 period_total = 0;
114 period_sum = 0;
115 }
116
117 }
118
119
120 switch_core_codec_destroy(&codec);
121
122 return SWITCH_STATUS_SUCCESS;
123
124}
125
126SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_sleep(switch_core_session_t *session, uint32_t ms, switch_bool_t sync, switch_input_args_t *args)
127{
128 switch_channel_t *channel = switch_core_session_get_channel(session);
129 switch_status_t status = SWITCH_STATUS_SUCCESS;
130 switch_time_t start = switch_micro_time_now(), now, done = switch_micro_time_now() + (ms * 1000);
131 switch_frame_t *read_frame, cng_frame = { 0 };
132 int32_t left;
133 uint32_t elapsed;
134 char data[2] = "";
135
136 switch_frame_t write_frame = { 0 };
137 unsigned char *abuf = NULL((void*)0);
138 switch_codec_implementation_t imp = { 0 };
139 switch_codec_t codec = { 0 };
140 int sval = 0;
141 const char *var;
142
143 arg_recursion_check_start(args)if (args) { if (args->loops >= 25) { switch_log_printf(
SWITCH_CHANNEL_ID_LOG, "src/switch_ivr.c", (const char *)__func__
, 143, ((void*)0), SWITCH_LOG_ERROR, "RECURSION ERROR! It's not the best idea to call things that collect input recursively from an input callback.\n"
); return SWITCH_STATUS_GENERR; } else {args->loops++;} }
;
144
145 switch_core_session_get_read_impl(session, &imp);
146
147 /*
148 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND && !switch_channel_test_flag(channel, CF_PROXY_MODE) &&
149 !switch_channel_media_ready(channel) && !switch_channel_test_flag(channel, CF_SERVICE)) {
150 if ((status = switch_channel_pre_answer(channel)) != SWITCH_STATUS_SUCCESS) {
151 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot establish media.\n");
152 return SWITCH_STATUS_FALSE;
153 }
154 }
155 */
156
157 if (!switch_channel_media_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_TRUE)) {
158
159 for (elapsed=0; switch_channel_up(channel)(switch_channel_check_signal(channel, SWITCH_TRUE) || switch_channel_get_state
(channel) < CS_HANGUP)
&& elapsed<(ms/20); elapsed++) {
160 if (switch_channel_test_flag(channel, CF_BREAK)) {
161 switch_channel_clear_flag(channel, CF_BREAK);
162 switch_goto_status(SWITCH_STATUS_BREAK, end)status = SWITCH_STATUS_BREAK; goto end;
163 }
164
165 switch_yield(20 * 1000)switch_sleep(20 * 1000);;
166 }
167 switch_goto_status(SWITCH_STATUS_SUCCESS, end)status = SWITCH_STATUS_SUCCESS; goto end;
168 }
169
170 if ((var = switch_channel_get_variable(channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE)switch_channel_get_variable_dup(channel, "send_silence_when_idle"
, SWITCH_TRUE, -1)
)
171 && (sval = atoi(var))) {
172 SWITCH_IVR_VERIFY_SILENCE_DIVISOR(sval){ if ((sval) <= 0 && (sval) != -1) { sval = 400; }
}
;
173 }
174
175 if (ms > 10 && sval) {
176
177 if (switch_core_codec_init(&codec,switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.actual_samples_per_second, imp.microseconds_per_packet
/ 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE |
SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
178 "L16",switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.actual_samples_per_second, imp.microseconds_per_packet
/ 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE |
SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
179 NULL,switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.actual_samples_per_second, imp.microseconds_per_packet
/ 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE |
SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
180 imp.actual_samples_per_second,switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.actual_samples_per_second, imp.microseconds_per_packet
/ 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE |
SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
181 imp.microseconds_per_packet / 1000,switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.actual_samples_per_second, imp.microseconds_per_packet
/ 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE |
SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
182 imp.number_of_channels,switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.actual_samples_per_second, imp.microseconds_per_packet
/ 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE |
SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
183 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.actual_samples_per_second, imp.microseconds_per_packet
/ 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE |
SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
184 switch_core_session_get_pool(session))switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.actual_samples_per_second, imp.microseconds_per_packet
/ 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE |
SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
!= SWITCH_STATUS_SUCCESS) {
185 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 185, (const char*)(session)
, SWITCH_LOG_ERROR, "Codec Error L16@%uhz %u channels %dms\n",
186 imp.actual_samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000);
187 switch_goto_status(SWITCH_STATUS_FALSE, end)status = SWITCH_STATUS_FALSE; goto end;
188 }
189
190
191 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 191, (const char*)(session)
, SWITCH_LOG_DEBUG, "Codec Activated L16@%uhz %u channels %dms\n",
192 imp.actual_samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000);
193
194 write_frame.codec = &codec;
195 switch_zmalloc(abuf, SWITCH_RECOMMENDED_BUFFER_SIZE)(void)((((abuf = calloc(1, (8192)))) ? (void) (0) : __assert_fail
("(abuf = calloc(1, (8192)))", "src/switch_ivr.c", 195, __PRETTY_FUNCTION__
)),abuf)
;
196 write_frame.data = abuf;
197 write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE8192;
198 write_frame.datalen = imp.decoded_bytes_per_packet;
199 write_frame.samples = write_frame.datalen / sizeof(int16_t);
200
201 }
202
203 if (!write_frame.datalen) {
204 sval = 0;
205 }
206
207 cng_frame.data = data;
208 cng_frame.datalen = 2;
209 cng_frame.buflen = 2;
210 switch_set_flag((&cng_frame), SFF_CNG)((&cng_frame))->flags |= (SFF_CNG);
211
212 if (sync) {
213 switch_channel_audio_sync(channel)switch_channel_perform_audio_sync(channel, "src/switch_ivr.c"
, (const char *)__func__, 213)
;
214 }
215
216 if (!ms) {
217 switch_goto_status(SWITCH_STATUS_SUCCESS, end)status = SWITCH_STATUS_SUCCESS; goto end;
218 }
219
220 for (;;) {
221 now = switch_micro_time_now();
222 elapsed = (int32_t) ((now - start) / 1000);
223 left = ms - elapsed;
224
225 if (!switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE)) {
226 status = SWITCH_STATUS_FALSE;
227 break;
228 }
229
230 if (switch_channel_test_flag(channel, CF_BREAK)) {
231 switch_channel_clear_flag(channel, CF_BREAK);
232 status = SWITCH_STATUS_BREAK;
233 break;
234 }
235
236 if (now > done || left <= 0) {
237 break;
238 }
239
240
241 switch_ivr_parse_all_events(session);
242
243
244 if (args) {
245 switch_dtmf_t dtmf = {0};
246
247 /*
248 dtmf handler function you can hook up to be executed when a digit is dialed during playback
249 if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
250 */
251 if (switch_channel_has_dtmf(channel)) {
252 if (!args->input_callback && !args->buf && !args->dmachine) {
253 status = SWITCH_STATUS_BREAK;
254 break;
255 }
256 switch_channel_dequeue_dtmf(channel, &dtmf);
257
258 if (args->dmachine) {
259 char ds[2] = {dtmf.digit, '\0'};
260 if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL((void*)0))) != SWITCH_STATUS_SUCCESS) {
261 break;
262 }
263 }
264
265 if (args->input_callback) {
266 status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
267 } else if (args->buf) {
268 *((char *) args->buf) = dtmf.digit;
269 status = SWITCH_STATUS_BREAK;
270 }
271 }
272
273 if (args->input_callback) {
274 switch_event_t *event = NULL((void*)0);
275
276 if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
277 switch_status_t ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen);
278 if (ostatus != SWITCH_STATUS_SUCCESS) {
279 status = ostatus;
280 }
281 switch_event_destroy(&event);
282 }
283 }
284
285 if (status != SWITCH_STATUS_SUCCESS) {
286 break;
287 }
288 }
289
290 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
291
292 if (!SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK
|| status == SWITCH_STATUS_INUSE)
) {
293 break;
294 }
295
296 if (args && args->dmachine) {
297 if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL((void*)0))) != SWITCH_STATUS_SUCCESS) {
298 break;
299 }
300 }
301
302 if (sval && write_frame.datalen) {
303 switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.samples, imp.number_of_channels, sval);
304 switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
305 } else {
306 switch_core_session_write_frame(session, &cng_frame, SWITCH_IO_FLAG_NONE, 0);
307 }
308 }
309
310
311 end:
312
313 arg_recursion_check_stop(args)if (args) args->loops--;
314
315 if (write_frame.codec) {
316 switch_core_codec_destroy(&codec);
317 }
318
319 switch_safe_free(abuf)if (abuf) {free(abuf);abuf=((void*)0);};
320
321 return status;
322}
323
324static void *SWITCH_THREAD_FUNC unicast_thread_run(switch_thread_t *thread, void *obj)
325{
326 switch_unicast_conninfo_t *conninfo = (switch_unicast_conninfo_t *) obj;
327 switch_size_t len;
328
329 if (!conninfo) {
330 return NULL((void*)0);
331 }
332
333 while (switch_test_flag(conninfo, SUF_READY)((conninfo)->flags & SUF_READY) && switch_test_flag(conninfo, SUF_THREAD_RUNNING)((conninfo)->flags & SUF_THREAD_RUNNING)) {
334 len = conninfo->write_frame.buflen;
335 if (switch_socket_recv(conninfo->socket, conninfo->write_frame.data, &len) != SWITCH_STATUS_SUCCESS || len == 0) {
336 break;
337 }
338 conninfo->write_frame.datalen = (uint32_t) len;
339 conninfo->write_frame.samples = conninfo->write_frame.datalen / 2;
340 switch_core_session_write_frame(conninfo->session, &conninfo->write_frame, SWITCH_IO_FLAG_NONE, conninfo->stream_id);
341 }
342
343 switch_clear_flag_locked(conninfo, SUF_READY)switch_mutex_lock(conninfo->flag_mutex); (conninfo)->flags
&= ~(SUF_READY); switch_mutex_unlock(conninfo->flag_mutex
);
;
344 switch_clear_flag_locked(conninfo, SUF_THREAD_RUNNING)switch_mutex_lock(conninfo->flag_mutex); (conninfo)->flags
&= ~(SUF_THREAD_RUNNING); switch_mutex_unlock(conninfo->
flag_mutex);
;
345
346 return NULL((void*)0);
347}
348
349static void unicast_thread_launch(switch_unicast_conninfo_t *conninfo)
350{
351 switch_thread_t *thread;
352 switch_threadattr_t *thd_attr = NULL((void*)0);
353
354 switch_threadattr_create(&thd_attr, switch_core_session_get_pool(conninfo->session));
355 switch_threadattr_detach_set(thd_attr, 1);
356 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024);
357 switch_set_flag_locked(conninfo, SUF_THREAD_RUNNING)((conninfo->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("conninfo->flag_mutex != ((void*)0)", "src/switch_ivr.c"
, 357, __PRETTY_FUNCTION__));switch_mutex_lock(conninfo->flag_mutex
);(conninfo)->flags |= (SUF_THREAD_RUNNING);switch_mutex_unlock
(conninfo->flag_mutex);
;
358 switch_thread_create(&thread, thd_attr, unicast_thread_run, conninfo, switch_core_session_get_pool(conninfo->session));
359}
360
361SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_deactivate_unicast(switch_core_session_t *session)
362{
363 switch_channel_t *channel = switch_core_session_get_channel(session);
364 switch_unicast_conninfo_t *conninfo;
365 int sanity = 0;
366
367 if (!switch_channel_test_flag(channel, CF_UNICAST)) {
368 return SWITCH_STATUS_FALSE;
369 }
370
371 if ((conninfo = switch_channel_get_private(channel, "unicast"))) {
372 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 372, (const char*)(session)
, SWITCH_LOG_DEBUG, "Shutting down unicast connection\n");
373 switch_clear_flag_locked(conninfo, SUF_READY)switch_mutex_lock(conninfo->flag_mutex); (conninfo)->flags
&= ~(SUF_READY); switch_mutex_unlock(conninfo->flag_mutex
);
;
374 switch_socket_shutdown(conninfo->socket, SWITCH_SHUTDOWN_READWRITE);
375 while (switch_test_flag(conninfo, SUF_THREAD_RUNNING)((conninfo)->flags & SUF_THREAD_RUNNING)) {
376 switch_yield(10000)switch_sleep(10000);;
377 if (++sanity >= 10000) {
378 break;
379 }
380 }
381 if (switch_core_codec_ready(&conninfo->read_codec)) {
382 switch_core_codec_destroy(&conninfo->read_codec);
383 }
384 switch_socket_close(conninfo->socket);
385 }
386 switch_channel_clear_flag(channel, CF_UNICAST);
387 return SWITCH_STATUS_SUCCESS;
388}
389
390SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_activate_unicast(switch_core_session_t *session,
391 char *local_ip,
392 switch_port_t local_port,
393 char *remote_ip, switch_port_t remote_port, char *transport, char *flags)
394{
395 switch_channel_t *channel = switch_core_session_get_channel(session);
396 switch_unicast_conninfo_t *conninfo = switch_core_session_alloc(session, sizeof(*conninfo))switch_core_perform_session_alloc(session, sizeof(*conninfo),
"src/switch_ivr.c", (const char *)__func__, 396)
;
397 switch_codec_t *read_codec;
398
399 switch_assert(conninfo != NULL)((conninfo != ((void*)0)) ? (void) (0) : __assert_fail ("conninfo != ((void*)0)"
, "src/switch_ivr.c", 399, __PRETTY_FUNCTION__))
;
400
401 conninfo->local_ip = switch_core_session_strdup(session, local_ip)switch_core_perform_session_strdup(session, local_ip, "src/switch_ivr.c"
, (const char *)__func__, 401)
;
402 conninfo->local_port = local_port;
403
404 conninfo->remote_ip = switch_core_session_strdup(session, remote_ip)switch_core_perform_session_strdup(session, remote_ip, "src/switch_ivr.c"
, (const char *)__func__, 404)
;
405 conninfo->remote_port = remote_port;
406 conninfo->session = session;
407
408 if (!strcasecmp(transport, "udp")) {
409 conninfo->type = AF_INET2;
410 conninfo->transport = SOCK_DGRAMSOCK_DGRAM;
411 } else if (!strcasecmp(transport, "tcp")) {
412 conninfo->type = AF_INET2;
413 conninfo->transport = SOCK_STREAMSOCK_STREAM;
414 } else {
415 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 415, (const char*)(session)
, SWITCH_LOG_ERROR, "Invalid transport %s\n", transport);
416 goto fail;
417 }
418
419 if (flags) {
420 if (strstr(flags, "native")) {
421 switch_set_flag(conninfo, SUF_NATIVE)(conninfo)->flags |= (SUF_NATIVE);
422 }
423 }
424
425 switch_mutex_init(&conninfo->flag_mutex, SWITCH_MUTEX_NESTED0x1, switch_core_session_get_pool(session));
426
427 read_codec = switch_core_session_get_read_codec(session);
428
429 if (!switch_test_flag(conninfo, SUF_NATIVE)((conninfo)->flags & SUF_NATIVE)) {
430 if (switch_core_codec_init(&conninfo->read_codec,switch_core_codec_init_with_bitrate(&conninfo->read_codec
, "L16", ((void*)0), read_codec->implementation->actual_samples_per_second
, read_codec->implementation->microseconds_per_packet /
1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
431 "L16",switch_core_codec_init_with_bitrate(&conninfo->read_codec
, "L16", ((void*)0), read_codec->implementation->actual_samples_per_second
, read_codec->implementation->microseconds_per_packet /
1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
432 NULL,switch_core_codec_init_with_bitrate(&conninfo->read_codec
, "L16", ((void*)0), read_codec->implementation->actual_samples_per_second
, read_codec->implementation->microseconds_per_packet /
1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
433 read_codec->implementation->actual_samples_per_second,switch_core_codec_init_with_bitrate(&conninfo->read_codec
, "L16", ((void*)0), read_codec->implementation->actual_samples_per_second
, read_codec->implementation->microseconds_per_packet /
1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
434 read_codec->implementation->microseconds_per_packet / 1000,switch_core_codec_init_with_bitrate(&conninfo->read_codec
, "L16", ((void*)0), read_codec->implementation->actual_samples_per_second
, read_codec->implementation->microseconds_per_packet /
1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
435 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,switch_core_codec_init_with_bitrate(&conninfo->read_codec
, "L16", ((void*)0), read_codec->implementation->actual_samples_per_second
, read_codec->implementation->microseconds_per_packet /
1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
436 NULL, switch_core_session_get_pool(session))switch_core_codec_init_with_bitrate(&conninfo->read_codec
, "L16", ((void*)0), read_codec->implementation->actual_samples_per_second
, read_codec->implementation->microseconds_per_packet /
1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
== SWITCH_STATUS_SUCCESS) {
437 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 437, (const char*)(session)
, SWITCH_LOG_DEBUG,
438 "Raw Codec Activation Success L16@%uhz 1 channel %dms\n",
439 read_codec->implementation->actual_samples_per_second, read_codec->implementation->microseconds_per_packet / 1000);
440 } else {
441 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 441, (const char*)(session)
, SWITCH_LOG_DEBUG, "Raw Codec Activation Failed L16@%uhz 1 channel %dms\n",
442 read_codec->implementation->actual_samples_per_second, read_codec->implementation->microseconds_per_packet / 1000);
443 goto fail;
444 }
445 }
446
447 conninfo->write_frame.data = conninfo->write_frame_data;
448 conninfo->write_frame.buflen = sizeof(conninfo->write_frame_data);
449 conninfo->write_frame.codec = switch_test_flag(conninfo, SUF_NATIVE)((conninfo)->flags & SUF_NATIVE) ? read_codec : &conninfo->read_codec;
450
451 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 451, (const char*)(session)
, SWITCH_LOG_DEBUG, "connect %s:%d->%s:%d\n",
452 conninfo->local_ip, conninfo->local_port, conninfo->remote_ip, conninfo->remote_port);
453
454 if (switch_sockaddr_info_get(&conninfo->local_addr,
455 conninfo->local_ip, SWITCH_UNSPEC0, conninfo->local_port, 0,
456 switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
457 goto fail;
458 }
459
460 if (switch_sockaddr_info_get(&conninfo->remote_addr,
461 conninfo->remote_ip, SWITCH_UNSPEC0, conninfo->remote_port, 0,
462 switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
463 goto fail;
464 }
465
466 if (switch_socket_create(&conninfo->socket, AF_INET2, SOCK_DGRAMSOCK_DGRAM, 0, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
467 if (switch_socket_bind(conninfo->socket, conninfo->local_addr) != SWITCH_STATUS_SUCCESS) {
468 goto fail;
469 }
470 } else {
471 goto fail;
472 }
473
474 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 474, (const char*)(session)
, SWITCH_LOG_INFO, "Created unicast connection %s:%d->%s:%d\n",
475 conninfo->local_ip, conninfo->local_port, conninfo->remote_ip, conninfo->remote_port);
476 switch_channel_set_private(channel, "unicast", conninfo);
477 switch_channel_set_flag(channel, CF_UNICAST)switch_channel_set_flag_value(channel, CF_UNICAST, 1);
478 switch_set_flag_locked(conninfo, SUF_READY)((conninfo->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("conninfo->flag_mutex != ((void*)0)", "src/switch_ivr.c"
, 478, __PRETTY_FUNCTION__));switch_mutex_lock(conninfo->flag_mutex
);(conninfo)->flags |= (SUF_READY);switch_mutex_unlock(conninfo
->flag_mutex);
;
479 return SWITCH_STATUS_SUCCESS;
480
481 fail:
482
483 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 483, (const char*)(session)
, SWITCH_LOG_CRIT, "Failure creating unicast connection %s:%d->%s:%d\n",
484 conninfo->local_ip, conninfo->local_port, conninfo->remote_ip, conninfo->remote_port);
485 return SWITCH_STATUS_FALSE;
486}
487
488SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_parse_event(switch_core_session_t *session, switch_event_t *event)
489{
490 switch_channel_t *channel = switch_core_session_get_channel(session);
491 char *cmd = switch_event_get_header(event, "call-command")switch_event_get_header_idx(event, "call-command", -1);
492 unsigned long cmd_hash;
493 switch_ssize_t hlen = -1;
494 unsigned long CMD_EXECUTE = switch_hashfunc_default("execute", &hlen);
495 unsigned long CMD_HANGUP = switch_hashfunc_default("hangup", &hlen);
496 unsigned long CMD_NOMEDIA = switch_hashfunc_default("nomedia", &hlen);
497 unsigned long CMD_UNICAST = switch_hashfunc_default("unicast", &hlen);
498 unsigned long CMD_XFEREXT = switch_hashfunc_default("xferext", &hlen);
499 char *lead_frames = switch_event_get_header(event, "lead-frames")switch_event_get_header_idx(event, "lead-frames", -1);
500 char *event_lock = switch_event_get_header(event, "event-lock")switch_event_get_header_idx(event, "event-lock", -1);
501 char *event_lock_pri = switch_event_get_header(event, "event-lock-pri")switch_event_get_header_idx(event, "event-lock-pri", -1);
502 switch_status_t status = SWITCH_STATUS_FALSE;
503 int el = 0, elp = 0;
504
505 if (zstr(cmd)_zstr(cmd)) {
506 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 506, (const char*)(session)
, SWITCH_LOG_ERROR, "Invalid Command!\n");
507 return SWITCH_STATUS_FALSE;
508 }
509
510 cmd_hash = switch_hashfunc_default(cmd, &hlen);
511
512 switch_channel_set_flag_recursive(channel, CF_EVENT_PARSE);
513
514 if (switch_true(event_lock)) {
515 switch_channel_set_flag_recursive(channel, CF_EVENT_LOCK);
516 el = 1;
517 }
518
519 if (switch_true(event_lock_pri)) {
520 switch_channel_set_flag_recursive(channel, CF_EVENT_LOCK_PRI);
521 elp = 1;
522 }
523
524 if (lead_frames) {
525 switch_frame_t *read_frame;
526 int frame_count = atoi(lead_frames);
527 int max_frames = frame_count * 2;
528
529 while (frame_count > 0 && --max_frames > 0) {
530 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
531 if (!SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK
|| status == SWITCH_STATUS_INUSE)
) {
532 goto done;
533 }
534 if (!switch_test_flag(read_frame, SFF_CNG)((read_frame)->flags & SFF_CNG)) {
535 frame_count--;
536 }
537 }
538 }
539
540 if (cmd_hash == CMD_EXECUTE) {
541 char *app_name = switch_event_get_header(event, "execute-app-name")switch_event_get_header_idx(event, "execute-app-name", -1);
542 char *event_uuid = switch_event_get_header(event, "event-uuid")switch_event_get_header_idx(event, "event-uuid", -1);
543 char *app_arg = switch_event_get_header(event, "execute-app-arg")switch_event_get_header_idx(event, "execute-app-arg", -1);
544 char *content_type = switch_event_get_header(event, "content-type")switch_event_get_header_idx(event, "content-type", -1);
545 char *loop_h = switch_event_get_header(event, "loops")switch_event_get_header_idx(event, "loops", -1);
546 char *hold_bleg = switch_event_get_header(event, "hold-bleg")switch_event_get_header_idx(event, "hold-bleg", -1);
547 int loops = 1;
548 int inner = 0;
549
550 if (zstr(app_arg)_zstr(app_arg) && !zstr(content_type)_zstr(content_type) && !strcasecmp(content_type, "text/plain")) {
551 app_arg = switch_event_get_body(event);
552 }
553
554 if (loop_h) {
555 loops = atoi(loop_h);
556 }
557
558 if (app_name) {
559 int x;
560 const char *b_uuid = NULL((void*)0);
561 switch_core_session_t *b_session = NULL((void*)0);
562
563 switch_channel_clear_flag(channel, CF_STOP_BROADCAST);
564
565 if (!switch_channel_test_flag(channel, CF_BRIDGED) || switch_channel_test_flag(channel, CF_BROADCAST)) {
566 inner++;
567 hold_bleg = NULL((void*)0);
568 }
569
570 if (!switch_channel_test_flag(channel, CF_BROADCAST)) {
571 switch_channel_set_flag(channel, CF_BROADCAST)switch_channel_set_flag_value(channel, CF_BROADCAST, 1);
572 if (inner) {
573 inner--;
574 }
575 }
576
577 if (hold_bleg && switch_true(hold_bleg)) {
578 if ((b_uuid = switch_channel_get_partner_uuid(channel))) {
579 const char *stream;
580 b_uuid = switch_core_session_strdup(session, b_uuid)switch_core_perform_session_strdup(session, b_uuid, "src/switch_ivr.c"
, (const char *)__func__, 580)
;
581
582 if (!(stream = switch_channel_get_hold_music_partner(channel))) {
583 stream = switch_channel_get_hold_music(channel);
584 }
585
586 if (stream && switch_is_moh(stream)) {
587 if ((b_session = switch_core_session_locate(b_uuid)switch_core_session_perform_locate(b_uuid, "src/switch_ivr.c"
, (const char *)__func__, 587)
)) {
588 switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
589 switch_status_t st;
590
591 switch_ivr_broadcast(b_uuid, stream, SMF_ECHO_ALEG | SMF_LOOP);
592 st = switch_channel_wait_for_flag(b_channel, CF_BROADCAST, SWITCH_TRUE, 5000, NULL((void*)0));
593 if (st != SWITCH_STATUS_SUCCESS &&
594 switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE) && switch_channel_ready(b_channel)switch_channel_test_ready(b_channel, SWITCH_TRUE, SWITCH_FALSE
)
&& !switch_channel_test_flag(b_channel, CF_BROADCAST)) {
595 switch_core_session_kill_channel(b_session, SWITCH_SIG_BREAK)switch_core_session_perform_kill_channel(b_session, "src/switch_ivr.c"
, (const char *)__func__, 595, SWITCH_SIG_BREAK)
;
596 st = switch_channel_wait_for_flag(b_channel, CF_BROADCAST, SWITCH_TRUE, 5000, NULL((void*)0));
597
598 if (st != SWITCH_STATUS_SUCCESS &&
599 switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE) && switch_channel_ready(b_channel)switch_channel_test_ready(b_channel, SWITCH_TRUE, SWITCH_FALSE
)
&& !switch_channel_test_flag(b_channel, CF_BROADCAST)) {
600 switch_core_session_flush_private_events(b_session);
601 }
602 }
603 switch_core_session_rwunlock(b_session);
604 }
605 } else {
606 b_uuid = NULL((void*)0);
607 }
608 }
609 }
610
611 for (x = 0; x < loops || loops < 0; x++) {
612 switch_time_t b4, aftr;
613
614 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 614, (const char*)(session)
, SWITCH_LOG_DEBUG, "%s Command Execute %s(%s)\n",
615 switch_channel_get_name(channel), app_name, switch_str_nil(app_arg)(app_arg ? app_arg : ""));
616 b4 = switch_micro_time_now();
617
618 if (event_uuid) {
619 switch_channel_set_variable(channel, "app_uuid", event_uuid)switch_channel_set_variable_var_check(channel, "app_uuid", event_uuid
, SWITCH_TRUE)
;
620 }
621
622 switch_channel_set_variable_printf(channel, "current_loop", "%d", x + 1);
623 switch_channel_set_variable_printf(channel, "total_loops", "%d", loops);
624
625 if (switch_core_session_execute_application(session, app_name, app_arg)switch_core_session_execute_application_get_flags(session, app_name
, app_arg, ((void*)0))
!= SWITCH_STATUS_SUCCESS) {
626 if (!inner || switch_channel_test_flag(channel, CF_STOP_BROADCAST)) switch_channel_clear_flag(channel, CF_BROADCAST);
627 break;
628 }
629
630 aftr = switch_micro_time_now();
631 if (!switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE) || switch_channel_test_flag(channel, CF_STOP_BROADCAST) || aftr - b4 < 500000) {
632 break;
633 }
634 }
635
636 switch_channel_set_variable(channel, "current_loop", NULL)switch_channel_set_variable_var_check(channel, "current_loop"
, ((void*)0), SWITCH_TRUE)
;
637 switch_channel_set_variable(channel, "total_loops", NULL)switch_channel_set_variable_var_check(channel, "total_loops",
((void*)0), SWITCH_TRUE)
;
638
639 if (b_uuid) {
640 if ((b_session = switch_core_session_locate(b_uuid)switch_core_session_perform_locate(b_uuid, "src/switch_ivr.c"
, (const char *)__func__, 640)
)) {
641 switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
642 switch_channel_stop_broadcast(b_channel)for(;;) {if (switch_channel_test_flag(b_channel, CF_BROADCAST
)) {switch_channel_set_flag_value(b_channel, CF_STOP_BROADCAST
, 1); switch_channel_set_flag_value(b_channel, CF_BREAK, 1); }
break;}
;
643 switch_channel_wait_for_flag(b_channel, CF_BROADCAST, SWITCH_FALSE, 5000, NULL((void*)0));
644 switch_core_session_rwunlock(b_session);
645 }
646 }
647
648 if (!inner) {
649 switch_channel_clear_flag(channel, CF_BROADCAST);
650 }
651
652 if (switch_channel_test_flag(channel, CF_STOP_BROADCAST)) {
653 switch_channel_clear_flag(channel, CF_BROADCAST);
654 switch_channel_set_flag(channel, CF_BREAK)switch_channel_set_flag_value(channel, CF_BREAK, 1);
655 }
656
657 switch_channel_audio_sync(channel)switch_channel_perform_audio_sync(channel, "src/switch_ivr.c"
, (const char *)__func__, 657)
;
658 }
659 } else if (cmd_hash == CMD_UNICAST) {
660 char *local_ip = switch_event_get_header(event, "local-ip")switch_event_get_header_idx(event, "local-ip", -1);
661 char *local_port = switch_event_get_header(event, "local-port")switch_event_get_header_idx(event, "local-port", -1);
662 char *remote_ip = switch_event_get_header(event, "remote-ip")switch_event_get_header_idx(event, "remote-ip", -1);
663 char *remote_port = switch_event_get_header(event, "remote-port")switch_event_get_header_idx(event, "remote-port", -1);
664 char *transport = switch_event_get_header(event, "transport")switch_event_get_header_idx(event, "transport", -1);
665 char *flags = switch_event_get_header(event, "flags")switch_event_get_header_idx(event, "flags", -1);
666
667 if (zstr(local_ip)_zstr(local_ip)) {
668 local_ip = "127.0.0.1";
669 }
670 if (zstr(remote_ip)_zstr(remote_ip)) {
671 remote_ip = "127.0.0.1";
672 }
673 if (zstr(local_port)_zstr(local_port)) {
674 local_port = "8025";
675 }
676 if (zstr(remote_port)_zstr(remote_port)) {
677 remote_port = "8026";
678 }
679 if (zstr(transport)_zstr(transport)) {
680 transport = "udp";
681 }
682
683 switch_ivr_activate_unicast(session, local_ip, (switch_port_t) atoi(local_port), remote_ip, (switch_port_t) atoi(remote_port), transport, flags);
684
685 } else if (cmd_hash == CMD_XFEREXT) {
686 switch_event_header_t *hp;
687 switch_caller_extension_t *extension = NULL((void*)0);
688
689
690 if ((extension = switch_caller_extension_new(session, "xferext", "xferext")) == 0) {
691 abort();
692 }
693
694 for (hp = event->headers; hp; hp = hp->next) {
695 char *app;
696 char *data;
697
698 if (!strcasecmp(hp->name, "application")) {
699 app = strdup(hp->value)(__extension__ (__builtin_constant_p (hp->value) &&
((size_t)(const void *)((hp->value) + 1) - (size_t)(const
void *)(hp->value) == 1) ? (((const char *) (hp->value
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen (hp->value) + 1; char *__retval = (
char *) malloc (__len); if (__retval != ((void*)0)) __retval =
(char *) memcpy (__retval, hp->value, __len); __retval; }
)) : __strdup (hp->value)))
;
700 if (app) {
701 data = strchr(app, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p
(app) && (' ') == '\0' ? (char *) __rawmemchr (app, ' '
) : __builtin_strchr (app, ' ')))
;
702
703 if (data) {
704 *data++ = '\0';
705 }
706
707 switch_caller_extension_add_application(session, extension, app, data);
708 free(app);
709 }
710 }
711 }
712
713 switch_channel_transfer_to_extension(channel, extension);
714
715 } else if (cmd_hash == CMD_HANGUP) {
716 char *cause_name = switch_event_get_header(event, "hangup-cause")switch_event_get_header_idx(event, "hangup-cause", -1);
717 switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;
718
719 if (cause_name) {
720 cause = switch_channel_str2cause(cause_name);
721 }
722
723 switch_channel_hangup(channel, cause)switch_channel_perform_hangup(channel, "src/switch_ivr.c", (const
char *)__func__, 723, cause)
;
724 } else if (cmd_hash == CMD_NOMEDIA) {
725 char *uuid = switch_event_get_header(event, "nomedia-uuid")switch_event_get_header_idx(event, "nomedia-uuid", -1);
726 switch_ivr_nomedia(uuid, SMF_REBRIDGE);
727 }
728
729 status = SWITCH_STATUS_SUCCESS;
730
731 done:
732
733 switch_channel_clear_flag_recursive(channel, CF_EVENT_PARSE);
734
735 if (el) {
736 switch_channel_clear_flag_recursive(channel, CF_EVENT_LOCK);
737 }
738
739 if (elp) {
740 switch_channel_clear_flag_recursive(channel, CF_EVENT_LOCK_PRI);
741 }
742
743 return switch_channel_test_flag(channel, CF_BREAK) ? SWITCH_STATUS_BREAK : status;
744}
745
746SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_parse_next_event(switch_core_session_t *session)
747{
748 switch_event_t *event;
749 switch_status_t status = SWITCH_STATUS_FALSE;
750
751 if (switch_core_session_dequeue_private_event(session, &event) == SWITCH_STATUS_SUCCESS) {
752 status = switch_ivr_parse_event(session, event);
753 event->event_id = SWITCH_EVENT_PRIVATE_COMMAND;
754 switch_event_prep_for_delivery(event)switch_event_prep_for_delivery_detailed("src/switch_ivr.c", (
const char * )(const char *)__func__, 754, event)
;
755 switch_channel_event_set_data(switch_core_session_get_channel(session), event);
756 switch_event_fire(&event)switch_event_fire_detailed("src/switch_ivr.c", (const char * )
(const char *)__func__, 756, &event, ((void*)0))
;
757 }
758
759 return status;
760
761}
762
763SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_process_indications(switch_core_session_t *session, switch_core_session_message_t *message)
764{
765 switch_status_t status = SWITCH_STATUS_SUCCESS;
766 switch_channel_t *channel = switch_core_session_get_channel(session);
767
768 switch(message->message_id) {
769 case SWITCH_MESSAGE_INDICATE_ANSWER:
770 if (switch_channel_answer(channel)switch_channel_perform_answer(channel, "src/switch_ivr.c", (const
char *)__func__, 770)
!= SWITCH_STATUS_SUCCESS) {
771 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "src/switch_ivr.c", (const
char *)__func__, 771, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
772 }
773 break;
774 case SWITCH_MESSAGE_INDICATE_PROGRESS:
775 if (switch_channel_pre_answer(channel)switch_channel_perform_pre_answer(channel, "src/switch_ivr.c"
, (const char *)__func__, 775)
!= SWITCH_STATUS_SUCCESS) {
776 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "src/switch_ivr.c", (const
char *)__func__, 776, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
777 }
778 break;
779 case SWITCH_MESSAGE_INDICATE_RINGING:
780 if (switch_channel_ring_ready(channel)switch_channel_perform_ring_ready_value(channel, SWITCH_RING_READY_RINGING
, "src/switch_ivr.c", (const char *)__func__, 780)
!= SWITCH_STATUS_SUCCESS) {
781 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "src/switch_ivr.c", (const
char *)__func__, 781, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
782 }
783 break;
784 default:
785 status = SWITCH_STATUS_FALSE;
786 break;
787 }
788
789 return status;
790}
791
792SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_parse_all_messages(switch_core_session_t *session)
793{
794 switch_core_session_message_t *message;
795 int i = 0;
796
797 switch_ivr_parse_all_signal_data(session);
798
799 while (switch_core_session_dequeue_message(session, &message) == SWITCH_STATUS_SUCCESS) {
800 i++;
801
802 if (switch_ivr_process_indications(session, message) == SWITCH_STATUS_SUCCESS) {
803 switch_core_session_free_message(&message);
804 } else {
805 switch_core_session_receive_message(session, message)switch_core_session_perform_receive_message(session, message,
"src/switch_ivr.c", (const char *)__func__, 805)
;
806 message = NULL((void*)0);
807 }
808 }
809
810 return i ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
811}
812
813
814SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_parse_all_signal_data(switch_core_session_t *session)
815{
816 void *data;
817 switch_core_session_message_t msg = { 0 };
818 int i = 0;
819 switch_channel_t *channel = switch_core_session_get_channel(session);
820
821 if (!switch_core_session_in_thread(session)) {
822 return SWITCH_STATUS_FALSE;
823 }
824
825 if (switch_channel_test_flag(channel, CF_SIGNAL_DATA)) {
826 return SWITCH_STATUS_FALSE;
827 }
828
829 switch_channel_set_flag(channel, CF_SIGNAL_DATA)switch_channel_set_flag_value(channel, CF_SIGNAL_DATA, 1);
830
831 msg.message_id = SWITCH_MESSAGE_INDICATE_SIGNAL_DATA;
832 msg.from = __FILE__"src/switch_ivr.c";
833
834 while (switch_core_session_dequeue_signal_data(session, &data) == SWITCH_STATUS_SUCCESS) {
835 i++;
836
837 msg.pointer_arg = data;
838 switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg
, "src/switch_ivr.c", (const char *)__func__, 838)
;
839
840 data = NULL((void*)0);
841
842 }
843
844 switch_channel_clear_flag(channel, CF_SIGNAL_DATA);
845
846 return i ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
847}
848
849SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_parse_all_events(switch_core_session_t *session)
850{
851 int x = 0;
852 switch_channel_t *channel;
853
854 switch_ivr_parse_all_messages(session);
855
856 channel = switch_core_session_get_channel(session);
857
858 if (!switch_channel_test_flag(channel, CF_PROXY_MODE) && switch_channel_test_flag(channel, CF_BLOCK_BROADCAST_UNTIL_MEDIA)) {
859 if (switch_channel_media_up(channel)(switch_channel_test_flag(channel, CF_ANSWERED) || switch_channel_test_flag
(channel, CF_EARLY_MEDIA))
) {
860 switch_channel_clear_flag(channel, CF_BLOCK_BROADCAST_UNTIL_MEDIA);
861 } else {
862 return SWITCH_STATUS_SUCCESS;
863 }
864 }
865
866 while (switch_ivr_parse_next_event(session) == SWITCH_STATUS_SUCCESS) {
867 x++;
868 }
869
870 return SWITCH_STATUS_SUCCESS;
871}
872
873
874SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_park(switch_core_session_t *session, switch_input_args_t *args)
875{
876 switch_status_t status = SWITCH_STATUS_SUCCESS;
877 switch_channel_t *channel = switch_core_session_get_channel(session);
878 switch_frame_t *read_frame = NULL((void*)0);
879 int stream_id = 0;
880 switch_event_t *event;
881 switch_unicast_conninfo_t *conninfo = NULL((void*)0);
882 uint32_t rate = 0;
883 uint32_t bpf = 0;
884 const char *to;
885 int timeout = 0;
886 time_t expires = 0;
887 switch_codec_implementation_t read_impl = { 0 };
888 switch_call_cause_t timeout_cause = SWITCH_CAUSE_NORMAL_CLEARING;
889 switch_codec_t codec = { 0 };
890 int sval = 0;
891 const char *var;
892 switch_frame_t write_frame = { 0 };
893 unsigned char *abuf = NULL((void*)0);
894 switch_codec_implementation_t imp = { 0 };
895
896
897
898 if (switch_channel_test_flag(channel, CF_RECOVERED) && switch_channel_test_flag(channel, CF_CONTROLLED)) {
899 switch_channel_clear_flag(channel, CF_CONTROLLED);
900 }
901
902 if (switch_channel_test_flag(channel, CF_CONTROLLED)) {
903 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 903, (const char*)(session)
, SWITCH_LOG_ERROR, "Cannot park channels that are under control already.\n");
904 return SWITCH_STATUS_FALSE;
905 }
906
907 if (switch_channel_get_state(channel) == CS_RESET) {
908 return SWITCH_STATUS_FALSE;
909 }
910
911 arg_recursion_check_start(args)if (args) { if (args->loops >= 25) { switch_log_printf(
SWITCH_CHANNEL_ID_LOG, "src/switch_ivr.c", (const char *)__func__
, 911, ((void*)0), SWITCH_LOG_ERROR, "RECURSION ERROR! It's not the best idea to call things that collect input recursively from an input callback.\n"
); return SWITCH_STATUS_GENERR; } else {args->loops++;} }
;
912
913 if ((to = switch_channel_get_variable(channel, "park_timeout")switch_channel_get_variable_dup(channel, "park_timeout", SWITCH_TRUE
, -1)
)) {
914 char *cause_str;
915
916 if ((cause_str = strchr(to, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(to) && (':') == '\0' ? (char *) __rawmemchr (to, ':'
) : __builtin_strchr (to, ':')))
)) {
917 timeout_cause = switch_channel_str2cause(cause_str + 1);
918 }
919
920 if ((timeout = atoi(to)) < 0) {
921 timeout = 0;
922 } else {
923 expires = switch_epoch_time_now(NULL((void*)0)) + timeout;
924 }
925 switch_channel_set_variable(channel, "park_timeout", NULL)switch_channel_set_variable_var_check(channel, "park_timeout"
, ((void*)0), SWITCH_TRUE)
;
926 switch_channel_set_variable(channel, SWITCH_PARK_AFTER_BRIDGE_VARIABLE, NULL)switch_channel_set_variable_var_check(channel, "park_after_bridge"
, ((void*)0), SWITCH_TRUE)
;
927 }
928
929 switch_channel_set_flag(channel, CF_CONTROLLED)switch_channel_set_flag_value(channel, CF_CONTROLLED, 1);
930 switch_channel_set_flag(channel, CF_PARK)switch_channel_set_flag_value(channel, CF_PARK, 1);
931
932 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_PARK)switch_event_create_subclass_detailed("src/switch_ivr.c", (const
char * )(const char *)__func__, 932, &event, SWITCH_EVENT_CHANNEL_PARK
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
933 switch_channel_event_set_data(channel, event);
934 switch_event_fire(&event)switch_event_fire_detailed("src/switch_ivr.c", (const char * )
(const char *)__func__, 934, &event, ((void*)0))
;
935 }
936
937 while (switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE) && switch_channel_test_flag(channel, CF_CONTROLLED) && switch_channel_test_flag(channel, CF_PARK)) {
938
939 if (!rate && switch_channel_media_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_TRUE)) {
940 switch_core_session_get_read_impl(session, &read_impl);
941 rate = read_impl.actual_samples_per_second;
942 bpf = read_impl.decoded_bytes_per_packet;
943
944 if ((var = switch_channel_get_variable(channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE)switch_channel_get_variable_dup(channel, "send_silence_when_idle"
, SWITCH_TRUE, -1)
) && (sval = atoi(var))) {
945 switch_core_session_get_read_impl(session, &imp);
946
947 if (switch_core_codec_init(&codec,switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.actual_samples_per_second, imp.microseconds_per_packet
/ 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE |
SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
948 "L16",switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.actual_samples_per_second, imp.microseconds_per_packet
/ 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE |
SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
949 NULL,switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.actual_samples_per_second, imp.microseconds_per_packet
/ 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE |
SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
950 imp.actual_samples_per_second,switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.actual_samples_per_second, imp.microseconds_per_packet
/ 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE |
SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
951 imp.microseconds_per_packet / 1000,switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.actual_samples_per_second, imp.microseconds_per_packet
/ 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE |
SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
952 imp.number_of_channels,switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.actual_samples_per_second, imp.microseconds_per_packet
/ 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE |
SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
953 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.actual_samples_per_second, imp.microseconds_per_packet
/ 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE |
SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
954 switch_core_session_get_pool(session))switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.actual_samples_per_second, imp.microseconds_per_packet
/ 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE |
SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
!= SWITCH_STATUS_SUCCESS) {
955 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 955, (const char*)(session)
, SWITCH_LOG_ERROR, "Codec Error L16@%uhz %u channels %dms\n",
956 imp.samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000);
957 switch_goto_status(SWITCH_STATUS_FALSE, end)status = SWITCH_STATUS_FALSE; goto end;
958 }
959
960
961 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 961, (const char*)(session)
, SWITCH_LOG_DEBUG, "Codec Activated L16@%uhz %u channels %dms\n",
962 imp.samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000);
963
964 write_frame.codec = &codec;
965 switch_zmalloc(abuf, SWITCH_RECOMMENDED_BUFFER_SIZE)(void)((((abuf = calloc(1, (8192)))) ? (void) (0) : __assert_fail
("(abuf = calloc(1, (8192)))", "src/switch_ivr.c", 965, __PRETTY_FUNCTION__
)),abuf)
;
966 write_frame.data = abuf;
967 write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE8192;
968 write_frame.datalen = imp.decoded_bytes_per_packet;
969 write_frame.samples = write_frame.datalen / sizeof(int16_t);
970 }
971 }
972
973 if (rate) {
974 if (switch_channel_test_flag(channel, CF_SERVICE)) {
975 switch_cond_next();
976 status = SWITCH_STATUS_SUCCESS;
977 } else {
978 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, stream_id);
979 }
980 } else {
981 switch_yield(20000)switch_sleep(20000);;
982
983 if (switch_core_session_dequeue_private_event(session, &event) == SWITCH_STATUS_SUCCESS) {
984 switch_ivr_parse_event(session, event);
985 switch_event_destroy(&event);
986 }
987
988 status = SWITCH_STATUS_SUCCESS;
989 }
990
991 if (!SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK
|| status == SWITCH_STATUS_INUSE)
) {
992 break;
993 }
994
995 if (rate && write_frame.data && sval) {
996 switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.samples, read_impl.number_of_channels, sval);
997 switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
998 }
999
1000 if (expires && switch_epoch_time_now(NULL((void*)0)) >= expires) {
1001 switch_channel_hangup(channel, timeout_cause)switch_channel_perform_hangup(channel, "src/switch_ivr.c", (const
char *)__func__, 1001, timeout_cause)
;
1002 break;
1003 }
1004
1005 if (switch_channel_test_flag(channel, CF_UNICAST)) {
1006 if (!switch_channel_media_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_TRUE)) {
1007 if (switch_channel_pre_answer(channel)switch_channel_perform_pre_answer(channel, "src/switch_ivr.c"
, (const char *)__func__, 1007)
!= SWITCH_STATUS_SUCCESS) {
1008 switch_goto_status(SWITCH_STATUS_FALSE, end)status = SWITCH_STATUS_FALSE; goto end;
1009 }
1010 }
1011
1012 if (!conninfo) {
1013 if (!(conninfo = switch_channel_get_private(channel, "unicast"))) {
1014 switch_channel_clear_flag(channel, CF_UNICAST);
1015 }
1016
1017 if (conninfo) {
1018 unicast_thread_launch(conninfo);
1019 }
1020 }
1021
1022 if (conninfo) {
1023 switch_size_t len = 0;
1024 uint32_t flags = 0;
1025 switch_byte_t decoded[SWITCH_RECOMMENDED_BUFFER_SIZE8192];
1026 uint32_t dlen = sizeof(decoded);
1027 switch_status_t tstatus;
1028 switch_byte_t *sendbuf = NULL((void*)0);
1029 uint32_t sendlen = 0;
1030
1031 switch_assert(read_frame)((read_frame) ? (void) (0) : __assert_fail ("read_frame", "src/switch_ivr.c"
, 1031, __PRETTY_FUNCTION__))
;
1032
1033 if (switch_test_flag(read_frame, SFF_CNG)((read_frame)->flags & SFF_CNG)) {
1034 sendlen = bpf;
1035 switch_assert(sendlen <= SWITCH_RECOMMENDED_BUFFER_SIZE)((sendlen <= 8192) ? (void) (0) : __assert_fail ("sendlen <= 8192"
, "src/switch_ivr.c", 1035, __PRETTY_FUNCTION__))
;
1036 memset(decoded, 255, sendlen);
1037 sendbuf = decoded;
1038 tstatus = SWITCH_STATUS_SUCCESS;
1039 } else {
1040 if (switch_test_flag(conninfo, SUF_NATIVE)((conninfo)->flags & SUF_NATIVE)) {
1041 tstatus = SWITCH_STATUS_NOOP;
1042 } else {
1043 switch_codec_t *read_codec = switch_core_session_get_read_codec(session);
1044 tstatus = switch_core_codec_decode(read_codec,
1045 &conninfo->read_codec,
1046 read_frame->data,
1047 read_frame->datalen, read_impl.actual_samples_per_second, decoded, &dlen, &rate, &flags);
1048 }
1049 switch (tstatus) {
1050 case SWITCH_STATUS_NOOP:
1051 case SWITCH_STATUS_BREAK:
1052 sendbuf = read_frame->data;
1053 sendlen = read_frame->datalen;
1054 tstatus = SWITCH_STATUS_SUCCESS;
1055 break;
1056 case SWITCH_STATUS_SUCCESS:
1057 sendbuf = decoded;
1058 sendlen = dlen;
1059 tstatus = SWITCH_STATUS_SUCCESS;
1060 break;
1061 default:
1062 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 1062, (const char*)(session)
, SWITCH_LOG_NOTICE, "Codec Error\n");
1063 switch_ivr_deactivate_unicast(session);
1064 break;
1065 }
1066 }
1067
1068 if (tstatus == SWITCH_STATUS_SUCCESS) {
1069 len = sendlen;
1070 if (switch_socket_sendto(conninfo->socket, conninfo->remote_addr, 0, (void *) sendbuf, &len) != SWITCH_STATUS_SUCCESS) {
1071 switch_ivr_deactivate_unicast(session);
1072 }
1073 }
1074 }
1075 }
1076
1077 switch_ivr_parse_all_events(session);
1078
1079
1080 if (switch_channel_has_dtmf(channel)) {
1081 switch_dtmf_t dtmf = { 0 };
1082
1083 if (args && !args->input_callback && !args->buf && !args->dmachine) {
1084 status = SWITCH_STATUS_BREAK;
1085 break;
1086 }
1087
1088 switch_channel_dequeue_dtmf(channel, &dtmf);
1089
1090 if (args) {
1091 if (args->dmachine) {
1092 char ds[2] = {dtmf.digit, '\0'};
1093 if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL((void*)0))) != SWITCH_STATUS_SUCCESS) {
1094 break;
1095 }
1096 }
1097
1098 if (args->input_callback) {
1099 if ((status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen)) != SWITCH_STATUS_SUCCESS) {
1100 break;
1101 }
1102 }
1103 }
1104 }
1105
1106 if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
1107 if (args && args->input_callback) {
1108 switch_status_t ostatus;
1109
1110 if ((ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen)) != SWITCH_STATUS_SUCCESS) {
1111 status = ostatus;
1112 break;
1113 }
1114 } else {
1115 switch_channel_event_set_data(channel, event);
1116 switch_event_fire(&event)switch_event_fire_detailed("src/switch_ivr.c", (const char * )
(const char *)__func__, 1116, &event, ((void*)0))
;
1117 }
1118 }
1119
1120 if (args && args->dmachine) {
1121 if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL((void*)0))) != SWITCH_STATUS_SUCCESS) {
1122 break;
1123 }
1124 }
1125
1126
1127 }
1128
1129 end:
1130
1131 arg_recursion_check_stop(args)if (args) args->loops--;
1132
1133 if (write_frame.codec) {
1134 switch_core_codec_destroy(&codec);
1135 }
1136
1137 switch_safe_free(abuf)if (abuf) {free(abuf);abuf=((void*)0);};
1138
1139 switch_channel_clear_flag(channel, CF_CONTROLLED);
1140 switch_channel_clear_flag(channel, CF_PARK);
1141
1142 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_UNPARK)switch_event_create_subclass_detailed("src/switch_ivr.c", (const
char * )(const char *)__func__, 1142, &event, SWITCH_EVENT_CHANNEL_UNPARK
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1143 switch_channel_event_set_data(channel, event);
1144 switch_event_fire(&event)switch_event_fire_detailed("src/switch_ivr.c", (const char * )
(const char *)__func__, 1144, &event, ((void*)0))
;
1145 }
1146
1147 if (switch_channel_test_flag(channel, CF_UNICAST)) {
1148 switch_ivr_deactivate_unicast(session);
1149 }
1150
1151 return status;
1152}
1153
1154SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_collect_digits_callback(switch_core_session_t *session, switch_input_args_t *args, uint32_t digit_timeout,
1155 uint32_t abs_timeout)
1156{
1157 switch_channel_t *channel = switch_core_session_get_channel(session);
1158 switch_status_t status = SWITCH_STATUS_SUCCESS;
1159 switch_time_t abs_started = 0, digit_started = 0;
1160 uint32_t abs_elapsed = 0, digit_elapsed = 0;
1161
1162 if (!args) {
1163 return SWITCH_STATUS_GENERR;
1164 }
1165
1166 arg_recursion_check_start(args)if (args) { if (args->loops >= 25) { switch_log_printf(
SWITCH_CHANNEL_ID_LOG, "src/switch_ivr.c", (const char *)__func__
, 1166, ((void*)0), SWITCH_LOG_ERROR, "RECURSION ERROR! It's not the best idea to call things that collect input recursively from an input callback.\n"
); return SWITCH_STATUS_GENERR; } else {args->loops++;} }
;
1167
1168 if (abs_timeout) {
1169 abs_started = switch_micro_time_now();
1170 }
1171 if (digit_timeout) {
1172 digit_started = switch_micro_time_now();
1173 }
1174
1175 while (switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE)) {
1176 switch_frame_t *read_frame = NULL((void*)0);
1177 switch_event_t *event;
1178 switch_dtmf_t dtmf = { 0 };
1179
1180 if (switch_channel_test_flag(channel, CF_BREAK)) {
1181 switch_channel_clear_flag(channel, CF_BREAK);
1182 status = SWITCH_STATUS_BREAK;
1183 break;
1184 }
1185
1186 if (abs_timeout) {
1187 abs_elapsed = (uint32_t) ((switch_micro_time_now() - abs_started) / 1000);
1188 if (abs_elapsed >= abs_timeout) {
1189 status = SWITCH_STATUS_TIMEOUT;
1190 break;
1191 }
1192 }
1193 if (digit_timeout) {
1194 digit_elapsed = (uint32_t) ((switch_micro_time_now() - digit_started) / 1000);
1195 if (digit_elapsed >= digit_timeout) {
1196 status = SWITCH_STATUS_TIMEOUT;
1197 break;
1198 }
1199 }
1200
1201
1202 switch_ivr_parse_all_events(session);
1203
1204
1205 if (switch_channel_has_dtmf(channel)) {
1206 if (!args->input_callback && !args->buf && !args->dmachine) {
1207 status = SWITCH_STATUS_BREAK;
1208 break;
1209 }
1210 switch_channel_dequeue_dtmf(channel, &dtmf);
1211
1212 if (args->dmachine) {
1213 char ds[2] = {dtmf.digit, '\0'};
1214 if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL((void*)0))) != SWITCH_STATUS_SUCCESS) {
1215 break;
1216 }
1217 }
1218
1219 if (args->input_callback) {
1220 status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
1221 }
1222
1223 if (digit_timeout) {
1224 digit_started = switch_micro_time_now();
1225 }
1226 }
1227
1228 if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
1229 switch_status_t ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen);
1230 if (ostatus != SWITCH_STATUS_SUCCESS) {
1231 status = ostatus;
1232 }
1233 switch_event_destroy(&event);
1234 }
1235
1236 if (status != SWITCH_STATUS_SUCCESS) {
1237 break;
1238 }
1239
1240 if (switch_channel_test_flag(channel, CF_SERVICE)) {
1241 switch_cond_next();
1242 } else {
1243 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
1244 }
1245
1246 if (!SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK
|| status == SWITCH_STATUS_INUSE)
) {
1247 break;
1248 }
1249
1250 if (args && args->dmachine) {
1251 if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL((void*)0))) != SWITCH_STATUS_SUCCESS) {
1252 break;
1253 }
1254 }
1255
1256 if (read_frame && args && (args->read_frame_callback)) {
1257 if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
1258 break;
1259 }
1260 }
1261 }
1262
1263 arg_recursion_check_stop(args)if (args) args->loops--;
1264
1265 return status;
1266}
1267
1268SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_collect_digits_count(switch_core_session_t *session,
1269 char *buf,
1270 switch_size_t buflen,
1271 switch_size_t maxdigits,
1272 const char *terminators, char *terminator,
1273 uint32_t first_timeout, uint32_t digit_timeout, uint32_t abs_timeout)
1274{
1275 switch_size_t i = 0, x = strlen(buf);
1276 switch_channel_t *channel = switch_core_session_get_channel(session);
1277 switch_status_t status = SWITCH_STATUS_FALSE;
1278 switch_time_t started = 0, digit_started = 0;
1279 uint32_t abs_elapsed = 0, digit_elapsed = 0;
1280 uint32_t eff_timeout = 0;
1281 switch_frame_t write_frame = { 0 };
1282 unsigned char *abuf = NULL((void*)0);
1283 switch_codec_implementation_t imp = { 0 };
1284 switch_codec_t codec = { 0 };
1285 int sval = 0;
1286 const char *var;
1287
1288 if ((var = switch_channel_get_variable(channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE)switch_channel_get_variable_dup(channel, "send_silence_when_idle"
, SWITCH_TRUE, -1)
) && (sval = atoi(var))) {
1289 switch_core_session_get_read_impl(session, &imp);
1290
1291 if (switch_core_codec_init(&codec,switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.samples_per_second, imp.microseconds_per_packet / 1000
, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
1292 "L16",switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.samples_per_second, imp.microseconds_per_packet / 1000
, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
1293 NULL,switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.samples_per_second, imp.microseconds_per_packet / 1000
, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
1294 imp.samples_per_second,switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.samples_per_second, imp.microseconds_per_packet / 1000
, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
1295 imp.microseconds_per_packet / 1000,switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.samples_per_second, imp.microseconds_per_packet / 1000
, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
1296 imp.number_of_channels,switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.samples_per_second, imp.microseconds_per_packet / 1000
, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
1297 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.samples_per_second, imp.microseconds_per_packet / 1000
, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
1298 switch_core_session_get_pool(session))switch_core_codec_init_with_bitrate(&codec, "L16", ((void
*)0), imp.samples_per_second, imp.microseconds_per_packet / 1000
, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
!= SWITCH_STATUS_SUCCESS) {
1299 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 1299, (const char*)(session)
, SWITCH_LOG_ERROR, "Codec Error L16@%uhz %u channels %dms\n",
1300 imp.samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000);
1301 return SWITCH_STATUS_FALSE;
1302 }
1303
1304
1305 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 1305, (const char*)(session)
, SWITCH_LOG_DEBUG, "Codec Activated L16@%uhz %u channels %dms\n",
1306 imp.samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000);
1307
1308 write_frame.codec = &codec;
1309 switch_zmalloc(abuf, SWITCH_RECOMMENDED_BUFFER_SIZE)(void)((((abuf = calloc(1, (8192)))) ? (void) (0) : __assert_fail
("(abuf = calloc(1, (8192)))", "src/switch_ivr.c", 1309, __PRETTY_FUNCTION__
)),abuf)
;
1310 write_frame.data = abuf;
1311 write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE8192;
1312 write_frame.datalen = imp.decoded_bytes_per_packet;
1313 write_frame.samples = write_frame.datalen / sizeof(int16_t);
1314 }
1315
1316 if (terminator != NULL((void*)0)) {
1317 *terminator = '\0';
1318 }
1319
1320 if (!zstr(terminators)_zstr(terminators)) {
1321 for (i = 0; i < x; i++) {
1322 if (strchr(terminators, buf[i])(__extension__ (__builtin_constant_p (buf[i]) && !__builtin_constant_p
(terminators) && (buf[i]) == '\0' ? (char *) __rawmemchr
(terminators, buf[i]) : __builtin_strchr (terminators, buf[i
])))
&& terminator != NULL((void*)0)) {
1323 *terminator = buf[i];
1324 buf[i] = '\0';
1325 switch_safe_free(abuf)if (abuf) {free(abuf);abuf=((void*)0);};
1326 return SWITCH_STATUS_SUCCESS;
1327 }
1328 }
1329 }
1330
1331 if (abs_timeout) {
1332 started = switch_micro_time_now();
1333 }
1334
1335 if (digit_timeout && first_timeout) {
1336 eff_timeout = first_timeout;
1337 } else if (digit_timeout && !first_timeout) {
1338 first_timeout = eff_timeout = digit_timeout;
1339 } else if (first_timeout) {
1340 digit_timeout = eff_timeout = first_timeout;
1341 }
1342
1343
1344 if (eff_timeout) {
1345 digit_started = switch_micro_time_now();
1346 }
1347
1348 while (switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE)) {
1349 switch_frame_t *read_frame;
1350
1351 if (abs_timeout) {
1352 abs_elapsed = (uint32_t) ((switch_micro_time_now() - started) / 1000);
1353 if (abs_elapsed >= abs_timeout) {
1354 status = SWITCH_STATUS_TIMEOUT;
1355 break;
1356 }
1357 }
1358
1359
1360 switch_ivr_parse_all_events(session);
1361
1362
1363
1364 if (eff_timeout) {
1365 digit_elapsed = (uint32_t) ((switch_micro_time_now() - digit_started) / 1000);
1366
1367 if (digit_elapsed >= eff_timeout) {
1368 status = SWITCH_STATUS_TIMEOUT;
1369 break;
1370 }
1371 }
1372
1373 if (switch_channel_has_dtmf(channel)) {
1374 switch_dtmf_t dtmf = { 0 };
1375 switch_size_t y;
1376
1377 if (eff_timeout) {
1378 eff_timeout = digit_timeout;
1379 digit_started = switch_micro_time_now();
1380 }
1381
1382 for (y = 0; y <= maxdigits; y++) {
1383 if (switch_channel_dequeue_dtmf(channel, &dtmf) != SWITCH_STATUS_SUCCESS) {
1384 break;
1385 }
1386
1387 if (!zstr(terminators)_zstr(terminators) && strchr(terminators, dtmf.digit)(__extension__ (__builtin_constant_p (dtmf.digit) && !
__builtin_constant_p (terminators) && (dtmf.digit) ==
'\0' ? (char *) __rawmemchr (terminators, dtmf.digit) : __builtin_strchr
(terminators, dtmf.digit)))
&& terminator != NULL((void*)0)) {
1388 *terminator = dtmf.digit;
1389 switch_safe_free(abuf)if (abuf) {free(abuf);abuf=((void*)0);};
1390 return SWITCH_STATUS_SUCCESS;
1391 }
1392
1393
1394 buf[x++] = dtmf.digit;
1395 buf[x] = '\0';
1396
1397 if (x >= buflen || x >= maxdigits) {
1398 switch_safe_free(abuf)if (abuf) {free(abuf);abuf=((void*)0);};
1399 return SWITCH_STATUS_SUCCESS;
1400 }
1401 }
1402 }
1403
1404 if (switch_channel_test_flag(channel, CF_SERVICE)) {
1405 switch_cond_next();
1406 } else {
1407 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
1408 if (!SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK
|| status == SWITCH_STATUS_INUSE)
) {
1409 break;
1410 }
1411
1412 if (write_frame.data) {
1413 switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.samples, imp.number_of_channels, sval);
1414 switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
1415 }
1416
1417 }
1418 }
1419
1420 if (write_frame.codec) {
1421 switch_core_codec_destroy(&codec);
1422 }
1423
1424 switch_safe_free(abuf)if (abuf) {free(abuf);abuf=((void*)0);};
1425
1426 return status;
1427}
1428
1429SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_hold(switch_core_session_t *session, const char *message, switch_bool_t moh)
1430{
1431 switch_core_session_message_t msg = { 0 };
1432 switch_channel_t *channel = switch_core_session_get_channel(session);
1433 const char *stream;
1434 const char *other_uuid;
1435 switch_event_t *event;
1436
1437 msg.message_id = SWITCH_MESSAGE_INDICATE_HOLD;
1438 msg.string_arg = message;
1439 msg.from = __FILE__"src/switch_ivr.c";
1440
1441 switch_channel_set_flag(channel, CF_HOLD)switch_channel_set_flag_value(channel, CF_HOLD, 1);
1442 switch_channel_set_flag(channel, CF_SUSPEND)switch_channel_set_flag_value(channel, CF_SUSPEND, 1);
1443
1444 switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg
, "src/switch_ivr.c", (const char *)__func__, 1444)
;
1445
1446 if (moh && (stream = switch_channel_get_hold_music(channel))) {
1447 if ((other_uuid = switch_channel_get_partner_uuid(channel))) {
1448 switch_ivr_broadcast(other_uuid, stream, SMF_ECHO_ALEG | SMF_LOOP);
1449 }
1450 }
1451
1452 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_HOLD)switch_event_create_subclass_detailed("src/switch_ivr.c", (const
char * )(const char *)__func__, 1452, &event, SWITCH_EVENT_CHANNEL_HOLD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1453 switch_channel_event_set_data(channel, event);
1454 switch_event_fire(&event)switch_event_fire_detailed("src/switch_ivr.c", (const char * )
(const char *)__func__, 1454, &event, ((void*)0))
;
1455 }
1456
1457
1458 return SWITCH_STATUS_SUCCESS;
1459}
1460
1461SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_hold_uuid(const char *uuid, const char *message, switch_bool_t moh)
1462{
1463 switch_core_session_t *session;
1464
1465 if ((session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "src/switch_ivr.c", (
const char *)__func__, 1465)
)) {
1466 switch_ivr_hold(session, message, moh);
1467 switch_core_session_rwunlock(session);
1468 }
1469
1470 return SWITCH_STATUS_SUCCESS;
1471}
1472
1473SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_hold_toggle_uuid(const char *uuid, const char *message, switch_bool_t moh)
1474{
1475 switch_core_session_t *session;
1476 switch_channel_t *channel;
1477 switch_channel_callstate_t callstate;
1478
1479 if ((session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "src/switch_ivr.c", (
const char *)__func__, 1479)
)) {
1480 if ((channel = switch_core_session_get_channel(session))) {
1481 callstate = switch_channel_get_callstate(channel);
1482
1483 if (callstate == CCS_ACTIVE) {
1484 switch_ivr_hold(session, message, moh);
1485 } else if (callstate == CCS_HELD) {
1486 switch_ivr_unhold(session);
1487 }
1488 }
1489 switch_core_session_rwunlock(session);
1490 }
1491
1492 return SWITCH_STATUS_SUCCESS;
1493}
1494
1495SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_unhold(switch_core_session_t *session)
1496{
1497 switch_core_session_message_t msg = { 0 };
1498 switch_channel_t *channel = switch_core_session_get_channel(session);
1499 const char *other_uuid;
1500 switch_core_session_t *b_session;
1501 switch_event_t *event;
1502
1503 msg.message_id = SWITCH_MESSAGE_INDICATE_UNHOLD;
1504 msg.from = __FILE__"src/switch_ivr.c";
1505
1506 switch_channel_clear_flag(channel, CF_HOLD);
1507 switch_channel_clear_flag(channel, CF_SUSPEND);
1508
1509 switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg
, "src/switch_ivr.c", (const char *)__func__, 1509)
;
1510
1511
1512 if ((other_uuid = switch_channel_get_partner_uuid(channel)) && (b_session = switch_core_session_locate(other_uuid)switch_core_session_perform_locate(other_uuid, "src/switch_ivr.c"
, (const char *)__func__, 1512)
)) {
1513 switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
1514 switch_channel_stop_broadcast(b_channel)for(;;) {if (switch_channel_test_flag(b_channel, CF_BROADCAST
)) {switch_channel_set_flag_value(b_channel, CF_STOP_BROADCAST
, 1); switch_channel_set_flag_value(b_channel, CF_BREAK, 1); }
break;}
;
1515 switch_channel_wait_for_flag(b_channel, CF_BROADCAST, SWITCH_FALSE, 5000, NULL((void*)0));
1516 switch_core_session_rwunlock(b_session);
1517 }
1518
1519
1520 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_UNHOLD)switch_event_create_subclass_detailed("src/switch_ivr.c", (const
char * )(const char *)__func__, 1520, &event, SWITCH_EVENT_CHANNEL_UNHOLD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1521 switch_channel_event_set_data(channel, event);
1522 switch_event_fire(&event)switch_event_fire_detailed("src/switch_ivr.c", (const char * )
(const char *)__func__, 1522, &event, ((void*)0))
;
1523 }
1524
1525 return SWITCH_STATUS_SUCCESS;
1526}
1527
1528SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_unhold_uuid(const char *uuid)
1529{
1530 switch_core_session_t *session;
1531
1532 if ((session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "src/switch_ivr.c", (
const char *)__func__, 1532)
)) {
1533 switch_ivr_unhold(session);
1534 switch_core_session_rwunlock(session);
1535 }
1536
1537 return SWITCH_STATUS_SUCCESS;
1538}
1539
1540SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_media(const char *uuid, switch_media_flag_t flags)
1541{
1542 const char *other_uuid = NULL((void*)0);
1543 switch_channel_t *channel, *other_channel = NULL((void*)0);
1544 switch_core_session_t *session, *other_session;
1545 switch_core_session_message_t msg = { 0 };
1546 switch_status_t status = SWITCH_STATUS_GENERR;
1547 uint8_t swap = 0;
1548 switch_frame_t *read_frame = NULL((void*)0);
1549
1550 msg.message_id = SWITCH_MESSAGE_INDICATE_MEDIA;
1551 msg.from = __FILE__"src/switch_ivr.c";
1552
1553 if ((session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "src/switch_ivr.c", (
const char *)__func__, 1553)
)) {
1554 channel = switch_core_session_get_channel(session);
1555
1556 if (switch_channel_test_flag(channel, CF_MEDIA_TRANS)) {
1557 switch_core_session_rwunlock(session);
1558 return SWITCH_STATUS_INUSE;
1559 }
1560
1561 switch_channel_set_flag(channel, CF_MEDIA_TRANS)switch_channel_set_flag_value(channel, CF_MEDIA_TRANS, 1);
1562
1563 if ((flags & SMF_REBRIDGE) && !switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) {
1564 swap = 1;
1565 }
1566
1567 if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
1568 status = SWITCH_STATUS_SUCCESS;
1569
1570 /* If we had early media in bypass mode before, it is no longer relevant */
1571 if (switch_channel_test_flag(channel, CF_EARLY_MEDIA)) {
1572 switch_core_session_message_t msg2 = { 0 };
1573
1574 msg2.message_id = SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS;
1575 msg2.from = __FILE__"src/switch_ivr.c";
1576 switch_core_session_receive_message(session, &msg2)switch_core_session_perform_receive_message(session, &msg2
, "src/switch_ivr.c", (const char *)__func__, 1576)
;
1577 }
1578
1579 if ((flags & SMF_REPLYONLY_A)) {
1580 msg.numeric_arg = 1;
1581 }
1582
1583 if (switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg
, "src/switch_ivr.c", (const char *)__func__, 1583)
!= SWITCH_STATUS_SUCCESS) {
1584 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 1584, (const char*)(session)
, SWITCH_LOG_ERROR, "Can't re-establsh media on %s\n", switch_channel_get_name(channel));
1585 switch_core_session_rwunlock(session);
1586 return SWITCH_STATUS_GENERR;
1587 }
1588
1589 if ((flags & SMF_REPLYONLY_B)) {
1590 msg.numeric_arg = 1;
1591 } else {
1592 msg.numeric_arg = 0;
1593 }
1594
1595 if ((flags & SMF_IMMEDIATE)) {
1596 switch_channel_wait_for_flag(channel, CF_REQ_MEDIA, SWITCH_FALSE, 250, NULL((void*)0));
1597 switch_yield(250000)switch_sleep(250000);;
1598 } else {
1599 switch_channel_wait_for_flag(channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL((void*)0));
1600 switch_channel_wait_for_flag(channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL((void*)0));
1601 switch_channel_wait_for_flag(channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL((void*)0));
1602 switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
1603 }
1604
1605 if ((flags & SMF_REBRIDGE)
1606 && (other_uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE)switch_channel_get_variable_dup(channel, "signal_bridge_to", SWITCH_TRUE
, -1)
)
1607 && (other_session = switch_core_session_locate(other_uuid)switch_core_session_perform_locate(other_uuid, "src/switch_ivr.c"
, (const char *)__func__, 1607)
)) {
1608 other_channel = switch_core_session_get_channel(other_session);
1609 switch_assert(other_channel != NULL)((other_channel != ((void*)0)) ? (void) (0) : __assert_fail (
"other_channel != ((void*)0)", "src/switch_ivr.c", 1609, __PRETTY_FUNCTION__
))
;
1610 switch_core_session_receive_message(other_session, &msg)switch_core_session_perform_receive_message(other_session, &
msg, "src/switch_ivr.c", (const char *)__func__, 1610)
;
1611 switch_channel_wait_for_flag(other_channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL((void*)0));
1612 switch_channel_wait_for_flag(other_channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL((void*)0));
1613 switch_channel_wait_for_flag(other_channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL((void*)0));
1614 switch_core_session_read_frame(other_session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
1615 switch_channel_clear_state_handler(other_channel, NULL((void*)0));
1616 switch_core_session_rwunlock(other_session);
1617 }
1618 if (other_channel) {
1619 switch_channel_clear_state_handler(channel, NULL((void*)0));
1620 }
1621 }
1622
1623 switch_channel_clear_flag(channel, CF_MEDIA_TRANS);
1624 switch_core_session_rwunlock(session);
1625
1626 if (other_channel) {
1627 if (swap) {
1628 switch_ivr_uuid_bridge(other_uuid, uuid);
1629 } else {
1630 switch_ivr_uuid_bridge(uuid, other_uuid);
1631 }
1632 switch_channel_wait_for_flag(channel, CF_BRIDGED, SWITCH_TRUE, 1000, NULL((void*)0));
1633 switch_channel_wait_for_flag(other_channel, CF_BRIDGED, SWITCH_TRUE, 1000, NULL((void*)0));
1634 }
1635 }
1636
1637 return status;
1638}
1639
1640SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_nomedia(const char *uuid, switch_media_flag_t flags)
1641{
1642 const char *other_uuid;
1643 switch_channel_t *channel, *other_channel = NULL((void*)0);
1644 switch_core_session_t *session, *other_session = NULL((void*)0);
1645 switch_core_session_message_t msg = { 0 };
1646 switch_status_t status = SWITCH_STATUS_GENERR;
1647 uint8_t swap = 0;
1648
1649 msg.message_id = SWITCH_MESSAGE_INDICATE_NOMEDIA;
1650 msg.from = __FILE__"src/switch_ivr.c";
1651
1652 if ((session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "src/switch_ivr.c", (
const char *)__func__, 1652)
)) {
1653 status = SWITCH_STATUS_SUCCESS;
1654 channel = switch_core_session_get_channel(session);
1655
1656 if (switch_channel_test_flag(channel, CF_MEDIA_TRANS)) {
1657 switch_core_session_rwunlock(session);
1658 return SWITCH_STATUS_INUSE;
1659 }
1660
1661 switch_channel_set_flag(channel, CF_MEDIA_TRANS)switch_channel_set_flag_value(channel, CF_MEDIA_TRANS, 1);
1662
1663 if ((flags & SMF_REBRIDGE) && !switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) {
1664 swap = 1;
1665 }
1666
1667 switch_channel_set_flag(channel, CF_REDIRECT)switch_channel_set_flag_value(channel, CF_REDIRECT, 1);
1668 switch_channel_set_flag(channel, CF_RESET)switch_channel_set_flag_value(channel, CF_RESET, 1);
1669
1670 if ((flags & SMF_FORCE) || !switch_channel_test_flag(channel, CF_PROXY_MODE)) {
1671 if ((flags & SMF_REBRIDGE) && (other_uuid = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE)switch_channel_get_variable_dup(channel, "bridge_to", SWITCH_TRUE
, -1)
) &&
1672 (other_session = switch_core_session_locate(other_uuid)switch_core_session_perform_locate(other_uuid, "src/switch_ivr.c"
, (const char *)__func__, 1672)
)) {
1673 other_channel = switch_core_session_get_channel(other_session);
1674
1675 switch_channel_set_flag(other_channel, CF_RESET)switch_channel_set_flag_value(other_channel, CF_RESET, 1);
1676 switch_channel_set_flag(other_channel, CF_REDIRECT)switch_channel_set_flag_value(other_channel, CF_REDIRECT, 1);
1677
1678 if (!switch_core_session_in_thread(session)) {
1679 switch_channel_set_state(channel, CS_PARK)switch_channel_perform_set_state(channel, "src/switch_ivr.c",
(const char *)__func__, 1679, CS_PARK)
;
1680 }
1681 switch_channel_set_state(other_channel, CS_PARK)switch_channel_perform_set_state(other_channel, "src/switch_ivr.c"
, (const char *)__func__, 1681, CS_PARK)
;
1682 if (switch_core_session_in_thread(session)) {
1683 switch_yield(100000)switch_sleep(100000);;
1684 } else {
1685 switch_channel_wait_for_state(other_channel, channel, CS_PARK);
1686 }
1687 switch_core_session_receive_message(other_session, &msg)switch_core_session_perform_receive_message(other_session, &
msg, "src/switch_ivr.c", (const char *)__func__, 1687)
;
1688 switch_channel_wait_for_flag(other_channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL((void*)0));
1689 //switch_channel_wait_for_flag(other_channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL);
1690 switch_channel_wait_for_flag(other_channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL((void*)0));
1691 }
1692
1693 switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg
, "src/switch_ivr.c", (const char *)__func__, 1693)
;
1694
1695 if (other_channel) {
1696 if (!switch_core_session_in_thread(session)) {
1697 switch_channel_wait_for_state(channel, NULL((void*)0), CS_PARK);
1698 switch_channel_wait_for_flag(channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL((void*)0));
1699 switch_channel_wait_for_flag(channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL((void*)0));
1700 switch_channel_wait_for_flag(channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL((void*)0));
1701 }
1702
1703 if (swap) {
1704 switch_ivr_signal_bridge(other_session, session);
1705 } else {
1706 switch_ivr_signal_bridge(session, other_session);
1707 }
1708
1709 if (switch_core_session_in_thread(session)) {
1710 switch_yield(100000)switch_sleep(100000);;
1711 } else {
1712 switch_channel_wait_for_state(other_channel, channel, CS_HIBERNATE);
1713 }
1714
1715 if (!switch_core_session_in_thread(session)) {
1716 switch_channel_wait_for_state(channel, other_channel, CS_HIBERNATE);
1717 }
1718 switch_core_session_rwunlock(other_session);
1719 }
1720 }
1721
1722 switch_channel_clear_flag(channel, CF_MEDIA_TRANS);
1723 switch_core_session_rwunlock(session);
1724 }
1725
1726
1727
1728 return status;
1729}
1730
1731SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_session_transfer(switch_core_session_t *session, const char *extension, const char *dialplan,
1732 const char *context)
1733{
1734 switch_channel_t *channel = switch_core_session_get_channel(session);
1735 switch_caller_profile_t *profile, *new_profile;
1736 switch_core_session_message_t msg = { 0 };
1737 switch_core_session_t *other_session;
1738 switch_channel_t *other_channel = NULL((void*)0);
1739 const char *uuid = NULL((void*)0);
1740 const char *max_forwards;
1741 const char *forwardvar = switch_channel_get_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE)switch_channel_get_variable_dup(channel, "max_forwards", SWITCH_TRUE
, -1)
;
1742 int forwardval = 70;
1743 const char *use_dialplan = dialplan, *use_context = context;
1744
1745 if (!zstr(forwardvar)_zstr(forwardvar)) {
1746 forwardval = atoi(forwardvar) - 1;
1747 }
1748 if (forwardval <= 0) {
1749 switch_channel_hangup(channel, SWITCH_CAUSE_EXCHANGE_ROUTING_ERROR)switch_channel_perform_hangup(channel, "src/switch_ivr.c", (const
char *)__func__, 1749, SWITCH_CAUSE_EXCHANGE_ROUTING_ERROR)
;
1750 return SWITCH_STATUS_FALSE;
1751 }
1752
1753 max_forwards = switch_core_session_sprintf(session, "%d", forwardval);
1754 switch_channel_set_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE, max_forwards)switch_channel_set_variable_var_check(channel, "max_forwards"
, max_forwards, SWITCH_TRUE)
;
1755
1756 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
1757 switch_channel_clear_flag(channel, CF_ORIGINATING);
1758
1759 /* clear all state handlers */
1760 switch_channel_clear_state_handler(channel, NULL((void*)0));
1761
1762 /* reset temp hold music */
1763 switch_channel_set_variable(channel, SWITCH_TEMP_HOLD_MUSIC_VARIABLE, NULL)switch_channel_set_variable_var_check(channel, "temp_hold_music"
, ((void*)0), SWITCH_TRUE)
;
1764
1765 if ((profile = switch_channel_get_caller_profile(channel))) {
1766 const char *var;
1767
1768 if (zstr(dialplan)_zstr(dialplan) && (var = switch_channel_get_variable(channel, "force_transfer_dialplan")switch_channel_get_variable_dup(channel, "force_transfer_dialplan"
, SWITCH_TRUE, -1)
)) {
1769 use_dialplan = var;
1770 }
1771
1772 if (zstr(context)_zstr(context) && (var = switch_channel_get_variable(channel, "force_transfer_context")switch_channel_get_variable_dup(channel, "force_transfer_context"
, SWITCH_TRUE, -1)
)) {
1773 use_context = var;
1774 }
1775
1776 if (zstr(use_dialplan)_zstr(use_dialplan)) {
1777 use_dialplan = profile->dialplan;
1778 if (!zstr(use_dialplan)_zstr(use_dialplan) && !strcasecmp(use_dialplan, "inline")) {
1779 use_dialplan = NULL((void*)0);
1780 }
1781 }
1782
1783 if (zstr(use_context)_zstr(use_context)) {
1784 use_context = profile->context;
1785 }
1786
1787 if (zstr(use_dialplan)_zstr(use_dialplan)) {
1788 use_dialplan = "XML";
1789 }
1790
1791 if (zstr(use_context)_zstr(use_context)) {
1792 use_context = "default";
1793 }
1794
1795 if (zstr(extension)_zstr(extension)) {
1796 extension = "service";
1797 }
1798
1799 new_profile = switch_caller_profile_clone(session, profile);
1800
1801 new_profile->dialplan = switch_core_strdup(new_profile->pool, use_dialplan)switch_core_perform_strdup(new_profile->pool, use_dialplan
, "src/switch_ivr.c", (const char *)__func__, 1801)
;
1802 new_profile->context = switch_core_strdup(new_profile->pool, use_context)switch_core_perform_strdup(new_profile->pool, use_context,
"src/switch_ivr.c", (const char *)__func__, 1802)
;
1803 new_profile->destination_number = switch_core_strdup(new_profile->pool, extension)switch_core_perform_strdup(new_profile->pool, extension, "src/switch_ivr.c"
, (const char *)__func__, 1803)
;
1804 new_profile->rdnis = switch_core_strdup(new_profile->pool, profile->destination_number)switch_core_perform_strdup(new_profile->pool, profile->
destination_number, "src/switch_ivr.c", (const char *)__func__
, 1804)
;
1805
1806 switch_channel_set_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE, NULL)switch_channel_set_variable_var_check(channel, "signal_bond",
((void*)0), SWITCH_TRUE)
;
1807
1808 /* Set CF_TRANSFER flag before hanging up bleg to avoid race condition */
1809 switch_channel_set_flag(channel, CF_TRANSFER)switch_channel_set_flag_value(channel, CF_TRANSFER, 1);
1810
1811 /* If HANGUP_AFTER_BRIDGE is set to 'true', SWITCH_SIGNAL_BRIDGE_VARIABLE
1812 * will not have a value, so we need to check SWITCH_BRIDGE_VARIABLE */
1813
1814 uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE)switch_channel_get_variable_dup(channel, "signal_bridge_to", SWITCH_TRUE
, -1)
;
1815
1816 if (!uuid) {
1817 uuid = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE)switch_channel_get_variable_dup(channel, "bridge_to", SWITCH_TRUE
, -1)
;
1818 }
1819
1820 if (uuid && (other_session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "src/switch_ivr.c", (
const char *)__func__, 1820)
)) {
1821 other_channel = switch_core_session_get_channel(other_session);
1822 switch_channel_set_variable(other_channel, SWITCH_SIGNAL_BOND_VARIABLE, NULL)switch_channel_set_variable_var_check(other_channel, "signal_bond"
, ((void*)0), SWITCH_TRUE)
;
1823 switch_core_session_rwunlock(other_session);
1824 }
1825
1826 if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE)switch_channel_get_variable_dup(channel, "signal_bridge_to", SWITCH_TRUE
, -1)
)
1827 && (other_session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "src/switch_ivr.c", (
const char *)__func__, 1827)
)) {
1828 other_channel = switch_core_session_get_channel(other_session);
1829
1830 switch_channel_set_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE, NULL)switch_channel_set_variable_var_check(channel, "signal_bridge_to"
, ((void*)0), SWITCH_TRUE)
;
1831 switch_channel_set_variable(other_channel, SWITCH_SIGNAL_BRIDGE_VARIABLE, NULL)switch_channel_set_variable_var_check(other_channel, "signal_bridge_to"
, ((void*)0), SWITCH_TRUE)
;
1832
1833 switch_channel_set_variable(channel, SWITCH_BRIDGE_VARIABLE, NULL)switch_channel_set_variable_var_check(channel, "bridge_to", (
(void*)0), SWITCH_TRUE)
;
1834 switch_channel_set_variable(other_channel, SWITCH_BRIDGE_VARIABLE, NULL)switch_channel_set_variable_var_check(other_channel, "bridge_to"
, ((void*)0), SWITCH_TRUE)
;
1835
1836 /* If we are transferring the CALLER out of the bridge, we do not want to hang up on them */
1837 switch_channel_set_variable(channel, SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE, "false")switch_channel_set_variable_var_check(channel, "hangup_after_bridge"
, "false", SWITCH_TRUE)
;
1838
1839 switch_channel_hangup(other_channel, SWITCH_CAUSE_BLIND_TRANSFER)switch_channel_perform_hangup(other_channel, "src/switch_ivr.c"
, (const char *)__func__, 1839, SWITCH_CAUSE_BLIND_TRANSFER)
;
1840 switch_ivr_media(uuid, SMF_NONE);
1841
1842 switch_core_session_rwunlock(other_session);
1843 }
1844
1845 switch_channel_set_caller_profile(channel, new_profile);
1846
1847 switch_channel_set_state(channel, CS_ROUTING)switch_channel_perform_set_state(channel, "src/switch_ivr.c",
(const char *)__func__, 1847, CS_ROUTING)
;
1848 switch_channel_audio_sync(channel)switch_channel_perform_audio_sync(channel, "src/switch_ivr.c"
, (const char *)__func__, 1848)
;
1849
1850 msg.message_id = SWITCH_MESSAGE_INDICATE_TRANSFER;
1851 msg.from = __FILE__"src/switch_ivr.c";
1852 switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg
, "src/switch_ivr.c", (const char *)__func__, 1852)
;
1853
1854 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 1854, (const char*)(session)
, SWITCH_LOG_NOTICE, "Transfer %s to %s[%s@%s]\n", switch_channel_get_name(channel), use_dialplan,
1855 extension, use_context);
1856
1857
1858 new_profile->transfer_source = switch_core_sprintf(new_profile->pool, "%ld:%s:bl_xfer:%s/%s/%s",
1859 (long) switch_epoch_time_now(NULL((void*)0)), new_profile->uuid_str,
1860 extension, use_context, use_dialplan);
1861 switch_channel_add_variable_var_check(channel, SWITCH_TRANSFER_HISTORY_VARIABLE"transfer_history", new_profile->transfer_source, SWITCH_FALSE, SWITCH_STACK_PUSH);
1862 switch_channel_set_variable_var_check(channel, SWITCH_TRANSFER_SOURCE_VARIABLE"transfer_source", new_profile->transfer_source, SWITCH_FALSE);
1863 return SWITCH_STATUS_SUCCESS;
1864 }
1865
1866 return SWITCH_STATUS_FALSE;
1867}
1868
1869SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_transfer_variable(switch_core_session_t *sessa, switch_core_session_t *sessb, char *var)
1870{
1871 switch_channel_t *chana = switch_core_session_get_channel(sessa);
1872 switch_channel_t *chanb = switch_core_session_get_channel(sessb);
1873 switch_event_t *var_event;
1874
1875 const char *val = NULL((void*)0);
1876 uint8_t prefix = 0;
1877
1878 if (var && *var == '~') {
1879 var++;
1880 prefix = 1;
1881 }
1882
1883 if (var && !prefix) {
1884 if ((val = switch_channel_get_variable(chana, var)switch_channel_get_variable_dup(chana, var, SWITCH_TRUE, -1))) {
1885 switch_channel_set_variable(chanb, var, val)switch_channel_set_variable_var_check(chanb, var, val, SWITCH_TRUE
)
;
1886 }
1887 } else {
1888 switch_event_header_t *hi;
1889
1890 switch_channel_get_variables(chana, &var_event);
1891
1892 for (hi = var_event->headers; hi; hi = hi->next) {
1893 char *vvar = hi->name;
1894 char *vval = hi->value;
1895 if (vvar && vval && (!prefix || (var && !strncmp((char *) vvar, var, strlen(var))(__extension__ (__builtin_constant_p (strlen(var)) &&
((__builtin_constant_p ((char *) vvar) && strlen ((char
*) vvar) < ((size_t) (strlen(var)))) || (__builtin_constant_p
(var) && strlen (var) < ((size_t) (strlen(var))))
) ? __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
((char *) vvar) && __builtin_constant_p (var) &&
(__s1_len = __builtin_strlen ((char *) vvar), __s2_len = __builtin_strlen
(var), (!((size_t)(const void *)(((char *) vvar) + 1) - (size_t
)(const void *)((char *) vvar) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)((var) + 1) - (size_t)(const void *
)(var) == 1) || __s2_len >= 4)) ? __builtin_strcmp ((char *
) vvar, var) : (__builtin_constant_p ((char *) vvar) &&
((size_t)(const void *)(((char *) vvar) + 1) - (size_t)(const
void *)((char *) vvar) == 1) && (__s1_len = __builtin_strlen
((char *) vvar), __s1_len < 4) ? (__builtin_constant_p (var
) && ((size_t)(const void *)((var) + 1) - (size_t)(const
void *)(var) == 1) ? __builtin_strcmp ((char *) vvar, var) :
(__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (var); int __result = (((const unsigned
char *) (const char *) ((char *) vvar))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) ((char *) vvar))[1] - __s2[1]); if (__s1_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) ((char *) vvar))[2] - __s2[2]); if (__s1_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) ((char *) vvar))[3] - __s2[3]); } } __result
; }))) : (__builtin_constant_p (var) && ((size_t)(const
void *)((var) + 1) - (size_t)(const void *)(var) == 1) &&
(__s2_len = __builtin_strlen (var), __s2_len < 4) ? (__builtin_constant_p
((char *) vvar) && ((size_t)(const void *)(((char *)
vvar) + 1) - (size_t)(const void *)((char *) vvar) == 1) ? __builtin_strcmp
((char *) vvar, var) : (- (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) ((char *) vvar
); int __result = (((const unsigned char *) (const char *) (var
))[0] - __s2[0]); if (__s2_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) (var)
)[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (var)
)[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (var))[
3] - __s2[3]); } } __result; })))) : __builtin_strcmp ((char *
) vvar, var)))); }) : strncmp ((char *) vvar, var, strlen(var
))))
))) {
1896 switch_channel_set_variable(chanb, (char *) vvar, (char *) vval)switch_channel_set_variable_var_check(chanb, (char *) vvar, (
char *) vval, SWITCH_TRUE)
;
1897 }
1898 }
1899
1900 switch_event_destroy(&var_event);
1901 }
1902
1903 return SWITCH_STATUS_SUCCESS;
1904}
1905
1906/******************************************************************************************************/
1907
1908struct switch_ivr_digit_stream_parser {
1909 int pool_auto_created;
1910 switch_memory_pool_t *pool;
1911 switch_hash_t *hash;
1912 switch_size_t maxlen;
1913 switch_size_t buflen;
1914 switch_size_t minlen;
1915 char terminator;
1916 unsigned int digit_timeout_ms;
1917};
1918
1919struct switch_ivr_digit_stream {
1920 char *digits;
1921 switch_time_t last_digit_time;
1922};
1923
1924SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_digit_stream_parser_new(switch_memory_pool_t *pool, switch_ivr_digit_stream_parser_t ** parser)
1925{
1926 switch_status_t status = SWITCH_STATUS_FALSE;
1927
1928 if (parser != NULL((void*)0)) {
1929 int pool_auto_created = 0;
1930
1931 /* if the caller didn't provide a pool, make one */
1932 if (pool == NULL((void*)0)) {
1933 switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "src/switch_ivr.c"
, (const char *)__func__, 1933)
;
1934 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_ivr.c", (const char *)__func__
, 1934, ((void*)0)
, SWITCH_LOG_DEBUG, "created a memory pool\n");
1935 if (pool != NULL((void*)0)) {
1936 pool_auto_created = 1;
1937 }
1938 }
1939 /* if we have a pool, make a parser object */
1940 if (pool != NULL((void*)0)) {
1941 *parser = (switch_ivr_digit_stream_parser_t *) switch_core_alloc(pool, sizeof(switch_ivr_digit_stream_parser_t))switch_core_perform_alloc(pool, sizeof(switch_ivr_digit_stream_parser_t
), "src/switch_ivr.c", (const char *)__func__, 1941)
;
1942 }
1943 /* if we have parser object, initialize it for the caller */
1944 if (pool && *parser != NULL((void*)0)) {
1945 memset(*parser, 0, sizeof(switch_ivr_digit_stream_parser_t));
1946 (*parser)->pool_auto_created = pool_auto_created;
1947 (*parser)->pool = pool;
1948 (*parser)->digit_timeout_ms = 1000;
1949 switch_core_hash_init(&(*parser)->hash)switch_core_hash_init_case(&(*parser)->hash, SWITCH_TRUE
)
;
1950
1951 status = SWITCH_STATUS_SUCCESS;
1952 } else {
1953 status = SWITCH_STATUS_MEMERR;
1954 /* if we can't create a parser object,clean up the pool if we created it */
1955 if (pool != NULL((void*)0) && pool_auto_created) {
1956 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "src/switch_ivr.c"
, (const char *)__func__, 1956)
;
1957 }
1958 }
1959 }
1960
1961 return status;
1962}
1963
1964SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_digit_stream_parser_destroy(switch_ivr_digit_stream_parser_t *parser)
1965{
1966 switch_status_t status = SWITCH_STATUS_FALSE;
1967
1968 if (parser != NULL((void*)0)) {
1969 if (parser->hash != NULL((void*)0)) {
1970 switch_core_hash_destroy(&parser->hash);
1971 parser->hash = NULL((void*)0);
1972 }
1973 /* free the memory pool if we created it */
1974 if (parser->pool_auto_created && parser->pool != NULL((void*)0)) {
1975 status = switch_core_destroy_memory_pool(&parser->pool)switch_core_perform_destroy_memory_pool(&parser->pool,
"src/switch_ivr.c", (const char *)__func__, 1975)
;
1976 }
1977 }
1978
1979 return status;
1980}
1981
1982SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_digit_stream_new(switch_ivr_digit_stream_parser_t *parser, switch_ivr_digit_stream_t ** stream)
1983{
1984 switch_status_t status = SWITCH_STATUS_FALSE;
1985
1986 /* if we have a parser object memory pool and a stream object pointer that is null */
1987 if (parser && stream && *stream == NULL((void*)0)) {
1988 *stream = (switch_ivr_digit_stream_t *) malloc(sizeof(**stream));
1989 switch_assert(*stream)((*stream) ? (void) (0) : __assert_fail ("*stream", "src/switch_ivr.c"
, 1989, __PRETTY_FUNCTION__))
;
1990 memset(*stream, 0, sizeof(**stream));
1991 switch_zmalloc((*stream)->digits, parser->buflen + 1)(void)(((((*stream)->digits = calloc(1, (parser->buflen
+ 1)))) ? (void) (0) : __assert_fail ("((*stream)->digits = calloc(1, (parser->buflen + 1)))"
, "src/switch_ivr.c", 1991, __PRETTY_FUNCTION__)),(*stream)->
digits)
;
1992 status = SWITCH_STATUS_SUCCESS;
1993 }
1994
1995 return status;
1996}
1997
1998SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_digit_stream_destroy(switch_ivr_digit_stream_t ** stream)
1999{
2000 switch_status_t status = SWITCH_STATUS_FALSE;
2001
2002 if (*stream) {
2003 switch_safe_free((*stream)->digits)if ((*stream)->digits) {free((*stream)->digits);(*stream
)->digits=((void*)0);}
;
2004 free(*stream);
2005 *stream = NULL((void*)0);
2006 status = SWITCH_STATUS_SUCCESS;
2007 }
2008
2009 return status;
2010}
2011
2012SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_digit_stream_parser_set_event(switch_ivr_digit_stream_parser_t *parser, char *digits, void *data)
2013{
2014 switch_status_t status = SWITCH_STATUS_FALSE;
2015
2016 if (parser != NULL((void*)0) && digits != NULL((void*)0) && *digits && parser->hash != NULL((void*)0)) {
2017
2018 status = switch_core_hash_insert(parser->hash, digits, data)switch_core_hash_insert_destructor(parser->hash, digits, data
, ((void*)0))
;
2019 if (status == SWITCH_STATUS_SUCCESS) {
2020 switch_size_t len = strlen(digits);
2021
2022 /* if we don't have a terminator, then we have to try and
2023 * figure out when a digit set is completed, therefore we
2024 * keep track of the min and max digit lengths
2025 */
2026
2027 if (len > parser->buflen) {
2028 parser->buflen = len;
2029 }
2030
2031 if (parser->terminator == '\0') {
2032 if (len > parser->maxlen) {
2033 parser->maxlen = len;
2034 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_ivr.c", (const char *)__func__
, 2034, ((void*)0)
, SWITCH_LOG_DEBUG, "max len %u\n", (uint32_t) parser->maxlen);
2035 }
2036 if (parser->minlen == 0 || len < parser->minlen) {
2037 parser->minlen = len;
2038 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_ivr.c", (const char *)__func__
, 2038, ((void*)0)
, SWITCH_LOG_DEBUG, "min len %u\n", (uint32_t) parser->minlen);
2039 }
2040 } else {
2041 /* since we have a terminator, reset min and max */
2042 parser->minlen = 0;
2043 parser->maxlen = 0;
2044 }
2045 }
2046 }
2047 if (status != SWITCH_STATUS_SUCCESS) {
2048 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_ivr.c", (const char *)__func__
, 2048, ((void*)0)
, SWITCH_LOG_DEBUG, "unable to add hash for '%s'\n", digits);
2049 }
2050
2051 return status;
2052}
2053
2054SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_digit_stream_parser_del_event(switch_ivr_digit_stream_parser_t *parser, char *digits)
2055{
2056 switch_status_t status = SWITCH_STATUS_FALSE;
2057
2058 if (parser != NULL((void*)0) && digits != NULL((void*)0) && *digits) {
2059 status = switch_core_hash_delete(parser->hash, digits);
2060 }
2061
2062 if (status != SWITCH_STATUS_SUCCESS) {
2063 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_ivr.c", (const char *)__func__
, 2063, ((void*)0)
, SWITCH_LOG_DEBUG, "unable to del hash for '%s'\n", digits);
2064 }
2065
2066 return status;
2067}
2068
2069SWITCH_DECLARE(void *)__attribute__((visibility("default"))) void * switch_ivr_digit_stream_parser_feed(switch_ivr_digit_stream_parser_t *parser, switch_ivr_digit_stream_t *stream, char digit)
2070{
2071 void *result = NULL((void*)0);
2072 switch_size_t len;
2073
2074 switch_assert(parser)((parser) ? (void) (0) : __assert_fail ("parser", "src/switch_ivr.c"
, 2074, __PRETTY_FUNCTION__))
;
2075 switch_assert(stream)((stream) ? (void) (0) : __assert_fail ("stream", "src/switch_ivr.c"
, 2075, __PRETTY_FUNCTION__))
;
2076 switch_assert(stream->digits)((stream->digits) ? (void) (0) : __assert_fail ("stream->digits"
, "src/switch_ivr.c", 2076, __PRETTY_FUNCTION__))
;
2077
2078 len = strlen(stream->digits);
2079
2080 /* handle new digit arrivals */
2081 if (digit) {
2082 /* if it's not a terminator digit, add it to the collected digits */
2083 if (digit != parser->terminator) {
2084 /* if collected digits length >= the max length of the keys
2085 * in the hash table, then left shift the digit string
2086 */
2087 if (len > 0 && parser->maxlen != 0 && len >= parser->maxlen) {
2088 char *src = stream->digits + 1;
2089 char *dst = stream->digits;
2090
2091 while (*src) {
2092 *(dst++) = *(src++);
2093 }
2094 *dst = digit;
2095 } else {
2096 *(stream->digits + (len++)) = digit;
2097 *(stream->digits + len) = '\0';
2098 stream->last_digit_time = switch_micro_time_now() / 1000;
2099 }
2100 }
2101 }
2102
2103 /* don't allow collected digit string testing if there are varying sized keys until timeout */
2104 if (parser->maxlen - parser->minlen > 0 && (switch_micro_time_now() / 1000) - stream->last_digit_time < parser->digit_timeout_ms) {
2105 len = 0;
2106 }
2107 /* if we have digits to test */
2108 if (len) {
2109 result = switch_core_hash_find(parser->hash, stream->digits);
2110 /* if we matched the digit string, or this digit is the terminator
2111 * reset the collected digits for next digit string
2112 */
2113 if (result != NULL((void*)0) || parser->terminator == digit) {
2114 *stream->digits = '\0';
2115 }
2116 }
2117
2118
2119 return result;
2120}
2121
2122SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_digit_stream_reset(switch_ivr_digit_stream_t *stream)
2123{
2124 switch_status_t status = SWITCH_STATUS_FALSE;
2125 switch_assert(stream)((stream) ? (void) (0) : __assert_fail ("stream", "src/switch_ivr.c"
, 2125, __PRETTY_FUNCTION__))
;
2126 switch_assert(stream->digits)((stream->digits) ? (void) (0) : __assert_fail ("stream->digits"
, "src/switch_ivr.c", 2126, __PRETTY_FUNCTION__))
;
2127
2128 *stream->digits = '\0';
2129 stream->last_digit_time = 0;
2130 status = SWITCH_STATUS_SUCCESS;
2131
2132 return status;
2133}
2134
2135SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_digit_stream_parser_set_terminator(switch_ivr_digit_stream_parser_t *parser, char digit)
2136{
2137 switch_status_t status = SWITCH_STATUS_FALSE;
2138
2139 if (parser != NULL((void*)0)) {
2140 parser->terminator = digit;
2141 /* since we have a terminator, reset min and max */
2142 parser->minlen = 0;
2143 parser->maxlen = 0;
2144 status = SWITCH_STATUS_SUCCESS;
2145 }
2146
2147 return status;
2148}
2149
2150SWITCH_DECLARE(int)__attribute__((visibility("default"))) int switch_ivr_set_xml_profile_data(switch_xml_t xml, switch_caller_profile_t *caller_profile, int off)
2151{
2152 switch_xml_t param;
2153
2154 if (!(param = switch_xml_add_child_d(xml, "username", off++)switch_xml_set_flag(switch_xml_add_child(xml, (__extension__ (
__builtin_constant_p ("username") && ((size_t)(const void
*)(("username") + 1) - (size_t)(const void *)("username") ==
1) ? (((const char *) ("username"))[0] == '\0' ? (char *) calloc
((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("username"
) + 1; char *__retval = (char *) malloc (__len); if (__retval
!= ((void*)0)) __retval = (char *) memcpy (__retval, "username"
, __len); __retval; })) : __strdup ("username"))), off++), SWITCH_XML_NAMEM
)
)) {
1
Assuming 'param' is not null
2
Taking false branch
2155 return -1;
2156 }
2157 switch_xml_set_txt_d(param, caller_profile->username)switch_xml_set_flag(switch_xml_set_txt(param, (__extension__ (
__builtin_constant_p (caller_profile->username) &&
((size_t)(const void *)((caller_profile->username) + 1) -
(size_t)(const void *)(caller_profile->username) == 1) ? (
((const char *) (caller_profile->username))[0] == '\0' ? (
char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen
(caller_profile->username) + 1; char *__retval = (char *)
malloc (__len); if (__retval != ((void*)0)) __retval = (char
*) memcpy (__retval, caller_profile->username, __len); __retval
; })) : __strdup (caller_profile->username)))), SWITCH_XML_TXTM
)
;
2158
2159 if (!(param = switch_xml_add_child_d(xml, "dialplan", off++)switch_xml_set_flag(switch_xml_add_child(xml, (__extension__ (
__builtin_constant_p ("dialplan") && ((size_t)(const void
*)(("dialplan") + 1) - (size_t)(const void *)("dialplan") ==
1) ? (((const char *) ("dialplan"))[0] == '\0' ? (char *) calloc
((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("dialplan"
) + 1; char *__retval = (char *) malloc (__len); if (__retval
!= ((void*)0)) __retval = (char *) memcpy (__retval, "dialplan"
, __len); __retval; })) : __strdup ("dialplan"))), off++), SWITCH_XML_NAMEM
)
)) {
3
Assuming 'param' is not null
4
Taking false branch
2160 return -1;
2161 }
2162 switch_xml_set_txt_d(param, caller_profile->dialplan)switch_xml_set_flag(switch_xml_set_txt(param, (__extension__ (
__builtin_constant_p (caller_profile->dialplan) &&
((size_t)(const void *)((caller_profile->dialplan) + 1) -
(size_t)(const void *)(caller_profile->dialplan) == 1) ? (
((const char *) (caller_profile->dialplan))[0] == '\0' ? (
char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen
(caller_profile->dialplan) + 1; char *__retval = (char *)
malloc (__len); if (__retval != ((void*)0)) __retval = (char
*) memcpy (__retval, caller_profile->dialplan, __len); __retval
; })) : __strdup (caller_profile->dialplan)))), SWITCH_XML_TXTM
)
;
2163
2164 if (!(param = switch_xml_add_child_d(xml, "caller_id_name", off++)switch_xml_set_flag(switch_xml_add_child(xml, (__extension__ (
__builtin_constant_p ("caller_id_name") && ((size_t)(
const void *)(("caller_id_name") + 1) - (size_t)(const void *
)("caller_id_name") == 1) ? (((const char *) ("caller_id_name"
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen ("caller_id_name") + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, "caller_id_name", __len); __retval
; })) : __strdup ("caller_id_name"))), off++), SWITCH_XML_NAMEM
)
)) {
5
Assuming 'param' is not null
6
Taking false branch
2165 return -1;
2166 }
2167 switch_xml_set_txt_d(param, caller_profile->caller_id_name)switch_xml_set_flag(switch_xml_set_txt(param, (__extension__ (
__builtin_constant_p (caller_profile->caller_id_name) &&
((size_t)(const void *)((caller_profile->caller_id_name) +
1) - (size_t)(const void *)(caller_profile->caller_id_name
) == 1) ? (((const char *) (caller_profile->caller_id_name
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen (caller_profile->caller_id_name) + 1
; char *__retval = (char *) malloc (__len); if (__retval != (
(void*)0)) __retval = (char *) memcpy (__retval, caller_profile
->caller_id_name, __len); __retval; })) : __strdup (caller_profile
->caller_id_name)))), SWITCH_XML_TXTM)
;
2168
2169 if (!(param = switch_xml_add_child_d(xml, "caller_id_number", off++)switch_xml_set_flag(switch_xml_add_child(xml, (__extension__ (
__builtin_constant_p ("caller_id_number") && ((size_t
)(const void *)(("caller_id_number") + 1) - (size_t)(const void
*)("caller_id_number") == 1) ? (((const char *) ("caller_id_number"
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen ("caller_id_number") + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, "caller_id_number", __len); __retval
; })) : __strdup ("caller_id_number"))), off++), SWITCH_XML_NAMEM
)
)) {
7
Assuming 'param' is not null
8
Taking false branch
2170 return -1;
2171 }
2172 switch_xml_set_txt_d(param, caller_profile->caller_id_number)switch_xml_set_flag(switch_xml_set_txt(param, (__extension__ (
__builtin_constant_p (caller_profile->caller_id_number) &&
((size_t)(const void *)((caller_profile->caller_id_number
) + 1) - (size_t)(const void *)(caller_profile->caller_id_number
) == 1) ? (((const char *) (caller_profile->caller_id_number
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen (caller_profile->caller_id_number) +
1; char *__retval = (char *) malloc (__len); if (__retval !=
((void*)0)) __retval = (char *) memcpy (__retval, caller_profile
->caller_id_number, __len); __retval; })) : __strdup (caller_profile
->caller_id_number)))), SWITCH_XML_TXTM)
;
2173
2174 if (!(param = switch_xml_add_child_d(xml, "callee_id_name", off++)switch_xml_set_flag(switch_xml_add_child(xml, (__extension__ (
__builtin_constant_p ("callee_id_name") && ((size_t)(
const void *)(("callee_id_name") + 1) - (size_t)(const void *
)("callee_id_name") == 1) ? (((const char *) ("callee_id_name"
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen ("callee_id_name") + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, "callee_id_name", __len); __retval
; })) : __strdup ("callee_id_name"))), off++), SWITCH_XML_NAMEM
)
)) {
9
Within the expansion of the macro 'switch_xml_add_child_d':
a
Memory is allocated
b
Assuming '__retval' is not equal to null
c
Potential leak of memory pointed to by '__retval'
2175 return -1;
2176 }
2177 switch_xml_set_txt_d(param, caller_profile->callee_id_name)switch_xml_set_flag(switch_xml_set_txt(param, (__extension__ (
__builtin_constant_p (caller_profile->callee_id_name) &&
((size_t)(const void *)((caller_profile->callee_id_name) +
1) - (size_t)(const void *)(caller_profile->callee_id_name
) == 1) ? (((const char *) (caller_profile->callee_id_name
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen (caller_profile->callee_id_name) + 1
; char *__retval = (char *) malloc (__len); if (__retval != (
(void*)0)) __retval = (char *) memcpy (__retval, caller_profile
->callee_id_name, __len); __retval; })) : __strdup (caller_profile
->callee_id_name)))), SWITCH_XML_TXTM)
;
2178
2179 if (!(param = switch_xml_add_child_d(xml, "callee_id_number", off++)switch_xml_set_flag(switch_xml_add_child(xml, (__extension__ (
__builtin_constant_p ("callee_id_number") && ((size_t
)(const void *)(("callee_id_number") + 1) - (size_t)(const void
*)("callee_id_number") == 1) ? (((const char *) ("callee_id_number"
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen ("callee_id_number") + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, "callee_id_number", __len); __retval
; })) : __strdup ("callee_id_number"))), off++), SWITCH_XML_NAMEM
)
)) {
2180 return -1;
2181 }
2182 switch_xml_set_txt_d(param, caller_profile->callee_id_number)switch_xml_set_flag(switch_xml_set_txt(param, (__extension__ (
__builtin_constant_p (caller_profile->callee_id_number) &&
((size_t)(const void *)((caller_profile->callee_id_number
) + 1) - (size_t)(const void *)(caller_profile->callee_id_number
) == 1) ? (((const char *) (caller_profile->callee_id_number
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen (caller_profile->callee_id_number) +
1; char *__retval = (char *) malloc (__len); if (__retval !=
((void*)0)) __retval = (char *) memcpy (__retval, caller_profile
->callee_id_number, __len); __retval; })) : __strdup (caller_profile
->callee_id_number)))), SWITCH_XML_TXTM)
;
2183
2184 if (!(param = switch_xml_add_child_d(xml, "ani", off++)switch_xml_set_flag(switch_xml_add_child(xml, (__extension__ (
__builtin_constant_p ("ani") && ((size_t)(const void *
)(("ani") + 1) - (size_t)(const void *)("ani") == 1) ? (((const
char *) ("ani"))[0] == '\0' ? (char *) calloc ((size_t) 1, (
size_t) 1) : ({ size_t __len = strlen ("ani") + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, "ani", __len); __retval; })) : __strdup
("ani"))), off++), SWITCH_XML_NAMEM)
)) {
2185 return -1;
2186 }
2187 switch_xml_set_txt_d(param, caller_profile->ani)switch_xml_set_flag(switch_xml_set_txt(param, (__extension__ (
__builtin_constant_p (caller_profile->ani) && ((size_t
)(const void *)((caller_profile->ani) + 1) - (size_t)(const
void *)(caller_profile->ani) == 1) ? (((const char *) (caller_profile
->ani))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t)
1) : ({ size_t __len = strlen (caller_profile->ani) + 1; char
*__retval = (char *) malloc (__len); if (__retval != ((void*
)0)) __retval = (char *) memcpy (__retval, caller_profile->
ani, __len); __retval; })) : __strdup (caller_profile->ani
)))), SWITCH_XML_TXTM)
;
2188
2189 if (!(param = switch_xml_add_child_d(xml, "aniii", off++)switch_xml_set_flag(switch_xml_add_child(xml, (__extension__ (
__builtin_constant_p ("aniii") && ((size_t)(const void
*)(("aniii") + 1) - (size_t)(const void *)("aniii") == 1) ? (
((const char *) ("aniii"))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen ("aniii") + 1; char
*__retval = (char *) malloc (__len); if (__retval != ((void*
)0)) __retval = (char *) memcpy (__retval, "aniii", __len); __retval
; })) : __strdup ("aniii"))), off++), SWITCH_XML_NAMEM)
)) {
2190 return -1;
2191 }
2192 switch_xml_set_txt_d(param, caller_profile->aniii)switch_xml_set_flag(switch_xml_set_txt(param, (__extension__ (
__builtin_constant_p (caller_profile->aniii) && ((
size_t)(const void *)((caller_profile->aniii) + 1) - (size_t
)(const void *)(caller_profile->aniii) == 1) ? (((const char
*) (caller_profile->aniii))[0] == '\0' ? (char *) calloc (
(size_t) 1, (size_t) 1) : ({ size_t __len = strlen (caller_profile
->aniii) + 1; char *__retval = (char *) malloc (__len); if
(__retval != ((void*)0)) __retval = (char *) memcpy (__retval
, caller_profile->aniii, __len); __retval; })) : __strdup (
caller_profile->aniii)))), SWITCH_XML_TXTM)
;
2193
2194
2195 if (!(param = switch_xml_add_child_d(xml, "network_addr", off++)switch_xml_set_flag(switch_xml_add_child(xml, (__extension__ (
__builtin_constant_p ("network_addr") && ((size_t)(const
void *)(("network_addr") + 1) - (size_t)(const void *)("network_addr"
) == 1) ? (((const char *) ("network_addr"))[0] == '\0' ? (char
*) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen
("network_addr") + 1; char *__retval = (char *) malloc (__len
); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval
, "network_addr", __len); __retval; })) : __strdup ("network_addr"
))), off++), SWITCH_XML_NAMEM)
)) {
2196 return -1;
2197 }
2198 switch_xml_set_txt_d(param, caller_profile->network_addr)switch_xml_set_flag(switch_xml_set_txt(param, (__extension__ (
__builtin_constant_p (caller_profile->network_addr) &&
((size_t)(const void *)((caller_profile->network_addr) + 1
) - (size_t)(const void *)(caller_profile->network_addr) ==
1) ? (((const char *) (caller_profile->network_addr))[0] ==
'\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen (caller_profile->network_addr) + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, caller_profile->network_addr
, __len); __retval; })) : __strdup (caller_profile->network_addr
)))), SWITCH_XML_TXTM)
;
2199
2200 if (!(param = switch_xml_add_child_d(xml, "rdnis", off++)switch_xml_set_flag(switch_xml_add_child(xml, (__extension__ (
__builtin_constant_p ("rdnis") && ((size_t)(const void
*)(("rdnis") + 1) - (size_t)(const void *)("rdnis") == 1) ? (
((const char *) ("rdnis"))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen ("rdnis") + 1; char
*__retval = (char *) malloc (__len); if (__retval != ((void*
)0)) __retval = (char *) memcpy (__retval, "rdnis", __len); __retval
; })) : __strdup ("rdnis"))), off++), SWITCH_XML_NAMEM)
)) {
2201 return -1;
2202 }
2203 switch_xml_set_txt_d(param, caller_profile->rdnis)switch_xml_set_flag(switch_xml_set_txt(param, (__extension__ (
__builtin_constant_p (caller_profile->rdnis) && ((
size_t)(const void *)((caller_profile->rdnis) + 1) - (size_t
)(const void *)(caller_profile->rdnis) == 1) ? (((const char
*) (caller_profile->rdnis))[0] == '\0' ? (char *) calloc (
(size_t) 1, (size_t) 1) : ({ size_t __len = strlen (caller_profile
->rdnis) + 1; char *__retval = (char *) malloc (__len); if
(__retval != ((void*)0)) __retval = (char *) memcpy (__retval
, caller_profile->rdnis, __len); __retval; })) : __strdup (
caller_profile->rdnis)))), SWITCH_XML_TXTM)
;
2204
2205 if (!(param = switch_xml_add_child_d(xml, "destination_number", off++)switch_xml_set_flag(switch_xml_add_child(xml, (__extension__ (
__builtin_constant_p ("destination_number") && ((size_t
)(const void *)(("destination_number") + 1) - (size_t)(const void
*)("destination_number") == 1) ? (((const char *) ("destination_number"
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen ("destination_number") + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, "destination_number", __len); __retval
; })) : __strdup ("destination_number"))), off++), SWITCH_XML_NAMEM
)
)) {
2206 return -1;
2207 }
2208 switch_xml_set_txt_d(param, caller_profile->destination_number)switch_xml_set_flag(switch_xml_set_txt(param, (__extension__ (
__builtin_constant_p (caller_profile->destination_number) &&
((size_t)(const void *)((caller_profile->destination_number
) + 1) - (size_t)(const void *)(caller_profile->destination_number
) == 1) ? (((const char *) (caller_profile->destination_number
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen (caller_profile->destination_number
) + 1; char *__retval = (char *) malloc (__len); if (__retval
!= ((void*)0)) __retval = (char *) memcpy (__retval, caller_profile
->destination_number, __len); __retval; })) : __strdup (caller_profile
->destination_number)))), SWITCH_XML_TXTM)
;
2209
2210 if (!(param = switch_xml_add_child_d(xml, "uuid", off++)switch_xml_set_flag(switch_xml_add_child(xml, (__extension__ (
__builtin_constant_p ("uuid") && ((size_t)(const void
*)(("uuid") + 1) - (size_t)(const void *)("uuid") == 1) ? ((
(const char *) ("uuid"))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen ("uuid") + 1; char
*__retval = (char *) malloc (__len); if (__retval != ((void*
)0)) __retval = (char *) memcpy (__retval, "uuid", __len); __retval
; })) : __strdup ("uuid"))), off++), SWITCH_XML_NAMEM)
)) {
2211 return -1;
2212 }
2213 switch_xml_set_txt_d(param, caller_profile->uuid)switch_xml_set_flag(switch_xml_set_txt(param, (__extension__ (
__builtin_constant_p (caller_profile->uuid) && ((size_t
)(const void *)((caller_profile->uuid) + 1) - (size_t)(const
void *)(caller_profile->uuid) == 1) ? (((const char *) (caller_profile
->uuid))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t
) 1) : ({ size_t __len = strlen (caller_profile->uuid) + 1
; char *__retval = (char *) malloc (__len); if (__retval != (
(void*)0)) __retval = (char *) memcpy (__retval, caller_profile
->uuid, __len); __retval; })) : __strdup (caller_profile->
uuid)))), SWITCH_XML_TXTM)
;
2214
2215 if (!(param = switch_xml_add_child_d(xml, "source", off++)switch_xml_set_flag(switch_xml_add_child(xml, (__extension__ (
__builtin_constant_p ("source") && ((size_t)(const void
*)(("source") + 1) - (size_t)(const void *)("source") == 1) ?
(((const char *) ("source"))[0] == '\0' ? (char *) calloc ((
size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("source") +
1; char *__retval = (char *) malloc (__len); if (__retval !=
((void*)0)) __retval = (char *) memcpy (__retval, "source", __len
); __retval; })) : __strdup ("source"))), off++), SWITCH_XML_NAMEM
)
)) {
2216 return -1;
2217 }
2218 switch_xml_set_txt_d(param, caller_profile->source)switch_xml_set_flag(switch_xml_set_txt(param, (__extension__ (
__builtin_constant_p (caller_profile->source) && (
(size_t)(const void *)((caller_profile->source) + 1) - (size_t
)(const void *)(caller_profile->source) == 1) ? (((const char
*) (caller_profile->source))[0] == '\0' ? (char *) calloc
((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (caller_profile
->source) + 1; char *__retval = (char *) malloc (__len); if
(__retval != ((void*)0)) __retval = (char *) memcpy (__retval
, caller_profile->source, __len); __retval; })) : __strdup
(caller_profile->source)))), SWITCH_XML_TXTM)
;
2219
2220 if (caller_profile->transfer_source) {
2221 if (!(param = switch_xml_add_child_d(xml, "transfer_source", off++)switch_xml_set_flag(switch_xml_add_child(xml, (__extension__ (
__builtin_constant_p ("transfer_source") && ((size_t)
(const void *)(("transfer_source") + 1) - (size_t)(const void
*)("transfer_source") == 1) ? (((const char *) ("transfer_source"
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen ("transfer_source") + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, "transfer_source", __len); __retval
; })) : __strdup ("transfer_source"))), off++), SWITCH_XML_NAMEM
)
)) {
2222 return -1;
2223 }
2224 switch_xml_set_txt_d(param, caller_profile->transfer_source)switch_xml_set_flag(switch_xml_set_txt(param, (__extension__ (
__builtin_constant_p (caller_profile->transfer_source) &&
((size_t)(const void *)((caller_profile->transfer_source)
+ 1) - (size_t)(const void *)(caller_profile->transfer_source
) == 1) ? (((const char *) (caller_profile->transfer_source
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen (caller_profile->transfer_source) +
1; char *__retval = (char *) malloc (__len); if (__retval !=
((void*)0)) __retval = (char *) memcpy (__retval, caller_profile
->transfer_source, __len); __retval; })) : __strdup (caller_profile
->transfer_source)))), SWITCH_XML_TXTM)
;
2225 }
2226
2227 if (!(param = switch_xml_add_child_d(xml, "context", off++)switch_xml_set_flag(switch_xml_add_child(xml, (__extension__ (
__builtin_constant_p ("context") && ((size_t)(const void
*)(("context") + 1) - (size_t)(const void *)("context") == 1
) ? (((const char *) ("context"))[0] == '\0' ? (char *) calloc
((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("context"
) + 1; char *__retval = (char *) malloc (__len); if (__retval
!= ((void*)0)) __retval = (char *) memcpy (__retval, "context"
, __len); __retval; })) : __strdup ("context"))), off++), SWITCH_XML_NAMEM
)
)) {
2228 return -1;
2229 }
2230 switch_xml_set_txt_d(param, caller_profile->context)switch_xml_set_flag(switch_xml_set_txt(param, (__extension__ (
__builtin_constant_p (caller_profile->context) && (
(size_t)(const void *)((caller_profile->context) + 1) - (size_t
)(const void *)(caller_profile->context) == 1) ? (((const char
*) (caller_profile->context))[0] == '\0' ? (char *) calloc
((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (caller_profile
->context) + 1; char *__retval = (char *) malloc (__len); if
(__retval != ((void*)0)) __retval = (char *) memcpy (__retval
, caller_profile->context, __len); __retval; })) : __strdup
(caller_profile->context)))), SWITCH_XML_TXTM)
;
2231
2232 if (!(param = switch_xml_add_child_d(xml, "chan_name", off++)switch_xml_set_flag(switch_xml_add_child(xml, (__extension__ (
__builtin_constant_p ("chan_name") && ((size_t)(const
void *)(("chan_name") + 1) - (size_t)(const void *)("chan_name"
) == 1) ? (((const char *) ("chan_name"))[0] == '\0' ? (char *
) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (
"chan_name") + 1; char *__retval = (char *) malloc (__len); if
(__retval != ((void*)0)) __retval = (char *) memcpy (__retval
, "chan_name", __len); __retval; })) : __strdup ("chan_name")
)), off++), SWITCH_XML_NAMEM)
)) {
2233 return -1;
2234 }
2235 switch_xml_set_txt_d(param, caller_profile->chan_name)switch_xml_set_flag(switch_xml_set_txt(param, (__extension__ (
__builtin_constant_p (caller_profile->chan_name) &&
((size_t)(const void *)((caller_profile->chan_name) + 1) -
(size_t)(const void *)(caller_profile->chan_name) == 1) ?
(((const char *) (caller_profile->chan_name))[0] == '\0' ?
(char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len =
strlen (caller_profile->chan_name) + 1; char *__retval = (
char *) malloc (__len); if (__retval != ((void*)0)) __retval =
(char *) memcpy (__retval, caller_profile->chan_name, __len
); __retval; })) : __strdup (caller_profile->chan_name))))
, SWITCH_XML_TXTM)
;
2236
2237
2238 if (caller_profile->soft) {
2239 profile_node_t *pn;
2240
2241 for (pn = caller_profile->soft; pn; pn = pn->next) {
2242
2243 if (!(param = switch_xml_add_child_d(xml, pn->var, off++)switch_xml_set_flag(switch_xml_add_child(xml, (__extension__ (
__builtin_constant_p (pn->var) && ((size_t)(const void
*)((pn->var) + 1) - (size_t)(const void *)(pn->var) ==
1) ? (((const char *) (pn->var))[0] == '\0' ? (char *) calloc
((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (pn->
var) + 1; char *__retval = (char *) malloc (__len); if (__retval
!= ((void*)0)) __retval = (char *) memcpy (__retval, pn->
var, __len); __retval; })) : __strdup (pn->var))), off++),
SWITCH_XML_NAMEM)
)) {
2244 return -1;
2245 }
2246 switch_xml_set_txt_d(param, pn->val)switch_xml_set_flag(switch_xml_set_txt(param, (__extension__ (
__builtin_constant_p (pn->val) && ((size_t)(const void
*)((pn->val) + 1) - (size_t)(const void *)(pn->val) ==
1) ? (((const char *) (pn->val))[0] == '\0' ? (char *) calloc
((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (pn->
val) + 1; char *__retval = (char *) malloc (__len); if (__retval
!= ((void*)0)) __retval = (char *) memcpy (__retval, pn->
val, __len); __retval; })) : __strdup (pn->val)))), SWITCH_XML_TXTM
)
;
2247 }
2248
2249 }
2250
2251
2252 return off;
2253}
2254
2255static int switch_ivr_set_xml_chan_var(switch_xml_t xml, const char *var, const char *val, int off)
2256{
2257 char *data;
2258 switch_size_t dlen = strlen(val) * 3 + 1;
2259 switch_xml_t variable;
2260
2261 if (!val) val = "";
2262
2263 if (!zstr(var)_zstr(var) && ((variable = switch_xml_add_child_d(xml, var, off++)switch_xml_set_flag(switch_xml_add_child(xml, (__extension__ (
__builtin_constant_p (var) && ((size_t)(const void *)
((var) + 1) - (size_t)(const void *)(var) == 1) ? (((const char
*) (var))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t)
1) : ({ size_t __len = strlen (var) + 1; char *__retval = (char
*) malloc (__len); if (__retval != ((void*)0)) __retval = (char
*) memcpy (__retval, var, __len); __retval; })) : __strdup (
var))), off++), SWITCH_XML_NAMEM)
))) {
2264 if ((data = malloc(dlen))) {
2265 memset(data, 0, dlen);
2266 switch_url_encode(val, data, dlen);
2267 switch_xml_set_txt_d(variable, data)switch_xml_set_flag(switch_xml_set_txt(variable, (__extension__
(__builtin_constant_p (data) && ((size_t)(const void
*)((data) + 1) - (size_t)(const void *)(data) == 1) ? (((const
char *) (data))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t
) 1) : ({ size_t __len = strlen (data) + 1; char *__retval = (
char *) malloc (__len); if (__retval != ((void*)0)) __retval =
(char *) memcpy (__retval, data, __len); __retval; })) : __strdup
(data)))), SWITCH_XML_TXTM)
;
2268 free(data);
2269 } else abort();
2270 }
2271
2272 return off;
2273
2274}
2275
2276
2277SWITCH_DECLARE(int)__attribute__((visibility("default"))) int switch_ivr_set_xml_chan_vars(switch_xml_t xml, switch_channel_t *channel, int off)
2278{
2279
2280 switch_event_header_t *hi = switch_channel_variable_first(channel);
2281
2282 if (!hi)
2283 return off;
2284
2285 for (; hi; hi = hi->next) {
2286 if (hi->idx) {
2287 int i;
2288
2289 for (i = 0; i < hi->idx; i++) {
2290 off = switch_ivr_set_xml_chan_var(xml, hi->name, hi->array[i], off);
2291 }
2292 } else {
2293 off = switch_ivr_set_xml_chan_var(xml, hi->name, hi->value, off);
2294 }
2295 }
2296 switch_channel_variable_last(channel);
2297
2298 return off;
2299}
2300
2301SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_generate_xml_cdr(switch_core_session_t *session, switch_xml_t *xml_cdr)
2302{
2303 switch_channel_t *channel = switch_core_session_get_channel(session);
2304 switch_caller_profile_t *caller_profile;
2305 switch_xml_t variables, cdr, x_main_cp, x_caller_profile, x_caller_extension, x_times, time_tag,
2306 x_application, x_callflow, x_inner_extension, x_apps, x_o, x_channel_data, x_field, xhr, x_hold;
2307 switch_app_log_t *app_log;
2308 char tmp[512], *f;
2309 int cdr_off = 0, v_off = 0, cd_off = 0;
2310 switch_hold_record_t *hold_record = switch_channel_get_hold_record(channel), *hr;
2311
2312 if (*xml_cdr) {
2313 cdr = *xml_cdr;
2314 } else {
2315 if (!(cdr = switch_xml_new("cdr"))) {
2316 return SWITCH_STATUS_SUCCESS;
2317 }
2318 }
2319
2320 switch_xml_set_attr_d(cdr, "core-uuid", switch_core_get_uuid())switch_xml_set_attr(switch_xml_set_flag(cdr, SWITCH_XML_DUP),
(__extension__ (__builtin_constant_p ("core-uuid") &&
((size_t)(const void *)(("core-uuid") + 1) - (size_t)(const void
*)("core-uuid") == 1) ? (((const char *) ("core-uuid"))[0] ==
'\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen ("core-uuid") + 1; char *__retval = (char *) malloc
(__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, "core-uuid", __len); __retval; })) : __strdup ("core-uuid"
))), (__extension__ (__builtin_constant_p ((switch_core_get_uuid
() ? switch_core_get_uuid() : "")) && ((size_t)(const
void *)(((switch_core_get_uuid() ? switch_core_get_uuid() : ""
)) + 1) - (size_t)(const void *)((switch_core_get_uuid() ? switch_core_get_uuid
() : "")) == 1) ? (((const char *) ((switch_core_get_uuid() ?
switch_core_get_uuid() : "")))[0] == '\0' ? (char *) calloc (
(size_t) 1, (size_t) 1) : ({ size_t __len = strlen ((switch_core_get_uuid
() ? switch_core_get_uuid() : "")) + 1; char *__retval = (char
*) malloc (__len); if (__retval != ((void*)0)) __retval = (char
*) memcpy (__retval, (switch_core_get_uuid() ? switch_core_get_uuid
() : ""), __len); __retval; })) : __strdup ((switch_core_get_uuid
() ? switch_core_get_uuid() : "")))))
;
2321 switch_xml_set_attr_d(cdr, "switchname", switch_core_get_switchname())switch_xml_set_attr(switch_xml_set_flag(cdr, SWITCH_XML_DUP),
(__extension__ (__builtin_constant_p ("switchname") &&
((size_t)(const void *)(("switchname") + 1) - (size_t)(const
void *)("switchname") == 1) ? (((const char *) ("switchname"
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen ("switchname") + 1; char *__retval = (
char *) malloc (__len); if (__retval != ((void*)0)) __retval =
(char *) memcpy (__retval, "switchname", __len); __retval; }
)) : __strdup ("switchname"))), (__extension__ (__builtin_constant_p
((switch_core_get_switchname() ? switch_core_get_switchname(
) : "")) && ((size_t)(const void *)(((switch_core_get_switchname
() ? switch_core_get_switchname() : "")) + 1) - (size_t)(const
void *)((switch_core_get_switchname() ? switch_core_get_switchname
() : "")) == 1) ? (((const char *) ((switch_core_get_switchname
() ? switch_core_get_switchname() : "")))[0] == '\0' ? (char *
) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (
(switch_core_get_switchname() ? switch_core_get_switchname() :
"")) + 1; char *__retval = (char *) malloc (__len); if (__retval
!= ((void*)0)) __retval = (char *) memcpy (__retval, (switch_core_get_switchname
() ? switch_core_get_switchname() : ""), __len); __retval; })
) : __strdup ((switch_core_get_switchname() ? switch_core_get_switchname
() : "")))))
;
2322
2323 if (!(x_channel_data = switch_xml_add_child_d(cdr, "channel_data", cdr_off++)switch_xml_set_flag(switch_xml_add_child(cdr, (__extension__ (
__builtin_constant_p ("channel_data") && ((size_t)(const
void *)(("channel_data") + 1) - (size_t)(const void *)("channel_data"
) == 1) ? (((const char *) ("channel_data"))[0] == '\0' ? (char
*) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen
("channel_data") + 1; char *__retval = (char *) malloc (__len
); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval
, "channel_data", __len); __retval; })) : __strdup ("channel_data"
))), cdr_off++), SWITCH_XML_NAMEM)
)) {
2324 goto error;
2325 }
2326
2327 x_field = switch_xml_add_child_d(x_channel_data, "state", cd_off++)switch_xml_set_flag(switch_xml_add_child(x_channel_data, (__extension__
(__builtin_constant_p ("state") && ((size_t)(const void
*)(("state") + 1) - (size_t)(const void *)("state") == 1) ? (
((const char *) ("state"))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen ("state") + 1; char
*__retval = (char *) malloc (__len); if (__retval != ((void*
)0)) __retval = (char *) memcpy (__retval, "state", __len); __retval
; })) : __strdup ("state"))), cd_off++), SWITCH_XML_NAMEM)
;
2328 switch_xml_set_txt_d(x_field, switch_channel_state_name(switch_channel_get_state(channel)))switch_xml_set_flag(switch_xml_set_txt(x_field, (__extension__
(__builtin_constant_p (switch_channel_state_name(switch_channel_get_state
(channel))) && ((size_t)(const void *)((switch_channel_state_name
(switch_channel_get_state(channel))) + 1) - (size_t)(const void
*)(switch_channel_state_name(switch_channel_get_state(channel
))) == 1) ? (((const char *) (switch_channel_state_name(switch_channel_get_state
(channel))))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t
) 1) : ({ size_t __len = strlen (switch_channel_state_name(switch_channel_get_state
(channel))) + 1; char *__retval = (char *) malloc (__len); if
(__retval != ((void*)0)) __retval = (char *) memcpy (__retval
, switch_channel_state_name(switch_channel_get_state(channel)
), __len); __retval; })) : __strdup (switch_channel_state_name
(switch_channel_get_state(channel)))))), SWITCH_XML_TXTM)
;
2329
2330 x_field = switch_xml_add_child_d(x_channel_data, "direction", cd_off++)switch_xml_set_flag(switch_xml_add_child(x_channel_data, (__extension__
(__builtin_constant_p ("direction") && ((size_t)(const
void *)(("direction") + 1) - (size_t)(const void *)("direction"
) == 1) ? (((const char *) ("direction"))[0] == '\0' ? (char *
) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (
"direction") + 1; char *__retval = (char *) malloc (__len); if
(__retval != ((void*)0)) __retval = (char *) memcpy (__retval
, "direction", __len); __retval; })) : __strdup ("direction")
)), cd_off++), SWITCH_XML_NAMEM)
;
2331 switch_xml_set_txt_d(x_field, switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound")switch_xml_set_flag(switch_xml_set_txt(x_field, (__extension__
(__builtin_constant_p (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND
? "outbound" : "inbound") && ((size_t)(const void *)
((switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND
? "outbound" : "inbound") + 1) - (size_t)(const void *)(switch_channel_direction
(channel) == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound"
) == 1) ? (((const char *) (switch_channel_direction(channel)
== SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound"))
[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t
__len = strlen (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND
? "outbound" : "inbound") + 1; char *__retval = (char *) malloc
(__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND
? "outbound" : "inbound", __len); __retval; })) : __strdup (
switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND
? "outbound" : "inbound")))), SWITCH_XML_TXTM)
;
2332
2333 x_field = switch_xml_add_child_d(x_channel_data, "state_number", cd_off++)switch_xml_set_flag(switch_xml_add_child(x_channel_data, (__extension__
(__builtin_constant_p ("state_number") && ((size_t)(
const void *)(("state_number") + 1) - (size_t)(const void *)(
"state_number") == 1) ? (((const char *) ("state_number"))[0]
== '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t
__len = strlen ("state_number") + 1; char *__retval = (char *
) malloc (__len); if (__retval != ((void*)0)) __retval = (char
*) memcpy (__retval, "state_number", __len); __retval; })) :
__strdup ("state_number"))), cd_off++), SWITCH_XML_NAMEM)
;
2334 switch_snprintf(tmp, sizeof(tmp), "%d", switch_channel_get_state(channel));
2335 switch_xml_set_txt_d(x_field, tmp)switch_xml_set_flag(switch_xml_set_txt(x_field, (__extension__
(__builtin_constant_p (tmp) && ((size_t)(const void *
)((tmp) + 1) - (size_t)(const void *)(tmp) == 1) ? (((const char
*) (tmp))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t)
1) : ({ size_t __len = strlen (tmp) + 1; char *__retval = (char
*) malloc (__len); if (__retval != ((void*)0)) __retval = (char
*) memcpy (__retval, tmp, __len); __retval; })) : __strdup (
tmp)))), SWITCH_XML_TXTM)
;
2336
2337 if ((f = switch_channel_get_flag_string(channel))) {
2338 x_field = switch_xml_add_child_d(x_channel_data, "flags", cd_off++)switch_xml_set_flag(switch_xml_add_child(x_channel_data, (__extension__
(__builtin_constant_p ("flags") && ((size_t)(const void
*)(("flags") + 1) - (size_t)(const void *)("flags") == 1) ? (
((const char *) ("flags"))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen ("flags") + 1; char
*__retval = (char *) malloc (__len); if (__retval != ((void*
)0)) __retval = (char *) memcpy (__retval, "flags", __len); __retval
; })) : __strdup ("flags"))), cd_off++), SWITCH_XML_NAMEM)
;
2339 switch_xml_set_txt_d(x_field, f)switch_xml_set_flag(switch_xml_set_txt(x_field, (__extension__
(__builtin_constant_p (f) && ((size_t)(const void *)
((f) + 1) - (size_t)(const void *)(f) == 1) ? (((const char *
) (f))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) :
({ size_t __len = strlen (f) + 1; char *__retval = (char *) malloc
(__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, f, __len); __retval; })) : __strdup (f)))), SWITCH_XML_TXTM
)
;
2340 free(f);
2341 }
2342
2343 if ((f = switch_channel_get_cap_string(channel))) {
2344 x_field = switch_xml_add_child_d(x_channel_data, "caps", cd_off++)switch_xml_set_flag(switch_xml_add_child(x_channel_data, (__extension__
(__builtin_constant_p ("caps") && ((size_t)(const void
*)(("caps") + 1) - (size_t)(const void *)("caps") == 1) ? ((
(const char *) ("caps"))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen ("caps") + 1; char
*__retval = (char *) malloc (__len); if (__retval != ((void*
)0)) __retval = (char *) memcpy (__retval, "caps", __len); __retval
; })) : __strdup ("caps"))), cd_off++), SWITCH_XML_NAMEM)
;
2345 switch_xml_set_txt_d(x_field, f)switch_xml_set_flag(switch_xml_set_txt(x_field, (__extension__
(__builtin_constant_p (f) && ((size_t)(const void *)
((f) + 1) - (size_t)(const void *)(f) == 1) ? (((const char *
) (f))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) :
({ size_t __len = strlen (f) + 1; char *__retval = (char *) malloc
(__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, f, __len); __retval; })) : __strdup (f)))), SWITCH_XML_TXTM
)
;
2346 free(f);
2347 }
2348
2349
2350 if (!(variables = switch_xml_add_child_d(cdr, "variables", cdr_off++)switch_xml_set_flag(switch_xml_add_child(cdr, (__extension__ (
__builtin_constant_p ("variables") && ((size_t)(const
void *)(("variables") + 1) - (size_t)(const void *)("variables"
) == 1) ? (((const char *) ("variables"))[0] == '\0' ? (char *
) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (
"variables") + 1; char *__retval = (char *) malloc (__len); if
(__retval != ((void*)0)) __retval = (char *) memcpy (__retval
, "variables", __len); __retval; })) : __strdup ("variables")
)), cdr_off++), SWITCH_XML_NAMEM)
)) {
2351 goto error;
2352 }
2353
2354 switch_ivr_set_xml_chan_vars(variables, channel, v_off);
2355
2356
2357 if ((app_log = switch_core_session_get_app_log(session))) {
2358 int app_off = 0;
2359 switch_app_log_t *ap;
2360
2361 if (!(x_apps = switch_xml_add_child_d(cdr, "app_log", cdr_off++)switch_xml_set_flag(switch_xml_add_child(cdr, (__extension__ (
__builtin_constant_p ("app_log") && ((size_t)(const void
*)(("app_log") + 1) - (size_t)(const void *)("app_log") == 1
) ? (((const char *) ("app_log"))[0] == '\0' ? (char *) calloc
((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("app_log"
) + 1; char *__retval = (char *) malloc (__len); if (__retval
!= ((void*)0)) __retval = (char *) memcpy (__retval, "app_log"
, __len); __retval; })) : __strdup ("app_log"))), cdr_off++),
SWITCH_XML_NAMEM)
)) {
2362 goto error;
2363 }
2364 for (ap = app_log; ap; ap = ap->next) {
2365 char tmp[128];
2366
2367 if (!(x_application = switch_xml_add_child_d(x_apps, "application", app_off++)switch_xml_set_flag(switch_xml_add_child(x_apps, (__extension__
(__builtin_constant_p ("application") && ((size_t)(const
void *)(("application") + 1) - (size_t)(const void *)("application"
) == 1) ? (((const char *) ("application"))[0] == '\0' ? (char
*) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen
("application") + 1; char *__retval = (char *) malloc (__len
); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval
, "application", __len); __retval; })) : __strdup ("application"
))), app_off++), SWITCH_XML_NAMEM)
)) {
2368 goto error;
2369 }
2370
2371 switch_xml_set_attr_d(x_application, "app_name", ap->app)switch_xml_set_attr(switch_xml_set_flag(x_application, SWITCH_XML_DUP
), (__extension__ (__builtin_constant_p ("app_name") &&
((size_t)(const void *)(("app_name") + 1) - (size_t)(const void
*)("app_name") == 1) ? (((const char *) ("app_name"))[0] == '\0'
? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen ("app_name") + 1; char *__retval = (char *) malloc (
__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, "app_name", __len); __retval; })) : __strdup ("app_name"
))), (__extension__ (__builtin_constant_p ((ap->app ? ap->
app : "")) && ((size_t)(const void *)(((ap->app ? ap
->app : "")) + 1) - (size_t)(const void *)((ap->app ? ap
->app : "")) == 1) ? (((const char *) ((ap->app ? ap->
app : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t
) 1) : ({ size_t __len = strlen ((ap->app ? ap->app : ""
)) + 1; char *__retval = (char *) malloc (__len); if (__retval
!= ((void*)0)) __retval = (char *) memcpy (__retval, (ap->
app ? ap->app : ""), __len); __retval; })) : __strdup ((ap
->app ? ap->app : "")))))
;
2372 switch_xml_set_attr_d(x_application, "app_data", ap->arg)switch_xml_set_attr(switch_xml_set_flag(x_application, SWITCH_XML_DUP
), (__extension__ (__builtin_constant_p ("app_data") &&
((size_t)(const void *)(("app_data") + 1) - (size_t)(const void
*)("app_data") == 1) ? (((const char *) ("app_data"))[0] == '\0'
? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen ("app_data") + 1; char *__retval = (char *) malloc (
__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, "app_data", __len); __retval; })) : __strdup ("app_data"
))), (__extension__ (__builtin_constant_p ((ap->arg ? ap->
arg : "")) && ((size_t)(const void *)(((ap->arg ? ap
->arg : "")) + 1) - (size_t)(const void *)((ap->arg ? ap
->arg : "")) == 1) ? (((const char *) ((ap->arg ? ap->
arg : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t
) 1) : ({ size_t __len = strlen ((ap->arg ? ap->arg : ""
)) + 1; char *__retval = (char *) malloc (__len); if (__retval
!= ((void*)0)) __retval = (char *) memcpy (__retval, (ap->
arg ? ap->arg : ""), __len); __retval; })) : __strdup ((ap
->arg ? ap->arg : "")))))
;
2373
2374 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT"ld", ap->stamp);
2375 switch_xml_set_attr_d_buf(x_application, "app_stamp", tmp)switch_xml_set_attr(switch_xml_set_flag(x_application, SWITCH_XML_DUP
), (__extension__ (__builtin_constant_p ("app_stamp") &&
((size_t)(const void *)(("app_stamp") + 1) - (size_t)(const void
*)("app_stamp") == 1) ? (((const char *) ("app_stamp"))[0] ==
'\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen ("app_stamp") + 1; char *__retval = (char *) malloc
(__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, "app_stamp", __len); __retval; })) : __strdup ("app_stamp"
))), (__extension__ (__builtin_constant_p (tmp) && ((
size_t)(const void *)((tmp) + 1) - (size_t)(const void *)(tmp
) == 1) ? (((const char *) (tmp))[0] == '\0' ? (char *) calloc
((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (tmp) + 1
; char *__retval = (char *) malloc (__len); if (__retval != (
(void*)0)) __retval = (char *) memcpy (__retval, tmp, __len);
__retval; })) : __strdup (tmp))))
;
2376 }
2377 }
2378
2379 if (hold_record) {
2380 int cf_off = 0;
2381
2382 if (!(xhr = switch_xml_add_child_d(cdr, "hold-record", cdr_off++)switch_xml_set_flag(switch_xml_add_child(cdr, (__extension__ (
__builtin_constant_p ("hold-record") && ((size_t)(const
void *)(("hold-record") + 1) - (size_t)(const void *)("hold-record"
) == 1) ? (((const char *) ("hold-record"))[0] == '\0' ? (char
*) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen
("hold-record") + 1; char *__retval = (char *) malloc (__len
); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval
, "hold-record", __len); __retval; })) : __strdup ("hold-record"
))), cdr_off++), SWITCH_XML_NAMEM)
)) {
2383 goto error;
2384 }
2385
2386 for (hr = hold_record; hr; hr = hr->next) {
2387 char *t = tmp;
2388 if (!(x_hold = switch_xml_add_child_d(xhr, "hold", cf_off++)switch_xml_set_flag(switch_xml_add_child(xhr, (__extension__ (
__builtin_constant_p ("hold") && ((size_t)(const void
*)(("hold") + 1) - (size_t)(const void *)("hold") == 1) ? ((
(const char *) ("hold"))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen ("hold") + 1; char
*__retval = (char *) malloc (__len); if (__retval != ((void*
)0)) __retval = (char *) memcpy (__retval, "hold", __len); __retval
; })) : __strdup ("hold"))), cf_off++), SWITCH_XML_NAMEM)
)) {
2389 goto error;
2390 }
2391
2392 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT"ld", hr->on);
2393 switch_xml_set_attr_d(x_hold, "on", t)switch_xml_set_attr(switch_xml_set_flag(x_hold, SWITCH_XML_DUP
), (__extension__ (__builtin_constant_p ("on") && ((size_t
)(const void *)(("on") + 1) - (size_t)(const void *)("on") ==
1) ? (((const char *) ("on"))[0] == '\0' ? (char *) calloc (
(size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("on") + 1
; char *__retval = (char *) malloc (__len); if (__retval != (
(void*)0)) __retval = (char *) memcpy (__retval, "on", __len)
; __retval; })) : __strdup ("on"))), (__extension__ (__builtin_constant_p
((t ? t : "")) && ((size_t)(const void *)(((t ? t : ""
)) + 1) - (size_t)(const void *)((t ? t : "")) == 1) ? (((const
char *) ((t ? t : "")))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen ((t ? t : "")) + 1
; char *__retval = (char *) malloc (__len); if (__retval != (
(void*)0)) __retval = (char *) memcpy (__retval, (t ? t : "")
, __len); __retval; })) : __strdup ((t ? t : "")))))
;
2394
2395 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT"ld", hr->off);
2396 switch_xml_set_attr_d(x_hold, "off", t)switch_xml_set_attr(switch_xml_set_flag(x_hold, SWITCH_XML_DUP
), (__extension__ (__builtin_constant_p ("off") && ((
size_t)(const void *)(("off") + 1) - (size_t)(const void *)("off"
) == 1) ? (((const char *) ("off"))[0] == '\0' ? (char *) calloc
((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("off") +
1; char *__retval = (char *) malloc (__len); if (__retval !=
((void*)0)) __retval = (char *) memcpy (__retval, "off", __len
); __retval; })) : __strdup ("off"))), (__extension__ (__builtin_constant_p
((t ? t : "")) && ((size_t)(const void *)(((t ? t : ""
)) + 1) - (size_t)(const void *)((t ? t : "")) == 1) ? (((const
char *) ((t ? t : "")))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen ((t ? t : "")) + 1
; char *__retval = (char *) malloc (__len); if (__retval != (
(void*)0)) __retval = (char *) memcpy (__retval, (t ? t : "")
, __len); __retval; })) : __strdup ((t ? t : "")))))
;
2397
2398 if (hr->uuid) {
2399 switch_xml_set_attr_d(x_hold, "bridged-to", hr->uuid)switch_xml_set_attr(switch_xml_set_flag(x_hold, SWITCH_XML_DUP
), (__extension__ (__builtin_constant_p ("bridged-to") &&
((size_t)(const void *)(("bridged-to") + 1) - (size_t)(const
void *)("bridged-to") == 1) ? (((const char *) ("bridged-to"
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen ("bridged-to") + 1; char *__retval = (
char *) malloc (__len); if (__retval != ((void*)0)) __retval =
(char *) memcpy (__retval, "bridged-to", __len); __retval; }
)) : __strdup ("bridged-to"))), (__extension__ (__builtin_constant_p
((hr->uuid ? hr->uuid : "")) && ((size_t)(const
void *)(((hr->uuid ? hr->uuid : "")) + 1) - (size_t)(const
void *)((hr->uuid ? hr->uuid : "")) == 1) ? (((const char
*) ((hr->uuid ? hr->uuid : "")))[0] == '\0' ? (char *)
calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (
(hr->uuid ? hr->uuid : "")) + 1; char *__retval = (char
*) malloc (__len); if (__retval != ((void*)0)) __retval = (char
*) memcpy (__retval, (hr->uuid ? hr->uuid : ""), __len
); __retval; })) : __strdup ((hr->uuid ? hr->uuid : "")
))))
;
2400 }
2401
2402
2403 }
2404
2405
2406 }
2407
2408
2409
2410 caller_profile = switch_channel_get_caller_profile(channel);
2411
2412 while (caller_profile) {
2413 int cf_off = 0;
2414 int cp_off = 0;
2415
2416 if (!(x_callflow = switch_xml_add_child_d(cdr, "callflow", cdr_off++)switch_xml_set_flag(switch_xml_add_child(cdr, (__extension__ (
__builtin_constant_p ("callflow") && ((size_t)(const void
*)(("callflow") + 1) - (size_t)(const void *)("callflow") ==
1) ? (((const char *) ("callflow"))[0] == '\0' ? (char *) calloc
((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("callflow"
) + 1; char *__retval = (char *) malloc (__len); if (__retval
!= ((void*)0)) __retval = (char *) memcpy (__retval, "callflow"
, __len); __retval; })) : __strdup ("callflow"))), cdr_off++)
, SWITCH_XML_NAMEM)
)) {
2417 goto error;
2418 }
2419
2420 if (!zstr(caller_profile->dialplan)_zstr(caller_profile->dialplan)) {
2421 switch_xml_set_attr_d(x_callflow, "dialplan", caller_profile->dialplan)switch_xml_set_attr(switch_xml_set_flag(x_callflow, SWITCH_XML_DUP
), (__extension__ (__builtin_constant_p ("dialplan") &&
((size_t)(const void *)(("dialplan") + 1) - (size_t)(const void
*)("dialplan") == 1) ? (((const char *) ("dialplan"))[0] == '\0'
? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen ("dialplan") + 1; char *__retval = (char *) malloc (
__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, "dialplan", __len); __retval; })) : __strdup ("dialplan"
))), (__extension__ (__builtin_constant_p ((caller_profile->
dialplan ? caller_profile->dialplan : "")) && ((size_t
)(const void *)(((caller_profile->dialplan ? caller_profile
->dialplan : "")) + 1) - (size_t)(const void *)((caller_profile
->dialplan ? caller_profile->dialplan : "")) == 1) ? ((
(const char *) ((caller_profile->dialplan ? caller_profile
->dialplan : "")))[0] == '\0' ? (char *) calloc ((size_t) 1
, (size_t) 1) : ({ size_t __len = strlen ((caller_profile->
dialplan ? caller_profile->dialplan : "")) + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, (caller_profile->dialplan ? caller_profile
->dialplan : ""), __len); __retval; })) : __strdup ((caller_profile
->dialplan ? caller_profile->dialplan : "")))))
;
2422 }
2423
2424 if (!zstr(caller_profile->uuid_str)_zstr(caller_profile->uuid_str)) {
2425 switch_xml_set_attr_d(x_callflow, "unique-id", caller_profile->uuid_str)switch_xml_set_attr(switch_xml_set_flag(x_callflow, SWITCH_XML_DUP
), (__extension__ (__builtin_constant_p ("unique-id") &&
((size_t)(const void *)(("unique-id") + 1) - (size_t)(const void
*)("unique-id") == 1) ? (((const char *) ("unique-id"))[0] ==
'\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen ("unique-id") + 1; char *__retval = (char *) malloc
(__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, "unique-id", __len); __retval; })) : __strdup ("unique-id"
))), (__extension__ (__builtin_constant_p ((caller_profile->
uuid_str ? caller_profile->uuid_str : "")) && ((size_t
)(const void *)(((caller_profile->uuid_str ? caller_profile
->uuid_str : "")) + 1) - (size_t)(const void *)((caller_profile
->uuid_str ? caller_profile->uuid_str : "")) == 1) ? ((
(const char *) ((caller_profile->uuid_str ? caller_profile
->uuid_str : "")))[0] == '\0' ? (char *) calloc ((size_t) 1
, (size_t) 1) : ({ size_t __len = strlen ((caller_profile->
uuid_str ? caller_profile->uuid_str : "")) + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, (caller_profile->uuid_str ? caller_profile
->uuid_str : ""), __len); __retval; })) : __strdup ((caller_profile
->uuid_str ? caller_profile->uuid_str : "")))))
;
2426 }
2427
2428 if (!zstr(caller_profile->clone_of)_zstr(caller_profile->clone_of)) {
2429 switch_xml_set_attr_d(x_callflow, "clone-of", caller_profile->clone_of)switch_xml_set_attr(switch_xml_set_flag(x_callflow, SWITCH_XML_DUP
), (__extension__ (__builtin_constant_p ("clone-of") &&
((size_t)(const void *)(("clone-of") + 1) - (size_t)(const void
*)("clone-of") == 1) ? (((const char *) ("clone-of"))[0] == '\0'
? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen ("clone-of") + 1; char *__retval = (char *) malloc (
__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, "clone-of", __len); __retval; })) : __strdup ("clone-of"
))), (__extension__ (__builtin_constant_p ((caller_profile->
clone_of ? caller_profile->clone_of : "")) && ((size_t
)(const void *)(((caller_profile->clone_of ? caller_profile
->clone_of : "")) + 1) - (size_t)(const void *)((caller_profile
->clone_of ? caller_profile->clone_of : "")) == 1) ? ((
(const char *) ((caller_profile->clone_of ? caller_profile
->clone_of : "")))[0] == '\0' ? (char *) calloc ((size_t) 1
, (size_t) 1) : ({ size_t __len = strlen ((caller_profile->
clone_of ? caller_profile->clone_of : "")) + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, (caller_profile->clone_of ? caller_profile
->clone_of : ""), __len); __retval; })) : __strdup ((caller_profile
->clone_of ? caller_profile->clone_of : "")))))
;
2430 }
2431
2432 if (!zstr(caller_profile->profile_index)_zstr(caller_profile->profile_index)) {
2433 switch_xml_set_attr_d(x_callflow, "profile_index", caller_profile->profile_index)switch_xml_set_attr(switch_xml_set_flag(x_callflow, SWITCH_XML_DUP
), (__extension__ (__builtin_constant_p ("profile_index") &&
((size_t)(const void *)(("profile_index") + 1) - (size_t)(const
void *)("profile_index") == 1) ? (((const char *) ("profile_index"
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen ("profile_index") + 1; char *__retval =
(char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, "profile_index", __len); __retval
; })) : __strdup ("profile_index"))), (__extension__ (__builtin_constant_p
((caller_profile->profile_index ? caller_profile->profile_index
: "")) && ((size_t)(const void *)(((caller_profile->
profile_index ? caller_profile->profile_index : "")) + 1) -
(size_t)(const void *)((caller_profile->profile_index ? caller_profile
->profile_index : "")) == 1) ? (((const char *) ((caller_profile
->profile_index ? caller_profile->profile_index : "")))
[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t
__len = strlen ((caller_profile->profile_index ? caller_profile
->profile_index : "")) + 1; char *__retval = (char *) malloc
(__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, (caller_profile->profile_index ? caller_profile
->profile_index : ""), __len); __retval; })) : __strdup ((
caller_profile->profile_index ? caller_profile->profile_index
: "")))))
;
2434 }
2435
2436 if (caller_profile->caller_extension) {
2437 switch_caller_application_t *ap;
2438 int app_off = 0;
2439
2440 if (!(x_caller_extension = switch_xml_add_child_d(x_callflow, "extension", cf_off++)switch_xml_set_flag(switch_xml_add_child(x_callflow, (__extension__
(__builtin_constant_p ("extension") && ((size_t)(const
void *)(("extension") + 1) - (size_t)(const void *)("extension"
) == 1) ? (((const char *) ("extension"))[0] == '\0' ? (char *
) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (
"extension") + 1; char *__retval = (char *) malloc (__len); if
(__retval != ((void*)0)) __retval = (char *) memcpy (__retval
, "extension", __len); __retval; })) : __strdup ("extension")
)), cf_off++), SWITCH_XML_NAMEM)
)) {
2441 goto error;
2442 }
2443
2444 switch_xml_set_attr_d(x_caller_extension, "name", caller_profile->caller_extension->extension_name)switch_xml_set_attr(switch_xml_set_flag(x_caller_extension, SWITCH_XML_DUP
), (__extension__ (__builtin_constant_p ("name") && (
(size_t)(const void *)(("name") + 1) - (size_t)(const void *)
("name") == 1) ? (((const char *) ("name"))[0] == '\0' ? (char
*) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen
("name") + 1; char *__retval = (char *) malloc (__len); if (
__retval != ((void*)0)) __retval = (char *) memcpy (__retval,
"name", __len); __retval; })) : __strdup ("name"))), (__extension__
(__builtin_constant_p ((caller_profile->caller_extension->
extension_name ? caller_profile->caller_extension->extension_name
: "")) && ((size_t)(const void *)(((caller_profile->
caller_extension->extension_name ? caller_profile->caller_extension
->extension_name : "")) + 1) - (size_t)(const void *)((caller_profile
->caller_extension->extension_name ? caller_profile->
caller_extension->extension_name : "")) == 1) ? (((const char
*) ((caller_profile->caller_extension->extension_name ?
caller_profile->caller_extension->extension_name : "")
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen ((caller_profile->caller_extension->
extension_name ? caller_profile->caller_extension->extension_name
: "")) + 1; char *__retval = (char *) malloc (__len); if (__retval
!= ((void*)0)) __retval = (char *) memcpy (__retval, (caller_profile
->caller_extension->extension_name ? caller_profile->
caller_extension->extension_name : ""), __len); __retval; }
)) : __strdup ((caller_profile->caller_extension->extension_name
? caller_profile->caller_extension->extension_name : ""
)))))
;
2445 switch_xml_set_attr_d(x_caller_extension, "number", caller_profile->caller_extension->extension_number)switch_xml_set_attr(switch_xml_set_flag(x_caller_extension, SWITCH_XML_DUP
), (__extension__ (__builtin_constant_p ("number") &&
((size_t)(const void *)(("number") + 1) - (size_t)(const void
*)("number") == 1) ? (((const char *) ("number"))[0] == '\0'
? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen ("number") + 1; char *__retval = (char *) malloc (__len
); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval
, "number", __len); __retval; })) : __strdup ("number"))), (__extension__
(__builtin_constant_p ((caller_profile->caller_extension->
extension_number ? caller_profile->caller_extension->extension_number
: "")) && ((size_t)(const void *)(((caller_profile->
caller_extension->extension_number ? caller_profile->caller_extension
->extension_number : "")) + 1) - (size_t)(const void *)((caller_profile
->caller_extension->extension_number ? caller_profile->
caller_extension->extension_number : "")) == 1) ? (((const
char *) ((caller_profile->caller_extension->extension_number
? caller_profile->caller_extension->extension_number :
"")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) :
({ size_t __len = strlen ((caller_profile->caller_extension
->extension_number ? caller_profile->caller_extension->
extension_number : "")) + 1; char *__retval = (char *) malloc
(__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, (caller_profile->caller_extension->extension_number
? caller_profile->caller_extension->extension_number :
""), __len); __retval; })) : __strdup ((caller_profile->caller_extension
->extension_number ? caller_profile->caller_extension->
extension_number : "")))))
;
2446 if (caller_profile->caller_extension->current_application) {
2447 switch_xml_set_attr_d(x_caller_extension, "current_app", caller_profile->caller_extension->current_application->application_name)switch_xml_set_attr(switch_xml_set_flag(x_caller_extension, SWITCH_XML_DUP
), (__extension__ (__builtin_constant_p ("current_app") &&
((size_t)(const void *)(("current_app") + 1) - (size_t)(const
void *)("current_app") == 1) ? (((const char *) ("current_app"
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen ("current_app") + 1; char *__retval = (
char *) malloc (__len); if (__retval != ((void*)0)) __retval =
(char *) memcpy (__retval, "current_app", __len); __retval; }
)) : __strdup ("current_app"))), (__extension__ (__builtin_constant_p
((caller_profile->caller_extension->current_application
->application_name ? caller_profile->caller_extension->
current_application->application_name : "")) && ((
size_t)(const void *)(((caller_profile->caller_extension->
current_application->application_name ? caller_profile->
caller_extension->current_application->application_name
: "")) + 1) - (size_t)(const void *)((caller_profile->caller_extension
->current_application->application_name ? caller_profile
->caller_extension->current_application->application_name
: "")) == 1) ? (((const char *) ((caller_profile->caller_extension
->current_application->application_name ? caller_profile
->caller_extension->current_application->application_name
: "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1
) : ({ size_t __len = strlen ((caller_profile->caller_extension
->current_application->application_name ? caller_profile
->caller_extension->current_application->application_name
: "")) + 1; char *__retval = (char *) malloc (__len); if (__retval
!= ((void*)0)) __retval = (char *) memcpy (__retval, (caller_profile
->caller_extension->current_application->application_name
? caller_profile->caller_extension->current_application
->application_name : ""), __len); __retval; })) : __strdup
((caller_profile->caller_extension->current_application
->application_name ? caller_profile->caller_extension->
current_application->application_name : "")))))
;
2448 }
2449
2450 for (ap = caller_profile->caller_extension->applications; ap; ap = ap->next) {
2451 if (!(x_application = switch_xml_add_child_d(x_caller_extension, "application", app_off++)switch_xml_set_flag(switch_xml_add_child(x_caller_extension, (
__extension__ (__builtin_constant_p ("application") &&
((size_t)(const void *)(("application") + 1) - (size_t)(const
void *)("application") == 1) ? (((const char *) ("application"
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen ("application") + 1; char *__retval = (
char *) malloc (__len); if (__retval != ((void*)0)) __retval =
(char *) memcpy (__retval, "application", __len); __retval; }
)) : __strdup ("application"))), app_off++), SWITCH_XML_NAMEM
)
)) {
2452 goto error;
2453 }
2454 if (ap == caller_profile->caller_extension->current_application) {
2455 switch_xml_set_attr_d(x_application, "last_executed", "true")switch_xml_set_attr(switch_xml_set_flag(x_application, SWITCH_XML_DUP
), (__extension__ (__builtin_constant_p ("last_executed") &&
((size_t)(const void *)(("last_executed") + 1) - (size_t)(const
void *)("last_executed") == 1) ? (((const char *) ("last_executed"
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen ("last_executed") + 1; char *__retval =
(char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, "last_executed", __len); __retval
; })) : __strdup ("last_executed"))), (__extension__ (__builtin_constant_p
(("true" ? "true" : "")) && ((size_t)(const void *)(
(("true" ? "true" : "")) + 1) - (size_t)(const void *)(("true"
? "true" : "")) == 1) ? (((const char *) (("true" ? "true" :
"")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) :
({ size_t __len = strlen (("true" ? "true" : "")) + 1; char *
__retval = (char *) malloc (__len); if (__retval != ((void*)0
)) __retval = (char *) memcpy (__retval, ("true" ? "true" : ""
), __len); __retval; })) : __strdup (("true" ? "true" : "")))
))
;
2456 }
2457 switch_xml_set_attr_d(x_application, "app_name", ap->application_name)switch_xml_set_attr(switch_xml_set_flag(x_application, SWITCH_XML_DUP
), (__extension__ (__builtin_constant_p ("app_name") &&
((size_t)(const void *)(("app_name") + 1) - (size_t)(const void
*)("app_name") == 1) ? (((const char *) ("app_name"))[0] == '\0'
? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen ("app_name") + 1; char *__retval = (char *) malloc (
__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, "app_name", __len); __retval; })) : __strdup ("app_name"
))), (__extension__ (__builtin_constant_p ((ap->application_name
? ap->application_name : "")) && ((size_t)(const void
*)(((ap->application_name ? ap->application_name : "")
) + 1) - (size_t)(const void *)((ap->application_name ? ap
->application_name : "")) == 1) ? (((const char *) ((ap->
application_name ? ap->application_name : "")))[0] == '\0'
? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen ((ap->application_name ? ap->application_name
: "")) + 1; char *__retval = (char *) malloc (__len); if (__retval
!= ((void*)0)) __retval = (char *) memcpy (__retval, (ap->
application_name ? ap->application_name : ""), __len); __retval
; })) : __strdup ((ap->application_name ? ap->application_name
: "")))))
;
2458 switch_xml_set_attr_d(x_application, "app_data", ap->application_data)switch_xml_set_attr(switch_xml_set_flag(x_application, SWITCH_XML_DUP
), (__extension__ (__builtin_constant_p ("app_data") &&
((size_t)(const void *)(("app_data") + 1) - (size_t)(const void
*)("app_data") == 1) ? (((const char *) ("app_data"))[0] == '\0'
? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen ("app_data") + 1; char *__retval = (char *) malloc (
__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, "app_data", __len); __retval; })) : __strdup ("app_data"
))), (__extension__ (__builtin_constant_p ((ap->application_data
? ap->application_data : "")) && ((size_t)(const void
*)(((ap->application_data ? ap->application_data : "")
) + 1) - (size_t)(const void *)((ap->application_data ? ap
->application_data : "")) == 1) ? (((const char *) ((ap->
application_data ? ap->application_data : "")))[0] == '\0'
? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen ((ap->application_data ? ap->application_data
: "")) + 1; char *__retval = (char *) malloc (__len); if (__retval
!= ((void*)0)) __retval = (char *) memcpy (__retval, (ap->
application_data ? ap->application_data : ""), __len); __retval
; })) : __strdup ((ap->application_data ? ap->application_data
: "")))))
;
2459 }
2460
2461 if (caller_profile->caller_extension->children) {
2462 switch_caller_profile_t *cp = NULL((void*)0);
2463 int i_off = 0, i_app_off = 0;
2464 for (cp = caller_profile->caller_extension->children; cp; cp = cp->next) {
2465
2466 if (!cp->caller_extension) {
2467 continue;
2468 }
2469 if (!(x_inner_extension = switch_xml_add_child_d(x_caller_extension, "sub_extensions", app_off++)switch_xml_set_flag(switch_xml_add_child(x_caller_extension, (
__extension__ (__builtin_constant_p ("sub_extensions") &&
((size_t)(const void *)(("sub_extensions") + 1) - (size_t)(const
void *)("sub_extensions") == 1) ? (((const char *) ("sub_extensions"
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen ("sub_extensions") + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, "sub_extensions", __len); __retval
; })) : __strdup ("sub_extensions"))), app_off++), SWITCH_XML_NAMEM
)
)) {
2470 goto error;
2471 }
2472
2473 if (!(x_caller_extension = switch_xml_add_child_d(x_inner_extension, "extension", i_off++)switch_xml_set_flag(switch_xml_add_child(x_inner_extension, (
__extension__ (__builtin_constant_p ("extension") && (
(size_t)(const void *)(("extension") + 1) - (size_t)(const void
*)("extension") == 1) ? (((const char *) ("extension"))[0] ==
'\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen ("extension") + 1; char *__retval = (char *) malloc
(__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, "extension", __len); __retval; })) : __strdup ("extension"
))), i_off++), SWITCH_XML_NAMEM)
)) {
2474 goto error;
2475 }
2476 switch_xml_set_attr_d(x_caller_extension, "name", cp->caller_extension->extension_name)switch_xml_set_attr(switch_xml_set_flag(x_caller_extension, SWITCH_XML_DUP
), (__extension__ (__builtin_constant_p ("name") && (
(size_t)(const void *)(("name") + 1) - (size_t)(const void *)
("name") == 1) ? (((const char *) ("name"))[0] == '\0' ? (char
*) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen
("name") + 1; char *__retval = (char *) malloc (__len); if (
__retval != ((void*)0)) __retval = (char *) memcpy (__retval,
"name", __len); __retval; })) : __strdup ("name"))), (__extension__
(__builtin_constant_p ((cp->caller_extension->extension_name
? cp->caller_extension->extension_name : "")) &&
((size_t)(const void *)(((cp->caller_extension->extension_name
? cp->caller_extension->extension_name : "")) + 1) - (
size_t)(const void *)((cp->caller_extension->extension_name
? cp->caller_extension->extension_name : "")) == 1) ? (
((const char *) ((cp->caller_extension->extension_name ?
cp->caller_extension->extension_name : "")))[0] == '\0'
? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen ((cp->caller_extension->extension_name ? cp->
caller_extension->extension_name : "")) + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, (cp->caller_extension->extension_name
? cp->caller_extension->extension_name : ""), __len); __retval
; })) : __strdup ((cp->caller_extension->extension_name
? cp->caller_extension->extension_name : "")))))
;
2477 switch_xml_set_attr_d(x_caller_extension, "number", cp->caller_extension->extension_number)switch_xml_set_attr(switch_xml_set_flag(x_caller_extension, SWITCH_XML_DUP
), (__extension__ (__builtin_constant_p ("number") &&
((size_t)(const void *)(("number") + 1) - (size_t)(const void
*)("number") == 1) ? (((const char *) ("number"))[0] == '\0'
? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen ("number") + 1; char *__retval = (char *) malloc (__len
); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval
, "number", __len); __retval; })) : __strdup ("number"))), (__extension__
(__builtin_constant_p ((cp->caller_extension->extension_number
? cp->caller_extension->extension_number : "")) &&
((size_t)(const void *)(((cp->caller_extension->extension_number
? cp->caller_extension->extension_number : "")) + 1) -
(size_t)(const void *)((cp->caller_extension->extension_number
? cp->caller_extension->extension_number : "")) == 1) ?
(((const char *) ((cp->caller_extension->extension_number
? cp->caller_extension->extension_number : "")))[0] ==
'\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen ((cp->caller_extension->extension_number ? cp
->caller_extension->extension_number : "")) + 1; char *
__retval = (char *) malloc (__len); if (__retval != ((void*)0
)) __retval = (char *) memcpy (__retval, (cp->caller_extension
->extension_number ? cp->caller_extension->extension_number
: ""), __len); __retval; })) : __strdup ((cp->caller_extension
->extension_number ? cp->caller_extension->extension_number
: "")))))
;
2478 switch_xml_set_attr_d(x_caller_extension, "dialplan", cp->dialplan)switch_xml_set_attr(switch_xml_set_flag(x_caller_extension, SWITCH_XML_DUP
), (__extension__ (__builtin_constant_p ("dialplan") &&
((size_t)(const void *)(("dialplan") + 1) - (size_t)(const void
*)("dialplan") == 1) ? (((const char *) ("dialplan"))[0] == '\0'
? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen ("dialplan") + 1; char *__retval = (char *) malloc (
__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, "dialplan", __len); __retval; })) : __strdup ("dialplan"
))), (__extension__ (__builtin_constant_p ((cp->dialplan ?
cp->dialplan : "")) && ((size_t)(const void *)(((
cp->dialplan ? cp->dialplan : "")) + 1) - (size_t)(const
void *)((cp->dialplan ? cp->dialplan : "")) == 1) ? ((
(const char *) ((cp->dialplan ? cp->dialplan : "")))[0]
== '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t
__len = strlen ((cp->dialplan ? cp->dialplan : "")) + 1
; char *__retval = (char *) malloc (__len); if (__retval != (
(void*)0)) __retval = (char *) memcpy (__retval, (cp->dialplan
? cp->dialplan : ""), __len); __retval; })) : __strdup ((
cp->dialplan ? cp->dialplan : "")))))
;
2479 if (cp->caller_extension->current_application) {
2480 switch_xml_set_attr_d(x_caller_extension, "current_app", cp->caller_extension->current_application->application_name)switch_xml_set_attr(switch_xml_set_flag(x_caller_extension, SWITCH_XML_DUP
), (__extension__ (__builtin_constant_p ("current_app") &&
((size_t)(const void *)(("current_app") + 1) - (size_t)(const
void *)("current_app") == 1) ? (((const char *) ("current_app"
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen ("current_app") + 1; char *__retval = (
char *) malloc (__len); if (__retval != ((void*)0)) __retval =
(char *) memcpy (__retval, "current_app", __len); __retval; }
)) : __strdup ("current_app"))), (__extension__ (__builtin_constant_p
((cp->caller_extension->current_application->application_name
? cp->caller_extension->current_application->application_name
: "")) && ((size_t)(const void *)(((cp->caller_extension
->current_application->application_name ? cp->caller_extension
->current_application->application_name : "")) + 1) - (
size_t)(const void *)((cp->caller_extension->current_application
->application_name ? cp->caller_extension->current_application
->application_name : "")) == 1) ? (((const char *) ((cp->
caller_extension->current_application->application_name
? cp->caller_extension->current_application->application_name
: "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1
) : ({ size_t __len = strlen ((cp->caller_extension->current_application
->application_name ? cp->caller_extension->current_application
->application_name : "")) + 1; char *__retval = (char *) malloc
(__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, (cp->caller_extension->current_application->
application_name ? cp->caller_extension->current_application
->application_name : ""), __len); __retval; })) : __strdup
((cp->caller_extension->current_application->application_name
? cp->caller_extension->current_application->application_name
: "")))))
;
2481 }
2482
2483 for (ap = cp->caller_extension->applications; ap; ap = ap->next) {
2484 if (!(x_application = switch_xml_add_child_d(x_caller_extension, "application", i_app_off++)switch_xml_set_flag(switch_xml_add_child(x_caller_extension, (
__extension__ (__builtin_constant_p ("application") &&
((size_t)(const void *)(("application") + 1) - (size_t)(const
void *)("application") == 1) ? (((const char *) ("application"
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen ("application") + 1; char *__retval = (
char *) malloc (__len); if (__retval != ((void*)0)) __retval =
(char *) memcpy (__retval, "application", __len); __retval; }
)) : __strdup ("application"))), i_app_off++), SWITCH_XML_NAMEM
)
)) {
2485 goto error;
2486 }
2487 if (ap == cp->caller_extension->current_application) {
2488 switch_xml_set_attr_d(x_application, "last_executed", "true")switch_xml_set_attr(switch_xml_set_flag(x_application, SWITCH_XML_DUP
), (__extension__ (__builtin_constant_p ("last_executed") &&
((size_t)(const void *)(("last_executed") + 1) - (size_t)(const
void *)("last_executed") == 1) ? (((const char *) ("last_executed"
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen ("last_executed") + 1; char *__retval =
(char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, "last_executed", __len); __retval
; })) : __strdup ("last_executed"))), (__extension__ (__builtin_constant_p
(("true" ? "true" : "")) && ((size_t)(const void *)(
(("true" ? "true" : "")) + 1) - (size_t)(const void *)(("true"
? "true" : "")) == 1) ? (((const char *) (("true" ? "true" :
"")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) :
({ size_t __len = strlen (("true" ? "true" : "")) + 1; char *
__retval = (char *) malloc (__len); if (__retval != ((void*)0
)) __retval = (char *) memcpy (__retval, ("true" ? "true" : ""
), __len); __retval; })) : __strdup (("true" ? "true" : "")))
))
;
2489 }
2490 switch_xml_set_attr_d(x_application, "app_name", ap->application_name)switch_xml_set_attr(switch_xml_set_flag(x_application, SWITCH_XML_DUP
), (__extension__ (__builtin_constant_p ("app_name") &&
((size_t)(const void *)(("app_name") + 1) - (size_t)(const void
*)("app_name") == 1) ? (((const char *) ("app_name"))[0] == '\0'
? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen ("app_name") + 1; char *__retval = (char *) malloc (
__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, "app_name", __len); __retval; })) : __strdup ("app_name"
))), (__extension__ (__builtin_constant_p ((ap->application_name
? ap->application_name : "")) && ((size_t)(const void
*)(((ap->application_name ? ap->application_name : "")
) + 1) - (size_t)(const void *)((ap->application_name ? ap
->application_name : "")) == 1) ? (((const char *) ((ap->
application_name ? ap->application_name : "")))[0] == '\0'
? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen ((ap->application_name ? ap->application_name
: "")) + 1; char *__retval = (char *) malloc (__len); if (__retval
!= ((void*)0)) __retval = (char *) memcpy (__retval, (ap->
application_name ? ap->application_name : ""), __len); __retval
; })) : __strdup ((ap->application_name ? ap->application_name
: "")))))
;
2491 switch_xml_set_attr_d(x_application, "app_data", ap->application_data)switch_xml_set_attr(switch_xml_set_flag(x_application, SWITCH_XML_DUP
), (__extension__ (__builtin_constant_p ("app_data") &&
((size_t)(const void *)(("app_data") + 1) - (size_t)(const void
*)("app_data") == 1) ? (((const char *) ("app_data"))[0] == '\0'
? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen ("app_data") + 1; char *__retval = (char *) malloc (
__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, "app_data", __len); __retval; })) : __strdup ("app_data"
))), (__extension__ (__builtin_constant_p ((ap->application_data
? ap->application_data : "")) && ((size_t)(const void
*)(((ap->application_data ? ap->application_data : "")
) + 1) - (size_t)(const void *)((ap->application_data ? ap
->application_data : "")) == 1) ? (((const char *) ((ap->
application_data ? ap->application_data : "")))[0] == '\0'
? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen ((ap->application_data ? ap->application_data
: "")) + 1; char *__retval = (char *) malloc (__len); if (__retval
!= ((void*)0)) __retval = (char *) memcpy (__retval, (ap->
application_data ? ap->application_data : ""), __len); __retval
; })) : __strdup ((ap->application_data ? ap->application_data
: "")))))
;
2492 }
2493 }
2494 }
2495 }
2496
2497 if (!(x_main_cp = switch_xml_add_child_d(x_callflow, "caller_profile", cf_off++)switch_xml_set_flag(switch_xml_add_child(x_callflow, (__extension__
(__builtin_constant_p ("caller_profile") && ((size_t
)(const void *)(("caller_profile") + 1) - (size_t)(const void
*)("caller_profile") == 1) ? (((const char *) ("caller_profile"
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen ("caller_profile") + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, "caller_profile", __len); __retval
; })) : __strdup ("caller_profile"))), cf_off++), SWITCH_XML_NAMEM
)
)) {
2498 goto error;
2499 }
2500
2501 cp_off += switch_ivr_set_xml_profile_data(x_main_cp, caller_profile, 0);
2502
2503 if (caller_profile->origination_caller_profile) {
2504 switch_caller_profile_t *cp = NULL((void*)0);
2505 int off = 0;
2506 if (!(x_o = switch_xml_add_child_d(x_main_cp, "origination", cp_off++)switch_xml_set_flag(switch_xml_add_child(x_main_cp, (__extension__
(__builtin_constant_p ("origination") && ((size_t)(const
void *)(("origination") + 1) - (size_t)(const void *)("origination"
) == 1) ? (((const char *) ("origination"))[0] == '\0' ? (char
*) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen
("origination") + 1; char *__retval = (char *) malloc (__len
); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval
, "origination", __len); __retval; })) : __strdup ("origination"
))), cp_off++), SWITCH_XML_NAMEM)
)) {
2507 goto error;
2508 }
2509
2510 for (cp = caller_profile->origination_caller_profile; cp; cp = cp->next) {
2511 if (!(x_caller_profile = switch_xml_add_child_d(x_o, "origination_caller_profile", off++)switch_xml_set_flag(switch_xml_add_child(x_o, (__extension__ (
__builtin_constant_p ("origination_caller_profile") &&
((size_t)(const void *)(("origination_caller_profile") + 1) -
(size_t)(const void *)("origination_caller_profile") == 1) ?
(((const char *) ("origination_caller_profile"))[0] == '\0' ?
(char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len =
strlen ("origination_caller_profile") + 1; char *__retval = (
char *) malloc (__len); if (__retval != ((void*)0)) __retval =
(char *) memcpy (__retval, "origination_caller_profile", __len
); __retval; })) : __strdup ("origination_caller_profile"))),
off++), SWITCH_XML_NAMEM)
)) {
2512 goto error;
2513 }
2514 switch_ivr_set_xml_profile_data(x_caller_profile, cp, 0);
2515 }
2516 }
2517
2518 if (caller_profile->originator_caller_profile) {
2519 switch_caller_profile_t *cp = NULL((void*)0);
2520 int off = 0;
2521 if (!(x_o = switch_xml_add_child_d(x_main_cp, "originator", cp_off++)switch_xml_set_flag(switch_xml_add_child(x_main_cp, (__extension__
(__builtin_constant_p ("originator") && ((size_t)(const
void *)(("originator") + 1) - (size_t)(const void *)("originator"
) == 1) ? (((const char *) ("originator"))[0] == '\0' ? (char
*) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen
("originator") + 1; char *__retval = (char *) malloc (__len)
; if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval
, "originator", __len); __retval; })) : __strdup ("originator"
))), cp_off++), SWITCH_XML_NAMEM)
)) {
2522 goto error;
2523 }
2524
2525 for (cp = caller_profile->originator_caller_profile; cp; cp = cp->next) {
2526 if (!(x_caller_profile = switch_xml_add_child_d(x_o, "originator_caller_profile", off++)switch_xml_set_flag(switch_xml_add_child(x_o, (__extension__ (
__builtin_constant_p ("originator_caller_profile") &&
((size_t)(const void *)(("originator_caller_profile") + 1) -
(size_t)(const void *)("originator_caller_profile") == 1) ? (
((const char *) ("originator_caller_profile"))[0] == '\0' ? (
char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen
("originator_caller_profile") + 1; char *__retval = (char *)
malloc (__len); if (__retval != ((void*)0)) __retval = (char
*) memcpy (__retval, "originator_caller_profile", __len); __retval
; })) : __strdup ("originator_caller_profile"))), off++), SWITCH_XML_NAMEM
)
)) {
2527 goto error;
2528 }
2529 switch_ivr_set_xml_profile_data(x_caller_profile, cp, 0);
2530 }
2531 }
2532
2533 if (caller_profile->originatee_caller_profile) {
2534 switch_caller_profile_t *cp = NULL((void*)0);
2535 int off = 0;
2536 if (!(x_o = switch_xml_add_child_d(x_main_cp, "originatee", cp_off++)switch_xml_set_flag(switch_xml_add_child(x_main_cp, (__extension__
(__builtin_constant_p ("originatee") && ((size_t)(const
void *)(("originatee") + 1) - (size_t)(const void *)("originatee"
) == 1) ? (((const char *) ("originatee"))[0] == '\0' ? (char
*) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen
("originatee") + 1; char *__retval = (char *) malloc (__len)
; if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval
, "originatee", __len); __retval; })) : __strdup ("originatee"
))), cp_off++), SWITCH_XML_NAMEM)
)) {
2537 goto error;
2538 }
2539 for (cp = caller_profile->originatee_caller_profile; cp; cp = cp->next) {
2540 if (!(x_caller_profile = switch_xml_add_child_d(x_o, "originatee_caller_profile", off++)switch_xml_set_flag(switch_xml_add_child(x_o, (__extension__ (
__builtin_constant_p ("originatee_caller_profile") &&
((size_t)(const void *)(("originatee_caller_profile") + 1) -
(size_t)(const void *)("originatee_caller_profile") == 1) ? (
((const char *) ("originatee_caller_profile"))[0] == '\0' ? (
char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen
("originatee_caller_profile") + 1; char *__retval = (char *)
malloc (__len); if (__retval != ((void*)0)) __retval = (char
*) memcpy (__retval, "originatee_caller_profile", __len); __retval
; })) : __strdup ("originatee_caller_profile"))), off++), SWITCH_XML_NAMEM
)
)) {
2541 goto error;
2542 }
2543 switch_ivr_set_xml_profile_data(x_caller_profile, cp, 0);
2544 }
2545 }
2546
2547 if (caller_profile->times) {
2548 int t_off = 0;
2549 if (!(x_times = switch_xml_add_child_d(x_callflow, "times", cf_off++)switch_xml_set_flag(switch_xml_add_child(x_callflow, (__extension__
(__builtin_constant_p ("times") && ((size_t)(const void
*)(("times") + 1) - (size_t)(const void *)("times") == 1) ? (
((const char *) ("times"))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen ("times") + 1; char
*__retval = (char *) malloc (__len); if (__retval != ((void*
)0)) __retval = (char *) memcpy (__retval, "times", __len); __retval
; })) : __strdup ("times"))), cf_off++), SWITCH_XML_NAMEM)
)) {
2550 goto error;
2551 }
2552 if (!(time_tag = switch_xml_add_child_d(x_times, "created_time", t_off++)switch_xml_set_flag(switch_xml_add_child(x_times, (__extension__
(__builtin_constant_p ("created_time") && ((size_t)(
const void *)(("created_time") + 1) - (size_t)(const void *)(
"created_time") == 1) ? (((const char *) ("created_time"))[0]
== '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t
__len = strlen ("created_time") + 1; char *__retval = (char *
) malloc (__len); if (__retval != ((void*)0)) __retval = (char
*) memcpy (__retval, "created_time", __len); __retval; })) :
__strdup ("created_time"))), t_off++), SWITCH_XML_NAMEM)
)) {
2553 goto error;
2554 }
2555 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT"ld", caller_profile->times->created);
2556 switch_xml_set_txt_d(time_tag, tmp)switch_xml_set_flag(switch_xml_set_txt(time_tag, (__extension__
(__builtin_constant_p (tmp) && ((size_t)(const void *
)((tmp) + 1) - (size_t)(const void *)(tmp) == 1) ? (((const char
*) (tmp))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t)
1) : ({ size_t __len = strlen (tmp) + 1; char *__retval = (char
*) malloc (__len); if (__retval != ((void*)0)) __retval = (char
*) memcpy (__retval, tmp, __len); __retval; })) : __strdup (
tmp)))), SWITCH_XML_TXTM)
;
2557
2558 if (!(time_tag = switch_xml_add_child_d(x_times, "profile_created_time", t_off++)switch_xml_set_flag(switch_xml_add_child(x_times, (__extension__
(__builtin_constant_p ("profile_created_time") && ((
size_t)(const void *)(("profile_created_time") + 1) - (size_t
)(const void *)("profile_created_time") == 1) ? (((const char
*) ("profile_created_time"))[0] == '\0' ? (char *) calloc ((
size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("profile_created_time"
) + 1; char *__retval = (char *) malloc (__len); if (__retval
!= ((void*)0)) __retval = (char *) memcpy (__retval, "profile_created_time"
, __len); __retval; })) : __strdup ("profile_created_time")))
, t_off++), SWITCH_XML_NAMEM)
)) {
2559 goto error;
2560 }
2561 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT"ld", caller_profile->times->profile_created);
2562 switch_xml_set_txt_d(time_tag, tmp)switch_xml_set_flag(switch_xml_set_txt(time_tag, (__extension__
(__builtin_constant_p (tmp) && ((size_t)(const void *
)((tmp) + 1) - (size_t)(const void *)(tmp) == 1) ? (((const char
*) (tmp))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t)
1) : ({ size_t __len = strlen (tmp) + 1; char *__retval = (char
*) malloc (__len); if (__retval != ((void*)0)) __retval = (char
*) memcpy (__retval, tmp, __len); __retval; })) : __strdup (
tmp)))), SWITCH_XML_TXTM)
;
2563
2564 if (!(time_tag = switch_xml_add_child_d(x_times, "progress_time", t_off++)switch_xml_set_flag(switch_xml_add_child(x_times, (__extension__
(__builtin_constant_p ("progress_time") && ((size_t)
(const void *)(("progress_time") + 1) - (size_t)(const void *
)("progress_time") == 1) ? (((const char *) ("progress_time")
)[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t
__len = strlen ("progress_time") + 1; char *__retval = (char
*) malloc (__len); if (__retval != ((void*)0)) __retval = (char
*) memcpy (__retval, "progress_time", __len); __retval; })) :
__strdup ("progress_time"))), t_off++), SWITCH_XML_NAMEM)
)) {
2565 goto error;
2566 }
2567 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT"ld", caller_profile->times->progress);
2568 switch_xml_set_txt_d(time_tag, tmp)switch_xml_set_flag(switch_xml_set_txt(time_tag, (__extension__
(__builtin_constant_p (tmp) && ((size_t)(const void *
)((tmp) + 1) - (size_t)(const void *)(tmp) == 1) ? (((const char
*) (tmp))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t)
1) : ({ size_t __len = strlen (tmp) + 1; char *__retval = (char
*) malloc (__len); if (__retval != ((void*)0)) __retval = (char
*) memcpy (__retval, tmp, __len); __retval; })) : __strdup (
tmp)))), SWITCH_XML_TXTM)
;
2569
2570
2571 if (!(time_tag = switch_xml_add_child_d(x_times, "progress_media_time", t_off++)switch_xml_set_flag(switch_xml_add_child(x_times, (__extension__
(__builtin_constant_p ("progress_media_time") && ((size_t
)(const void *)(("progress_media_time") + 1) - (size_t)(const
void *)("progress_media_time") == 1) ? (((const char *) ("progress_media_time"
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen ("progress_media_time") + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, "progress_media_time", __len); __retval
; })) : __strdup ("progress_media_time"))), t_off++), SWITCH_XML_NAMEM
)
)) {
2572 goto error;
2573 }
2574 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT"ld", caller_profile->times->progress_media);
2575 switch_xml_set_txt_d(time_tag, tmp)switch_xml_set_flag(switch_xml_set_txt(time_tag, (__extension__
(__builtin_constant_p (tmp) && ((size_t)(const void *
)((tmp) + 1) - (size_t)(const void *)(tmp) == 1) ? (((const char
*) (tmp))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t)
1) : ({ size_t __len = strlen (tmp) + 1; char *__retval = (char
*) malloc (__len); if (__retval != ((void*)0)) __retval = (char
*) memcpy (__retval, tmp, __len); __retval; })) : __strdup (
tmp)))), SWITCH_XML_TXTM)
;
2576
2577 if (!(time_tag = switch_xml_add_child_d(x_times, "answered_time", t_off++)switch_xml_set_flag(switch_xml_add_child(x_times, (__extension__
(__builtin_constant_p ("answered_time") && ((size_t)
(const void *)(("answered_time") + 1) - (size_t)(const void *
)("answered_time") == 1) ? (((const char *) ("answered_time")
)[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t
__len = strlen ("answered_time") + 1; char *__retval = (char
*) malloc (__len); if (__retval != ((void*)0)) __retval = (char
*) memcpy (__retval, "answered_time", __len); __retval; })) :
__strdup ("answered_time"))), t_off++), SWITCH_XML_NAMEM)
)) {
2578 goto error;
2579 }
2580 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT"ld", caller_profile->times->answered);
2581 switch_xml_set_txt_d(time_tag, tmp)switch_xml_set_flag(switch_xml_set_txt(time_tag, (__extension__
(__builtin_constant_p (tmp) && ((size_t)(const void *
)((tmp) + 1) - (size_t)(const void *)(tmp) == 1) ? (((const char
*) (tmp))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t)
1) : ({ size_t __len = strlen (tmp) + 1; char *__retval = (char
*) malloc (__len); if (__retval != ((void*)0)) __retval = (char
*) memcpy (__retval, tmp, __len); __retval; })) : __strdup (
tmp)))), SWITCH_XML_TXTM)
;
2582
2583 if (!(time_tag = switch_xml_add_child_d(x_times, "bridged_time", t_off++)switch_xml_set_flag(switch_xml_add_child(x_times, (__extension__
(__builtin_constant_p ("bridged_time") && ((size_t)(
const void *)(("bridged_time") + 1) - (size_t)(const void *)(
"bridged_time") == 1) ? (((const char *) ("bridged_time"))[0]
== '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t
__len = strlen ("bridged_time") + 1; char *__retval = (char *
) malloc (__len); if (__retval != ((void*)0)) __retval = (char
*) memcpy (__retval, "bridged_time", __len); __retval; })) :
__strdup ("bridged_time"))), t_off++), SWITCH_XML_NAMEM)
)) {
2584 goto error;
2585 }
2586 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT"ld", caller_profile->times->bridged);
2587 switch_xml_set_txt_d(time_tag, tmp)switch_xml_set_flag(switch_xml_set_txt(time_tag, (__extension__
(__builtin_constant_p (tmp) && ((size_t)(const void *
)((tmp) + 1) - (size_t)(const void *)(tmp) == 1) ? (((const char
*) (tmp))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t)
1) : ({ size_t __len = strlen (tmp) + 1; char *__retval = (char
*) malloc (__len); if (__retval != ((void*)0)) __retval = (char
*) memcpy (__retval, tmp, __len); __retval; })) : __strdup (
tmp)))), SWITCH_XML_TXTM)
;
2588
2589 if (!(time_tag = switch_xml_add_child_d(x_times, "last_hold_time", t_off++)switch_xml_set_flag(switch_xml_add_child(x_times, (__extension__
(__builtin_constant_p ("last_hold_time") && ((size_t
)(const void *)(("last_hold_time") + 1) - (size_t)(const void
*)("last_hold_time") == 1) ? (((const char *) ("last_hold_time"
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen ("last_hold_time") + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, "last_hold_time", __len); __retval
; })) : __strdup ("last_hold_time"))), t_off++), SWITCH_XML_NAMEM
)
)) {
2590 goto error;
2591 }
2592 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT"ld", caller_profile->times->last_hold);
2593 switch_xml_set_txt_d(time_tag, tmp)switch_xml_set_flag(switch_xml_set_txt(time_tag, (__extension__
(__builtin_constant_p (tmp) && ((size_t)(const void *
)((tmp) + 1) - (size_t)(const void *)(tmp) == 1) ? (((const char
*) (tmp))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t)
1) : ({ size_t __len = strlen (tmp) + 1; char *__retval = (char
*) malloc (__len); if (__retval != ((void*)0)) __retval = (char
*) memcpy (__retval, tmp, __len); __retval; })) : __strdup (
tmp)))), SWITCH_XML_TXTM)
;
2594
2595 if (!(time_tag = switch_xml_add_child_d(x_times, "hold_accum_time", t_off++)switch_xml_set_flag(switch_xml_add_child(x_times, (__extension__
(__builtin_constant_p ("hold_accum_time") && ((size_t
)(const void *)(("hold_accum_time") + 1) - (size_t)(const void
*)("hold_accum_time") == 1) ? (((const char *) ("hold_accum_time"
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen ("hold_accum_time") + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, "hold_accum_time", __len); __retval
; })) : __strdup ("hold_accum_time"))), t_off++), SWITCH_XML_NAMEM
)
)) {
2596 goto error;
2597 }
2598 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT"ld", caller_profile->times->hold_accum);
2599 switch_xml_set_txt_d(time_tag, tmp)switch_xml_set_flag(switch_xml_set_txt(time_tag, (__extension__
(__builtin_constant_p (tmp) && ((size_t)(const void *
)((tmp) + 1) - (size_t)(const void *)(tmp) == 1) ? (((const char
*) (tmp))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t)
1) : ({ size_t __len = strlen (tmp) + 1; char *__retval = (char
*) malloc (__len); if (__retval != ((void*)0)) __retval = (char
*) memcpy (__retval, tmp, __len); __retval; })) : __strdup (
tmp)))), SWITCH_XML_TXTM)
;
2600
2601 if (!(time_tag = switch_xml_add_child_d(x_times, "hangup_time", t_off++)switch_xml_set_flag(switch_xml_add_child(x_times, (__extension__
(__builtin_constant_p ("hangup_time") && ((size_t)(const
void *)(("hangup_time") + 1) - (size_t)(const void *)("hangup_time"
) == 1) ? (((const char *) ("hangup_time"))[0] == '\0' ? (char
*) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen
("hangup_time") + 1; char *__retval = (char *) malloc (__len
); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval
, "hangup_time", __len); __retval; })) : __strdup ("hangup_time"
))), t_off++), SWITCH_XML_NAMEM)
)) {
2602 goto error;
2603 }
2604 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT"ld", caller_profile->times->hungup);
2605 switch_xml_set_txt_d(time_tag, tmp)switch_xml_set_flag(switch_xml_set_txt(time_tag, (__extension__
(__builtin_constant_p (tmp) && ((size_t)(const void *
)((tmp) + 1) - (size_t)(const void *)(tmp) == 1) ? (((const char
*) (tmp))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t)
1) : ({ size_t __len = strlen (tmp) + 1; char *__retval = (char
*) malloc (__len); if (__retval != ((void*)0)) __retval = (char
*) memcpy (__retval, tmp, __len); __retval; })) : __strdup (
tmp)))), SWITCH_XML_TXTM)
;
2606
2607 if (!(time_tag = switch_xml_add_child_d(x_times, "resurrect_time", t_off++)switch_xml_set_flag(switch_xml_add_child(x_times, (__extension__
(__builtin_constant_p ("resurrect_time") && ((size_t
)(const void *)(("resurrect_time") + 1) - (size_t)(const void
*)("resurrect_time") == 1) ? (((const char *) ("resurrect_time"
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen ("resurrect_time") + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, "resurrect_time", __len); __retval
; })) : __strdup ("resurrect_time"))), t_off++), SWITCH_XML_NAMEM
)
)) {
2608 goto error;
2609 }
2610 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT"ld", caller_profile->times->resurrected);
2611 switch_xml_set_txt_d(time_tag, tmp)switch_xml_set_flag(switch_xml_set_txt(time_tag, (__extension__
(__builtin_constant_p (tmp) && ((size_t)(const void *
)((tmp) + 1) - (size_t)(const void *)(tmp) == 1) ? (((const char
*) (tmp))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t)
1) : ({ size_t __len = strlen (tmp) + 1; char *__retval = (char
*) malloc (__len); if (__retval != ((void*)0)) __retval = (char
*) memcpy (__retval, tmp, __len); __retval; })) : __strdup (
tmp)))), SWITCH_XML_TXTM)
;
2612
2613 if (!(time_tag = switch_xml_add_child_d(x_times, "transfer_time", t_off++)switch_xml_set_flag(switch_xml_add_child(x_times, (__extension__
(__builtin_constant_p ("transfer_time") && ((size_t)
(const void *)(("transfer_time") + 1) - (size_t)(const void *
)("transfer_time") == 1) ? (((const char *) ("transfer_time")
)[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t
__len = strlen ("transfer_time") + 1; char *__retval = (char
*) malloc (__len); if (__retval != ((void*)0)) __retval = (char
*) memcpy (__retval, "transfer_time", __len); __retval; })) :
__strdup ("transfer_time"))), t_off++), SWITCH_XML_NAMEM)
)) {
2614 goto error;
2615 }
2616 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT"ld", caller_profile->times->transferred);
2617 switch_xml_set_txt_d(time_tag, tmp)switch_xml_set_flag(switch_xml_set_txt(time_tag, (__extension__
(__builtin_constant_p (tmp) && ((size_t)(const void *
)((tmp) + 1) - (size_t)(const void *)(tmp) == 1) ? (((const char
*) (tmp))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t)
1) : ({ size_t __len = strlen (tmp) + 1; char *__retval = (char
*) malloc (__len); if (__retval != ((void*)0)) __retval = (char
*) memcpy (__retval, tmp, __len); __retval; })) : __strdup (
tmp)))), SWITCH_XML_TXTM)
;
2618 }
2619
2620 caller_profile = caller_profile->next;
2621 }
2622
2623 *xml_cdr = cdr;
2624
2625 return SWITCH_STATUS_SUCCESS;
2626
2627 error:
2628
2629 if (cdr) {
2630 switch_xml_free(cdr);
2631 }
2632
2633 return SWITCH_STATUS_FALSE;
2634}
2635
2636static void switch_ivr_set_json_profile_data(cJSON *json, switch_caller_profile_t *caller_profile)
2637{
2638 cJSON_AddItemToObject(json, "username", cJSON_CreateString((char *)caller_profile->username));
2639 cJSON_AddItemToObject(json, "dialplan", cJSON_CreateString((char *)caller_profile->dialplan));
2640 cJSON_AddItemToObject(json, "caller_id_name", cJSON_CreateString((char *)caller_profile->caller_id_name));
2641 cJSON_AddItemToObject(json, "ani", cJSON_CreateString((char *)caller_profile->ani));
2642 cJSON_AddItemToObject(json, "aniii", cJSON_CreateString((char *)caller_profile->aniii));
2643 cJSON_AddItemToObject(json, "caller_id_number", cJSON_CreateString((char *)caller_profile->caller_id_number));
2644 cJSON_AddItemToObject(json, "network_addr", cJSON_CreateString((char *)caller_profile->network_addr));
2645 cJSON_AddItemToObject(json, "rdnis", cJSON_CreateString((char *)caller_profile->rdnis));
2646 cJSON_AddItemToObject(json, "destination_number", cJSON_CreateString(caller_profile->destination_number));
2647 cJSON_AddItemToObject(json, "uuid", cJSON_CreateString(caller_profile->uuid));
2648 cJSON_AddItemToObject(json, "source", cJSON_CreateString((char *)caller_profile->source));
2649 cJSON_AddItemToObject(json, "context", cJSON_CreateString((char *)caller_profile->context));
2650 cJSON_AddItemToObject(json, "chan_name", cJSON_CreateString(caller_profile->chan_name));
2651}
2652
2653static void switch_ivr_set_json_chan_vars(cJSON *json, switch_channel_t *channel, switch_bool_t urlencode)
2654{
2655 switch_event_header_t *hi = switch_channel_variable_first(channel);
2656
2657 if (!hi)
2658 return;
2659
2660 for (; hi; hi = hi->next) {
2661 if (!zstr(hi->name)_zstr(hi->name) && !zstr(hi->value)_zstr(hi->value)) {
2662 char *data = hi->value;
2663 if (urlencode) {
2664 switch_size_t dlen = strlen(hi->value) * 3;
2665
2666 if ((data = malloc(dlen))) {
2667 memset(data, 0, dlen);
2668 switch_url_encode(hi->value, data, dlen);
2669 }
2670 }
2671
2672 cJSON_AddItemToObject(json, hi->name, cJSON_CreateString(data));
2673
2674 if (data != hi->value) {
2675 switch_safe_free(data)if (data) {free(data);data=((void*)0);};
2676 }
2677 }
2678 }
2679 switch_channel_variable_last(channel);
2680}
2681
2682
2683
2684SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_generate_json_cdr(switch_core_session_t *session, cJSON **json_cdr, switch_bool_t urlencode)
2685{
2686 cJSON *cdr = cJSON_CreateObject();
2687 switch_channel_t *channel = switch_core_session_get_channel(session);
2688 switch_caller_profile_t *caller_profile;
2689 cJSON *variables, *j_main_cp, *j_caller_profile, *j_caller_extension, *j_caller_extension_apps, *j_times,
2690 *j_application, *j_callflow, *j_inner_extension, *j_app_log, *j_apps, *j_o, *j_o_profiles, *j_channel_data;
2691 switch_app_log_t *app_log;
2692 char tmp[512], *f;
2693
2694 cJSON_AddItemToObject(cdr, "core-uuid", cJSON_CreateString(switch_core_get_uuid()));
2695 cJSON_AddItemToObject(cdr, "switchname", cJSON_CreateString(switch_core_get_switchname()));
2696 j_channel_data = cJSON_CreateObject();
2697
2698 cJSON_AddItemToObject(cdr, "channel_data", j_channel_data);
2699
2700 cJSON_AddItemToObject(j_channel_data, "state", cJSON_CreateString((char *) switch_channel_state_name(switch_channel_get_state(channel))));
2701 cJSON_AddItemToObject(j_channel_data, "direction", cJSON_CreateString(switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound"));
2702
2703 switch_snprintf(tmp, sizeof(tmp), "%d", switch_channel_get_state(channel));
2704 cJSON_AddItemToObject(j_channel_data, "state_number", cJSON_CreateString((char *) tmp));
2705
2706 if ((f = switch_channel_get_flag_string(channel))) {
2707 cJSON_AddItemToObject(j_channel_data, "flags", cJSON_CreateString((char *) f));
2708 free(f);
2709 }
2710
2711 if ((f = switch_channel_get_cap_string(channel))) {
2712 cJSON_AddItemToObject(j_channel_data, "caps", cJSON_CreateString((char *) f));
2713 free(f);
2714 }
2715
2716 variables = cJSON_CreateObject();
2717 cJSON_AddItemToObject(cdr, "variables", variables);
2718
2719 switch_ivr_set_json_chan_vars(variables, channel, urlencode);
2720
2721
2722 if ((app_log = switch_core_session_get_app_log(session))) {
2723 switch_app_log_t *ap;
2724
2725 j_app_log = cJSON_CreateObject();
2726 j_apps = cJSON_CreateArray();
2727
2728 cJSON_AddItemToObject(cdr, "app_log", j_app_log);
2729 cJSON_AddItemToObject(j_app_log, "applications", j_apps);
2730
2731 for (ap = app_log; ap; ap = ap->next) {
2732 j_application = cJSON_CreateObject();
2733
2734 cJSON_AddItemToObject(j_application, "app_name", cJSON_CreateString(ap->app));
2735 cJSON_AddItemToObject(j_application, "app_data", cJSON_CreateString(ap->arg));
2736
2737 cJSON_AddItemToArray(j_apps, j_application);
2738 }
2739 }
2740
2741
2742 caller_profile = switch_channel_get_caller_profile(channel);
2743
2744 while (caller_profile) {
2745
2746 j_callflow = cJSON_CreateObject();
2747
2748 cJSON_AddItemToObject(cdr, "callflow", j_callflow);
2749
2750 if (!zstr(caller_profile->dialplan)_zstr(caller_profile->dialplan)) {
2751 cJSON_AddItemToObject(j_callflow, "dialplan", cJSON_CreateString((char *)caller_profile->dialplan));
2752 }
2753
2754 if (!zstr(caller_profile->profile_index)_zstr(caller_profile->profile_index)) {
2755 cJSON_AddItemToObject(j_callflow, "profile_index", cJSON_CreateString((char *)caller_profile->profile_index));
2756 }
2757
2758 if (caller_profile->caller_extension) {
2759 switch_caller_application_t *ap;
2760
2761 j_caller_extension = cJSON_CreateObject();
2762 j_caller_extension_apps = cJSON_CreateArray();
2763
2764 cJSON_AddItemToObject(j_callflow, "extension", j_caller_extension);
2765
2766 cJSON_AddItemToObject(j_caller_extension, "name", cJSON_CreateString(caller_profile->caller_extension->extension_name));
2767 cJSON_AddItemToObject(j_caller_extension, "number", cJSON_CreateString(caller_profile->caller_extension->extension_number));
2768 cJSON_AddItemToObject(j_caller_extension, "applications", j_caller_extension_apps);
2769
2770 if (caller_profile->caller_extension->current_application) {
2771 cJSON_AddItemToObject(j_caller_extension, "current_app", cJSON_CreateString(caller_profile->caller_extension->current_application->application_name));
2772 }
2773
2774 for (ap = caller_profile->caller_extension->applications; ap; ap = ap->next) {
2775 j_application = cJSON_CreateObject();
2776
2777 cJSON_AddItemToArray(j_caller_extension_apps, j_application);
2778
2779 if (ap == caller_profile->caller_extension->current_application) {
2780 cJSON_AddItemToObject(j_application, "last_executed", cJSON_CreateString("true"));
2781 }
2782 cJSON_AddItemToObject(j_application, "app_name", cJSON_CreateString(ap->application_name));
2783 cJSON_AddItemToObject(j_application, "app_data", cJSON_CreateString(switch_str_nil(ap->application_data)(ap->application_data ? ap->application_data : "")));
2784 }
2785
2786 if (caller_profile->caller_extension->children) {
2787 switch_caller_profile_t *cp = NULL((void*)0);
2788 j_inner_extension = cJSON_CreateArray();
2789 cJSON_AddItemToObject(j_caller_extension, "sub_extensions", j_inner_extension);
2790 for (cp = caller_profile->caller_extension->children; cp; cp = cp->next) {
2791
2792 if (!cp->caller_extension) {
2793 continue;
2794 }
2795
2796 j_caller_extension = cJSON_CreateObject();
2797 cJSON_AddItemToArray(j_inner_extension, j_caller_extension);
2798
2799 cJSON_AddItemToObject(j_caller_extension, "name", cJSON_CreateString(cp->caller_extension->extension_name));
2800 cJSON_AddItemToObject(j_caller_extension, "number", cJSON_CreateString(cp->caller_extension->extension_number));
2801
2802 cJSON_AddItemToObject(j_caller_extension, "dialplan", cJSON_CreateString((char *)cp->dialplan));
2803
2804 if (cp->caller_extension->current_application) {
2805 cJSON_AddItemToObject(j_caller_extension, "current_app", cJSON_CreateString(cp->caller_extension->current_application->application_name));
2806 }
2807
2808 j_caller_extension_apps = cJSON_CreateArray();
2809 cJSON_AddItemToObject(j_caller_extension, "applications", j_caller_extension_apps);
2810 for (ap = cp->caller_extension->applications; ap; ap = ap->next) {
2811 j_application = cJSON_CreateObject();
2812 cJSON_AddItemToArray(j_caller_extension_apps, j_application);
2813
2814 if (ap == cp->caller_extension->current_application) {
2815 cJSON_AddItemToObject(j_application, "last_executed", cJSON_CreateString("true"));
2816 }
2817 cJSON_AddItemToObject(j_application, "app_name", cJSON_CreateString(ap->application_name));
2818 cJSON_AddItemToObject(j_application, "app_data", cJSON_CreateString(switch_str_nil(ap->application_data)(ap->application_data ? ap->application_data : "")));
2819 }
2820 }
2821 }
2822 }
2823
2824 j_main_cp = cJSON_CreateObject();
2825 cJSON_AddItemToObject(j_callflow, "caller_profile", j_main_cp);
2826
2827 switch_ivr_set_json_profile_data(j_main_cp, caller_profile);
2828
2829 if (caller_profile->originator_caller_profile) {
2830 switch_caller_profile_t *cp = NULL((void*)0);
2831
2832 j_o = cJSON_CreateObject();
2833 cJSON_AddItemToObject(j_main_cp, "originator", j_o);
2834
2835 j_o_profiles = cJSON_CreateArray();
2836 cJSON_AddItemToObject(j_o, "originator_caller_profiles", j_o_profiles);
2837
2838 for (cp = caller_profile->originator_caller_profile; cp; cp = cp->next) {
2839 j_caller_profile = cJSON_CreateObject();
2840 cJSON_AddItemToArray(j_o_profiles, j_caller_profile);
2841
2842 switch_ivr_set_json_profile_data(j_caller_profile, cp);
2843 }
2844 }
2845
2846 if (caller_profile->originatee_caller_profile) {
2847 switch_caller_profile_t *cp = NULL((void*)0);
2848
2849 j_o = cJSON_CreateObject();
2850 cJSON_AddItemToObject(j_main_cp, "originatee", j_o);
2851
2852 j_o_profiles = cJSON_CreateArray();
2853 cJSON_AddItemToObject(j_o, "originatee_caller_profiles", j_o_profiles);
2854
2855 for (cp = caller_profile->originatee_caller_profile; cp; cp = cp->next) {
2856 j_caller_profile = cJSON_CreateObject();
2857 cJSON_AddItemToArray(j_o_profiles, j_caller_profile);
2858
2859 switch_ivr_set_json_profile_data(j_caller_profile, cp);
2860 }
2861 }
2862
2863 if (caller_profile->times) {
2864
2865 j_times = cJSON_CreateObject();
2866 cJSON_AddItemToObject(j_callflow, "times", j_times);
2867
2868 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT"ld", caller_profile->times->created);
2869 cJSON_AddItemToObject(j_times, "created_time", cJSON_CreateString(tmp));
2870
2871 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT"ld", caller_profile->times->profile_created);
2872 cJSON_AddItemToObject(j_times, "profile_created_time", cJSON_CreateString(tmp));
2873
2874 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT"ld", caller_profile->times->progress);
2875 cJSON_AddItemToObject(j_times, "progress_time", cJSON_CreateString(tmp));
2876
2877 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT"ld", caller_profile->times->progress_media);
2878 cJSON_AddItemToObject(j_times, "progress_media_time", cJSON_CreateString(tmp));
2879
2880 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT"ld", caller_profile->times->answered);
2881 cJSON_AddItemToObject(j_times, "answered_time", cJSON_CreateString(tmp));
2882
2883 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT"ld", caller_profile->times->bridged);
2884 cJSON_AddItemToObject(j_times, "bridged_time", cJSON_CreateString(tmp));
2885
2886 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT"ld", caller_profile->times->last_hold);
2887 cJSON_AddItemToObject(j_times, "last_hold_time", cJSON_CreateString(tmp));
2888
2889 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT"ld", caller_profile->times->hold_accum);
2890 cJSON_AddItemToObject(j_times, "hold_accum_time", cJSON_CreateString(tmp));
2891
2892 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT"ld", caller_profile->times->hungup);
2893 cJSON_AddItemToObject(j_times, "hangup_time", cJSON_CreateString(tmp));
2894
2895 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT"ld", caller_profile->times->resurrected);
2896 cJSON_AddItemToObject(j_times, "resurrect_time", cJSON_CreateString(tmp));
2897
2898 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT"ld", caller_profile->times->transferred);
2899 cJSON_AddItemToObject(j_times, "transfer_time", cJSON_CreateString(tmp));
2900
2901 }
2902
2903 caller_profile = caller_profile->next;
2904 }
2905
2906 *json_cdr = cdr;
2907
2908 return SWITCH_STATUS_SUCCESS;
2909
2910}
2911
2912
2913SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_ivr_park_session(switch_core_session_t *session)
2914{
2915 switch_channel_t *channel = switch_core_session_get_channel(session);
2916 switch_channel_set_state(channel, CS_PARK)switch_channel_perform_set_state(channel, "src/switch_ivr.c",
(const char *)__func__, 2916, CS_PARK)
;
2917 switch_channel_set_flag(channel, CF_TRANSFER)switch_channel_set_flag_value(channel, CF_TRANSFER, 1);
2918
2919}
2920
2921SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_ivr_delay_echo(switch_core_session_t *session, uint32_t delay_ms)
2922{
2923 stfu_instance_t *jb;
2924 int qlen = 0;
2925 stfu_frame_t *jb_frame;
2926 switch_frame_t *read_frame, write_frame = { 0 };
2927 switch_status_t status;
2928 switch_channel_t *channel = switch_core_session_get_channel(session);
2929 uint32_t interval;
2930 uint32_t ts = 0;
2931 switch_codec_implementation_t read_impl = { 0 };
2932 switch_core_session_get_read_impl(session, &read_impl);
2933
2934
2935 if (delay_ms < 1 || delay_ms > 10000) {
2936 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 2936, (const char*)(session)
, SWITCH_LOG_ERROR, "Invalid delay [%d] must be between 1 and 10000\n", delay_ms);
2937 return;
2938 }
2939
2940 interval = read_impl.microseconds_per_packet / 1000;
2941 //samples = switch_samples_per_packet(read_impl.samples_per_second, interval);
2942
2943 if (delay_ms < interval * 2) {
2944 delay_ms = interval * 2;
2945 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 2945, (const char*)(session)
, SWITCH_LOG_WARNING, "Minimum possible delay for this codec (%d) has been chosen\n", delay_ms);
2946 }
2947
2948
2949 qlen = delay_ms / (interval);
2950 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 2950, (const char*)(session)
, SWITCH_LOG_DEBUG, "Setting delay to %dms (%d frames)\n", delay_ms, qlen);
2951 jb = stfu_n_init(qlen, qlen, read_impl.samples_per_packet, read_impl.samples_per_second, 0);
2952
2953 write_frame.codec = switch_core_session_get_read_codec(session);
2954
2955 while (switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE)) {
2956 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
2957 if (!SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK
|| status == SWITCH_STATUS_INUSE)
) {
2958 break;
2959 }
2960
2961 stfu_n_eat(jb, ts, 0, read_frame->payload, read_frame->data, read_frame->datalen, 0)stfu_n_add_data(jb, ts, 0, read_frame->payload, read_frame
->data, read_frame->datalen, 0, 0)
;
2962 ts += read_impl.samples_per_packet;
2963
2964 if ((jb_frame = stfu_n_read_a_frame(jb))) {
2965 write_frame.data = jb_frame->data;
2966 write_frame.datalen = (uint32_t) jb_frame->dlen;
2967 write_frame.buflen = (uint32_t) jb_frame->dlen;
2968 status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
2969 if (!SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK
|| status == SWITCH_STATUS_INUSE)
) {
2970 break;
2971 }
2972 }
2973 }
2974
2975 stfu_n_destroy(&jb);
2976}
2977
2978SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_say(switch_core_session_t *session,
2979 const char *tosay,
2980 const char *module_name,
2981 const char *say_type,
2982 const char *say_method,
2983 const char *say_gender,
2984 switch_input_args_t *args)
2985{
2986 switch_say_interface_t *si;
2987 switch_channel_t *channel;
2988 switch_status_t status = SWITCH_STATUS_FALSE;
2989 const char *save_path = NULL((void*)0), *chan_lang = NULL((void*)0), *lang = NULL((void*)0), *sound_path = NULL((void*)0);
2990 switch_event_t *hint_data;
2991 switch_xml_t cfg, xml = NULL((void*)0), language = NULL((void*)0), macros = NULL((void*)0), phrases = NULL((void*)0);
2992 char *p;
2993
2994 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_ivr.c"
, 2994, __PRETTY_FUNCTION__))
;
2995 channel = switch_core_session_get_channel(session);
2996 switch_assert(channel)((channel) ? (void) (0) : __assert_fail ("channel", "src/switch_ivr.c"
, 2996, __PRETTY_FUNCTION__))
;
2997
2998 arg_recursion_check_start(args)if (args) { if (args->loops >= 25) { switch_log_printf(
SWITCH_CHANNEL_ID_LOG, "src/switch_ivr.c", (const char *)__func__
, 2998, ((void*)0), SWITCH_LOG_ERROR, "RECURSION ERROR! It's not the best idea to call things that collect input recursively from an input callback.\n"
); return SWITCH_STATUS_GENERR; } else {args->loops++;} }
;
2999
3000
3001 if (zstr(module_name)_zstr(module_name)) {
3002 module_name = "en";
3003 }
3004
3005 if (module_name) {
3006 char *p;
3007 p = switch_core_session_strdup(session, module_name)switch_core_perform_session_strdup(session, module_name, "src/switch_ivr.c"
, (const char *)__func__, 3007)
;
3008 module_name = p;
3009
3010 if ((p = strchr(module_name, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(module_name) && (':') == '\0' ? (char *) __rawmemchr
(module_name, ':') : __builtin_strchr (module_name, ':')))
)) {
3011 *p++ = '\0';
3012 chan_lang = p;
3013 }
3014 }
3015
3016 if (!chan_lang) {
3017 lang = switch_channel_get_variable(channel, "language")switch_channel_get_variable_dup(channel, "language", SWITCH_TRUE
, -1)
;
3018
3019 if (!lang) {
3020 chan_lang = switch_channel_get_variable(channel, "default_language")switch_channel_get_variable_dup(channel, "default_language", SWITCH_TRUE
, -1)
;
3021 if (!chan_lang) {
3022 chan_lang = module_name;
3023 }
3024 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 3024, (const char*)(session)
, SWITCH_LOG_DEBUG, "No language specified - Using [%s]\n", chan_lang);
3025 } else {
3026 chan_lang = lang;
3027 }
3028 }
3029
3030 switch_event_create(&hint_data, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("src/switch_ivr.c", (const
char * )(const char *)__func__, 3030, &hint_data, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
3031 switch_assert(hint_data)((hint_data) ? (void) (0) : __assert_fail ("hint_data", "src/switch_ivr.c"
, 3031, __PRETTY_FUNCTION__))
;
3032
3033 switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "macro_name", "say_app");
3034 switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "lang", chan_lang);
3035 switch_channel_event_set_data(channel, hint_data);
3036
3037 if (switch_xml_locate_language(&xml, &cfg, hint_data, &language, &phrases, &macros, chan_lang) != SWITCH_STATUS_SUCCESS) {
3038 goto done;
3039 }
3040
3041 if ((p = (char *) switch_xml_attr(language, "say-module"))) {
3042 module_name = switch_core_session_strdup(session, p)switch_core_perform_session_strdup(session, p, "src/switch_ivr.c"
, (const char *)__func__, 3042)
;
3043 } else if ((p = (char *) switch_xml_attr(language, "module"))) {
3044 module_name = switch_core_session_strdup(session, p)switch_core_perform_session_strdup(session, p, "src/switch_ivr.c"
, (const char *)__func__, 3044)
;
3045 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 3045, (const char*)(session)
, SWITCH_LOG_WARNING, "Deprecated usage of module attribute\n");
3046 } else {
3047 module_name = chan_lang;
3048 }
3049
3050 if (!(sound_path = (char *) switch_xml_attr(language, "sound-prefix"))) {
3051 if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
3052 sound_path = (char *) switch_xml_attr(language, "sound_path");
3053 }
3054 }
3055
3056 if (channel) {
3057 const char *p = switch_channel_get_variable(channel, "sound_prefix_enforced")switch_channel_get_variable_dup(channel, "sound_prefix_enforced"
, SWITCH_TRUE, -1)
;
3058 if (!switch_true(p)) {
3059 save_path = switch_channel_get_variable(channel, "sound_prefix")switch_channel_get_variable_dup(channel, "sound_prefix", SWITCH_TRUE
, -1)
;
3060 if (sound_path) {
3061 switch_channel_set_variable(channel, "sound_prefix", sound_path)switch_channel_set_variable_var_check(channel, "sound_prefix"
, sound_path, SWITCH_TRUE)
;
3062 }
3063 }
3064 }
3065
3066 if ((si = switch_loadable_module_get_say_interface(module_name))) {
3067 /* should go back and proto all the say mods to const.... */
3068 switch_say_args_t say_args = {0};
3069
3070 say_args.type = switch_ivr_get_say_type_by_name(say_type);
3071 say_args.method = switch_ivr_get_say_method_by_name(say_method);
3072 say_args.gender = switch_ivr_get_say_gender_by_name(say_gender);
3073
3074 status = si->say_function(session, (char *) tosay, &say_args, args);
3075 } else {
3076 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 3076, (const char*)(session)
, SWITCH_LOG_ERROR, "Invalid SAY Interface [%s]!\n", module_name);
3077 status = SWITCH_STATUS_FALSE;
3078 }
3079
3080 done:
3081
3082 arg_recursion_check_stop(args)if (args) args->loops--;
3083
3084
3085 if (hint_data) {
3086 switch_event_destroy(&hint_data);
3087 }
3088
3089 if (save_path) {
3090 switch_channel_set_variable(channel, "sound_prefix", save_path)switch_channel_set_variable_var_check(channel, "sound_prefix"
, save_path, SWITCH_TRUE)
;
3091 }
3092
3093 if (xml) {
3094 switch_xml_free(xml);
3095 }
3096
3097 return status;
3098}
3099
3100SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_say_string(switch_core_session_t *session,
3101 const char *lang,
3102 const char *ext,
3103 const char *tosay,
3104 const char *module_name,
3105 const char *say_type,
3106 const char *say_method,
3107 const char *say_gender,
3108 char **rstr)
3109{
3110 switch_say_interface_t *si;
3111 switch_channel_t *channel = NULL((void*)0);
3112 switch_status_t status = SWITCH_STATUS_FALSE;
3113 const char *save_path = NULL((void*)0), *chan_lang = NULL((void*)0), *sound_path = NULL((void*)0);
3114 switch_event_t *hint_data;
3115 switch_xml_t cfg, xml = NULL((void*)0), language = NULL((void*)0), macros = NULL((void*)0), phrases = NULL((void*)0);
3116
3117 if (session) {
3118 channel = switch_core_session_get_channel(session);
3119
3120 if (!lang) {
3121 lang = switch_channel_get_variable(channel, "language")switch_channel_get_variable_dup(channel, "language", SWITCH_TRUE
, -1)
;
3122
3123 if (!lang) {
3124 chan_lang = switch_channel_get_variable(channel, "default_language")switch_channel_get_variable_dup(channel, "default_language", SWITCH_TRUE
, -1)
;
3125 if (!chan_lang) {
3126 chan_lang = "en";
3127 }
3128 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 3128, (const char*)(session)
, SWITCH_LOG_DEBUG, "No language specified - Using [%s]\n", chan_lang);
3129 } else {
3130 chan_lang = lang;
3131 }
3132 }
3133 }
3134
3135 if (!lang) lang = "en";
3136 if (!chan_lang) chan_lang = lang;
3137
3138 switch_event_create(&hint_data, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("src/switch_ivr.c", (const
char * )(const char *)__func__, 3138, &hint_data, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
3139 switch_assert(hint_data)((hint_data) ? (void) (0) : __assert_fail ("hint_data", "src/switch_ivr.c"
, 3139, __PRETTY_FUNCTION__))
;
3140
3141 switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "macro_name", "say_app");
3142 switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "lang", chan_lang);
3143
3144 if (channel) {
3145 switch_channel_event_set_data(channel, hint_data);
3146 }
3147
3148 if (switch_xml_locate_language(&xml, &cfg, hint_data, &language, &phrases, &macros, chan_lang) != SWITCH_STATUS_SUCCESS) {
3149 goto done;
3150 }
3151
3152 if ((module_name = switch_xml_attr(language, "say-module"))) {
3153 } else if ((module_name = switch_xml_attr(language, "module"))) {
3154 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 3154, (const char*)(session)
, SWITCH_LOG_WARNING, "Deprecated usage of module attribute\n");
3155 } else {
3156 module_name = chan_lang;
3157 }
3158
3159 if (!(sound_path = (char *) switch_xml_attr(language, "sound-prefix"))) {
3160 if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
3161 sound_path = (char *) switch_xml_attr(language, "sound_path");
3162 }
3163 }
3164
3165 if (channel) {
3166 const char *p = switch_channel_get_variable(channel, "sound_prefix_enforced")switch_channel_get_variable_dup(channel, "sound_prefix_enforced"
, SWITCH_TRUE, -1)
;
3167 if (!switch_true(p)) {
3168 save_path = switch_channel_get_variable(channel, "sound_prefix")switch_channel_get_variable_dup(channel, "sound_prefix", SWITCH_TRUE
, -1)
;
3169 if (sound_path) {
3170 switch_channel_set_variable(channel, "sound_prefix", sound_path)switch_channel_set_variable_var_check(channel, "sound_prefix"
, sound_path, SWITCH_TRUE)
;
3171 }
3172 }
3173 }
3174
3175 if ((si = switch_loadable_module_get_say_interface(module_name)) && si->say_string_function) {
3176 /* should go back and proto all the say mods to const.... */
3177 switch_say_args_t say_args = {0};
3178
3179 say_args.type = switch_ivr_get_say_type_by_name(say_type);
3180 say_args.method = switch_ivr_get_say_method_by_name(say_method);
3181 say_args.gender = switch_ivr_get_say_gender_by_name(say_gender);
3182 say_args.ext = ext;
3183 status = si->say_string_function(session, (char *) tosay, &say_args, rstr);
3184 } else {
3185 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 3185, (const char*)(session)
, SWITCH_LOG_ERROR, "Invalid SAY Interface [%s]!\n", module_name);
3186 status = SWITCH_STATUS_FALSE;
3187 }
3188
3189 done:
3190
3191 if (hint_data) {
3192 switch_event_destroy(&hint_data);
3193 }
3194
3195 if (save_path && channel) {
3196 switch_channel_set_variable(channel, "sound_prefix", save_path)switch_channel_set_variable_var_check(channel, "sound_prefix"
, save_path, SWITCH_TRUE)
;
3197 }
3198
3199 if (xml) {
3200 switch_xml_free(xml);
3201 }
3202
3203 return status;
3204}
3205
3206
3207static const char *get_prefixed_str(char *buffer, size_t buffer_size, const char *prefix, size_t prefix_size, const char *str)
3208{
3209 size_t str_len;
3210
3211 if (!buffer) {
3212 /*
3213 if buffer is null then it just returns the str without the prefix appended, otherwise buffer contains the prefix followed by the original string
3214 */
3215
3216 return str;
3217 }
3218
3219 str_len = strlen(str);
3220 memcpy(buffer, prefix, prefix_size);
3221
3222 if (str_len + prefix_size + 1 > buffer_size) {
3223 memcpy(buffer + prefix_size, str, buffer_size - prefix_size - 1);
3224 buffer[buffer_size - prefix_size - 1] = '\0';
3225 } else {
3226 memcpy(buffer + prefix_size, str, str_len + 1);
3227 }
3228
3229 return buffer;
3230}
3231
3232SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_set_user_xml(switch_core_session_t *session, const char *prefix,
3233 const char *user, const char *domain, switch_xml_t x_user)
3234{
3235 switch_xml_t x_params, x_param;
3236 char *number_alias;
3237 switch_channel_t *channel = switch_core_session_get_channel(session);
3238 switch_status_t status = SWITCH_STATUS_FALSE;
3239
3240 char *prefix_buffer = NULL((void*)0);
3241 size_t buffer_size = 0;
3242 size_t prefix_size = 0;
3243
3244
3245 status = SWITCH_STATUS_SUCCESS;
3246
3247 if (!zstr(prefix)_zstr(prefix)) {
3248 prefix_size = strlen(prefix);
3249 buffer_size = 1024 + prefix_size + 1;
3250 prefix_buffer = switch_core_session_alloc(session, buffer_size)switch_core_perform_session_alloc(session, buffer_size, "src/switch_ivr.c"
, (const char *)__func__, 3250)
;
3251 }
3252
3253 if ((number_alias = (char *) switch_xml_attr(x_user, "number-alias"))) {
3254 switch_channel_set_variable(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, "number_alias"), number_alias)switch_channel_set_variable_var_check(channel, get_prefixed_str
(prefix_buffer, buffer_size, prefix, prefix_size, "number_alias"
), number_alias, SWITCH_TRUE)
;
3255 }
3256
3257 if ((x_params = switch_xml_child(x_user, "variables"))) {
3258 for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) {
3259 const char *var = switch_xml_attr(x_param, "name");
3260 const char *val = switch_xml_attr(x_param, "value");
3261
3262 if (var && val) {
3263 switch_channel_set_variable(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, var), val)switch_channel_set_variable_var_check(channel, get_prefixed_str
(prefix_buffer, buffer_size, prefix, prefix_size, var), val, SWITCH_TRUE
)
;
3264 }
3265 }
3266 }
3267
3268 if ((x_params = switch_xml_child(x_user, "profile-variables"))) {
3269 for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) {
3270 const char *var = switch_xml_attr(x_param, "name");
3271 const char *val = switch_xml_attr(x_param, "value");
3272
3273 if (var && val) {
3274 switch_channel_set_profile_var(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, var), val);
3275 }
3276 }
3277 }
3278
3279 if (user && domain) {
3280 switch_channel_set_variable(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, "user_name"), user)switch_channel_set_variable_var_check(channel, get_prefixed_str
(prefix_buffer, buffer_size, prefix, prefix_size, "user_name"
), user, SWITCH_TRUE)
;
3281 switch_channel_set_variable(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, "domain_name"), domain)switch_channel_set_variable_var_check(channel, get_prefixed_str
(prefix_buffer, buffer_size, prefix, prefix_size, "domain_name"
), domain, SWITCH_TRUE)
;
3282 }
3283
3284 return status;
3285}
3286
3287SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_set_user(switch_core_session_t *session, const char *data)
3288{
3289 switch_xml_t x_user = 0;
3290 char *user, *domain;
3291 switch_status_t status = SWITCH_STATUS_FALSE;
3292
3293 char *prefix;
3294
3295 if (zstr(data)_zstr(data)) {
3296 goto error;
3297 }
3298
3299 user = switch_core_session_strdup(session, data)switch_core_perform_session_strdup(session, data, "src/switch_ivr.c"
, (const char *)__func__, 3299)
;
3300
3301 if ((prefix = strchr(user, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p
(user) && (' ') == '\0' ? (char *) __rawmemchr (user
, ' ') : __builtin_strchr (user, ' ')))
)) {
3302 *prefix++ = 0;
3303 }
3304
3305 if (!(domain = strchr(user, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p
(user) && ('@') == '\0' ? (char *) __rawmemchr (user
, '@') : __builtin_strchr (user, '@')))
)) {
3306 goto error;
3307 }
3308
3309 *domain++ = '\0';
3310
3311
3312 if (switch_xml_locate_user_merged("id", user, domain, NULL((void*)0), &x_user, NULL((void*)0)) != SWITCH_STATUS_SUCCESS) {
3313 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 3313, (const char*)(session)
, SWITCH_LOG_WARNING, "can't find user [%s@%s]\n", user, domain);
3314 goto done;
3315 }
3316
3317 status = switch_ivr_set_user_xml(session, prefix, user, domain, x_user);
3318
3319 goto done;
3320
3321 error:
3322 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 3322, (const char*)(session)
, SWITCH_LOG_ERROR, "No user@domain specified.\n");
3323
3324 done:
3325
3326 if (x_user) {
3327 switch_xml_free(x_user);
3328 }
3329
3330 return status;
3331}
3332
3333SWITCH_DECLARE(switch_bool_t)__attribute__((visibility("default"))) switch_bool_t switch_ivr_uuid_exists(const char *uuid)
3334{
3335 switch_bool_t exists = SWITCH_FALSE;
3336 switch_core_session_t *psession = NULL((void*)0);
3337
3338 if ((psession = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "src/switch_ivr.c", (
const char *)__func__, 3338)
)) {
3339 switch_core_session_rwunlock(psession);
3340 exists = 1;
3341 }
3342
3343 return exists;
3344}
3345
3346SWITCH_DECLARE(switch_bool_t)__attribute__((visibility("default"))) switch_bool_t switch_ivr_uuid_force_exists(const char *uuid)
3347{
3348 switch_bool_t exists = SWITCH_FALSE;
3349 switch_core_session_t *psession = NULL((void*)0);
3350
3351 if ((psession = switch_core_session_force_locate(uuid)switch_core_session_perform_force_locate(uuid, "src/switch_ivr.c"
, (const char *)__func__, 3351)
)) {
3352 switch_core_session_rwunlock(psession);
3353 exists = 1;
3354 }
3355
3356 return exists;
3357}
3358
3359SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_process_fh(switch_core_session_t *session, const char *cmd, switch_file_handle_t *fhp)
3360{
3361 if (zstr(cmd)_zstr(cmd)) {
3362 return SWITCH_STATUS_SUCCESS;
3363 }
3364
3365 if (fhp) {
3366 if (!switch_test_flag(fhp, SWITCH_FILE_OPEN)((fhp)->flags & SWITCH_FILE_OPEN)) {
3367 return SWITCH_STATUS_FALSE;
3368 }
3369
3370 if (!strncasecmp(cmd, "speed", 5)) {
3371 char *p;
3372
3373 if ((p = strchr(cmd, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(cmd) && (':') == '\0' ? (char *) __rawmemchr (cmd, ':'
) : __builtin_strchr (cmd, ':')))
)) {
3374 p++;
3375 if (*p == '+' || *p == '-') {
3376 int step;
3377 if (!(step = atoi(p))) {
3378 step = 1;
3379 }
3380 fhp->speed += step;
3381 } else {
3382 int speed = atoi(p);
3383 fhp->speed = speed;
3384 }
3385 return SWITCH_STATUS_SUCCESS;
3386 }
3387
3388 return SWITCH_STATUS_FALSE;
3389
3390 } else if (!strncasecmp(cmd, "volume", 6)) {
3391 char *p;
3392
3393 if ((p = strchr(cmd, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(cmd) && (':') == '\0' ? (char *) __rawmemchr (cmd, ':'
) : __builtin_strchr (cmd, ':')))
)) {
3394 p++;
3395 if (*p == '+' || *p == '-') {
3396 int step;
3397 if (!(step = atoi(p))) {
3398 step = 1;
3399 }
3400 fhp->vol += step;
3401 } else {
3402 int vol = atoi(p);
3403 fhp->vol = vol;
3404 }
3405 return SWITCH_STATUS_SUCCESS;
3406 }
3407
3408 if (fhp->vol) {
3409 switch_normalize_volume(fhp->vol)if (fhp->vol > 4) fhp->vol = 4; if (fhp->vol <
-4) fhp->vol = -4;
;
3410 }
3411
3412 return SWITCH_STATUS_FALSE;
3413 } else if (!strcasecmp(cmd, "pause")) {
3414 if (switch_test_flag(fhp, SWITCH_FILE_PAUSE)((fhp)->flags & SWITCH_FILE_PAUSE)) {
3415 switch_clear_flag(fhp, SWITCH_FILE_PAUSE)(fhp)->flags &= ~(SWITCH_FILE_PAUSE);
3416 } else {
3417 switch_set_flag(fhp, SWITCH_FILE_PAUSE)(fhp)->flags |= (SWITCH_FILE_PAUSE);
3418 }
3419 return SWITCH_STATUS_SUCCESS;
3420 } else if (!strcasecmp(cmd, "stop")) {
3421 switch_set_flag(fhp, SWITCH_FILE_DONE)(fhp)->flags |= (SWITCH_FILE_DONE);
3422 return SWITCH_STATUS_FALSE;
3423 } else if (!strcasecmp(cmd, "truncate")) {
3424 switch_core_file_truncate(fhp, 0);
3425 } else if (!strcasecmp(cmd, "restart")) {
3426 unsigned int pos = 0;
3427 fhp->speed = 0;
3428 switch_core_file_seek(fhp, &pos, 0, SEEK_SET0);
3429 return SWITCH_STATUS_SUCCESS;
3430 } else if (!strncasecmp(cmd, "seek", 4)) {
3431 //switch_codec_t *codec;
3432 unsigned int samps = 0;
3433 unsigned int pos = 0;
3434 char *p;
3435 //codec = switch_core_session_get_read_codec(session);
3436
3437 if ((p = strchr(cmd, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(cmd) && (':') == '\0' ? (char *) __rawmemchr (cmd, ':'
) : __builtin_strchr (cmd, ':')))
)) {
3438 p++;
3439 if (*p == '+' || *p == '-') {
3440 int step;
3441 int32_t target;
3442 if (!(step = atoi(p))) {
3443 step = 1000;
3444 }
3445
3446 samps = step * (fhp->native_rate / 1000);
3447 target = (int32_t)fhp->offset_pos + samps;
3448
3449 if (target < 0) {
3450 target = 0;
3451 }
3452
3453 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 3453, (const char*)(session)
, SWITCH_LOG_DEBUG, "seek to position %d\n", target);
3454 switch_core_file_seek(fhp, &pos, target, SEEK_SET0);
3455
3456 } else {
3457 samps = switch_atoui(p) * (fhp->native_rate / 1000);
3458 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 3458, (const char*)(session)
, SWITCH_LOG_DEBUG, "seek to position %d\n", samps);
3459 switch_core_file_seek(fhp, &pos, samps, SEEK_SET0);
3460 }
3461 }
3462
3463 return SWITCH_STATUS_SUCCESS;
3464 }
3465 }
3466
3467 if (!strcmp(cmd, "true")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(cmd) && __builtin_constant_p ("true") && (__s1_len
= __builtin_strlen (cmd), __s2_len = __builtin_strlen ("true"
), (!((size_t)(const void *)((cmd) + 1) - (size_t)(const void
*)(cmd) == 1) || __s1_len >= 4) && (!((size_t)(const
void *)(("true") + 1) - (size_t)(const void *)("true") == 1)
|| __s2_len >= 4)) ? __builtin_strcmp (cmd, "true") : (__builtin_constant_p
(cmd) && ((size_t)(const void *)((cmd) + 1) - (size_t
)(const void *)(cmd) == 1) && (__s1_len = __builtin_strlen
(cmd), __s1_len < 4) ? (__builtin_constant_p ("true") &&
((size_t)(const void *)(("true") + 1) - (size_t)(const void *
)("true") == 1) ? __builtin_strcmp (cmd, "true") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("true"); int __result = (((const unsigned char *) (
const char *) (cmd))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (cmd))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (cmd))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (cmd))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("true") && ((size_t)(const void *)(("true") + 1) - (
size_t)(const void *)("true") == 1) && (__s2_len = __builtin_strlen
("true"), __s2_len < 4) ? (__builtin_constant_p (cmd) &&
((size_t)(const void *)((cmd) + 1) - (size_t)(const void *)(
cmd) == 1) ? __builtin_strcmp (cmd, "true") : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (cmd); int __result = (((const unsigned char *) (const
char *) ("true"))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("true"))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("true"))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) ("true"))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(cmd, "true")))); })
|| !strcmp(cmd, "undefined")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(cmd) && __builtin_constant_p ("undefined") &&
(__s1_len = __builtin_strlen (cmd), __s2_len = __builtin_strlen
("undefined"), (!((size_t)(const void *)((cmd) + 1) - (size_t
)(const void *)(cmd) == 1) || __s1_len >= 4) && (!
((size_t)(const void *)(("undefined") + 1) - (size_t)(const void
*)("undefined") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(cmd, "undefined") : (__builtin_constant_p (cmd) && (
(size_t)(const void *)((cmd) + 1) - (size_t)(const void *)(cmd
) == 1) && (__s1_len = __builtin_strlen (cmd), __s1_len
< 4) ? (__builtin_constant_p ("undefined") && ((size_t
)(const void *)(("undefined") + 1) - (size_t)(const void *)("undefined"
) == 1) ? __builtin_strcmp (cmd, "undefined") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("undefined"); int __result = (((const unsigned char
*) (const char *) (cmd))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (cmd))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (cmd))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (cmd))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("undefined") && ((size_t)(const void *)(("undefined"
) + 1) - (size_t)(const void *)("undefined") == 1) &&
(__s2_len = __builtin_strlen ("undefined"), __s2_len < 4)
? (__builtin_constant_p (cmd) && ((size_t)(const void
*)((cmd) + 1) - (size_t)(const void *)(cmd) == 1) ? __builtin_strcmp
(cmd, "undefined") : (- (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (cmd); int __result
= (((const unsigned char *) (const char *) ("undefined"))[0]
- __s2[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("undefined"))[1]
- __s2[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("undefined"))[2]
- __s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) ("undefined"))[3]
- __s2[3]); } } __result; })))) : __builtin_strcmp (cmd, "undefined"
)))); })
) {
3468 return SWITCH_STATUS_SUCCESS;
3469 }
3470
3471 return SWITCH_STATUS_FALSE;
3472
3473}
3474
3475#define START_SAMPLES32768 32768
3476
3477SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_insert_file(switch_core_session_t *session, const char *file, const char *insert_file, switch_size_t sample_point)
3478{
3479 switch_file_handle_t orig_fh = { 0 };
3480 switch_file_handle_t new_fh = { 0 };
3481 switch_codec_implementation_t read_impl = { 0 };
3482 char *tmp_file;
3483 switch_uuid_t uuid;
3484 char uuid_str[SWITCH_UUID_FORMATTED_LENGTH256 + 1];
3485 int16_t *abuf = NULL((void*)0);
3486 switch_size_t olen = 0;
3487 int asis = 0;
3488 switch_channel_t *channel = switch_core_session_get_channel(session);
3489 switch_size_t sample_count = 0;
3490 uint32_t pos = 0;
3491 char *ext;
3492
3493 switch_uuid_get(&uuid);
3494 switch_uuid_format(uuid_str, &uuid);
3495
3496 if ((ext = strrchr(file, '.'))) {
3497 ext++;
3498 } else {
3499 ext = "wav";
3500 }
3501
3502 tmp_file = switch_core_session_sprintf(session, "%s%smsg_%s.%s",
3503 SWITCH_GLOBAL_dirs.temp_dir, SWITCH_PATH_SEPARATOR"/", uuid_str, ext);
3504
3505 switch_core_session_get_read_impl(session, &read_impl);
3506
3507 new_fh.channels = read_impl.number_of_channels;
3508 new_fh.native_rate = read_impl.actual_samples_per_second;
3509
3510
3511 if (switch_core_file_open(&new_fh,switch_core_perform_file_open("src/switch_ivr.c", (const char
*)__func__, 3514, &new_fh, tmp_file, new_fh.channels, read_impl
.actual_samples_per_second, SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT
, ((void*)0))
3512 tmp_file,switch_core_perform_file_open("src/switch_ivr.c", (const char
*)__func__, 3514, &new_fh, tmp_file, new_fh.channels, read_impl
.actual_samples_per_second, SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT
, ((void*)0))
3513 new_fh.channels,switch_core_perform_file_open("src/switch_ivr.c", (const char
*)__func__, 3514, &new_fh, tmp_file, new_fh.channels, read_impl
.actual_samples_per_second, SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT
, ((void*)0))
3514 read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT, NULL)switch_core_perform_file_open("src/switch_ivr.c", (const char
*)__func__, 3514, &new_fh, tmp_file, new_fh.channels, read_impl
.actual_samples_per_second, SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT
, ((void*)0))
!= SWITCH_STATUS_SUCCESS) {
3515 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 3515, (const char*)(session)
, SWITCH_LOG_ERROR, "Failed to open file %s\n", tmp_file);
3516 goto end;
3517 }
3518
3519
3520 if (switch_core_file_open(&orig_fh,switch_core_perform_file_open("src/switch_ivr.c", (const char
*)__func__, 3523, &orig_fh, file, new_fh.channels, read_impl
.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT
, ((void*)0))
3521 file,switch_core_perform_file_open("src/switch_ivr.c", (const char
*)__func__, 3523, &orig_fh, file, new_fh.channels, read_impl
.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT
, ((void*)0))
3522 new_fh.channels,switch_core_perform_file_open("src/switch_ivr.c", (const char
*)__func__, 3523, &orig_fh, file, new_fh.channels, read_impl
.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT
, ((void*)0))
3523 read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL)switch_core_perform_file_open("src/switch_ivr.c", (const char
*)__func__, 3523, &orig_fh, file, new_fh.channels, read_impl
.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT
, ((void*)0))
!= SWITCH_STATUS_SUCCESS) {
3524 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 3524, (const char*)(session)
, SWITCH_LOG_ERROR, "Failed to open file %s\n", file);
3525 goto end;
3526 }
3527
3528
3529 switch_zmalloc(abuf, START_SAMPLES * sizeof(*abuf))(void)((((abuf = calloc(1, (32768 * sizeof(*abuf))))) ? (void
) (0) : __assert_fail ("(abuf = calloc(1, (32768 * sizeof(*abuf))))"
, "src/switch_ivr.c", 3529, __PRETTY_FUNCTION__)),abuf)
;
3530
3531 if (switch_test_flag((&orig_fh), SWITCH_FILE_NATIVE)(((&orig_fh))->flags & SWITCH_FILE_NATIVE)) {
3532 asis = 1;
3533 }
3534
3535 while (switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE)) {
3536 olen = START_SAMPLES32768;
3537
3538 if (!asis) {
3539 olen /= 2;
3540 }
3541
3542 if ((sample_count + olen) > sample_point) {
3543 olen = sample_point - sample_count;
3544 }
3545
3546 if (!olen || switch_core_file_read(&orig_fh, abuf, &olen) != SWITCH_STATUS_SUCCESS || !olen) {
3547 break;
3548 }
3549
3550 sample_count += olen;
3551
3552 switch_core_file_write(&new_fh, abuf, &olen);
3553 }
3554
3555 switch_core_file_close(&orig_fh);
3556
3557
3558 if (switch_core_file_open(&orig_fh,switch_core_perform_file_open("src/switch_ivr.c", (const char
*)__func__, 3561, &orig_fh, insert_file, new_fh.channels
, read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ |
SWITCH_FILE_DATA_SHORT, ((void*)0))
3559 insert_file,switch_core_perform_file_open("src/switch_ivr.c", (const char
*)__func__, 3561, &orig_fh, insert_file, new_fh.channels
, read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ |
SWITCH_FILE_DATA_SHORT, ((void*)0))
3560 new_fh.channels,switch_core_perform_file_open("src/switch_ivr.c", (const char
*)__func__, 3561, &orig_fh, insert_file, new_fh.channels
, read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ |
SWITCH_FILE_DATA_SHORT, ((void*)0))
3561 read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL)switch_core_perform_file_open("src/switch_ivr.c", (const char
*)__func__, 3561, &orig_fh, insert_file, new_fh.channels
, read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ |
SWITCH_FILE_DATA_SHORT, ((void*)0))
!= SWITCH_STATUS_SUCCESS) {
3562 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 3562, (const char*)(session)
, SWITCH_LOG_ERROR, "Failed to open file %s\n", file);
3563 goto end;
3564 }
3565
3566
3567 while (switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE)) {
3568 olen = START_SAMPLES32768;
3569
3570 if (!asis) {
3571 olen /= 2;
3572 }
3573
3574 if (switch_core_file_read(&orig_fh, abuf, &olen) != SWITCH_STATUS_SUCCESS || !olen) {
3575 break;
3576 }
3577
3578 sample_count += olen;
3579
3580 switch_core_file_write(&new_fh, abuf, &olen);
3581 }
3582
3583 switch_core_file_close(&orig_fh);
3584
3585 if (switch_core_file_open(&orig_fh,switch_core_perform_file_open("src/switch_ivr.c", (const char
*)__func__, 3588, &orig_fh, file, new_fh.channels, read_impl
.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT
, ((void*)0))
3586 file,switch_core_perform_file_open("src/switch_ivr.c", (const char
*)__func__, 3588, &orig_fh, file, new_fh.channels, read_impl
.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT
, ((void*)0))
3587 new_fh.channels,switch_core_perform_file_open("src/switch_ivr.c", (const char
*)__func__, 3588, &orig_fh, file, new_fh.channels, read_impl
.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT
, ((void*)0))
3588 read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL)switch_core_perform_file_open("src/switch_ivr.c", (const char
*)__func__, 3588, &orig_fh, file, new_fh.channels, read_impl
.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT
, ((void*)0))
!= SWITCH_STATUS_SUCCESS) {
3589 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *)
__func__, 3589, (const char*)(session)
, SWITCH_LOG_ERROR, "Failed to open file %s\n", file);
3590 goto end;
3591 }
3592
3593 pos = 0;
3594 switch_core_file_seek(&orig_fh, &pos, sample_point, SEEK_SET0);
3595
3596 while (switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE)) {
3597 olen = START_SAMPLES32768;
3598
3599 if (!asis) {
3600 olen /= 2;
3601 }
3602
3603 if (switch_core_file_read(&orig_fh, abuf, &olen) != SWITCH_STATUS_SUCCESS || !olen) {
3604 break;
3605 }
3606
3607 sample_count += olen;
3608
3609 switch_core_file_write(&new_fh, abuf, &olen);
3610 }
3611
3612 end:
3613
3614 if (switch_test_flag((&orig_fh), SWITCH_FILE_OPEN)(((&orig_fh))->flags & SWITCH_FILE_OPEN)) {
3615 switch_core_file_close(&orig_fh);
3616 }
3617
3618 if (switch_test_flag((&new_fh), SWITCH_FILE_OPEN)(((&new_fh))->flags & SWITCH_FILE_OPEN)) {
3619 switch_core_file_close(&new_fh);
3620 }
3621
3622 switch_file_rename(tmp_file, file, switch_core_session_get_pool(session));
3623 unlink(tmp_file);
3624
3625 switch_safe_free(abuf)if (abuf) {free(abuf);abuf=((void*)0);};
3626
3627 return SWITCH_STATUS_SUCCESS;
3628}
3629
3630
3631SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_create_message_reply(switch_event_t **reply, switch_event_t *message, const char *new_proto)
3632{
3633 switch_status_t status = SWITCH_STATUS_SUCCESS;
3634
3635 if ((status = switch_event_dup_reply(reply, message) != SWITCH_STATUS_SUCCESS)) {
3636 abort();
3637 }
3638
3639 switch_event_add_header_string(*reply, SWITCH_STACK_BOTTOM, "proto", new_proto);
3640
3641 return status;
3642}
3643
3644SWITCH_DECLARE(char *)__attribute__((visibility("default"))) char * switch_ivr_check_presence_mapping(const char *exten_name, const char *domain_name)
3645{
3646 char *cf = "presence_map.conf";
3647 switch_xml_t cfg, xml, x_domains, x_domain, x_exten;
3648 char *r = NULL((void*)0);
3649 switch_event_t *params = NULL((void*)0);
3650 switch_regex_t *re = NULL((void*)0);
3651 int proceed = 0, ovector[100];
3652
3653 switch_event_create(&params, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("src/switch_ivr.c", (const
char * )(const char *)__func__, 3653, &params, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
3654 switch_assert(params)((params) ? (void) (0) : __assert_fail ("params", "src/switch_ivr.c"
, 3654, __PRETTY_FUNCTION__))
;
3655
3656 if ( !zstr(domain_name)_zstr(domain_name) ) {
3657 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "domain", domain_name);
3658 }
3659
3660 if ( !zstr(exten_name)_zstr(exten_name) ) {
3661 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "exten", exten_name);
3662 }
3663
3664 if (!(xml = switch_xml_open_cfg(cf, &cfg, params))) {
3665 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_ivr.c", (const char *)__func__
, 3665, ((void*)0)
, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
3666 goto end;
3667 }
3668
3669 if (!(x_domains = switch_xml_child(cfg, "domains"))) {
3670 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_ivr.c", (const char *)__func__
, 3670, ((void*)0)
, SWITCH_LOG_ERROR, "Can't find any domains!\n");
3671 goto end;
3672 }
3673
3674 for (x_domain = switch_xml_child(x_domains, "domain"); x_domain; x_domain = x_domain->next) {
3675 const char *dname = switch_xml_attr(x_domain, "name");
3676 if (!dname || (strcasecmp(dname, "*") && strcasecmp(domain_name, dname))) continue;
3677
3678 for (x_exten = switch_xml_child(x_domain, "exten"); x_exten; x_exten = x_exten->next) {
3679 const char *regex = switch_xml_attr(x_exten, "regex");
3680 const char *proto = switch_xml_attr(x_exten, "proto");
3681
3682 if (!zstr(regex)_zstr(regex) && !zstr(proto)_zstr(proto)) {
3683 proceed = switch_regex_perform(exten_name, regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));
3684 switch_regex_safe_free(re)if (re) { switch_regex_free(re); re = ((void*)0); };
3685
3686 if (proceed) {
3687 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_ivr.c", (const char *)__func__
, 3687, ((void*)0)
, SWITCH_LOG_DEBUG1, "Mapping %s@%s to proto %s matching expression [%s]\n",
3688 exten_name, domain_name, proto, regex);
3689 r = strdup(proto)(__extension__ (__builtin_constant_p (proto) && ((size_t
)(const void *)((proto) + 1) - (size_t)(const void *)(proto) ==
1) ? (((const char *) (proto))[0] == '\0' ? (char *) calloc (
(size_t) 1, (size_t) 1) : ({ size_t __len = strlen (proto) + 1
; char *__retval = (char *) malloc (__len); if (__retval != (
(void*)0)) __retval = (char *) memcpy (__retval, proto, __len
); __retval; })) : __strdup (proto)))
;
3690 goto end;
3691 }
3692
3693 }
3694 }
3695 }
3696
3697 end:
3698 switch_event_destroy(&params);
3699
3700 if (xml) {
3701 switch_xml_free(xml);
3702 }
3703
3704 return r;
3705
3706}
3707
3708SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_kill_uuid(const char *uuid, switch_call_cause_t cause)
3709{
3710 switch_core_session_t *session;
3711
3712 if (zstr(uuid)_zstr(uuid) || !(session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "src/switch_ivr.c", (
const char *)__func__, 3712)
)) {
3713 return SWITCH_STATUS_FALSE;
3714 } else {
3715 switch_channel_t *channel = switch_core_session_get_channel(session);
3716 switch_channel_hangup(channel, cause)switch_channel_perform_hangup(channel, "src/switch_ivr.c", (const
char *)__func__, 3716, cause)
;
3717 switch_core_session_rwunlock(session);
3718 return SWITCH_STATUS_SUCCESS;
3719 }
3720}
3721
3722SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_blind_transfer_ack(switch_core_session_t *session, switch_bool_t success)
3723{
3724 switch_channel_t *channel = switch_core_session_get_channel(session);
3725 switch_status_t status = SWITCH_STATUS_FALSE;
3726
3727 if (switch_channel_test_flag(channel, CF_CONFIRM_BLIND_TRANSFER)) {
3728 switch_core_session_t *other_session;
3729 const char *uuid = switch_channel_get_variable(channel, "blind_transfer_uuid")switch_channel_get_variable_dup(channel, "blind_transfer_uuid"
, SWITCH_TRUE, -1)
;
3730
3731 switch_channel_clear_flag(channel, CF_CONFIRM_BLIND_TRANSFER);
3732
3733 if (!zstr(uuid)_zstr(uuid) && (other_session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "src/switch_ivr.c", (
const char *)__func__, 3733)
)) {
3734 switch_core_session_message_t msg = { 0 };
3735 msg.message_id = SWITCH_MESSAGE_INDICATE_BLIND_TRANSFER_RESPONSE;
3736 msg.from = __FILE__"src/switch_ivr.c";
3737 msg.numeric_arg = success;
3738 switch_core_session_receive_message(other_session, &msg)switch_core_session_perform_receive_message(other_session, &
msg, "src/switch_ivr.c", (const char *)__func__, 3738)
;
3739 switch_core_session_rwunlock(other_session);
3740 status = SWITCH_STATUS_SUCCESS;
3741 }
3742 }
3743
3744 return status;
3745
3746}
3747
3748/* For Emacs:
3749 * Local Variables:
3750 * mode:c
3751 * indent-tabs-mode:t
3752 * tab-width:4
3753 * c-basic-offset:4
3754 * End:
3755 * For VIM:
3756 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
3757 */