2006-02-26 23:10:22 +00:00
/*
* FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
* Copyright ( C ) 2005 / 2006 , Anthony Minessale II < anthmct @ yahoo . com >
*
* Version : MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 ( the " License " ) ; you may not use this file except in compliance with
* the License . You may obtain a copy of the License at
* http : //www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an " AS IS " basis ,
* WITHOUT WARRANTY OF ANY KIND , either express or implied . See the License
* for the specific language governing rights and limitations under the
* License .
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
*
* The Initial Developer of the Original Code is
* Anthony Minessale II < anthmct @ yahoo . com >
* Portions created by the Initial Developer are Copyright ( C )
* the Initial Developer . All Rights Reserved .
*
* Contributor ( s ) :
*
* Anthony Minessale II < anthmct @ yahoo . com >
*
*
* mod_spidermonkey . c - - Javascript Module
*
*/
2006-03-01 06:25:56 +00:00
# ifndef HAVE_CURL
2006-03-01 00:58:32 +00:00
# define HAVE_CURL
2006-03-01 06:25:56 +00:00
# endif
2006-11-10 21:49:57 +00:00
# include "mod_spidermonkey.h"
2006-03-01 00:58:32 +00:00
# ifdef HAVE_CURL
# include <curl/curl.h>
# endif
2006-02-26 23:10:22 +00:00
static const char modname [ ] = " mod_spidermonkey " ;
2006-11-10 21:49:57 +00:00
2007-03-29 22:31:56 +00:00
static void session_destroy ( JSContext * cx , JSObject * obj ) ;
static JSBool session_construct ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval ) ;
static JSBool session_originate ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval ) ;
2006-10-08 07:11:42 +00:00
static switch_api_interface_t js_run_interface ;
2007-05-14 03:17:38 +00:00
static switch_api_interface_t jsapi_interface ;
2006-02-26 23:10:22 +00:00
static struct {
size_t gStackChunkSize ;
jsuword gStackBase ;
int gExitCode ;
JSBool gQuitting ;
FILE * gErrFile ;
FILE * gOutFile ;
int stackDummy ;
JSRuntime * rt ;
} globals ;
static JSClass global_class = {
2007-03-29 22:31:56 +00:00
" Global " , JSCLASS_HAS_PRIVATE ,
JS_PropertyStub , JS_PropertyStub , JS_PropertyStub , JS_PropertyStub ,
JS_EnumerateStub , JS_ResolveStub , JS_ConvertStub , JS_FinalizeStub
2006-02-26 23:10:22 +00:00
} ;
2006-11-10 21:49:57 +00:00
static struct {
switch_hash_t * mod_hash ;
switch_hash_t * load_hash ;
2007-03-29 22:31:56 +00:00
switch_memory_pool_t * pool ;
2006-11-10 21:49:57 +00:00
} module_manager ;
struct sm_loadable_module {
char * filename ;
void * lib ;
const sm_module_interface_t * module_interface ;
spidermonkey_init_t spidermonkey_init ;
} ;
typedef struct sm_loadable_module sm_loadable_module_t ;
2006-02-26 23:10:22 +00:00
2006-03-01 22:55:28 +00:00
typedef enum {
2007-03-27 00:40:53 +00:00
S_HUP = ( 1 < < 0 ) ,
2007-04-13 22:15:58 +00:00
S_FREE = ( 1 < < 1 ) ,
S_RDLOCK = ( 1 < < 2 )
2006-03-01 22:55:28 +00:00
} session_flag_t ;
2006-11-09 05:39:04 +00:00
struct input_callback_state {
2006-02-28 02:08:42 +00:00
struct js_session * session_state ;
char code_buffer [ 1024 ] ;
2006-02-28 05:55:22 +00:00
size_t code_buffer_len ;
2006-02-28 02:08:42 +00:00
char ret_buffer [ 1024 ] ;
int ret_buffer_len ;
int digit_count ;
2006-11-09 05:39:04 +00:00
JSFunction * function ;
jsval arg ;
jsval ret ;
JSContext * cx ;
JSObject * obj ;
2007-03-29 22:31:56 +00:00
jsrefcount saveDepth ;
2006-02-28 02:08:42 +00:00
void * extra ;
} ;
2006-03-02 17:36:23 +00:00
struct fileio_obj {
char * path ;
unsigned int flags ;
switch_file_t * fd ;
2006-04-29 01:00:52 +00:00
switch_memory_pool_t * pool ;
2006-03-02 17:46:15 +00:00
char * buf ;
switch_size_t buflen ;
2006-03-02 17:36:23 +00:00
int32 bufsize ;
} ;
2007-05-14 03:17:38 +00:00
struct request_obj {
const char * cmd ;
switch_core_session_t * session ;
switch_stream_handle_t * stream ;
} ;
/* Request Object */
/*********************************************************************************/
static JSBool request_write ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
{
struct request_obj * ro = JS_GetPrivate ( cx , obj ) ;
if ( ! ro ) {
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
return JS_TRUE ;
}
if ( argc > 0 ) {
char * string = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 0 ] ) ) ;
ro - > stream - > write_function ( ro - > stream , " %s " , string ) ;
* rval = BOOLEAN_TO_JSVAL ( JS_TRUE ) ;
return JS_TRUE ;
}
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
return JS_TRUE ;
}
static JSBool request_add_header ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
{
struct request_obj * ro = JS_GetPrivate ( cx , obj ) ;
if ( ! ro ) {
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
return JS_TRUE ;
}
if ( argc > 1 ) {
char * hname = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 0 ] ) ) ;
char * hval = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 1 ] ) ) ;
switch_event_add_header ( ro - > stream - > event , SWITCH_STACK_BOTTOM , hname , " %s " , hval ) ;
* rval = BOOLEAN_TO_JSVAL ( JS_TRUE ) ;
return JS_TRUE ;
}
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
return JS_TRUE ;
}
static JSBool request_get_header ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
{
struct request_obj * ro = JS_GetPrivate ( cx , obj ) ;
if ( ! ro ) {
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
return JS_TRUE ;
}
if ( argc > 0 ) {
char * hname = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 0 ] ) ) ;
char * val = switch_event_get_header ( ro - > stream - > event , hname ) ;
* rval = STRING_TO_JSVAL ( JS_NewStringCopyZ ( cx , val ) ) ;
return JS_TRUE ;
}
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
return JS_TRUE ;
}
static JSBool request_dump_env ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
{
struct request_obj * ro = JS_GetPrivate ( cx , obj ) ;
char * how = " text " ;
if ( ! ro ) {
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
return JS_TRUE ;
}
if ( argc > 0 ) {
how = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 0 ] ) ) ;
}
if ( ! strcasecmp ( how , " xml " ) ) {
switch_xml_t xml ;
char * xmlstr ;
if ( ( xml = switch_event_xmlize ( ro - > stream - > event , NULL ) ) ) {
xmlstr = switch_xml_toxml ( xml ) ;
* rval = STRING_TO_JSVAL ( JS_NewStringCopyZ ( cx , xmlstr ) ) ;
return JS_TRUE ;
}
} else {
char * buf ;
switch_event_serialize ( ro - > stream - > event , & buf ) ;
if ( buf ) {
* rval = STRING_TO_JSVAL ( JS_NewStringCopyZ ( cx , buf ) ) ;
free ( buf ) ;
return JS_TRUE ;
}
}
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
return JS_FALSE ;
}
static void request_destroy ( JSContext * cx , JSObject * obj )
{
}
enum request_tinyid {
REQUEST_COMMAND
} ;
static JSFunctionSpec request_methods [ ] = {
{ " write " , request_write , 1 } ,
{ " getHeader " , request_get_header , 1 } ,
{ " addHeader " , request_add_header , 1 } ,
{ " dumpENV " , request_dump_env , 1 } ,
{ 0 }
} ;
static JSPropertySpec request_props [ ] = {
{ " command " , REQUEST_COMMAND , JSPROP_READONLY | JSPROP_PERMANENT } ,
{ 0 }
} ;
static JSBool request_getProperty ( JSContext * cx , JSObject * obj , jsval id , jsval * vp )
{
JSBool res = JS_TRUE ;
struct request_obj * ro = JS_GetPrivate ( cx , obj ) ;
char * name ;
int param = 0 ;
if ( ! ro ) {
* vp = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
return JS_TRUE ;
}
name = JS_GetStringBytes ( JS_ValueToString ( cx , id ) ) ;
/* numbers are our props anything else is a method */
if ( name [ 0 ] > = 48 & & name [ 0 ] < = 57 ) {
param = atoi ( name ) ;
} else {
return JS_TRUE ;
}
switch ( param ) {
case REQUEST_COMMAND :
* vp = STRING_TO_JSVAL ( JS_NewStringCopyZ ( cx , ro - > cmd ) ) ;
break ;
}
return res ;
}
JSClass request_class = {
" Request " , JSCLASS_HAS_PRIVATE ,
JS_PropertyStub , JS_PropertyStub , request_getProperty , JS_PropertyStub ,
JS_EnumerateStub , JS_ResolveStub , JS_ConvertStub , request_destroy , NULL , NULL , NULL , NULL
} ;
static JSObject * new_request ( JSContext * cx , JSObject * obj , struct request_obj * ro )
{
JSObject * Request ;
if ( ( Request = JS_DefineObject ( cx , obj , " request " , & request_class , NULL , 0 ) ) ) {
if ( ( JS_SetPrivate ( cx , Request , ro ) & &
JS_DefineProperties ( cx , Request , request_props ) & & JS_DefineFunctions ( cx , Request , request_methods ) ) ) {
return Request ;
}
}
return NULL ;
}
2006-11-09 05:39:04 +00:00
struct event_obj {
switch_event_t * event ;
int freed ;
} ;
2006-08-18 01:28:50 +00:00
/* Event Object */
/*********************************************************************************/
2007-03-29 22:31:56 +00:00
static JSBool event_construct ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-08-18 01:28:50 +00:00
{
if ( argc > 0 ) {
switch_event_t * event ;
2006-11-09 05:39:04 +00:00
struct event_obj * eo ;
2006-08-18 01:28:50 +00:00
switch_event_types_t etype ;
char * ename = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 0 ] ) ) ;
2006-11-09 05:39:04 +00:00
if ( ( eo = malloc ( sizeof ( * eo ) ) ) ) {
2006-08-18 01:28:50 +00:00
2006-11-09 05:39:04 +00:00
if ( switch_name_event ( ename , & etype ) ! = SWITCH_STATUS_SUCCESS ) {
2007-04-02 20:20:46 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Unknown event %s \n " , ename ) ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-08-18 01:28:50 +00:00
return JS_TRUE ;
}
2006-11-09 05:39:04 +00:00
if ( etype = = SWITCH_EVENT_CUSTOM ) {
char * subclass_name ;
if ( argc < 1 ) {
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-11-09 05:39:04 +00:00
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
2006-11-09 05:39:04 +00:00
subclass_name = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 1 ] ) ) ;
if ( switch_event_create_subclass ( & event , etype , subclass_name ) ! = SWITCH_STATUS_SUCCESS ) {
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-11-09 05:39:04 +00:00
return JS_TRUE ;
}
} else {
2007-04-02 20:20:46 +00:00
if ( switch_event_create ( & event , etype ) ! = SWITCH_STATUS_SUCCESS ) {
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-11-09 05:39:04 +00:00
return JS_TRUE ;
}
2006-08-18 01:28:50 +00:00
}
2006-11-09 05:39:04 +00:00
eo - > event = event ;
eo - > freed = 0 ;
JS_SetPrivate ( cx , obj , eo ) ;
return JS_TRUE ;
}
2006-08-18 01:28:50 +00:00
}
return JS_FALSE ;
}
2007-03-29 22:31:56 +00:00
static void event_destroy ( JSContext * cx , JSObject * obj )
2006-08-18 01:28:50 +00:00
{
2006-11-09 05:39:04 +00:00
struct event_obj * eo = JS_GetPrivate ( cx , obj ) ;
2006-08-18 01:28:50 +00:00
2006-11-09 05:39:04 +00:00
if ( eo ) {
if ( ! eo - > freed & & eo - > event ) {
switch_event_destroy ( & eo - > event ) ;
}
switch_safe_free ( eo ) ;
2006-08-18 01:28:50 +00:00
}
}
2007-03-29 22:31:56 +00:00
static JSBool event_add_header ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-08-18 01:28:50 +00:00
{
2006-11-09 05:39:04 +00:00
struct event_obj * eo = JS_GetPrivate ( cx , obj ) ;
2006-08-18 01:28:50 +00:00
2006-11-09 05:39:04 +00:00
if ( ! eo | | eo - > freed ) {
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-08-18 01:28:50 +00:00
return JS_TRUE ;
}
if ( argc > 1 ) {
char * hname = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 0 ] ) ) ;
char * hval = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 1 ] ) ) ;
2007-02-13 04:43:49 +00:00
switch_event_add_header ( eo - > event , SWITCH_STACK_BOTTOM , hname , " %s " , hval ) ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_TRUE ) ;
2006-08-18 01:28:50 +00:00
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-08-18 01:28:50 +00:00
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
static JSBool event_get_header ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-08-18 01:28:50 +00:00
{
2006-11-09 05:39:04 +00:00
struct event_obj * eo = JS_GetPrivate ( cx , obj ) ;
2006-08-18 01:28:50 +00:00
2006-11-09 05:39:04 +00:00
if ( ! eo ) {
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-08-18 01:28:50 +00:00
return JS_TRUE ;
}
if ( argc > 0 ) {
char * hname = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 0 ] ) ) ;
2006-11-09 05:39:04 +00:00
char * val = switch_event_get_header ( eo - > event , hname ) ;
2007-03-29 22:31:56 +00:00
* rval = STRING_TO_JSVAL ( JS_NewStringCopyZ ( cx , val ) ) ;
2006-08-18 01:28:50 +00:00
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-08-18 01:28:50 +00:00
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
static JSBool event_add_body ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-08-18 01:28:50 +00:00
{
2006-11-09 05:39:04 +00:00
struct event_obj * eo = JS_GetPrivate ( cx , obj ) ;
2006-08-18 01:28:50 +00:00
2006-11-09 05:39:04 +00:00
if ( ! eo | | eo - > freed ) {
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-08-18 01:28:50 +00:00
return JS_TRUE ;
}
if ( argc > 0 ) {
char * body = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 0 ] ) ) ;
2007-02-14 03:32:13 +00:00
switch_event_add_body ( eo - > event , " %s " , body ) ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_TRUE ) ;
2006-08-18 01:28:50 +00:00
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-08-18 01:28:50 +00:00
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
static JSBool event_get_body ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-08-18 01:28:50 +00:00
{
2006-11-09 05:39:04 +00:00
struct event_obj * eo = JS_GetPrivate ( cx , obj ) ;
2006-08-18 01:28:50 +00:00
2006-11-09 05:39:04 +00:00
if ( ! eo ) {
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-08-18 01:28:50 +00:00
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
* rval = STRING_TO_JSVAL ( JS_NewStringCopyZ ( cx , switch_event_get_body ( eo - > event ) ) ) ;
2006-11-09 05:39:04 +00:00
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
static JSBool event_get_type ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-11-09 05:39:04 +00:00
{
struct event_obj * eo = JS_GetPrivate ( cx , obj ) ;
if ( ! eo ) {
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-11-09 05:39:04 +00:00
return JS_TRUE ;
}
2006-08-18 01:28:50 +00:00
2007-03-29 22:31:56 +00:00
* rval = STRING_TO_JSVAL ( JS_NewStringCopyZ ( cx , switch_event_name ( eo - > event - > event_id ) ) ) ;
2006-08-18 01:28:50 +00:00
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
static JSBool event_serialize ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-08-18 01:28:50 +00:00
{
2006-11-09 05:39:04 +00:00
struct event_obj * eo = JS_GetPrivate ( cx , obj ) ;
2006-11-11 19:32:45 +00:00
char * buf ;
2006-08-18 01:28:50 +00:00
uint8_t isxml = 0 ;
2006-11-09 05:39:04 +00:00
if ( ! eo ) {
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-08-18 01:28:50 +00:00
return JS_TRUE ;
}
if ( argc > 0 ) {
char * arg = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 0 ] ) ) ;
if ( ! strcasecmp ( arg , " xml " ) ) {
isxml + + ;
}
}
if ( isxml ) {
switch_xml_t xml ;
char * xmlstr ;
2007-03-29 22:31:56 +00:00
if ( ( xml = switch_event_xmlize ( eo - > event , SWITCH_VA_NONE ) ) ) {
xmlstr = switch_xml_toxml ( xml ) ;
* rval = STRING_TO_JSVAL ( JS_NewStringCopyZ ( cx , xmlstr ) ) ;
2006-08-18 01:28:50 +00:00
switch_xml_free ( xml ) ;
2007-03-29 22:31:56 +00:00
free ( xmlstr ) ;
2006-08-18 01:28:50 +00:00
} else {
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-08-18 01:28:50 +00:00
}
} else {
2006-11-11 19:32:45 +00:00
if ( switch_event_serialize ( eo - > event , & buf ) = = SWITCH_STATUS_SUCCESS ) {
2007-03-29 22:31:56 +00:00
* rval = STRING_TO_JSVAL ( JS_NewStringCopyZ ( cx , buf ) ) ;
2006-11-11 19:32:45 +00:00
switch_safe_free ( buf ) ;
}
2006-08-18 01:28:50 +00:00
}
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
static JSBool event_fire ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-08-18 01:28:50 +00:00
{
2006-11-09 05:39:04 +00:00
struct event_obj * eo = JS_GetPrivate ( cx , obj ) ;
2006-08-18 01:28:50 +00:00
2006-11-09 05:39:04 +00:00
if ( eo ) {
switch_event_fire ( & eo - > event ) ;
2006-08-18 01:28:50 +00:00
JS_SetPrivate ( cx , obj , NULL ) ;
2006-11-09 05:39:04 +00:00
switch_safe_free ( eo ) ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_TRUE ) ;
2006-08-18 01:28:50 +00:00
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-08-18 01:28:50 +00:00
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
static JSBool event_destroy_ ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-08-18 01:28:50 +00:00
{
2006-11-09 05:39:04 +00:00
struct event_obj * eo = JS_GetPrivate ( cx , obj ) ;
2007-03-29 22:31:56 +00:00
2006-11-09 05:39:04 +00:00
if ( eo ) {
if ( ! eo - > freed ) {
switch_event_destroy ( & eo - > event ) ;
}
2006-08-18 01:28:50 +00:00
JS_SetPrivate ( cx , obj , NULL ) ;
2006-11-09 05:39:04 +00:00
switch_safe_free ( eo ) ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_TRUE ) ;
2006-08-18 01:28:50 +00:00
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-08-18 01:28:50 +00:00
return JS_TRUE ;
}
enum event_tinyid {
EVENT_READY
} ;
static JSFunctionSpec event_methods [ ] = {
{ " addHeader " , event_add_header , 1 } ,
{ " getHeader " , event_get_header , 1 } ,
{ " addBody " , event_add_body , 1 } ,
{ " getBody " , event_get_body , 1 } ,
2006-11-09 05:39:04 +00:00
{ " getType " , event_get_type , 1 } ,
2006-08-18 01:28:50 +00:00
{ " serialize " , event_serialize , 0 } ,
{ " fire " , event_fire , 0 } ,
{ " destroy " , event_destroy_ , 0 } ,
{ 0 }
} ;
static JSPropertySpec event_props [ ] = {
2007-03-29 22:31:56 +00:00
{ " ready " , EVENT_READY , JSPROP_READONLY | JSPROP_PERMANENT } ,
2006-08-18 01:28:50 +00:00
{ 0 }
} ;
2007-03-29 22:31:56 +00:00
static JSBool event_getProperty ( JSContext * cx , JSObject * obj , jsval id , jsval * vp )
2006-08-18 01:28:50 +00:00
{
JSBool res = JS_TRUE ;
switch_event_t * event = JS_GetPrivate ( cx , obj ) ;
char * name ;
int param = 0 ;
2007-03-29 22:31:56 +00:00
if ( ! event ) {
* vp = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-08-18 01:28:50 +00:00
return JS_TRUE ;
2007-03-29 22:31:56 +00:00
}
2006-08-18 01:28:50 +00:00
name = JS_GetStringBytes ( JS_ValueToString ( cx , id ) ) ;
2007-03-29 22:31:56 +00:00
/* numbers are our props anything else is a method */
if ( name [ 0 ] > = 48 & & name [ 0 ] < = 57 ) {
param = atoi ( name ) ;
} else {
return JS_TRUE ;
}
switch ( param ) {
2006-08-18 01:28:50 +00:00
case EVENT_READY :
2007-03-29 22:31:56 +00:00
* vp = BOOLEAN_TO_JSVAL ( JS_TRUE ) ;
2006-08-18 01:28:50 +00:00
break ;
}
return res ;
}
JSClass event_class = {
2007-03-29 22:31:56 +00:00
" Event " , JSCLASS_HAS_PRIVATE ,
JS_PropertyStub , JS_PropertyStub , event_getProperty , JS_PropertyStub ,
JS_EnumerateStub , JS_ResolveStub , JS_ConvertStub , event_destroy , NULL , NULL , NULL ,
2006-08-18 01:28:50 +00:00
event_construct
} ;
2007-03-29 22:31:56 +00:00
static void js_error ( JSContext * cx , const char * message , JSErrorReport * report )
2006-02-26 23:10:22 +00:00
{
2007-03-29 22:31:56 +00:00
const char * filename = __FILE__ ;
int line = __LINE__ ;
const char * text = " " ;
char * ex = " " ;
2007-01-19 21:56:31 +00:00
if ( message & & report ) {
2007-03-29 22:31:56 +00:00
if ( report - > filename ) {
filename = report - > filename ;
}
line = report - > lineno ;
if ( report - > linebuf ) {
text = report - > linebuf ;
ex = " near " ;
}
}
if ( ! message ) {
message = " (N/A) " ;
}
switch_log_printf ( SWITCH_CHANNEL_ID_LOG , filename , modname , line , SWITCH_LOG_ERROR , " %s %s%s \n " , ex , message , text ) ;
2007-01-19 21:56:31 +00:00
2006-02-26 23:10:22 +00:00
}
2006-11-10 21:49:57 +00:00
2006-11-28 20:52:04 +00:00
static switch_status_t sm_load_file ( char * filename )
2006-11-10 21:49:57 +00:00
{
sm_loadable_module_t * module = NULL ;
2007-03-09 20:44:13 +00:00
switch_dso_handle_t * dso = NULL ;
switch_status_t status = SWITCH_STATUS_SUCCESS ;
switch_dso_handle_sym_t function_handle = NULL ;
2006-11-12 00:42:51 +00:00
spidermonkey_init_t spidermonkey_init = NULL ;
2006-11-15 03:59:40 +00:00
const sm_module_interface_t * module_interface = NULL , * mp ;
2006-11-10 21:49:57 +00:00
int loading = 1 ;
const char * err = NULL ;
char derr [ 512 ] = " " ;
assert ( filename ! = NULL ) ;
2007-03-09 20:44:13 +00:00
status = switch_dso_load ( & dso , filename , module_manager . pool ) ;
2006-11-10 21:49:57 +00:00
while ( loading ) {
2007-03-09 20:44:13 +00:00
if ( status ! = SWITCH_STATUS_SUCCESS ) {
switch_dso_error ( dso , derr , sizeof ( derr ) ) ;
2006-11-10 21:49:57 +00:00
err = derr ;
break ;
}
2007-03-09 20:44:13 +00:00
status = switch_dso_sym ( & function_handle , dso , " spidermonkey_init " ) ;
2007-03-29 22:31:56 +00:00
spidermonkey_init = ( spidermonkey_init_t ) ( intptr_t ) function_handle ;
2006-11-10 21:49:57 +00:00
if ( spidermonkey_init = = NULL ) {
err = " Cannot Load " ;
break ;
}
2007-03-29 22:31:56 +00:00
2006-11-10 21:49:57 +00:00
if ( spidermonkey_init ( & module_interface ) ! = SWITCH_STATUS_SUCCESS ) {
err = " Module load routine returned an error " ;
break ;
}
2006-11-28 20:52:04 +00:00
if ( ! ( module = ( sm_loadable_module_t * ) switch_core_permanent_alloc ( sizeof ( * module ) ) ) ) {
2006-11-10 21:49:57 +00:00
err = " Could not allocate memory \n " ;
break ;
}
loading = 0 ;
}
if ( err ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CONSOLE , " Error Loading module %s \n **%s** \n " , filename , err ) ;
return SWITCH_STATUS_GENERR ;
}
module - > filename = switch_core_permanent_strdup ( filename ) ;
module - > spidermonkey_init = spidermonkey_init ;
module - > module_interface = module_interface ;
2007-03-29 22:31:56 +00:00
2006-11-10 21:49:57 +00:00
module - > lib = dso ;
switch_core_hash_insert ( module_manager . mod_hash , ( char * ) module - > filename , ( void * ) module ) ;
2007-03-29 22:31:56 +00:00
2006-11-28 20:52:04 +00:00
for ( mp = module - > module_interface ; mp ; mp = mp - > next ) {
2007-03-29 22:31:56 +00:00
switch_core_hash_insert ( module_manager . load_hash , ( char * ) mp - > name , ( void * ) mp ) ;
2006-11-10 21:49:57 +00:00
}
2007-03-29 22:31:56 +00:00
2006-11-10 21:49:57 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CONSOLE , " Successfully Loaded [%s] \n " , module - > filename ) ;
2007-03-29 22:31:56 +00:00
2006-11-10 21:49:57 +00:00
return SWITCH_STATUS_SUCCESS ;
}
static switch_status_t sm_load_module ( char * dir , char * fname )
{
switch_size_t len = 0 ;
char * path ;
char * file ;
# ifdef WIN32
const char * ext = " .dll " ;
# elif defined (MACOSX) || defined (DARWIN)
const char * ext = " .dylib " ;
# else
const char * ext = " .so " ;
# endif
if ( ( file = switch_core_strdup ( module_manager . pool , fname ) ) = = 0 ) {
return SWITCH_STATUS_FALSE ;
}
if ( * file = = ' / ' ) {
path = switch_core_strdup ( module_manager . pool , file ) ;
} else {
if ( strchr ( file , ' . ' ) ) {
len = strlen ( dir ) ;
len + = strlen ( file ) ;
len + = 4 ;
path = ( char * ) switch_core_alloc ( module_manager . pool , len ) ;
snprintf ( path , len , " %s%s%s " , dir , SWITCH_PATH_SEPARATOR , file ) ;
} else {
len = strlen ( dir ) ;
len + = strlen ( file ) ;
len + = 8 ;
path = ( char * ) switch_core_alloc ( module_manager . pool , len ) ;
snprintf ( path , len , " %s%s%s%s " , dir , SWITCH_PATH_SEPARATOR , file , ext ) ;
}
}
2007-03-29 22:31:56 +00:00
2006-11-28 20:52:04 +00:00
return sm_load_file ( path ) ;
2006-11-10 21:49:57 +00:00
}
static switch_status_t load_modules ( void )
{
char * cf = " spidermonkey.conf " ;
switch_xml_t cfg , xml ;
unsigned int count = 0 ;
# ifdef WIN32
const char * ext = " .dll " ;
const char * EXT = " .DLL " ;
# elif defined (MACOSX) || defined (DARWIN)
const char * ext = " .dylib " ;
const char * EXT = " .DYLIB " ;
# else
const char * ext = " .so " ;
const char * EXT = " .SO " ;
# endif
memset ( & module_manager , 0 , sizeof ( module_manager ) ) ;
switch_core_new_memory_pool ( & module_manager . pool ) ;
switch_core_hash_init ( & module_manager . mod_hash , module_manager . pool ) ;
switch_core_hash_init ( & module_manager . load_hash , module_manager . pool ) ;
if ( ( xml = switch_xml_open_cfg ( cf , & cfg , NULL ) ) ) {
switch_xml_t mods , ld ;
if ( ( mods = switch_xml_child ( cfg , " modules " ) ) ) {
for ( ld = switch_xml_child ( mods , " load " ) ; ld ; ld = ld - > next ) {
const char * val = switch_xml_attr_soft ( ld , " module " ) ;
if ( strchr ( val , ' . ' ) & & ! strstr ( val , ext ) & & ! strstr ( val , EXT ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CONSOLE , " Invalid extension for %s \n " , val ) ;
continue ;
}
sm_load_module ( ( char * ) SWITCH_GLOBAL_dirs . mod_dir , ( char * ) val ) ;
count + + ;
}
}
switch_xml_free ( xml ) ;
2007-03-29 22:31:56 +00:00
2006-11-10 21:49:57 +00:00
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CONSOLE , " open of %s failed \n " , cf ) ;
}
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 23:43:28 +00:00
static switch_status_t init_js ( void )
2006-02-26 23:10:22 +00:00
{
memset ( & globals , 0 , sizeof ( globals ) ) ;
globals . gQuitting = JS_FALSE ;
globals . gErrFile = NULL ;
globals . gOutFile = NULL ;
globals . gStackChunkSize = 8192 ;
2007-03-29 22:31:56 +00:00
globals . gStackBase = ( jsuword ) & globals . stackDummy ;
2006-02-26 23:10:22 +00:00
globals . gErrFile = stderr ;
globals . gOutFile = stdout ;
2006-03-02 14:52:51 +00:00
if ( ! ( globals . rt = JS_NewRuntime ( 64L * 1024L * 1024L ) ) ) {
2006-02-26 23:10:22 +00:00
return SWITCH_STATUS_FALSE ;
}
2007-03-29 22:31:56 +00:00
2006-11-10 21:49:57 +00:00
if ( load_modules ( ) ! = SWITCH_STATUS_SUCCESS ) {
return SWITCH_STATUS_FALSE ;
}
2006-02-26 23:10:22 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2007-03-29 22:31:56 +00:00
JSObject * new_js_event ( switch_event_t * event , char * name , JSContext * cx , JSObject * obj )
2006-02-26 23:10:22 +00:00
{
2006-11-09 05:39:04 +00:00
struct event_obj * eo ;
JSObject * Event = NULL ;
if ( ( eo = malloc ( sizeof ( * eo ) ) ) ) {
eo - > event = event ;
eo - > freed = 1 ;
if ( ( Event = JS_DefineObject ( cx , obj , name , & event_class , NULL , 0 ) ) ) {
2007-03-30 00:13:31 +00:00
if ( ( JS_SetPrivate ( cx , Event , eo ) & & JS_DefineProperties ( cx , Event , event_props ) & & JS_DefineFunctions ( cx , Event , event_methods ) ) ) {
2006-11-09 05:39:04 +00:00
}
}
}
return Event ;
}
2007-04-28 14:48:18 +00:00
# define MAX_STACK_DEPTH 2
2006-11-09 05:39:04 +00:00
2007-03-30 00:13:31 +00:00
static switch_status_t js_common_callback ( switch_core_session_t * session , void * input , switch_input_type_t itype , void * buf , unsigned int buflen )
2006-11-09 05:39:04 +00:00
{
char * dtmf = NULL ;
switch_event_t * event = NULL ;
struct input_callback_state * cb_state = buf ;
struct js_session * jss = cb_state - > session_state ;
uintN argc = 0 ;
jsval argv [ 4 ] ;
JSObject * Event = NULL ;
2007-03-27 00:40:53 +00:00
if ( ! jss | | ! jss - > session ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " You must call the session.originate method before calling this method! \n " ) ;
2006-11-09 05:39:04 +00:00
return SWITCH_STATUS_FALSE ;
}
2007-04-26 23:09:26 +00:00
jss - > stack_depth + + ;
2006-07-12 18:39:19 +00:00
switch ( itype ) {
2006-11-09 05:39:04 +00:00
case SWITCH_INPUT_TYPE_EVENT :
if ( ( event = ( switch_event_t * ) input ) ) {
if ( ( Event = new_js_event ( event , " _XX_EVENT_XX_ " , cb_state - > cx , cb_state - > obj ) ) ) {
2007-03-29 22:31:56 +00:00
argv [ argc + + ] = STRING_TO_JSVAL ( JS_NewStringCopyZ ( cb_state - > cx , " event " ) ) ;
2006-11-09 05:39:04 +00:00
argv [ argc + + ] = OBJECT_TO_JSVAL ( Event ) ;
}
}
if ( ! Event ) {
2007-04-26 23:09:26 +00:00
jss - > stack_depth - - ;
2006-07-12 18:39:19 +00:00
return SWITCH_STATUS_FALSE ;
}
2006-11-09 05:39:04 +00:00
break ;
2007-03-29 22:31:56 +00:00
case SWITCH_INPUT_TYPE_DTMF :
2006-11-09 05:39:04 +00:00
dtmf = ( char * ) input ;
2007-03-29 22:31:56 +00:00
argv [ argc + + ] = STRING_TO_JSVAL ( JS_NewStringCopyZ ( cb_state - > cx , " dtmf " ) ) ;
argv [ argc + + ] = STRING_TO_JSVAL ( JS_NewStringCopyZ ( cb_state - > cx , dtmf ) ) ;
2006-11-09 05:39:04 +00:00
break ;
}
2006-02-28 02:08:42 +00:00
2006-11-09 05:39:04 +00:00
if ( cb_state - > arg ) {
argv [ argc + + ] = cb_state - > arg ;
}
2007-04-26 23:09:26 +00:00
if ( jss - > stack_depth > MAX_STACK_DEPTH ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Maximum recursive callback limit %d reached. \n " , MAX_STACK_DEPTH ) ;
jss - > stack_depth - - ;
return SWITCH_STATUS_FALSE ;
}
2007-03-29 22:31:56 +00:00
JS_ResumeRequest ( cb_state - > cx , cb_state - > saveDepth ) ;
2006-11-09 05:39:04 +00:00
JS_CallFunction ( cb_state - > cx , cb_state - > obj , cb_state - > function , argc , argv , & cb_state - > ret ) ;
2007-03-29 22:31:56 +00:00
cb_state - > saveDepth = JS_SuspendRequest ( cb_state - > cx ) ;
2006-11-09 05:39:04 +00:00
2007-04-26 23:09:26 +00:00
jss - > stack_depth - - ;
2006-11-09 05:39:04 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-07-12 18:39:19 +00:00
2007-03-30 00:13:31 +00:00
static switch_status_t js_stream_input_callback ( switch_core_session_t * session , void * input , switch_input_type_t itype , void * buf , unsigned int buflen )
2006-11-09 05:39:04 +00:00
{
char * ret ;
switch_status_t status ;
struct input_callback_state * cb_state = buf ;
switch_file_handle_t * fh = cb_state - > extra ;
struct js_session * jss = cb_state - > session_state ;
if ( ( status = js_common_callback ( session , input , itype , buf , buflen ) ) ! = SWITCH_STATUS_SUCCESS ) {
return status ;
}
2006-11-10 01:40:22 +00:00
2006-11-09 05:39:04 +00:00
if ( ( ret = JS_GetStringBytes ( JS_ValueToString ( cb_state - > cx , cb_state - > ret ) ) ) ) {
if ( ! strncasecmp ( ret , " speed " , 4 ) ) {
char * p ;
2007-03-29 22:31:56 +00:00
2006-11-09 05:39:04 +00:00
if ( ( p = strchr ( ret , ' : ' ) ) ) {
p + + ;
if ( * p = = ' + ' | | * p = = ' - ' ) {
int step ;
if ( ! ( step = atoi ( p ) ) ) {
step = 1 ;
2006-02-28 21:21:48 +00:00
}
2006-11-09 05:39:04 +00:00
fh - > speed + = step ;
2006-02-28 21:21:48 +00:00
} else {
2006-11-09 05:39:04 +00:00
int speed = atoi ( p ) ;
fh - > speed = speed ;
2006-02-28 21:21:48 +00:00
}
return SWITCH_STATUS_SUCCESS ;
2006-11-09 05:39:04 +00:00
}
2007-03-29 22:31:56 +00:00
2006-11-09 05:39:04 +00:00
return SWITCH_STATUS_FALSE ;
} else if ( ! strcasecmp ( ret , " pause " ) ) {
if ( switch_test_flag ( fh , SWITCH_FILE_PAUSE ) ) {
switch_clear_flag ( fh , SWITCH_FILE_PAUSE ) ;
} else {
switch_set_flag ( fh , SWITCH_FILE_PAUSE ) ;
}
return SWITCH_STATUS_SUCCESS ;
} else if ( ! strcasecmp ( ret , " restart " ) ) {
unsigned int pos = 0 ;
fh - > speed = 0 ;
switch_core_file_seek ( fh , & pos , 0 , SEEK_SET ) ;
return SWITCH_STATUS_SUCCESS ;
} else if ( ! strncasecmp ( ret , " seek " , 4 ) ) {
switch_codec_t * codec ;
unsigned int samps = 0 ;
unsigned int pos = 0 ;
char * p ;
codec = switch_core_session_get_read_codec ( jss - > session ) ;
if ( ( p = strchr ( ret , ' : ' ) ) ) {
p + + ;
if ( * p = = ' + ' | | * p = = ' - ' ) {
int step ;
if ( ! ( step = atoi ( p ) ) ) {
step = 1000 ;
}
if ( step > 0 ) {
samps = step * ( codec - > implementation - > samples_per_second / 1000 ) ;
2007-03-29 22:31:56 +00:00
switch_core_file_seek ( fh , & pos , samps , SEEK_CUR ) ;
2006-02-28 21:21:48 +00:00
} else {
2006-11-09 05:39:04 +00:00
samps = step * ( codec - > implementation - > samples_per_second / 1000 ) ;
switch_core_file_seek ( fh , & pos , fh - > pos - samps , SEEK_SET ) ;
2006-02-28 21:21:48 +00:00
}
2006-11-09 05:39:04 +00:00
} else {
samps = atoi ( p ) * ( codec - > implementation - > samples_per_second / 1000 ) ;
switch_core_file_seek ( fh , & pos , samps , SEEK_SET ) ;
2006-03-02 14:52:51 +00:00
}
2006-07-12 18:39:19 +00:00
}
2006-02-28 02:08:42 +00:00
2006-11-09 05:39:04 +00:00
return SWITCH_STATUS_SUCCESS ;
2006-02-28 02:08:42 +00:00
}
2006-07-12 18:39:19 +00:00
2006-11-09 05:39:04 +00:00
if ( ! strcmp ( ret , " true " ) | | ! strcmp ( ret , " undefined " ) ) {
2007-03-29 22:31:56 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-11-09 05:39:04 +00:00
return SWITCH_STATUS_BREAK ;
2006-11-10 01:40:22 +00:00
2006-02-28 02:08:42 +00:00
}
2006-07-12 18:39:19 +00:00
return SWITCH_STATUS_SUCCESS ;
2006-02-28 02:08:42 +00:00
}
2006-02-26 23:10:22 +00:00
2007-03-30 00:13:31 +00:00
static switch_status_t js_record_input_callback ( switch_core_session_t * session , void * input , switch_input_type_t itype , void * buf , unsigned int buflen )
2006-03-01 04:47:34 +00:00
{
2006-11-09 05:39:04 +00:00
char * ret ;
switch_status_t status ;
struct input_callback_state * cb_state = buf ;
switch_file_handle_t * fh = cb_state - > extra ;
2006-03-01 04:47:34 +00:00
2006-11-09 05:39:04 +00:00
if ( ( status = js_common_callback ( session , input , itype , buf , buflen ) ) ! = SWITCH_STATUS_SUCCESS ) {
return status ;
}
2007-03-29 22:31:56 +00:00
2006-11-09 05:39:04 +00:00
if ( ( ret = JS_GetStringBytes ( JS_ValueToString ( cb_state - > cx , cb_state - > ret ) ) ) ) {
if ( ! strcasecmp ( ret , " pause " ) ) {
if ( switch_test_flag ( fh , SWITCH_FILE_PAUSE ) ) {
switch_clear_flag ( fh , SWITCH_FILE_PAUSE ) ;
} else {
switch_set_flag ( fh , SWITCH_FILE_PAUSE ) ;
2006-03-01 04:47:34 +00:00
}
return SWITCH_STATUS_SUCCESS ;
2006-11-09 05:39:04 +00:00
} else if ( ! strcasecmp ( ret , " restart " ) ) {
unsigned int pos = 0 ;
fh - > speed = 0 ;
switch_core_file_seek ( fh , & pos , 0 , SEEK_SET ) ;
return SWITCH_STATUS_SUCCESS ;
}
2006-07-12 18:39:19 +00:00
2006-11-09 05:39:04 +00:00
if ( ! strcmp ( ret , " true " ) | | ! strcmp ( ret , " undefined " ) ) {
2007-03-29 22:31:56 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-11-10 01:40:22 +00:00
2006-11-09 05:39:04 +00:00
return SWITCH_STATUS_BREAK ;
2006-11-10 01:40:22 +00:00
2006-03-01 04:47:34 +00:00
}
2006-07-12 18:39:19 +00:00
return SWITCH_STATUS_SUCCESS ;
2006-03-01 04:47:34 +00:00
}
2007-03-30 00:13:31 +00:00
static switch_status_t js_collect_input_callback ( switch_core_session_t * session , void * input , switch_input_type_t itype , void * buf , unsigned int buflen )
2006-03-01 04:47:34 +00:00
{
2006-11-09 05:39:04 +00:00
char * ret ;
switch_status_t status ;
struct input_callback_state * cb_state = buf ;
2006-03-01 04:47:34 +00:00
2006-11-09 05:39:04 +00:00
if ( ( status = js_common_callback ( session , input , itype , buf , buflen ) ) ! = SWITCH_STATUS_SUCCESS ) {
return status ;
}
2006-07-12 18:39:19 +00:00
2006-11-09 05:39:04 +00:00
if ( ( ret = JS_GetStringBytes ( JS_ValueToString ( cb_state - > cx , cb_state - > ret ) ) ) ) {
if ( ! strcmp ( ret , " true " ) | | ! strcmp ( ret , " undefined " ) ) {
return SWITCH_STATUS_SUCCESS ;
2006-03-01 04:47:34 +00:00
}
}
2006-11-10 01:40:22 +00:00
return SWITCH_STATUS_BREAK ;
2006-03-01 04:47:34 +00:00
}
2007-03-29 22:31:56 +00:00
static JSBool session_flush_digits ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-08-18 21:18:41 +00:00
{
struct js_session * jss = JS_GetPrivate ( cx , obj ) ;
char buf [ 256 ] ;
switch_size_t has ;
2006-12-14 01:23:03 +00:00
switch_channel_t * channel ;
2006-08-18 21:18:41 +00:00
2007-03-27 00:40:53 +00:00
if ( ! jss | | ! jss - > session ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " You must call the session.originate method before calling this method! \n " ) ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2007-03-27 00:40:53 +00:00
return JS_TRUE ;
}
2006-08-18 21:18:41 +00:00
channel = switch_core_session_get_channel ( jss - > session ) ;
2007-03-29 22:31:56 +00:00
assert ( channel ! = NULL ) ;
2006-08-18 21:18:41 +00:00
2007-02-17 18:40:42 +00:00
while ( ( has = switch_channel_has_dtmf ( channel ) ) ) {
switch_channel_dequeue_dtmf ( channel , buf , sizeof ( buf ) ) ;
2006-08-18 21:18:41 +00:00
}
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_TRUE ) ;
return JS_TRUE ;
2006-08-18 21:18:41 +00:00
}
2007-03-29 22:31:56 +00:00
static JSBool session_flush_events ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-08-18 21:18:41 +00:00
{
struct js_session * jss = JS_GetPrivate ( cx , obj ) ;
switch_event_t * event ;
2007-03-29 22:31:56 +00:00
switch_channel_t * channel ;
2006-12-14 01:23:03 +00:00
2007-03-27 00:40:53 +00:00
if ( ! jss | | ! jss - > session ) {
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2007-03-27 00:40:53 +00:00
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
channel = switch_core_session_get_channel ( jss - > session ) ;
assert ( channel ! = NULL ) ;
2006-12-14 01:23:03 +00:00
2006-08-18 21:18:41 +00:00
while ( switch_core_session_dequeue_event ( jss - > session , & event ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_destroy ( & event ) ;
}
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_TRUE ) ;
return JS_TRUE ;
2006-08-18 21:18:41 +00:00
}
2007-03-29 22:31:56 +00:00
static JSBool session_recordfile ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-03-01 04:47:34 +00:00
{
struct js_session * jss = JS_GetPrivate ( cx , obj ) ;
2006-04-29 06:05:03 +00:00
switch_channel_t * channel ;
2006-03-01 04:47:34 +00:00
char * file_name = NULL ;
void * bp = NULL ;
int len = 0 ;
2006-07-12 18:39:19 +00:00
switch_input_callback_function_t dtmf_func = NULL ;
2007-03-29 22:31:56 +00:00
struct input_callback_state cb_state = { 0 } ;
switch_file_handle_t fh = { 0 } ;
2006-11-09 05:39:04 +00:00
JSFunction * function ;
2007-03-29 22:31:56 +00:00
int32 limit = 0 ;
switch_input_args_t args = { 0 } ;
2006-03-01 04:47:34 +00:00
2007-03-27 00:40:53 +00:00
if ( ! jss | | ! jss - > session ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " You must call the session.originate method before calling this method! \n " ) ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2007-03-27 00:40:53 +00:00
return JS_TRUE ;
}
2006-03-01 04:47:34 +00:00
channel = switch_core_session_get_channel ( jss - > session ) ;
2006-03-02 14:52:51 +00:00
assert ( channel ! = NULL ) ;
2006-12-14 01:23:03 +00:00
2007-03-29 22:31:56 +00:00
if ( ! switch_channel_ready ( channel ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Session is not active! \n " ) ;
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
return JS_TRUE ;
}
2006-12-14 01:23:03 +00:00
2006-03-01 04:47:34 +00:00
if ( argc > 0 ) {
file_name = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 0 ] ) ) ;
if ( switch_strlen_zero ( file_name ) ) {
return JS_FALSE ;
}
}
if ( argc > 1 ) {
2006-11-09 05:39:04 +00:00
if ( ( function = JS_ValueToFunction ( cx , argv [ 1 ] ) ) ) {
2006-03-01 04:47:34 +00:00
memset ( & cb_state , 0 , sizeof ( cb_state ) ) ;
cb_state . session_state = jss ;
2006-11-09 05:39:04 +00:00
cb_state . function = function ;
cb_state . cx = cx ;
2007-03-29 22:31:56 +00:00
cb_state . obj = obj ;
2006-11-09 05:39:04 +00:00
if ( argc > 2 ) {
2007-03-29 22:31:56 +00:00
cb_state . arg = argv [ 2 ] ;
}
2006-11-09 05:39:04 +00:00
dtmf_func = js_record_input_callback ;
2006-03-01 04:47:34 +00:00
bp = & cb_state ;
len = sizeof ( cb_state ) ;
}
2006-11-28 21:46:29 +00:00
2007-03-29 22:31:56 +00:00
if ( argc > 3 ) {
JS_ValueToInt32 ( cx , argv [ 3 ] , & limit ) ;
}
2006-11-29 17:10:40 +00:00
2007-03-29 22:31:56 +00:00
if ( argc > 4 ) {
int32 thresh ;
JS_ValueToInt32 ( cx , argv [ 4 ] , & thresh ) ;
fh . thresh = thresh ;
}
2006-11-29 17:10:40 +00:00
2007-03-29 22:31:56 +00:00
if ( argc > 5 ) {
int32 silence_hits ;
JS_ValueToInt32 ( cx , argv [ 5 ] , & silence_hits ) ;
fh . silence_hits = silence_hits ;
}
2006-03-01 04:47:34 +00:00
}
2007-03-29 22:31:56 +00:00
2006-03-01 04:47:34 +00:00
cb_state . extra = & fh ;
2007-03-29 22:31:56 +00:00
cb_state . ret = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
cb_state . saveDepth = JS_SuspendRequest ( cx ) ;
args . input_callback = dtmf_func ;
args . buf = bp ;
args . buflen = len ;
2006-12-23 16:40:37 +00:00
switch_ivr_record_file ( jss - > session , & fh , file_name , & args , limit ) ;
2007-03-29 22:31:56 +00:00
JS_ResumeRequest ( cx , cb_state . saveDepth ) ;
2006-11-09 05:39:04 +00:00
* rval = cb_state . ret ;
2006-12-14 01:23:03 +00:00
return JS_TRUE ;
2006-11-09 05:39:04 +00:00
}
2007-03-29 22:31:56 +00:00
static JSBool session_collect_input ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-11-09 05:39:04 +00:00
{
struct js_session * jss = JS_GetPrivate ( cx , obj ) ;
switch_channel_t * channel ;
void * bp = NULL ;
int len = 0 ;
int32 to = 0 ;
switch_input_callback_function_t dtmf_func = NULL ;
2007-03-29 22:31:56 +00:00
struct input_callback_state cb_state = { 0 } ;
2006-11-09 05:39:04 +00:00
JSFunction * function ;
2007-03-29 22:31:56 +00:00
switch_input_args_t args = { 0 } ;
2006-11-09 05:39:04 +00:00
2007-03-27 00:40:53 +00:00
if ( ! jss | | ! jss - > session ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " You must call the session.originate method before calling this method! \n " ) ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2007-03-27 00:40:53 +00:00
return JS_TRUE ;
}
2006-11-09 05:39:04 +00:00
channel = switch_core_session_get_channel ( jss - > session ) ;
assert ( channel ! = NULL ) ;
2006-12-14 01:23:03 +00:00
2007-03-29 22:31:56 +00:00
if ( ! switch_channel_ready ( channel ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Session is not active! \n " ) ;
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
return JS_TRUE ;
}
2006-12-14 01:23:03 +00:00
2006-11-09 05:39:04 +00:00
if ( argc > 0 ) {
if ( ( function = JS_ValueToFunction ( cx , argv [ 0 ] ) ) ) {
memset ( & cb_state , 0 , sizeof ( cb_state ) ) ;
cb_state . function = function ;
if ( argc > 1 ) {
2007-03-29 22:31:56 +00:00
cb_state . arg = argv [ 1 ] ;
}
2006-11-09 05:39:04 +00:00
cb_state . session_state = jss ;
cb_state . cx = cx ;
2007-03-29 22:31:56 +00:00
cb_state . obj = obj ;
2006-11-09 05:39:04 +00:00
dtmf_func = js_collect_input_callback ;
bp = & cb_state ;
len = sizeof ( cb_state ) ;
}
}
if ( argc > 2 ) {
JS_ValueToInt32 ( jss - > cx , argv [ 2 ] , & to ) ;
}
2007-03-29 22:31:56 +00:00
cb_state . saveDepth = JS_SuspendRequest ( cx ) ;
args . input_callback = dtmf_func ;
args . buf = bp ;
args . buflen = len ;
2006-12-23 16:40:37 +00:00
switch_ivr_collect_digits_callback ( jss - > session , & args , to ) ;
2007-03-29 22:31:56 +00:00
JS_ResumeRequest ( cx , cb_state . saveDepth ) ;
2006-12-02 05:40:58 +00:00
2006-11-10 01:40:22 +00:00
* rval = cb_state . ret ;
2006-03-01 04:47:34 +00:00
2006-12-14 01:23:03 +00:00
return JS_TRUE ;
2006-03-01 04:47:34 +00:00
}
2007-02-09 21:56:44 +00:00
/* session.sayphrase(phrase_name, phrase_data, language, dtmf_callback, dtmf_callback_args)*/
2007-03-29 22:31:56 +00:00
static JSBool session_sayphrase ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2007-02-09 21:56:44 +00:00
{
struct js_session * jss = JS_GetPrivate ( cx , obj ) ;
switch_channel_t * channel ;
char * phrase_name = NULL ;
2007-03-29 22:31:56 +00:00
char * phrase_data = NULL ;
char * phrase_lang = NULL ;
2007-02-09 21:56:44 +00:00
//char *input_callback = NULL;
void * bp = NULL ;
int len = 0 ;
switch_input_callback_function_t dtmf_func = NULL ;
2007-03-29 22:31:56 +00:00
struct input_callback_state cb_state = { 0 } ;
2007-02-09 21:56:44 +00:00
JSFunction * function ;
2007-03-29 22:31:56 +00:00
switch_input_args_t args = { 0 } ;
2007-02-09 21:56:44 +00:00
2007-03-27 00:40:53 +00:00
if ( ! jss | | ! jss - > session ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " You must call the session.originate method before calling this method! \n " ) ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2007-03-27 00:40:53 +00:00
return JS_TRUE ;
}
2007-02-09 21:56:44 +00:00
channel = switch_core_session_get_channel ( jss - > session ) ;
assert ( channel ! = NULL ) ;
2007-03-29 22:31:56 +00:00
if ( ! switch_channel_ready ( channel ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Session is not active! \n " ) ;
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
return JS_TRUE ;
}
2007-02-09 21:56:44 +00:00
if ( argc > 0 ) {
phrase_name = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 0 ] ) ) ;
if ( switch_strlen_zero ( phrase_name ) ) {
return JS_FALSE ;
}
2007-02-09 22:55:48 +00:00
} else {
return JS_FALSE ;
2007-02-09 21:56:44 +00:00
}
2007-02-09 22:55:48 +00:00
2007-03-29 22:31:56 +00:00
if ( argc > 1 ) {
phrase_data = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 1 ] ) ) ;
}
2007-02-09 21:56:44 +00:00
2007-03-29 22:31:56 +00:00
if ( argc > 2 ) {
phrase_lang = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 2 ] ) ) ;
}
2007-02-09 21:56:44 +00:00
if ( argc > 3 ) {
if ( ( function = JS_ValueToFunction ( cx , argv [ 3 ] ) ) ) {
memset ( & cb_state , 0 , sizeof ( cb_state ) ) ;
cb_state . function = function ;
if ( argc > 4 ) {
cb_state . arg = argv [ 4 ] ;
}
cb_state . session_state = jss ;
cb_state . cx = cx ;
cb_state . obj = obj ;
2007-02-10 01:00:02 +00:00
dtmf_func = js_collect_input_callback ;
2007-02-09 21:56:44 +00:00
bp = & cb_state ;
len = sizeof ( cb_state ) ;
}
}
2007-03-29 22:31:56 +00:00
cb_state . ret = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
cb_state . saveDepth = JS_SuspendRequest ( cx ) ;
args . input_callback = dtmf_func ;
args . buf = bp ;
args . buflen = len ;
2007-02-09 21:56:44 +00:00
2007-03-29 22:31:56 +00:00
switch_ivr_phrase_macro ( jss - > session , phrase_name , phrase_data , phrase_lang , & args ) ;
2007-02-09 21:56:44 +00:00
2007-03-29 22:31:56 +00:00
JS_ResumeRequest ( cx , cb_state . saveDepth ) ;
2007-02-09 21:56:44 +00:00
* rval = cb_state . ret ;
2007-03-29 22:31:56 +00:00
2007-02-09 21:56:44 +00:00
return JS_TRUE ;
}
2007-03-27 00:40:53 +00:00
static void check_hangup_hook ( struct js_session * jss )
{
2007-04-23 20:11:28 +00:00
jsval argv [ 3 ] = { 0 } ;
2007-03-27 00:40:53 +00:00
int argc = 0 ;
jsval ret ;
2007-04-23 20:11:28 +00:00
if ( jss - > on_hangup & & ( jss - > hook_state = = CS_HANGUP | | jss - > hook_state = = CS_RING ) ) {
2007-03-29 22:31:56 +00:00
argv [ argc + + ] = OBJECT_TO_JSVAL ( jss - > obj ) ;
2007-04-23 20:11:28 +00:00
if ( jss - > hook_state = = CS_HANGUP ) {
argv [ argc + + ] = STRING_TO_JSVAL ( JS_NewStringCopyZ ( jss - > cx , " hangup " ) ) ;
} else {
argv [ argc + + ] = STRING_TO_JSVAL ( JS_NewStringCopyZ ( jss - > cx , " transfer " ) ) ;
}
2007-03-27 00:40:53 +00:00
JS_CallFunction ( jss - > cx , jss - > obj , jss - > on_hangup , argc , argv , & ret ) ;
}
}
static switch_status_t hanguphook ( switch_core_session_t * session )
{
switch_channel_t * channel ;
struct js_session * jss = NULL ;
2007-04-23 20:11:28 +00:00
switch_channel_state_t state ;
2007-03-27 00:40:53 +00:00
channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
2007-03-29 22:31:56 +00:00
2007-04-23 20:11:28 +00:00
state = switch_channel_get_state ( channel ) ;
if ( ( jss = switch_channel_get_private ( channel , " jss " ) ) ) {
if ( jss - > hook_state ! = state ) {
jss - > hook_state = state ;
2007-03-27 00:40:53 +00:00
check_hangup_hook ( jss ) ;
}
}
2007-04-23 20:11:28 +00:00
2007-03-27 00:40:53 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2007-03-29 22:31:56 +00:00
static JSBool session_hanguphook ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2007-03-27 00:40:53 +00:00
{
JSFunction * function ;
struct js_session * jss ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2007-03-27 00:40:53 +00:00
if ( ( jss = JS_GetPrivate ( cx , obj ) ) & & jss - > session ) {
if ( argc > 0 ) {
if ( ( function = JS_ValueToFunction ( cx , argv [ 0 ] ) ) ) {
switch_channel_t * channel = switch_core_session_get_channel ( jss - > session ) ;
assert ( channel ! = NULL ) ;
jss - > on_hangup = function ;
2007-04-23 20:11:28 +00:00
jss - > hook_state = switch_channel_get_state ( channel ) ;
2007-03-27 00:40:53 +00:00
switch_channel_set_private ( channel , " jss " , jss ) ;
2007-03-29 22:31:56 +00:00
switch_core_event_hook_add_state_change ( jss - > session , hanguphook ) ;
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2007-03-27 00:40:53 +00:00
}
}
}
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
static JSBool session_streamfile ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-02-28 02:08:42 +00:00
{
struct js_session * jss = JS_GetPrivate ( cx , obj ) ;
2006-04-29 06:05:03 +00:00
switch_channel_t * channel ;
2006-02-28 02:08:42 +00:00
char * file_name = NULL ;
2006-11-09 05:39:04 +00:00
//char *input_callback = NULL;
2006-02-28 02:08:42 +00:00
void * bp = NULL ;
int len = 0 ;
2006-07-12 18:39:19 +00:00
switch_input_callback_function_t dtmf_func = NULL ;
2007-03-29 22:31:56 +00:00
struct input_callback_state cb_state = { 0 } ;
switch_file_handle_t fh = { 0 } ;
2006-11-09 05:39:04 +00:00
JSFunction * function ;
2007-03-29 22:31:56 +00:00
switch_input_args_t args = { 0 } ;
2006-02-28 02:08:42 +00:00
2007-03-27 00:40:53 +00:00
if ( ! jss | | ! jss - > session ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " You must call the session.originate method before calling this method! \n " ) ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2007-03-27 00:40:53 +00:00
return JS_TRUE ;
}
2006-02-28 02:08:42 +00:00
channel = switch_core_session_get_channel ( jss - > session ) ;
2006-03-02 14:52:51 +00:00
assert ( channel ! = NULL ) ;
2006-12-14 01:23:03 +00:00
2007-03-29 22:31:56 +00:00
if ( ! switch_channel_ready ( channel ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Session is not active! \n " ) ;
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
return JS_TRUE ;
}
2006-12-14 01:23:03 +00:00
2006-02-26 23:10:22 +00:00
if ( argc > 0 ) {
2006-02-28 02:08:42 +00:00
file_name = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 0 ] ) ) ;
if ( switch_strlen_zero ( file_name ) ) {
return JS_FALSE ;
2006-02-26 23:10:22 +00:00
}
}
2006-12-23 16:40:37 +00:00
2006-02-28 02:08:42 +00:00
if ( argc > 1 ) {
2006-12-23 16:40:37 +00:00
if ( ( function = JS_ValueToFunction ( cx , argv [ 1 ] ) ) ) {
2006-02-28 02:08:42 +00:00
memset ( & cb_state , 0 , sizeof ( cb_state ) ) ;
2006-11-09 05:39:04 +00:00
cb_state . function = function ;
2006-12-23 16:40:37 +00:00
if ( argc > 2 ) {
cb_state . arg = argv [ 2 ] ;
2006-11-09 05:39:04 +00:00
}
2006-02-28 02:08:42 +00:00
cb_state . session_state = jss ;
2006-11-09 05:39:04 +00:00
cb_state . cx = cx ;
cb_state . obj = obj ;
dtmf_func = js_stream_input_callback ;
2006-02-28 02:08:42 +00:00
bp = & cb_state ;
len = sizeof ( cb_state ) ;
}
}
2007-03-29 22:31:56 +00:00
if ( argc > 3 ) {
int32 samps ;
JS_ValueToInt32 ( cx , argv [ 3 ] , & samps ) ;
fh . samples = samps ;
}
2006-11-28 20:52:04 +00:00
2006-02-28 02:08:42 +00:00
cb_state . extra = & fh ;
2007-03-29 22:31:56 +00:00
cb_state . ret = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
cb_state . saveDepth = JS_SuspendRequest ( cx ) ;
args . input_callback = dtmf_func ;
args . buf = bp ;
args . buflen = len ;
2006-12-23 16:40:37 +00:00
switch_ivr_play_file ( jss - > session , & fh , file_name , & args ) ;
2007-03-29 22:31:56 +00:00
JS_ResumeRequest ( cx , cb_state . saveDepth ) ;
2006-11-09 05:39:04 +00:00
* rval = cb_state . ret ;
2007-03-29 22:31:56 +00:00
2006-12-14 01:23:03 +00:00
return JS_TRUE ;
2006-02-26 23:10:22 +00:00
}
2007-03-29 22:31:56 +00:00
static JSBool session_set_variable ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-08-21 20:16:28 +00:00
{
struct js_session * jss = JS_GetPrivate ( cx , obj ) ;
2007-03-29 22:31:56 +00:00
switch_channel_t * channel ;
2006-08-21 20:16:28 +00:00
2007-03-27 00:40:53 +00:00
if ( ! jss | | ! jss - > session ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " You must call the session.originate method before calling this method! \n " ) ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2007-03-27 00:40:53 +00:00
return JS_TRUE ;
}
2006-08-21 20:16:28 +00:00
channel = switch_core_session_get_channel ( jss - > session ) ;
2007-03-29 22:31:56 +00:00
assert ( channel ! = NULL ) ;
2006-08-21 20:16:28 +00:00
if ( argc > 1 ) {
char * var , * val ;
var = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 0 ] ) ) ;
val = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 1 ] ) ) ;
switch_channel_set_variable ( channel , var , val ) ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_TRUE ) ;
2006-08-21 20:16:28 +00:00
} else {
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-08-21 20:16:28 +00:00
}
2007-03-29 22:31:56 +00:00
2006-08-21 20:16:28 +00:00
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
static JSBool session_get_variable ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-08-21 20:16:28 +00:00
{
struct js_session * jss = JS_GetPrivate ( cx , obj ) ;
2007-03-29 22:31:56 +00:00
switch_channel_t * channel ;
2006-08-21 20:16:28 +00:00
2007-03-27 00:40:53 +00:00
if ( ! jss | | ! jss - > session ) {
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2007-03-27 00:40:53 +00:00
return JS_TRUE ;
}
2006-08-21 20:16:28 +00:00
channel = switch_core_session_get_channel ( jss - > session ) ;
2007-03-29 22:31:56 +00:00
assert ( channel ! = NULL ) ;
2006-08-21 20:16:28 +00:00
if ( argc > 0 ) {
char * var , * val ;
2007-03-29 22:31:56 +00:00
2006-08-21 20:16:28 +00:00
var = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 0 ] ) ) ;
val = switch_channel_get_variable ( channel , var ) ;
if ( val ) {
2007-03-29 22:31:56 +00:00
* rval = STRING_TO_JSVAL ( JS_NewStringCopyZ ( cx , val ) ) ;
2006-08-21 20:16:28 +00:00
} else {
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-08-21 20:16:28 +00:00
}
} else {
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-08-21 20:16:28 +00:00
}
2007-03-29 22:31:56 +00:00
2006-08-21 20:16:28 +00:00
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
static JSBool session_speak ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-02-26 23:10:22 +00:00
{
2006-02-28 02:08:42 +00:00
struct js_session * jss = JS_GetPrivate ( cx , obj ) ;
2006-04-29 06:05:03 +00:00
switch_channel_t * channel ;
2006-02-26 23:10:22 +00:00
char * tts_name = NULL ;
char * voice_name = NULL ;
char * text = NULL ;
2006-04-29 06:05:03 +00:00
switch_codec_t * codec ;
2006-02-28 02:08:42 +00:00
void * bp = NULL ;
int len = 0 ;
2007-03-29 22:31:56 +00:00
struct input_callback_state cb_state = { 0 } ;
2006-07-12 18:39:19 +00:00
switch_input_callback_function_t dtmf_func = NULL ;
2006-11-09 05:39:04 +00:00
JSFunction * function ;
2007-03-29 22:31:56 +00:00
switch_input_args_t args = { 0 } ;
2006-02-26 23:10:22 +00:00
2007-03-27 00:40:53 +00:00
if ( ! jss | | ! jss - > session ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " You must call the session.originate method before calling this method! \n " ) ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2007-03-27 00:40:53 +00:00
return JS_TRUE ;
}
2006-02-28 02:08:42 +00:00
channel = switch_core_session_get_channel ( jss - > session ) ;
2006-03-02 14:52:51 +00:00
assert ( channel ! = NULL ) ;
2006-12-14 01:23:03 +00:00
2007-03-29 22:31:56 +00:00
if ( ! switch_channel_ready ( channel ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Session is not active! \n " ) ;
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
return JS_TRUE ;
}
2006-12-14 01:23:03 +00:00
2006-02-26 23:10:22 +00:00
if ( argc > 0 ) {
tts_name = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 0 ] ) ) ;
}
if ( argc > 1 ) {
2007-03-29 22:31:56 +00:00
voice_name = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 1 ] ) ) ;
2006-02-26 23:10:22 +00:00
}
if ( argc > 2 ) {
text = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 2 ] ) ) ;
}
2006-02-28 02:08:42 +00:00
if ( argc > 3 ) {
2006-11-09 05:39:04 +00:00
if ( ( function = JS_ValueToFunction ( cx , argv [ 3 ] ) ) ) {
2006-03-01 00:58:32 +00:00
memset ( & cb_state , 0 , sizeof ( cb_state ) ) ;
2006-11-09 05:39:04 +00:00
cb_state . function = function ;
if ( argc > 4 ) {
2007-03-29 22:31:56 +00:00
cb_state . arg = argv [ 4 ] ;
}
2006-11-09 05:39:04 +00:00
cb_state . cx = cx ;
2007-03-29 22:31:56 +00:00
cb_state . obj = obj ;
2006-03-01 00:58:32 +00:00
cb_state . session_state = jss ;
2006-11-09 05:39:04 +00:00
dtmf_func = js_collect_input_callback ;
2006-03-01 00:58:32 +00:00
bp = & cb_state ;
len = sizeof ( cb_state ) ;
}
2006-02-28 02:08:42 +00:00
}
2006-02-26 23:10:22 +00:00
if ( ! tts_name & & text ) {
return JS_FALSE ;
}
2006-02-28 02:08:42 +00:00
codec = switch_core_session_get_read_codec ( jss - > session ) ;
2007-03-29 22:31:56 +00:00
cb_state . ret = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
cb_state . saveDepth = JS_SuspendRequest ( cx ) ;
args . input_callback = dtmf_func ;
args . buf = bp ;
args . buflen = len ;
2007-03-30 00:15:25 +00:00
switch_ivr_speak_text ( jss - > session , tts_name , voice_name
& & strlen ( voice_name ) ? voice_name : NULL , codec - > implementation - > samples_per_second , text , & args ) ;
2007-03-29 22:31:56 +00:00
JS_ResumeRequest ( cx , cb_state . saveDepth ) ;
2006-11-09 05:39:04 +00:00
* rval = cb_state . ret ;
2006-03-01 00:58:32 +00:00
2006-12-14 01:23:03 +00:00
return JS_TRUE ;
2006-02-26 23:10:22 +00:00
}
2007-03-29 22:31:56 +00:00
static JSBool session_get_digits ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-02-26 23:10:22 +00:00
{
2006-02-28 02:08:42 +00:00
struct js_session * jss = JS_GetPrivate ( cx , obj ) ;
2006-02-26 23:10:22 +00:00
char * terminators = NULL ;
2007-03-29 22:31:56 +00:00
char buf [ 513 ] = { 0 } ;
2007-02-11 00:39:46 +00:00
int32 digits = 0 , timeout = 5000 ;
2006-12-14 01:23:03 +00:00
switch_channel_t * channel ;
2007-03-27 00:40:53 +00:00
if ( ! jss | | ! jss - > session ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " You must call the session.originate method before calling this method! \n " ) ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2007-03-27 00:40:53 +00:00
return JS_TRUE ;
}
2006-12-14 01:23:03 +00:00
channel = switch_core_session_get_channel ( jss - > session ) ;
2007-03-29 22:31:56 +00:00
assert ( channel ! = NULL ) ;
if ( ! switch_channel_ready ( channel ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Session is not active! \n " ) ;
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
return JS_TRUE ;
}
2006-12-14 01:23:03 +00:00
2006-02-26 23:10:22 +00:00
if ( argc > 0 ) {
char term ;
2007-02-11 00:39:46 +00:00
JS_ValueToInt32 ( cx , argv [ 0 ] , & digits ) ;
if ( digits > sizeof ( buf ) - 1 ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Exceeded max digits of % " SWITCH_SIZE_T_FMT " \n " , sizeof ( buf ) - 1 ) ;
2007-02-11 00:39:46 +00:00
return JS_FALSE ;
}
2007-03-29 22:31:56 +00:00
2006-02-26 23:10:22 +00:00
if ( argc > 1 ) {
terminators = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 1 ] ) ) ;
}
2006-03-01 00:58:32 +00:00
if ( argc > 2 ) {
JS_ValueToInt32 ( cx , argv [ 2 ] , & timeout ) ;
}
2006-06-09 22:59:13 +00:00
2007-02-10 23:16:34 +00:00
switch_ivr_collect_digits_count ( jss - > session , buf , sizeof ( buf ) , digits , terminators , & term , timeout ) ;
2007-03-29 22:31:56 +00:00
* rval = STRING_TO_JSVAL ( JS_NewStringCopyZ ( cx , buf ) ) ;
2006-02-26 23:10:22 +00:00
return JS_TRUE ;
}
return JS_FALSE ;
}
2007-03-29 22:31:56 +00:00
static JSBool session_autohangup ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2007-03-27 00:40:53 +00:00
{
struct js_session * jss = JS_GetPrivate ( cx , obj ) ;
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
if ( ! jss | | ! jss - > session ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " You must call the session.originate method before calling this method! \n " ) ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2007-03-27 00:40:53 +00:00
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
2007-03-27 00:40:53 +00:00
if ( argv [ 0 ] ) {
JSBool tf ;
JS_ValueToBoolean ( cx , argv [ 0 ] , & tf ) ;
if ( tf = = JS_TRUE ) {
switch_set_flag ( jss , S_HUP ) ;
} else {
switch_clear_flag ( jss , S_HUP ) ;
}
* rval = BOOLEAN_TO_JSVAL ( tf ) ;
}
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
static JSBool session_answer ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-02-26 23:10:22 +00:00
{
2006-02-28 02:08:42 +00:00
struct js_session * jss = JS_GetPrivate ( cx , obj ) ;
2006-04-29 06:05:03 +00:00
switch_channel_t * channel ;
2006-02-26 23:10:22 +00:00
2007-03-27 00:40:53 +00:00
if ( ! jss | | ! jss - > session ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " You must call the session.originate method before calling this method! \n " ) ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2007-03-27 00:40:53 +00:00
return JS_TRUE ;
}
2006-02-28 02:08:42 +00:00
channel = switch_core_session_get_channel ( jss - > session ) ;
2006-02-26 23:10:22 +00:00
assert ( channel ! = NULL ) ;
2007-03-29 22:31:56 +00:00
if ( ! switch_channel_ready ( channel ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Session is not active! \n " ) ;
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
return JS_TRUE ;
}
2006-12-14 01:23:03 +00:00
2006-02-26 23:10:22 +00:00
switch_channel_answer ( channel ) ;
return JS_TRUE ;
}
2007-02-14 15:19:01 +00:00
2007-03-29 22:31:56 +00:00
static JSBool session_cdr ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2007-02-14 15:19:01 +00:00
{
struct js_session * jss = JS_GetPrivate ( cx , obj ) ;
switch_xml_t cdr ;
2007-03-29 22:31:56 +00:00
/*Always a pessimist... sheesh! */
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2007-02-14 15:19:01 +00:00
2007-03-27 00:40:53 +00:00
if ( ! jss | | ! jss - > session ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " You must call the session.originate method before calling this method! \n " ) ;
2007-03-27 00:40:53 +00:00
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
if ( switch_ivr_generate_xml_cdr ( jss - > session , & cdr ) = = SWITCH_STATUS_SUCCESS ) {
2007-02-14 15:19:01 +00:00
char * xml_text ;
if ( ( xml_text = switch_xml_toxml ( cdr ) ) ) {
2007-03-29 22:31:56 +00:00
* rval = STRING_TO_JSVAL ( JS_NewStringCopyZ ( cx , xml_text ) ) ;
2007-02-14 15:19:01 +00:00
}
switch_safe_free ( xml_text ) ;
switch_xml_free ( cdr ) ;
}
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
static JSBool session_ready ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-03-01 22:55:28 +00:00
{
struct js_session * jss = JS_GetPrivate ( cx , obj ) ;
2006-04-29 06:05:03 +00:00
switch_channel_t * channel ;
2006-03-01 22:55:28 +00:00
2007-03-27 00:40:53 +00:00
if ( ! jss | | ! jss - > session ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " You must call the session.originate method before calling this method! \n " ) ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2007-03-27 00:40:53 +00:00
return JS_TRUE ;
}
2006-03-01 22:55:28 +00:00
channel = switch_core_session_get_channel ( jss - > session ) ;
assert ( channel ! = NULL ) ;
2006-12-14 01:23:03 +00:00
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( switch_channel_ready ( channel ) ? JS_TRUE : JS_FALSE ) ;
2006-03-01 22:55:28 +00:00
return JS_TRUE ;
}
2006-11-09 05:39:04 +00:00
2007-03-29 22:31:56 +00:00
static JSBool session_wait_for_media ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-03-01 22:55:28 +00:00
{
struct js_session * jss = JS_GetPrivate ( cx , obj ) ;
2006-04-29 06:05:03 +00:00
switch_channel_t * channel ;
2006-03-01 22:55:28 +00:00
switch_time_t started ;
unsigned int elapsed ;
2006-03-01 23:50:07 +00:00
int32 timeout = 60 ;
2006-12-14 01:23:03 +00:00
2007-03-27 00:40:53 +00:00
if ( ! jss | | ! jss - > session ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " You must call the session.originate method before calling this method! \n " ) ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2007-03-27 00:40:53 +00:00
return JS_TRUE ;
}
2006-03-01 22:55:28 +00:00
channel = switch_core_session_get_channel ( jss - > session ) ;
assert ( channel ! = NULL ) ;
2006-12-14 01:23:03 +00:00
2006-03-01 22:55:28 +00:00
started = switch_time_now ( ) ;
if ( argc > 0 ) {
JS_ValueToInt32 ( cx , argv [ 0 ] , & timeout ) ;
}
2007-03-29 22:31:56 +00:00
for ( ; ; ) {
if ( ( ( elapsed = ( unsigned int ) ( ( switch_time_now ( ) - started ) / 1000 ) ) > ( switch_time_t ) timeout )
| | switch_channel_get_state ( channel ) > = CS_HANGUP ) {
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
break ;
2006-11-09 05:39:04 +00:00
}
2007-03-29 22:31:56 +00:00
if ( switch_channel_ready ( channel )
& & ( switch_channel_test_flag ( channel , CF_ANSWERED ) | | switch_channel_test_flag ( channel , CF_EARLY_MEDIA ) ) ) {
* rval = BOOLEAN_TO_JSVAL ( JS_TRUE ) ;
2006-03-01 22:55:28 +00:00
break ;
}
2007-03-29 22:31:56 +00:00
2006-03-01 22:55:28 +00:00
switch_yield ( 1000 ) ;
}
2007-03-29 22:31:56 +00:00
2006-11-09 05:39:04 +00:00
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
static JSBool session_wait_for_answer ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-11-09 05:39:04 +00:00
{
struct js_session * jss = JS_GetPrivate ( cx , obj ) ;
switch_channel_t * channel ;
switch_time_t started ;
unsigned int elapsed ;
int32 timeout = 60 ;
2006-12-14 01:23:03 +00:00
2007-03-27 00:40:53 +00:00
if ( ! jss | | ! jss - > session ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " You must call the session.originate method before calling this method! \n " ) ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2007-03-27 00:40:53 +00:00
return JS_TRUE ;
}
2006-11-09 05:39:04 +00:00
channel = switch_core_session_get_channel ( jss - > session ) ;
assert ( channel ! = NULL ) ;
2006-12-14 01:23:03 +00:00
2006-11-09 05:39:04 +00:00
started = switch_time_now ( ) ;
if ( argc > 0 ) {
JS_ValueToInt32 ( cx , argv [ 0 ] , & timeout ) ;
}
2007-03-29 22:31:56 +00:00
for ( ; ; ) {
if ( ( ( elapsed = ( unsigned int ) ( ( switch_time_now ( ) - started ) / 1000 ) ) > ( switch_time_t ) timeout )
| | switch_channel_get_state ( channel ) > = CS_HANGUP ) {
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
break ;
2006-11-09 05:39:04 +00:00
}
2006-03-01 22:55:28 +00:00
2006-11-09 05:39:04 +00:00
if ( switch_channel_ready ( channel ) & & switch_channel_test_flag ( channel , CF_ANSWERED ) ) {
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_TRUE ) ;
2006-11-09 05:39:04 +00:00
break ;
}
2007-03-29 22:31:56 +00:00
2006-11-09 05:39:04 +00:00
switch_yield ( 1000 ) ;
}
2007-03-29 22:31:56 +00:00
2006-03-01 22:55:28 +00:00
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
static JSBool session_execute ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-03-07 15:24:57 +00:00
{
JSBool retval = JS_FALSE ;
2006-12-14 01:23:03 +00:00
switch_channel_t * channel ;
2007-03-29 22:31:56 +00:00
struct js_session * jss = JS_GetPrivate ( cx , obj ) ;
2006-12-14 01:23:03 +00:00
2007-03-27 00:40:53 +00:00
if ( ! jss | | ! jss - > session ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " You must call the session.originate method before calling this method! \n " ) ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2007-03-27 00:40:53 +00:00
return JS_TRUE ;
}
2006-12-14 01:23:03 +00:00
channel = switch_core_session_get_channel ( jss - > session ) ;
2007-03-29 22:31:56 +00:00
assert ( channel ! = NULL ) ;
2006-12-14 01:23:03 +00:00
2007-03-29 22:31:56 +00:00
if ( ! switch_channel_ready ( channel ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Session is not active! \n " ) ;
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
return JS_TRUE ;
}
2006-12-14 01:23:03 +00:00
2006-03-07 15:24:57 +00:00
if ( argc > 1 ) {
2006-04-29 23:43:28 +00:00
const switch_application_interface_t * application_interface ;
2006-03-07 15:24:57 +00:00
char * app_name = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 0 ] ) ) ;
char * app_arg = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 1 ] ) ) ;
struct js_session * jss = JS_GetPrivate ( cx , obj ) ;
2006-12-02 05:40:58 +00:00
jsrefcount saveDepth ;
2006-03-07 15:24:57 +00:00
2007-03-27 00:40:53 +00:00
if ( ! jss | | ! jss - > session ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " You must call the session.originate method before calling this method! \n " ) ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2007-03-27 00:40:53 +00:00
return JS_TRUE ;
}
2006-03-07 15:24:57 +00:00
if ( ( application_interface = switch_loadable_module_get_application_interface ( app_name ) ) ) {
if ( application_interface - > application_function ) {
2006-12-02 05:40:58 +00:00
saveDepth = JS_SuspendRequest ( cx ) ;
2007-04-21 01:03:58 +00:00
switch_core_session_exec ( jss - > session , application_interface , app_arg ) ;
2006-12-02 05:40:58 +00:00
JS_ResumeRequest ( cx , saveDepth ) ;
2006-03-07 15:24:57 +00:00
retval = JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
}
2006-03-07 15:24:57 +00:00
}
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( retval ) ;
2006-03-07 15:24:57 +00:00
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
static JSBool session_get_event ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-08-18 01:28:50 +00:00
{
struct js_session * jss = JS_GetPrivate ( cx , obj ) ;
switch_event_t * event ;
2006-12-14 01:23:03 +00:00
2007-03-27 00:40:53 +00:00
if ( ! jss | | ! jss - > session ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " You must call the session.originate method before calling this method! \n " ) ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2007-03-27 00:40:53 +00:00
return JS_TRUE ;
}
2006-08-18 01:28:50 +00:00
if ( switch_core_session_dequeue_event ( jss - > session , & event ) = = SWITCH_STATUS_SUCCESS ) {
JSObject * Event ;
2006-11-09 05:39:04 +00:00
struct event_obj * eo ;
2007-03-29 22:31:56 +00:00
2006-11-09 05:39:04 +00:00
if ( ( eo = malloc ( sizeof ( * eo ) ) ) ) {
eo - > event = event ;
eo - > freed = 0 ;
if ( ( Event = JS_DefineObject ( cx , obj , " __event__ " , & event_class , NULL , 0 ) ) ) {
2007-03-30 00:13:31 +00:00
if ( ( JS_SetPrivate ( cx , Event , eo ) & & JS_DefineProperties ( cx , Event , event_props ) & & JS_DefineFunctions ( cx , Event , event_methods ) ) ) {
2007-03-29 22:31:56 +00:00
* rval = OBJECT_TO_JSVAL ( Event ) ;
2006-11-09 05:39:04 +00:00
return JS_TRUE ;
}
2006-08-18 01:28:50 +00:00
}
}
}
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
return JS_TRUE ;
2006-08-18 01:28:50 +00:00
}
2007-03-29 22:31:56 +00:00
static JSBool session_send_event ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-08-18 01:28:50 +00:00
{
struct js_session * jss = JS_GetPrivate ( cx , obj ) ;
JSObject * Event ;
2006-11-09 05:39:04 +00:00
struct event_obj * eo ;
2006-08-18 01:28:50 +00:00
2007-03-27 00:40:53 +00:00
if ( ! jss | | ! jss - > session ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " You must call the session.originate method before calling this method! \n " ) ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2007-03-27 00:40:53 +00:00
return JS_TRUE ;
}
2006-08-18 01:28:50 +00:00
if ( argc > 0 ) {
if ( JS_ValueToObject ( cx , argv [ 0 ] , & Event ) ) {
2006-11-09 05:39:04 +00:00
if ( ( eo = JS_GetPrivate ( cx , Event ) ) ) {
if ( switch_core_session_receive_event ( jss - > session , & eo - > event ) ! = SWITCH_STATUS_SUCCESS ) {
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-08-18 01:28:50 +00:00
return JS_TRUE ;
}
JS_SetPrivate ( cx , Event , NULL ) ;
}
}
}
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_TRUE ) ;
return JS_TRUE ;
2006-08-18 01:28:50 +00:00
}
2006-03-07 15:24:57 +00:00
2007-03-29 22:31:56 +00:00
static JSBool session_hangup ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-03-01 22:55:28 +00:00
{
struct js_session * jss = JS_GetPrivate ( cx , obj ) ;
2006-04-29 06:05:03 +00:00
switch_channel_t * channel ;
2006-05-12 15:33:49 +00:00
char * cause_name = NULL ;
switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING ;
2007-03-27 00:40:53 +00:00
if ( ! jss | | ! jss - > session ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " You must call the session.originate method before calling this method! \n " ) ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2007-03-27 00:40:53 +00:00
return JS_TRUE ;
}
2006-12-14 01:23:03 +00:00
channel = switch_core_session_get_channel ( jss - > session ) ;
assert ( channel ! = NULL ) ;
2007-03-29 22:31:56 +00:00
if ( ! switch_channel_ready ( channel ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Session is not active! \n " ) ;
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
return JS_TRUE ;
}
2006-12-14 01:23:03 +00:00
2006-05-12 15:33:49 +00:00
if ( argc > 1 ) {
cause_name = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 0 ] ) ) ;
cause = switch_channel_str2cause ( cause_name ) ;
}
2006-03-01 22:55:28 +00:00
2006-05-12 15:33:49 +00:00
switch_channel_hangup ( channel , cause ) ;
2006-03-01 22:55:28 +00:00
switch_core_session_kill_channel ( jss - > session , SWITCH_SIG_KILL ) ;
return JS_TRUE ;
}
2006-03-01 00:58:32 +00:00
# ifdef HAVE_CURL
struct config_data {
JSContext * cx ;
JSObject * obj ;
char * name ;
2006-03-07 15:47:34 +00:00
int fd ;
2006-03-01 00:58:32 +00:00
} ;
2006-03-07 15:47:34 +00:00
static size_t hash_callback ( void * ptr , size_t size , size_t nmemb , void * data )
2006-03-01 00:58:32 +00:00
{
2006-03-02 14:52:51 +00:00
register size_t realsize = size * nmemb ;
2006-03-01 00:58:32 +00:00
char * line , lineb [ 2048 ] , * nextline = NULL , * val = NULL , * p = NULL ;
jsval rval ;
struct config_data * config_data = data ;
char code [ 256 ] ;
if ( config_data - > name ) {
switch_copy_string ( lineb , ( char * ) ptr , sizeof ( lineb ) ) ;
line = lineb ;
while ( line ) {
if ( ( nextline = strchr ( line , ' \n ' ) ) ) {
* nextline = ' \0 ' ;
nextline + + ;
}
2007-03-29 22:31:56 +00:00
2006-03-01 00:58:32 +00:00
if ( ( val = strchr ( line , ' = ' ) ) ) {
2006-03-02 14:52:51 +00:00
* val = ' \0 ' ;
val + + ;
if ( val [ 0 ] = = ' > ' ) {
* val = ' \0 ' ;
val + + ;
}
2007-03-29 22:31:56 +00:00
2006-03-02 14:52:51 +00:00
for ( p = line ; p & & * p = = ' ' ; p + + ) ;
line = p ;
2007-03-29 22:31:56 +00:00
for ( p = line + strlen ( line ) - 1 ; * p = = ' ' ; p - - )
2006-03-02 14:52:51 +00:00
* p = ' \0 ' ;
for ( p = val ; p & & * p = = ' ' ; p + + ) ;
val = p ;
2007-03-29 22:31:56 +00:00
for ( p = val + strlen ( val ) - 1 ; * p = = ' ' ; p - - )
2006-03-02 14:52:51 +00:00
* p = ' \0 ' ;
2006-03-01 00:58:32 +00:00
snprintf ( code , sizeof ( code ) , " ~%s[ \" %s \" ] = \" %s \" " , config_data - > name , line , val ) ;
eval_some_js ( code , config_data - > cx , config_data - > obj , & rval ) ;
2006-03-02 14:52:51 +00:00
}
2006-03-01 00:58:32 +00:00
line = nextline ;
}
2007-03-29 22:31:56 +00:00
}
2006-03-01 00:58:32 +00:00
return realsize ;
}
2006-03-07 15:47:34 +00:00
static size_t file_callback ( void * ptr , size_t size , size_t nmemb , void * data )
{
2007-03-29 22:31:56 +00:00
register unsigned int realsize = ( unsigned int ) ( size * nmemb ) ;
2006-03-07 15:47:34 +00:00
struct config_data * config_data = data ;
write ( config_data - > fd , ptr , realsize ) ;
return realsize ;
}
2007-03-29 22:31:56 +00:00
static JSBool js_fetchurl_hash ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-03-01 00:58:32 +00:00
{
char * url = NULL , * name = NULL ;
CURL * curl_handle = NULL ;
struct config_data config_data ;
2007-03-29 22:31:56 +00:00
if ( argc > 1 ) {
2006-03-07 15:47:34 +00:00
url = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 0 ] ) ) ;
name = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 1 ] ) ) ;
2006-05-12 15:33:49 +00:00
2006-03-01 00:58:32 +00:00
curl_handle = curl_easy_init ( ) ;
if ( ! strncasecmp ( url , " https " , 5 ) ) {
curl_easy_setopt ( curl_handle , CURLOPT_SSL_VERIFYPEER , 0 ) ;
curl_easy_setopt ( curl_handle , CURLOPT_SSL_VERIFYHOST , 0 ) ;
}
config_data . cx = cx ;
config_data . obj = obj ;
2006-03-07 15:47:34 +00:00
if ( name ) {
2006-03-01 00:58:32 +00:00
config_data . name = name ;
2006-03-07 15:47:34 +00:00
}
2006-03-01 00:58:32 +00:00
curl_easy_setopt ( curl_handle , CURLOPT_URL , url ) ;
2006-03-07 15:47:34 +00:00
curl_easy_setopt ( curl_handle , CURLOPT_WRITEFUNCTION , hash_callback ) ;
2007-03-29 22:31:56 +00:00
curl_easy_setopt ( curl_handle , CURLOPT_WRITEDATA , ( void * ) & config_data ) ;
2006-03-07 15:47:34 +00:00
curl_easy_setopt ( curl_handle , CURLOPT_USERAGENT , " freeswitch-js/1.0 " ) ;
2006-03-01 00:58:32 +00:00
curl_easy_perform ( curl_handle ) ;
curl_easy_cleanup ( curl_handle ) ;
2006-03-02 14:52:51 +00:00
} else {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error! \n " ) ;
2006-03-01 00:58:32 +00:00
return JS_FALSE ;
}
return JS_TRUE ;
}
2006-03-07 15:47:34 +00:00
2007-03-29 22:31:56 +00:00
static JSBool js_fetchurl_file ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-03-07 15:47:34 +00:00
{
char * url = NULL , * filename = NULL ;
CURL * curl_handle = NULL ;
struct config_data config_data ;
2007-03-29 22:31:56 +00:00
if ( argc > 1 ) {
2006-03-07 15:47:34 +00:00
url = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 0 ] ) ) ;
filename = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 1 ] ) ) ;
curl_global_init ( CURL_GLOBAL_ALL ) ;
curl_handle = curl_easy_init ( ) ;
if ( ! strncasecmp ( url , " https " , 5 ) ) {
curl_easy_setopt ( curl_handle , CURLOPT_SSL_VERIFYPEER , 0 ) ;
curl_easy_setopt ( curl_handle , CURLOPT_SSL_VERIFYHOST , 0 ) ;
}
config_data . cx = cx ;
config_data . obj = obj ;
config_data . name = filename ;
if ( ( config_data . fd = open ( filename , O_CREAT | O_RDWR | O_TRUNC ) ) > - 1 ) {
curl_easy_setopt ( curl_handle , CURLOPT_URL , url ) ;
curl_easy_setopt ( curl_handle , CURLOPT_WRITEFUNCTION , file_callback ) ;
2007-03-29 22:31:56 +00:00
curl_easy_setopt ( curl_handle , CURLOPT_WRITEDATA , ( void * ) & config_data ) ;
2006-03-07 15:47:34 +00:00
curl_easy_setopt ( curl_handle , CURLOPT_USERAGENT , " freeswitch-js/1.0 " ) ;
curl_easy_perform ( curl_handle ) ;
curl_easy_cleanup ( curl_handle ) ;
close ( config_data . fd ) ;
} else {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error! \n " ) ;
2006-03-07 15:47:34 +00:00
}
} else {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error! \n " ) ;
2006-03-07 15:47:34 +00:00
}
return JS_TRUE ;
}
2006-03-01 00:58:32 +00:00
# endif
2006-08-18 01:28:50 +00:00
2006-02-28 21:21:48 +00:00
/* Session Object */
/*********************************************************************************/
enum session_tinyid {
2006-03-02 14:52:51 +00:00
SESSION_NAME , SESSION_STATE ,
2007-03-29 22:31:56 +00:00
PROFILE_DIALPLAN , PROFILE_CID_NAME , PROFILE_CID_NUM , PROFILE_IP , PROFILE_ANI , PROFILE_ANI_II , PROFILE_DEST ,
SESSION_UUID , SESSION_CAUSE
2006-02-26 23:10:22 +00:00
} ;
2006-02-28 21:21:48 +00:00
static JSFunctionSpec session_methods [ ] = {
2007-03-29 22:31:56 +00:00
{ " originate " , session_originate , 2 } ,
{ " setHangupHook " , session_hanguphook , 1 } ,
{ " setAutoHangup " , session_autohangup , 1 } ,
{ " sayPhrase " , session_sayphrase , 1 } ,
{ " streamFile " , session_streamfile , 1 } ,
{ " collectInput " , session_collect_input , 1 } ,
{ " recordFile " , session_recordfile , 1 } ,
{ " flushEvents " , session_flush_events , 1 } ,
{ " flushDigits " , session_flush_digits , 1 } ,
{ " speak " , session_speak , 1 } ,
{ " setVariable " , session_set_variable , 1 } ,
{ " getVariable " , session_get_variable , 1 } ,
2006-03-02 14:52:51 +00:00
{ " getDigits " , session_get_digits , 1 } ,
2007-03-29 22:31:56 +00:00
{ " answer " , session_answer , 0 } ,
{ " generateXmlCdr " , session_cdr , 0 } ,
{ " ready " , session_ready , 0 } ,
{ " waitForAnswer " , session_wait_for_answer , 0 } ,
{ " waitForMedia " , session_wait_for_media , 0 } ,
2006-08-18 01:28:50 +00:00
{ " getEvent " , session_get_event , 0 } ,
{ " sendEvent " , session_send_event , 0 } ,
2007-03-29 22:31:56 +00:00
{ " hangup " , session_hangup , 0 } ,
{ " execute " , session_execute , 0 } ,
2006-02-26 23:10:22 +00:00
{ 0 }
} ;
2006-02-28 21:21:48 +00:00
static JSPropertySpec session_props [ ] = {
2007-03-29 22:31:56 +00:00
{ " 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 } ,
{ " aniii " , PROFILE_ANI_II , JSPROP_READONLY | JSPROP_PERMANENT } ,
{ " destination " , PROFILE_DEST , JSPROP_READONLY | JSPROP_PERMANENT } ,
{ " uuid " , SESSION_UUID , JSPROP_READONLY | JSPROP_PERMANENT } ,
{ " cause " , SESSION_CAUSE , JSPROP_READONLY | JSPROP_PERMANENT } ,
2006-03-02 14:52:51 +00:00
{ 0 }
2006-02-26 23:10:22 +00:00
} ;
2007-03-29 22:31:56 +00:00
static JSBool session_getProperty ( JSContext * cx , JSObject * obj , jsval id , jsval * vp )
2006-02-26 23:10:22 +00:00
{
2006-02-28 02:08:42 +00:00
struct js_session * jss = JS_GetPrivate ( cx , obj ) ;
2006-02-26 23:10:22 +00:00
int param = 0 ;
2007-03-27 00:40:53 +00:00
switch_channel_t * channel = NULL ;
switch_caller_profile_t * caller_profile = NULL ;
char * name = NULL ;
2006-02-26 23:10:22 +00:00
2007-03-27 00:40:53 +00:00
if ( jss & & jss - > session ) {
channel = switch_core_session_get_channel ( jss - > session ) ;
assert ( channel ! = NULL ) ;
caller_profile = switch_channel_get_caller_profile ( channel ) ;
}
2006-03-01 22:55:28 +00:00
2006-02-27 04:01:38 +00:00
name = JS_GetStringBytes ( JS_ValueToString ( cx , id ) ) ;
2007-03-27 00:40:53 +00:00
2006-02-26 23:10:22 +00:00
/* numbers are our props anything else is a method */
if ( name [ 0 ] > = 48 & & name [ 0 ] < = 57 ) {
param = atoi ( name ) ;
} else {
return JS_TRUE ;
}
2007-03-27 00:40:53 +00:00
if ( ! channel ) {
2007-03-29 22:31:56 +00:00
switch ( param ) {
2007-03-27 00:40:53 +00:00
case SESSION_CAUSE :
2007-03-29 22:31:56 +00:00
* vp = STRING_TO_JSVAL ( JS_NewStringCopyZ ( cx , switch_channel_cause2str ( jss - > cause ) ) ) ;
2007-03-27 00:40:53 +00:00
break ;
default :
* vp = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
}
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
switch ( param ) {
2007-03-27 00:40:53 +00:00
case SESSION_CAUSE :
2007-03-29 22:31:56 +00:00
* vp = STRING_TO_JSVAL ( JS_NewStringCopyZ ( cx , switch_channel_cause2str ( switch_channel_get_cause ( channel ) ) ) ) ;
2007-03-27 00:40:53 +00:00
break ;
2006-02-28 21:21:48 +00:00
case SESSION_NAME :
2006-02-26 23:10:22 +00:00
* vp = STRING_TO_JSVAL ( JS_NewStringCopyZ ( cx , switch_channel_get_name ( channel ) ) ) ;
break ;
2006-12-22 19:25:38 +00:00
case SESSION_UUID :
* vp = STRING_TO_JSVAL ( JS_NewStringCopyZ ( cx , switch_channel_get_uuid ( channel ) ) ) ;
break ;
2006-02-28 21:21:48 +00:00
case SESSION_STATE :
2006-03-01 22:55:28 +00:00
* 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 ;
2006-10-17 23:33:32 +00:00
case PROFILE_ANI_II :
2006-03-01 22:55:28 +00:00
if ( caller_profile ) {
2006-10-17 23:33:32 +00:00
* vp = STRING_TO_JSVAL ( JS_NewStringCopyZ ( cx , caller_profile - > aniii ) ) ;
2006-03-01 22:55:28 +00:00
}
break ;
case PROFILE_DEST :
if ( caller_profile ) {
* vp = STRING_TO_JSVAL ( JS_NewStringCopyZ ( cx , caller_profile - > destination_number ) ) ;
}
2006-02-26 23:10:22 +00:00
break ;
default :
2007-03-27 00:40:53 +00:00
* vp = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-02-26 23:10:22 +00:00
break ;
2007-03-29 22:31:56 +00:00
2006-02-26 23:10:22 +00:00
}
2007-03-27 00:40:53 +00:00
return JS_TRUE ;
2006-02-26 23:10:22 +00:00
}
2006-02-28 02:08:42 +00:00
JSClass session_class = {
2007-03-29 22:31:56 +00:00
" Session " , JSCLASS_HAS_PRIVATE ,
JS_PropertyStub , JS_PropertyStub , session_getProperty , JS_PropertyStub ,
JS_EnumerateStub , JS_ResolveStub , JS_ConvertStub , session_destroy , NULL , NULL , NULL ,
2006-03-01 22:55:28 +00:00
session_construct
2006-02-26 23:10:22 +00:00
} ;
2007-03-30 00:13:31 +00:00
static JSObject * new_js_session ( JSContext * cx , JSObject * obj , switch_core_session_t * session , struct js_session * jss , char * name , int flags )
2006-02-28 21:21:48 +00:00
{
JSObject * session_obj ;
if ( ( session_obj = JS_DefineObject ( cx , obj , name , & session_class , NULL , 0 ) ) ) {
memset ( jss , 0 , sizeof ( struct js_session ) ) ;
jss - > session = session ;
jss - > flags = flags ;
jss - > cx = cx ;
2007-03-27 00:40:53 +00:00
jss - > obj = session_obj ;
2007-04-26 23:09:26 +00:00
jss - > stack_depth = 0 ;
2006-02-28 21:21:48 +00:00
if ( ( JS_SetPrivate ( cx , session_obj , jss ) & &
2007-03-30 00:13:31 +00:00
JS_DefineProperties ( cx , session_obj , session_props ) & & JS_DefineFunctions ( cx , session_obj , session_methods ) ) ) {
2006-02-28 21:21:48 +00:00
return session_obj ;
}
}
2007-03-29 22:31:56 +00:00
2006-02-28 21:21:48 +00:00
return NULL ;
}
2006-03-01 22:55:28 +00:00
/* Session Object */
/*********************************************************************************/
2007-03-27 00:40:53 +00:00
2007-03-29 22:31:56 +00:00
static JSBool session_construct ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-03-01 22:55:28 +00:00
{
2007-03-27 00:40:53 +00:00
struct js_session * jss = NULL ;
assert ( ( jss = malloc ( sizeof ( * jss ) ) ) ) ;
memset ( jss , 0 , sizeof ( * jss ) ) ;
jss - > cx = cx ;
jss - > obj = obj ;
switch_set_flag ( jss , S_FREE ) ;
JS_SetPrivate ( cx , obj , jss ) ;
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
static JSBool session_originate ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2007-03-27 00:40:53 +00:00
{
struct js_session * jss = NULL ;
2006-04-29 01:00:52 +00:00
switch_memory_pool_t * pool = NULL ;
2007-03-27 00:40:53 +00:00
jss = JS_GetPrivate ( cx , obj ) ;
jss - > cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ;
2006-08-21 19:14:51 +00:00
if ( argc > 1 ) {
2006-03-01 22:55:28 +00:00
JSObject * session_obj ;
2006-04-29 06:05:03 +00:00
switch_core_session_t * session = NULL , * peer_session = NULL ;
2007-03-27 00:40:53 +00:00
switch_caller_profile_t * caller_profile = NULL , * orig_caller_profile = NULL ;
2006-03-01 22:55:28 +00:00
char * dest = NULL ;
char * dialplan = NULL ;
char * cid_name = " " ;
char * cid_num = " " ;
char * network_addr = " " ;
char * ani = " " ;
2006-10-17 23:33:32 +00:00
char * aniii = " " ;
2006-04-21 22:31:08 +00:00
char * rdnis = " " ;
2006-04-28 19:46:57 +00:00
char * context = " " ;
2006-05-26 16:00:08 +00:00
char * username = NULL ;
2006-08-21 19:14:51 +00:00
char * to = NULL ;
2007-03-27 00:40:53 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-03-23 19:22:06 +00:00
2006-03-01 22:55:28 +00:00
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 ;
2007-03-27 00:40:53 +00:00
orig_caller_profile = switch_channel_get_caller_profile ( switch_core_session_get_channel ( session ) ) ;
dialplan = orig_caller_profile - > dialplan ;
cid_name = orig_caller_profile - > caller_id_name ;
cid_num = orig_caller_profile - > caller_id_number ;
ani = orig_caller_profile - > ani ;
aniii = orig_caller_profile - > aniii ;
rdnis = orig_caller_profile - > rdnis ;
context = orig_caller_profile - > context ;
username = orig_caller_profile - > username ;
2006-03-01 22:55:28 +00:00
}
}
2006-08-21 19:14:51 +00:00
dest = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 1 ] ) ) ;
2006-03-01 22:55:28 +00:00
2006-09-03 04:29:42 +00:00
if ( ! strchr ( dest , ' / ' ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Invalid Channel String \n " ) ;
2007-03-27 00:40:53 +00:00
goto done ;
2006-09-03 04:29:42 +00:00
}
2006-08-21 19:14:51 +00:00
if ( argc > 2 ) {
dialplan = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 2 ] ) ) ;
}
2006-03-01 22:55:28 +00:00
if ( argc > 3 ) {
2006-08-21 19:14:51 +00:00
context = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 3 ] ) ) ;
2006-03-01 22:55:28 +00:00
}
if ( argc > 4 ) {
2006-08-21 19:14:51 +00:00
cid_name = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 4 ] ) ) ;
2006-03-01 22:55:28 +00:00
}
if ( argc > 5 ) {
2006-08-21 19:14:51 +00:00
cid_num = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 5 ] ) ) ;
2006-03-01 22:55:28 +00:00
}
if ( argc > 6 ) {
2006-08-21 19:14:51 +00:00
network_addr = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 6 ] ) ) ;
2006-03-01 22:55:28 +00:00
}
if ( argc > 7 ) {
2006-08-21 19:14:51 +00:00
ani = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 7 ] ) ) ;
2006-03-01 22:55:28 +00:00
}
if ( argc > 8 ) {
2006-10-17 23:33:32 +00:00
aniii = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 8 ] ) ) ;
2006-03-01 22:55:28 +00:00
}
2006-04-21 22:31:08 +00:00
if ( argc > 9 ) {
2006-08-21 19:14:51 +00:00
rdnis = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 9 ] ) ) ;
2006-04-21 22:31:08 +00:00
}
2006-04-28 19:46:57 +00:00
if ( argc > 10 ) {
2006-08-21 19:14:51 +00:00
username = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 10 ] ) ) ;
2006-04-28 19:46:57 +00:00
}
2006-05-26 16:00:08 +00:00
if ( argc > 11 ) {
2006-08-21 19:14:51 +00:00
to = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 11 ] ) ) ;
2006-05-26 16:00:08 +00:00
}
2007-03-29 22:31:56 +00:00
2006-03-22 23:55:53 +00:00
if ( switch_core_new_memory_pool ( & pool ) ! = SWITCH_STATUS_SUCCESS ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " OH OH no pool \n " ) ;
2006-03-22 23:55:53 +00:00
return JS_FALSE ;
2006-03-01 22:55:28 +00:00
}
2006-08-21 19:14:51 +00:00
caller_profile = switch_caller_profile_new ( pool ,
2007-03-30 00:15:25 +00:00
username , dialplan , cid_name , cid_num , network_addr , ani , aniii , rdnis , ( char * ) modname , context ,
dest ) ;
2007-03-30 00:13:31 +00:00
if ( switch_ivr_originate ( session , & peer_session , & jss - > cause , dest , to ? atoi ( to ) : 60 , NULL , NULL , NULL , caller_profile ) ! = SWITCH_STATUS_SUCCESS ) {
2006-08-21 19:14:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Cannot Create Outgoing Channel! [%s] \n " , dest ) ;
2007-03-27 00:40:53 +00:00
goto done ;
2006-03-01 22:55:28 +00:00
}
2006-08-21 19:14:51 +00:00
jss - > session = peer_session ;
2007-04-13 22:15:58 +00:00
jss - > flags = S_RDLOCK ;
2007-03-27 00:40:53 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_TRUE ) ;
2006-08-21 19:14:51 +00:00
2006-03-01 22:55:28 +00:00
} else {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Missing Args \n " ) ;
2006-03-01 22:55:28 +00:00
}
2007-03-29 22:31:56 +00:00
done :
2006-03-23 19:22:06 +00:00
return JS_TRUE ;
2006-03-01 22:55:28 +00:00
}
2007-03-27 00:40:53 +00:00
2007-03-29 22:31:56 +00:00
static void session_destroy ( JSContext * cx , JSObject * obj )
2006-03-01 22:55:28 +00:00
{
struct js_session * jss ;
2007-03-27 00:40:53 +00:00
switch_channel_t * channel = NULL ;
2007-03-29 22:31:56 +00:00
2006-03-01 22:55:28 +00:00
if ( cx & & obj ) {
if ( ( jss = JS_GetPrivate ( cx , obj ) ) ) {
2007-03-27 00:40:53 +00:00
if ( jss - > session ) {
channel = switch_core_session_get_channel ( jss - > session ) ;
switch_channel_set_private ( channel , " jss " , NULL ) ;
}
2006-03-01 22:55:28 +00:00
2007-03-27 00:40:53 +00:00
if ( channel & & switch_test_flag ( jss , S_HUP ) ) {
switch_channel_hangup ( channel , SWITCH_CAUSE_NORMAL_CLEARING ) ;
}
2007-04-13 22:15:58 +00:00
if ( jss - > session & & switch_test_flag ( jss , S_RDLOCK ) ) {
switch_core_session_rwunlock ( jss - > session ) ;
}
2007-03-27 00:40:53 +00:00
if ( switch_test_flag ( jss , S_FREE ) ) {
free ( jss ) ;
2006-03-01 22:55:28 +00:00
}
}
}
2007-03-29 22:31:56 +00:00
2006-03-01 22:55:28 +00:00
return ;
}
2006-03-02 17:36:23 +00:00
/* FileIO Object */
/*********************************************************************************/
2007-03-29 22:31:56 +00:00
static JSBool fileio_construct ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-03-02 17:36:23 +00:00
{
2006-04-29 01:00:52 +00:00
switch_memory_pool_t * pool ;
2006-03-02 17:36:23 +00:00
switch_file_t * fd ;
char * path , * flags_str ;
unsigned int flags = 0 ;
struct fileio_obj * fio ;
if ( argc > 1 ) {
path = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 0 ] ) ) ;
flags_str = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 1 ] ) ) ;
2007-03-29 22:31:56 +00:00
2006-03-02 17:36:23 +00:00
if ( strchr ( flags_str , ' r ' ) ) {
flags | = SWITCH_FOPEN_READ ;
}
if ( strchr ( flags_str , ' w ' ) ) {
flags | = SWITCH_FOPEN_WRITE ;
}
if ( strchr ( flags_str , ' c ' ) ) {
flags | = SWITCH_FOPEN_CREATE ;
}
if ( strchr ( flags_str , ' a ' ) ) {
flags | = SWITCH_FOPEN_APPEND ;
}
if ( strchr ( flags_str , ' t ' ) ) {
flags | = SWITCH_FOPEN_TRUNCATE ;
}
if ( strchr ( flags_str , ' b ' ) ) {
flags | = SWITCH_FOPEN_BINARY ;
}
switch_core_new_memory_pool ( & pool ) ;
2007-03-29 22:31:56 +00:00
if ( switch_file_open ( & fd , path , flags , SWITCH_FPROT_UREAD | SWITCH_FPROT_UWRITE , pool ) ! = SWITCH_STATUS_SUCCESS ) {
2006-08-22 17:19:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Cannot Open File: %s \n " , path ) ;
2006-03-02 17:36:23 +00:00
switch_core_destroy_memory_pool ( & pool ) ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-08-22 17:19:31 +00:00
return JS_TRUE ;
2006-03-02 17:36:23 +00:00
}
fio = switch_core_alloc ( pool , sizeof ( * fio ) ) ;
fio - > fd = fd ;
fio - > pool = pool ;
fio - > path = switch_core_strdup ( pool , path ) ;
fio - > flags = flags ;
JS_SetPrivate ( cx , obj , fio ) ;
return JS_TRUE ;
}
2006-08-22 17:19:31 +00:00
return JS_TRUE ;
2006-03-02 17:36:23 +00:00
}
2007-03-29 22:31:56 +00:00
static void fileio_destroy ( JSContext * cx , JSObject * obj )
2006-03-02 17:36:23 +00:00
{
struct fileio_obj * fio = JS_GetPrivate ( cx , obj ) ;
if ( fio ) {
2006-08-21 22:48:01 +00:00
switch_memory_pool_t * pool ;
2007-03-29 22:31:56 +00:00
if ( fio - > fd ) {
2006-08-21 19:14:51 +00:00
switch_file_close ( fio - > fd ) ;
}
2006-08-21 22:48:01 +00:00
pool = fio - > pool ;
2006-03-02 17:36:23 +00:00
switch_core_destroy_memory_pool ( & pool ) ;
pool = NULL ;
}
}
2007-03-29 22:31:56 +00:00
static JSBool fileio_read ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-03-02 17:36:23 +00:00
{
struct fileio_obj * fio = JS_GetPrivate ( cx , obj ) ;
int32 bytes = 0 ;
switch_size_t read = 0 ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2007-03-27 00:40:53 +00:00
if ( ! fio ) {
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-08-22 17:19:31 +00:00
return JS_TRUE ;
}
2006-03-02 17:36:23 +00:00
if ( ! ( fio - > flags & SWITCH_FOPEN_READ ) ) {
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
2006-03-02 17:36:23 +00:00
if ( argc > 0 ) {
JS_ValueToInt32 ( cx , argv [ 0 ] , & bytes ) ;
}
if ( bytes ) {
if ( ! fio - > buf | | fio - > bufsize < bytes ) {
fio - > buf = switch_core_alloc ( fio - > pool , bytes ) ;
fio - > bufsize = bytes ;
}
read = bytes ;
switch_file_read ( fio - > fd , fio - > buf , & read ) ;
fio - > buflen = read ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( ( read > 0 ) ? JS_TRUE : JS_FALSE ) ;
}
2006-03-02 17:36:23 +00:00
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
static JSBool fileio_data ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-03-02 17:36:23 +00:00
{
struct fileio_obj * fio = JS_GetPrivate ( cx , obj ) ;
2006-08-22 17:19:31 +00:00
if ( ! fio ) {
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-08-22 17:19:31 +00:00
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
* rval = STRING_TO_JSVAL ( JS_NewStringCopyZ ( cx , fio - > buf ) ) ;
2006-03-02 17:36:23 +00:00
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
static JSBool fileio_write ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-03-02 17:36:23 +00:00
{
struct fileio_obj * fio = JS_GetPrivate ( cx , obj ) ;
switch_size_t wrote = 0 ;
char * data = NULL ;
2006-08-22 17:19:31 +00:00
if ( ! fio ) {
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-08-22 17:19:31 +00:00
return JS_TRUE ;
}
2006-03-02 17:36:23 +00:00
if ( ! ( fio - > flags & SWITCH_FOPEN_WRITE ) ) {
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-03-02 17:36:23 +00:00
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
2006-03-02 17:36:23 +00:00
if ( argc > 0 ) {
data = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 0 ] ) ) ;
}
if ( data ) {
2006-08-22 00:03:47 +00:00
wrote = strlen ( data ) ;
2007-03-30 00:13:31 +00:00
* rval = BOOLEAN_TO_JSVAL ( ( switch_file_write ( fio - > fd , data , & wrote ) = = SWITCH_STATUS_SUCCESS ) ? JS_TRUE : JS_FALSE ) ;
2006-03-02 17:36:23 +00:00
}
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-03-02 17:36:23 +00:00
return JS_TRUE ;
}
enum fileio_tinyid {
2006-08-22 17:19:31 +00:00
FILEIO_PATH , FILEIO_OPEN
2006-03-02 17:36:23 +00:00
} ;
static JSFunctionSpec fileio_methods [ ] = {
{ " read " , fileio_read , 1 } ,
{ " write " , fileio_write , 1 } ,
{ " data " , fileio_data , 0 } ,
{ 0 }
} ;
static JSPropertySpec fileio_props [ ] = {
2007-03-29 22:31:56 +00:00
{ " path " , FILEIO_PATH , JSPROP_READONLY | JSPROP_PERMANENT } ,
{ " open " , FILEIO_OPEN , JSPROP_READONLY | JSPROP_PERMANENT } ,
2006-03-02 17:36:23 +00:00
{ 0 }
} ;
2007-03-29 22:31:56 +00:00
static JSBool fileio_getProperty ( JSContext * cx , JSObject * obj , jsval id , jsval * vp )
2006-03-02 17:36:23 +00:00
{
JSBool res = JS_TRUE ;
struct fileio_obj * fio = JS_GetPrivate ( cx , obj ) ;
char * name ;
int param = 0 ;
2007-03-29 22:31:56 +00:00
2006-03-02 17:36:23 +00:00
name = JS_GetStringBytes ( JS_ValueToString ( cx , id ) ) ;
2007-03-29 22:31:56 +00:00
/* numbers are our props anything else is a method */
if ( name [ 0 ] > = 48 & & name [ 0 ] < = 57 ) {
param = atoi ( name ) ;
} else {
return JS_TRUE ;
}
switch ( param ) {
2006-03-02 17:36:23 +00:00
case FILEIO_PATH :
2006-08-22 17:19:31 +00:00
if ( fio ) {
* vp = STRING_TO_JSVAL ( JS_NewStringCopyZ ( cx , fio - > path ) ) ;
} else {
2007-03-29 22:31:56 +00:00
* vp = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-08-22 17:19:31 +00:00
}
break ;
case FILEIO_OPEN :
2007-03-29 22:31:56 +00:00
* vp = BOOLEAN_TO_JSVAL ( fio ? JS_TRUE : JS_FALSE ) ;
2006-03-02 17:36:23 +00:00
break ;
}
return res ;
}
JSClass fileio_class = {
2007-03-29 22:31:56 +00:00
" FileIO " , JSCLASS_HAS_PRIVATE ,
JS_PropertyStub , JS_PropertyStub , fileio_getProperty , JS_PropertyStub ,
JS_EnumerateStub , JS_ResolveStub , JS_ConvertStub , fileio_destroy , NULL , NULL , NULL ,
2006-03-02 17:36:23 +00:00
fileio_construct
} ;
2006-02-28 21:21:48 +00:00
/* Built-In*/
/*********************************************************************************/
2007-03-29 22:31:56 +00:00
static JSBool js_exit ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-08-22 17:19:31 +00:00
{
return JS_FALSE ;
}
2007-03-29 22:31:56 +00:00
static JSBool js_log ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-02-26 23:10:22 +00:00
{
2006-07-12 21:23:22 +00:00
char * level_str , * msg ;
switch_log_level_t level = SWITCH_LOG_DEBUG ;
2006-11-09 05:39:04 +00:00
JSScript * script = NULL ;
const char * file = __FILE__ ;
int line = __LINE__ ;
JSStackFrame * caller ;
2007-03-29 22:31:56 +00:00
2006-11-09 05:39:04 +00:00
caller = JS_GetScriptedCaller ( cx , NULL ) ;
script = JS_GetFrameScript ( cx , caller ) ;
if ( script ) {
file = JS_GetScriptFilename ( cx , script ) ;
line = JS_GetScriptBaseLineNumber ( cx , script ) ;
2007-03-29 22:31:56 +00:00
}
2006-11-09 05:39:04 +00:00
2006-07-12 21:23:22 +00:00
if ( argc > 1 ) {
if ( ( level_str = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 0 ] ) ) ) ) {
level = switch_log_str2level ( level_str ) ;
}
2006-02-26 23:10:22 +00:00
2006-07-12 21:23:22 +00:00
if ( ( msg = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 1 ] ) ) ) ) {
2007-02-13 20:59:17 +00:00
switch_log_printf ( SWITCH_CHANNEL_ID_LOG , file , " console_log " , line , level , " %s " , msg ) ;
2006-07-12 21:23:22 +00:00
return JS_TRUE ;
2007-03-29 22:31:56 +00:00
}
2006-07-12 21:23:22 +00:00
} else if ( argc > 0 ) {
if ( ( msg = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 0 ] ) ) ) ) {
2007-02-13 20:59:17 +00:00
switch_log_printf ( SWITCH_CHANNEL_ID_LOG , file , " console_log " , line , level , " %s " , msg ) ;
2006-07-12 21:23:22 +00:00
return JS_TRUE ;
}
}
2006-02-26 23:10:22 +00:00
return JS_FALSE ;
}
2007-03-29 22:31:56 +00:00
static JSBool js_include ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-03-01 00:58:32 +00:00
{
char * code ;
2007-03-29 22:31:56 +00:00
if ( argc > 0 & & ( code = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 0 ] ) ) ) ) {
2007-03-07 22:17:02 +00:00
if ( eval_some_js ( code , cx , obj , rval ) < 0 ) {
return JS_FALSE ;
}
2006-03-01 00:58:32 +00:00
return JS_TRUE ;
}
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Invalid Arguements \n " ) ;
2006-03-01 00:58:32 +00:00
return JS_FALSE ;
}
2007-03-29 22:31:56 +00:00
static JSBool js_api_use ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-11-10 21:49:57 +00:00
{
char * mod_name = NULL ;
if ( argc > 0 & & ( mod_name = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 0 ] ) ) ) ) {
const sm_module_interface_t * mp ;
if ( ( mp = switch_core_hash_find ( module_manager . load_hash , mod_name ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Loading %s \n " , mod_name ) ;
mp - > spidermonkey_load ( cx , obj ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error loading %s \n " , mod_name ) ;
}
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Invalid Filename \n " ) ;
}
return JS_TRUE ;
2007-03-29 22:31:56 +00:00
2006-11-10 21:49:57 +00:00
}
2007-03-29 22:31:56 +00:00
static JSBool js_api_execute ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-03-07 02:06:40 +00:00
{
if ( argc > 1 ) {
char * cmd = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 0 ] ) ) ;
char * arg = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 1 ] ) ) ;
2006-07-26 20:12:49 +00:00
switch_core_session_t * session = NULL ;
2007-03-29 22:31:56 +00:00
switch_stream_handle_t stream = { 0 } ;
2006-08-01 04:45:22 +00:00
char retbuf [ 2048 ] = " " ;
2006-07-26 20:12:49 +00:00
if ( argc > 2 ) {
JSObject * session_obj ;
struct js_session * jss ;
if ( JS_ValueToObject ( cx , argv [ 2 ] , & session_obj ) ) {
if ( ( jss = JS_GetPrivate ( cx , session_obj ) ) ) {
session = jss - > session ;
}
}
}
2007-03-29 22:31:56 +00:00
2006-05-10 15:47:54 +00:00
stream . data = retbuf ;
stream . end = stream . data ;
stream . data_size = sizeof ( retbuf ) ;
2006-07-12 18:39:19 +00:00
stream . write_function = switch_console_stream_write ;
2007-02-23 22:43:11 +00:00
switch_api_execute ( cmd , arg , session , & stream ) ;
2006-07-12 18:39:19 +00:00
2007-03-29 22:31:56 +00:00
* rval = STRING_TO_JSVAL ( JS_NewStringCopyZ ( cx , retbuf ) ) ;
2006-03-07 02:06:40 +00:00
} else {
2007-03-29 22:31:56 +00:00
* rval = STRING_TO_JSVAL ( JS_NewStringCopyZ ( cx , " " ) ) ;
2006-03-07 02:06:40 +00:00
}
return JS_TRUE ;
}
2007-03-29 22:31:56 +00:00
static JSBool js_bridge ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-03-01 22:55:28 +00:00
{
struct js_session * jss_a = NULL , * jss_b = NULL ;
JSObject * session_obj_a = NULL , * session_obj_b = NULL ;
2006-11-09 05:39:04 +00:00
void * bp = NULL ;
int len = 0 ;
switch_input_callback_function_t dtmf_func = NULL ;
2007-03-29 22:31:56 +00:00
struct input_callback_state cb_state = { 0 } ;
2006-11-09 05:39:04 +00:00
JSFunction * function ;
2006-03-01 22:55:28 +00:00
if ( argc > 1 ) {
if ( JS_ValueToObject ( cx , argv [ 0 ] , & session_obj_a ) ) {
if ( ! ( jss_a = JS_GetPrivate ( cx , session_obj_a ) ) ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Cannot Find Session [1] \n " ) ;
2006-03-01 22:55:28 +00:00
return JS_FALSE ;
}
2007-03-29 22:31:56 +00:00
}
2006-03-01 22:55:28 +00:00
if ( JS_ValueToObject ( cx , argv [ 1 ] , & session_obj_b ) ) {
if ( ! ( jss_b = JS_GetPrivate ( cx , session_obj_b ) ) ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Cannot Find Session [1] \n " ) ;
2006-03-01 22:55:28 +00:00
return JS_FALSE ;
}
2007-03-29 22:31:56 +00:00
}
2006-03-01 22:55:28 +00:00
}
2007-03-29 22:31:56 +00:00
2006-03-01 22:55:28 +00:00
if ( ! ( jss_a & & jss_b ) ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Failure! %s %s \n " , jss_a ? " y " : " n " , jss_b ? " y " : " n " ) ;
2006-03-01 22:55:28 +00:00
return JS_FALSE ;
}
2006-11-09 05:39:04 +00:00
if ( argc > 2 ) {
if ( ( function = JS_ValueToFunction ( cx , argv [ 2 ] ) ) ) {
memset ( & cb_state , 0 , sizeof ( cb_state ) ) ;
cb_state . function = function ;
if ( argc > 3 ) {
2007-03-29 22:31:56 +00:00
cb_state . arg = argv [ 3 ] ;
}
2006-11-09 05:39:04 +00:00
cb_state . cx = cx ;
2007-03-29 22:31:56 +00:00
cb_state . obj = obj ;
2006-11-09 05:39:04 +00:00
cb_state . session_state = jss_a ;
dtmf_func = js_collect_input_callback ;
bp = & cb_state ;
len = sizeof ( cb_state ) ;
}
}
2007-03-29 22:31:56 +00:00
cb_state . saveDepth = JS_SuspendRequest ( cx ) ;
2006-11-09 05:39:04 +00:00
switch_ivr_multi_threaded_bridge ( jss_a - > session , jss_b - > session , dtmf_func , bp , bp ) ;
2007-03-29 22:31:56 +00:00
JS_ResumeRequest ( cx , cb_state . saveDepth ) ;
2006-12-02 05:40:58 +00:00
2006-11-09 05:39:04 +00:00
2006-03-01 22:55:28 +00:00
return JS_TRUE ;
}
2006-12-29 20:42:16 +00:00
/* Replace this with more robust version later */
2007-03-29 22:31:56 +00:00
static JSBool js_system ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-12-29 20:42:16 +00:00
{
2007-03-29 22:31:56 +00:00
char * cmd ;
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
2006-12-29 20:42:16 +00:00
2007-03-29 22:31:56 +00:00
if ( argc > 0 & & ( cmd = JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 0 ] ) ) ) ) {
* rval = INT_TO_JSVAL ( system ( cmd ) ) ;
return JS_TRUE ;
}
2006-12-29 20:42:16 +00:00
2007-03-29 22:31:56 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Invalid Arguements \n " ) ;
return JS_FALSE ;
2006-12-29 20:42:16 +00:00
}
2007-03-29 22:31:56 +00:00
static JSBool js_file_unlink ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
2006-12-27 22:47:46 +00:00
{
const char * path ;
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_FALSE ) ;
if ( argc > 0 & & ( path = ( const char * ) JS_GetStringBytes ( JS_ValueToString ( cx , argv [ 0 ] ) ) ) ) {
2006-12-27 22:47:46 +00:00
if ( ( switch_file_remove ( path , NULL ) ) = = SWITCH_STATUS_SUCCESS ) {
2007-03-29 22:31:56 +00:00
* rval = BOOLEAN_TO_JSVAL ( JS_TRUE ) ;
2006-12-27 22:47:46 +00:00
}
return JS_TRUE ;
}
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Invalid Arguements \n " ) ;
return JS_FALSE ;
}
2006-02-26 23:10:22 +00:00
static JSFunctionSpec fs_functions [ ] = {
2007-03-29 22:31:56 +00:00
{ " console_log " , js_log , 2 } ,
{ " exit " , js_exit , 0 } ,
{ " include " , js_include , 1 } ,
2006-03-01 22:55:28 +00:00
{ " bridge " , js_bridge , 2 } ,
2006-03-07 02:06:40 +00:00
{ " apiExecute " , js_api_execute , 2 } ,
2006-11-10 21:49:57 +00:00
{ " use " , js_api_use , 1 } ,
2006-12-27 23:03:54 +00:00
{ " fileDelete " , js_file_unlink , 1 } ,
2006-12-29 20:42:16 +00:00
{ " system " , js_system , 1 } ,
2006-03-01 00:58:32 +00:00
# ifdef HAVE_CURL
2007-03-29 22:31:56 +00:00
{ " fetchURLHash " , js_fetchurl_hash , 1 } ,
{ " fetchURLFile " , js_fetchurl_file , 1 } ,
# endif
2006-02-26 23:10:22 +00:00
{ 0 }
} ;
2007-03-29 22:31:56 +00:00
static int env_init ( JSContext * cx , JSObject * javascript_object )
2006-03-01 22:55:28 +00:00
{
JS_DefineFunctions ( cx , javascript_object , fs_functions ) ;
JS_InitStandardClasses ( cx , javascript_object ) ;
2006-12-23 01:39:27 +00:00
2007-03-30 00:13:31 +00:00
JS_InitClass ( cx , javascript_object , NULL , & session_class , session_construct , 3 , session_props , session_methods , session_props , session_methods ) ;
2006-03-01 22:55:28 +00:00
2007-03-30 00:13:31 +00:00
JS_InitClass ( cx , javascript_object , NULL , & fileio_class , fileio_construct , 3 , fileio_props , fileio_methods , fileio_props , fileio_methods ) ;
2006-03-02 17:36:23 +00:00
2007-03-30 00:13:31 +00:00
JS_InitClass ( cx , javascript_object , NULL , & event_class , event_construct , 3 , event_props , event_methods , event_props , event_methods ) ;
2006-08-18 01:28:50 +00:00
2006-03-01 22:55:28 +00:00
return 1 ;
}
2007-05-14 03:17:38 +00:00
static void js_parse_and_execute ( switch_core_session_t * session , char * input_code , struct request_obj * ro )
2006-02-26 23:10:22 +00:00
{
2006-03-30 23:02:50 +00:00
JSObject * javascript_global_object = NULL ;
2006-03-02 15:22:39 +00:00
char buf [ 1024 ] , * script , * arg , * argv [ 512 ] ;
int argc = 0 , x = 0 , y = 0 ;
unsigned int flags = 0 ;
2006-02-28 02:08:42 +00:00
struct js_session jss ;
2006-03-02 15:22:39 +00:00
JSContext * cx = NULL ;
jsval rval ;
2006-02-26 23:10:22 +00:00
2007-03-29 22:31:56 +00:00
2006-03-02 15:22:39 +00:00
if ( ( cx = JS_NewContext ( globals . rt , globals . gStackChunkSize ) ) ) {
2006-11-10 21:49:57 +00:00
JS_BeginRequest ( cx ) ;
2006-03-02 15:22:39 +00:00
JS_SetErrorReporter ( cx , js_error ) ;
javascript_global_object = JS_NewObject ( cx , & global_class , NULL , NULL ) ;
env_init ( cx , javascript_global_object ) ;
JS_SetGlobalObject ( cx , javascript_global_object ) ;
2006-02-26 23:10:22 +00:00
2006-03-02 15:22:39 +00:00
/* Emaculent conception of session object into the script if one is available */
2006-03-30 23:02:50 +00:00
if ( session & & new_js_session ( cx , javascript_global_object , session , & jss , " session " , flags ) ) {
2006-03-02 15:22:39 +00:00
JS_SetPrivate ( cx , javascript_global_object , session ) ;
}
2007-05-14 03:17:38 +00:00
if ( ro ) {
new_request ( cx , javascript_global_object , ro ) ;
}
2006-03-02 15:22:39 +00:00
} else {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Allocation Error! \n " ) ;
2006-02-26 23:10:22 +00:00
return ;
}
2006-03-02 15:22:39 +00:00
script = input_code ;
if ( ( arg = strchr ( script , ' ' ) ) ) {
* arg + + = ' \0 ' ;
2007-04-02 21:31:03 +00:00
argc = switch_separate_string ( arg , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ;
2006-02-26 23:10:22 +00:00
}
2007-03-29 22:31:56 +00:00
2007-05-14 03:17:38 +00:00
if ( ! argc ) {
snprintf ( buf , sizeof ( buf ) , " ~var argv = new Array(); " ) ;
eval_some_js ( buf , cx , javascript_global_object , & rval ) ;
} else {
/* create a js doppleganger of this argc/argv */
2006-03-02 17:36:23 +00:00
snprintf ( buf , sizeof ( buf ) , " ~var argv = new Array(%d); " , argc ) ;
2006-03-02 15:22:39 +00:00
eval_some_js ( buf , cx , javascript_global_object , & rval ) ;
snprintf ( buf , sizeof ( buf ) , " ~var argc = %d " , argc ) ;
eval_some_js ( buf , cx , javascript_global_object , & rval ) ;
for ( y = 0 ; y < argc ; y + + ) {
2006-03-02 17:36:23 +00:00
snprintf ( buf , sizeof ( buf ) , " ~argv[%d] = \" %s \" ; " , x + + , argv [ y ] ) ;
2006-03-02 15:22:39 +00:00
eval_some_js ( buf , cx , javascript_global_object , & rval ) ;
2006-02-26 23:10:22 +00:00
}
}
2006-03-02 15:22:39 +00:00
2006-02-26 23:10:22 +00:00
if ( cx ) {
2006-03-02 15:22:39 +00:00
eval_some_js ( script , cx , javascript_global_object , & rval ) ;
2006-02-26 23:10:22 +00:00
JS_DestroyContext ( cx ) ;
}
}
2007-05-14 03:17:38 +00:00
static void js_dp_function ( switch_core_session_t * session , char * input_code )
{
js_parse_and_execute ( session , input_code , NULL ) ;
}
2006-03-02 15:22:39 +00:00
2007-03-30 00:13:31 +00:00
static void * SWITCH_THREAD_FUNC js_thread_run ( switch_thread_t * thread , void * obj )
2006-03-01 22:55:28 +00:00
{
char * input_code = obj ;
2007-05-14 03:17:38 +00:00
js_parse_and_execute ( NULL , input_code , NULL ) ;
2006-03-01 22:55:28 +00:00
if ( input_code ) {
free ( input_code ) ;
}
2006-03-02 15:22:39 +00:00
2006-03-01 22:55:28 +00:00
return NULL ;
}
2006-04-29 01:00:52 +00:00
static switch_memory_pool_t * module_pool = NULL ;
2006-03-01 22:55:28 +00:00
2007-05-12 14:48:14 +00:00
static void js_thread_launch ( const char * text )
2006-03-01 22:55:28 +00:00
{
2006-04-29 01:00:52 +00:00
switch_thread_t * thread ;
2006-03-01 22:55:28 +00:00
switch_threadattr_t * thd_attr = NULL ;
if ( ! module_pool ) {
if ( switch_core_new_memory_pool ( & module_pool ) ! = SWITCH_STATUS_SUCCESS ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " OH OH no pool \n " ) ;
2006-03-01 22:55:28 +00:00
return ;
}
}
2007-03-29 22:31:56 +00:00
2006-03-01 22:55:28 +00:00
switch_threadattr_create ( & thd_attr , module_pool ) ;
switch_threadattr_detach_set ( thd_attr , 1 ) ;
2006-04-26 17:18:33 +00:00
switch_threadattr_stacksize_set ( thd_attr , SWITCH_THREAD_STACKSIZE ) ;
2006-03-01 22:55:28 +00:00
switch_thread_create ( & thread , thd_attr , js_thread_run , strdup ( text ) , module_pool ) ;
}
2007-05-14 03:17:38 +00:00
SWITCH_STANDARD_API ( jsapi_function )
{
struct request_obj ro = { 0 } ;
if ( switch_strlen_zero ( cmd ) ) {
stream - > write_function ( stream , " USAGE: %s \n " , jsapi_interface . syntax ) ;
return SWITCH_STATUS_SUCCESS ;
}
ro . cmd = cmd ;
ro . session = session ;
ro . stream = stream ;
js_parse_and_execute ( session , ( char * ) cmd , & ro ) ;
return SWITCH_STATUS_SUCCESS ;
}
2006-03-01 22:55:28 +00:00
2007-05-12 21:36:15 +00:00
SWITCH_STANDARD_API ( launch_async )
2006-03-01 22:55:28 +00:00
{
2007-05-12 21:36:15 +00:00
if ( switch_strlen_zero ( cmd ) ) {
2006-10-08 07:11:42 +00:00
stream - > write_function ( stream , " USAGE: %s \n " , js_run_interface . syntax ) ;
2006-03-29 19:11:20 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2007-05-12 21:36:15 +00:00
js_thread_launch ( cmd ) ;
2006-10-08 07:11:42 +00:00
stream - > write_function ( stream , " OK \n " ) ;
2006-03-01 22:55:28 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 23:43:28 +00:00
static const switch_application_interface_t ivrtest_application_interface = {
2006-02-26 23:10:22 +00:00
/*.interface_name */ " javascript " ,
2007-05-14 03:17:38 +00:00
/*.application_function */ js_dp_function ,
2007-02-26 21:38:10 +00:00
/* long_desc */ " Run a javascript ivr on a channel " ,
/* short_desc */ " Launch JS ivr. " ,
/* syntax */ " <script> [additional_vars [...]] " ,
2007-03-29 22:31:56 +00:00
/* flags */ SAF_NONE ,
/* should we support no media mode here? If so, we need to detect the mode, and either disable the media functions or indicate media if/when we need */
/*.next */ NULL
2006-02-26 23:10:22 +00:00
} ;
2007-05-14 03:17:38 +00:00
static switch_api_interface_t jsapi_interface = {
/*.interface_name */ " jsapi " ,
/*.desc */ " execute an api call " ,
/*.function */ jsapi_function ,
/*.syntax */ " jsapi <script> [additional_vars [...]] " ,
/*.next */ NULL
} ;
2006-04-29 23:43:28 +00:00
static switch_api_interface_t js_run_interface = {
2006-03-01 22:55:28 +00:00
/*.interface_name */ " jsrun " ,
/*.desc */ " run a script " ,
/*.function */ launch_async ,
2007-02-26 21:38:10 +00:00
/*.syntax */ " jsrun <script> [additional_vars [...]] " ,
2007-05-14 03:17:38 +00:00
/*.next */ & jsapi_interface
2006-03-01 22:55:28 +00:00
} ;
2006-02-26 23:10:22 +00:00
2006-04-29 23:43:28 +00:00
static switch_loadable_module_interface_t spidermonkey_module_interface = {
2006-02-26 23:10:22 +00:00
/*.module_name */ modname ,
/*.endpoint_interface */ NULL ,
/*.timer_interface */ NULL ,
/*.dialplan_interface */ NULL ,
/*.codec_interface */ NULL ,
/*.application_interface */ & ivrtest_application_interface ,
2006-03-01 22:55:28 +00:00
/*.api_interface */ & js_run_interface ,
2006-02-26 23:10:22 +00:00
/*.file_interface */ NULL ,
/*.speech_interface */ NULL ,
/*.directory_interface */ NULL
} ;
2007-04-02 21:31:03 +00:00
static void message_query_handler ( switch_event_t * event )
{
char * account = switch_event_get_header ( event , " message-account " ) ;
if ( account ) {
2007-04-04 03:08:17 +00:00
char * path , * cmd ;
2007-04-02 21:31:03 +00:00
2007-04-04 03:08:17 +00:00
path = switch_mprintf ( " %s%smwi.js " , SWITCH_GLOBAL_dirs . script_dir , SWITCH_PATH_SEPARATOR ) ;
assert ( path ! = NULL ) ;
2007-04-02 21:31:03 +00:00
2007-04-23 15:33:25 +00:00
if ( switch_file_exists ( path , NULL ) = = SWITCH_STATUS_SUCCESS ) {
2007-04-04 03:08:17 +00:00
cmd = switch_mprintf ( " %s %s " , path , account ) ;
assert ( cmd ! = NULL ) ;
js_thread_launch ( cmd ) ;
switch_safe_free ( cmd ) ;
2007-04-02 23:34:58 +00:00
}
2007-04-04 03:08:17 +00:00
switch_safe_free ( path ) ;
2007-04-02 21:31:03 +00:00
}
}
2007-03-30 00:13:31 +00:00
SWITCH_MOD_DECLARE ( switch_status_t ) switch_module_load ( const switch_loadable_module_interface_t * * module_interface , char * filename )
2006-02-26 23:10:22 +00:00
{
2006-04-29 23:43:28 +00:00
switch_status_t status ;
2006-02-26 23:10:22 +00:00
2006-03-02 14:52:51 +00:00
if ( ( status = init_js ( ) ) ! = SWITCH_STATUS_SUCCESS ) {
2006-02-26 23:10:22 +00:00
return status ;
}
2007-03-29 22:31:56 +00:00
2007-04-02 21:31:03 +00:00
if ( switch_event_bind ( ( char * ) modname , SWITCH_EVENT_MESSAGE_QUERY , SWITCH_EVENT_SUBCLASS_ANY , message_query_handler , NULL )
! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Couldn't bind! \n " ) ;
return SWITCH_STATUS_GENERR ;
}
2006-02-26 23:10:22 +00:00
/* connect my internal structure to the blank pointer passed to me */
2006-04-30 18:24:24 +00:00
* module_interface = & spidermonkey_module_interface ;
2006-02-26 23:10:22 +00:00
2006-05-12 15:33:49 +00:00
curl_global_init ( CURL_GLOBAL_ALL ) ;
2006-02-26 23:10:22 +00:00
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS ;
}
2006-05-12 15:33:49 +00:00
SWITCH_MOD_DECLARE ( switch_status_t ) switch_module_shutdown ( void )
{
curl_global_cleanup ( ) ;
return SWITCH_STATUS_SUCCESS ;
}
2006-11-27 22:30:48 +00:00
/* For Emacs:
* Local Variables :
* mode : c
2007-02-09 02:36:03 +00:00
* indent - tabs - mode : t
2006-11-27 22:30:48 +00:00
* tab - width : 4
* c - basic - offset : 4
* End :
* For VIM :
* vim : set softtabstop = 4 shiftwidth = 4 tabstop = 4 expandtab :
*/