break everything

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@720 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2006-03-01 22:55:28 +00:00
parent b77747e0d1
commit 4799ec8b8a
16 changed files with 490 additions and 79 deletions

View File

@ -8,8 +8,10 @@ $ip and $port or die "Usage $0: <ip> <port>\n";
$socket = new IO::Socket::INET->new( PeerPort => $port, $socket = new IO::Socket::INET->new( PeerPort => $port,
Proto => 'udp', Proto => 'udp',
PeerAddr => $ip); PeerAddr => $ip);
open(I, $file);
my $buf = `cat $file`; $/ = undef;
my $buf = <I>;
close(I);
$socket->send("$buf\n"); $socket->send("$buf\n");

View File

@ -134,7 +134,7 @@ extern "C" {
/*! /*!
\brief Create a new caller profile object \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 dialplan name of the dialplan module in use
\param caller_id_name caller ID name \param caller_id_name caller ID name
\param caller_id_number caller ID number \param caller_id_number caller ID number
@ -144,7 +144,7 @@ extern "C" {
\param destination_number destination number \param destination_number destination number
\return a new profile object allocated from the session's memory pool \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 *dialplan,
char *caller_id_name, char *caller_id_name,
char *caller_id_number, char *caller_id_number,

View File

@ -65,6 +65,13 @@ typedef struct {
*/ */
SWITCH_DECLARE(switch_channel_state) switch_channel_get_state(switch_channel *channel); 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 \brief Set the current state of a channel
\param channel channel to set state of \param channel channel to set state of

View File

@ -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); 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 \brief Allocate memory from the main pool with no intention of returning it
\param memory the number of bytes to allocate \param memory the number of bytes to allocate

View File

@ -239,6 +239,8 @@ CF_RECV_AUDIO = (1 << 1) - Channel will receive audio
CF_ANSWERED = (1 << 2) - Channel is answered CF_ANSWERED = (1 << 2) - Channel is answered
CF_OUTBOUND = (1 << 3) - Channel is an outbound channel CF_OUTBOUND = (1 << 3) - Channel is an outbound channel
CF_EARLY_MEDIA = (1 << 4) - Channel is ready for audio before answer 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> </pre>
*/ */
@ -247,7 +249,9 @@ typedef enum {
CF_RECV_AUDIO = (1 << 1), CF_RECV_AUDIO = (1 << 1),
CF_ANSWERED = (1 << 2), CF_ANSWERED = (1 << 2),
CF_OUTBOUND = (1 << 3), 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; } switch_channel_flag;

View File

@ -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_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->dialplan,
caller_caller_profile->caller_id_name, caller_caller_profile->caller_id_name,
caller_caller_profile->caller_id_number, caller_caller_profile->caller_id_number,

View File

@ -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 == 0) {
tech_pvt->read_frame.datalen = tech_pvt->read_frame.datalen =
jrtp4c_read(tech_pvt->rtp_session, tech_pvt->read_frame.data, sizeof(tech_pvt->read_buf), &payload); 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.*/ /* RFC2833 ... TBD try harder to honor the duration etc.*/
if (payload == 101) { if (payload == 101) {
unsigned char *packet = tech_pvt->read_frame.data; 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); tech_pvt = switch_core_session_get_private(session);
assert(tech_pvt != NULL); assert(tech_pvt != NULL);
switch_clear_flag(tech_pvt, TFLAG_IO); switch_clear_flag(tech_pvt, TFLAG_IO);
switch_set_flag(tech_pvt, TFLAG_BYE); 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); snprintf(name, sizeof(name), "Exosip/%s-%04x", event->request->from->url->username, rand() & 0xffff);
switch_channel_set_name(channel, name); 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, globals.dialplan,
event->request->from->displayname, event->request->from->displayname,
event->request->from->url->username, event->request->from->url->username,

View File

@ -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, globals.dialplan,
iaxevent->ies.calling_name, iaxevent->ies.calling_name,
iaxevent->ies.calling_number, iaxevent->ies.calling_number,

View File

@ -808,7 +808,7 @@ static switch_status place_call(char *dest, char *out, size_t outlen)
return SWITCH_STATUS_FALSE; 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.dialplan,
globals.cid_name, globals.cid_name,
globals.cid_num, NULL, NULL, NULL, dest)) != 0) { globals.cid_num, NULL, NULL, NULL, dest)) != 0) {

View File

@ -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); 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, globals.dialplan,
"wanpipe fixme", "wanpipe fixme",
event->ring.callingnum, event->ring.callingnum,

View File

