mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-13 15:50:59 +00:00
break everything
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@720 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
b77747e0d1
commit
4799ec8b8a
@ -8,8 +8,10 @@ $ip and $port or die "Usage $0: <ip> <port>\n";
|
||||
$socket = new IO::Socket::INET->new( PeerPort => $port,
|
||||
Proto => 'udp',
|
||||
PeerAddr => $ip);
|
||||
|
||||
my $buf = `cat $file`;
|
||||
open(I, $file);
|
||||
$/ = undef;
|
||||
my $buf = <I>;
|
||||
close(I);
|
||||
|
||||
$socket->send("$buf\n");
|
||||
|
||||
|
@ -134,7 +134,7 @@ extern "C" {
|
||||
|
||||
/*!
|
||||
\brief Create a new caller profile object
|
||||
\param session session associated with the profile (bound by scope)
|
||||
\param pool memory pool to use
|
||||
\param dialplan name of the dialplan module in use
|
||||
\param caller_id_name caller ID name
|
||||
\param caller_id_number caller ID number
|
||||
@ -144,7 +144,7 @@ extern "C" {
|
||||
\param destination_number destination number
|
||||
\return a new profile object allocated from the session's memory pool
|
||||
*/
|
||||
SWITCH_DECLARE(switch_caller_profile *) switch_caller_profile_new(switch_core_session *session,
|
||||
SWITCH_DECLARE(switch_caller_profile *) switch_caller_profile_new(switch_memory_pool *pool,
|
||||
char *dialplan,
|
||||
char *caller_id_name,
|
||||
char *caller_id_number,
|
||||
|
@ -65,6 +65,13 @@ typedef struct {
|
||||
*/
|
||||
SWITCH_DECLARE(switch_channel_state) switch_channel_get_state(switch_channel *channel);
|
||||
|
||||
/*!
|
||||
\brief Determine if a channel is ready for io
|
||||
\param channel channel to test
|
||||
\return true if the channel is ready
|
||||
*/
|
||||
SWITCH_DECLARE(unsigned int) switch_channel_ready(switch_channel *channel);
|
||||
|
||||
/*!
|
||||
\brief Set the current state of a channel
|
||||
\param channel channel to set state of
|
||||
|
@ -157,6 +157,12 @@ SWITCH_DECLARE(switch_status) switch_core_destroy_memory_pool(switch_memory_pool
|
||||
*/
|
||||
SWITCH_DECLARE(void) switch_core_session_run(switch_core_session *session);
|
||||
|
||||
/*!
|
||||
\brief determine if the session's state machine is running
|
||||
\param session the session on which to check
|
||||
*/
|
||||
SWITCH_DECLARE(unsigned int) switch_core_session_runing(switch_core_session *session);
|
||||
|
||||
/*!
|
||||
\brief Allocate memory from the main pool with no intention of returning it
|
||||
\param memory the number of bytes to allocate
|
||||
|
@ -239,6 +239,8 @@ CF_RECV_AUDIO = (1 << 1) - Channel will receive audio
|
||||
CF_ANSWERED = (1 << 2) - Channel is answered
|
||||
CF_OUTBOUND = (1 << 3) - Channel is an outbound channel
|
||||
CF_EARLY_MEDIA = (1 << 4) - Channel is ready for audio before answer
|
||||
CF_ORIGINATOR = (1 << 5) - Channel is an originator
|
||||
CF_TRANSFER = (1 << 6) - Channel is being transfered
|
||||
</pre>
|
||||
*/
|
||||
|
||||
@ -247,7 +249,9 @@ typedef enum {
|
||||
CF_RECV_AUDIO = (1 << 1),
|
||||
CF_ANSWERED = (1 << 2),
|
||||
CF_OUTBOUND = (1 << 3),
|
||||
CF_EARLY_MEDIA = (1 << 4)
|
||||
CF_EARLY_MEDIA = (1 << 4),
|
||||
CF_ORIGINATOR = (1 << 5),
|
||||
CF_TRANSFER = (1 << 6)
|
||||
} switch_channel_flag;
|
||||
|
||||
|
||||
|
@ -55,7 +55,7 @@ static void audio_bridge_function(switch_core_session *session, char *data)
|
||||
}
|
||||
|
||||
caller_caller_profile = switch_channel_get_caller_profile(caller_channel);
|
||||
caller_profile = switch_caller_profile_new(session,
|
||||
caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
|
||||
caller_caller_profile->dialplan,
|
||||
caller_caller_profile->caller_id_name,
|
||||
caller_caller_profile->caller_id_number,
|
||||
|
@ -550,7 +550,6 @@ static switch_status exosip_read_frame(switch_core_session *session, switch_fram
|
||||
&& tech_pvt->read_frame.datalen == 0) {
|
||||
tech_pvt->read_frame.datalen =
|
||||
jrtp4c_read(tech_pvt->rtp_session, tech_pvt->read_frame.data, sizeof(tech_pvt->read_buf), &payload);
|
||||
|
||||
/* RFC2833 ... TBD try harder to honor the duration etc.*/
|
||||
if (payload == 101) {
|
||||
unsigned char *packet = tech_pvt->read_frame.data;
|
||||
@ -732,7 +731,6 @@ static switch_status exosip_kill_channel(switch_core_session *session, int sig)
|
||||
tech_pvt = switch_core_session_get_private(session);
|
||||
assert(tech_pvt != NULL);
|
||||
|
||||
|
||||
switch_clear_flag(tech_pvt, TFLAG_IO);
|
||||
switch_set_flag(tech_pvt, TFLAG_BYE);
|
||||
|
||||
@ -1008,7 +1006,7 @@ static switch_status exosip_create_call(eXosip_event_t * event)
|
||||
snprintf(name, sizeof(name), "Exosip/%s-%04x", event->request->from->url->username, rand() & 0xffff);
|
||||
switch_channel_set_name(channel, name);
|
||||
|
||||
if ((tech_pvt->caller_profile = switch_caller_profile_new(session,
|
||||
if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
|
||||
globals.dialplan,
|
||||
event->request->from->displayname,
|
||||
event->request->from->url->username,
|
||||
|
@ -979,7 +979,7 @@ SWITCH_MOD_DECLARE(switch_status) switch_module_runtime(void)
|
||||
}
|
||||
|
||||
|
||||
if ((tech_pvt->caller_profile = switch_caller_profile_new(session,
|
||||
if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
|
||||
globals.dialplan,
|
||||
iaxevent->ies.calling_name,
|
||||
iaxevent->ies.calling_number,
|
||||
|
@ -808,7 +808,7 @@ static switch_status place_call(char *dest, char *out, size_t outlen)
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if ((tech_pvt->caller_profile = switch_caller_profile_new(session,
|
||||
if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
|
||||
globals.dialplan,
|
||||
globals.cid_name,
|
||||
globals.cid_num, NULL, NULL, NULL, dest)) != 0) {
|
||||
|
@ -973,7 +973,7 @@ static int on_ring(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri
|
||||
snprintf(ani2str, 5, "%.2d", event->ring.ani2);
|
||||
}
|
||||
|
||||
if ((tech_pvt->caller_profile = switch_caller_profile_new(session,
|
||||
if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
|
||||
globals.dialplan,
|
||||
"wanpipe fixme",
|
||||
event->ring.callingnum,
|
||||
|
@ -1064,7 +1064,7 @@ static void *woomera_channel_thread_run(switch_thread *thread, void *obj)
|
||||
}
|
||||
ip = woomera_message_header(&wmsg, "Remote-Address");
|
||||
|
||||
if ((tech_pvt->caller_profile = switch_caller_profile_new(session,
|
||||
if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
|
||||
tech_pvt->profile->dialplan,
|
||||
cid_name, cid_num, ip, NULL, NULL, exten)) != 0) {
|
||||
char name[128];
|
||||
|
@ -63,6 +63,8 @@
|
||||
static const char modname[] = "mod_spidermonkey";
|
||||
|
||||
static int eval_some_js(char *code, JSContext *cx, JSObject *obj, jsval *rval);
|
||||
static void session_destroy(JSContext *cx, JSObject *obj);
|
||||
static JSBool session_construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
|
||||
static struct {
|
||||
size_t gStackChunkSize;
|
||||
@ -86,6 +88,10 @@ typedef enum {
|
||||
TTF_DTMF = (1 << 0)
|
||||
} teletone_flag_t;
|
||||
|
||||
typedef enum {
|
||||
S_HUP = (1 << 0)
|
||||
} session_flag_t;
|
||||
|
||||
struct dtmf_callback_state {
|
||||
struct js_session *session_state;
|
||||
char code_buffer[1024];
|
||||
@ -100,6 +106,7 @@ struct js_session {
|
||||
switch_core_session *session;
|
||||
JSContext *cx;
|
||||
JSObject *obj;
|
||||
switch_memory_pool *pool;
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
@ -407,7 +414,7 @@ static JSBool session_recordfile(JSContext *cx, JSObject *obj, uintN argc, jsval
|
||||
switch_ivr_record_file(jss->session, &fh, file_name, dtmf_func, bp, len);
|
||||
*rval = STRING_TO_JSVAL (JS_NewStringCopyZ(cx, cb_state.ret_buffer));
|
||||
|
||||
return (switch_channel_get_state(channel) == CS_EXECUTE) ? JS_TRUE : JS_FALSE;
|
||||
return (switch_channel_ready(channel)) ? JS_TRUE : JS_FALSE;
|
||||
}
|
||||
|
||||
static JSBool session_streamfile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
@ -459,7 +466,7 @@ static JSBool session_streamfile(JSContext *cx, JSObject *obj, uintN argc, jsval
|
||||
switch_ivr_play_file(jss->session, &fh, file_name, timer_name, dtmf_func, bp, len);
|
||||
*rval = STRING_TO_JSVAL (JS_NewStringCopyZ(cx, cb_state.ret_buffer));
|
||||
|
||||
return (switch_channel_get_state(channel) == CS_EXECUTE) ? JS_TRUE : JS_FALSE;
|
||||
return (switch_channel_ready(channel)) ? JS_TRUE : JS_FALSE;
|
||||
}
|
||||
|
||||
static JSBool session_speak(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
@ -520,7 +527,7 @@ static JSBool session_speak(JSContext *cx, JSObject *obj, uintN argc, jsval *arg
|
||||
|
||||
*rval = STRING_TO_JSVAL (JS_NewStringCopyZ(cx, cb_state.ret_buffer));
|
||||
|
||||
return (switch_channel_get_state(channel) == CS_EXECUTE) ? JS_TRUE : JS_FALSE;
|
||||
return (switch_channel_ready(channel)) ? JS_TRUE : JS_FALSE;
|
||||
}
|
||||
|
||||
static JSBool session_get_digits(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
@ -566,6 +573,59 @@ static JSBool session_answer(JSContext *cx, JSObject *obj, uintN argc, jsval *ar
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool session_ready(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
struct js_session *jss = JS_GetPrivate(cx, obj);
|
||||
switch_channel *channel;
|
||||
|
||||
channel = switch_core_session_get_channel(jss->session);
|
||||
assert(channel != NULL);
|
||||
*rval = BOOLEAN_TO_JSVAL( switch_channel_ready(channel) ? JS_TRUE : JS_FALSE );
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool session_wait_for_answer(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
struct js_session *jss = JS_GetPrivate(cx, obj);
|
||||
switch_channel *channel;
|
||||
switch_time_t started;
|
||||
unsigned int elapsed;
|
||||
channel = switch_core_session_get_channel(jss->session);
|
||||
assert(channel != NULL);
|
||||
int32 timeout = 60;
|
||||
started = switch_time_now();
|
||||
|
||||
if (argc > 0) {
|
||||
JS_ValueToInt32(cx, argv[0], &timeout);
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
elapsed = (unsigned int)((switch_time_now() - started) / 1000);
|
||||
if ((int32)elapsed > timeout || switch_channel_test_flag(channel, CF_ANSWERED) ||
|
||||
switch_channel_test_flag(channel, CF_EARLY_MEDIA)) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch_yield(1000);
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool session_hangup(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
struct js_session *jss = JS_GetPrivate(cx, obj);
|
||||
switch_channel *channel;
|
||||
|
||||
channel = switch_core_session_get_channel(jss->session);
|
||||
assert(channel != NULL);
|
||||
|
||||
switch_channel_hangup(channel);
|
||||
switch_core_session_kill_channel(jss->session, SWITCH_SIG_KILL);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
#ifdef HAVE_CURL
|
||||
|
||||
struct config_data {
|
||||
@ -658,7 +718,8 @@ static JSBool js_fetchurl(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
/* Session Object */
|
||||
/*********************************************************************************/
|
||||
enum session_tinyid {
|
||||
SESSION_NAME, SESSION_STATE
|
||||
SESSION_NAME, SESSION_STATE,
|
||||
PROFILE_DIALPLAN, PROFILE_CID_NAME, PROFILE_CID_NUM, PROFILE_IP, PROFILE_ANI, PROFILE_ANI2, PROFILE_DEST
|
||||
};
|
||||
|
||||
static JSFunctionSpec session_methods[] = {
|
||||
@ -667,6 +728,9 @@ static JSFunctionSpec session_methods[] = {
|
||||
{"speak", session_speak, 1},
|
||||
{"getDigits", session_get_digits, 1},
|
||||
{"answer", session_answer, 0},
|
||||
{"ready", session_ready, 0},
|
||||
{"waitForAnswer", session_wait_for_answer, 0},
|
||||
{"hangup", session_hangup, 0},
|
||||
{0}
|
||||
};
|
||||
|
||||
@ -674,6 +738,13 @@ static JSFunctionSpec session_methods[] = {
|
||||
static JSPropertySpec session_props[] = {
|
||||
{"name", SESSION_NAME, JSPROP_READONLY|JSPROP_PERMANENT},
|
||||
{"state", SESSION_STATE, JSPROP_READONLY|JSPROP_PERMANENT},
|
||||
{"dialplan", PROFILE_DIALPLAN, JSPROP_READONLY|JSPROP_PERMANENT},
|
||||
{"caller_id_name", PROFILE_CID_NAME, JSPROP_READONLY|JSPROP_PERMANENT},
|
||||
{"caller_id_num", PROFILE_CID_NUM, JSPROP_READONLY|JSPROP_PERMANENT},
|
||||
{"network_addr", PROFILE_IP, JSPROP_READONLY|JSPROP_PERMANENT},
|
||||
{"ani", PROFILE_ANI, JSPROP_READONLY|JSPROP_PERMANENT},
|
||||
{"ani2", PROFILE_ANI2, JSPROP_READONLY|JSPROP_PERMANENT},
|
||||
{"destination", PROFILE_DEST, JSPROP_READONLY|JSPROP_PERMANENT},
|
||||
{0}
|
||||
};
|
||||
|
||||
@ -683,11 +754,14 @@ static JSBool session_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval
|
||||
int param = 0;
|
||||
JSBool res = JS_TRUE;
|
||||
switch_channel *channel;
|
||||
switch_caller_profile *caller_profile;
|
||||
char *name;
|
||||
|
||||
channel = switch_core_session_get_channel(jss->session);
|
||||
assert(channel != NULL);
|
||||
|
||||
caller_profile = switch_channel_get_caller_profile(channel);
|
||||
|
||||
name = JS_GetStringBytes(JS_ValueToString(cx, id));
|
||||
/* numbers are our props anything else is a method */
|
||||
if (name[0] >= 48 && name[0] <= 57) {
|
||||
@ -701,7 +775,42 @@ static JSBool session_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, switch_channel_get_name(channel)));
|
||||
break;
|
||||
case SESSION_STATE:
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, switch_channel_state_name(switch_channel_get_state(channel)) ));
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, switch_channel_state_name(switch_channel_get_state(channel))));
|
||||
break;
|
||||
case PROFILE_DIALPLAN:
|
||||
if (caller_profile) {
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, caller_profile->dialplan));
|
||||
}
|
||||
break;
|
||||
case PROFILE_CID_NAME:
|
||||
if (caller_profile) {
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, caller_profile->caller_id_name));
|
||||
}
|
||||
break;
|
||||
case PROFILE_CID_NUM:
|
||||
if (caller_profile) {
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, caller_profile->caller_id_number));
|
||||
}
|
||||
break;
|
||||
case PROFILE_IP:
|
||||
if (caller_profile) {
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, caller_profile->network_addr));
|
||||
}
|
||||
break;
|
||||
case PROFILE_ANI:
|
||||
if (caller_profile) {
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, caller_profile->ani));
|
||||
}
|
||||
break;
|
||||
case PROFILE_ANI2:
|
||||
if (caller_profile) {
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, caller_profile->ani2));
|
||||
}
|
||||
break;
|
||||
case PROFILE_DEST:
|
||||
if (caller_profile) {
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, caller_profile->destination_number));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
res = JS_FALSE;
|
||||
@ -715,7 +824,8 @@ static JSBool session_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval
|
||||
JSClass session_class = {
|
||||
"Session", JSCLASS_HAS_PRIVATE,
|
||||
JS_PropertyStub, JS_PropertyStub, session_getProperty, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, session_destroy, NULL, NULL, NULL,
|
||||
session_construct
|
||||
};
|
||||
|
||||
|
||||
@ -752,6 +862,117 @@ static int teletone_handler(teletone_generation_session_t *ts, teletone_tone_map
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Session Object */
|
||||
/*********************************************************************************/
|
||||
static JSBool session_construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
switch_memory_pool *pool = NULL;
|
||||
int need_pool = 1;
|
||||
if (argc > 2) {
|
||||
struct js_session *jss = NULL;
|
||||
JSObject *session_obj;
|
||||
switch_core_session *session = NULL, *peer_session = NULL;
|
||||
switch_caller_profile *caller_profile = NULL;
|
||||
char *channel_type = NULL;
|
||||
char *dest = NULL;
|
||||
char *dialplan = NULL;
|
||||
char *cid_name = "";
|
||||
char *cid_num = "";
|
||||
char *network_addr = "";
|
||||
char *ani = "";
|
||||
char *ani2 = "";
|
||||
|
||||
|
||||
if (JS_ValueToObject(cx, argv[0], &session_obj)) {
|
||||
struct js_session *old_jss = NULL;
|
||||
if ((old_jss = JS_GetPrivate(cx, session_obj))) {
|
||||
session = old_jss->session;
|
||||
pool = switch_core_session_get_pool(session);
|
||||
need_pool = 0;
|
||||
}
|
||||
}
|
||||
|
||||
channel_type = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
|
||||
dest = JS_GetStringBytes(JS_ValueToString(cx, argv[2]));
|
||||
|
||||
if (argc > 3) {
|
||||
dialplan = JS_GetStringBytes(JS_ValueToString(cx, argv[3]));
|
||||
}
|
||||
if (argc > 4) {
|
||||
cid_name = JS_GetStringBytes(JS_ValueToString(cx, argv[4]));
|
||||
}
|
||||
if (argc > 5) {
|
||||
cid_num = JS_GetStringBytes(JS_ValueToString(cx, argv[5]));
|
||||
}
|
||||
if (argc > 6) {
|
||||
network_addr = JS_GetStringBytes(JS_ValueToString(cx, argv[6]));
|
||||
}
|
||||
if (argc > 7) {
|
||||
ani = JS_GetStringBytes(JS_ValueToString(cx, argv[7]));
|
||||
}
|
||||
if (argc > 8) {
|
||||
ani2 = JS_GetStringBytes(JS_ValueToString(cx, argv[8]));
|
||||
}
|
||||
|
||||
if (need_pool) {
|
||||
if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "OH OH no pool\n");
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
caller_profile = switch_caller_profile_new(pool, dialplan, cid_name, cid_num, network_addr, ani, ani2, dest);
|
||||
if (switch_core_session_outgoing_channel(session, channel_type, caller_profile, &peer_session) == SWITCH_STATUS_SUCCESS) {
|
||||
jss = switch_core_session_alloc(peer_session, sizeof(*jss));
|
||||
jss->session = peer_session;
|
||||
jss->flags = 0;
|
||||
jss->cx = cx;
|
||||
jss->obj = obj;
|
||||
JS_SetPrivate(cx, obj, jss);
|
||||
if (need_pool) {
|
||||
jss->pool = pool;
|
||||
}
|
||||
switch_core_session_thread_launch(peer_session);
|
||||
switch_set_flag(jss, S_HUP);
|
||||
|
||||
return JS_TRUE;
|
||||
} else {
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Cannot Create Channel\n");
|
||||
}
|
||||
} else {
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Missing Args\n");
|
||||
}
|
||||
|
||||
if (need_pool) {
|
||||
switch_core_destroy_memory_pool(&pool);
|
||||
}
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
static void session_destroy(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
struct js_session *jss;
|
||||
|
||||
if (cx && obj) {
|
||||
if ((jss = JS_GetPrivate(cx, obj))) {
|
||||
if (jss->pool) {
|
||||
switch_core_destroy_memory_pool(&jss->pool);
|
||||
}
|
||||
|
||||
if (switch_test_flag(jss, S_HUP)) {
|
||||
switch_channel *channel;
|
||||
|
||||
if (jss->session) {
|
||||
channel = switch_core_session_get_channel(jss->session);
|
||||
switch_channel_hangup(channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* TeleTone Object */
|
||||
/*********************************************************************************/
|
||||
static JSBool teletone_construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
@ -1072,6 +1293,42 @@ static int write_buf(int fd, char *buf) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static JSBool js_bridge(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
struct js_session *jss_a = NULL, *jss_b = NULL;
|
||||
JSObject *session_obj_a = NULL, *session_obj_b = NULL;
|
||||
int32 timelimit = 60;
|
||||
|
||||
if (argc > 1) {
|
||||
if (JS_ValueToObject(cx, argv[0], &session_obj_a)) {
|
||||
if (!(jss_a = JS_GetPrivate(cx, session_obj_a))) {
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Cannot Find Session [1]\n");
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
if (JS_ValueToObject(cx, argv[1], &session_obj_b)) {
|
||||
if (!(jss_b = JS_GetPrivate(cx, session_obj_b))) {
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Cannot Find Session [1]\n");
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (argc > 3) {
|
||||
if (!JS_ValueToInt32(cx, argv[3], &timelimit)) {
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Cannot Convert to INT\n");
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
if (!(jss_a && jss_b)) {
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Failure! %s %s\n", jss_a ? "y" : "n", jss_b ? "y" : "n");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
switch_ivr_multi_threaded_bridge(jss_a->session, jss_b->session, timelimit, NULL, NULL, NULL);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool js_email(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
char *to = NULL, *from = NULL, *headers, *body = NULL, *file = NULL;
|
||||
@ -1195,6 +1452,7 @@ static JSFunctionSpec fs_functions[] = {
|
||||
{"console_log", js_log, 2},
|
||||
{"include", js_include, 1},
|
||||
{"email", js_email, 2},
|
||||
{"bridge", js_bridge, 2},
|
||||
#ifdef HAVE_CURL
|
||||
{"fetchURL", js_fetchurl, 1},
|
||||
#endif
|
||||
@ -1231,6 +1489,40 @@ static int eval_some_js(char *code, JSContext *cx, JSObject *obj, jsval *rval)
|
||||
return res;
|
||||
}
|
||||
|
||||
static int env_init(JSContext *cx, JSObject *javascript_object)
|
||||
{
|
||||
|
||||
JS_DefineFunctions(cx, javascript_object, fs_functions);
|
||||
|
||||
JS_InitStandardClasses(cx, javascript_object);
|
||||
|
||||
JS_InitClass(cx,
|
||||
javascript_object,
|
||||
NULL,
|
||||
&teletone_class,
|
||||
teletone_construct,
|
||||
3,
|
||||
teletone_props,
|
||||
teletone_methods,
|
||||
teletone_props,
|
||||
teletone_methods
|
||||
);
|
||||
|
||||
JS_InitClass(cx,
|
||||
javascript_object,
|
||||
NULL,
|
||||
&session_class,
|
||||
session_construct,
|
||||
3,
|
||||
session_props,
|
||||
session_methods,
|
||||
session_props,
|
||||
session_methods
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void js_exec(switch_core_session *session, char *data)
|
||||
{
|
||||
char *code, *next, *arg, *nextarg;
|
||||
@ -1270,28 +1562,14 @@ static void js_exec(switch_core_session *session, char *data)
|
||||
if ((cx = JS_NewContext(globals.rt, globals.gStackChunkSize))) {
|
||||
JS_SetErrorReporter(cx, js_error);
|
||||
if ((javascript_global_object = JS_NewObject(cx, &global_class, NULL, NULL)) &&
|
||||
JS_DefineFunctions(cx, javascript_global_object, fs_functions) &&
|
||||
JS_InitStandardClasses(cx, javascript_global_object) &&
|
||||
env_init(cx, javascript_global_object) &&
|
||||
(session_obj = new_js_session(cx, javascript_global_object, session, &jss, "session", flags))) {
|
||||
JS_SetGlobalObject(cx, javascript_global_object);
|
||||
JS_SetPrivate(cx, javascript_global_object, session);
|
||||
res = 0;
|
||||
|
||||
|
||||
JS_InitClass(cx,
|
||||
javascript_global_object,
|
||||
NULL,
|
||||
&teletone_class,
|
||||
teletone_construct,
|
||||
3,
|
||||
teletone_props,
|
||||
teletone_methods,
|
||||
teletone_props,
|
||||
teletone_methods
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
do {
|
||||
if ((next = strchr(code, '|'))) {
|
||||
*next = '\0';
|
||||
@ -1330,6 +1608,89 @@ static void js_exec(switch_core_session *session, char *data)
|
||||
}
|
||||
}
|
||||
|
||||
static void *js_thread_run(switch_thread *thread, void *obj)
|
||||
{
|
||||
JSContext *cx = NULL;
|
||||
JSObject *javascript_global_object = NULL;
|
||||
cx = JS_NewContext(globals.rt, globals.gStackChunkSize);
|
||||
char buf[1024];
|
||||
char *code, *next, *arg, *nextarg;
|
||||
jsval rval;
|
||||
int x = 0;
|
||||
char *input_code = obj;
|
||||
|
||||
javascript_global_object = JS_NewObject(cx, &global_class, NULL, NULL);
|
||||
env_init(cx, javascript_global_object);
|
||||
code = input_code;
|
||||
|
||||
do {
|
||||
if ((next = strchr(code, '|'))) {
|
||||
*next = '\0';
|
||||
next++;
|
||||
}
|
||||
if ((arg = strchr(code, ':'))) {
|
||||
int y;
|
||||
for (y=0;(arg=strchr(arg, ':'));y++)
|
||||
arg++;
|
||||
arg = strchr(code, ':');
|
||||
*arg = '\0';
|
||||
arg++;
|
||||
snprintf(buf, sizeof(buf), "~var Argv = new Array(%d);", y);
|
||||
eval_some_js(buf, cx, javascript_global_object, &rval);
|
||||
snprintf(buf, sizeof(buf), "~var argc = %d", y);
|
||||
eval_some_js(buf, cx, javascript_global_object, &rval);
|
||||
do {
|
||||
if ((nextarg = strchr(arg, ':'))) {
|
||||
*nextarg = '\0';
|
||||
nextarg++;
|
||||
}
|
||||
snprintf(buf, sizeof(buf), "~Argv[%d] = \"%s\";", x++, arg);
|
||||
eval_some_js(buf, cx, javascript_global_object, &rval);
|
||||
arg = nextarg;
|
||||
} while (arg);
|
||||
}
|
||||
if (!eval_some_js(code, cx, javascript_global_object, &rval)) {
|
||||
break;
|
||||
}
|
||||
code = next;
|
||||
} while (code);
|
||||
|
||||
if (input_code) {
|
||||
free(input_code);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static switch_memory_pool *module_pool = NULL;
|
||||
|
||||
static void js_thread_launch(char *text)
|
||||
{
|
||||
switch_thread *thread;
|
||||
switch_threadattr_t *thd_attr = NULL;
|
||||
|
||||
if (!module_pool) {
|
||||
if (switch_core_new_memory_pool(&module_pool) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "OH OH no pool\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch_threadattr_create(&thd_attr, module_pool);
|
||||
switch_threadattr_detach_set(thd_attr, 1);
|
||||
switch_thread_create(&thread, thd_attr, js_thread_run, strdup(text), module_pool);
|
||||
}
|
||||
|
||||
|
||||
static switch_status launch_async(char *text, char *out, size_t outlen)
|
||||
{
|
||||
|
||||
js_thread_launch(text);
|
||||
switch_copy_string(out, "OK", outlen);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static const switch_application_interface ivrtest_application_interface = {
|
||||
/*.interface_name */ "javascript",
|
||||
/*.application_function */ js_exec,
|
||||
@ -1337,6 +1698,12 @@ static const switch_application_interface ivrtest_application_interface = {
|
||||
/*.next*/ NULL
|
||||
};
|
||||
|
||||
static struct switch_api_interface js_run_interface = {
|
||||
/*.interface_name */ "jsrun",
|
||||
/*.desc */ "run a script",
|
||||
/*.function */ launch_async,
|
||||
/*.next */ NULL
|
||||
};
|
||||
|
||||
static switch_loadable_module_interface spidermonkey_module_interface = {
|
||||
/*.module_name */ modname,
|
||||
@ -1345,7 +1712,7 @@ static switch_loadable_module_interface spidermonkey_module_interface = {
|
||||
/*.dialplan_interface */ NULL,
|
||||
/*.codec_interface */ NULL,
|
||||
/*.application_interface */ &ivrtest_application_interface,
|
||||
/*.api_interface */ NULL,
|
||||
/*.api_interface */ &js_run_interface,
|
||||
/*.file_interface */ NULL,
|
||||
/*.speech_interface */ NULL,
|
||||
/*.directory_interface */ NULL
|
||||
|
@ -31,7 +31,7 @@
|
||||
*/
|
||||
#include <switch_caller.h>
|
||||
|
||||
SWITCH_DECLARE(switch_caller_profile *) switch_caller_profile_new(switch_core_session *session,
|
||||
SWITCH_DECLARE(switch_caller_profile *) switch_caller_profile_new(switch_memory_pool *pool,
|
||||
char *dialplan,
|
||||
char *caller_id_name,
|
||||
char *caller_id_number,
|
||||
@ -42,14 +42,14 @@ SWITCH_DECLARE(switch_caller_profile *) switch_caller_profile_new(switch_core_se
|
||||
|
||||
switch_caller_profile *profile = NULL;
|
||||
|
||||
if ((profile = switch_core_session_alloc(session, sizeof(switch_caller_profile))) != 0) {
|
||||
profile->dialplan = switch_core_session_strdup(session, dialplan);
|
||||
profile->caller_id_name = switch_core_session_strdup(session, caller_id_name);
|
||||
profile->caller_id_number = switch_core_session_strdup(session, caller_id_number);
|
||||
profile->network_addr = switch_core_session_strdup(session, network_addr);
|
||||
profile->ani = switch_core_session_strdup(session, ani);
|
||||
profile->ani2 = switch_core_session_strdup(session, ani2);
|
||||
profile->destination_number = switch_core_session_strdup(session, destination_number);
|
||||
if ((profile = switch_core_alloc(pool, sizeof(switch_caller_profile))) != 0) {
|
||||
profile->dialplan = switch_core_strdup(pool, dialplan);
|
||||
profile->caller_id_name = switch_core_strdup(pool, caller_id_name);
|
||||
profile->caller_id_number = switch_core_strdup(pool, caller_id_number);
|
||||
profile->network_addr = switch_core_strdup(pool, network_addr);
|
||||
profile->ani = switch_core_strdup(pool, ani);
|
||||
profile->ani2 = switch_core_strdup(pool, ani2);
|
||||
profile->destination_number = switch_core_strdup(pool, destination_number);
|
||||
}
|
||||
|
||||
return profile;
|
||||
|
@ -248,6 +248,12 @@ SWITCH_DECLARE(switch_channel_state) switch_channel_get_state(switch_channel *ch
|
||||
return channel->state;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(unsigned int) switch_channel_ready(switch_channel *channel)
|
||||
{
|
||||
assert(channel != NULL);
|
||||
return (channel->state > CS_RING && channel->state < CS_HANGUP) ? 1 : 0;
|
||||
}
|
||||
|
||||
static const char *state_names[] = {
|
||||
"CS_NEW",
|
||||
"CS_INIT",
|
||||
|
@ -42,6 +42,7 @@ EXTERN_C void xs_init(pTHX);
|
||||
struct switch_core_session {
|
||||
unsigned long id;
|
||||
char name[80];
|
||||
int thread_running;
|
||||
switch_memory_pool *pool;
|
||||
switch_channel *channel;
|
||||
switch_thread *thread;
|
||||
@ -714,9 +715,9 @@ SWITCH_DECLARE(char *) switch_core_session_strdup(switch_core_session *session,
|
||||
assert(session != NULL);
|
||||
assert(session->pool != NULL);
|
||||
|
||||
if (!todup)
|
||||
if (!todup) {
|
||||
return NULL;
|
||||
|
||||
}
|
||||
len = strlen(todup) + 1;
|
||||
|
||||
if (todup && (duped = apr_palloc(session->pool, len)) != 0) {
|
||||
@ -731,10 +732,11 @@ SWITCH_DECLARE(char *) switch_core_strdup(switch_memory_pool *pool, char *todup)
|
||||
char *duped = NULL;
|
||||
size_t len;
|
||||
assert(pool != NULL);
|
||||
assert(todup != NULL);
|
||||
|
||||
if (!todup)
|
||||
if (!todup) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len = strlen(todup) + 1;
|
||||
|
||||
if (todup && (duped = apr_palloc(pool, len)) != 0) {
|
||||
@ -792,9 +794,11 @@ SWITCH_DECLARE(switch_status) switch_core_session_outgoing_channel(switch_core_s
|
||||
if ((status =
|
||||
endpoint_interface->io_routines->outgoing_channel(session, caller_profile,
|
||||
new_session)) == SWITCH_STATUS_SUCCESS) {
|
||||
for (ptr = session->event_hooks.outgoing_channel; ptr; ptr = ptr->next) {
|
||||
if ((status = ptr->outgoing_channel(session, caller_profile, *new_session)) != SWITCH_STATUS_SUCCESS) {
|
||||
break;
|
||||
if (session) {
|
||||
for (ptr = session->event_hooks.outgoing_channel; ptr; ptr = ptr->next) {
|
||||
if ((status = ptr->outgoing_channel(session, caller_profile, *new_session)) != SWITCH_STATUS_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -806,7 +810,7 @@ SWITCH_DECLARE(switch_status) switch_core_session_outgoing_channel(switch_core_s
|
||||
switch_caller_profile *profile = NULL, *peer_profile = NULL, *cloned_profile = NULL;
|
||||
switch_channel *channel = NULL, *peer_channel = NULL;
|
||||
|
||||
if ((channel = switch_core_session_get_channel(session)) != 0) {
|
||||
if (session && (channel = switch_core_session_get_channel(session)) != 0) {
|
||||
profile = switch_channel_get_caller_profile(channel);
|
||||
}
|
||||
if ((peer_channel = switch_core_session_get_channel(*new_session)) != 0) {
|
||||
@ -820,7 +824,7 @@ SWITCH_DECLARE(switch_status) switch_core_session_outgoing_channel(switch_core_s
|
||||
}
|
||||
}
|
||||
if (peer_profile) {
|
||||
if ((cloned_profile = switch_caller_profile_clone(session, peer_profile)) != 0) {
|
||||
if (session && (cloned_profile = switch_caller_profile_clone(session, peer_profile)) != 0) {
|
||||
switch_channel_set_originatee_caller_profile(channel, cloned_profile);
|
||||
}
|
||||
}
|
||||
@ -1536,7 +1540,7 @@ SWITCH_DECLARE(switch_status) switch_core_new_memory_pool(switch_memory_pool **p
|
||||
return SWITCH_STATUS_MEMERR;
|
||||
}
|
||||
|
||||
if ((apr_pool_create(pool, runtime.memory_pool)) != APR_SUCCESS) {
|
||||
if ((apr_pool_create(pool, runtime.memory_pool)) != SWITCH_STATUS_SUCCESS) {
|
||||
*pool = NULL;
|
||||
return SWITCH_STATUS_MEMERR;
|
||||
}
|
||||
@ -1574,6 +1578,12 @@ static void switch_core_standard_on_ring(switch_core_session *session)
|
||||
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Standard RING %s\n", switch_channel_get_name(session->channel));
|
||||
|
||||
|
||||
if (switch_channel_test_flag(session->channel, CF_OUTBOUND)) {
|
||||
switch_channel_set_state(session->channel, CS_TRANSMIT);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((caller_profile = switch_channel_get_caller_profile(session->channel)) == 0) {
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't get profile!\n");
|
||||
switch_channel_set_state(session->channel, CS_HANGUP);
|
||||
@ -1656,6 +1666,11 @@ SWITCH_DECLARE(void) switch_core_session_signal_state_change(switch_core_session
|
||||
switch_thread_cond_signal(session->cond);
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(unsigned int) switch_core_session_runing(switch_core_session *session)
|
||||
{
|
||||
return session->thread_running;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(void) switch_core_session_run(switch_core_session *session)
|
||||
{
|
||||
switch_channel_state state = CS_NEW, laststate = CS_HANGUP, midstate = CS_DONE;
|
||||
@ -1679,8 +1694,8 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session *session)
|
||||
|
||||
*/
|
||||
assert(session != NULL);
|
||||
|
||||
|
||||
|
||||
session->thread_running = 1;
|
||||
endpoint_interface = session->endpoint_interface;
|
||||
assert(endpoint_interface != NULL);
|
||||
|
||||
@ -1943,7 +1958,7 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session *session)
|
||||
switch_thread_cond_wait(session->cond, session->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
session->thread_running = 0;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(void) switch_core_session_destroy(switch_core_session **session)
|
||||
@ -2065,10 +2080,11 @@ SWITCH_DECLARE(void) switch_core_session_thread_launch(switch_core_session *sess
|
||||
switch_threadattr_create(&thd_attr, session->pool);
|
||||
switch_threadattr_detach_set(thd_attr, 1);
|
||||
|
||||
if (switch_thread_create(&thread, thd_attr, switch_core_session_thread, session, session->pool) != APR_SUCCESS) {
|
||||
switch_core_session_destroy(&session);
|
||||
if (! session->thread_running) {
|
||||
if (switch_thread_create(&thread, thd_attr, switch_core_session_thread, session, session->pool) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_core_session_destroy(&session);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(void) switch_core_session_launch_thread(switch_core_session *session, switch_thread_start_t func,
|
||||
@ -2227,12 +2243,12 @@ SWITCH_DECLARE(switch_status) switch_core_init(char *console)
|
||||
}
|
||||
|
||||
/* INIT APR and Create the pool context */
|
||||
if (apr_initialize() != APR_SUCCESS) {
|
||||
if (apr_initialize() != SWITCH_STATUS_SUCCESS) {
|
||||
apr_terminate();
|
||||
return SWITCH_STATUS_MEMERR;
|
||||
}
|
||||
|
||||
if (apr_pool_create(&runtime.memory_pool, NULL) != APR_SUCCESS) {
|
||||
if (apr_pool_create(&runtime.memory_pool, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Could not allocate memory pool\n");
|
||||
switch_core_destroy();
|
||||
return SWITCH_STATUS_MEMERR;
|
||||
|
@ -50,7 +50,7 @@ SWITCH_DECLARE(switch_status) switch_ivr_collect_digits_callback(switch_core_ses
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
while (switch_channel_get_state(channel) == CS_EXECUTE) {
|
||||
while(switch_channel_ready(channel)) {
|
||||
switch_frame *read_frame;
|
||||
char dtmf[128];
|
||||
|
||||
@ -105,7 +105,8 @@ SWITCH_DECLARE(switch_status) switch_ivr_collect_digits_count(switch_core_sessio
|
||||
if (timeout) {
|
||||
started = switch_time_now();
|
||||
}
|
||||
while (switch_channel_get_state(channel) == CS_EXECUTE) {
|
||||
|
||||
while(switch_channel_ready(channel)) {
|
||||
switch_frame *read_frame;
|
||||
|
||||
if (timeout) {
|
||||
@ -161,7 +162,7 @@ SWITCH_DECLARE(switch_status) switch_ivr_record_file(switch_core_session *sessio
|
||||
switch_codec codec, *read_codec;
|
||||
char *codec_name;
|
||||
switch_status status = SWITCH_STATUS_SUCCESS;
|
||||
|
||||
|
||||
if (!fh) {
|
||||
fh = &lfh;
|
||||
}
|
||||
@ -206,7 +207,7 @@ SWITCH_DECLARE(switch_status) switch_ivr_record_file(switch_core_session *sessio
|
||||
}
|
||||
|
||||
|
||||
while (switch_channel_get_state(channel) == CS_EXECUTE) {
|
||||
while(switch_channel_ready(channel)) {
|
||||
size_t len;
|
||||
|
||||
if (dtmf_callback || buf) {
|
||||
@ -267,7 +268,7 @@ SWITCH_DECLARE(switch_status) switch_ivr_play_file(switch_core_session *session,
|
||||
int stream_id;
|
||||
switch_status status = SWITCH_STATUS_SUCCESS;
|
||||
switch_file_handle lfh;
|
||||
|
||||
|
||||
if (!fh) {
|
||||
fh = &lfh;
|
||||
memset(fh, 0, sizeof(lfh));
|
||||
@ -332,7 +333,7 @@ SWITCH_DECLARE(switch_status) switch_ivr_play_file(switch_core_session *session,
|
||||
}
|
||||
|
||||
ilen = samples;
|
||||
while (switch_channel_get_state(channel) == CS_EXECUTE) {
|
||||
while(switch_channel_ready(channel)) {
|
||||
int done = 0;
|
||||
int do_speed = 1;
|
||||
int last_speed = -1;
|
||||
@ -586,8 +587,7 @@ SWITCH_DECLARE(switch_status) switch_ivr_speak_text(switch_core_session *session
|
||||
}
|
||||
|
||||
ilen = len;
|
||||
while (switch_channel_get_state(channel) == CS_EXECUTE) {
|
||||
|
||||
while(switch_channel_ready(channel)) {
|
||||
if (dtmf_callback || buf) {
|
||||
|
||||
|
||||
@ -667,7 +667,6 @@ SWITCH_DECLARE(switch_status) switch_ivr_speak_text(switch_core_session *session
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "done speaking text\n");
|
||||
switch_core_codec_destroy(&codec);
|
||||
flags = 0;
|
||||
switch_core_codec_destroy(&codec);
|
||||
|
||||
if (timer_name) {
|
||||
/* End the audio absorbing thread */
|
||||
@ -798,9 +797,11 @@ static switch_status audio_bridge_on_hangup(switch_core_session *session)
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "CUSTOM HANGUP %s kill %s\n", switch_channel_get_name(channel),
|
||||
switch_channel_get_name(other_channel));
|
||||
|
||||
switch_core_session_kill_channel(other_session, SWITCH_SIG_KILL);
|
||||
switch_core_session_kill_channel(session, SWITCH_SIG_KILL);
|
||||
|
||||
//switch_core_session_kill_channel(other_session, SWITCH_SIG_KILL);
|
||||
//switch_core_session_kill_channel(session, SWITCH_SIG_KILL);
|
||||
if (switch_channel_test_flag(channel, CF_ORIGINATOR) && !switch_channel_test_flag(other_channel, CF_TRANSFER)) {
|
||||
switch_core_session_kill_channel(other_session, SWITCH_SIG_KILL);
|
||||
}
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -855,6 +856,7 @@ SWITCH_DECLARE(switch_status) switch_ivr_multi_threaded_bridge(switch_core_sessi
|
||||
switch_channel *caller_channel, *peer_channel;
|
||||
time_t start;
|
||||
int stream_id = 0;
|
||||
switch_frame *read_frame;
|
||||
|
||||
caller_channel = switch_core_session_get_channel(session);
|
||||
assert(caller_channel != NULL);
|
||||
@ -895,12 +897,15 @@ SWITCH_DECLARE(switch_status) switch_ivr_multi_threaded_bridge(switch_core_sessi
|
||||
}
|
||||
|
||||
time(&start);
|
||||
while (switch_channel_get_state(caller_channel) == CS_EXECUTE &&
|
||||
switch_channel_get_state(peer_channel) == CS_TRANSMIT &&
|
||||
while (switch_channel_ready(caller_channel) &&
|
||||
switch_channel_ready(peer_channel) &&
|
||||
!switch_channel_test_flag(peer_channel, CF_ANSWERED) &&
|
||||
!switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA) &&
|
||||
((time(NULL) - start) < timelimit)) {
|
||||
switch_yield(20000);
|
||||
if (switch_core_session_read_frame(session, &read_frame, 1000, 0) != SWITCH_STATUS_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
switch_yield(1000);
|
||||
}
|
||||
|
||||
if (switch_channel_test_flag(peer_channel, CF_ANSWERED)) {
|
||||
@ -913,7 +918,7 @@ SWITCH_DECLARE(switch_status) switch_ivr_multi_threaded_bridge(switch_core_sessi
|
||||
switch_core_session_launch_thread(session, audio_bridge_thread, (void *) &other_audio_thread);
|
||||
audio_bridge_thread(NULL, (void *) &this_audio_thread);
|
||||
|
||||
switch_channel_hangup(peer_channel);
|
||||
//switch_channel_hangup(peer_channel);
|
||||
if (other_audio_thread.running > 0) {
|
||||
other_audio_thread.running = -1;
|
||||
/* wait for the other audio thread */
|
||||
|
Loading…
x
Reference in New Issue
Block a user