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