File: | src/switch_ivr.c |
Location: | line 2154, column 16 |
Description: | Potential leak of memory pointed to by '__retval' |
1 | /* | ||||||
2 | * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application | ||||||
3 | * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org> | ||||||
4 | * | ||||||
5 | * Version: MPL 1.1 | ||||||
6 | * | ||||||
7 | * The contents of this file are subject to the Mozilla Public License Version | ||||||
8 | * 1.1 (the "License"); you may not use this file except in compliance with | ||||||
9 | * the License. You may obtain a copy of the License at | ||||||
10 | * http://www.mozilla.org/MPL/ | ||||||
11 | * | ||||||
12 | * Software distributed under the License is distributed on an "AS IS" basis, | ||||||
13 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | ||||||
14 | * for the specific language governing rights and limitations under the | ||||||
15 | * License. | ||||||
16 | * | ||||||
17 | * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application | ||||||
18 | * | ||||||
19 | * The Initial Developer of the Original Code is | ||||||
20 | * Anthony Minessale II <anthm@freeswitch.org> | ||||||
21 | * Portions created by the Initial Developer are Copyright (C) | ||||||
22 | * the Initial Developer. All Rights Reserved. | ||||||
23 | * | ||||||
24 | * Contributor(s): | ||||||
25 | * | ||||||
26 | * Anthony Minessale II <anthm@freeswitch.org> | ||||||
27 | * Paul D. Tinsley <pdt at jackhammer.org> | ||||||
28 | * Neal Horman <neal at wanlink dot com> | ||||||
29 | * Matt Klein <mklein@nmedia.net> | ||||||
30 | * Michael Jerris <mike@jerris.com> | ||||||
31 | * Ken Rice <krice at suspicious dot org> | ||||||
32 | * Marc Olivier Chouinard <mochouinard@moctel.com> | ||||||
33 | * | ||||||
34 | * switch_ivr.c -- IVR Library | ||||||
35 | * | ||||||
36 | */ | ||||||
37 | |||||||
38 | #include <switch.h> | ||||||
39 | #include <switch_ivr.h> | ||||||
40 | |||||||
41 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_sound_test(switch_core_session_t *session) | ||||||
42 | { | ||||||
43 | |||||||
44 | switch_codec_implementation_t imp = { 0 }; | ||||||
45 | switch_codec_t codec = { 0 }; | ||||||
46 | int16_t peak = 0; | ||||||
47 | int16_t *data; | ||||||
48 | switch_frame_t *read_frame = NULL((void*)0); | ||||||
49 | uint32_t i; | ||||||
50 | switch_channel_t *channel = switch_core_session_get_channel(session); | ||||||
51 | switch_status_t status = SWITCH_STATUS_SUCCESS; | ||||||
52 | int64_t global_total = 0, global_sum = 0, period_sum = 0; | ||||||
53 | int period_total = 0; | ||||||
54 | int period_avg = 0, global_avg = 0; | ||||||
55 | int avg = 0; | ||||||
56 | int period_len; | ||||||
57 | |||||||
58 | switch_core_session_get_read_impl(session, &imp); | ||||||
59 | |||||||
60 | period_len = imp.actual_samples_per_second / imp.samples_per_packet; | ||||||
61 | |||||||
62 | if (switch_core_codec_init(&codec,switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.samples_per_second, imp.microseconds_per_packet / 1000 , imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , ((void*)0), switch_core_session_get_pool(session)) | ||||||
63 | "L16",switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.samples_per_second, imp.microseconds_per_packet / 1000 , imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , ((void*)0), switch_core_session_get_pool(session)) | ||||||
64 | NULL,switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.samples_per_second, imp.microseconds_per_packet / 1000 , imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , ((void*)0), switch_core_session_get_pool(session)) | ||||||
65 | imp.samples_per_second,switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.samples_per_second, imp.microseconds_per_packet / 1000 , imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , ((void*)0), switch_core_session_get_pool(session)) | ||||||
66 | imp.microseconds_per_packet / 1000,switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.samples_per_second, imp.microseconds_per_packet / 1000 , imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , ((void*)0), switch_core_session_get_pool(session)) | ||||||
67 | imp.number_of_channels,switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.samples_per_second, imp.microseconds_per_packet / 1000 , imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , ((void*)0), switch_core_session_get_pool(session)) | ||||||
68 | SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.samples_per_second, imp.microseconds_per_packet / 1000 , imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , ((void*)0), switch_core_session_get_pool(session)) | ||||||
69 | switch_core_session_get_pool(session))switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.samples_per_second, imp.microseconds_per_packet / 1000 , imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , ((void*)0), switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { | ||||||
70 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *) __func__, 70, (const char*)(session), SWITCH_LOG_ERROR, "Codec Error L16@%uhz %u channels %dms\n", | ||||||
71 | imp.samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000); | ||||||
72 | return SWITCH_STATUS_FALSE; | ||||||
73 | } | ||||||
74 | |||||||
75 | while (switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE)) { | ||||||
76 | status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); | ||||||
77 | |||||||
78 | if (!SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK || status == SWITCH_STATUS_INUSE)) { | ||||||
79 | break; | ||||||
80 | } | ||||||
81 | |||||||
82 | if (switch_test_flag(read_frame, SFF_CNG)((read_frame)->flags & SFF_CNG) || !read_frame->samples) { | ||||||
83 | continue; | ||||||
84 | } | ||||||
85 | |||||||
86 | |||||||
87 | data = (int16_t *) read_frame->data; | ||||||
88 | peak = 0; | ||||||
89 | avg = 0; | ||||||
90 | for (i = 0; i < read_frame->samples; i++) { | ||||||
91 | const int16_t s = (int16_t) abs(data[i]); | ||||||
92 | if (s > peak) { | ||||||
93 | peak = s; | ||||||
94 | } | ||||||
95 | avg += s; | ||||||
96 | } | ||||||
97 | |||||||
98 | avg /= read_frame->samples; | ||||||
99 | |||||||
100 | period_sum += peak; | ||||||
101 | global_sum += peak; | ||||||
102 | |||||||
103 | global_total++; | ||||||
104 | period_total++; | ||||||
105 | |||||||
106 | period_avg = (int) (period_sum / period_total); | ||||||
107 | |||||||
108 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *) __func__, 108, (const char*)(session), SWITCH_LOG_CONSOLE, | ||||||
109 | "\npacket_avg=%d packet_peak=%d period_avg=%d global_avg=%d\n\n", avg, peak, period_avg, global_avg); | ||||||
110 | |||||||
111 | if (period_total >= period_len) { | ||||||
112 | global_avg = (int) (global_sum / global_total); | ||||||
113 | period_total = 0; | ||||||
114 | period_sum = 0; | ||||||
115 | } | ||||||
116 | |||||||
117 | } | ||||||
118 | |||||||
119 | |||||||
120 | switch_core_codec_destroy(&codec); | ||||||
121 | |||||||
122 | return SWITCH_STATUS_SUCCESS; | ||||||
123 | |||||||
124 | } | ||||||
125 | |||||||
126 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_sleep(switch_core_session_t *session, uint32_t ms, switch_bool_t sync, switch_input_args_t *args) | ||||||
127 | { | ||||||
128 | switch_channel_t *channel = switch_core_session_get_channel(session); | ||||||
129 | switch_status_t status = SWITCH_STATUS_SUCCESS; | ||||||
130 | switch_time_t start = switch_micro_time_now(), now, done = switch_micro_time_now() + (ms * 1000); | ||||||
131 | switch_frame_t *read_frame, cng_frame = { 0 }; | ||||||
132 | int32_t left; | ||||||
133 | uint32_t elapsed; | ||||||
134 | char data[2] = ""; | ||||||
135 | |||||||
136 | switch_frame_t write_frame = { 0 }; | ||||||
137 | unsigned char *abuf = NULL((void*)0); | ||||||
138 | switch_codec_implementation_t imp = { 0 }; | ||||||
139 | switch_codec_t codec = { 0 }; | ||||||
140 | int sval = 0; | ||||||
141 | const char *var; | ||||||
142 | |||||||
143 | arg_recursion_check_start(args)if (args) { if (args->loops >= 25) { switch_log_printf( SWITCH_CHANNEL_ID_LOG, "src/switch_ivr.c", (const char *)__func__ , 143, ((void*)0), SWITCH_LOG_ERROR, "RECURSION ERROR! It's not the best idea to call things that collect input recursively from an input callback.\n" ); return SWITCH_STATUS_GENERR; } else {args->loops++;} }; | ||||||
144 | |||||||
145 | switch_core_session_get_read_impl(session, &imp); | ||||||
146 | |||||||
147 | /* | ||||||
148 | if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND && !switch_channel_test_flag(channel, CF_PROXY_MODE) && | ||||||
149 | !switch_channel_media_ready(channel) && !switch_channel_test_flag(channel, CF_SERVICE)) { | ||||||
150 | if ((status = switch_channel_pre_answer(channel)) != SWITCH_STATUS_SUCCESS) { | ||||||
151 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot establish media.\n"); | ||||||
152 | return SWITCH_STATUS_FALSE; | ||||||
153 | } | ||||||
154 | } | ||||||
155 | */ | ||||||
156 | |||||||
157 | if (!switch_channel_media_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_TRUE)) { | ||||||
158 | |||||||
159 | for (elapsed=0; switch_channel_up(channel)(switch_channel_check_signal(channel, SWITCH_TRUE) || switch_channel_get_state (channel) < CS_HANGUP) && elapsed<(ms/20); elapsed++) { | ||||||
160 | if (switch_channel_test_flag(channel, CF_BREAK)) { | ||||||
161 | switch_channel_clear_flag(channel, CF_BREAK); | ||||||
162 | switch_goto_status(SWITCH_STATUS_BREAK, end)status = SWITCH_STATUS_BREAK; goto end; | ||||||
163 | } | ||||||
164 | |||||||
165 | switch_yield(20 * 1000)switch_sleep(20 * 1000);; | ||||||
166 | } | ||||||
167 | switch_goto_status(SWITCH_STATUS_SUCCESS, end)status = SWITCH_STATUS_SUCCESS; goto end; | ||||||
168 | } | ||||||
169 | |||||||
170 | if ((var = switch_channel_get_variable(channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE)switch_channel_get_variable_dup(channel, "send_silence_when_idle" , SWITCH_TRUE, -1)) | ||||||
171 | && (sval = atoi(var))) { | ||||||
172 | SWITCH_IVR_VERIFY_SILENCE_DIVISOR(sval){ if ((sval) <= 0 && (sval) != -1) { sval = 400; } }; | ||||||
173 | } | ||||||
174 | |||||||
175 | if (ms > 10 && sval) { | ||||||
176 | |||||||
177 | if (switch_core_codec_init(&codec,switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.actual_samples_per_second, imp.microseconds_per_packet / 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool (session)) | ||||||
178 | "L16",switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.actual_samples_per_second, imp.microseconds_per_packet / 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool (session)) | ||||||
179 | NULL,switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.actual_samples_per_second, imp.microseconds_per_packet / 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool (session)) | ||||||
180 | imp.actual_samples_per_second,switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.actual_samples_per_second, imp.microseconds_per_packet / 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool (session)) | ||||||
181 | imp.microseconds_per_packet / 1000,switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.actual_samples_per_second, imp.microseconds_per_packet / 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool (session)) | ||||||
182 | imp.number_of_channels,switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.actual_samples_per_second, imp.microseconds_per_packet / 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool (session)) | ||||||
183 | SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.actual_samples_per_second, imp.microseconds_per_packet / 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool (session)) | ||||||
184 | switch_core_session_get_pool(session))switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.actual_samples_per_second, imp.microseconds_per_packet / 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool (session)) != SWITCH_STATUS_SUCCESS) { | ||||||
185 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *) __func__, 185, (const char*)(session), SWITCH_LOG_ERROR, "Codec Error L16@%uhz %u channels %dms\n", | ||||||
186 | imp.actual_samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000); | ||||||
187 | switch_goto_status(SWITCH_STATUS_FALSE, end)status = SWITCH_STATUS_FALSE; goto end; | ||||||
188 | } | ||||||
189 | |||||||
190 | |||||||
191 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *) __func__, 191, (const char*)(session), SWITCH_LOG_DEBUG, "Codec Activated L16@%uhz %u channels %dms\n", | ||||||
192 | imp.actual_samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000); | ||||||
193 | |||||||
194 | write_frame.codec = &codec; | ||||||
195 | switch_zmalloc(abuf, SWITCH_RECOMMENDED_BUFFER_SIZE)(void)((((abuf = calloc(1, (8192)))) ? (void) (0) : __assert_fail ("(abuf = calloc(1, (8192)))", "src/switch_ivr.c", 195, __PRETTY_FUNCTION__ )),abuf); | ||||||
196 | write_frame.data = abuf; | ||||||
197 | write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE8192; | ||||||
198 | write_frame.datalen = imp.decoded_bytes_per_packet; | ||||||
199 | write_frame.samples = write_frame.datalen / sizeof(int16_t); | ||||||
200 | |||||||
201 | } | ||||||
202 | |||||||
203 | if (!write_frame.datalen) { | ||||||
204 | sval = 0; | ||||||
205 | } | ||||||
206 | |||||||
207 | cng_frame.data = data; | ||||||
208 | cng_frame.datalen = 2; | ||||||
209 | cng_frame.buflen = 2; | ||||||
210 | switch_set_flag((&cng_frame), SFF_CNG)((&cng_frame))->flags |= (SFF_CNG); | ||||||
211 | |||||||
212 | if (sync) { | ||||||
213 | switch_channel_audio_sync(channel)switch_channel_perform_audio_sync(channel, "src/switch_ivr.c" , (const char *)__func__, 213); | ||||||
214 | } | ||||||
215 | |||||||
216 | if (!ms) { | ||||||
217 | switch_goto_status(SWITCH_STATUS_SUCCESS, end)status = SWITCH_STATUS_SUCCESS; goto end; | ||||||
218 | } | ||||||
219 | |||||||
220 | for (;;) { | ||||||
221 | now = switch_micro_time_now(); | ||||||
222 | elapsed = (int32_t) ((now - start) / 1000); | ||||||
223 | left = ms - elapsed; | ||||||
224 | |||||||
225 | if (!switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE)) { | ||||||
226 | status = SWITCH_STATUS_FALSE; | ||||||
227 | break; | ||||||
228 | } | ||||||
229 | |||||||
230 | if (switch_channel_test_flag(channel, CF_BREAK)) { | ||||||
231 | switch_channel_clear_flag(channel, CF_BREAK); | ||||||
232 | status = SWITCH_STATUS_BREAK; | ||||||
233 | break; | ||||||
234 | } | ||||||
235 | |||||||
236 | if (now > done || left <= 0) { | ||||||
237 | break; | ||||||
238 | } | ||||||
239 | |||||||
240 | |||||||
241 | switch_ivr_parse_all_events(session); | ||||||
242 | |||||||
243 | |||||||
244 | if (args) { | ||||||
245 | switch_dtmf_t dtmf = {0}; | ||||||
246 | |||||||
247 | /* | ||||||
248 | dtmf handler function you can hook up to be executed when a digit is dialed during playback | ||||||
249 | if you return anything but SWITCH_STATUS_SUCCESS the playback will stop. | ||||||
250 | */ | ||||||
251 | if (switch_channel_has_dtmf(channel)) { | ||||||
252 | if (!args->input_callback && !args->buf && !args->dmachine) { | ||||||
253 | status = SWITCH_STATUS_BREAK; | ||||||
254 | break; | ||||||
255 | } | ||||||
256 | switch_channel_dequeue_dtmf(channel, &dtmf); | ||||||
257 | |||||||
258 | if (args->dmachine) { | ||||||
259 | char ds[2] = {dtmf.digit, '\0'}; | ||||||
260 | if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL((void*)0))) != SWITCH_STATUS_SUCCESS) { | ||||||
261 | break; | ||||||
262 | } | ||||||
263 | } | ||||||
264 | |||||||
265 | if (args->input_callback) { | ||||||
266 | status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen); | ||||||
267 | } else if (args->buf) { | ||||||
268 | *((char *) args->buf) = dtmf.digit; | ||||||
269 | status = SWITCH_STATUS_BREAK; | ||||||
270 | } | ||||||
271 | } | ||||||
272 | |||||||
273 | if (args->input_callback) { | ||||||
274 | switch_event_t *event = NULL((void*)0); | ||||||
275 | |||||||
276 | if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { | ||||||
277 | switch_status_t ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen); | ||||||
278 | if (ostatus != SWITCH_STATUS_SUCCESS) { | ||||||
279 | status = ostatus; | ||||||
280 | } | ||||||
281 | switch_event_destroy(&event); | ||||||
282 | } | ||||||
283 | } | ||||||
284 | |||||||
285 | if (status != SWITCH_STATUS_SUCCESS) { | ||||||
286 | break; | ||||||
287 | } | ||||||
288 | } | ||||||
289 | |||||||
290 | status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); | ||||||
291 | |||||||
292 | if (!SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK || status == SWITCH_STATUS_INUSE)) { | ||||||
293 | break; | ||||||
294 | } | ||||||
295 | |||||||
296 | if (args && args->dmachine) { | ||||||
297 | if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL((void*)0))) != SWITCH_STATUS_SUCCESS) { | ||||||
298 | break; | ||||||
299 | } | ||||||
300 | } | ||||||
301 | |||||||
302 | if (sval && write_frame.datalen) { | ||||||
303 | switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.samples, imp.number_of_channels, sval); | ||||||
304 | switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0); | ||||||
305 | } else { | ||||||
306 | switch_core_session_write_frame(session, &cng_frame, SWITCH_IO_FLAG_NONE, 0); | ||||||
307 | } | ||||||
308 | } | ||||||
309 | |||||||
310 | |||||||
311 | end: | ||||||
312 | |||||||
313 | arg_recursion_check_stop(args)if (args) args->loops--; | ||||||
314 | |||||||
315 | if (write_frame.codec) { | ||||||
316 | switch_core_codec_destroy(&codec); | ||||||
317 | } | ||||||
318 | |||||||
319 | switch_safe_free(abuf)if (abuf) {free(abuf);abuf=((void*)0);}; | ||||||
320 | |||||||
321 | return status; | ||||||
322 | } | ||||||
323 | |||||||
324 | static void *SWITCH_THREAD_FUNC unicast_thread_run(switch_thread_t *thread, void *obj) | ||||||
325 | { | ||||||
326 | switch_unicast_conninfo_t *conninfo = (switch_unicast_conninfo_t *) obj; | ||||||
327 | switch_size_t len; | ||||||
328 | |||||||
329 | if (!conninfo) { | ||||||
330 | return NULL((void*)0); | ||||||
331 | } | ||||||
332 | |||||||
333 | while (switch_test_flag(conninfo, SUF_READY)((conninfo)->flags & SUF_READY) && switch_test_flag(conninfo, SUF_THREAD_RUNNING)((conninfo)->flags & SUF_THREAD_RUNNING)) { | ||||||
334 | len = conninfo->write_frame.buflen; | ||||||
335 | if (switch_socket_recv(conninfo->socket, conninfo->write_frame.data, &len) != SWITCH_STATUS_SUCCESS || len == 0) { | ||||||
336 | break; | ||||||
337 | } | ||||||
338 | conninfo->write_frame.datalen = (uint32_t) len; | ||||||
339 | conninfo->write_frame.samples = conninfo->write_frame.datalen / 2; | ||||||
340 | switch_core_session_write_frame(conninfo->session, &conninfo->write_frame, SWITCH_IO_FLAG_NONE, conninfo->stream_id); | ||||||
341 | } | ||||||
342 | |||||||
343 | switch_clear_flag_locked(conninfo, SUF_READY)switch_mutex_lock(conninfo->flag_mutex); (conninfo)->flags &= ~(SUF_READY); switch_mutex_unlock(conninfo->flag_mutex );; | ||||||
344 | switch_clear_flag_locked(conninfo, SUF_THREAD_RUNNING)switch_mutex_lock(conninfo->flag_mutex); (conninfo)->flags &= ~(SUF_THREAD_RUNNING); switch_mutex_unlock(conninfo-> flag_mutex);; | ||||||
345 | |||||||
346 | return NULL((void*)0); | ||||||
347 | } | ||||||
348 | |||||||
349 | static void unicast_thread_launch(switch_unicast_conninfo_t *conninfo) | ||||||
350 | { | ||||||
351 | switch_thread_t *thread; | ||||||
352 | switch_threadattr_t *thd_attr = NULL((void*)0); | ||||||
353 | |||||||
354 | switch_threadattr_create(&thd_attr, switch_core_session_get_pool(conninfo->session)); | ||||||
355 | switch_threadattr_detach_set(thd_attr, 1); | ||||||
356 | switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024); | ||||||
357 | switch_set_flag_locked(conninfo, SUF_THREAD_RUNNING)((conninfo->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("conninfo->flag_mutex != ((void*)0)", "src/switch_ivr.c" , 357, __PRETTY_FUNCTION__));switch_mutex_lock(conninfo->flag_mutex );(conninfo)->flags |= (SUF_THREAD_RUNNING);switch_mutex_unlock (conninfo->flag_mutex);; | ||||||
358 | switch_thread_create(&thread, thd_attr, unicast_thread_run, conninfo, switch_core_session_get_pool(conninfo->session)); | ||||||
359 | } | ||||||
360 | |||||||
361 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_deactivate_unicast(switch_core_session_t *session) | ||||||
362 | { | ||||||
363 | switch_channel_t *channel = switch_core_session_get_channel(session); | ||||||
364 | switch_unicast_conninfo_t *conninfo; | ||||||
365 | int sanity = 0; | ||||||
366 | |||||||
367 | if (!switch_channel_test_flag(channel, CF_UNICAST)) { | ||||||
368 | return SWITCH_STATUS_FALSE; | ||||||
369 | } | ||||||
370 | |||||||
371 | if ((conninfo = switch_channel_get_private(channel, "unicast"))) { | ||||||
372 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *) __func__, 372, (const char*)(session), SWITCH_LOG_DEBUG, "Shutting down unicast connection\n"); | ||||||
373 | switch_clear_flag_locked(conninfo, SUF_READY)switch_mutex_lock(conninfo->flag_mutex); (conninfo)->flags &= ~(SUF_READY); switch_mutex_unlock(conninfo->flag_mutex );; | ||||||
374 | switch_socket_shutdown(conninfo->socket, SWITCH_SHUTDOWN_READWRITE); | ||||||
375 | while (switch_test_flag(conninfo, SUF_THREAD_RUNNING)((conninfo)->flags & SUF_THREAD_RUNNING)) { | ||||||
376 | switch_yield(10000)switch_sleep(10000);; | ||||||
377 | if (++sanity >= 10000) { | ||||||
378 | break; | ||||||
379 | } | ||||||
380 | } | ||||||
381 | if (switch_core_codec_ready(&conninfo->read_codec)) { | ||||||
382 | switch_core_codec_destroy(&conninfo->read_codec); | ||||||
383 | } | ||||||
384 | switch_socket_close(conninfo->socket); | ||||||
385 | } | ||||||
386 | switch_channel_clear_flag(channel, CF_UNICAST); | ||||||
387 | return SWITCH_STATUS_SUCCESS; | ||||||
388 | } | ||||||
389 | |||||||
390 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_activate_unicast(switch_core_session_t *session, | ||||||
391 | char *local_ip, | ||||||
392 | switch_port_t local_port, | ||||||
393 | char *remote_ip, switch_port_t remote_port, char *transport, char *flags) | ||||||
394 | { | ||||||
395 | switch_channel_t *channel = switch_core_session_get_channel(session); | ||||||
396 | switch_unicast_conninfo_t *conninfo = switch_core_session_alloc(session, sizeof(*conninfo))switch_core_perform_session_alloc(session, sizeof(*conninfo), "src/switch_ivr.c", (const char *)__func__, 396); | ||||||
397 | switch_codec_t *read_codec; | ||||||
398 | |||||||
399 | switch_assert(conninfo != NULL)((conninfo != ((void*)0)) ? (void) (0) : __assert_fail ("conninfo != ((void*)0)" , "src/switch_ivr.c", 399, __PRETTY_FUNCTION__)); | ||||||
400 | |||||||
401 | conninfo->local_ip = switch_core_session_strdup(session, local_ip)switch_core_perform_session_strdup(session, local_ip, "src/switch_ivr.c" , (const char *)__func__, 401); | ||||||
402 | conninfo->local_port = local_port; | ||||||
403 | |||||||
404 | conninfo->remote_ip = switch_core_session_strdup(session, remote_ip)switch_core_perform_session_strdup(session, remote_ip, "src/switch_ivr.c" , (const char *)__func__, 404); | ||||||
405 | conninfo->remote_port = remote_port; | ||||||
406 | conninfo->session = session; | ||||||
407 | |||||||
408 | if (!strcasecmp(transport, "udp")) { | ||||||
409 | conninfo->type = AF_INET2; | ||||||
410 | conninfo->transport = SOCK_DGRAMSOCK_DGRAM; | ||||||
411 | } else if (!strcasecmp(transport, "tcp")) { | ||||||
412 | conninfo->type = AF_INET2; | ||||||
413 | conninfo->transport = SOCK_STREAMSOCK_STREAM; | ||||||
414 | } else { | ||||||
415 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *) __func__, 415, (const char*)(session), SWITCH_LOG_ERROR, "Invalid transport %s\n", transport); | ||||||
416 | goto fail; | ||||||
417 | } | ||||||
418 | |||||||
419 | if (flags) { | ||||||
420 | if (strstr(flags, "native")) { | ||||||
421 | switch_set_flag(conninfo, SUF_NATIVE)(conninfo)->flags |= (SUF_NATIVE); | ||||||
422 | } | ||||||
423 | } | ||||||
424 | |||||||
425 | switch_mutex_init(&conninfo->flag_mutex, SWITCH_MUTEX_NESTED0x1, switch_core_session_get_pool(session)); | ||||||
426 | |||||||
427 | read_codec = switch_core_session_get_read_codec(session); | ||||||
428 | |||||||
429 | if (!switch_test_flag(conninfo, SUF_NATIVE)((conninfo)->flags & SUF_NATIVE)) { | ||||||
430 | if (switch_core_codec_init(&conninfo->read_codec,switch_core_codec_init_with_bitrate(&conninfo->read_codec , "L16", ((void*)0), read_codec->implementation->actual_samples_per_second , read_codec->implementation->microseconds_per_packet / 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , ((void*)0), switch_core_session_get_pool(session)) | ||||||
431 | "L16",switch_core_codec_init_with_bitrate(&conninfo->read_codec , "L16", ((void*)0), read_codec->implementation->actual_samples_per_second , read_codec->implementation->microseconds_per_packet / 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , ((void*)0), switch_core_session_get_pool(session)) | ||||||
432 | NULL,switch_core_codec_init_with_bitrate(&conninfo->read_codec , "L16", ((void*)0), read_codec->implementation->actual_samples_per_second , read_codec->implementation->microseconds_per_packet / 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , ((void*)0), switch_core_session_get_pool(session)) | ||||||
433 | read_codec->implementation->actual_samples_per_second,switch_core_codec_init_with_bitrate(&conninfo->read_codec , "L16", ((void*)0), read_codec->implementation->actual_samples_per_second , read_codec->implementation->microseconds_per_packet / 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , ((void*)0), switch_core_session_get_pool(session)) | ||||||
434 | read_codec->implementation->microseconds_per_packet / 1000,switch_core_codec_init_with_bitrate(&conninfo->read_codec , "L16", ((void*)0), read_codec->implementation->actual_samples_per_second , read_codec->implementation->microseconds_per_packet / 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , ((void*)0), switch_core_session_get_pool(session)) | ||||||
435 | 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,switch_core_codec_init_with_bitrate(&conninfo->read_codec , "L16", ((void*)0), read_codec->implementation->actual_samples_per_second , read_codec->implementation->microseconds_per_packet / 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , ((void*)0), switch_core_session_get_pool(session)) | ||||||
436 | NULL, switch_core_session_get_pool(session))switch_core_codec_init_with_bitrate(&conninfo->read_codec , "L16", ((void*)0), read_codec->implementation->actual_samples_per_second , read_codec->implementation->microseconds_per_packet / 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , ((void*)0), switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) { | ||||||
437 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *) __func__, 437, (const char*)(session), SWITCH_LOG_DEBUG, | ||||||
438 | "Raw Codec Activation Success L16@%uhz 1 channel %dms\n", | ||||||
439 | read_codec->implementation->actual_samples_per_second, read_codec->implementation->microseconds_per_packet / 1000); | ||||||
440 | } else { | ||||||
441 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *) __func__, 441, (const char*)(session), SWITCH_LOG_DEBUG, "Raw Codec Activation Failed L16@%uhz 1 channel %dms\n", | ||||||
442 | read_codec->implementation->actual_samples_per_second, read_codec->implementation->microseconds_per_packet / 1000); | ||||||
443 | goto fail; | ||||||
444 | } | ||||||
445 | } | ||||||
446 | |||||||
447 | conninfo->write_frame.data = conninfo->write_frame_data; | ||||||
448 | conninfo->write_frame.buflen = sizeof(conninfo->write_frame_data); | ||||||
449 | conninfo->write_frame.codec = switch_test_flag(conninfo, SUF_NATIVE)((conninfo)->flags & SUF_NATIVE) ? read_codec : &conninfo->read_codec; | ||||||
450 | |||||||
451 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *) __func__, 451, (const char*)(session), SWITCH_LOG_DEBUG, "connect %s:%d->%s:%d\n", | ||||||
452 | conninfo->local_ip, conninfo->local_port, conninfo->remote_ip, conninfo->remote_port); | ||||||
453 | |||||||
454 | if (switch_sockaddr_info_get(&conninfo->local_addr, | ||||||
455 | conninfo->local_ip, SWITCH_UNSPEC0, conninfo->local_port, 0, | ||||||
456 | switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { | ||||||
457 | goto fail; | ||||||
458 | } | ||||||
459 | |||||||
460 | if (switch_sockaddr_info_get(&conninfo->remote_addr, | ||||||
461 | conninfo->remote_ip, SWITCH_UNSPEC0, conninfo->remote_port, 0, | ||||||
462 | switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { | ||||||
463 | goto fail; | ||||||
464 | } | ||||||
465 | |||||||
466 | if (switch_socket_create(&conninfo->socket, AF_INET2, SOCK_DGRAMSOCK_DGRAM, 0, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) { | ||||||
467 | if (switch_socket_bind(conninfo->socket, conninfo->local_addr) != SWITCH_STATUS_SUCCESS) { | ||||||
468 | goto fail; | ||||||
469 | } | ||||||
470 | } else { | ||||||
471 | goto fail; | ||||||
472 | } | ||||||
473 | |||||||
474 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *) __func__, 474, (const char*)(session), SWITCH_LOG_INFO, "Created unicast connection %s:%d->%s:%d\n", | ||||||
475 | conninfo->local_ip, conninfo->local_port, conninfo->remote_ip, conninfo->remote_port); | ||||||
476 | switch_channel_set_private(channel, "unicast", conninfo); | ||||||
477 | switch_channel_set_flag(channel, CF_UNICAST)switch_channel_set_flag_value(channel, CF_UNICAST, 1); | ||||||
478 | switch_set_flag_locked(conninfo, SUF_READY)((conninfo->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("conninfo->flag_mutex != ((void*)0)", "src/switch_ivr.c" , 478, __PRETTY_FUNCTION__));switch_mutex_lock(conninfo->flag_mutex );(conninfo)->flags |= (SUF_READY);switch_mutex_unlock(conninfo ->flag_mutex);; | ||||||
479 | return SWITCH_STATUS_SUCCESS; | ||||||
480 | |||||||
481 | fail: | ||||||
482 | |||||||
483 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *) __func__, 483, (const char*)(session), SWITCH_LOG_CRIT, "Failure creating unicast connection %s:%d->%s:%d\n", | ||||||
484 | conninfo->local_ip, conninfo->local_port, conninfo->remote_ip, conninfo->remote_port); | ||||||
485 | return SWITCH_STATUS_FALSE; | ||||||
486 | } | ||||||
487 | |||||||
488 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_parse_event(switch_core_session_t *session, switch_event_t *event) | ||||||
489 | { | ||||||
490 | switch_channel_t *channel = switch_core_session_get_channel(session); | ||||||
491 | char *cmd = switch_event_get_header(event, "call-command")switch_event_get_header_idx(event, "call-command", -1); | ||||||
492 | unsigned long cmd_hash; | ||||||
493 | switch_ssize_t hlen = -1; | ||||||
494 | unsigned long CMD_EXECUTE = switch_hashfunc_default("execute", &hlen); | ||||||
495 | unsigned long CMD_HANGUP = switch_hashfunc_default("hangup", &hlen); | ||||||
496 | unsigned long CMD_NOMEDIA = switch_hashfunc_default("nomedia", &hlen); | ||||||
497 | unsigned long CMD_UNICAST = switch_hashfunc_default("unicast", &hlen); | ||||||
498 | unsigned long CMD_XFEREXT = switch_hashfunc_default("xferext", &hlen); | ||||||
499 | char *lead_frames = switch_event_get_header(event, "lead-frames")switch_event_get_header_idx(event, "lead-frames", -1); | ||||||
500 | char *event_lock = switch_event_get_header(event, "event-lock")switch_event_get_header_idx(event, "event-lock", -1); | ||||||
501 | char *event_lock_pri = switch_event_get_header(event, "event-lock-pri")switch_event_get_header_idx(event, "event-lock-pri", -1); | ||||||
502 | switch_status_t status = SWITCH_STATUS_FALSE; | ||||||
503 | int el = 0, elp = 0; | ||||||
504 | |||||||
505 | if (zstr(cmd)_zstr(cmd)) { | ||||||
506 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *) __func__, 506, (const char*)(session), SWITCH_LOG_ERROR, "Invalid Command!\n"); | ||||||
507 | return SWITCH_STATUS_FALSE; | ||||||
508 | } | ||||||
509 | |||||||
510 | cmd_hash = switch_hashfunc_default(cmd, &hlen); | ||||||
511 | |||||||
512 | switch_channel_set_flag_recursive(channel, CF_EVENT_PARSE); | ||||||
513 | |||||||
514 | if (switch_true(event_lock)) { | ||||||
515 | switch_channel_set_flag_recursive(channel, CF_EVENT_LOCK); | ||||||
516 | el = 1; | ||||||
517 | } | ||||||
518 | |||||||
519 | if (switch_true(event_lock_pri)) { | ||||||
520 | switch_channel_set_flag_recursive(channel, CF_EVENT_LOCK_PRI); | ||||||
521 | elp = 1; | ||||||
522 | } | ||||||
523 | |||||||
524 | if (lead_frames) { | ||||||
525 | switch_frame_t *read_frame; | ||||||
526 | int frame_count = atoi(lead_frames); | ||||||
527 | int max_frames = frame_count * 2; | ||||||
528 | |||||||
529 | while (frame_count > 0 && --max_frames > 0) { | ||||||
530 | status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); | ||||||
531 | if (!SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK || status == SWITCH_STATUS_INUSE)) { | ||||||
532 | goto done; | ||||||
533 | } | ||||||
534 | if (!switch_test_flag(read_frame, SFF_CNG)((read_frame)->flags & SFF_CNG)) { | ||||||
535 | frame_count--; | ||||||
536 | } | ||||||
537 | } | ||||||
538 | } | ||||||
539 | |||||||
540 | if (cmd_hash == CMD_EXECUTE) { | ||||||
541 | char *app_name = switch_event_get_header(event, "execute-app-name")switch_event_get_header_idx(event, "execute-app-name", -1); | ||||||
542 | char *event_uuid = switch_event_get_header(event, "event-uuid")switch_event_get_header_idx(event, "event-uuid", -1); | ||||||
543 | char *app_arg = switch_event_get_header(event, "execute-app-arg")switch_event_get_header_idx(event, "execute-app-arg", -1); | ||||||
544 | char *content_type = switch_event_get_header(event, "content-type")switch_event_get_header_idx(event, "content-type", -1); | ||||||
545 | char *loop_h = switch_event_get_header(event, "loops")switch_event_get_header_idx(event, "loops", -1); | ||||||
546 | char *hold_bleg = switch_event_get_header(event, "hold-bleg")switch_event_get_header_idx(event, "hold-bleg", -1); | ||||||
547 | int loops = 1; | ||||||
548 | int inner = 0; | ||||||
549 | |||||||
550 | if (zstr(app_arg)_zstr(app_arg) && !zstr(content_type)_zstr(content_type) && !strcasecmp(content_type, "text/plain")) { | ||||||
551 | app_arg = switch_event_get_body(event); | ||||||
552 | } | ||||||
553 | |||||||
554 | if (loop_h) { | ||||||
555 | loops = atoi(loop_h); | ||||||
556 | } | ||||||
557 | |||||||
558 | if (app_name) { | ||||||
559 | int x; | ||||||
560 | const char *b_uuid = NULL((void*)0); | ||||||
561 | switch_core_session_t *b_session = NULL((void*)0); | ||||||
562 | |||||||
563 | switch_channel_clear_flag(channel, CF_STOP_BROADCAST); | ||||||
564 | |||||||
565 | if (!switch_channel_test_flag(channel, CF_BRIDGED) || switch_channel_test_flag(channel, CF_BROADCAST)) { | ||||||
566 | inner++; | ||||||
567 | hold_bleg = NULL((void*)0); | ||||||
568 | } | ||||||
569 | |||||||
570 | if (!switch_channel_test_flag(channel, CF_BROADCAST)) { | ||||||
571 | switch_channel_set_flag(channel, CF_BROADCAST)switch_channel_set_flag_value(channel, CF_BROADCAST, 1); | ||||||
572 | if (inner) { | ||||||
573 | inner--; | ||||||
574 | } | ||||||
575 | } | ||||||
576 | |||||||
577 | if (hold_bleg && switch_true(hold_bleg)) { | ||||||
578 | if ((b_uuid = switch_channel_get_partner_uuid(channel))) { | ||||||
579 | const char *stream; | ||||||
580 | b_uuid = switch_core_session_strdup(session, b_uuid)switch_core_perform_session_strdup(session, b_uuid, "src/switch_ivr.c" , (const char *)__func__, 580); | ||||||
581 | |||||||
582 | if (!(stream = switch_channel_get_hold_music_partner(channel))) { | ||||||
583 | stream = switch_channel_get_hold_music(channel); | ||||||
584 | } | ||||||
585 | |||||||
586 | if (stream && switch_is_moh(stream)) { | ||||||
587 | if ((b_session = switch_core_session_locate(b_uuid)switch_core_session_perform_locate(b_uuid, "src/switch_ivr.c" , (const char *)__func__, 587))) { | ||||||
588 | switch_channel_t *b_channel = switch_core_session_get_channel(b_session); | ||||||
589 | switch_status_t st; | ||||||
590 | |||||||
591 | switch_ivr_broadcast(b_uuid, stream, SMF_ECHO_ALEG | SMF_LOOP); | ||||||
592 | st = switch_channel_wait_for_flag(b_channel, CF_BROADCAST, SWITCH_TRUE, 5000, NULL((void*)0)); | ||||||
593 | if (st != SWITCH_STATUS_SUCCESS && | ||||||
594 | switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE) && switch_channel_ready(b_channel)switch_channel_test_ready(b_channel, SWITCH_TRUE, SWITCH_FALSE ) && !switch_channel_test_flag(b_channel, CF_BROADCAST)) { | ||||||
595 | switch_core_session_kill_channel(b_session, SWITCH_SIG_BREAK)switch_core_session_perform_kill_channel(b_session, "src/switch_ivr.c" , (const char *)__func__, 595, SWITCH_SIG_BREAK); | ||||||
596 | st = switch_channel_wait_for_flag(b_channel, CF_BROADCAST, SWITCH_TRUE, 5000, NULL((void*)0)); | ||||||
597 | |||||||
598 | if (st != SWITCH_STATUS_SUCCESS && | ||||||
599 | switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE) && switch_channel_ready(b_channel)switch_channel_test_ready(b_channel, SWITCH_TRUE, SWITCH_FALSE ) && !switch_channel_test_flag(b_channel, CF_BROADCAST)) { | ||||||
600 | switch_core_session_flush_private_events(b_session); | ||||||
601 | } | ||||||
602 | } | ||||||
603 | switch_core_session_rwunlock(b_session); | ||||||
604 | } | ||||||
605 | } else { | ||||||
606 | b_uuid = NULL((void*)0); | ||||||
607 | } | ||||||
608 | } | ||||||
609 | } | ||||||
610 | |||||||
611 | for (x = 0; x < loops || loops < 0; x++) { | ||||||
612 | switch_time_t b4, aftr; | ||||||
613 | |||||||
614 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *) __func__, 614, (const char*)(session), SWITCH_LOG_DEBUG, "%s Command Execute %s(%s)\n", | ||||||
615 | switch_channel_get_name(channel), app_name, switch_str_nil(app_arg)(app_arg ? app_arg : "")); | ||||||
616 | b4 = switch_micro_time_now(); | ||||||
617 | |||||||
618 | if (event_uuid) { | ||||||
619 | switch_channel_set_variable(channel, "app_uuid", event_uuid)switch_channel_set_variable_var_check(channel, "app_uuid", event_uuid , SWITCH_TRUE); | ||||||
620 | } | ||||||
621 | |||||||
622 | switch_channel_set_variable_printf(channel, "current_loop", "%d", x + 1); | ||||||
623 | switch_channel_set_variable_printf(channel, "total_loops", "%d", loops); | ||||||
624 | |||||||
625 | if (switch_core_session_execute_application(session, app_name, app_arg)switch_core_session_execute_application_get_flags(session, app_name , app_arg, ((void*)0)) != SWITCH_STATUS_SUCCESS) { | ||||||
626 | if (!inner || switch_channel_test_flag(channel, CF_STOP_BROADCAST)) switch_channel_clear_flag(channel, CF_BROADCAST); | ||||||
627 | break; | ||||||
628 | } | ||||||
629 | |||||||
630 | aftr = switch_micro_time_now(); | ||||||
631 | if (!switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE) || switch_channel_test_flag(channel, CF_STOP_BROADCAST) || aftr - b4 < 500000) { | ||||||
632 | break; | ||||||
633 | } | ||||||
634 | } | ||||||
635 | |||||||
636 | switch_channel_set_variable(channel, "current_loop", NULL)switch_channel_set_variable_var_check(channel, "current_loop" , ((void*)0), SWITCH_TRUE); | ||||||
637 | switch_channel_set_variable(channel, "total_loops", NULL)switch_channel_set_variable_var_check(channel, "total_loops", ((void*)0), SWITCH_TRUE); | ||||||
638 | |||||||
639 | if (b_uuid) { | ||||||
640 | if ((b_session = switch_core_session_locate(b_uuid)switch_core_session_perform_locate(b_uuid, "src/switch_ivr.c" , (const char *)__func__, 640))) { | ||||||
641 | switch_channel_t *b_channel = switch_core_session_get_channel(b_session); | ||||||
642 | switch_channel_stop_broadcast(b_channel)for(;;) {if (switch_channel_test_flag(b_channel, CF_BROADCAST )) {switch_channel_set_flag_value(b_channel, CF_STOP_BROADCAST , 1); switch_channel_set_flag_value(b_channel, CF_BREAK, 1); } break;}; | ||||||
643 | switch_channel_wait_for_flag(b_channel, CF_BROADCAST, SWITCH_FALSE, 5000, NULL((void*)0)); | ||||||
644 | switch_core_session_rwunlock(b_session); | ||||||
645 | } | ||||||
646 | } | ||||||
647 | |||||||
648 | if (!inner) { | ||||||
649 | switch_channel_clear_flag(channel, CF_BROADCAST); | ||||||
650 | } | ||||||
651 | |||||||
652 | if (switch_channel_test_flag(channel, CF_STOP_BROADCAST)) { | ||||||
653 | switch_channel_clear_flag(channel, CF_BROADCAST); | ||||||
654 | switch_channel_set_flag(channel, CF_BREAK)switch_channel_set_flag_value(channel, CF_BREAK, 1); | ||||||
655 | } | ||||||
656 | |||||||
657 | switch_channel_audio_sync(channel)switch_channel_perform_audio_sync(channel, "src/switch_ivr.c" , (const char *)__func__, 657); | ||||||
658 | } | ||||||
659 | } else if (cmd_hash == CMD_UNICAST) { | ||||||
660 | char *local_ip = switch_event_get_header(event, "local-ip")switch_event_get_header_idx(event, "local-ip", -1); | ||||||
661 | char *local_port = switch_event_get_header(event, "local-port")switch_event_get_header_idx(event, "local-port", -1); | ||||||
662 | char *remote_ip = switch_event_get_header(event, "remote-ip")switch_event_get_header_idx(event, "remote-ip", -1); | ||||||
663 | char *remote_port = switch_event_get_header(event, "remote-port")switch_event_get_header_idx(event, "remote-port", -1); | ||||||
664 | char *transport = switch_event_get_header(event, "transport")switch_event_get_header_idx(event, "transport", -1); | ||||||
665 | char *flags = switch_event_get_header(event, "flags")switch_event_get_header_idx(event, "flags", -1); | ||||||
666 | |||||||
667 | if (zstr(local_ip)_zstr(local_ip)) { | ||||||
668 | local_ip = "127.0.0.1"; | ||||||
669 | } | ||||||
670 | if (zstr(remote_ip)_zstr(remote_ip)) { | ||||||
671 | remote_ip = "127.0.0.1"; | ||||||
672 | } | ||||||
673 | if (zstr(local_port)_zstr(local_port)) { | ||||||
674 | local_port = "8025"; | ||||||
675 | } | ||||||
676 | if (zstr(remote_port)_zstr(remote_port)) { | ||||||
677 | remote_port = "8026"; | ||||||
678 | } | ||||||
679 | if (zstr(transport)_zstr(transport)) { | ||||||
680 | transport = "udp"; | ||||||
681 | } | ||||||
682 | |||||||
683 | switch_ivr_activate_unicast(session, local_ip, (switch_port_t) atoi(local_port), remote_ip, (switch_port_t) atoi(remote_port), transport, flags); | ||||||
684 | |||||||
685 | } else if (cmd_hash == CMD_XFEREXT) { | ||||||
686 | switch_event_header_t *hp; | ||||||
687 | switch_caller_extension_t *extension = NULL((void*)0); | ||||||
688 | |||||||
689 | |||||||
690 | if ((extension = switch_caller_extension_new(session, "xferext", "xferext")) == 0) { | ||||||
691 | abort(); | ||||||
692 | } | ||||||
693 | |||||||
694 | for (hp = event->headers; hp; hp = hp->next) { | ||||||
695 | char *app; | ||||||
696 | char *data; | ||||||
697 | |||||||
698 | if (!strcasecmp(hp->name, "application")) { | ||||||
699 | app = strdup(hp->value)(__extension__ (__builtin_constant_p (hp->value) && ((size_t)(const void *)((hp->value) + 1) - (size_t)(const void *)(hp->value) == 1) ? (((const char *) (hp->value ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (hp->value) + 1; char *__retval = ( char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, hp->value, __len); __retval; } )) : __strdup (hp->value))); | ||||||
700 | if (app) { | ||||||
701 | data = strchr(app, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p (app) && (' ') == '\0' ? (char *) __rawmemchr (app, ' ' ) : __builtin_strchr (app, ' '))); | ||||||
702 | |||||||
703 | if (data) { | ||||||
704 | *data++ = '\0'; | ||||||
705 | } | ||||||
706 | |||||||
707 | switch_caller_extension_add_application(session, extension, app, data); | ||||||
708 | free(app); | ||||||
709 | } | ||||||
710 | } | ||||||
711 | } | ||||||
712 | |||||||
713 | switch_channel_transfer_to_extension(channel, extension); | ||||||
714 | |||||||
715 | } else if (cmd_hash == CMD_HANGUP) { | ||||||
716 | char *cause_name = switch_event_get_header(event, "hangup-cause")switch_event_get_header_idx(event, "hangup-cause", -1); | ||||||
717 | switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING; | ||||||
718 | |||||||
719 | if (cause_name) { | ||||||
720 | cause = switch_channel_str2cause(cause_name); | ||||||
721 | } | ||||||
722 | |||||||
723 | switch_channel_hangup(channel, cause)switch_channel_perform_hangup(channel, "src/switch_ivr.c", (const char *)__func__, 723, cause); | ||||||
724 | } else if (cmd_hash == CMD_NOMEDIA) { | ||||||
725 | char *uuid = switch_event_get_header(event, "nomedia-uuid")switch_event_get_header_idx(event, "nomedia-uuid", -1); | ||||||
726 | switch_ivr_nomedia(uuid, SMF_REBRIDGE); | ||||||
727 | } | ||||||
728 | |||||||
729 | status = SWITCH_STATUS_SUCCESS; | ||||||
730 | |||||||
731 | done: | ||||||
732 | |||||||
733 | switch_channel_clear_flag_recursive(channel, CF_EVENT_PARSE); | ||||||
734 | |||||||
735 | if (el) { | ||||||
736 | switch_channel_clear_flag_recursive(channel, CF_EVENT_LOCK); | ||||||
737 | } | ||||||
738 | |||||||
739 | if (elp) { | ||||||
740 | switch_channel_clear_flag_recursive(channel, CF_EVENT_LOCK_PRI); | ||||||
741 | } | ||||||
742 | |||||||
743 | return switch_channel_test_flag(channel, CF_BREAK) ? SWITCH_STATUS_BREAK : status; | ||||||
744 | } | ||||||
745 | |||||||
746 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_parse_next_event(switch_core_session_t *session) | ||||||
747 | { | ||||||
748 | switch_event_t *event; | ||||||
749 | switch_status_t status = SWITCH_STATUS_FALSE; | ||||||
750 | |||||||
751 | if (switch_core_session_dequeue_private_event(session, &event) == SWITCH_STATUS_SUCCESS) { | ||||||
752 | status = switch_ivr_parse_event(session, event); | ||||||
753 | event->event_id = SWITCH_EVENT_PRIVATE_COMMAND; | ||||||
754 | switch_event_prep_for_delivery(event)switch_event_prep_for_delivery_detailed("src/switch_ivr.c", ( const char * )(const char *)__func__, 754, event); | ||||||
755 | switch_channel_event_set_data(switch_core_session_get_channel(session), event); | ||||||
756 | switch_event_fire(&event)switch_event_fire_detailed("src/switch_ivr.c", (const char * ) (const char *)__func__, 756, &event, ((void*)0)); | ||||||
757 | } | ||||||
758 | |||||||
759 | return status; | ||||||
760 | |||||||
761 | } | ||||||
762 | |||||||
763 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_process_indications(switch_core_session_t *session, switch_core_session_message_t *message) | ||||||
764 | { | ||||||
765 | switch_status_t status = SWITCH_STATUS_SUCCESS; | ||||||
766 | switch_channel_t *channel = switch_core_session_get_channel(session); | ||||||
767 | |||||||
768 | switch(message->message_id) { | ||||||
769 | case SWITCH_MESSAGE_INDICATE_ANSWER: | ||||||
770 | if (switch_channel_answer(channel)switch_channel_perform_answer(channel, "src/switch_ivr.c", (const char *)__func__, 770) != SWITCH_STATUS_SUCCESS) { | ||||||
771 | switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "src/switch_ivr.c", (const char *)__func__, 771, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); | ||||||
772 | } | ||||||
773 | break; | ||||||
774 | case SWITCH_MESSAGE_INDICATE_PROGRESS: | ||||||
775 | if (switch_channel_pre_answer(channel)switch_channel_perform_pre_answer(channel, "src/switch_ivr.c" , (const char *)__func__, 775) != SWITCH_STATUS_SUCCESS) { | ||||||
776 | switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "src/switch_ivr.c", (const char *)__func__, 776, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); | ||||||
777 | } | ||||||
778 | break; | ||||||
779 | case SWITCH_MESSAGE_INDICATE_RINGING: | ||||||
780 | if (switch_channel_ring_ready(channel)switch_channel_perform_ring_ready_value(channel, SWITCH_RING_READY_RINGING , "src/switch_ivr.c", (const char *)__func__, 780) != SWITCH_STATUS_SUCCESS) { | ||||||
781 | switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "src/switch_ivr.c", (const char *)__func__, 781, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); | ||||||
782 | } | ||||||
783 | break; | ||||||
784 | default: | ||||||
785 | status = SWITCH_STATUS_FALSE; | ||||||
786 | break; | ||||||
787 | } | ||||||
788 | |||||||
789 | return status; | ||||||
790 | } | ||||||
791 | |||||||
792 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_parse_all_messages(switch_core_session_t *session) | ||||||
793 | { | ||||||
794 | switch_core_session_message_t *message; | ||||||
795 | int i = 0; | ||||||
796 | |||||||
797 | switch_ivr_parse_all_signal_data(session); | ||||||
798 | |||||||
799 | while (switch_core_session_dequeue_message(session, &message) == SWITCH_STATUS_SUCCESS) { | ||||||
800 | i++; | ||||||
801 | |||||||
802 | if (switch_ivr_process_indications(session, message) == SWITCH_STATUS_SUCCESS) { | ||||||
803 | switch_core_session_free_message(&message); | ||||||
804 | } else { | ||||||
805 | switch_core_session_receive_message(session, message)switch_core_session_perform_receive_message(session, message, "src/switch_ivr.c", (const char *)__func__, 805); | ||||||
806 | message = NULL((void*)0); | ||||||
807 | } | ||||||
808 | } | ||||||
809 | |||||||
810 | return i ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; | ||||||
811 | } | ||||||
812 | |||||||
813 | |||||||
814 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_parse_all_signal_data(switch_core_session_t *session) | ||||||
815 | { | ||||||
816 | void *data; | ||||||
817 | switch_core_session_message_t msg = { 0 }; | ||||||
818 | int i = 0; | ||||||
819 | switch_channel_t *channel = switch_core_session_get_channel(session); | ||||||
820 | |||||||
821 | if (!switch_core_session_in_thread(session)) { | ||||||
822 | return SWITCH_STATUS_FALSE; | ||||||
823 | } | ||||||
824 | |||||||
825 | if (switch_channel_test_flag(channel, CF_SIGNAL_DATA)) { | ||||||
826 | return SWITCH_STATUS_FALSE; | ||||||
827 | } | ||||||
828 | |||||||
829 | switch_channel_set_flag(channel, CF_SIGNAL_DATA)switch_channel_set_flag_value(channel, CF_SIGNAL_DATA, 1); | ||||||
830 | |||||||
831 | msg.message_id = SWITCH_MESSAGE_INDICATE_SIGNAL_DATA; | ||||||
832 | msg.from = __FILE__"src/switch_ivr.c"; | ||||||
833 | |||||||
834 | while (switch_core_session_dequeue_signal_data(session, &data) == SWITCH_STATUS_SUCCESS) { | ||||||
835 | i++; | ||||||
836 | |||||||
837 | msg.pointer_arg = data; | ||||||
838 | switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg , "src/switch_ivr.c", (const char *)__func__, 838); | ||||||
839 | |||||||
840 | data = NULL((void*)0); | ||||||
841 | |||||||
842 | } | ||||||
843 | |||||||
844 | switch_channel_clear_flag(channel, CF_SIGNAL_DATA); | ||||||
845 | |||||||
846 | return i ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; | ||||||
847 | } | ||||||
848 | |||||||
849 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_parse_all_events(switch_core_session_t *session) | ||||||
850 | { | ||||||
851 | int x = 0; | ||||||
852 | switch_channel_t *channel; | ||||||
853 | |||||||
854 | switch_ivr_parse_all_messages(session); | ||||||
855 | |||||||
856 | channel = switch_core_session_get_channel(session); | ||||||
857 | |||||||
858 | if (!switch_channel_test_flag(channel, CF_PROXY_MODE) && switch_channel_test_flag(channel, CF_BLOCK_BROADCAST_UNTIL_MEDIA)) { | ||||||
859 | if (switch_channel_media_up(channel)(switch_channel_test_flag(channel, CF_ANSWERED) || switch_channel_test_flag (channel, CF_EARLY_MEDIA))) { | ||||||
860 | switch_channel_clear_flag(channel, CF_BLOCK_BROADCAST_UNTIL_MEDIA); | ||||||
861 | } else { | ||||||
862 | return SWITCH_STATUS_SUCCESS; | ||||||
863 | } | ||||||
864 | } | ||||||
865 | |||||||
866 | while (switch_ivr_parse_next_event(session) == SWITCH_STATUS_SUCCESS) { | ||||||
867 | x++; | ||||||
868 | } | ||||||
869 | |||||||
870 | return SWITCH_STATUS_SUCCESS; | ||||||
871 | } | ||||||
872 | |||||||
873 | |||||||
874 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_park(switch_core_session_t *session, switch_input_args_t *args) | ||||||
875 | { | ||||||
876 | switch_status_t status = SWITCH_STATUS_SUCCESS; | ||||||
877 | switch_channel_t *channel = switch_core_session_get_channel(session); | ||||||
878 | switch_frame_t *read_frame = NULL((void*)0); | ||||||
879 | int stream_id = 0; | ||||||
880 | switch_event_t *event; | ||||||
881 | switch_unicast_conninfo_t *conninfo = NULL((void*)0); | ||||||
882 | uint32_t rate = 0; | ||||||
883 | uint32_t bpf = 0; | ||||||
884 | const char *to; | ||||||
885 | int timeout = 0; | ||||||
886 | time_t expires = 0; | ||||||
887 | switch_codec_implementation_t read_impl = { 0 }; | ||||||
888 | switch_call_cause_t timeout_cause = SWITCH_CAUSE_NORMAL_CLEARING; | ||||||
889 | switch_codec_t codec = { 0 }; | ||||||
890 | int sval = 0; | ||||||
891 | const char *var; | ||||||
892 | switch_frame_t write_frame = { 0 }; | ||||||
893 | unsigned char *abuf = NULL((void*)0); | ||||||
894 | switch_codec_implementation_t imp = { 0 }; | ||||||
895 | |||||||
896 | |||||||
897 | |||||||
898 | if (switch_channel_test_flag(channel, CF_RECOVERED) && switch_channel_test_flag(channel, CF_CONTROLLED)) { | ||||||
899 | switch_channel_clear_flag(channel, CF_CONTROLLED); | ||||||
900 | } | ||||||
901 | |||||||
902 | if (switch_channel_test_flag(channel, CF_CONTROLLED)) { | ||||||
903 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *) __func__, 903, (const char*)(session), SWITCH_LOG_ERROR, "Cannot park channels that are under control already.\n"); | ||||||
904 | return SWITCH_STATUS_FALSE; | ||||||
905 | } | ||||||
906 | |||||||
907 | if (switch_channel_get_state(channel) == CS_RESET) { | ||||||
908 | return SWITCH_STATUS_FALSE; | ||||||
909 | } | ||||||
910 | |||||||
911 | arg_recursion_check_start(args)if (args) { if (args->loops >= 25) { switch_log_printf( SWITCH_CHANNEL_ID_LOG, "src/switch_ivr.c", (const char *)__func__ , 911, ((void*)0), SWITCH_LOG_ERROR, "RECURSION ERROR! It's not the best idea to call things that collect input recursively from an input callback.\n" ); return SWITCH_STATUS_GENERR; } else {args->loops++;} }; | ||||||
912 | |||||||
913 | if ((to = switch_channel_get_variable(channel, "park_timeout")switch_channel_get_variable_dup(channel, "park_timeout", SWITCH_TRUE , -1))) { | ||||||
914 | char *cause_str; | ||||||
915 | |||||||
916 | if ((cause_str = strchr(to, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p (to) && (':') == '\0' ? (char *) __rawmemchr (to, ':' ) : __builtin_strchr (to, ':'))))) { | ||||||
917 | timeout_cause = switch_channel_str2cause(cause_str + 1); | ||||||
918 | } | ||||||
919 | |||||||
920 | if ((timeout = atoi(to)) < 0) { | ||||||
921 | timeout = 0; | ||||||
922 | } else { | ||||||
923 | expires = switch_epoch_time_now(NULL((void*)0)) + timeout; | ||||||
924 | } | ||||||
925 | switch_channel_set_variable(channel, "park_timeout", NULL)switch_channel_set_variable_var_check(channel, "park_timeout" , ((void*)0), SWITCH_TRUE); | ||||||
926 | switch_channel_set_variable(channel, SWITCH_PARK_AFTER_BRIDGE_VARIABLE, NULL)switch_channel_set_variable_var_check(channel, "park_after_bridge" , ((void*)0), SWITCH_TRUE); | ||||||
927 | } | ||||||
928 | |||||||
929 | switch_channel_set_flag(channel, CF_CONTROLLED)switch_channel_set_flag_value(channel, CF_CONTROLLED, 1); | ||||||
930 | switch_channel_set_flag(channel, CF_PARK)switch_channel_set_flag_value(channel, CF_PARK, 1); | ||||||
931 | |||||||
932 | if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_PARK)switch_event_create_subclass_detailed("src/switch_ivr.c", (const char * )(const char *)__func__, 932, &event, SWITCH_EVENT_CHANNEL_PARK , ((void*)0)) == SWITCH_STATUS_SUCCESS) { | ||||||
933 | switch_channel_event_set_data(channel, event); | ||||||
934 | switch_event_fire(&event)switch_event_fire_detailed("src/switch_ivr.c", (const char * ) (const char *)__func__, 934, &event, ((void*)0)); | ||||||
935 | } | ||||||
936 | |||||||
937 | while (switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE) && switch_channel_test_flag(channel, CF_CONTROLLED) && switch_channel_test_flag(channel, CF_PARK)) { | ||||||
938 | |||||||
939 | if (!rate && switch_channel_media_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_TRUE)) { | ||||||
940 | switch_core_session_get_read_impl(session, &read_impl); | ||||||
941 | rate = read_impl.actual_samples_per_second; | ||||||
942 | bpf = read_impl.decoded_bytes_per_packet; | ||||||
943 | |||||||
944 | if ((var = switch_channel_get_variable(channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE)switch_channel_get_variable_dup(channel, "send_silence_when_idle" , SWITCH_TRUE, -1)) && (sval = atoi(var))) { | ||||||
945 | switch_core_session_get_read_impl(session, &imp); | ||||||
946 | |||||||
947 | if (switch_core_codec_init(&codec,switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.actual_samples_per_second, imp.microseconds_per_packet / 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool (session)) | ||||||
948 | "L16",switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.actual_samples_per_second, imp.microseconds_per_packet / 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool (session)) | ||||||
949 | NULL,switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.actual_samples_per_second, imp.microseconds_per_packet / 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool (session)) | ||||||
950 | imp.actual_samples_per_second,switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.actual_samples_per_second, imp.microseconds_per_packet / 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool (session)) | ||||||
951 | imp.microseconds_per_packet / 1000,switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.actual_samples_per_second, imp.microseconds_per_packet / 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool (session)) | ||||||
952 | imp.number_of_channels,switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.actual_samples_per_second, imp.microseconds_per_packet / 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool (session)) | ||||||
953 | SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.actual_samples_per_second, imp.microseconds_per_packet / 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool (session)) | ||||||
954 | switch_core_session_get_pool(session))switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.actual_samples_per_second, imp.microseconds_per_packet / 1000, imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool (session)) != SWITCH_STATUS_SUCCESS) { | ||||||
955 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *) __func__, 955, (const char*)(session), SWITCH_LOG_ERROR, "Codec Error L16@%uhz %u channels %dms\n", | ||||||
956 | imp.samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000); | ||||||
957 | switch_goto_status(SWITCH_STATUS_FALSE, end)status = SWITCH_STATUS_FALSE; goto end; | ||||||
958 | } | ||||||
959 | |||||||
960 | |||||||
961 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *) __func__, 961, (const char*)(session), SWITCH_LOG_DEBUG, "Codec Activated L16@%uhz %u channels %dms\n", | ||||||
962 | imp.samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000); | ||||||
963 | |||||||
964 | write_frame.codec = &codec; | ||||||
965 | switch_zmalloc(abuf, SWITCH_RECOMMENDED_BUFFER_SIZE)(void)((((abuf = calloc(1, (8192)))) ? (void) (0) : __assert_fail ("(abuf = calloc(1, (8192)))", "src/switch_ivr.c", 965, __PRETTY_FUNCTION__ )),abuf); | ||||||
966 | write_frame.data = abuf; | ||||||
967 | write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE8192; | ||||||
968 | write_frame.datalen = imp.decoded_bytes_per_packet; | ||||||
969 | write_frame.samples = write_frame.datalen / sizeof(int16_t); | ||||||
970 | } | ||||||
971 | } | ||||||
972 | |||||||
973 | if (rate) { | ||||||
974 | if (switch_channel_test_flag(channel, CF_SERVICE)) { | ||||||
975 | switch_cond_next(); | ||||||
976 | status = SWITCH_STATUS_SUCCESS; | ||||||
977 | } else { | ||||||
978 | status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, stream_id); | ||||||
979 | } | ||||||
980 | } else { | ||||||
981 | switch_yield(20000)switch_sleep(20000);; | ||||||
982 | |||||||
983 | if (switch_core_session_dequeue_private_event(session, &event) == SWITCH_STATUS_SUCCESS) { | ||||||
984 | switch_ivr_parse_event(session, event); | ||||||
985 | switch_event_destroy(&event); | ||||||
986 | } | ||||||
987 | |||||||
988 | status = SWITCH_STATUS_SUCCESS; | ||||||
989 | } | ||||||
990 | |||||||
991 | if (!SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK || status == SWITCH_STATUS_INUSE)) { | ||||||
992 | break; | ||||||
993 | } | ||||||
994 | |||||||
995 | if (rate && write_frame.data && sval) { | ||||||
996 | switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.samples, read_impl.number_of_channels, sval); | ||||||
997 | switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0); | ||||||
998 | } | ||||||
999 | |||||||
1000 | if (expires && switch_epoch_time_now(NULL((void*)0)) >= expires) { | ||||||
1001 | switch_channel_hangup(channel, timeout_cause)switch_channel_perform_hangup(channel, "src/switch_ivr.c", (const char *)__func__, 1001, timeout_cause); | ||||||
1002 | break; | ||||||
1003 | } | ||||||
1004 | |||||||
1005 | if (switch_channel_test_flag(channel, CF_UNICAST)) { | ||||||
1006 | if (!switch_channel_media_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_TRUE)) { | ||||||
1007 | if (switch_channel_pre_answer(channel)switch_channel_perform_pre_answer(channel, "src/switch_ivr.c" , (const char *)__func__, 1007) != SWITCH_STATUS_SUCCESS) { | ||||||
1008 | switch_goto_status(SWITCH_STATUS_FALSE, end)status = SWITCH_STATUS_FALSE; goto end; | ||||||
1009 | } | ||||||
1010 | } | ||||||
1011 | |||||||
1012 | if (!conninfo) { | ||||||
1013 | if (!(conninfo = switch_channel_get_private(channel, "unicast"))) { | ||||||
1014 | switch_channel_clear_flag(channel, CF_UNICAST); | ||||||
1015 | } | ||||||
1016 | |||||||
1017 | if (conninfo) { | ||||||
1018 | unicast_thread_launch(conninfo); | ||||||
1019 | } | ||||||
1020 | } | ||||||
1021 | |||||||
1022 | if (conninfo) { | ||||||
1023 | switch_size_t len = 0; | ||||||
1024 | uint32_t flags = 0; | ||||||
1025 | switch_byte_t decoded[SWITCH_RECOMMENDED_BUFFER_SIZE8192]; | ||||||
1026 | uint32_t dlen = sizeof(decoded); | ||||||
1027 | switch_status_t tstatus; | ||||||
1028 | switch_byte_t *sendbuf = NULL((void*)0); | ||||||
1029 | uint32_t sendlen = 0; | ||||||
1030 | |||||||
1031 | switch_assert(read_frame)((read_frame) ? (void) (0) : __assert_fail ("read_frame", "src/switch_ivr.c" , 1031, __PRETTY_FUNCTION__)); | ||||||
1032 | |||||||
1033 | if (switch_test_flag(read_frame, SFF_CNG)((read_frame)->flags & SFF_CNG)) { | ||||||
1034 | sendlen = bpf; | ||||||
1035 | switch_assert(sendlen <= SWITCH_RECOMMENDED_BUFFER_SIZE)((sendlen <= 8192) ? (void) (0) : __assert_fail ("sendlen <= 8192" , "src/switch_ivr.c", 1035, __PRETTY_FUNCTION__)); | ||||||
1036 | memset(decoded, 255, sendlen); | ||||||
1037 | sendbuf = decoded; | ||||||
1038 | tstatus = SWITCH_STATUS_SUCCESS; | ||||||
1039 | } else { | ||||||
1040 | if (switch_test_flag(conninfo, SUF_NATIVE)((conninfo)->flags & SUF_NATIVE)) { | ||||||
1041 | tstatus = SWITCH_STATUS_NOOP; | ||||||
1042 | } else { | ||||||
1043 | switch_codec_t *read_codec = switch_core_session_get_read_codec(session); | ||||||
1044 | tstatus = switch_core_codec_decode(read_codec, | ||||||
1045 | &conninfo->read_codec, | ||||||
1046 | read_frame->data, | ||||||
1047 | read_frame->datalen, read_impl.actual_samples_per_second, decoded, &dlen, &rate, &flags); | ||||||
1048 | } | ||||||
1049 | switch (tstatus) { | ||||||
1050 | case SWITCH_STATUS_NOOP: | ||||||
1051 | case SWITCH_STATUS_BREAK: | ||||||
1052 | sendbuf = read_frame->data; | ||||||
1053 | sendlen = read_frame->datalen; | ||||||
1054 | tstatus = SWITCH_STATUS_SUCCESS; | ||||||
1055 | break; | ||||||
1056 | case SWITCH_STATUS_SUCCESS: | ||||||
1057 | sendbuf = decoded; | ||||||
1058 | sendlen = dlen; | ||||||
1059 | tstatus = SWITCH_STATUS_SUCCESS; | ||||||
1060 | break; | ||||||
1061 | default: | ||||||
1062 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *) __func__, 1062, (const char*)(session), SWITCH_LOG_NOTICE, "Codec Error\n"); | ||||||
1063 | switch_ivr_deactivate_unicast(session); | ||||||
1064 | break; | ||||||
1065 | } | ||||||
1066 | } | ||||||
1067 | |||||||
1068 | if (tstatus == SWITCH_STATUS_SUCCESS) { | ||||||
1069 | len = sendlen; | ||||||
1070 | if (switch_socket_sendto(conninfo->socket, conninfo->remote_addr, 0, (void *) sendbuf, &len) != SWITCH_STATUS_SUCCESS) { | ||||||
1071 | switch_ivr_deactivate_unicast(session); | ||||||
1072 | } | ||||||
1073 | } | ||||||
1074 | } | ||||||
1075 | } | ||||||
1076 | |||||||
1077 | switch_ivr_parse_all_events(session); | ||||||
1078 | |||||||
1079 | |||||||
1080 | if (switch_channel_has_dtmf(channel)) { | ||||||
1081 | switch_dtmf_t dtmf = { 0 }; | ||||||
1082 | |||||||
1083 | if (args && !args->input_callback && !args->buf && !args->dmachine) { | ||||||
1084 | status = SWITCH_STATUS_BREAK; | ||||||
1085 | break; | ||||||
1086 | } | ||||||
1087 | |||||||
1088 | switch_channel_dequeue_dtmf(channel, &dtmf); | ||||||
1089 | |||||||
1090 | if (args) { | ||||||
1091 | if (args->dmachine) { | ||||||
1092 | char ds[2] = {dtmf.digit, '\0'}; | ||||||
1093 | if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL((void*)0))) != SWITCH_STATUS_SUCCESS) { | ||||||
1094 | break; | ||||||
1095 | } | ||||||
1096 | } | ||||||
1097 | |||||||
1098 | if (args->input_callback) { | ||||||
1099 | if ((status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen)) != SWITCH_STATUS_SUCCESS) { | ||||||
1100 | break; | ||||||
1101 | } | ||||||
1102 | } | ||||||
1103 | } | ||||||
1104 | } | ||||||
1105 | |||||||
1106 | if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { | ||||||
1107 | if (args && args->input_callback) { | ||||||
1108 | switch_status_t ostatus; | ||||||
1109 | |||||||
1110 | if ((ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen)) != SWITCH_STATUS_SUCCESS) { | ||||||
1111 | status = ostatus; | ||||||
1112 | break; | ||||||
1113 | } | ||||||
1114 | } else { | ||||||
1115 | switch_channel_event_set_data(channel, event); | ||||||
1116 | switch_event_fire(&event)switch_event_fire_detailed("src/switch_ivr.c", (const char * ) (const char *)__func__, 1116, &event, ((void*)0)); | ||||||
1117 | } | ||||||
1118 | } | ||||||
1119 | |||||||
1120 | if (args && args->dmachine) { | ||||||
1121 | if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL((void*)0))) != SWITCH_STATUS_SUCCESS) { | ||||||
1122 | break; | ||||||
1123 | } | ||||||
1124 | } | ||||||
1125 | |||||||
1126 | |||||||
1127 | } | ||||||
1128 | |||||||
1129 | end: | ||||||
1130 | |||||||
1131 | arg_recursion_check_stop(args)if (args) args->loops--; | ||||||
1132 | |||||||
1133 | if (write_frame.codec) { | ||||||
1134 | switch_core_codec_destroy(&codec); | ||||||
1135 | } | ||||||
1136 | |||||||
1137 | switch_safe_free(abuf)if (abuf) {free(abuf);abuf=((void*)0);}; | ||||||
1138 | |||||||
1139 | switch_channel_clear_flag(channel, CF_CONTROLLED); | ||||||
1140 | switch_channel_clear_flag(channel, CF_PARK); | ||||||
1141 | |||||||
1142 | if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_UNPARK)switch_event_create_subclass_detailed("src/switch_ivr.c", (const char * )(const char *)__func__, 1142, &event, SWITCH_EVENT_CHANNEL_UNPARK , ((void*)0)) == SWITCH_STATUS_SUCCESS) { | ||||||
1143 | switch_channel_event_set_data(channel, event); | ||||||
1144 | switch_event_fire(&event)switch_event_fire_detailed("src/switch_ivr.c", (const char * ) (const char *)__func__, 1144, &event, ((void*)0)); | ||||||
1145 | } | ||||||
1146 | |||||||
1147 | if (switch_channel_test_flag(channel, CF_UNICAST)) { | ||||||
1148 | switch_ivr_deactivate_unicast(session); | ||||||
1149 | } | ||||||
1150 | |||||||
1151 | return status; | ||||||
1152 | } | ||||||
1153 | |||||||
1154 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_collect_digits_callback(switch_core_session_t *session, switch_input_args_t *args, uint32_t digit_timeout, | ||||||
1155 | uint32_t abs_timeout) | ||||||
1156 | { | ||||||
1157 | switch_channel_t *channel = switch_core_session_get_channel(session); | ||||||
1158 | switch_status_t status = SWITCH_STATUS_SUCCESS; | ||||||
1159 | switch_time_t abs_started = 0, digit_started = 0; | ||||||
1160 | uint32_t abs_elapsed = 0, digit_elapsed = 0; | ||||||
1161 | |||||||
1162 | if (!args) { | ||||||
1163 | return SWITCH_STATUS_GENERR; | ||||||
1164 | } | ||||||
1165 | |||||||
1166 | arg_recursion_check_start(args)if (args) { if (args->loops >= 25) { switch_log_printf( SWITCH_CHANNEL_ID_LOG, "src/switch_ivr.c", (const char *)__func__ , 1166, ((void*)0), SWITCH_LOG_ERROR, "RECURSION ERROR! It's not the best idea to call things that collect input recursively from an input callback.\n" ); return SWITCH_STATUS_GENERR; } else {args->loops++;} }; | ||||||
1167 | |||||||
1168 | if (abs_timeout) { | ||||||
1169 | abs_started = switch_micro_time_now(); | ||||||
1170 | } | ||||||
1171 | if (digit_timeout) { | ||||||
1172 | digit_started = switch_micro_time_now(); | ||||||
1173 | } | ||||||
1174 | |||||||
1175 | while (switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE)) { | ||||||
1176 | switch_frame_t *read_frame = NULL((void*)0); | ||||||
1177 | switch_event_t *event; | ||||||
1178 | switch_dtmf_t dtmf = { 0 }; | ||||||
1179 | |||||||
1180 | if (switch_channel_test_flag(channel, CF_BREAK)) { | ||||||
1181 | switch_channel_clear_flag(channel, CF_BREAK); | ||||||
1182 | status = SWITCH_STATUS_BREAK; | ||||||
1183 | break; | ||||||
1184 | } | ||||||
1185 | |||||||
1186 | if (abs_timeout) { | ||||||
1187 | abs_elapsed = (uint32_t) ((switch_micro_time_now() - abs_started) / 1000); | ||||||
1188 | if (abs_elapsed >= abs_timeout) { | ||||||
1189 | status = SWITCH_STATUS_TIMEOUT; | ||||||
1190 | break; | ||||||
1191 | } | ||||||
1192 | } | ||||||
1193 | if (digit_timeout) { | ||||||
1194 | digit_elapsed = (uint32_t) ((switch_micro_time_now() - digit_started) / 1000); | ||||||
1195 | if (digit_elapsed >= digit_timeout) { | ||||||
1196 | status = SWITCH_STATUS_TIMEOUT; | ||||||
1197 | break; | ||||||
1198 | } | ||||||
1199 | } | ||||||
1200 | |||||||
1201 | |||||||
1202 | switch_ivr_parse_all_events(session); | ||||||
1203 | |||||||
1204 | |||||||
1205 | if (switch_channel_has_dtmf(channel)) { | ||||||
1206 | if (!args->input_callback && !args->buf && !args->dmachine) { | ||||||
1207 | status = SWITCH_STATUS_BREAK; | ||||||
1208 | break; | ||||||
1209 | } | ||||||
1210 | switch_channel_dequeue_dtmf(channel, &dtmf); | ||||||
1211 | |||||||
1212 | if (args->dmachine) { | ||||||
1213 | char ds[2] = {dtmf.digit, '\0'}; | ||||||
1214 | if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL((void*)0))) != SWITCH_STATUS_SUCCESS) { | ||||||
1215 | break; | ||||||
1216 | } | ||||||
1217 | } | ||||||
1218 | |||||||
1219 | if (args->input_callback) { | ||||||
1220 | status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen); | ||||||
1221 | } | ||||||
1222 | |||||||
1223 | if (digit_timeout) { | ||||||
1224 | digit_started = switch_micro_time_now(); | ||||||
1225 | } | ||||||
1226 | } | ||||||
1227 | |||||||
1228 | if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { | ||||||
1229 | switch_status_t ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen); | ||||||
1230 | if (ostatus != SWITCH_STATUS_SUCCESS) { | ||||||
1231 | status = ostatus; | ||||||
1232 | } | ||||||
1233 | switch_event_destroy(&event); | ||||||
1234 | } | ||||||
1235 | |||||||
1236 | if (status != SWITCH_STATUS_SUCCESS) { | ||||||
1237 | break; | ||||||
1238 | } | ||||||
1239 | |||||||
1240 | if (switch_channel_test_flag(channel, CF_SERVICE)) { | ||||||
1241 | switch_cond_next(); | ||||||
1242 | } else { | ||||||
1243 | status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); | ||||||
1244 | } | ||||||
1245 | |||||||
1246 | if (!SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK || status == SWITCH_STATUS_INUSE)) { | ||||||
1247 | break; | ||||||
1248 | } | ||||||
1249 | |||||||
1250 | if (args && args->dmachine) { | ||||||
1251 | if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL((void*)0))) != SWITCH_STATUS_SUCCESS) { | ||||||
1252 | break; | ||||||
1253 | } | ||||||
1254 | } | ||||||
1255 | |||||||
1256 | if (read_frame && args && (args->read_frame_callback)) { | ||||||
1257 | if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) { | ||||||
1258 | break; | ||||||
1259 | } | ||||||
1260 | } | ||||||
1261 | } | ||||||
1262 | |||||||
1263 | arg_recursion_check_stop(args)if (args) args->loops--; | ||||||
1264 | |||||||
1265 | return status; | ||||||
1266 | } | ||||||
1267 | |||||||
1268 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_collect_digits_count(switch_core_session_t *session, | ||||||
1269 | char *buf, | ||||||
1270 | switch_size_t buflen, | ||||||
1271 | switch_size_t maxdigits, | ||||||
1272 | const char *terminators, char *terminator, | ||||||
1273 | uint32_t first_timeout, uint32_t digit_timeout, uint32_t abs_timeout) | ||||||
1274 | { | ||||||
1275 | switch_size_t i = 0, x = strlen(buf); | ||||||
1276 | switch_channel_t *channel = switch_core_session_get_channel(session); | ||||||
1277 | switch_status_t status = SWITCH_STATUS_FALSE; | ||||||
1278 | switch_time_t started = 0, digit_started = 0; | ||||||
1279 | uint32_t abs_elapsed = 0, digit_elapsed = 0; | ||||||
1280 | uint32_t eff_timeout = 0; | ||||||
1281 | switch_frame_t write_frame = { 0 }; | ||||||
1282 | unsigned char *abuf = NULL((void*)0); | ||||||
1283 | switch_codec_implementation_t imp = { 0 }; | ||||||
1284 | switch_codec_t codec = { 0 }; | ||||||
1285 | int sval = 0; | ||||||
1286 | const char *var; | ||||||
1287 | |||||||
1288 | if ((var = switch_channel_get_variable(channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE)switch_channel_get_variable_dup(channel, "send_silence_when_idle" , SWITCH_TRUE, -1)) && (sval = atoi(var))) { | ||||||
1289 | switch_core_session_get_read_impl(session, &imp); | ||||||
1290 | |||||||
1291 | if (switch_core_codec_init(&codec,switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.samples_per_second, imp.microseconds_per_packet / 1000 , imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , ((void*)0), switch_core_session_get_pool(session)) | ||||||
1292 | "L16",switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.samples_per_second, imp.microseconds_per_packet / 1000 , imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , ((void*)0), switch_core_session_get_pool(session)) | ||||||
1293 | NULL,switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.samples_per_second, imp.microseconds_per_packet / 1000 , imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , ((void*)0), switch_core_session_get_pool(session)) | ||||||
1294 | imp.samples_per_second,switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.samples_per_second, imp.microseconds_per_packet / 1000 , imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , ((void*)0), switch_core_session_get_pool(session)) | ||||||
1295 | imp.microseconds_per_packet / 1000,switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.samples_per_second, imp.microseconds_per_packet / 1000 , imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , ((void*)0), switch_core_session_get_pool(session)) | ||||||
1296 | imp.number_of_channels,switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.samples_per_second, imp.microseconds_per_packet / 1000 , imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , ((void*)0), switch_core_session_get_pool(session)) | ||||||
1297 | SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.samples_per_second, imp.microseconds_per_packet / 1000 , imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , ((void*)0), switch_core_session_get_pool(session)) | ||||||
1298 | switch_core_session_get_pool(session))switch_core_codec_init_with_bitrate(&codec, "L16", ((void *)0), imp.samples_per_second, imp.microseconds_per_packet / 1000 , imp.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , ((void*)0), switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { | ||||||
1299 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *) __func__, 1299, (const char*)(session), SWITCH_LOG_ERROR, "Codec Error L16@%uhz %u channels %dms\n", | ||||||
1300 | imp.samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000); | ||||||
1301 | return SWITCH_STATUS_FALSE; | ||||||
1302 | } | ||||||
1303 | |||||||
1304 | |||||||
1305 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *) __func__, 1305, (const char*)(session), SWITCH_LOG_DEBUG, "Codec Activated L16@%uhz %u channels %dms\n", | ||||||
1306 | imp.samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000); | ||||||
1307 | |||||||
1308 | write_frame.codec = &codec; | ||||||
1309 | switch_zmalloc(abuf, SWITCH_RECOMMENDED_BUFFER_SIZE)(void)((((abuf = calloc(1, (8192)))) ? (void) (0) : __assert_fail ("(abuf = calloc(1, (8192)))", "src/switch_ivr.c", 1309, __PRETTY_FUNCTION__ )),abuf); | ||||||
1310 | write_frame.data = abuf; | ||||||
1311 | write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE8192; | ||||||
1312 | write_frame.datalen = imp.decoded_bytes_per_packet; | ||||||
1313 | write_frame.samples = write_frame.datalen / sizeof(int16_t); | ||||||
1314 | } | ||||||
1315 | |||||||
1316 | if (terminator != NULL((void*)0)) { | ||||||
1317 | *terminator = '\0'; | ||||||
1318 | } | ||||||
1319 | |||||||
1320 | if (!zstr(terminators)_zstr(terminators)) { | ||||||
1321 | for (i = 0; i < x; i++) { | ||||||
1322 | if (strchr(terminators, buf[i])(__extension__ (__builtin_constant_p (buf[i]) && !__builtin_constant_p (terminators) && (buf[i]) == '\0' ? (char *) __rawmemchr (terminators, buf[i]) : __builtin_strchr (terminators, buf[i ]))) && terminator != NULL((void*)0)) { | ||||||
1323 | *terminator = buf[i]; | ||||||
1324 | buf[i] = '\0'; | ||||||
1325 | switch_safe_free(abuf)if (abuf) {free(abuf);abuf=((void*)0);}; | ||||||
1326 | return SWITCH_STATUS_SUCCESS; | ||||||
1327 | } | ||||||
1328 | } | ||||||
1329 | } | ||||||
1330 | |||||||
1331 | if (abs_timeout) { | ||||||
1332 | started = switch_micro_time_now(); | ||||||
1333 | } | ||||||
1334 | |||||||
1335 | if (digit_timeout && first_timeout) { | ||||||
1336 | eff_timeout = first_timeout; | ||||||
1337 | } else if (digit_timeout && !first_timeout) { | ||||||
1338 | first_timeout = eff_timeout = digit_timeout; | ||||||
1339 | } else if (first_timeout) { | ||||||
1340 | digit_timeout = eff_timeout = first_timeout; | ||||||
1341 | } | ||||||
1342 | |||||||
1343 | |||||||
1344 | if (eff_timeout) { | ||||||
1345 | digit_started = switch_micro_time_now(); | ||||||
1346 | } | ||||||
1347 | |||||||
1348 | while (switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE)) { | ||||||
1349 | switch_frame_t *read_frame; | ||||||
1350 | |||||||
1351 | if (abs_timeout) { | ||||||
1352 | abs_elapsed = (uint32_t) ((switch_micro_time_now() - started) / 1000); | ||||||
1353 | if (abs_elapsed >= abs_timeout) { | ||||||
1354 | status = SWITCH_STATUS_TIMEOUT; | ||||||
1355 | break; | ||||||
1356 | } | ||||||
1357 | } | ||||||
1358 | |||||||
1359 | |||||||
1360 | switch_ivr_parse_all_events(session); | ||||||
1361 | |||||||
1362 | |||||||
1363 | |||||||
1364 | if (eff_timeout) { | ||||||
1365 | digit_elapsed = (uint32_t) ((switch_micro_time_now() - digit_started) / 1000); | ||||||
1366 | |||||||
1367 | if (digit_elapsed >= eff_timeout) { | ||||||
1368 | status = SWITCH_STATUS_TIMEOUT; | ||||||
1369 | break; | ||||||
1370 | } | ||||||
1371 | } | ||||||
1372 | |||||||
1373 | if (switch_channel_has_dtmf(channel)) { | ||||||
1374 | switch_dtmf_t dtmf = { 0 }; | ||||||
1375 | switch_size_t y; | ||||||
1376 | |||||||
1377 | if (eff_timeout) { | ||||||
1378 | eff_timeout = digit_timeout; | ||||||
1379 | digit_started = switch_micro_time_now(); | ||||||
1380 | } | ||||||
1381 | |||||||
1382 | for (y = 0; y <= maxdigits; y++) { | ||||||
1383 | if (switch_channel_dequeue_dtmf(channel, &dtmf) != SWITCH_STATUS_SUCCESS) { | ||||||
1384 | break; | ||||||
1385 | } | ||||||
1386 | |||||||
1387 | if (!zstr(terminators)_zstr(terminators) && strchr(terminators, dtmf.digit)(__extension__ (__builtin_constant_p (dtmf.digit) && ! __builtin_constant_p (terminators) && (dtmf.digit) == '\0' ? (char *) __rawmemchr (terminators, dtmf.digit) : __builtin_strchr (terminators, dtmf.digit))) && terminator != NULL((void*)0)) { | ||||||
1388 | *terminator = dtmf.digit; | ||||||
1389 | switch_safe_free(abuf)if (abuf) {free(abuf);abuf=((void*)0);}; | ||||||
1390 | return SWITCH_STATUS_SUCCESS; | ||||||
1391 | } | ||||||
1392 | |||||||
1393 | |||||||
1394 | buf[x++] = dtmf.digit; | ||||||
1395 | buf[x] = '\0'; | ||||||
1396 | |||||||
1397 | if (x >= buflen || x >= maxdigits) { | ||||||
1398 | switch_safe_free(abuf)if (abuf) {free(abuf);abuf=((void*)0);}; | ||||||
1399 | return SWITCH_STATUS_SUCCESS; | ||||||
1400 | } | ||||||
1401 | } | ||||||
1402 | } | ||||||
1403 | |||||||
1404 | if (switch_channel_test_flag(channel, CF_SERVICE)) { | ||||||
1405 | switch_cond_next(); | ||||||
1406 | } else { | ||||||
1407 | status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); | ||||||
1408 | if (!SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK || status == SWITCH_STATUS_INUSE)) { | ||||||
1409 | break; | ||||||
1410 | } | ||||||
1411 | |||||||
1412 | if (write_frame.data) { | ||||||
1413 | switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.samples, imp.number_of_channels, sval); | ||||||
1414 | switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0); | ||||||
1415 | } | ||||||
1416 | |||||||
1417 | } | ||||||
1418 | } | ||||||
1419 | |||||||
1420 | if (write_frame.codec) { | ||||||
1421 | switch_core_codec_destroy(&codec); | ||||||
1422 | } | ||||||
1423 | |||||||
1424 | switch_safe_free(abuf)if (abuf) {free(abuf);abuf=((void*)0);}; | ||||||
1425 | |||||||
1426 | return status; | ||||||
1427 | } | ||||||
1428 | |||||||
1429 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_hold(switch_core_session_t *session, const char *message, switch_bool_t moh) | ||||||
1430 | { | ||||||
1431 | switch_core_session_message_t msg = { 0 }; | ||||||
1432 | switch_channel_t *channel = switch_core_session_get_channel(session); | ||||||
1433 | const char *stream; | ||||||
1434 | const char *other_uuid; | ||||||
1435 | switch_event_t *event; | ||||||
1436 | |||||||
1437 | msg.message_id = SWITCH_MESSAGE_INDICATE_HOLD; | ||||||
1438 | msg.string_arg = message; | ||||||
1439 | msg.from = __FILE__"src/switch_ivr.c"; | ||||||
1440 | |||||||
1441 | switch_channel_set_flag(channel, CF_HOLD)switch_channel_set_flag_value(channel, CF_HOLD, 1); | ||||||
1442 | switch_channel_set_flag(channel, CF_SUSPEND)switch_channel_set_flag_value(channel, CF_SUSPEND, 1); | ||||||
1443 | |||||||
1444 | switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg , "src/switch_ivr.c", (const char *)__func__, 1444); | ||||||
1445 | |||||||
1446 | if (moh && (stream = switch_channel_get_hold_music(channel))) { | ||||||
1447 | if ((other_uuid = switch_channel_get_partner_uuid(channel))) { | ||||||
1448 | switch_ivr_broadcast(other_uuid, stream, SMF_ECHO_ALEG | SMF_LOOP); | ||||||
1449 | } | ||||||
1450 | } | ||||||
1451 | |||||||
1452 | if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_HOLD)switch_event_create_subclass_detailed("src/switch_ivr.c", (const char * )(const char *)__func__, 1452, &event, SWITCH_EVENT_CHANNEL_HOLD , ((void*)0)) == SWITCH_STATUS_SUCCESS) { | ||||||
1453 | switch_channel_event_set_data(channel, event); | ||||||
1454 | switch_event_fire(&event)switch_event_fire_detailed("src/switch_ivr.c", (const char * ) (const char *)__func__, 1454, &event, ((void*)0)); | ||||||
1455 | } | ||||||
1456 | |||||||
1457 | |||||||
1458 | return SWITCH_STATUS_SUCCESS; | ||||||
1459 | } | ||||||
1460 | |||||||
1461 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_hold_uuid(const char *uuid, const char *message, switch_bool_t moh) | ||||||
1462 | { | ||||||
1463 | switch_core_session_t *session; | ||||||
1464 | |||||||
1465 | if ((session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "src/switch_ivr.c", ( const char *)__func__, 1465))) { | ||||||
1466 | switch_ivr_hold(session, message, moh); | ||||||
1467 | switch_core_session_rwunlock(session); | ||||||
1468 | } | ||||||
1469 | |||||||
1470 | return SWITCH_STATUS_SUCCESS; | ||||||
1471 | } | ||||||
1472 | |||||||
1473 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_hold_toggle_uuid(const char *uuid, const char *message, switch_bool_t moh) | ||||||
1474 | { | ||||||
1475 | switch_core_session_t *session; | ||||||
1476 | switch_channel_t *channel; | ||||||
1477 | switch_channel_callstate_t callstate; | ||||||
1478 | |||||||
1479 | if ((session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "src/switch_ivr.c", ( const char *)__func__, 1479))) { | ||||||
1480 | if ((channel = switch_core_session_get_channel(session))) { | ||||||
1481 | callstate = switch_channel_get_callstate(channel); | ||||||
1482 | |||||||
1483 | if (callstate == CCS_ACTIVE) { | ||||||
1484 | switch_ivr_hold(session, message, moh); | ||||||
1485 | } else if (callstate == CCS_HELD) { | ||||||
1486 | switch_ivr_unhold(session); | ||||||
1487 | } | ||||||
1488 | } | ||||||
1489 | switch_core_session_rwunlock(session); | ||||||
1490 | } | ||||||
1491 | |||||||
1492 | return SWITCH_STATUS_SUCCESS; | ||||||
1493 | } | ||||||
1494 | |||||||
1495 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_unhold(switch_core_session_t *session) | ||||||
1496 | { | ||||||
1497 | switch_core_session_message_t msg = { 0 }; | ||||||
1498 | switch_channel_t *channel = switch_core_session_get_channel(session); | ||||||
1499 | const char *other_uuid; | ||||||
1500 | switch_core_session_t *b_session; | ||||||
1501 | switch_event_t *event; | ||||||
1502 | |||||||
1503 | msg.message_id = SWITCH_MESSAGE_INDICATE_UNHOLD; | ||||||
1504 | msg.from = __FILE__"src/switch_ivr.c"; | ||||||
1505 | |||||||
1506 | switch_channel_clear_flag(channel, CF_HOLD); | ||||||
1507 | switch_channel_clear_flag(channel, CF_SUSPEND); | ||||||
1508 | |||||||
1509 | switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg , "src/switch_ivr.c", (const char *)__func__, 1509); | ||||||
1510 | |||||||
1511 | |||||||
1512 | if ((other_uuid = switch_channel_get_partner_uuid(channel)) && (b_session = switch_core_session_locate(other_uuid)switch_core_session_perform_locate(other_uuid, "src/switch_ivr.c" , (const char *)__func__, 1512))) { | ||||||
1513 | switch_channel_t *b_channel = switch_core_session_get_channel(b_session); | ||||||
1514 | switch_channel_stop_broadcast(b_channel)for(;;) {if (switch_channel_test_flag(b_channel, CF_BROADCAST )) {switch_channel_set_flag_value(b_channel, CF_STOP_BROADCAST , 1); switch_channel_set_flag_value(b_channel, CF_BREAK, 1); } break;}; | ||||||
1515 | switch_channel_wait_for_flag(b_channel, CF_BROADCAST, SWITCH_FALSE, 5000, NULL((void*)0)); | ||||||
1516 | switch_core_session_rwunlock(b_session); | ||||||
1517 | } | ||||||
1518 | |||||||
1519 | |||||||
1520 | if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_UNHOLD)switch_event_create_subclass_detailed("src/switch_ivr.c", (const char * )(const char *)__func__, 1520, &event, SWITCH_EVENT_CHANNEL_UNHOLD , ((void*)0)) == SWITCH_STATUS_SUCCESS) { | ||||||
1521 | switch_channel_event_set_data(channel, event); | ||||||
1522 | switch_event_fire(&event)switch_event_fire_detailed("src/switch_ivr.c", (const char * ) (const char *)__func__, 1522, &event, ((void*)0)); | ||||||
1523 | } | ||||||
1524 | |||||||
1525 | return SWITCH_STATUS_SUCCESS; | ||||||
1526 | } | ||||||
1527 | |||||||
1528 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_unhold_uuid(const char *uuid) | ||||||
1529 | { | ||||||
1530 | switch_core_session_t *session; | ||||||
1531 | |||||||
1532 | if ((session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "src/switch_ivr.c", ( const char *)__func__, 1532))) { | ||||||
1533 | switch_ivr_unhold(session); | ||||||
1534 | switch_core_session_rwunlock(session); | ||||||
1535 | } | ||||||
1536 | |||||||
1537 | return SWITCH_STATUS_SUCCESS; | ||||||
1538 | } | ||||||
1539 | |||||||
1540 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_media(const char *uuid, switch_media_flag_t flags) | ||||||
1541 | { | ||||||
1542 | const char *other_uuid = NULL((void*)0); | ||||||
1543 | switch_channel_t *channel, *other_channel = NULL((void*)0); | ||||||
1544 | switch_core_session_t *session, *other_session; | ||||||
1545 | switch_core_session_message_t msg = { 0 }; | ||||||
1546 | switch_status_t status = SWITCH_STATUS_GENERR; | ||||||
1547 | uint8_t swap = 0; | ||||||
1548 | switch_frame_t *read_frame = NULL((void*)0); | ||||||
1549 | |||||||
1550 | msg.message_id = SWITCH_MESSAGE_INDICATE_MEDIA; | ||||||
1551 | msg.from = __FILE__"src/switch_ivr.c"; | ||||||
1552 | |||||||
1553 | if ((session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "src/switch_ivr.c", ( const char *)__func__, 1553))) { | ||||||
1554 | channel = switch_core_session_get_channel(session); | ||||||
1555 | |||||||
1556 | if (switch_channel_test_flag(channel, CF_MEDIA_TRANS)) { | ||||||
1557 | switch_core_session_rwunlock(session); | ||||||
1558 | return SWITCH_STATUS_INUSE; | ||||||
1559 | } | ||||||
1560 | |||||||
1561 | switch_channel_set_flag(channel, CF_MEDIA_TRANS)switch_channel_set_flag_value(channel, CF_MEDIA_TRANS, 1); | ||||||
1562 | |||||||
1563 | if ((flags & SMF_REBRIDGE) && !switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) { | ||||||
1564 | swap = 1; | ||||||
1565 | } | ||||||
1566 | |||||||
1567 | if (switch_channel_test_flag(channel, CF_PROXY_MODE)) { | ||||||
1568 | status = SWITCH_STATUS_SUCCESS; | ||||||
1569 | |||||||
1570 | /* If we had early media in bypass mode before, it is no longer relevant */ | ||||||
1571 | if (switch_channel_test_flag(channel, CF_EARLY_MEDIA)) { | ||||||
1572 | switch_core_session_message_t msg2 = { 0 }; | ||||||
1573 | |||||||
1574 | msg2.message_id = SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS; | ||||||
1575 | msg2.from = __FILE__"src/switch_ivr.c"; | ||||||
1576 | switch_core_session_receive_message(session, &msg2)switch_core_session_perform_receive_message(session, &msg2 , "src/switch_ivr.c", (const char *)__func__, 1576); | ||||||
1577 | } | ||||||
1578 | |||||||
1579 | if ((flags & SMF_REPLYONLY_A)) { | ||||||
1580 | msg.numeric_arg = 1; | ||||||
1581 | } | ||||||
1582 | |||||||
1583 | if (switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg , "src/switch_ivr.c", (const char *)__func__, 1583) != SWITCH_STATUS_SUCCESS) { | ||||||
1584 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *) __func__, 1584, (const char*)(session), SWITCH_LOG_ERROR, "Can't re-establsh media on %s\n", switch_channel_get_name(channel)); | ||||||
1585 | switch_core_session_rwunlock(session); | ||||||
1586 | return SWITCH_STATUS_GENERR; | ||||||
1587 | } | ||||||
1588 | |||||||
1589 | if ((flags & SMF_REPLYONLY_B)) { | ||||||
1590 | msg.numeric_arg = 1; | ||||||
1591 | } else { | ||||||
1592 | msg.numeric_arg = 0; | ||||||
1593 | } | ||||||
1594 | |||||||
1595 | if ((flags & SMF_IMMEDIATE)) { | ||||||
1596 | switch_channel_wait_for_flag(channel, CF_REQ_MEDIA, SWITCH_FALSE, 250, NULL((void*)0)); | ||||||
1597 | switch_yield(250000)switch_sleep(250000);; | ||||||
1598 | } else { | ||||||
1599 | switch_channel_wait_for_flag(channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL((void*)0)); | ||||||
1600 | switch_channel_wait_for_flag(channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL((void*)0)); | ||||||
1601 | switch_channel_wait_for_flag(channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL((void*)0)); | ||||||
1602 | switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); | ||||||
1603 | } | ||||||
1604 | |||||||
1605 | if ((flags & SMF_REBRIDGE) | ||||||
1606 | && (other_uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE)switch_channel_get_variable_dup(channel, "signal_bridge_to", SWITCH_TRUE , -1)) | ||||||
1607 | && (other_session = switch_core_session_locate(other_uuid)switch_core_session_perform_locate(other_uuid, "src/switch_ivr.c" , (const char *)__func__, 1607))) { | ||||||
1608 | other_channel = switch_core_session_get_channel(other_session); | ||||||
1609 | switch_assert(other_channel != NULL)((other_channel != ((void*)0)) ? (void) (0) : __assert_fail ( "other_channel != ((void*)0)", "src/switch_ivr.c", 1609, __PRETTY_FUNCTION__ )); | ||||||
1610 | switch_core_session_receive_message(other_session, &msg)switch_core_session_perform_receive_message(other_session, & msg, "src/switch_ivr.c", (const char *)__func__, 1610); | ||||||
1611 | switch_channel_wait_for_flag(other_channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL((void*)0)); | ||||||
1612 | switch_channel_wait_for_flag(other_channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL((void*)0)); | ||||||
1613 | switch_channel_wait_for_flag(other_channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL((void*)0)); | ||||||
1614 | switch_core_session_read_frame(other_session, &read_frame, SWITCH_IO_FLAG_NONE, 0); | ||||||
1615 | switch_channel_clear_state_handler(other_channel, NULL((void*)0)); | ||||||
1616 | switch_core_session_rwunlock(other_session); | ||||||
1617 | } | ||||||
1618 | if (other_channel) { | ||||||
1619 | switch_channel_clear_state_handler(channel, NULL((void*)0)); | ||||||
1620 | } | ||||||
1621 | } | ||||||
1622 | |||||||
1623 | switch_channel_clear_flag(channel, CF_MEDIA_TRANS); | ||||||
1624 | switch_core_session_rwunlock(session); | ||||||
1625 | |||||||
1626 | if (other_channel) { | ||||||
1627 | if (swap) { | ||||||
1628 | switch_ivr_uuid_bridge(other_uuid, uuid); | ||||||
1629 | } else { | ||||||
1630 | switch_ivr_uuid_bridge(uuid, other_uuid); | ||||||
1631 | } | ||||||
1632 | switch_channel_wait_for_flag(channel, CF_BRIDGED, SWITCH_TRUE, 1000, NULL((void*)0)); | ||||||
1633 | switch_channel_wait_for_flag(other_channel, CF_BRIDGED, SWITCH_TRUE, 1000, NULL((void*)0)); | ||||||
1634 | } | ||||||
1635 | } | ||||||
1636 | |||||||
1637 | return status; | ||||||
1638 | } | ||||||
1639 | |||||||
1640 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_nomedia(const char *uuid, switch_media_flag_t flags) | ||||||
1641 | { | ||||||
1642 | const char *other_uuid; | ||||||
1643 | switch_channel_t *channel, *other_channel = NULL((void*)0); | ||||||
1644 | switch_core_session_t *session, *other_session = NULL((void*)0); | ||||||
1645 | switch_core_session_message_t msg = { 0 }; | ||||||
1646 | switch_status_t status = SWITCH_STATUS_GENERR; | ||||||
1647 | uint8_t swap = 0; | ||||||
1648 | |||||||
1649 | msg.message_id = SWITCH_MESSAGE_INDICATE_NOMEDIA; | ||||||
1650 | msg.from = __FILE__"src/switch_ivr.c"; | ||||||
1651 | |||||||
1652 | if ((session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "src/switch_ivr.c", ( const char *)__func__, 1652))) { | ||||||
1653 | status = SWITCH_STATUS_SUCCESS; | ||||||
1654 | channel = switch_core_session_get_channel(session); | ||||||
1655 | |||||||
1656 | if (switch_channel_test_flag(channel, CF_MEDIA_TRANS)) { | ||||||
1657 | switch_core_session_rwunlock(session); | ||||||
1658 | return SWITCH_STATUS_INUSE; | ||||||
1659 | } | ||||||
1660 | |||||||
1661 | switch_channel_set_flag(channel, CF_MEDIA_TRANS)switch_channel_set_flag_value(channel, CF_MEDIA_TRANS, 1); | ||||||
1662 | |||||||
1663 | if ((flags & SMF_REBRIDGE) && !switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) { | ||||||
1664 | swap = 1; | ||||||
1665 | } | ||||||
1666 | |||||||
1667 | switch_channel_set_flag(channel, CF_REDIRECT)switch_channel_set_flag_value(channel, CF_REDIRECT, 1); | ||||||
1668 | switch_channel_set_flag(channel, CF_RESET)switch_channel_set_flag_value(channel, CF_RESET, 1); | ||||||
1669 | |||||||
1670 | if ((flags & SMF_FORCE) || !switch_channel_test_flag(channel, CF_PROXY_MODE)) { | ||||||
1671 | if ((flags & SMF_REBRIDGE) && (other_uuid = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE)switch_channel_get_variable_dup(channel, "bridge_to", SWITCH_TRUE , -1)) && | ||||||
1672 | (other_session = switch_core_session_locate(other_uuid)switch_core_session_perform_locate(other_uuid, "src/switch_ivr.c" , (const char *)__func__, 1672))) { | ||||||
1673 | other_channel = switch_core_session_get_channel(other_session); | ||||||
1674 | |||||||
1675 | switch_channel_set_flag(other_channel, CF_RESET)switch_channel_set_flag_value(other_channel, CF_RESET, 1); | ||||||
1676 | switch_channel_set_flag(other_channel, CF_REDIRECT)switch_channel_set_flag_value(other_channel, CF_REDIRECT, 1); | ||||||
1677 | |||||||
1678 | if (!switch_core_session_in_thread(session)) { | ||||||
1679 | switch_channel_set_state(channel, CS_PARK)switch_channel_perform_set_state(channel, "src/switch_ivr.c", (const char *)__func__, 1679, CS_PARK); | ||||||
1680 | } | ||||||
1681 | switch_channel_set_state(other_channel, CS_PARK)switch_channel_perform_set_state(other_channel, "src/switch_ivr.c" , (const char *)__func__, 1681, CS_PARK); | ||||||
1682 | if (switch_core_session_in_thread(session)) { | ||||||
1683 | switch_yield(100000)switch_sleep(100000);; | ||||||
1684 | } else { | ||||||
1685 | switch_channel_wait_for_state(other_channel, channel, CS_PARK); | ||||||
1686 | } | ||||||
1687 | switch_core_session_receive_message(other_session, &msg)switch_core_session_perform_receive_message(other_session, & msg, "src/switch_ivr.c", (const char *)__func__, 1687); | ||||||
1688 | switch_channel_wait_for_flag(other_channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL((void*)0)); | ||||||
1689 | //switch_channel_wait_for_flag(other_channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL); | ||||||
1690 | switch_channel_wait_for_flag(other_channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL((void*)0)); | ||||||
1691 | } | ||||||
1692 | |||||||
1693 | switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg , "src/switch_ivr.c", (const char *)__func__, 1693); | ||||||
1694 | |||||||
1695 | if (other_channel) { | ||||||
1696 | if (!switch_core_session_in_thread(session)) { | ||||||
1697 | switch_channel_wait_for_state(channel, NULL((void*)0), CS_PARK); | ||||||
1698 | switch_channel_wait_for_flag(channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL((void*)0)); | ||||||
1699 | switch_channel_wait_for_flag(channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL((void*)0)); | ||||||
1700 | switch_channel_wait_for_flag(channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL((void*)0)); | ||||||
1701 | } | ||||||
1702 | |||||||
1703 | if (swap) { | ||||||
1704 | switch_ivr_signal_bridge(other_session, session); | ||||||
1705 | } else { | ||||||
1706 | switch_ivr_signal_bridge(session, other_session); | ||||||
1707 | } | ||||||
1708 | |||||||
1709 | if (switch_core_session_in_thread(session)) { | ||||||
1710 | switch_yield(100000)switch_sleep(100000);; | ||||||
1711 | } else { | ||||||
1712 | switch_channel_wait_for_state(other_channel, channel, CS_HIBERNATE); | ||||||
1713 | } | ||||||
1714 | |||||||
1715 | if (!switch_core_session_in_thread(session)) { | ||||||
1716 | switch_channel_wait_for_state(channel, other_channel, CS_HIBERNATE); | ||||||
1717 | } | ||||||
1718 | switch_core_session_rwunlock(other_session); | ||||||
1719 | } | ||||||
1720 | } | ||||||
1721 | |||||||
1722 | switch_channel_clear_flag(channel, CF_MEDIA_TRANS); | ||||||
1723 | switch_core_session_rwunlock(session); | ||||||
1724 | } | ||||||
1725 | |||||||
1726 | |||||||
1727 | |||||||
1728 | return status; | ||||||
1729 | } | ||||||
1730 | |||||||
1731 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_session_transfer(switch_core_session_t *session, const char *extension, const char *dialplan, | ||||||
1732 | const char *context) | ||||||
1733 | { | ||||||
1734 | switch_channel_t *channel = switch_core_session_get_channel(session); | ||||||
1735 | switch_caller_profile_t *profile, *new_profile; | ||||||
1736 | switch_core_session_message_t msg = { 0 }; | ||||||
1737 | switch_core_session_t *other_session; | ||||||
1738 | switch_channel_t *other_channel = NULL((void*)0); | ||||||
1739 | const char *uuid = NULL((void*)0); | ||||||
1740 | const char *max_forwards; | ||||||
1741 | const char *forwardvar = switch_channel_get_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE)switch_channel_get_variable_dup(channel, "max_forwards", SWITCH_TRUE , -1); | ||||||
1742 | int forwardval = 70; | ||||||
1743 | const char *use_dialplan = dialplan, *use_context = context; | ||||||
1744 | |||||||
1745 | if (!zstr(forwardvar)_zstr(forwardvar)) { | ||||||
1746 | forwardval = atoi(forwardvar) - 1; | ||||||
1747 | } | ||||||
1748 | if (forwardval <= 0) { | ||||||
1749 | switch_channel_hangup(channel, SWITCH_CAUSE_EXCHANGE_ROUTING_ERROR)switch_channel_perform_hangup(channel, "src/switch_ivr.c", (const char *)__func__, 1749, SWITCH_CAUSE_EXCHANGE_ROUTING_ERROR); | ||||||
1750 | return SWITCH_STATUS_FALSE; | ||||||
1751 | } | ||||||
1752 | |||||||
1753 | max_forwards = switch_core_session_sprintf(session, "%d", forwardval); | ||||||
1754 | switch_channel_set_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE, max_forwards)switch_channel_set_variable_var_check(channel, "max_forwards" , max_forwards, SWITCH_TRUE); | ||||||
1755 | |||||||
1756 | switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); | ||||||
1757 | switch_channel_clear_flag(channel, CF_ORIGINATING); | ||||||
1758 | |||||||
1759 | /* clear all state handlers */ | ||||||
1760 | switch_channel_clear_state_handler(channel, NULL((void*)0)); | ||||||
1761 | |||||||
1762 | /* reset temp hold music */ | ||||||
1763 | switch_channel_set_variable(channel, SWITCH_TEMP_HOLD_MUSIC_VARIABLE, NULL)switch_channel_set_variable_var_check(channel, "temp_hold_music" , ((void*)0), SWITCH_TRUE); | ||||||
1764 | |||||||
1765 | if ((profile = switch_channel_get_caller_profile(channel))) { | ||||||
1766 | const char *var; | ||||||
1767 | |||||||
1768 | if (zstr(dialplan)_zstr(dialplan) && (var = switch_channel_get_variable(channel, "force_transfer_dialplan")switch_channel_get_variable_dup(channel, "force_transfer_dialplan" , SWITCH_TRUE, -1))) { | ||||||
1769 | use_dialplan = var; | ||||||
1770 | } | ||||||
1771 | |||||||
1772 | if (zstr(context)_zstr(context) && (var = switch_channel_get_variable(channel, "force_transfer_context")switch_channel_get_variable_dup(channel, "force_transfer_context" , SWITCH_TRUE, -1))) { | ||||||
1773 | use_context = var; | ||||||
1774 | } | ||||||
1775 | |||||||
1776 | if (zstr(use_dialplan)_zstr(use_dialplan)) { | ||||||
1777 | use_dialplan = profile->dialplan; | ||||||
1778 | if (!zstr(use_dialplan)_zstr(use_dialplan) && !strcasecmp(use_dialplan, "inline")) { | ||||||
1779 | use_dialplan = NULL((void*)0); | ||||||
1780 | } | ||||||
1781 | } | ||||||
1782 | |||||||
1783 | if (zstr(use_context)_zstr(use_context)) { | ||||||
1784 | use_context = profile->context; | ||||||
1785 | } | ||||||
1786 | |||||||
1787 | if (zstr(use_dialplan)_zstr(use_dialplan)) { | ||||||
1788 | use_dialplan = "XML"; | ||||||
1789 | } | ||||||
1790 | |||||||
1791 | if (zstr(use_context)_zstr(use_context)) { | ||||||
1792 | use_context = "default"; | ||||||
1793 | } | ||||||
1794 | |||||||
1795 | if (zstr(extension)_zstr(extension)) { | ||||||
1796 | extension = "service"; | ||||||
1797 | } | ||||||
1798 | |||||||
1799 | new_profile = switch_caller_profile_clone(session, profile); | ||||||
1800 | |||||||
1801 | new_profile->dialplan = switch_core_strdup(new_profile->pool, use_dialplan)switch_core_perform_strdup(new_profile->pool, use_dialplan , "src/switch_ivr.c", (const char *)__func__, 1801); | ||||||
1802 | new_profile->context = switch_core_strdup(new_profile->pool, use_context)switch_core_perform_strdup(new_profile->pool, use_context, "src/switch_ivr.c", (const char *)__func__, 1802); | ||||||
1803 | new_profile->destination_number = switch_core_strdup(new_profile->pool, extension)switch_core_perform_strdup(new_profile->pool, extension, "src/switch_ivr.c" , (const char *)__func__, 1803); | ||||||
1804 | new_profile->rdnis = switch_core_strdup(new_profile->pool, profile->destination_number)switch_core_perform_strdup(new_profile->pool, profile-> destination_number, "src/switch_ivr.c", (const char *)__func__ , 1804); | ||||||
1805 | |||||||
1806 | switch_channel_set_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE, NULL)switch_channel_set_variable_var_check(channel, "signal_bond", ((void*)0), SWITCH_TRUE); | ||||||
1807 | |||||||
1808 | /* Set CF_TRANSFER flag before hanging up bleg to avoid race condition */ | ||||||
1809 | switch_channel_set_flag(channel, CF_TRANSFER)switch_channel_set_flag_value(channel, CF_TRANSFER, 1); | ||||||
1810 | |||||||
1811 | /* If HANGUP_AFTER_BRIDGE is set to 'true', SWITCH_SIGNAL_BRIDGE_VARIABLE | ||||||
1812 | * will not have a value, so we need to check SWITCH_BRIDGE_VARIABLE */ | ||||||
1813 | |||||||
1814 | uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE)switch_channel_get_variable_dup(channel, "signal_bridge_to", SWITCH_TRUE , -1); | ||||||
1815 | |||||||
1816 | if (!uuid) { | ||||||
1817 | uuid = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE)switch_channel_get_variable_dup(channel, "bridge_to", SWITCH_TRUE , -1); | ||||||
1818 | } | ||||||
1819 | |||||||
1820 | if (uuid && (other_session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "src/switch_ivr.c", ( const char *)__func__, 1820))) { | ||||||
1821 | other_channel = switch_core_session_get_channel(other_session); | ||||||
1822 | switch_channel_set_variable(other_channel, SWITCH_SIGNAL_BOND_VARIABLE, NULL)switch_channel_set_variable_var_check(other_channel, "signal_bond" , ((void*)0), SWITCH_TRUE); | ||||||
1823 | switch_core_session_rwunlock(other_session); | ||||||
1824 | } | ||||||
1825 | |||||||
1826 | if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE)switch_channel_get_variable_dup(channel, "signal_bridge_to", SWITCH_TRUE , -1)) | ||||||
1827 | && (other_session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "src/switch_ivr.c", ( const char *)__func__, 1827))) { | ||||||
1828 | other_channel = switch_core_session_get_channel(other_session); | ||||||
1829 | |||||||
1830 | switch_channel_set_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE, NULL)switch_channel_set_variable_var_check(channel, "signal_bridge_to" , ((void*)0), SWITCH_TRUE); | ||||||
1831 | switch_channel_set_variable(other_channel, SWITCH_SIGNAL_BRIDGE_VARIABLE, NULL)switch_channel_set_variable_var_check(other_channel, "signal_bridge_to" , ((void*)0), SWITCH_TRUE); | ||||||
1832 | |||||||
1833 | switch_channel_set_variable(channel, SWITCH_BRIDGE_VARIABLE, NULL)switch_channel_set_variable_var_check(channel, "bridge_to", ( (void*)0), SWITCH_TRUE); | ||||||
1834 | switch_channel_set_variable(other_channel, SWITCH_BRIDGE_VARIABLE, NULL)switch_channel_set_variable_var_check(other_channel, "bridge_to" , ((void*)0), SWITCH_TRUE); | ||||||
1835 | |||||||
1836 | /* If we are transferring the CALLER out of the bridge, we do not want to hang up on them */ | ||||||
1837 | switch_channel_set_variable(channel, SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE, "false")switch_channel_set_variable_var_check(channel, "hangup_after_bridge" , "false", SWITCH_TRUE); | ||||||
1838 | |||||||
1839 | switch_channel_hangup(other_channel, SWITCH_CAUSE_BLIND_TRANSFER)switch_channel_perform_hangup(other_channel, "src/switch_ivr.c" , (const char *)__func__, 1839, SWITCH_CAUSE_BLIND_TRANSFER); | ||||||
1840 | switch_ivr_media(uuid, SMF_NONE); | ||||||
1841 | |||||||
1842 | switch_core_session_rwunlock(other_session); | ||||||
1843 | } | ||||||
1844 | |||||||
1845 | switch_channel_set_caller_profile(channel, new_profile); | ||||||
1846 | |||||||
1847 | switch_channel_set_state(channel, CS_ROUTING)switch_channel_perform_set_state(channel, "src/switch_ivr.c", (const char *)__func__, 1847, CS_ROUTING); | ||||||
1848 | switch_channel_audio_sync(channel)switch_channel_perform_audio_sync(channel, "src/switch_ivr.c" , (const char *)__func__, 1848); | ||||||
1849 | |||||||
1850 | msg.message_id = SWITCH_MESSAGE_INDICATE_TRANSFER; | ||||||
1851 | msg.from = __FILE__"src/switch_ivr.c"; | ||||||
1852 | switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg , "src/switch_ivr.c", (const char *)__func__, 1852); | ||||||
1853 | |||||||
1854 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr.c", (const char *) __func__, 1854, (const char*)(session), SWITCH_LOG_NOTICE, "Transfer %s to %s[%s@%s]\n", switch_channel_get_name(channel), use_dialplan, | ||||||
1855 | extension, use_context); | ||||||
1856 | |||||||
1857 | |||||||
1858 | new_profile->transfer_source = switch_core_sprintf(new_profile->pool, "%ld:%s:bl_xfer:%s/%s/%s", | ||||||
1859 | (long) switch_epoch_time_now(NULL((void*)0)), new_profile->uuid_str, | ||||||
1860 | extension, use_context, use_dialplan); | ||||||
1861 | switch_channel_add_variable_var_check(channel, SWITCH_TRANSFER_HISTORY_VARIABLE"transfer_history", new_profile->transfer_source, SWITCH_FALSE, SWITCH_STACK_PUSH); | ||||||
1862 | switch_channel_set_variable_var_check(channel, SWITCH_TRANSFER_SOURCE_VARIABLE"transfer_source", new_profile->transfer_source, SWITCH_FALSE); | ||||||
1863 | return SWITCH_STATUS_SUCCESS; | ||||||
1864 | } | ||||||
1865 | |||||||
1866 | return SWITCH_STATUS_FALSE; | ||||||
1867 | } | ||||||
1868 | |||||||
1869 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_transfer_variable(switch_core_session_t *sessa, switch_core_session_t *sessb, char *var) | ||||||
1870 | { | ||||||
1871 | switch_channel_t *chana = switch_core_session_get_channel(sessa); | ||||||
1872 | switch_channel_t *chanb = switch_core_session_get_channel(sessb); | ||||||
1873 | switch_event_t *var_event; | ||||||
1874 | |||||||
1875 | const char *val = NULL((void*)0); | ||||||
1876 | uint8_t prefix = 0; | ||||||
1877 | |||||||
1878 | if (var && *var == '~') { | ||||||
1879 | var++; | ||||||
1880 | prefix = 1; | ||||||
1881 | } | ||||||
1882 | |||||||
1883 | if (var && !prefix) { | ||||||
1884 | if ((val = switch_channel_get_variable(chana, var)switch_channel_get_variable_dup(chana, var, SWITCH_TRUE, -1))) { | ||||||
1885 | switch_channel_set_variable(chanb, var, val)switch_channel_set_variable_var_check(chanb, var, val, SWITCH_TRUE ); | ||||||
1886 | } | ||||||
1887 | } else { | ||||||
1888 | switch_event_header_t *hi; | ||||||
1889 | |||||||
1890 | switch_channel_get_variables(chana, &var_event); | ||||||
1891 | |||||||
1892 | for (hi = var_event->headers; hi; hi = hi->next) { | ||||||
1893 | char *vvar = hi->name; | ||||||
1894 | char *vval = hi->value; | ||||||
1895 | if (vvar && vval && (!prefix || (var && !strncmp((char *) vvar, var, strlen(var))(__extension__ (__builtin_constant_p (strlen(var)) && ((__builtin_constant_p ((char *) vvar) && strlen ((char *) vvar) < ((size_t) (strlen(var)))) || (__builtin_constant_p (var) && strlen (var) < ((size_t) (strlen(var)))) ) ? __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p ((char *) vvar) && __builtin_constant_p (var) && (__s1_len = __builtin_strlen ((char *) vvar), __s2_len = __builtin_strlen (var), (!((size_t)(const void *)(((char *) vvar) + 1) - (size_t )(const void *)((char *) vvar) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((var) + 1) - (size_t)(const void * )(var) == 1) || __s2_len >= 4)) ? __builtin_strcmp ((char * ) vvar, var) : (__builtin_constant_p ((char *) vvar) && ((size_t)(const void *)(((char *) vvar) + 1) - (size_t)(const void *)((char *) vvar) == 1) && (__s1_len = __builtin_strlen ((char *) vvar), __s1_len < 4) ? (__builtin_constant_p (var ) && ((size_t)(const void *)((var) + 1) - (size_t)(const void *)(var) == 1) ? __builtin_strcmp ((char *) vvar, var) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (var); int __result = (((const unsigned char *) (const char *) ((char *) vvar))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ((char *) vvar))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ((char *) vvar))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ((char *) vvar))[3] - __s2[3]); } } __result ; }))) : (__builtin_constant_p (var) && ((size_t)(const void *)((var) + 1) - (size_t)(const void *)(var) == 1) && (__s2_len = __builtin_strlen (var), __s2_len < 4) ? (__builtin_constant_p ((char *) vvar) && ((size_t)(const void *)(((char *) vvar) + 1) - (size_t)(const void *)((char *) vvar) == 1) ? __builtin_strcmp ((char *) vvar, var) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ((char *) vvar ); int __result = (((const unsigned char *) (const char *) (var ))[0] - __s2[0]); if (__s2_len > 0 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (var) )[1] - __s2[1]); if (__s2_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (var) )[2] - __s2[2]); if (__s2_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (var))[ 3] - __s2[3]); } } __result; })))) : __builtin_strcmp ((char * ) vvar, var)))); }) : strncmp ((char *) vvar, var, strlen(var ))))))) { | ||||||
1896 | switch_channel_set_variable(chanb, (char *) vvar, (char *) vval)switch_channel_set_variable_var_check(chanb, (char *) vvar, ( char *) vval, SWITCH_TRUE); | ||||||
1897 | } | ||||||
1898 | } | ||||||
1899 | |||||||
1900 | switch_event_destroy(&var_event); | ||||||
1901 | } | ||||||
1902 | |||||||
1903 | return SWITCH_STATUS_SUCCESS; | ||||||
1904 | } | ||||||
1905 | |||||||
1906 | /******************************************************************************************************/ | ||||||
1907 | |||||||
1908 | struct switch_ivr_digit_stream_parser { | ||||||
1909 | int pool_auto_created; | ||||||
1910 | switch_memory_pool_t *pool; | ||||||
1911 | switch_hash_t *hash; | ||||||
1912 | switch_size_t maxlen; | ||||||
1913 | switch_size_t buflen; | ||||||
1914 | switch_size_t minlen; | ||||||
1915 | char terminator; | ||||||
1916 | unsigned int digit_timeout_ms; | ||||||
1917 | }; | ||||||
1918 | |||||||
1919 | struct switch_ivr_digit_stream { | ||||||
1920 | char *digits; | ||||||
1921 | switch_time_t last_digit_time; | ||||||
1922 | }; | ||||||
1923 | |||||||
1924 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_digit_stream_parser_new(switch_memory_pool_t *pool, switch_ivr_digit_stream_parser_t ** parser) | ||||||
1925 | { | ||||||
1926 | switch_status_t status = SWITCH_STATUS_FALSE; | ||||||
1927 | |||||||
1928 | if (parser != NULL((void*)0)) { | ||||||
1929 | int pool_auto_created = 0; | ||||||
1930 | |||||||
1931 | /* if the caller didn't provide a pool, make one */ | ||||||
1932 | if (pool == NULL((void*)0)) { | ||||||
1933 | switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "src/switch_ivr.c" , (const char *)__func__, 1933); | ||||||
1934 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_ivr.c", (const char *)__func__ , 1934, ((void*)0), SWITCH_LOG_DEBUG, "created a memory pool\n"); | ||||||
1935 | if (pool != NULL((void*)0)) { | ||||||
1936 | pool_auto_created = 1; | ||||||
1937 | } | ||||||
1938 | } | ||||||
1939 | /* if we have a pool, make a parser object */ | ||||||
1940 | if (pool != NULL((void*)0)) { | ||||||
1941 | *parser = (switch_ivr_digit_stream_parser_t *) switch_core_alloc(pool, sizeof(switch_ivr_digit_stream_parser_t))switch_core_perform_alloc(pool, sizeof(switch_ivr_digit_stream_parser_t ), "src/switch_ivr.c", (const char *)__func__, 1941); | ||||||
1942 | } | ||||||
1943 | /* if we have parser object, initialize it for the caller */ | ||||||
1944 | if (pool && *parser != NULL((void*)0)) { | ||||||
1945 | memset(*parser, 0, sizeof(switch_ivr_digit_stream_parser_t)); | ||||||
1946 | (*parser)->pool_auto_created = pool_auto_created; | ||||||
1947 | (*parser)->pool = pool; | ||||||
1948 | (*parser)->digit_timeout_ms = 1000; | ||||||
1949 | switch_core_hash_init(&(*parser)->hash)switch_core_hash_init_case(&(*parser)->hash, SWITCH_TRUE ); | ||||||
1950 | |||||||
1951 | status = SWITCH_STATUS_SUCCESS; | ||||||
1952 | } else { | ||||||
1953 | status = SWITCH_STATUS_MEMERR; | ||||||
1954 | /* if we can't create a parser object,clean up the pool if we created it */ | ||||||
1955 | if (pool != NULL((void*)0) && pool_auto_created) { | ||||||
1956 | switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "src/switch_ivr.c" , (const char *)__func__, 1956); | ||||||
1957 | } | ||||||
1958 | } | ||||||
1959 | } | ||||||
1960 | |||||||
1961 | return status; | ||||||
1962 | } | ||||||
1963 | |||||||
1964 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_digit_stream_parser_destroy(switch_ivr_digit_stream_parser_t *parser) | ||||||
1965 | { | ||||||
1966 | switch_status_t status = SWITCH_STATUS_FALSE; | ||||||
1967 | |||||||
1968 | if (parser != NULL((void*)0)) { | ||||||
1969 | if (parser->hash != NULL((void*)0)) { | ||||||
1970 | switch_core_hash_destroy(&parser->hash); | ||||||
1971 | parser->hash = NULL((void*)0); | ||||||
1972 | } | ||||||
1973 | /* free the memory pool if we created it */ | ||||||
1974 | if (parser->pool_auto_created && parser->pool != NULL((void*)0)) { | ||||||
1975 | status = switch_core_destroy_memory_pool(&parser->pool)switch_core_perform_destroy_memory_pool(&parser->pool, "src/switch_ivr.c", (const char *)__func__, 1975); | ||||||
1976 | } | ||||||
1977 | } | ||||||
1978 | |||||||
1979 | return status; | ||||||
1980 | } | ||||||
1981 | |||||||
1982 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_digit_stream_new(switch_ivr_digit_stream_parser_t *parser, switch_ivr_digit_stream_t ** stream) | ||||||
1983 | { | ||||||
1984 | switch_status_t status = SWITCH_STATUS_FALSE; | ||||||
1985 | |||||||
1986 | /* if we have a parser object memory pool and a stream object pointer that is null */ | ||||||
1987 | if (parser && stream && *stream == NULL((void*)0)) { | ||||||
1988 | *stream = (switch_ivr_digit_stream_t *) malloc(sizeof(**stream)); | ||||||
1989 | switch_assert(*stream)((*stream) ? (void) (0) : __assert_fail ("*stream", "src/switch_ivr.c" , 1989, __PRETTY_FUNCTION__)); | ||||||
1990 | memset(*stream, 0, sizeof(**stream)); | ||||||
1991 | switch_zmalloc((*stream)->digits, parser->buflen + 1)(void)(((((*stream)->digits = calloc(1, (parser->buflen + 1)))) ? (void) (0) : __assert_fail ("((*stream)->digits = calloc(1, (parser->buflen + 1)))" , "src/switch_ivr.c", 1991, __PRETTY_FUNCTION__)),(*stream)-> digits); | ||||||
1992 | status = SWITCH_STATUS_SUCCESS; | ||||||
1993 | } | ||||||
1994 | |||||||
1995 | return status; | ||||||
1996 | } | ||||||
1997 | |||||||
1998 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_digit_stream_destroy(switch_ivr_digit_stream_t ** stream) | ||||||
1999 | { | ||||||
2000 | switch_status_t status = SWITCH_STATUS_FALSE; | ||||||
2001 | |||||||
2002 | if (*stream) { | ||||||
2003 | switch_safe_free((*stream)->digits)if ((*stream)->digits) {free((*stream)->digits);(*stream )->digits=((void*)0);}; | ||||||
2004 | free(*stream); | ||||||
2005 | *stream = NULL((void*)0); | ||||||
2006 | status = SWITCH_STATUS_SUCCESS; | ||||||
2007 | } | ||||||
2008 | |||||||
2009 | return status; | ||||||
2010 | } | ||||||
2011 | |||||||
2012 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_digit_stream_parser_set_event(switch_ivr_digit_stream_parser_t *parser, char *digits, void *data) | ||||||
2013 | { | ||||||
2014 | switch_status_t status = SWITCH_STATUS_FALSE; | ||||||
2015 | |||||||
2016 | if (parser != NULL((void*)0) && digits != NULL((void*)0) && *digits && parser->hash != NULL((void*)0)) { | ||||||
2017 | |||||||
2018 | status = switch_core_hash_insert(parser->hash, digits, data)switch_core_hash_insert_destructor(parser->hash, digits, data , ((void*)0)); | ||||||
2019 | if (status == SWITCH_STATUS_SUCCESS) { | ||||||
2020 | switch_size_t len = strlen(digits); | ||||||
2021 | |||||||
2022 | /* if we don't have a terminator, then we have to try and | ||||||
2023 | * figure out when a digit set is completed, therefore we | ||||||
2024 | * keep track of the min and max digit lengths | ||||||
2025 | */ | ||||||
2026 | |||||||
2027 | if (len > parser->buflen) { | ||||||
2028 | parser->buflen = len; | ||||||
2029 | } | ||||||
2030 | |||||||
2031 | if (parser->terminator == '\0') { | ||||||
2032 | if (len > parser->maxlen) { | ||||||
2033 | parser->maxlen = len; | ||||||
2034 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_ivr.c", (const char *)__func__ , 2034, ((void*)0), SWITCH_LOG_DEBUG, "max len %u\n", (uint32_t) parser->maxlen); | ||||||
2035 | } | ||||||
2036 | if (parser->minlen == 0 || len < parser->minlen) { | ||||||
2037 | parser->minlen = len; | ||||||
2038 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_ivr.c", (const char *)__func__ , 2038, ((void*)0), SWITCH_LOG_DEBUG, "min len %u\n", (uint32_t) parser->minlen); | ||||||
2039 | } | ||||||
2040 | } else { | ||||||
2041 | /* since we have a terminator, reset min and max */ | ||||||
2042 | parser->minlen = 0; | ||||||
2043 | parser->maxlen = 0; | ||||||
2044 | } | ||||||
2045 | } | ||||||
2046 | } | ||||||
2047 | if (status != SWITCH_STATUS_SUCCESS) { | ||||||
2048 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_ivr.c", (const char *)__func__ , 2048, ((void*)0), SWITCH_LOG_DEBUG, "unable to add hash for '%s'\n", digits); | ||||||
2049 | } | ||||||
2050 | |||||||
2051 | return status; | ||||||
2052 | } | ||||||
2053 | |||||||
2054 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_digit_stream_parser_del_event(switch_ivr_digit_stream_parser_t *parser, char *digits) | ||||||
2055 | { | ||||||
2056 | switch_status_t status = SWITCH_STATUS_FALSE; | ||||||
2057 | |||||||
2058 | if (parser != NULL((void*)0) && digits != NULL((void*)0) && *digits) { | ||||||
2059 | status = switch_core_hash_delete(parser->hash, digits); | ||||||
2060 | } | ||||||
2061 | |||||||
2062 | if (status != SWITCH_STATUS_SUCCESS) { | ||||||
2063 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_ivr.c", (const char *)__func__ , 2063, ((void*)0), SWITCH_LOG_DEBUG, "unable to del hash for '%s'\n", digits); | ||||||
2064 | } | ||||||
2065 | |||||||
2066 | return status; | ||||||
2067 | } | ||||||
2068 | |||||||
2069 | SWITCH_DECLARE(void *)__attribute__((visibility("default"))) void * switch_ivr_digit_stream_parser_feed(switch_ivr_digit_stream_parser_t *parser, switch_ivr_digit_stream_t *stream, char digit) | ||||||
2070 | { | ||||||
2071 | void *result = NULL((void*)0); | ||||||
2072 | switch_size_t len; | ||||||
2073 | |||||||
2074 | switch_assert(parser)((parser) ? (void) (0) : __assert_fail ("parser", "src/switch_ivr.c" , 2074, __PRETTY_FUNCTION__)); | ||||||
2075 | switch_assert(stream)((stream) ? (void) (0) : __assert_fail ("stream", "src/switch_ivr.c" , 2075, __PRETTY_FUNCTION__)); | ||||||
2076 | switch_assert(stream->digits)((stream->digits) ? (void) (0) : __assert_fail ("stream->digits" , "src/switch_ivr.c", 2076, __PRETTY_FUNCTION__)); | ||||||
2077 | |||||||
2078 | len = strlen(stream->digits); | ||||||
2079 | |||||||
2080 | /* handle new digit arrivals */ | ||||||
2081 | if (digit) { | ||||||
2082 | /* if it's not a terminator digit, add it to the collected digits */ | ||||||
2083 | if (digit != parser->terminator) { | ||||||
2084 | /* if collected digits length >= the max length of the keys | ||||||
2085 | * in the hash table, then left shift the digit string | ||||||
2086 | */ | ||||||
2087 | if (len > 0 && parser->maxlen != 0 && len >= parser->maxlen) { | ||||||
2088 | char *src = stream->digits + 1; | ||||||
2089 | char *dst = stream->digits; | ||||||
2090 | |||||||
2091 | while (*src) { | ||||||
2092 | *(dst++) = *(src++); | ||||||
2093 | } | ||||||
2094 | *dst = digit; | ||||||
2095 | } else { | ||||||
2096 | *(stream->digits + (len++)) = digit; | ||||||
2097 | *(stream->digits + len) = '\0'; | ||||||
2098 | stream->last_digit_time = switch_micro_time_now() / 1000; | ||||||
2099 | } | ||||||
2100 | } | ||||||
2101 | } | ||||||
2102 | |||||||
2103 | /* don't allow collected digit string testing if there are varying sized keys until timeout */ | ||||||
2104 | if (parser->maxlen - parser->minlen > 0 && (switch_micro_time_now() / 1000) - stream->last_digit_time < parser->digit_timeout_ms) { | ||||||
2105 | len = 0; | ||||||
2106 | } | ||||||
2107 | /* if we have digits to test */ | ||||||
2108 | if (len) { | ||||||
2109 | result = switch_core_hash_find(parser->hash, stream->digits); | ||||||
2110 | /* if we matched the digit string, or this digit is the terminator | ||||||
2111 | * reset the collected digits for next digit string | ||||||
2112 | */ | ||||||
2113 | if (result != NULL((void*)0) || parser->terminator == digit) { | ||||||
2114 | *stream->digits = '\0'; | ||||||
2115 | } | ||||||
2116 | } | ||||||
2117 | |||||||
2118 | |||||||
2119 | return result; | ||||||
2120 | } | ||||||
2121 | |||||||
2122 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_digit_stream_reset(switch_ivr_digit_stream_t *stream) | ||||||
2123 | { | ||||||
2124 | switch_status_t status = SWITCH_STATUS_FALSE; | ||||||
2125 | switch_assert(stream)((stream) ? (void) (0) : __assert_fail ("stream", "src/switch_ivr.c" , 2125, __PRETTY_FUNCTION__)); | ||||||
2126 | switch_assert(stream->digits)((stream->digits) ? (void) (0) : __assert_fail ("stream->digits" , "src/switch_ivr.c", 2126, __PRETTY_FUNCTION__)); | ||||||
2127 | |||||||
2128 | *stream->digits = '\0'; | ||||||
2129 | stream->last_digit_time = 0; | ||||||
2130 | status = SWITCH_STATUS_SUCCESS; | ||||||
2131 | |||||||
2132 | return status; | ||||||
2133 | } | ||||||
2134 | |||||||
2135 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_digit_stream_parser_set_terminator(switch_ivr_digit_stream_parser_t *parser, char digit) | ||||||
2136 | { | ||||||
2137 | switch_status_t status = SWITCH_STATUS_FALSE; | ||||||
2138 | |||||||
2139 | if (parser != NULL((void*)0)) { | ||||||
2140 | parser->terminator = digit; | ||||||
2141 | /* since we have a terminator, reset min and max */ | ||||||
2142 | parser->minlen = 0; | ||||||
2143 | parser->maxlen = 0; | ||||||
2144 | status = SWITCH_STATUS_SUCCESS; | ||||||
2145 | } | ||||||
2146 | |||||||
2147 | return status; | ||||||
2148 | } | ||||||
2149 | |||||||
2150 | SWITCH_DECLARE(int)__attribute__((visibility("default"))) int switch_ivr_set_xml_profile_data(switch_xml_t xml, switch_caller_profile_t *caller_profile, int off) | ||||||
2151 | { | ||||||
2152 | switch_xml_t param; | ||||||
2153 | |||||||
2154 | if (!(param = switch_xml_add_child_d(xml, "username", off++)switch_xml_set_flag(switch_xml_add_child(xml, (__extension__ ( __builtin_constant_p ("username") && ((size_t)(const void *)(("username") + 1) - (size_t)(const void *)("username") == 1) ? (((const char *) ("username"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("username" ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "username" , __len); __retval; })) : __strdup ("username"))), off++), SWITCH_XML_NAMEM ))) { | ||||||
Within the expansion of the macro 'switch_xml_add_child_d':
| |||||||
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 | */ |