@ -1064,7 +1064,7 @@ static void *woomera_channel_thread_run(switch_thread *thread, void *obj)
} }
ip = woomera_message_header(&wmsg, "Remote-Address"); 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, tech_pvt->profile->dialplan,
cid_name, cid_num, ip, NULL, NULL, exten)) != 0) { cid_name, cid_num, ip, NULL, NULL, exten)) != 0) {
char name[128]; char name[128];

View File

@ -63,6 +63,8 @@
static const char modname[] = "mod_spidermonkey"; static const char modname[] = "mod_spidermonkey";
static int eval_some_js(char *code, JSContext *cx, JSObject *obj, jsval *rval); 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 { static struct {
size_t gStackChunkSize; size_t gStackChunkSize;
@ -86,6 +88,10 @@ typedef enum {
TTF_DTMF = (1 << 0) TTF_DTMF = (1 << 0)
} teletone_flag_t; } teletone_flag_t;
typedef enum {
S_HUP = (1 << 0)
} session_flag_t;
struct dtmf_callback_state { struct dtmf_callback_state {
struct js_session *session_state; struct js_session *session_state;
char code_buffer[1024]; char code_buffer[1024];
@ -100,6 +106,7 @@ struct js_session {
switch_core_session *session; switch_core_session *session;
JSContext *cx; JSContext *cx;
JSObject *obj; JSObject *obj;
switch_memory_pool *pool;
unsigned int flags; 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); switch_ivr_record_file(jss->session, &fh, file_name, dtmf_func, bp, len);
*rval = STRING_TO_JSVAL (JS_NewStringCopyZ(cx, cb_state.ret_buffer)); *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) 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); 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)); *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) 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)); *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) 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; 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 #ifdef HAVE_CURL
struct config_data { struct config_data {
@ -658,7 +718,8 @@ static JSBool js_fetchurl(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
/* Session Object */ /* Session Object */
/*********************************************************************************/ /*********************************************************************************/
enum session_tinyid { 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[] = { static JSFunctionSpec session_methods[] = {
@ -667,6 +728,9 @@ static JSFunctionSpec session_methods[] = {
{"speak", session_speak, 1}, {"speak", session_speak, 1},
{"getDigits", session_get_digits, 1}, {"getDigits", session_get_digits, 1},
{"answer", session_answer, 0}, {"answer", session_answer, 0},
{"ready", session_ready, 0},
{"waitForAnswer", session_wait_for_answer, 0},
{"hangup", session_hangup, 0},
{0} {0}
}; };
@ -674,6 +738,13 @@ static JSFunctionSpec session_methods[] = {
static JSPropertySpec session_props[] = { static JSPropertySpec session_props[] = {
{"name", SESSION_NAME, JSPROP_READONLY|JSPROP_PERMANENT}, {"name", SESSION_NAME, JSPROP_READONLY|JSPROP_PERMANENT},
{"state", SESSION_STATE, 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} {0}
}; };
@ -683,11 +754,14 @@ static JSBool session_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval
int param = 0; int param = 0;
JSBool res = JS_TRUE; JSBool res = JS_TRUE;
switch_channel *channel; switch_channel *channel;
switch_caller_profile *caller_profile;
char *name; char *name;
channel = switch_core_session_get_channel(jss->session); channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL); assert(channel != NULL);
caller_profile = switch_channel_get_caller_profile(channel);
name = JS_GetStringBytes(JS_ValueToString(cx, id)); name = JS_GetStringBytes(JS_ValueToString(cx, id));
/* numbers are our props anything else is a method */ /* numbers are our props anything else is a method */
if (name[0] >= 48 && name[0] <= 57) { 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))); *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, switch_channel_get_name(channel)));
break; break;
case SESSION_STATE: 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; break;
default: default:
res = JS_FALSE; res = JS_FALSE;
@ -715,7 +824,8 @@ static JSBool session_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval
JSClass session_class = { JSClass session_class = {
"Session", JSCLASS_HAS_PRIVATE, "Session", JSCLASS_HAS_PRIVATE,
JS_PropertyStub, JS_PropertyStub, session_getProperty, JS_PropertyStub, 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; 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 */ /* TeleTone Object */
/*********************************************************************************/ /*********************************************************************************/
static JSBool teletone_construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) 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; 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) static JSBool js_email(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{ {
char *to = NULL, *from = NULL, *headers, *body = NULL, *file = NULL; char *to = NULL, *from = NULL, *headers, *body = NULL, *file = NULL;
@ -1195,6 +1452,7 @@ static JSFunctionSpec fs_functions[] = {
{"console_log", js_log, 2}, {"console_log", js_log, 2},
{"include", js_include, 1}, {"include", js_include, 1},
{"email", js_email, 2}, {"email", js_email, 2},
{"bridge", js_bridge, 2},
#ifdef HAVE_CURL #ifdef HAVE_CURL
{"fetchURL", js_fetchurl, 1}, {"fetchURL", js_fetchurl, 1},
#endif #endif
@ -1231,6 +1489,40 @@ static int eval_some_js(char *code, JSContext *cx, JSObject *obj, jsval *rval)
return res; 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) static void js_exec(switch_core_session *session, char *data)
{ {
char *code, *next, *arg, *nextarg; 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))) { if ((cx = JS_NewContext(globals.rt, globals.gStackChunkSize))) {
JS_SetErrorReporter(cx, js_error); JS_SetErrorReporter(cx, js_error);
if ((javascript_global_object = JS_NewObject(cx, &global_class, NULL, NULL)) && if ((javascript_global_object = JS_NewObject(cx, &global_class, NULL, NULL)) &&
JS_DefineFunctions(cx, javascript_global_object, fs_functions) && env_init(cx, javascript_global_object) &&
JS_InitStandardClasses(cx, javascript_global_object) &&
(session_obj = new_js_session(cx, javascript_global_object, session, &jss, "session", flags))) { (session_obj = new_js_session(cx, javascript_global_object, session, &jss, "session", flags))) {
JS_SetGlobalObject(cx, javascript_global_object); JS_SetGlobalObject(cx, javascript_global_object);
JS_SetPrivate(cx, javascript_global_object, session); JS_SetPrivate(cx, javascript_global_object, session);
res = 0; res = 0;
JS_InitClass(cx,
javascript_global_object,
NULL,
&teletone_class,
teletone_construct,
3,
teletone_props,
teletone_methods,
teletone_props,
teletone_methods
);
do { do {
if ((next = strchr(code, '|'))) { if ((next = strchr(code, '|'))) {
*next = '\0'; *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 = { static const switch_application_interface ivrtest_application_interface = {
/*.interface_name */ "javascript", /*.interface_name */ "javascript",
/*.application_function */ js_exec, /*.application_function */ js_exec,
@ -1337,6 +1698,12 @@ static const switch_application_interface ivrtest_application_interface = {
/*.next*/ NULL /*.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 = { static switch_loadable_module_interface spidermonkey_module_interface = {
/*.module_name */ modname, /*.module_name */ modname,
@ -1345,7 +1712,7 @@ static switch_loadable_module_interface spidermonkey_module_interface = {
/*.dialplan_interface */ NULL, /*.dialplan_interface */ NULL,
/*.codec_interface */ NULL, /*.codec_interface */ NULL,
/*.application_interface */ &ivrtest_application_interface, /*.application_interface */ &ivrtest_application_interface,
/*.api_interface */ NULL, /*.api_interface */ &js_run_interface,
/*.file_interface */ NULL, /*.file_interface */ NULL,
/*.speech_interface */ NULL, /*.speech_interface */ NULL,
/*.directory_interface */ NULL /*.directory_interface */ NULL

View File

@ -31,7 +31,7 @@
*/ */
#include <switch_caller.h> #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 *dialplan,
char *caller_id_name, char *caller_id_name,
char *caller_id_number, 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; switch_caller_profile *profile = NULL;
if ((profile = switch_core_session_alloc(session, sizeof(switch_caller_profile))) != 0) { if ((profile = switch_core_alloc(pool, sizeof(switch_caller_profile))) != 0) {
profile->dialplan = switch_core_session_strdup(session, dialplan); profile->dialplan = switch_core_strdup(pool, dialplan);
profile->caller_id_name = switch_core_session_strdup(session, caller_id_name); profile->caller_id_name = switch_core_strdup(pool, caller_id_name);
profile->caller_id_number = switch_core_session_strdup(session, caller_id_number); profile->caller_id_number = switch_core_strdup(pool, caller_id_number);
profile->network_addr = switch_core_session_strdup(session, network_addr); profile->network_addr = switch_core_strdup(pool, network_addr);
profile->ani = switch_core_session_strdup(session, ani); profile->ani = switch_core_strdup(pool, ani);
profile->ani2 = switch_core_session_strdup(session, ani2); profile->ani2 = switch_core_strdup(pool, ani2);
profile->destination_number = switch_core_session_strdup(session, destination_number); profile->destination_number = switch_core_strdup(pool, destination_number);
} }
return profile; return profile;

View File

@ -248,6 +248,12 @@ SWITCH_DECLARE(switch_channel_state) switch_channel_get_state(switch_channel *ch
return channel->state; 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[] = { static const char *state_names[] = {
"CS_NEW", "CS_NEW",
"CS_INIT", "CS_INIT",

View File

@ -42,6 +42,7 @@ EXTERN_C void xs_init(pTHX);
struct switch_core_session { struct switch_core_session {
unsigned long id; unsigned long id;
char name[80]; char name[80];
int thread_running;
switch_memory_pool *pool; switch_memory_pool *pool;
switch_channel *channel; switch_channel *channel;
switch_thread *thread; switch_thread *thread;
@ -714,9 +715,9 @@ SWITCH_DECLARE(char *) switch_core_session_strdup(switch_core_session *session,
assert(session != NULL); assert(session != NULL);
assert(session->pool != NULL); assert(session->pool != NULL);
if (!todup) if (!todup) {
return NULL; return NULL;
}
len = strlen(todup) + 1; len = strlen(todup) + 1;
if (todup && (duped = apr_palloc(session->pool, len)) != 0) { 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; char *duped = NULL;
size_t len; size_t len;
assert(pool != NULL); assert(pool != NULL);
assert(todup != NULL);
if (!todup) if (!todup) {
return NULL; return NULL;
}
len = strlen(todup) + 1; len = strlen(todup) + 1;
if (todup && (duped = apr_palloc(pool, len)) != 0) { 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 = if ((status =
endpoint_interface->io_routines->outgoing_channel(session, caller_profile, endpoint_interface->io_routines->outgoing_channel(session, caller_profile,
new_session)) == SWITCH_STATUS_SUCCESS) { new_session)) == SWITCH_STATUS_SUCCESS) {
for (ptr = session->event_hooks.outgoing_channel; ptr; ptr = ptr->next) { if (session) {
if ((status = ptr->outgoing_channel(session, caller_profile, *new_session)) != SWITCH_STATUS_SUCCESS) { for (ptr = session->event_hooks.outgoing_channel; ptr; ptr = ptr->next) {
break; if ((status = ptr->outgoing_channel(session, caller_profile, *new_session)) != SWITCH_STATUS_SUCCESS) {
break;
}
} }
} }
} else { } 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_caller_profile *profile = NULL, *peer_profile = NULL, *cloned_profile = NULL;
switch_channel *channel = NULL, *peer_channel = 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); profile = switch_channel_get_caller_profile(channel);
} }
if ((peer_channel = switch_core_session_get_channel(*new_session)) != 0) { 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 (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); 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; 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; *pool = NULL;
return SWITCH_STATUS_MEMERR; 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)); 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) { if ((caller_profile = switch_channel_get_caller_profile(session->channel)) == 0) {
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't get profile!\n"); switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't get profile!\n");
switch_channel_set_state(session->channel, CS_HANGUP); 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_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_DECLARE(void) switch_core_session_run(switch_core_session *session)
{ {
switch_channel_state state = CS_NEW, laststate = CS_HANGUP, midstate = CS_DONE; 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); assert(session != NULL);
session->thread_running = 1;
endpoint_interface = session->endpoint_interface; endpoint_interface = session->endpoint_interface;
assert(endpoint_interface != NULL); 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); switch_thread_cond_wait(session->cond, session->mutex);
} }
} }
session->thread_running = 0;
} }
SWITCH_DECLARE(void) switch_core_session_destroy(switch_core_session **session) 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_create(&thd_attr, session->pool);
switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_detach_set(thd_attr, 1);
if (switch_thread_create(&thread, thd_attr, switch_core_session_thread, session, session->pool) != APR_SUCCESS) { if (! session->thread_running) {
switch_core_session_destroy(&session); 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, 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 */ /* INIT APR and Create the pool context */
if (apr_initialize() != APR_SUCCESS) { if (apr_initialize() != SWITCH_STATUS_SUCCESS) {
apr_terminate(); apr_terminate();
return SWITCH_STATUS_MEMERR; 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_console_printf(SWITCH_CHANNEL_CONSOLE, "Could not allocate memory pool\n");
switch_core_destroy(); switch_core_destroy();
return SWITCH_STATUS_MEMERR; return SWITCH_STATUS_MEMERR;

View File

@ -50,7 +50,7 @@ SWITCH_DECLARE(switch_status) switch_ivr_collect_digits_callback(switch_core_ses
return SWITCH_STATUS_GENERR; return SWITCH_STATUS_GENERR;
} }
while (switch_channel_get_state(channel) == CS_EXECUTE) { while(switch_channel_ready(channel)) {
switch_frame *read_frame; switch_frame *read_frame;
char dtmf[128]; char dtmf[128];
@ -105,7 +105,8 @@ SWITCH_DECLARE(switch_status) switch_ivr_collect_digits_count(switch_core_sessio
if (timeout) { if (timeout) {
started = switch_time_now(); started = switch_time_now();
} }
while (switch_channel_get_state(channel) == CS_EXECUTE) {
while(switch_channel_ready(channel)) {
switch_frame *read_frame; switch_frame *read_frame;
if (timeout) { if (timeout) {
@ -161,7 +162,7 @@ SWITCH_DECLARE(switch_status) switch_ivr_record_file(switch_core_session *sessio
switch_codec codec, *read_codec; switch_codec codec, *read_codec;
char *codec_name; char *codec_name;
switch_status status = SWITCH_STATUS_SUCCESS; switch_status status = SWITCH_STATUS_SUCCESS;
if (!fh) { if (!fh) {
fh = &lfh; 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; size_t len;
if (dtmf_callback || buf) { if (dtmf_callback || buf) {
@ -267,7 +268,7 @@ SWITCH_DECLARE(switch_status) switch_ivr_play_file(switch_core_session *session,
int stream_id; int stream_id;
switch_status status = SWITCH_STATUS_SUCCESS; switch_status status = SWITCH_STATUS_SUCCESS;
switch_file_handle lfh; switch_file_handle lfh;
if (!fh) { if (!fh) {
fh = &lfh; fh = &lfh;
memset(fh, 0, sizeof(lfh)); memset(fh, 0, sizeof(lfh));
@ -332,7 +333,7 @@ SWITCH_DECLARE(switch_status) switch_ivr_play_file(switch_core_session *session,
} }
ilen = samples; ilen = samples;
while (switch_channel_get_state(channel) == CS_EXECUTE) { while(switch_channel_ready(channel)) {
int done = 0; int done = 0;
int do_speed = 1; int do_speed = 1;
int last_speed = -1; int last_speed = -1;
@ -586,8 +587,7 @@ SWITCH_DECLARE(switch_status) switch_ivr_speak_text(switch_core_session *session
} }
ilen = len; ilen = len;
while (switch_channel_get_state(channel) == CS_EXECUTE) { while(switch_channel_ready(channel)) {
if (dtmf_callback || buf) { 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_console_printf(SWITCH_CHANNEL_CONSOLE, "done speaking text\n");
switch_core_codec_destroy(&codec); switch_core_codec_destroy(&codec);
flags = 0; flags = 0;
switch_core_codec_destroy(&codec);
if (timer_name) { if (timer_name) {
/* End the audio absorbing thread */ /* 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_console_printf(SWITCH_CHANNEL_CONSOLE, "CUSTOM HANGUP %s kill %s\n", switch_channel_get_name(channel),
switch_channel_get_name(other_channel)); switch_channel_get_name(other_channel));
switch_core_session_kill_channel(other_session, SWITCH_SIG_KILL); //switch_core_session_kill_channel(other_session, SWITCH_SIG_KILL);
switch_core_session_kill_channel(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; 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; switch_channel *caller_channel, *peer_channel;
time_t start; time_t start;
int stream_id = 0; int stream_id = 0;
switch_frame *read_frame;
caller_channel = switch_core_session_get_channel(session); caller_channel = switch_core_session_get_channel(session);
assert(caller_channel != NULL); assert(caller_channel != NULL);
@ -895,12 +897,15 @@ SWITCH_DECLARE(switch_status) switch_ivr_multi_threaded_bridge(switch_core_sessi
} }
time(&start); time(&start);
while (switch_channel_get_state(caller_channel) == CS_EXECUTE && while (switch_channel_ready(caller_channel) &&
switch_channel_get_state(peer_channel) == CS_TRANSMIT && switch_channel_ready(peer_channel) &&
!switch_channel_test_flag(peer_channel, CF_ANSWERED) && !switch_channel_test_flag(peer_channel, CF_ANSWERED) &&
!switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA) && !switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA) &&
((time(NULL) - start) < timelimit)) { ((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)) { 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); switch_core_session_launch_thread(session, audio_bridge_thread, (void *) &other_audio_thread);
audio_bridge_thread(NULL, (void *) &this_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) { if (other_audio_thread.running > 0) {
other_audio_thread.running = -1; other_audio_thread.running = -1;
/* wait for the other audio thread */ /* wait for the other audio thread */