]> git.ipfire.org Git - thirdparty/freeswitch.git/blame - src/switch_cpp.cpp
start of msvc build for mod_lua
[thirdparty/freeswitch.git] / src / switch_cpp.cpp
CommitLineData
03845667
MJ
1/*
2 * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3 * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
4 *
5 * Version: MPL 1.1
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18 *
19 * The Initial Developer of the Original Code is
20 * Anthony Minessale II <anthmct@yahoo.com>
21 * Portions created by the Initial Developer are Copyright (C)
22 * the Initial Developer. All Rights Reserved.
23 *
24 * Contributor(s):
25 *
26 * Anthony Minessale II <anthmct@yahoo.com>
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
e028f269 40
069d4681 41SWITCH_DECLARE_CONSTRUCTOR Event::Event(const char *type, const char *subclass_name)
ae76db7b
AM
42{
43 switch_event_types_t event_id;
59526679 44
ae76db7b
AM
45 if (switch_name_event(type, &event_id) != SWITCH_STATUS_SUCCESS) {
46 event_id = SWITCH_EVENT_MESSAGE;
47 }
48
49 switch_event_create_subclass(&event, event_id, subclass_name);
59526679
AM
50 serialized_string = NULL;
51 mine = 1;
52}
53
069d4681 54SWITCH_DECLARE_CONSTRUCTOR Event::Event(switch_event_t *wrap_me, int free_me)
59526679
AM
55{
56 event = wrap_me;
57 mine = free_me;
58 serialized_string = NULL;
ae76db7b
AM
59}
60
069d4681 61SWITCH_DECLARE_CONSTRUCTOR Event::~Event()
ae76db7b 62{
59526679
AM
63
64 if (serialized_string) {
65 free(serialized_string);
66 }
67
68 if (event && mine) {
ae76db7b
AM
69 switch_event_destroy(&event);
70 }
71}
72
59526679 73
069d4681 74SWITCH_DECLARE(const char *)Event::serialize(const char *format)
59526679
AM
75{
76 int isxml = 0;
77
78 if (serialized_string) {
79 free(serialized_string);
80 }
81
82 if (!event) {
83 return "";
84 }
85
86 if (format && !strcasecmp(format, "xml")) {
87 isxml++;
88 }
89
90 if (isxml) {
91 switch_xml_t xml;
59526679
AM
92 if ((xml = switch_event_xmlize(event, SWITCH_VA_NONE))) {
93 serialized_string = switch_xml_toxml(xml, SWITCH_FALSE);
94 switch_xml_free(xml);
95 return serialized_string;
96 } else {
97 return "";
98 }
99 } else {
100 if (switch_event_serialize(event, &serialized_string, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) {
101 return serialized_string;
102 }
103 }
104
105 return "";
106
107}
108
069d4681 109SWITCH_DECLARE(bool) Event::fire(void)
ae76db7b 110{
59526679
AM
111 if (!mine) {
112 switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "Not My event!\n");
113 return false;
114 }
115
ae76db7b
AM
116 if (event) {
117 switch_event_fire(&event);
118 return true;
119 }
120 return false;
121}
122
069d4681 123SWITCH_DECLARE(bool) Event::set_priority(switch_priority_t priority)
ae76db7b
AM
124{
125 if (event) {
126 switch_event_set_priority(event, priority);
127 return true;
128 }
129 return false;
130}
131
069d4681 132SWITCH_DECLARE(char *)Event::get_header(char *header_name)
ae76db7b
AM
133{
134 if (event) {
135 return switch_event_get_header(event, header_name);
136 }
137 return NULL;
138}
139
069d4681 140SWITCH_DECLARE(bool) Event::add_header(const char *header_name, const char *value)
ae76db7b
AM
141{
142 if (event) {
143 return switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header_name, value) == SWITCH_STATUS_SUCCESS ? true : false;
144 }
145
146 return false;
147}
148
069d4681 149SWITCH_DECLARE(bool) Event::del_header(const char *header_name)
ae76db7b
AM
150{
151 if (event) {
152 return switch_event_del_header(event, header_name) == SWITCH_STATUS_SUCCESS ? true : false;
153 }
154
155 return false;
156}
157
158
069d4681 159SWITCH_DECLARE(bool) Event::add_body(const char *value)
ae76db7b
AM
160{
161 if (event) {
162 return switch_event_add_body(event, "%s", value) == SWITCH_STATUS_SUCCESS ? true : false;
163 }
164
165 return false;
166}
167
069d4681 168SWITCH_DECLARE(char *)Event::get_body(void)
ae76db7b
AM
169{
170 if (event) {
171 return switch_event_get_body(event);
172 }
173
174 return NULL;
175}
176
069d4681 177SWITCH_DECLARE_CONSTRUCTOR Stream::Stream()
ae76db7b
AM
178{
179 SWITCH_STANDARD_STREAM(mystream);
180 stream_p = &mystream;
181 mine = 1;
182}
183
069d4681 184SWITCH_DECLARE_CONSTRUCTOR Stream::Stream(switch_stream_handle_t *sp)
ae76db7b
AM
185{
186 stream_p = sp;
187 mine = 0;
188}
189
190
069d4681 191SWITCH_DECLARE_CONSTRUCTOR Stream::~Stream()
ae76db7b
AM
192{
193 if (mine) {
194 switch_safe_free(mystream.data);
195 }
196}
197
069d4681 198SWITCH_DECLARE(void) Stream::write(const char *data)
ae76db7b
AM
199{
200 stream_p->write_function(stream_p, "%s", data);
201}
202
069d4681 203SWITCH_DECLARE(const char *)Stream::get_data()
ae76db7b
AM
204{
205 return stream_p ? (const char *)stream_p->data : NULL;
206}
e028f269
MJ
207
208
47985c56 209SWITCH_DECLARE_CONSTRUCTOR CoreSession::CoreSession()
e028f269 210{
eb3dc7f2
MJ
211 session = NULL;
212 channel = NULL;
213 uuid = NULL;
214 tts_name = NULL;
215 voice_name = NULL;
216 memset(&args, 0, sizeof(args));
217 ap = NULL;
218 on_hangup = NULL;
219 cb_state.function = NULL;
94b22258 220
eb3dc7f2
MJ
221 memset(&caller_profile, 0, sizeof(caller_profile));
222 caller_profile.source = "mod_unknown";
223 caller_profile.dialplan = "";
224 caller_profile.context = "";
225 caller_profile.caller_id_name = "";
226 caller_profile.caller_id_number = "";
227 caller_profile.network_addr = "";
228 caller_profile.ani = "";
229 caller_profile.aniii = "";
230 caller_profile.rdnis = "";
231 caller_profile.username = "";
232
e028f269 233}
83f84876 234
47985c56 235SWITCH_DECLARE_CONSTRUCTOR CoreSession::CoreSession(char *nuuid)
83f84876 236{
a06997ee
AM
237 memset(&caller_profile, 0, sizeof(caller_profile));
238 init_vars();
59526679 239 if (!strchr(nuuid, '/') && (session = switch_core_session_locate(nuuid))) {
94b22258 240 uuid = strdup(nuuid);
d895c81d 241 channel = switch_core_session_get_channel(session);
94b22258 242 allocated = 1;
ae76db7b
AM
243 } else {
244 switch_call_cause_t cause;
245 if (switch_ivr_originate(NULL, &session, &cause, nuuid, 60, NULL, NULL, NULL, NULL, SOF_NONE) == SWITCH_STATUS_SUCCESS) {
d895c81d 246 channel = switch_core_session_get_channel(session);
ae76db7b
AM
247 allocated = 1;
248 switch_set_flag(this, S_HUP);
249 uuid = strdup(switch_core_session_get_uuid(session));
250 switch_channel_set_state(switch_core_session_get_channel(session), CS_TRANSMIT);
251 }
252 }
83f84876
AM
253}
254
47985c56 255SWITCH_DECLARE_CONSTRUCTOR CoreSession::CoreSession(switch_core_session_t *new_session)
83f84876 256{
eb3dc7f2 257 memset(&caller_profile, 0, sizeof(caller_profile));
83f84876 258 init_vars();
6d1f4f6d
MJ
259 if (new_session) {
260 session = new_session;
261 channel = switch_core_session_get_channel(session);
262 allocated = 1;
263 switch_core_session_read_lock(session);
264 }
83f84876
AM
265}
266
47985c56 267SWITCH_DECLARE_CONSTRUCTOR CoreSession::~CoreSession()
83f84876 268{
e49f38e8 269 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CoreSession::~CoreSession desctructor\n");
6f78befa 270 switch_channel_t *channel = NULL;
83f84876
AM
271
272 if (session) {
6f78befa 273 channel = switch_core_session_get_channel(session);
482badff 274 if (switch_test_flag(this, S_HUP)) {
6f78befa
TL
275 switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
276 }
83f84876
AM
277 switch_core_session_rwunlock(session);
278 }
279
280 switch_safe_free(uuid);
281 switch_safe_free(tts_name);
282 switch_safe_free(voice_name);
283}
284
47985c56 285SWITCH_DECLARE(int) CoreSession::answer()
83f84876
AM
286{
287 switch_status_t status;
288
289 sanity_check(-1);
290 status = switch_channel_answer(channel);
291 return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
292}
293
47985c56 294SWITCH_DECLARE(int) CoreSession::preAnswer()
83f84876
AM
295{
296 switch_status_t status;
297 sanity_check(-1);
8107c49a 298 status = switch_channel_pre_answer(channel);
83f84876
AM
299 return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
300}
301
47985c56 302SWITCH_DECLARE(void) CoreSession::hangup(char *cause)
83f84876 303{
f45d0601 304 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CoreSession::hangup\n");
f32f6f24 305 sanity_check_noreturn;
83f84876
AM
306 switch_channel_hangup(channel, switch_channel_str2cause(cause));
307}
308
47985c56 309SWITCH_DECLARE(void) CoreSession::setPrivate(char *var, void *val)
59526679
AM
310{
311 sanity_check_noreturn;
312 switch_channel_set_private(channel, var, val);
313}
314
47985c56 315SWITCH_DECLARE(void *)CoreSession::getPrivate(char *var)
59526679
AM
316{
317 sanity_check(NULL);
318 return switch_channel_get_private(channel, var);
319}
320
47985c56 321SWITCH_DECLARE(void) CoreSession::setVariable(char *var, char *val)
83f84876 322{
f32f6f24 323 sanity_check_noreturn;
83f84876
AM
324 switch_channel_set_variable(channel, var, val);
325}
326
47985c56 327SWITCH_DECLARE(const char *)CoreSession::getVariable(char *var)
83f84876 328{
343d77a4
AM
329 sanity_check(NULL);
330 return switch_channel_get_variable(channel, var);
83f84876
AM
331}
332
47985c56 333SWITCH_DECLARE(void) CoreSession::execute(char *app, char *data)
83f84876
AM
334{
335 const switch_application_interface_t *application_interface;
f32f6f24 336 sanity_check_noreturn;
83f84876 337
c806a20d 338 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CoreSession::execute. app: %s data:%s\n", app, data);
83f84876 339 if ((application_interface = switch_loadable_module_get_application_interface(app))) {
fedefcb6 340 begin_allow_threads();
83f84876 341 switch_core_session_exec(session, application_interface, data);
fedefcb6 342 end_allow_threads();
83f84876
AM
343 }
344}
345
47985c56 346SWITCH_DECLARE(void) CoreSession::setDTMFCallback(void *cbfunc, char *funcargs) {
6f78befa 347
a06997ee
AM
348 sanity_check_noreturn;
349
6f78befa
TL
350 cb_state.funcargs = funcargs;
351 cb_state.function = cbfunc;
352
353 args.buf = &cb_state;
354 args.buflen = sizeof(cb_state); // not sure what this is used for, copy mod_spidermonkey
355
356 switch_channel_set_private(channel, "CoreSession", this);
357
358 // we cannot set the actual callback to a python function, because
359 // the callback is a function pointer with a specific signature.
360 // so, set it to the following c function which will act as a proxy,
361 // finding the python callback in the args callback args structure
362 args.input_callback = dtmf_callback;
363 ap = &args;
364
365
366}
f45d0601 367
47985c56 368SWITCH_DECLARE(void) CoreSession::sendEvent(Event *sendME)
59526679
AM
369{
370 if (sendME->mine) {
371 switch_core_session_receive_event(session, &sendME->event);
372 } else {
373 switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "Not My event!\n");
374 }
375}
376
47985c56 377SWITCH_DECLARE(int) CoreSession::speak(char *text)
83f84876
AM
378{
379 switch_status_t status;
83f84876
AM
380
381 sanity_check(-1);
6f78befa
TL
382
383 // create and store an empty filehandle in callback args
384 // to workaround a bug in the presumptuous process_callback_result()
385 switch_file_handle_t fh = { 0 };
386 store_file_handle(&fh);
387
f45d0601 388 if (!tts_name) {
e49f38e8 389 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No TTS engine specified\n");
f45d0601
MJ
390 return SWITCH_STATUS_FALSE;
391 }
392
393 if (!voice_name) {
e49f38e8 394 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No TTS voice specified\n");
f45d0601
MJ
395 return SWITCH_STATUS_FALSE;
396 }
397
160edc55 398
fedefcb6 399 begin_allow_threads();
160edc55 400 status = switch_ivr_speak_text(session, tts_name, voice_name, text, ap);
fedefcb6 401 end_allow_threads();
83f84876
AM
402 return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
403}
404
47985c56 405SWITCH_DECLARE(void) CoreSession::set_tts_parms(char *tts_name_p, char *voice_name_p)
83f84876 406{
f32f6f24 407 sanity_check_noreturn;
83f84876
AM
408 switch_safe_free(tts_name);
409 switch_safe_free(voice_name);
410 tts_name = strdup(tts_name_p);
411 voice_name = strdup(voice_name_p);
412}
413
c806a20d
TL
414
415
47985c56 416SWITCH_DECLARE(int) CoreSession::collectDigits(int timeout) {
c806a20d
TL
417 sanity_check(-1);
418 begin_allow_threads();
419 switch_ivr_collect_digits_callback(session, ap, timeout);
420 end_allow_threads();
a4301f0d 421 return SWITCH_STATUS_SUCCESS;
c806a20d
TL
422}
423
47985c56 424SWITCH_DECLARE(int) CoreSession::getDigits(char *dtmf_buf,
e8f7c1b4
MJ
425 switch_size_t buflen,
426 switch_size_t maxdigits,
f45d0601
MJ
427 char *terminators,
428 char *terminator,
429 int timeout)
83f84876
AM
430{
431 switch_status_t status;
432 sanity_check(-1);
fedefcb6 433 begin_allow_threads();
6f78befa 434
f45d0601
MJ
435 status = switch_ivr_collect_digits_count(session,
436 dtmf_buf,
e8f7c1b4
MJ
437 buflen,
438 maxdigits,
f45d0601
MJ
439 terminators,
440 terminator,
df749a42 441 (uint32_t) timeout, 0, 0);
6f78befa
TL
442
443 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "getDigits dtmf_buf: %s\n", dtmf_buf);
fedefcb6 444 end_allow_threads();
83f84876
AM
445 return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
446}
447
47985c56 448SWITCH_DECLARE(int) CoreSession::transfer(char *extension, char *dialplan, char *context)
83f84876
AM
449{
450 switch_status_t status;
451 sanity_check(-1);
e028f269 452 begin_allow_threads();
83f84876 453 status = switch_ivr_session_transfer(session, extension, dialplan, context);
700aa0df 454 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "transfer result: %d\n", status);
e028f269 455 end_allow_threads();
83f84876
AM
456 return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
457}
458
47985c56 459SWITCH_DECLARE(int) CoreSession::playAndGetDigits(int min_digits,
f45d0601
MJ
460 int max_digits,
461 int max_tries,
462 int timeout,
463 char *terminators,
464 char *audio_files,
465 char *bad_input_audio_files,
466 char *dtmf_buf,
467 char *digits_regex)
83f84876
AM
468{
469 switch_status_t status;
470 sanity_check(-1);
fedefcb6
MJ
471 begin_allow_threads();
472 status = switch_play_and_get_digits( session,
473 (uint32_t) min_digits,
474 (uint32_t) max_digits,
475 (uint32_t) max_tries,
476 (uint32_t) timeout,
477 terminators,
478 audio_files,
479 bad_input_audio_files,
c806a20d
TL
480 dtmf_buf,
481 128,
fedefcb6 482 digits_regex);
6f78befa
TL
483
484 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "playAndGetDigits dtmf_buf: %s\n", dtmf_buf);
485
fedefcb6 486 end_allow_threads();
83f84876
AM
487 return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
488}
489
47985c56 490SWITCH_DECLARE(int) CoreSession::streamFile(char *file, int starting_sample_count) {
f45d0601
MJ
491
492 switch_status_t status;
59526679 493 //switch_file_handle_t fh = { 0 };
622a2733 494 const char *prebuf;
f45d0601
MJ
495
496 sanity_check(-1);
59526679
AM
497
498 memset(&local_fh, 0, sizeof(local_fh));
499 fhp = &local_fh;
500 local_fh.samples = starting_sample_count;
f45d0601 501
f45d0601
MJ
502
503 if ((prebuf = switch_channel_get_variable(this->channel, "stream_prebuffer"))) {
504 int maybe = atoi(prebuf);
505 if (maybe > 0) {
59526679 506 local_fh.prebuf = maybe;
f45d0601
MJ
507 }
508 }
509
59526679
AM
510
511 store_file_handle(&local_fh);
512
513 begin_allow_threads();
514 status = switch_ivr_play_file(session, fhp, file, ap);
515 end_allow_threads();
516
f45d0601
MJ
517 return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
518
519}
520
47985c56 521SWITCH_DECLARE(bool) CoreSession::ready() {
f45d0601
MJ
522
523 switch_channel_t *channel;
524
525 if (!session) {
526 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "You must call the session.originate method before calling this method!\n");
527 return false;
528 }
529
530 channel = switch_core_session_get_channel(session);
f45d0601 531
482badff 532 return switch_channel_ready(channel) != 0;
fedefcb6
MJ
533}
534
47985c56 535SWITCH_DECLARE(int) CoreSession::originate(CoreSession *a_leg_session,
e028f269
MJ
536 char *dest,
537 int timeout)
538{
539
540 switch_memory_pool_t *pool = NULL;
541 switch_core_session_t *aleg_core_session = NULL;
542 switch_call_cause_t cause;
543
544 cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
545
700aa0df
TL
546 if (a_leg_session != NULL) {
547 aleg_core_session = a_leg_session->session;
e028f269
MJ
548 }
549
700aa0df
TL
550 // this session has no valid switch_core_session_t at this point, and therefore
551 // no valid channel. since the threadstate is stored in the channel, and there
552 // is none, if we try to call begin_alllow_threads it will fail miserably.
553 // use the 'a leg session' to do the thread swapping stuff.
3d3ee88d 554 if (a_leg_session) a_leg_session->begin_allow_threads();
e028f269
MJ
555
556 if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
557 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n");
558 goto failed;
559 }
560
561 if (switch_ivr_originate(aleg_core_session,
562 &session,
563 &cause,
564 dest,
565 timeout,
566 NULL,
567 NULL,
568 NULL,
8433c7e0
AM
569 &caller_profile,
570 SOF_NONE) != SWITCH_STATUS_SUCCESS) {
e028f269
MJ
571 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Error Creating Outgoing Channel! [%s]\n", dest);
572 goto failed;
573
574 }
575
3d3ee88d 576 if (a_leg_session) a_leg_session->end_allow_threads();
d895c81d 577 channel = switch_core_session_get_channel(session);
94b22258 578 allocated = 1;
ae76db7b
AM
579 switch_channel_set_state(switch_core_session_get_channel(session), CS_TRANSMIT);
580
e028f269
MJ
581 return SWITCH_STATUS_SUCCESS;
582
583 failed:
3d3ee88d 584 if (a_leg_session) a_leg_session->end_allow_threads();
e028f269
MJ
585 return SWITCH_STATUS_FALSE;
586}
587
47985c56 588SWITCH_DECLARE(int) CoreSession::recordFile(char *file_name, int max_len, int silence_threshold, int silence_secs)
bd2c91b0
MJ
589{
590 switch_file_handle_t fh = { 0 };
591 switch_status_t status;
592
593 fh.thresh = silence_threshold;
594 fh.silence_hits = silence_secs;
595 store_file_handle(&fh);
596 begin_allow_threads();
597 status = switch_ivr_record_file(session, &fh, file_name, &args, max_len);
598 end_allow_threads();
599 return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
600
601}
e028f269 602
47985c56 603SWITCH_DECLARE(int) CoreSession::flushEvents()
6f78befa
TL
604{
605 switch_event_t *event;
606 switch_channel_t *channel;
607
608 if (!session) {
609 return SWITCH_STATUS_FALSE;
610 }
611 channel = switch_core_session_get_channel(session);
6f78befa
TL
612
613 while (switch_core_session_dequeue_event(session, &event) == SWITCH_STATUS_SUCCESS) {
614 switch_event_destroy(&event);
615 }
616 return SWITCH_STATUS_SUCCESS;
617}
618
47985c56 619SWITCH_DECLARE(int) CoreSession::flushDigits()
6f78befa 620{
482badff 621 switch_channel_flush_dtmf(switch_core_session_get_channel(session));
6f78befa
TL
622 return SWITCH_STATUS_SUCCESS;
623}
624
47985c56 625SWITCH_DECLARE(int) CoreSession::setAutoHangup(bool val)
6f78befa
TL
626{
627 if (!session) {
628 return SWITCH_STATUS_FALSE;
629 }
630 if (val) {
631 switch_set_flag(this, S_HUP);
632 } else {
633 switch_clear_flag(this, S_HUP);
634 }
635 return SWITCH_STATUS_SUCCESS;
636}
637
47985c56 638SWITCH_DECLARE(void) CoreSession::setCallerData(char *var, char *val) {
e028f269
MJ
639
640 if (strcmp(var, "dialplan") == 0) {
641 caller_profile.dialplan = val;
642 }
643 if (strcmp(var, "context") == 0) {
644 caller_profile.context = val;
645 }
646 if (strcmp(var, "caller_id_name") == 0) {
647 caller_profile.caller_id_name = val;
648 }
649 if (strcmp(var, "caller_id_number") == 0) {
650 caller_profile.caller_id_number = val;
651 }
652 if (strcmp(var, "network_addr") == 0) {
653 caller_profile.network_addr = val;
654 }
655 if (strcmp(var, "ani") == 0) {
656 caller_profile.ani = val;
657 }
658 if (strcmp(var, "aniii") == 0) {
659 caller_profile.aniii = val;
660 }
661 if (strcmp(var, "rdnis") == 0) {
662 caller_profile.rdnis = val;
663 }
664 if (strcmp(var, "username") == 0) {
665 caller_profile.username = val;
666 }
667
668}
669
47985c56 670SWITCH_DECLARE(void) CoreSession::setHangupHook(void *hangup_func) {
6f78befa 671
a06997ee
AM
672 sanity_check_noreturn;
673
6f78befa
TL
674 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CoreSession::seHangupHook, hangup_func: %p\n", hangup_func);
675 on_hangup = hangup_func;
676 switch_channel_t *channel = switch_core_session_get_channel(session);
6f78befa
TL
677
678 hook_state = switch_channel_get_state(channel);
679 switch_channel_set_private(channel, "CoreSession", this);
680 switch_core_event_hook_add_state_change(session, hanguphook);
fedefcb6
MJ
681}
682
f45d0601
MJ
683/** \brief Store a file handle in the callback args
684 *
685 * In a few of the methods like playFile and streamfile,
686 * an empty switch_file_handle_t is created and passed
687 * to core, and stored in callback args so that the callback
688 * handler can retrieve it for pausing, ff, rewinding file ptr.
689 *
690 * \param fh - a switch_file_handle_t
691 */
692void CoreSession::store_file_handle(switch_file_handle_t *fh) {
693 cb_state.extra = fh; // set a file handle so callback handler can pause
694 args.buf = &cb_state;
695 ap = &args;
696}
fedefcb6 697
83f84876 698
e028f269
MJ
699/* ---- methods not bound to CoreSession instance ---- */
700
701
47985c56 702SWITCH_DECLARE(void) console_log(char *level_str, char *msg)
e028f269
MJ
703{
704 switch_log_level_t level = SWITCH_LOG_DEBUG;
705 if (level_str) {
706 level = switch_log_str2level(level_str);
cc71ce69
MJ
707 if (level == SWITCH_LOG_INVALID) {
708 level = SWITCH_LOG_DEBUG;
709 }
e028f269 710 }
ae76db7b 711 switch_log_printf(SWITCH_CHANNEL_LOG, level, "%s", switch_str_nil(msg));
e028f269
MJ
712}
713
47985c56 714SWITCH_DECLARE(void) console_clean_log(char *msg)
e028f269 715{
ae76db7b 716 switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN,SWITCH_LOG_DEBUG, "%s", switch_str_nil(msg));
e028f269
MJ
717}
718
719
47985c56 720SWITCH_DECLARE(char *)api_execute(char *cmd, char *arg)
e028f269
MJ
721{
722 switch_stream_handle_t stream = { 0 };
723 SWITCH_STANDARD_STREAM(stream);
724 switch_api_execute(cmd, arg, NULL, &stream);
725 return (char *) stream.data;
726}
727
47985c56 728SWITCH_DECLARE(void) api_reply_delete(char *reply)
e028f269
MJ
729{
730 if (!switch_strlen_zero(reply)) {
731 free(reply);
732 }
733}
734
735
47985c56 736SWITCH_DECLARE(void) bridge(CoreSession &session_a, CoreSession &session_b)
e028f269
MJ
737{
738 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "bridge called, session_a uuid: %s\n", session_a.get_uuid());
739 switch_input_callback_function_t dtmf_func = NULL;
740 switch_input_args_t args;
741
742 session_a.begin_allow_threads();
743 args = session_a.get_cb_args(); // get the cb_args data structure for session a
744 dtmf_func = args.input_callback; // get the call back function
745 switch_ivr_multi_threaded_bridge(session_a.session, session_b.session, dtmf_func, args.buf, args.buf);
746 session_a.end_allow_threads();
747
748}
749
750
47985c56 751SWITCH_DECLARE_NONSTD(switch_status_t) hanguphook(switch_core_session_t *session_hungup)
6f78befa 752{
482badff 753 switch_channel_t *channel = switch_core_session_get_channel(session_hungup);
6f78befa 754 CoreSession *coresession = NULL;
482badff 755 switch_channel_state_t state = switch_channel_get_state(channel);
6f78befa
TL
756
757 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "hangup_hook called\n");
59526679 758
6f78befa 759
6f78befa
TL
760 if ((coresession = (CoreSession *) switch_channel_get_private(channel, "CoreSession"))) {
761 if (coresession->hook_state != state) {
762 coresession->hook_state = state;
763 coresession->check_hangup_hook();
764 }
765 }
766
767 return SWITCH_STATUS_SUCCESS;
768}
769
770
47985c56 771SWITCH_DECLARE_NONSTD(switch_status_t) dtmf_callback(switch_core_session_t *session_cb,
6f78befa
TL
772 void *input,
773 switch_input_type_t itype,
774 void *buf,
775 unsigned int buflen) {
776
482badff 777 switch_channel_t *channel = switch_core_session_get_channel(session_cb);
6f78befa
TL
778 CoreSession *coresession = NULL;
779 switch_status_t result;
780
c806a20d 781 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "dtmf_callback called\n");
6f78befa 782
59526679
AM
783
784 //coresession = (CoreSession *) buf;
6f78befa 785 coresession = (CoreSession *) switch_channel_get_private(channel, "CoreSession");
59526679 786
6f78befa
TL
787 if (!coresession) {
788 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid CoreSession\n");
789 return SWITCH_STATUS_FALSE;
790 }
791
792 result = coresession->run_dtmf_callback(input, itype);
793 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "process_callback_result returned\n");
794 if (result) {
795 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "process_callback_result returned: %d\n", result);
796 }
797 return result;
798
799}
800
59526679
AM
801
802
47985c56 803SWITCH_DECLARE(switch_status_t) CoreSession::process_callback_result(char *ret)
e028f269
MJ
804{
805
806 switch_file_handle_t *fh = NULL;
6f78befa 807
59526679
AM
808 if (fhp) {
809 fh = fhp;
810 } else {
811 if (!cb_state.extra) {
812 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Process callback result aborted because cb_state.extra is null\n");
813 return SWITCH_STATUS_FALSE;
814 }
815
816 fh = (switch_file_handle_t *) cb_state.extra;
817 }
6f78befa 818
e028f269
MJ
819
820 if (!fh) {
6f78befa
TL
821 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Process callback result aborted because fh is null\n");
822 return SWITCH_STATUS_FALSE;
823 }
824
825 if (!fh->file_interface) {
826 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Process callback result aborted because fh->file_interface is null\n");
e028f269
MJ
827 return SWITCH_STATUS_FALSE;
828 }
829
830 if (!ret) {
59526679 831 return SWITCH_STATUS_SUCCESS;
6f78befa
TL
832 }
833
834 if (!session) {
835 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Process callback result aborted because session is null\n");
e028f269
MJ
836 return SWITCH_STATUS_FALSE;
837 }
838
6f78befa 839
e028f269
MJ
840 if (!strncasecmp(ret, "speed", 4)) {
841 char *p;
842
843 if ((p = strchr(ret, ':'))) {
844 p++;
845 if (*p == '+' || *p == '-') {
846 int step;
847 if (!(step = atoi(p))) {
848 step = 1;
849 }
850 fh->speed += step;
851 } else {
852 int speed = atoi(p);
853 fh->speed = speed;
854 }
855 return SWITCH_STATUS_SUCCESS;
856 }
857
858 return SWITCH_STATUS_FALSE;
859
860 } else if (!strcasecmp(ret, "pause")) {
861 if (switch_test_flag(fh, SWITCH_FILE_PAUSE)) {
862 switch_clear_flag(fh, SWITCH_FILE_PAUSE);
863 } else {
864 switch_set_flag(fh, SWITCH_FILE_PAUSE);
865 }
866 return SWITCH_STATUS_SUCCESS;
867 } else if (!strcasecmp(ret, "stop")) {
868 return SWITCH_STATUS_FALSE;
869 } else if (!strcasecmp(ret, "restart")) {
870 unsigned int pos = 0;
871 fh->speed = 0;
872 switch_core_file_seek(fh, &pos, 0, SEEK_SET);
873 return SWITCH_STATUS_SUCCESS;
874 } else if (!strncasecmp(ret, "seek", 4)) {
875 switch_codec_t *codec;
876 unsigned int samps = 0;
877 unsigned int pos = 0;
878 char *p;
879 codec = switch_core_session_get_read_codec(session);
6f78befa 880 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "got codec\n");
e028f269
MJ
881 if ((p = strchr(ret, ':'))) {
882 p++;
883 if (*p == '+' || *p == '-') {
884 int step;
885 if (!(step = atoi(p))) {
886 step = 1000;
887 }
888 if (step > 0) {
889 samps = step * (codec->implementation->samples_per_second / 1000);
6f78befa 890 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "going to seek\n");
e028f269 891 switch_core_file_seek(fh, &pos, samps, SEEK_CUR);
6f78befa 892 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "done seek\n");
e028f269
MJ
893 } else {
894 samps = step * (codec->implementation->samples_per_second / 1000);
6f78befa 895 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "going to seek\n");
e028f269 896 switch_core_file_seek(fh, &pos, fh->pos - samps, SEEK_SET);
6f78befa 897 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "done seek\n");
e028f269
MJ
898 }
899 } else {
900 samps = atoi(p) * (codec->implementation->samples_per_second / 1000);
6f78befa 901 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "going to seek\n");
e028f269 902 switch_core_file_seek(fh, &pos, samps, SEEK_SET);
6f78befa 903 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "done seek\n");
e028f269
MJ
904 }
905 }
906
907 return SWITCH_STATUS_SUCCESS;
908 }
909
910 if (!strcmp(ret, "true") || !strcmp(ret, "undefined")) {
6f78befa 911 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "return success\n");
e028f269
MJ
912 return SWITCH_STATUS_SUCCESS;
913 }
914
6f78befa 915 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "no match, return false\n");
e028f269 916
c815c059 917 return SWITCH_STATUS_FALSE;
e028f269
MJ
918}
919
83f84876
AM
920/* For Emacs:
921 * Local Variables:
922 * mode:c
923 * indent-tabs-mode:t
924 * tab-width:4
925 * c-basic-offset:4
926 * End:
927 * For VIM:
928 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
929 */