File: | src/switch_ivr.c |
Location: | line 921, column 4 |
Description: | Value stored to 'timeout' is never read |
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; |
Value stored to 'timeout' is never read | |
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 | */ |