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