FS-4745 --resolve

This commit is contained in:
Brian West 2012-11-01 15:04:31 -05:00
parent efcd5656fb
commit 43dfc70327
7 changed files with 291 additions and 10 deletions

View File

@ -1,13 +1,8 @@
<configuration name="java.conf" description="Java Plug-Ins">
<!-- Path to the Java 1.6 virtual machine to use -->
<javavm path="/usr/java/jdk1.6.0/jre/lib/i386/client/libjvm.so"/>
<!-- Options to pass to Java -->
<javavm path="/opt/jdk1.6.0_04/jre/lib/amd64/server/libjvm.so"/>
<options>
<!-- Your class path (make sure freeswitch.jar is on it) -->
<option value="-Djava.class.path=$${base_dir}/scripts/freeswitch.jar"/>
<!-- Enable remote debugging -->
<option value="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=127.0.0.1:8000"/>
<option value="-Djava.class.path=$${base_dir}/scripts/freeswitch.jar:$${base_dir}/scripts/example.jar"/>
<option value="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:8000"/>
</options>
<startup class="net/cog/fs/system/Control" method="startup" arg="start up arg"/>
<shutdown class="net/cog/fs/system/Control" method="shutdown" arg="shutdown arg"/>
<startup class="org/freeswitch/example/ApplicationLauncher" method="startup"/>
</configuration>

View File

