File: | src/switch_ivr.c |
Location: | line 2629, column 6 |
Description: | Potential leak of memory pointed to by '__retval' |
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 | ||||
41 | SWITCH_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 | ||||
126 | SWITCH_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 | ||||
324 | static 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 | ||||
349 | static 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 | ||||
361 | SWITCH_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 | ||||
390 | SWITCH_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 | ||||
488 | SWITCH_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 | ||||
746 | SWITCH_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 | ||||
763 | SWITCH_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 | ||||
792 | SWITCH_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 | ||||
814 | SWITCH_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 | ||||
849 | SWITCH_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 | ||||
874 | SWITCH_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 | ||||
1154 | SWITCH_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 | ||||
1268 | SWITCH_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 | ||||
1429 | SWITCH_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 | ||||
1461 | SWITCH_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 | ||||
1473 | SWITCH_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 | ||||
1495 | SWITCH_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 | ||||
1528 | SWITCH_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 | ||||
1540 | SWITCH_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 | ||||
1640 | SWITCH_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 | ||||
1731 | SWITCH_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 | ||||
1869 | SWITCH_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 | ||||
1908 | struct 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 | ||||
1919 | struct switch_ivr_digit_stream { | |||
1920 | char *digits; | |||
1921 | switch_time_t last_digit_time; | |||
1922 | }; | |||
1923 | ||||
1924 | SWITCH_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 | ||||
1964 | SWITCH_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 | ||||
1982 | SWITCH_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 | ||||
1998 | SWITCH_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 | ||||
2012 | SWITCH_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 | ||||
2054 | SWITCH_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 | ||||
2069 | SWITCH_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 | ||||
2122 | SWITCH_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 | ||||
2135 | SWITCH_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 | ||||
2150 | SWITCH_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 ))) { | |||
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 ))) { | |||
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 ))) { | |||
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 ))) { | |||
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 ))) { | |||
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 | ||||
2255 | static 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 | ||||
2277 | SWITCH_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 | ||||
2301 | SWITCH_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 | ||||
2636 | static 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 | ||||
2653 | static 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 | ||||
2684 | SWITCH_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 | ||||
2913 | SWITCH_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 | ||||
2921 | SWITCH_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 | ||||
2978 | SWITCH_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, ¯os, 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 | ||||
3100 | SWITCH_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, ¯os, 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 | ||||
3207 | static 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 | ||||
3232 | SWITCH_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 | ||||
3287 | SWITCH_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 | ||||
3333 | SWITCH_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 | ||||
3346 | SWITCH_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 | ||||
3359 | SWITCH_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 | ||||
3477 | SWITCH_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 | ||||
3631 | SWITCH_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 | ||||
3644 | SWITCH_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(¶ms, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("src/switch_ivr.c", (const char * )(const char *)__func__, 3653, ¶ms, 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(¶ms); | |||
3699 | ||||
3700 | if (xml) { | |||
3701 | switch_xml_free(xml); | |||
3702 | } | |||
3703 | ||||
3704 | return r; | |||
3705 | ||||
3706 | } | |||
3707 | ||||
3708 | SWITCH_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 | ||||
3722 | SWITCH_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 | */ |