]>
Commit | Line | Data |
---|---|---|
03845667 MJ |
1 | /* |
2 | * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application | |
6e7d5d08 | 3 | * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org> |
03845667 MJ |
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 | |
ae220d33 | 20 | * Anthony Minessale II <anthm@freeswitch.org> |
03845667 MJ |
21 | * Portions created by the Initial Developer are Copyright (C) |
22 | * the Initial Developer. All Rights Reserved. | |
23 | * | |
24 | * Contributor(s): | |
25 | * | |
ae220d33 | 26 | * Anthony Minessale II <anthm@freeswitch.org> |
03845667 MJ |
27 | * |
28 | * | |
29 | * switch_cpp.cpp -- C++ wrapper | |
30 | * | |
31 | */ | |
32 | ||
83f84876 AM |
33 | #include <switch.h> |
34 | #include <switch_cpp.h> | |
35 | ||
8107c49a MJ |
36 | #ifdef _MSC_VER |
37 | #pragma warning(disable:4127 4003) | |
38 | #endif | |
39 | ||
eec83be1 AM |
40 | static void event_handler(switch_event_t *event) |
41 | { | |
a1cf7067 AM |
42 | EventConsumer *E = (EventConsumer *) event->bind_user_data; |
43 | switch_event_t *dup; | |
44 | ||
45 | switch_event_dup(&dup, event); | |
46 | ||
47 | if (switch_queue_trypush(E->events, dup) != SWITCH_STATUS_SUCCESS) { | |
48 | switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot queue any more events.....\n"); | |
1e22ba2b | 49 | switch_event_destroy(&dup); |
a1cf7067 AM |
50 | } |
51 | ||
eec83be1 AM |
52 | } |
53 | ||
830755ac | 54 | SWITCH_DECLARE_CONSTRUCTOR EventConsumer::EventConsumer(const char *event_name, const char *subclass_name, int len) |
eec83be1 | 55 | { |
a7f74af7 AM |
56 | |
57 | switch_core_new_memory_pool(&pool); | |
830755ac | 58 | switch_queue_create(&events, len, pool); |
05bf1d83 | 59 | node_index = 0; |
0e41c484 | 60 | ready = 1; |
a1cf7067 | 61 | |
a7f74af7 AM |
62 | if (!zstr(event_name)) { |
63 | bind(event_name, subclass_name); | |
eec83be1 | 64 | } |
a7f74af7 AM |
65 | } |
66 | ||
67 | SWITCH_DECLARE(int) EventConsumer::bind(const char *event_name, const char *subclass_name) | |
68 | { | |
69 | switch_event_types_t event_id = SWITCH_EVENT_CUSTOM; | |
a7f74af7 | 70 | |
1e22ba2b AM |
71 | if (!ready) { |
72 | return 0; | |
73 | } | |
74 | ||
94d28e0f MJ |
75 | if (switch_name_event(event_name, &event_id) != SWITCH_STATUS_SUCCESS) { |
76 | switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't bind to %s, event not found\n", event_name); | |
77 | return 0; | |
78 | } | |
a7f74af7 AM |
79 | |
80 | if (zstr(subclass_name)) { | |
81 | subclass_name = NULL; | |
82 | } | |
a1cf7067 | 83 | |
7fd3aff6 AM |
84 | if (node_index <= SWITCH_EVENT_ALL && |
85 | switch_event_bind_removable(__FILE__, event_id, subclass_name, event_handler, this, &enodes[node_index]) == SWITCH_STATUS_SUCCESS) { | |
a7f74af7 | 86 | switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "bound to %s %s\n", event_name, switch_str_nil(subclass_name)); |
7fd3aff6 | 87 | node_index++; |
a7f74af7 | 88 | return 1; |
eec83be1 | 89 | } |
94d28e0f MJ |
90 | |
91 | switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot bind to %s %s\n", event_name, switch_str_nil(subclass_name)); | |
92 | return 0; | |
a1cf7067 AM |
93 | } |
94 | ||
eec83be1 | 95 | |
b992e296 | 96 | SWITCH_DECLARE(Event *) EventConsumer::pop(int block, int timeout) |
a1cf7067 AM |
97 | { |
98 | void *pop = NULL; | |
99 | Event *ret = NULL; | |
100 | switch_event_t *event; | |
1e22ba2b AM |
101 | |
102 | if (!ready) { | |
103 | return NULL; | |
104 | } | |
eec83be1 | 105 | |
a1cf7067 | 106 | if (block) { |
b992e296 JL |
107 | if (timeout > 0) { |
108 | switch_queue_pop_timeout(events, &pop, (switch_interval_time_t) timeout * 1000); // millisec rather than microsec | |
109 | } else { | |
110 | switch_queue_pop(events, &pop); | |
111 | } | |
a1cf7067 AM |
112 | } else { |
113 | switch_queue_trypop(events, &pop); | |
114 | } | |
115 | ||
116 | if ((event = (switch_event_t *) pop)) { | |
cf22bd97 | 117 | ret = new Event(event, 1); |
a1cf7067 | 118 | } |
eec83be1 | 119 | |
a1cf7067 AM |
120 | return ret; |
121 | } | |
eec83be1 | 122 | |
1e22ba2b | 123 | SWITCH_DECLARE(void) EventConsumer::cleanup() |
eec83be1 | 124 | { |
1e22ba2b | 125 | |
7fd3aff6 | 126 | uint32_t i; |
1e22ba2b AM |
127 | void *pop; |
128 | ||
129 | if (!ready) { | |
130 | return; | |
131 | } | |
132 | ||
133 | ready = 0; | |
a7f74af7 | 134 | |
7fd3aff6 AM |
135 | for (i = 0; i < node_index; i++) { |
136 | switch_event_unbind(&enodes[i]); | |
137 | } | |
a1cf7067 | 138 | |
1e22ba2b AM |
139 | node_index = 0; |
140 | ||
608ca822 AM |
141 | if (events) { |
142 | switch_queue_interrupt_all(events); | |
143 | } | |
144 | ||
1e22ba2b AM |
145 | while(switch_queue_trypop(events, &pop) == SWITCH_STATUS_SUCCESS) { |
146 | switch_event_t *event = (switch_event_t *) pop; | |
147 | switch_event_destroy(&event); | |
148 | } | |
149 | ||
150 | ||
a1cf7067 | 151 | switch_core_destroy_memory_pool(&pool); |
1e22ba2b AM |
152 | |
153 | } | |
154 | ||
155 | ||
156 | SWITCH_DECLARE_CONSTRUCTOR EventConsumer::~EventConsumer() | |
157 | { | |
158 | cleanup(); | |
eec83be1 | 159 | } |
aa47e3e5 AM |
160 | |
161 | SWITCH_DECLARE_CONSTRUCTOR IVRMenu::IVRMenu(IVRMenu *main, | |
162 | const char *name, | |
163 | const char *greeting_sound, | |
164 | const char *short_greeting_sound, | |
165 | const char *invalid_sound, | |
166 | const char *exit_sound, | |
fb34ff9a | 167 | const char *transfer_sound, |
aa47e3e5 AM |
168 | const char *confirm_macro, |
169 | const char *confirm_key, | |
85c26566 BW |
170 | const char *tts_engine, |
171 | const char *tts_voice, | |
aa47e3e5 AM |
172 | int confirm_attempts, |
173 | int inter_timeout, | |
174 | int digit_len, | |
175 | int timeout, | |
fb06cc2d AM |
176 | int max_failures, |
177 | int max_timeouts) | |
aa47e3e5 AM |
178 | { |
179 | menu = NULL; | |
180 | switch_core_new_memory_pool(&pool); | |
181 | switch_assert(pool); | |
df7637f6 | 182 | if (zstr(name)) { |
aa47e3e5 AM |
183 | name = "no name"; |
184 | } | |
185 | ||
186 | switch_ivr_menu_init(&menu, main ? main->menu : NULL, name, greeting_sound, short_greeting_sound, invalid_sound, | |
fb34ff9a | 187 | exit_sound, transfer_sound, confirm_macro, confirm_key, tts_engine, tts_voice, confirm_attempts, inter_timeout, |
85c26566 | 188 | digit_len, timeout, max_failures, max_timeouts, pool); |
aa47e3e5 AM |
189 | |
190 | ||
191 | } | |
192 | ||
193 | SWITCH_DECLARE_CONSTRUCTOR IVRMenu::~IVRMenu() | |
194 | { | |
195 | if (menu) { | |
196 | switch_ivr_menu_stack_free(menu); | |
197 | } | |
198 | switch_core_destroy_memory_pool(&pool); | |
199 | } | |
200 | ||
201 | SWITCH_DECLARE(void) IVRMenu::bindAction(char *action, const char *arg, const char *bind) | |
202 | { | |
203 | switch_ivr_action_t ivr_action = SWITCH_IVR_ACTION_NOOP; | |
204 | ||
878bbceb AM |
205 | this_check_void(); |
206 | ||
aa47e3e5 AM |
207 | if (switch_ivr_menu_str2action(action, &ivr_action) == SWITCH_STATUS_SUCCESS) { |
208 | switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "bind %s to %s(%s)\n", bind, action, arg); | |
209 | switch_ivr_menu_bind_action(menu, ivr_action, arg, bind); | |
210 | } else { | |
211 | switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "invalid action %s\n", action); | |
212 | } | |
213 | } | |
214 | ||
215 | SWITCH_DECLARE(void) IVRMenu::execute(CoreSession *session, const char *name) | |
216 | { | |
878bbceb | 217 | this_check_void(); |
aa47e3e5 AM |
218 | switch_ivr_menu_execute(session->session, menu, (char *)name, NULL); |
219 | } | |
220 | ||
802794b9 | 221 | SWITCH_DECLARE_CONSTRUCTOR API::API(CoreSession *s) |
8f5a873d | 222 | { |
802794b9 AM |
223 | if (s) { |
224 | session = s->session; | |
225 | } else { | |
226 | session = NULL; | |
227 | } | |
8f5a873d AM |
228 | } |
229 | ||
230 | SWITCH_DECLARE_CONSTRUCTOR API::~API() | |
231 | { | |
3a00260d | 232 | return; |
8f5a873d AM |
233 | } |
234 | ||
235 | ||
1a2131de | 236 | SWITCH_DECLARE(const char *) API::execute(const char *cmd, const char *arg) |
8f5a873d AM |
237 | { |
238 | switch_stream_handle_t stream = { 0 }; | |
878bbceb | 239 | this_check(""); |
4d7a0ac0 | 240 | |
8f5a873d | 241 | SWITCH_STANDARD_STREAM(stream); |
4d7a0ac0 AM |
242 | |
243 | if (zstr(cmd)) { | |
244 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No application specified\n"); | |
245 | stream.write_function(&stream, "-ERR No application specified"); | |
246 | } else { | |
247 | switch_api_execute(cmd, arg, session, &stream); | |
248 | } | |
249 | ||
3a00260d | 250 | return (char *) stream.data; |
8f5a873d AM |
251 | } |
252 | ||
072ec6a7 AM |
253 | |
254 | /* we have to do this as a string because swig and languages can't find an embedded way to pass a big int */ | |
8812477e | 255 | SWITCH_DECLARE(char *) API::getTime(void) |
072ec6a7 AM |
256 | { |
257 | switch_time_t now = switch_micro_time_now() / 1000; | |
258 | snprintf(time_buf, sizeof(time_buf), "%" SWITCH_TIME_T_FMT, now); | |
259 | return time_buf; | |
260 | } | |
261 | ||
262 | ||
263 | ||
1a2131de | 264 | SWITCH_DECLARE(const char *) API::executeString(const char *cmd) |
8f5a873d AM |
265 | { |
266 | char *arg; | |
267 | switch_stream_handle_t stream = { 0 }; | |
cc2efd55 | 268 | char *mycmd = NULL; |
8f5a873d | 269 | |
878bbceb AM |
270 | this_check(""); |
271 | ||
4e997750 ML |
272 | SWITCH_STANDARD_STREAM(stream); |
273 | ||
274 | if (zstr(cmd)) { | |
275 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No application specified\n"); | |
276 | stream.write_function(&stream, "-ERR No application specified"); | |
277 | } else { | |
278 | mycmd = strdup(cmd); | |
cc2efd55 | 279 | |
4e997750 ML |
280 | switch_assert(mycmd); |
281 | ||
282 | if ((arg = strchr(mycmd, ' '))) { | |
283 | *arg++ = '\0'; | |
284 | } | |
cc2efd55 | 285 | |
4e997750 ML |
286 | switch_api_execute(mycmd, arg, session, &stream); |
287 | switch_safe_free(mycmd); | |
8f5a873d AM |
288 | } |
289 | ||
3a00260d | 290 | return (char *) stream.data; |
8f5a873d | 291 | } |
e028f269 | 292 | |
069d4681 | 293 | SWITCH_DECLARE_CONSTRUCTOR Event::Event(const char *type, const char *subclass_name) |
ae76db7b AM |
294 | { |
295 | switch_event_types_t event_id; | |
ae76db7b | 296 | |
c5086b15 AM |
297 | if (!strcasecmp(type, "json") && !zstr(subclass_name)) { |
298 | if (switch_event_create_json(&event, subclass_name) != SWITCH_STATUS_SUCCESS) { | |
299 | return; | |
300 | } | |
301 | ||
302 | event_id = event->event_id; | |
303 | ||
304 | } else { | |
305 | if (switch_name_event(type, &event_id) != SWITCH_STATUS_SUCCESS) { | |
306 | event_id = SWITCH_EVENT_MESSAGE; | |
307 | } | |
7aa7dd7e | 308 | |
c5086b15 AM |
309 | if (!zstr(subclass_name) && event_id != SWITCH_EVENT_CUSTOM) { |
310 | switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_WARNING, "Changing event type to custom because you specified a subclass name!\n"); | |
311 | event_id = SWITCH_EVENT_CUSTOM; | |
312 | } | |
313 | ||
314 | if (switch_event_create_subclass(&event, event_id, subclass_name) != SWITCH_STATUS_SUCCESS) { | |
315 | switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "Failed to create event!\n"); | |
316 | event = NULL; | |
317 | } | |
7aa7dd7e BW |
318 | } |
319 | ||
59526679 AM |
320 | serialized_string = NULL; |
321 | mine = 1; | |
322 | } | |
323 | ||
069d4681 | 324 | SWITCH_DECLARE_CONSTRUCTOR Event::Event(switch_event_t *wrap_me, int free_me) |
59526679 AM |
325 | { |
326 | event = wrap_me; | |
327 | mine = free_me; | |
328 | serialized_string = NULL; | |
ae76db7b AM |
329 | } |
330 | ||
069d4681 | 331 | SWITCH_DECLARE_CONSTRUCTOR Event::~Event() |
ae76db7b | 332 | { |
59526679 AM |
333 | |
334 | if (serialized_string) { | |
335 | free(serialized_string); | |
336 | } | |
337 | ||
338 | if (event && mine) { | |
ae76db7b AM |
339 | switch_event_destroy(&event); |
340 | } | |
341 | } | |
342 | ||
7333d46d AM |
343 | SWITCH_DECLARE(int)Event::chat_execute(const char *app, const char *data) |
344 | { | |
345 | return (int) switch_core_execute_chat_app(event, app, data); | |
346 | } | |
347 | ||
348 | SWITCH_DECLARE(int)Event::chat_send(const char *dest_proto) | |
349 | { | |
350 | if (zstr(dest_proto)) { | |
351 | dest_proto = switch_event_get_header(event, "dest_proto"); | |
352 | } | |
353 | ||
354 | return (int) switch_core_chat_send(dest_proto, event); | |
355 | } | |
59526679 | 356 | |
069d4681 | 357 | SWITCH_DECLARE(const char *)Event::serialize(const char *format) |
59526679 | 358 | { |
878bbceb AM |
359 | this_check(""); |
360 | ||
59526679 | 361 | |
a1cf7067 AM |
362 | switch_safe_free(serialized_string); |
363 | ||
59526679 AM |
364 | if (!event) { |
365 | return ""; | |
366 | } | |
367 | ||
368 | if (format && !strcasecmp(format, "xml")) { | |
59526679 | 369 | switch_xml_t xml; |
59526679 AM |
370 | if ((xml = switch_event_xmlize(event, SWITCH_VA_NONE))) { |
371 | serialized_string = switch_xml_toxml(xml, SWITCH_FALSE); | |
372 | switch_xml_free(xml); | |
373 | return serialized_string; | |
374 | } else { | |
375 | return ""; | |
376 | } | |
c5086b15 AM |
377 | } else if (format && !strcasecmp(format, "json")) { |
378 | switch_event_serialize_json(event, &serialized_string); | |
379 | return serialized_string; | |
59526679 AM |
380 | } else { |
381 | if (switch_event_serialize(event, &serialized_string, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) { | |
e858a1d8 AM |
382 | char *new_serialized_string = switch_mprintf("'%s'", serialized_string); |
383 | free(serialized_string); | |
384 | serialized_string = new_serialized_string; | |
59526679 AM |
385 | return serialized_string; |
386 | } | |
387 | } | |
388 | ||
389 | return ""; | |
390 | ||
391 | } | |
392 | ||
069d4681 | 393 | SWITCH_DECLARE(bool) Event::fire(void) |
ae76db7b | 394 | { |
878bbceb AM |
395 | |
396 | this_check(false); | |
397 | ||
59526679 AM |
398 | if (!mine) { |
399 | switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "Not My event!\n"); | |
400 | return false; | |
401 | } | |
402 | ||
ae76db7b | 403 | if (event) { |
2b5f3563 AM |
404 | switch_event_t *new_event; |
405 | if (switch_event_dup(&new_event, event) == SWITCH_STATUS_SUCCESS) { | |
7aa7dd7e BW |
406 | if (switch_event_fire(&new_event) != SWITCH_STATUS_SUCCESS) { |
407 | switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "Failed to fire the event!\n"); | |
408 | switch_event_destroy(&new_event); | |
409 | return false; | |
410 | } | |
2b5f3563 | 411 | return true; |
7aa7dd7e BW |
412 | } else { |
413 | switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "Failed to dup the event!\n"); | |
2b5f3563 | 414 | } |
7aa7dd7e BW |
415 | } else { |
416 | switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "Trying to fire an event that does not exist!\n"); | |
ae76db7b AM |
417 | } |
418 | return false; | |
419 | } | |
420 | ||
b6d649fc | 421 | SWITCH_DECLARE(bool) Event::setPriority(switch_priority_t priority) |
ae76db7b | 422 | { |
878bbceb AM |
423 | this_check(false); |
424 | ||
ae76db7b AM |
425 | if (event) { |
426 | switch_event_set_priority(event, priority); | |
427 | return true; | |
7aa7dd7e BW |
428 | } else { |
429 | switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "Trying to setPriority an event that does not exist!\n"); | |
ae76db7b AM |
430 | } |
431 | return false; | |
432 | } | |
433 | ||
c27a26e3 | 434 | SWITCH_DECLARE(const char *)Event::getHeader(const char *header_name) |
ae76db7b | 435 | { |
878bbceb AM |
436 | this_check(""); |
437 | ||
4e997750 ML |
438 | if (zstr(header_name)) { |
439 | switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Trying to getHeader an invalid header!\n"); | |
440 | return NULL; | |
441 | } | |
442 | ||
ae76db7b AM |
443 | if (event) { |
444 | return switch_event_get_header(event, header_name); | |
7aa7dd7e BW |
445 | } else { |
446 | switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "Trying to getHeader an event that does not exist!\n"); | |
ae76db7b AM |
447 | } |
448 | return NULL; | |
449 | } | |
450 | ||
b6d649fc | 451 | SWITCH_DECLARE(bool) Event::addHeader(const char *header_name, const char *value) |
ae76db7b | 452 | { |
878bbceb AM |
453 | this_check(false); |
454 | ||
ae76db7b AM |
455 | if (event) { |
456 | return switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header_name, value) == SWITCH_STATUS_SUCCESS ? true : false; | |
7aa7dd7e BW |
457 | } else { |
458 | switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "Trying to addHeader an event that does not exist!\n"); | |
ae76db7b AM |
459 | } |
460 | ||
461 | return false; | |
462 | } | |
463 | ||
b6d649fc | 464 | SWITCH_DECLARE(bool) Event::delHeader(const char *header_name) |
ae76db7b | 465 | { |
878bbceb AM |
466 | this_check(false); |
467 | ||
4e997750 ML |
468 | if (zstr(header_name)) { |
469 | switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Trying to delHeader an invalid header!\n"); | |
470 | return false; | |
471 | } | |
472 | ||
ae76db7b AM |
473 | if (event) { |
474 | return switch_event_del_header(event, header_name) == SWITCH_STATUS_SUCCESS ? true : false; | |
7aa7dd7e BW |
475 | } else { |
476 | switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "Trying to delHeader an event that does not exist!\n"); | |
ae76db7b AM |
477 | } |
478 | ||
479 | return false; | |
480 | } | |
481 | ||
482 | ||
b6d649fc | 483 | SWITCH_DECLARE(bool) Event::addBody(const char *value) |
ae76db7b | 484 | { |
878bbceb AM |
485 | this_check(false); |
486 | ||
ae76db7b AM |
487 | if (event) { |
488 | return switch_event_add_body(event, "%s", value) == SWITCH_STATUS_SUCCESS ? true : false; | |
7aa7dd7e BW |
489 | } else { |
490 | switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "Trying to addBody an event that does not exist!\n"); | |
ae76db7b AM |
491 | } |
492 | ||
493 | return false; | |
494 | } | |
495 | ||
b6d649fc | 496 | SWITCH_DECLARE(char *)Event::getBody(void) |
ae76db7b | 497 | { |
878bbceb AM |
498 | |
499 | this_check((char *)""); | |
500 | ||
ae76db7b AM |
501 | if (event) { |
502 | return switch_event_get_body(event); | |
7aa7dd7e BW |
503 | } else { |
504 | switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "Trying to getBody an event that does not exist!\n"); | |
ae76db7b AM |
505 | } |
506 | ||
507 | return NULL; | |
508 | } | |
509 | ||
d5e4046d | 510 | SWITCH_DECLARE(const char *)Event::getType(void) |
b6d649fc | 511 | { |
878bbceb AM |
512 | this_check(""); |
513 | ||
b6d649fc AM |
514 | if (event) { |
515 | return switch_event_name(event->event_id); | |
7aa7dd7e BW |
516 | } else { |
517 | switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "Trying to getType an event that does not exist!\n"); | |
b6d649fc AM |
518 | } |
519 | ||
d5e4046d | 520 | return (char *) "invalid"; |
b6d649fc AM |
521 | } |
522 | ||
a3ccefa7 AM |
523 | |
524 | SWITCH_DECLARE_CONSTRUCTOR DTMF::DTMF(char idigit, uint32_t iduration) | |
525 | { | |
526 | digit = idigit; | |
527 | ||
528 | if (iduration == 0) { | |
a358cf8e | 529 | iduration = SWITCH_DEFAULT_DTMF_DURATION; |
a3ccefa7 AM |
530 | } |
531 | ||
532 | duration = iduration; | |
533 | } | |
534 | ||
535 | SWITCH_DECLARE_CONSTRUCTOR DTMF::~DTMF() | |
536 | { | |
537 | ||
538 | } | |
539 | ||
540 | ||
069d4681 | 541 | SWITCH_DECLARE_CONSTRUCTOR Stream::Stream() |
ae76db7b AM |
542 | { |
543 | SWITCH_STANDARD_STREAM(mystream); | |
544 | stream_p = &mystream; | |
545 | mine = 1; | |
546 | } | |
547 | ||
069d4681 | 548 | SWITCH_DECLARE_CONSTRUCTOR Stream::Stream(switch_stream_handle_t *sp) |
ae76db7b AM |
549 | { |
550 | stream_p = sp; | |
551 | mine = 0; | |
552 | } | |
553 | ||
554 | ||
069d4681 | 555 | SWITCH_DECLARE_CONSTRUCTOR Stream::~Stream() |
ae76db7b AM |
556 | { |
557 | if (mine) { | |
558 | switch_safe_free(mystream.data); | |
559 | } | |
560 | } | |
561 | ||
31f78d8c | 562 | /* WARNING!! you are not encouraged to use this unless you understand the risk!!! */ |
1a4e6e30 | 563 | SWITCH_DECLARE(const char *) Stream::read(int *len) |
31f78d8c SD |
564 | { |
565 | uint8_t *buff; | |
31f78d8c | 566 | |
1a4e6e30 | 567 | this_check(NULL); |
31f78d8c | 568 | |
1a4e6e30 | 569 | if (!stream_p->read_function) return NULL; |
31f78d8c | 570 | |
1a4e6e30 | 571 | buff = stream_p->read_function(stream_p, len); |
31f78d8c | 572 | |
aa15994c SD |
573 | if (!buff || *len <= 0) { |
574 | *len = 0; | |
575 | return NULL; | |
576 | } | |
31f78d8c | 577 | |
1a4e6e30 | 578 | return (const char *)buff; |
31f78d8c SD |
579 | } |
580 | ||
069d4681 | 581 | SWITCH_DECLARE(void) Stream::write(const char *data) |
ae76db7b | 582 | { |
878bbceb | 583 | this_check_void(); |
ae76db7b AM |
584 | stream_p->write_function(stream_p, "%s", data); |
585 | } | |
586 | ||
1a4e6e30 | 587 | SWITCH_DECLARE(void) Stream::raw_write(const char *data, int len) |
31f78d8c SD |
588 | { |
589 | this_check_void(); | |
1a4e6e30 | 590 | stream_p->raw_write_function(stream_p, (uint8_t *)data, len); |
31f78d8c SD |
591 | } |
592 | ||
069d4681 | 593 | SWITCH_DECLARE(const char *)Stream::get_data() |
ae76db7b | 594 | { |
878bbceb AM |
595 | this_check(""); |
596 | ||
ae76db7b AM |
597 | return stream_p ? (const char *)stream_p->data : NULL; |
598 | } | |
e028f269 MJ |
599 | |
600 | ||
47985c56 | 601 | SWITCH_DECLARE_CONSTRUCTOR CoreSession::CoreSession() |
e028f269 | 602 | { |
24a27c6e | 603 | init_vars(); |
e028f269 | 604 | } |
83f84876 | 605 | |
df5afbca | 606 | SWITCH_DECLARE_CONSTRUCTOR CoreSession::CoreSession(char *nuuid, CoreSession *a_leg) |
83f84876 | 607 | { |
0ba25358 AM |
608 | switch_channel_t *other_channel = NULL; |
609 | ||
a06997ee | 610 | init_vars(); |
24a27c6e | 611 | |
0ba25358 AM |
612 | if (a_leg && a_leg->session) { |
613 | other_channel = switch_core_session_get_channel(a_leg->session); | |
614 | } | |
615 | ||
301ea9fb | 616 | if (!strchr(nuuid, '/') && (session = switch_core_session_force_locate(nuuid))) { |
94b22258 | 617 | uuid = strdup(nuuid); |
d895c81d | 618 | channel = switch_core_session_get_channel(session); |
94b22258 | 619 | allocated = 1; |
ae76db7b | 620 | } else { |
2261b687 | 621 | cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; |
2fa0c491 | 622 | if (switch_ivr_originate(a_leg ? a_leg->session : NULL, &session, &cause, nuuid, 60, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL) |
a579a283 | 623 | == SWITCH_STATUS_SUCCESS) { |
d895c81d | 624 | channel = switch_core_session_get_channel(session); |
ae76db7b AM |
625 | allocated = 1; |
626 | switch_set_flag(this, S_HUP); | |
627 | uuid = strdup(switch_core_session_get_uuid(session)); | |
4b929592 | 628 | switch_channel_set_state(switch_core_session_get_channel(session), CS_SOFT_EXECUTE); |
0ba25358 | 629 | switch_channel_wait_for_state(channel, other_channel, CS_SOFT_EXECUTE); |
ae76db7b AM |
630 | } |
631 | } | |
83f84876 AM |
632 | } |
633 | ||
47985c56 | 634 | SWITCH_DECLARE_CONSTRUCTOR CoreSession::CoreSession(switch_core_session_t *new_session) |
83f84876 AM |
635 | { |
636 | init_vars(); | |
24a27c6e | 637 | |
6d1f4f6d MJ |
638 | if (new_session) { |
639 | session = new_session; | |
640 | channel = switch_core_session_get_channel(session); | |
641 | allocated = 1; | |
ce14c6c2 | 642 | switch_core_session_read_lock_hangup(session); |
11fc21f7 | 643 | uuid = strdup(switch_core_session_get_uuid(session)); |
6d1f4f6d | 644 | } |
83f84876 AM |
645 | } |
646 | ||
47985c56 | 647 | SWITCH_DECLARE_CONSTRUCTOR CoreSession::~CoreSession() |
83f84876 | 648 | { |
75dbe890 | 649 | this_check_void(); |
540445cb | 650 | if (allocated) destroy(); |
83f84876 AM |
651 | } |
652 | ||
a5e10ebc AM |
653 | SWITCH_DECLARE(char *) CoreSession::getXMLCDR() |
654 | { | |
655 | ||
3a6bb506 | 656 | switch_xml_t cdr = NULL; |
878bbceb AM |
657 | |
658 | this_check((char *)""); | |
d5e4046d | 659 | sanity_check((char *)""); |
a5e10ebc AM |
660 | |
661 | switch_safe_free(xml_cdr_text); | |
662 | ||
663 | if (switch_ivr_generate_xml_cdr(session, &cdr) == SWITCH_STATUS_SUCCESS) { | |
664 | xml_cdr_text = switch_xml_toxml(cdr, SWITCH_FALSE); | |
665 | switch_xml_free(cdr); | |
666 | } | |
667 | ||
668 | return (char *) (xml_cdr_text ? xml_cdr_text : ""); | |
669 | } | |
670 | ||
671 | SWITCH_DECLARE(void) CoreSession::setEventData(Event *e) | |
672 | { | |
878bbceb | 673 | this_check_void(); |
a5e10ebc AM |
674 | sanity_check_noreturn; |
675 | ||
676 | if (channel && e->event) { | |
677 | switch_channel_event_set_data(channel, e->event); | |
678 | } | |
679 | } | |
680 | ||
47985c56 | 681 | SWITCH_DECLARE(int) CoreSession::answer() |
83f84876 AM |
682 | { |
683 | switch_status_t status; | |
878bbceb | 684 | this_check(-1); |
83f84876 AM |
685 | sanity_check(-1); |
686 | status = switch_channel_answer(channel); | |
687 | return status == SWITCH_STATUS_SUCCESS ? 1 : 0; | |
688 | } | |
689 | ||
c4e350ab AM |
690 | SWITCH_DECLARE(int) CoreSession::insertFile(const char *file, const char *insert_file, int sample_point) |
691 | { | |
692 | switch_status_t status; | |
693 | this_check(-1); | |
694 | sanity_check(-1); | |
695 | status = switch_ivr_insert_file(session, file, insert_file, (switch_size_t)sample_point); | |
696 | return status == SWITCH_STATUS_SUCCESS ? 1 : 0; | |
697 | } | |
698 | ||
47985c56 | 699 | SWITCH_DECLARE(int) CoreSession::preAnswer() |
83f84876 AM |
700 | { |
701 | switch_status_t status; | |
878bbceb | 702 | this_check(-1); |
83f84876 | 703 | sanity_check(-1); |
8107c49a | 704 | status = switch_channel_pre_answer(channel); |
83f84876 AM |
705 | return status == SWITCH_STATUS_SUCCESS ? 1 : 0; |
706 | } | |
707 | ||
f4239d95 AM |
708 | SWITCH_DECLARE(void) CoreSession::hangupState(void) |
709 | { | |
710 | sanity_check_noreturn; | |
711 | this->begin_allow_threads(); | |
74bfa46a | 712 | if (switch_channel_down(channel)) { |
d13a46ac | 713 | switch_core_session_hangup_state(session, SWITCH_FALSE); |
74bfa46a | 714 | } |
f4239d95 AM |
715 | this->end_allow_threads(); |
716 | } | |
717 | ||
bf91ac16 | 718 | SWITCH_DECLARE(void) CoreSession::hangup(const char *cause) |
83f84876 | 719 | { |
878bbceb AM |
720 | this_check_void(); |
721 | sanity_check_noreturn; | |
c2d5f970 | 722 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "CoreSession::hangup\n"); |
996cfa54 | 723 | this->begin_allow_threads(); |
4fc4c523 | 724 | switch_channel_hangup(channel, switch_channel_str2cause(cause)); |
996cfa54 | 725 | this->end_allow_threads(); |
83f84876 AM |
726 | } |
727 | ||
47985c56 | 728 | SWITCH_DECLARE(void) CoreSession::setPrivate(char *var, void *val) |
59526679 | 729 | { |
878bbceb | 730 | this_check_void(); |
59526679 AM |
731 | sanity_check_noreturn; |
732 | switch_channel_set_private(channel, var, val); | |
733 | } | |
734 | ||
47985c56 | 735 | SWITCH_DECLARE(void *)CoreSession::getPrivate(char *var) |
59526679 | 736 | { |
878bbceb | 737 | this_check(NULL); |
59526679 AM |
738 | sanity_check(NULL); |
739 | return switch_channel_get_private(channel, var); | |
740 | } | |
741 | ||
47985c56 | 742 | SWITCH_DECLARE(void) CoreSession::setVariable(char *var, char *val) |
83f84876 | 743 | { |
878bbceb | 744 | this_check_void(); |
f32f6f24 | 745 | sanity_check_noreturn; |
49b9d7f9 | 746 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "CoreSession::setVariable('%s', '%s')\n", var, val); |
5cd072a3 | 747 | switch_channel_set_variable_var_check(channel, var, val, SWITCH_FALSE); |
83f84876 AM |
748 | } |
749 | ||
47985c56 | 750 | SWITCH_DECLARE(const char *)CoreSession::getVariable(char *var) |
83f84876 | 751 | { |
878bbceb AM |
752 | this_check(""); |
753 | sanity_check(""); | |
343d77a4 | 754 | return switch_channel_get_variable(channel, var); |
83f84876 AM |
755 | } |
756 | ||
b32de058 | 757 | SWITCH_DECLARE(void) CoreSession::execute(const char *app, const char *data) |
83f84876 | 758 | { |
878bbceb | 759 | this_check_void(); |
f32f6f24 | 760 | sanity_check_noreturn; |
83f84876 | 761 | |
4d7a0ac0 AM |
762 | if (zstr(app)) { |
763 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No application specified\n"); | |
764 | return; | |
765 | } | |
766 | ||
b32de058 AM |
767 | begin_allow_threads(); |
768 | switch_core_session_execute_application(session, app, data); | |
769 | end_allow_threads(); | |
83f84876 AM |
770 | } |
771 | ||
47985c56 | 772 | SWITCH_DECLARE(void) CoreSession::setDTMFCallback(void *cbfunc, char *funcargs) { |
6f78befa | 773 | |
878bbceb | 774 | this_check_void(); |
a06997ee AM |
775 | sanity_check_noreturn; |
776 | ||
6f78befa TL |
777 | cb_state.funcargs = funcargs; |
778 | cb_state.function = cbfunc; | |
779 | ||
780 | args.buf = &cb_state; | |
781 | args.buflen = sizeof(cb_state); // not sure what this is used for, copy mod_spidermonkey | |
782 | ||
783 | switch_channel_set_private(channel, "CoreSession", this); | |
784 | ||
785 | // we cannot set the actual callback to a python function, because | |
786 | // the callback is a function pointer with a specific signature. | |
787 | // so, set it to the following c function which will act as a proxy, | |
788 | // finding the python callback in the args callback args structure | |
789 | args.input_callback = dtmf_callback; | |
790 | ap = &args; | |
791 | ||
792 | ||
793 | } | |
f45d0601 | 794 | |
47985c56 | 795 | SWITCH_DECLARE(void) CoreSession::sendEvent(Event *sendME) |
59526679 | 796 | { |
878bbceb AM |
797 | this_check_void(); |
798 | sanity_check_noreturn; | |
799 | ||
2b5f3563 AM |
800 | if (sendME->event) { |
801 | switch_event_t *new_event; | |
802 | if (switch_event_dup(&new_event, sendME->event) == SWITCH_STATUS_SUCCESS) { | |
803 | switch_core_session_receive_event(session, &new_event); | |
804 | } | |
59526679 AM |
805 | } |
806 | } | |
807 | ||
47985c56 | 808 | SWITCH_DECLARE(int) CoreSession::speak(char *text) |
83f84876 AM |
809 | { |
810 | switch_status_t status; | |
83f84876 | 811 | |
878bbceb | 812 | this_check(-1); |
83f84876 | 813 | sanity_check(-1); |
6f78befa | 814 | |
f45d0601 | 815 | if (!tts_name) { |
c2d5f970 | 816 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No TTS engine specified\n"); |
f45d0601 MJ |
817 | return SWITCH_STATUS_FALSE; |
818 | } | |
819 | ||
820 | if (!voice_name) { | |
c2d5f970 | 821 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No TTS voice specified\n"); |
f45d0601 MJ |
822 | return SWITCH_STATUS_FALSE; |
823 | } | |
824 | ||
160edc55 | 825 | |
fedefcb6 | 826 | begin_allow_threads(); |
160edc55 | 827 | status = switch_ivr_speak_text(session, tts_name, voice_name, text, ap); |
fedefcb6 | 828 | end_allow_threads(); |
83f84876 AM |
829 | return status == SWITCH_STATUS_SUCCESS ? 1 : 0; |
830 | } | |
831 | ||
47985c56 | 832 | SWITCH_DECLARE(void) CoreSession::set_tts_parms(char *tts_name_p, char *voice_name_p) |
83f84876 | 833 | { |
3199f5ce | 834 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "set_tts_parms is deprecated. Use set_tts_params.\n"); |
878bbceb | 835 | this_check_void(); |
f32f6f24 | 836 | sanity_check_noreturn; |
83f84876 AM |
837 | switch_safe_free(tts_name); |
838 | switch_safe_free(voice_name); | |
839 | tts_name = strdup(tts_name_p); | |
840 | voice_name = strdup(voice_name_p); | |
841 | } | |
842 | ||
3199f5ce WK |
843 | SWITCH_DECLARE(void) CoreSession::set_tts_params(char *tts_name_p, char *voice_name_p) |
844 | { | |
845 | this_check_void(); | |
846 | sanity_check_noreturn; | |
847 | switch_safe_free(tts_name); | |
848 | switch_safe_free(voice_name); | |
849 | tts_name = strdup(tts_name_p); | |
850 | voice_name = strdup(voice_name_p); | |
851 | } | |
c806a20d | 852 | |
3bc20b3c BW |
853 | SWITCH_DECLARE(int) CoreSession::collectDigits(int abs_timeout) { |
854 | return collectDigits(0, abs_timeout); | |
855 | } | |
856 | ||
857 | SWITCH_DECLARE(int) CoreSession::collectDigits(int digit_timeout, int abs_timeout) { | |
878bbceb | 858 | this_check(-1); |
c806a20d TL |
859 | sanity_check(-1); |
860 | begin_allow_threads(); | |
3bc20b3c | 861 | switch_ivr_collect_digits_callback(session, ap, digit_timeout, abs_timeout); |
c806a20d | 862 | end_allow_threads(); |
a4301f0d | 863 | return SWITCH_STATUS_SUCCESS; |
c806a20d TL |
864 | } |
865 | ||
444c93c3 MJ |
866 | SWITCH_DECLARE(char *) CoreSession::getDigits(int maxdigits, char *terminators, int timeout) |
867 | { | |
868 | return getDigits(maxdigits, terminators, timeout, 0); | |
869 | } | |
870 | ||
38038078 | 871 | SWITCH_DECLARE(char *) CoreSession::getDigits(int maxdigits, |
4fda174f | 872 | char *terminators, |
444c93c3 MJ |
873 | int timeout, |
874 | int interdigit) | |
83f84876 | 875 | { |
878bbceb | 876 | this_check((char *)""); |
d5e4046d | 877 | sanity_check((char *)""); |
fedefcb6 | 878 | begin_allow_threads(); |
4fda174f | 879 | char terminator; |
6f78befa | 880 | |
85fc8c37 | 881 | memset(dtmf_buf, 0, sizeof(dtmf_buf)); |
7963c404 MJ |
882 | switch_ivr_collect_digits_count(session, |
883 | dtmf_buf, | |
884 | sizeof(dtmf_buf), | |
885 | maxdigits, | |
886 | terminators, | |
887 | &terminator, | |
888 | (uint32_t) timeout, (uint32_t)interdigit, 0); | |
6f78befa | 889 | |
c2d5f970 | 890 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "getDigits dtmf_buf: %s\n", dtmf_buf); |
fedefcb6 | 891 | end_allow_threads(); |
7963c404 | 892 | return dtmf_buf; |
83f84876 AM |
893 | } |
894 | ||
47985c56 | 895 | SWITCH_DECLARE(int) CoreSession::transfer(char *extension, char *dialplan, char *context) |
83f84876 AM |
896 | { |
897 | switch_status_t status; | |
878bbceb | 898 | this_check(-1); |
83f84876 | 899 | sanity_check(-1); |
e028f269 | 900 | begin_allow_threads(); |
83f84876 | 901 | status = switch_ivr_session_transfer(session, extension, dialplan, context); |
c2d5f970 | 902 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "transfer result: %d\n", status); |
e028f269 | 903 | end_allow_threads(); |
83f84876 AM |
904 | return status == SWITCH_STATUS_SUCCESS ? 1 : 0; |
905 | } | |
906 | ||
8e0b64a1 AM |
907 | |
908 | SWITCH_DECLARE(char *) CoreSession::read(int min_digits, | |
909 | int max_digits, | |
910 | const char *prompt_audio_file, | |
911 | int timeout, | |
cfa30468 AM |
912 | const char *valid_terminators, |
913 | int digit_timeout) | |
8e0b64a1 | 914 | { |
878bbceb AM |
915 | this_check((char *)""); |
916 | sanity_check((char *)""); | |
8e0b64a1 AM |
917 | if (min_digits < 1) { |
918 | min_digits = 1; | |
919 | } | |
920 | ||
921 | if (max_digits < 1) { | |
922 | max_digits = 1; | |
923 | } | |
924 | ||
925 | if (timeout < 1) { | |
926 | timeout = 1; | |
927 | } | |
928 | ||
5195d311 | 929 | begin_allow_threads(); |
cfa30468 AM |
930 | switch_ivr_read(session, min_digits, max_digits, prompt_audio_file, NULL, dtmf_buf, |
931 | sizeof(dtmf_buf), timeout, valid_terminators, (uint32_t)digit_timeout); | |
5195d311 AM |
932 | end_allow_threads(); |
933 | ||
8e0b64a1 AM |
934 | return dtmf_buf; |
935 | } | |
936 | ||
85fc8c37 | 937 | SWITCH_DECLARE(char *) CoreSession::playAndGetDigits(int min_digits, |
8b8a7f14 BW |
938 | int max_digits, |
939 | int max_tries, | |
940 | int timeout, | |
941 | char *terminators, | |
942 | char *audio_files, | |
69f73575 | 943 | char *bad_input_audio_files, |
dbb40708 | 944 | char *digits_regex, |
cfa30468 | 945 | const char *var_name, |
e4d47319 MC |
946 | int digit_timeout, |
947 | const char *transfer_on_failure) | |
83f84876 | 948 | { |
d5e4046d | 949 | sanity_check((char *)""); |
878bbceb | 950 | this_check((char *)""); |
fedefcb6 | 951 | begin_allow_threads(); |
85fc8c37 | 952 | memset(dtmf_buf, 0, sizeof(dtmf_buf)); |
7963c404 MJ |
953 | switch_play_and_get_digits( session, |
954 | (uint32_t) min_digits, | |
955 | (uint32_t) max_digits, | |
956 | (uint32_t) max_tries, | |
957 | (uint32_t) timeout, | |
958 | terminators, | |
959 | audio_files, | |
960 | bad_input_audio_files, | |
961 | var_name, | |
962 | dtmf_buf, | |
963 | sizeof(dtmf_buf), | |
964 | digits_regex, | |
965 | (uint32_t) digit_timeout, | |
966 | transfer_on_failure); | |
6f78befa | 967 | |
fedefcb6 | 968 | end_allow_threads(); |
85fc8c37 | 969 | return dtmf_buf; |
83f84876 AM |
970 | } |
971 | ||
7c16b84a | 972 | SWITCH_DECLARE(void) CoreSession::say(const char *tosay, const char *module_name, const char *say_type, const char *say_method, const char *say_gender) |
40efe06a | 973 | { |
878bbceb | 974 | this_check_void(); |
40efe06a AM |
975 | sanity_check_noreturn; |
976 | if (!(tosay && module_name && say_type && say_method)) { | |
c2d5f970 | 977 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error! invalid args.\n"); |
40efe06a AM |
978 | return; |
979 | } | |
980 | begin_allow_threads(); | |
7c16b84a | 981 | switch_ivr_say(session, tosay, module_name, say_type, say_method, say_gender, ap); |
40efe06a AM |
982 | end_allow_threads(); |
983 | } | |
984 | ||
985 | SWITCH_DECLARE(void) CoreSession::sayPhrase(const char *phrase_name, const char *phrase_data, const char *phrase_lang) | |
986 | { | |
878bbceb | 987 | this_check_void(); |
40efe06a AM |
988 | sanity_check_noreturn; |
989 | ||
990 | if (!(phrase_name)) { | |
c2d5f970 | 991 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error! invalid args.\n"); |
40efe06a AM |
992 | return; |
993 | } | |
994 | ||
995 | begin_allow_threads(); | |
996 | switch_ivr_phrase_macro(session, phrase_name, phrase_data, phrase_lang, ap); | |
997 | end_allow_threads(); | |
998 | } | |
999 | ||
47985c56 | 1000 | SWITCH_DECLARE(int) CoreSession::streamFile(char *file, int starting_sample_count) { |
f45d0601 MJ |
1001 | |
1002 | switch_status_t status; | |
59526679 | 1003 | //switch_file_handle_t fh = { 0 }; |
622a2733 | 1004 | const char *prebuf; |
f2495ec8 | 1005 | switch_file_handle_t local_fh; |
f45d0601 | 1006 | |
878bbceb | 1007 | this_check(-1); |
f45d0601 | 1008 | sanity_check(-1); |
59526679 AM |
1009 | |
1010 | memset(&local_fh, 0, sizeof(local_fh)); | |
1011 | fhp = &local_fh; | |
1012 | local_fh.samples = starting_sample_count; | |
f45d0601 | 1013 | |
f45d0601 MJ |
1014 | |
1015 | if ((prebuf = switch_channel_get_variable(this->channel, "stream_prebuffer"))) { | |
1016 | int maybe = atoi(prebuf); | |
1017 | if (maybe > 0) { | |
59526679 | 1018 | local_fh.prebuf = maybe; |
f45d0601 MJ |
1019 | } |
1020 | } | |
1021 | ||
59526679 AM |
1022 | begin_allow_threads(); |
1023 | status = switch_ivr_play_file(session, fhp, file, ap); | |
1024 | end_allow_threads(); | |
1025 | ||
a3ccefa7 AM |
1026 | fhp = NULL; |
1027 | ||
f45d0601 MJ |
1028 | return status == SWITCH_STATUS_SUCCESS ? 1 : 0; |
1029 | ||
1030 | } | |
1031 | ||
71054917 | 1032 | SWITCH_DECLARE(int) CoreSession::sleep(int ms, int sync) { |
32bbdb74 AM |
1033 | |
1034 | switch_status_t status; | |
1035 | ||
1036 | this_check(-1); | |
1037 | sanity_check(-1); | |
1038 | ||
1039 | begin_allow_threads(); | |
71054917 | 1040 | status = switch_ivr_sleep(session, ms, (switch_bool_t) sync, ap); |
32bbdb74 AM |
1041 | end_allow_threads(); |
1042 | ||
1043 | return status == SWITCH_STATUS_SUCCESS ? 1 : 0; | |
1044 | ||
1045 | } | |
1046 | ||
47985c56 | 1047 | SWITCH_DECLARE(bool) CoreSession::ready() { |
f45d0601 | 1048 | |
878bbceb | 1049 | this_check(false); |
83ebebc5 AM |
1050 | |
1051 | if (!session) { | |
1052 | return false; | |
1053 | } | |
1054 | sanity_check(false); | |
1055 | ||
482badff | 1056 | return switch_channel_ready(channel) != 0; |
fedefcb6 MJ |
1057 | } |
1058 | ||
334abcda AM |
1059 | |
1060 | SWITCH_DECLARE(bool) CoreSession::bridged() { | |
1061 | ||
1062 | this_check(false); | |
1063 | ||
1064 | if (!session) { | |
1065 | return false; | |
1066 | } | |
1067 | sanity_check(false); | |
1068 | ||
1069 | return (switch_channel_up(channel) && switch_channel_test_flag(channel, CF_BRIDGED)); | |
1070 | } | |
1071 | ||
830a8493 AM |
1072 | SWITCH_DECLARE(bool) CoreSession::mediaReady() { |
1073 | ||
1074 | this_check(false); | |
1075 | sanity_check(false); | |
1076 | return switch_channel_media_ready(channel) != 0; | |
1077 | } | |
1078 | ||
1079 | SWITCH_DECLARE(bool) CoreSession::answered() { | |
1080 | ||
1081 | this_check(false); | |
1082 | sanity_check(false); | |
1083 | return switch_channel_test_flag(channel, CF_ANSWERED) != 0; | |
1084 | } | |
1085 | ||
ddd1ae14 AM |
1086 | SWITCH_DECLARE(void) CoreSession::destroy(void) |
1087 | { | |
1088 | this_check_void(); | |
4025b424 AM |
1089 | |
1090 | if (!allocated) { | |
1091 | return; | |
1092 | } | |
ddd1ae14 | 1093 | |
540445cb AM |
1094 | allocated = 0; |
1095 | ||
ddd1ae14 AM |
1096 | switch_safe_free(xml_cdr_text); |
1097 | switch_safe_free(uuid); | |
1098 | switch_safe_free(tts_name); | |
1099 | switch_safe_free(voice_name); | |
1100 | ||
1101 | if (session) { | |
523e0653 AM |
1102 | if (!channel) { |
1103 | channel = switch_core_session_get_channel(session); | |
1104 | } | |
1105 | ||
1106 | if (channel) { | |
540445cb AM |
1107 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, |
1108 | "%s destroy/unlink session from object\n", switch_channel_get_name(channel)); | |
523e0653 | 1109 | switch_channel_set_private(channel, "CoreSession", NULL); |
540445cb AM |
1110 | if (switch_channel_up(channel) && switch_test_flag(this, S_HUP) && !switch_channel_test_flag(channel, CF_TRANSFER)) { |
1111 | switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); | |
1112 | } | |
523e0653 | 1113 | } |
540445cb | 1114 | |
ddd1ae14 AM |
1115 | switch_core_session_rwunlock(session); |
1116 | session = NULL; | |
523e0653 | 1117 | channel = NULL; |
ddd1ae14 AM |
1118 | } |
1119 | ||
4025b424 | 1120 | init_vars(); |
ddd1ae14 AM |
1121 | |
1122 | } | |
1123 | ||
c54f0c39 AM |
1124 | SWITCH_DECLARE(const char *) CoreSession::hangupCause() |
1125 | { | |
2261b687 | 1126 | this_check(NULL); |
c54f0c39 AM |
1127 | return switch_channel_cause2str(cause); |
1128 | } | |
1129 | ||
635e2fb5 AM |
1130 | SWITCH_DECLARE(const char *) CoreSession::getState() |
1131 | { | |
1132 | this_check(NULL); | |
1133 | ||
1134 | if (channel) { | |
1135 | return switch_channel_state_name(switch_channel_get_state(channel)); | |
1136 | } | |
1137 | ||
1138 | return "ERROR"; | |
1139 | ||
1140 | } | |
1141 | ||
5a5f3081 | 1142 | SWITCH_DECLARE(int) CoreSession::originate(CoreSession *a_leg_session, char *dest, int timeout, switch_state_handler_table_t *handlers) |
e028f269 MJ |
1143 | { |
1144 | ||
e028f269 | 1145 | switch_core_session_t *aleg_core_session = NULL; |
e028f269 | 1146 | |
878bbceb | 1147 | this_check(0); |
878bbceb | 1148 | |
e028f269 MJ |
1149 | cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; |
1150 | ||
700aa0df TL |
1151 | if (a_leg_session != NULL) { |
1152 | aleg_core_session = a_leg_session->session; | |
e028f269 MJ |
1153 | } |
1154 | ||
700aa0df TL |
1155 | // this session has no valid switch_core_session_t at this point, and therefore |
1156 | // no valid channel. since the threadstate is stored in the channel, and there | |
1157 | // is none, if we try to call begin_alllow_threads it will fail miserably. | |
1158 | // use the 'a leg session' to do the thread swapping stuff. | |
3d3ee88d | 1159 | if (a_leg_session) a_leg_session->begin_allow_threads(); |
e028f269 | 1160 | |
e028f269 MJ |
1161 | if (switch_ivr_originate(aleg_core_session, |
1162 | &session, | |
1163 | &cause, | |
1164 | dest, | |
1165 | timeout, | |
5a5f3081 | 1166 | handlers, |
e028f269 MJ |
1167 | NULL, |
1168 | NULL, | |
c5f1d9ec | 1169 | NULL, |
a579a283 | 1170 | NULL, |
2fa0c491 AM |
1171 | SOF_NONE, |
1172 | NULL) != SWITCH_STATUS_SUCCESS) { | |
e028f269 MJ |
1173 | switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Error Creating Outgoing Channel! [%s]\n", dest); |
1174 | goto failed; | |
1175 | ||
1176 | } | |
1177 | ||
3d3ee88d | 1178 | if (a_leg_session) a_leg_session->end_allow_threads(); |
d895c81d | 1179 | channel = switch_core_session_get_channel(session); |
94b22258 | 1180 | allocated = 1; |
2a3be1dc MR |
1181 | switch_safe_free(uuid); |
1182 | uuid = strdup(switch_core_session_get_uuid(session)); | |
4b929592 | 1183 | switch_channel_set_state(switch_core_session_get_channel(session), CS_SOFT_EXECUTE); |
ae76db7b | 1184 | |
e028f269 MJ |
1185 | return SWITCH_STATUS_SUCCESS; |
1186 | ||
1187 | failed: | |
3d3ee88d | 1188 | if (a_leg_session) a_leg_session->end_allow_threads(); |
e028f269 MJ |
1189 | return SWITCH_STATUS_FALSE; |
1190 | } | |
1191 | ||
3a67cbf4 | 1192 | SWITCH_DECLARE(int) CoreSession::recordFile(char *file_name, int time_limit, int silence_threshold, int silence_hits) |
bd2c91b0 | 1193 | { |
bd2c91b0 | 1194 | switch_status_t status; |
f2495ec8 | 1195 | switch_file_handle_t local_fh; |
bd2c91b0 | 1196 | |
878bbceb AM |
1197 | this_check(-1); |
1198 | sanity_check(-1); | |
1199 | ||
a3ccefa7 AM |
1200 | memset(&local_fh, 0, sizeof(local_fh)); |
1201 | fhp = &local_fh; | |
1202 | local_fh.thresh = silence_threshold; | |
3a67cbf4 | 1203 | local_fh.silence_hits = silence_hits; |
a3ccefa7 | 1204 | |
bd2c91b0 | 1205 | begin_allow_threads(); |
1d91b7d6 | 1206 | status = switch_ivr_record_file(session, &local_fh, file_name, ap, time_limit); |
bd2c91b0 | 1207 | end_allow_threads(); |
a3ccefa7 AM |
1208 | |
1209 | fhp = NULL; | |
1210 | ||
bd2c91b0 MJ |
1211 | return status == SWITCH_STATUS_SUCCESS ? 1 : 0; |
1212 | ||
1213 | } | |
e028f269 | 1214 | |
47985c56 | 1215 | SWITCH_DECLARE(int) CoreSession::flushEvents() |
6f78befa TL |
1216 | { |
1217 | switch_event_t *event; | |
6f78befa | 1218 | |
878bbceb AM |
1219 | this_check(-1); |
1220 | sanity_check(-1); | |
1221 | ||
6f78befa TL |
1222 | if (!session) { |
1223 | return SWITCH_STATUS_FALSE; | |
1224 | } | |
6f78befa | 1225 | |
99026e02 | 1226 | while (switch_core_session_dequeue_event(session, &event, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) { |
6f78befa TL |
1227 | switch_event_destroy(&event); |
1228 | } | |
1229 | return SWITCH_STATUS_SUCCESS; | |
1230 | } | |
1231 | ||
47985c56 | 1232 | SWITCH_DECLARE(int) CoreSession::flushDigits() |
6f78befa | 1233 | { |
878bbceb AM |
1234 | this_check(-1); |
1235 | sanity_check(-1); | |
482badff | 1236 | switch_channel_flush_dtmf(switch_core_session_get_channel(session)); |
6f78befa TL |
1237 | return SWITCH_STATUS_SUCCESS; |
1238 | } | |
1239 | ||
47985c56 | 1240 | SWITCH_DECLARE(int) CoreSession::setAutoHangup(bool val) |
6f78befa | 1241 | { |
878bbceb AM |
1242 | this_check(-1); |
1243 | sanity_check(-1); | |
1244 | ||
6f78befa TL |
1245 | if (!session) { |
1246 | return SWITCH_STATUS_FALSE; | |
1247 | } | |
1248 | if (val) { | |
1249 | switch_set_flag(this, S_HUP); | |
1250 | } else { | |
1251 | switch_clear_flag(this, S_HUP); | |
1252 | } | |
1253 | return SWITCH_STATUS_SUCCESS; | |
1254 | } | |
1255 | ||
7f4c8a6d AM |
1256 | SWITCH_DECLARE(void) CoreSession::waitForAnswer(CoreSession *calling_session) |
1257 | { | |
1258 | this_check_void(); | |
1259 | sanity_check_noreturn; | |
1260 | ||
1261 | switch_ivr_wait_for_answer(calling_session ? calling_session->session : NULL, session); | |
1262 | ||
1263 | } | |
1264 | ||
47985c56 | 1265 | SWITCH_DECLARE(void) CoreSession::setHangupHook(void *hangup_func) { |
6f78befa | 1266 | |
878bbceb | 1267 | this_check_void(); |
a06997ee | 1268 | sanity_check_noreturn; |
878bbceb | 1269 | |
c2d5f970 | 1270 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "CoreSession::seHangupHook, hangup_func: %p\n", hangup_func); |
6f78befa TL |
1271 | on_hangup = hangup_func; |
1272 | switch_channel_t *channel = switch_core_session_get_channel(session); | |
6f78befa TL |
1273 | |
1274 | hook_state = switch_channel_get_state(channel); | |
1275 | switch_channel_set_private(channel, "CoreSession", this); | |
1276 | switch_core_event_hook_add_state_change(session, hanguphook); | |
fedefcb6 MJ |
1277 | } |
1278 | ||
e60f37f6 AM |
1279 | SWITCH_DECLARE(void) CoreSession::consoleLog(char *level_str, char *msg) |
1280 | { | |
1281 | switch_log_level_t level = SWITCH_LOG_DEBUG; | |
1282 | if (level_str) { | |
1283 | level = switch_log_str2level(level_str); | |
1284 | if (level == SWITCH_LOG_INVALID) { | |
1285 | level = SWITCH_LOG_DEBUG; | |
1286 | } | |
1287 | } | |
1288 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), level, "%s", switch_str_nil(msg)); | |
1289 | } | |
1290 | ||
74262ee9 TC |
1291 | SWITCH_DECLARE(void) CoreSession::consoleLog2(char *level_str, char *file, char *func, int line, char *msg) |
1292 | { | |
1293 | switch_log_level_t level = SWITCH_LOG_DEBUG; | |
1294 | if (level_str) { | |
1295 | level = switch_log_str2level(level_str); | |
1296 | if (level == SWITCH_LOG_INVALID) { | |
1297 | level = SWITCH_LOG_DEBUG; | |
1298 | } | |
1299 | } | |
1300 | switch_log_printf(SWITCH_CHANNEL_ID_SESSION, file, func, line, (const char*)session, | |
1301 | level, "%s", switch_str_nil(msg)); | |
1302 | } | |
1303 | ||
e028f269 MJ |
1304 | /* ---- methods not bound to CoreSession instance ---- */ |
1305 | ||
c017c24b AM |
1306 | |
1307 | SWITCH_DECLARE(int) globalSetVariable(const char *var, const char *val, const char *val2) | |
1308 | { | |
1309 | if (zstr(val)) val = NULL; | |
1310 | if (zstr(val2)) val2 = NULL; | |
1311 | ||
1312 | if (val2) { | |
ea5e699c | 1313 | return switch_core_set_var_conditional(var, val, val2); |
c017c24b AM |
1314 | } else { |
1315 | switch_core_set_variable(var, val); | |
ea5e699c | 1316 | return SWITCH_STATUS_SUCCESS; |
c017c24b AM |
1317 | } |
1318 | } | |
1319 | ||
2faaee0e AM |
1320 | SWITCH_DECLARE(void) setGlobalVariable(char *var_name, char *var_val) |
1321 | { | |
1322 | switch_core_set_variable(var_name, var_val); | |
1323 | } | |
1324 | ||
1325 | SWITCH_DECLARE(char *) getGlobalVariable(char *var_name) | |
1326 | { | |
1327 | return switch_core_get_variable_dup(var_name); | |
1328 | } | |
1329 | ||
1330 | ||
428cd029 AM |
1331 | SWITCH_DECLARE(bool) running(void) |
1332 | { | |
1333 | return switch_core_running() ? true : false; | |
1334 | } | |
1335 | ||
8f5a873d AM |
1336 | SWITCH_DECLARE(void) consoleLog(char *level_str, char *msg) |
1337 | { | |
1338 | return console_log(level_str, msg); | |
1339 | } | |
1340 | ||
d1ec6432 | 1341 | SWITCH_DECLARE(void) consoleLog2(char *level_str, char *file, char *func, int line, char *msg) |
8f5a873d | 1342 | { |
d1ec6432 | 1343 | return console_log2(level_str, file, func, line, msg); |
8f5a873d | 1344 | } |
e028f269 | 1345 | |
d1ec6432 | 1346 | SWITCH_DECLARE(void) consoleCleanLog(char *msg) |
a99df489 | 1347 | { |
d1ec6432 | 1348 | return console_clean_log(msg); |
a99df489 BW |
1349 | } |
1350 | ||
47985c56 | 1351 | SWITCH_DECLARE(void) console_log(char *level_str, char *msg) |
e028f269 MJ |
1352 | { |
1353 | switch_log_level_t level = SWITCH_LOG_DEBUG; | |
1354 | if (level_str) { | |
1355 | level = switch_log_str2level(level_str); | |
cc71ce69 MJ |
1356 | if (level == SWITCH_LOG_INVALID) { |
1357 | level = SWITCH_LOG_DEBUG; | |
1358 | } | |
e028f269 | 1359 | } |
ae76db7b | 1360 | switch_log_printf(SWITCH_CHANNEL_LOG, level, "%s", switch_str_nil(msg)); |
e028f269 MJ |
1361 | } |
1362 | ||
d1ec6432 | 1363 | SWITCH_DECLARE(void) console_log2(char *level_str, char *file, char *func, int line, char *msg) |
a99df489 BW |
1364 | { |
1365 | switch_log_level_t level = SWITCH_LOG_DEBUG; | |
1366 | if (level_str) { | |
1367 | level = switch_log_str2level(level_str); | |
1368 | if (level == SWITCH_LOG_INVALID) { | |
1369 | level = SWITCH_LOG_DEBUG; | |
1370 | } | |
1371 | } | |
1372 | switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, level, "%s", switch_str_nil(msg)); | |
1373 | } | |
1374 | ||
d1ec6432 TC |
1375 | SWITCH_DECLARE(void) console_clean_log(char *msg) |
1376 | { | |
1377 | switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN,SWITCH_LOG_DEBUG, "%s", switch_str_nil(msg)); | |
1378 | } | |
1379 | ||
89c5f3bf BW |
1380 | SWITCH_DECLARE(bool) email(char *to, char *from, char *headers, char *body, char *file, char *convert_cmd, char *convert_ext) |
1381 | { | |
1382 | if (switch_simple_email(to, from, headers, body, file, convert_cmd, convert_ext) == SWITCH_TRUE) { | |
1383 | return true; | |
1384 | } | |
1385 | return false; | |
1386 | } | |
e028f269 | 1387 | |
1af72288 | 1388 | SWITCH_DECLARE(void) switch_msleep(unsigned ms) |
369e6065 MJ |
1389 | { |
1390 | switch_sleep(ms * 1000); | |
1391 | return; | |
1392 | } | |
1393 | ||
47985c56 | 1394 | SWITCH_DECLARE(void) bridge(CoreSession &session_a, CoreSession &session_b) |
e028f269 | 1395 | { |
e028f269 MJ |
1396 | switch_input_callback_function_t dtmf_func = NULL; |
1397 | switch_input_args_t args; | |
920ef82c AM |
1398 | switch_channel_t *channel_a = NULL, *channel_b = NULL; |
1399 | const char *err = "Channels not ready\n"; | |
1400 | ||
1401 | if (session_a.allocated && session_a.session && session_b.allocated && session_b.session) { | |
1402 | channel_a = switch_core_session_get_channel(session_a.session); | |
1403 | channel_b = switch_core_session_get_channel(session_b.session); | |
1404 | ||
1405 | if (switch_channel_ready(channel_a) && switch_channel_ready(channel_b)) { | |
1406 | session_a.begin_allow_threads(); | |
93cc3dc5 | 1407 | if (switch_channel_direction(channel_a) == SWITCH_CALL_DIRECTION_INBOUND && !switch_channel_media_ready(channel_a)) { |
88ae7890 | 1408 | switch_channel_pre_answer(channel_a); |
920ef82c | 1409 | } |
88ae7890 | 1410 | |
920ef82c AM |
1411 | if (switch_channel_ready(channel_a) && switch_channel_ready(channel_b)) { |
1412 | args = session_a.get_cb_args(); // get the cb_args data structure for session a | |
1413 | dtmf_func = args.input_callback; // get the call back function | |
1414 | err = NULL; | |
1415 | switch_ivr_multi_threaded_bridge(session_a.session, session_b.session, dtmf_func, args.buf, args.buf); | |
920ef82c | 1416 | } |
df5afbca | 1417 | session_a.end_allow_threads(); |
920ef82c AM |
1418 | } |
1419 | } | |
1420 | ||
1421 | if (err) { | |
c2d5f970 | 1422 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a.session), SWITCH_LOG_ERROR, "%s", err); |
920ef82c | 1423 | } |
e028f269 | 1424 | |
e028f269 MJ |
1425 | |
1426 | } | |
1427 | ||
47985c56 | 1428 | SWITCH_DECLARE_NONSTD(switch_status_t) hanguphook(switch_core_session_t *session_hungup) |
6f78befa | 1429 | { |
3ff3f327 MJ |
1430 | if (session_hungup) { |
1431 | switch_channel_t *channel = switch_core_session_get_channel(session_hungup); | |
1432 | CoreSession *coresession = NULL; | |
1433 | switch_channel_state_t state = switch_channel_get_state(channel); | |
1434 | ||
1435 | if ((coresession = (CoreSession *) switch_channel_get_private(channel, "CoreSession"))) { | |
1436 | if (coresession->hook_state != state) { | |
1437 | coresession->cause = switch_channel_get_cause(channel); | |
1438 | coresession->hook_state = state; | |
1439 | coresession->check_hangup_hook(); | |
1440 | } | |
6f78befa | 1441 | } |
6f78befa | 1442 | |
3ff3f327 MJ |
1443 | return SWITCH_STATUS_SUCCESS; |
1444 | } else { | |
1445 | switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "hangup hook called with null session, something is horribly wrong\n"); | |
1446 | return SWITCH_STATUS_FALSE; | |
1447 | } | |
6f78befa TL |
1448 | } |
1449 | ||
1450 | ||
47985c56 | 1451 | SWITCH_DECLARE_NONSTD(switch_status_t) dtmf_callback(switch_core_session_t *session_cb, |
8b8a7f14 BW |
1452 | void *input, |
1453 | switch_input_type_t itype, | |
1454 | void *buf, | |
1455 | unsigned int buflen) { | |
6f78befa | 1456 | |
482badff | 1457 | switch_channel_t *channel = switch_core_session_get_channel(session_cb); |
6f78befa | 1458 | CoreSession *coresession = NULL; |
6f78befa | 1459 | |
6f78befa | 1460 | coresession = (CoreSession *) switch_channel_get_private(channel, "CoreSession"); |
59526679 | 1461 | |
6f78befa | 1462 | if (!coresession) { |
6f78befa TL |
1463 | return SWITCH_STATUS_FALSE; |
1464 | } | |
1465 | ||
4780a3d3 | 1466 | return coresession->run_dtmf_callback(input, itype); |
6f78befa TL |
1467 | } |
1468 | ||
59526679 | 1469 | |
fe854bdb | 1470 | SWITCH_DECLARE(switch_status_t) CoreSession::process_callback_result(char *result) |
e028f269 MJ |
1471 | { |
1472 | ||
878bbceb AM |
1473 | this_check(SWITCH_STATUS_FALSE); |
1474 | sanity_check(SWITCH_STATUS_FALSE); | |
1475 | ||
c4369fc8 | 1476 | return switch_ivr_process_fh(session, result, fhp); |
e028f269 MJ |
1477 | } |
1478 | ||
83f84876 AM |
1479 | /* For Emacs: |
1480 | * Local Variables: | |
1481 | * mode:c | |
1482 | * indent-tabs-mode:t | |
1483 | * tab-width:4 | |
1484 | * c-basic-offset:4 | |
1485 | * End: | |
1486 | * For VIM: | |
32adc789 | 1487 | * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: |
83f84876 | 1488 | */ |