@ -1,5 +1,35 @@
#include "freeswitch_java.h"
jobject originate_state_handler;
SWITCH_DECLARE(void) setOriginateStateHandler(jobject stateHandler)
{
JNIEnv *env = NULL;
jint envStatus = javaVM->GetEnv((void**)&env, JNI_VERSION_1_4);
if ( envStatus != JNI_OK ) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error getting JNIEnv!\n");
return;
}
if ( stateHandler != NULL && originate_state_handler != NULL ) {
const char* errorMessage = "Originate state handler is already registered";
jclass exceptionClass = env->FindClass("java/util/TooManyListenersException");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, errorMessage);
env->ThrowNew(exceptionClass, errorMessage);
} else if ( stateHandler == NULL && originate_state_handler != NULL ) {
env->DeleteGlobalRef(originate_state_handler);
originate_state_handler = NULL;
} else {
originate_state_handler = env->NewGlobalRef(stateHandler);
if ( originate_state_handler == NULL ) {
const char* errorMessage = "Unable to create global reference for state handler";
jclass exceptionClass = env->FindClass("java/lang/OutOfMemoryError");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, errorMessage);
env->ThrowNew(exceptionClass, errorMessage);
}
}
}
JavaSession::JavaSession() : CoreSession()
{
}
@ -328,3 +358,152 @@ done:
return status;
}
switch_status_t originate_handler_method(switch_core_session_t *session, const char* method) {
if ( originate_state_handler != NULL ) {
JNIEnv *env = NULL;
bool needDetach = false;
jint envStatus = javaVM->GetEnv((void**)&env, JNI_VERSION_1_4);
if ( envStatus == JNI_EDETACHED ) {
envStatus = javaVM->AttachCurrentThread((void**)&env, NULL);
if ( envStatus == JNI_OK ) needDetach = true;
}
if ( envStatus != JNI_OK ) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error getting JNIEnv!\n");
return SWITCH_STATUS_FALSE;
}
jclass handlerClass = env->GetObjectClass(originate_state_handler);
if ( handlerClass == NULL ) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error getting handler class!\n");
if ( needDetach ) javaVM->DetachCurrentThread();
return SWITCH_STATUS_FALSE;
}
jint result = SWITCH_STATUS_FALSE;
jmethodID handlerMethod = env->GetMethodID(handlerClass, method, "(Ljava/lang/String;)I");
if ( handlerMethod != NULL ) {
char *uuid = switch_core_session_get_uuid(session);
jstring javaUuid = env->NewStringUTF(uuid);
result = env->CallIntMethod(originate_state_handler, handlerMethod, javaUuid);
env->DeleteLocalRef(javaUuid);
}
env->DeleteLocalRef(handlerClass);
if ( needDetach ) javaVM->DetachCurrentThread();
return (switch_status_t)result;
}
return SWITCH_STATUS_FALSE;
}
switch_status_t originate_on_init(switch_core_session_t *session) {
return originate_handler_method(session, "onInit");
}
switch_status_t originate_on_routing(switch_core_session_t *session) {
return originate_handler_method(session, "onRouting");
}
switch_status_t originate_on_execute(switch_core_session_t *session) {
return originate_handler_method(session, "onExecute");
}
switch_status_t originate_on_hangup(switch_core_session_t *session) {
if ( originate_state_handler != NULL ) {
JNIEnv *env = NULL;
bool needDetach = false;
jint envStatus = javaVM->GetEnv((void**)&env, JNI_VERSION_1_4);
if ( envStatus == JNI_EDETACHED ) {
envStatus = javaVM->AttachCurrentThread((void**)&env, NULL);
if ( envStatus == JNI_OK ) needDetach = true;
}
if ( envStatus != JNI_OK ) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error getting JNIEnv!\n");
return SWITCH_STATUS_FALSE;
}
jclass handlerClass = env->GetObjectClass(originate_state_handler);
if ( handlerClass == NULL ) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error getting handler class!\n");
if ( needDetach ) javaVM->DetachCurrentThread();
return SWITCH_STATUS_FALSE;
}
jint result = SWITCH_STATUS_FALSE;
jmethodID handlerMethod = env->GetMethodID(handlerClass, "onHangup", "(Ljava/lang/String;Ljava/lang/String;)I");
if ( handlerMethod != NULL ) {
switch_channel_t *channel = switch_core_session_get_channel(session);
const char *uuid = switch_core_session_get_uuid(session);
const char *cause = switch_channel_cause2str(switch_channel_get_cause(channel));
jstring javaUuid = env->NewStringUTF(uuid);
jstring javaCause = env->NewStringUTF(cause);
result = env->CallIntMethod(originate_state_handler, handlerMethod, javaUuid, javaCause);
env->DeleteLocalRef(javaUuid);
env->DeleteLocalRef(javaCause);
}
env->DeleteLocalRef(handlerClass);
if ( needDetach ) javaVM->DetachCurrentThread();
return (switch_status_t)result;
}
return SWITCH_STATUS_FALSE;
}
switch_status_t originate_on_exchange_media(switch_core_session_t *session) {
return originate_handler_method(session, "onExchangeMedia");
}
switch_status_t originate_on_soft_execute(switch_core_session_t *session) {
return originate_handler_method(session, "onSoftExecute");
}
switch_status_t originate_on_consume_media(switch_core_session_t *session) {
return originate_handler_method(session, "onConsumeMedia");
}
switch_status_t originate_on_hibernate(switch_core_session_t *session) {
return originate_handler_method(session, "onHibernate");
}
switch_status_t originate_on_reset(switch_core_session_t *session) {
return originate_handler_method(session, "onReset");
}
switch_status_t originate_on_park(switch_core_session_t *session) {
return originate_handler_method(session, "onPark");
}
switch_status_t originate_on_reporting(switch_core_session_t *session) {
return originate_handler_method(session, "onReporting");
}
switch_status_t originate_on_destroy(switch_core_session_t *session) {
return originate_handler_method(session, "onDestroy");
}
switch_state_handler_table_t originate_state_handlers = {
/*.on_init */ &originate_on_init,
/*.on_routing */ &originate_on_routing,
/*.on_execute */ &originate_on_execute,
/*.on_hangup */ &originate_on_hangup,
/*.on_exchange_media */ &originate_on_exchange_media,
/*.on_soft_execute */ &originate_on_soft_execute,
/*.on_consume_media */ &originate_on_consume_media,
/*.on_hibernate */ &originate_on_hibernate,
/*.on_reset */ &originate_on_reset,
/*.on_park */ &originate_on_park,
/*.on_reporting */ &originate_on_reporting,
/*.on_destroy */ &originate_on_destroy
};
int JavaSession::originate(JavaSession* aleg, char* destination, int timeout) {
switch_state_handler_table_t *stateHandlers = NULL;
if ( originate_state_handler != NULL ) stateHandlers = &originate_state_handlers;
return CoreSession::originate(aleg, destination, timeout, stateHandlers);
}

