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