File: | src/switch_ivr.c |
Location: | line 2174, 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 ))) { | |||||||||
| ||||||||||
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 | */ |