View File

@ -6,6 +6,16 @@
extern JavaVM *javaVM;
#ifdef __cplusplus
extern "C" {
#endif
SWITCH_DECLARE(void) setOriginateStateHandler(jobject stateHandler);
#ifdef __cplusplus
}
#endif
class JavaSession:public CoreSession {
public:
JavaSession();
@ -19,6 +29,7 @@ class JavaSession:public CoreSession {
void setHangupHook(jobject hangupHook);
virtual void check_hangup_hook();
virtual switch_status_t run_dtmf_callback(void *input, switch_input_type_t itype);
int originate(JavaSession* aleg, char* destination, int timeout);
};
#endif

View File

@ -2,6 +2,7 @@
%include ../../../../swig_common.i
/** insert the following includes into generated code so it compiles */
%{
#include "switch.h"
#include "switch_cpp.h"
#include "freeswitch_java.h"
%}
@ -53,7 +54,11 @@
%typemap(javain) char *terminator "$javainput"
%typemap(freearg) char *terminator ""
#define SWITCH_DECLARE(type) type
%javamethodmodifiers CoreSession::originate(CoreSession *, char *, int, switch_state_handler_table_t *) "protected";
%javaexception ("java.util.TooManyListenersException") setOriginateStateHandler(jobject);
%typemap(jtype) jobject stateHandler "org.freeswitch.StateHandler"
%typemap(jstype) jobject stateHandler "org.freeswitch.StateHandler"
%include "enums.swg"
%include switch_swigable_cpp.h

View File

@ -0,0 +1,15 @@
package org.freeswitch.example;
import org.freeswitch.swig.freeswitch;
public class ApplicationLauncher {
public static final void startup(String arg) {
try {
freeswitch.setOriginateStateHandler(OriginateStateHandler.getInstance());
} catch (Exception e) {
freeswitch.console_log("err", "Error registering originate state handler");
}
}
}

View File

@ -0,0 +1,22 @@
package org.freeswitch.example;
import org.freeswitch.StateHandler.OnHangupHandler;
public class OriginateStateHandler implements OnHangupHandler {
private static OriginateStateHandler instance = null;
public static final OriginateStateHandler getInstance() {
if ( instance == null ) instance = new OriginateStateHandler();
return instance;
}
private OriginateStateHandler() {
// hide constructor
}
public int onHangup(String uuid, String cause) {
return 1; // SWITCH_STATUS_FALSE
}
}

View File

@ -0,0 +1,54 @@
package org.freeswitch;
public interface StateHandler {
public interface OnInitHandler extends StateHandler {
public int onInit(String uuid);
}
public static interface OnRoutingHandler extends StateHandler {
public int onRouting(String uuid);
}
public static interface OnExecuteHandler extends StateHandler {
public int onExecute(String uuid);
}
public static interface OnHangupHandler extends StateHandler {
public int onHangup(String uuid, String cause);
}
public static interface OnExchangeMediaHandler extends StateHandler {
public int onExchangeMedia(String uuid);
}
public static interface OnSoftExecuteHandler extends StateHandler {
public int onSoftExecute(String uuid);
}
public static interface OnConsumeMediaHandler extends StateHandler {
public int onConsumeMedia(String uuid);
}
public static interface OnHibernateHandler extends StateHandler {
public int onHibernate(String uuid);
}
public static interface OnResetHandler extends StateHandler {
public int onReset(String uuid);
}
public static interface OnParkHandler extends StateHandler {
public int onPark(String uuid);
}
public static interface OnReportingHandler extends StateHandler {
public int onReporting(String uuid);
}
public static interface OnDestroyHandler extends StateHandler {
public int onDestroy(String uuid);
}
}