]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-4745 --resolve
authorBrian West <brian@freeswitch.org>
Thu, 1 Nov 2012 20:04:31 +0000 (15:04 -0500)
committerBrian West <brian@freeswitch.org>
Thu, 1 Nov 2012 20:04:31 +0000 (15:04 -0500)
conf/vanilla/autoload_configs/java.conf.xml
src/mod/languages/mod_java/freeswitch_java.cpp
src/mod/languages/mod_java/freeswitch_java.h
src/mod/languages/mod_java/mod_java.i
src/mod/languages/mod_java/src/org/freeswitch/ApplicationLauncher.java [new file with mode: 0644]
src/mod/languages/mod_java/src/org/freeswitch/OriginateStateHandler.java [new file with mode: 0644]
src/mod/languages/mod_java/src/org/freeswitch/StateHandler.java [new file with mode: 0644]

index 3d1a3b5e5b986cbf1b912fb0578c9ad4c484e4b3..5f71553e30f6085e1632ee3501eebca9b44964b8 100644 (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>
index d8390b2ade747ed037492716aaa947fb676098bc..d8508e145caafc2d8ccc7bf49a417788e806c433 100644 (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);
+}
+
index e87b5928f0b646606ff262681852812175b69a62..5d6d138168b9fc825613d85deb62b118152f420f 100644 (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
index 42527fd5413ae5072133594eed7942a585a66754..858dac8d083fbe11d0e0d93afdc3cb2e9893b445 100644 (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"
 %}
 %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
diff --git a/src/mod/languages/mod_java/src/org/freeswitch/ApplicationLauncher.java b/src/mod/languages/mod_java/src/org/freeswitch/ApplicationLauncher.java
new file mode 100644 (file)
index 0000000..0e7ad0a
--- /dev/null
@@ -0,0 +1,15 @@
+package org.freeswitch.example;\r
+\r
+import org.freeswitch.swig.freeswitch;\r
+\r
+public class ApplicationLauncher {\r
+\r
+       public static final void startup(String arg) {\r
+               try {\r
+                       freeswitch.setOriginateStateHandler(OriginateStateHandler.getInstance());\r
+               } catch (Exception e) {\r
+                       freeswitch.console_log("err", "Error registering originate state handler");\r
+               }\r
+       }\r
+\r
+}\r
diff --git a/src/mod/languages/mod_java/src/org/freeswitch/OriginateStateHandler.java b/src/mod/languages/mod_java/src/org/freeswitch/OriginateStateHandler.java
new file mode 100644 (file)
index 0000000..dd59515
--- /dev/null
@@ -0,0 +1,22 @@
+package org.freeswitch.example;\r
+\r
+import org.freeswitch.StateHandler.OnHangupHandler;\r
+\r
+public class OriginateStateHandler implements OnHangupHandler {\r
+\r
+       private static OriginateStateHandler instance = null;\r
+\r
+       public static final OriginateStateHandler getInstance() {\r
+               if ( instance == null ) instance = new OriginateStateHandler();\r
+               return instance;\r
+       }\r
+\r
+       private OriginateStateHandler() {\r
+               // hide constructor\r
+       }\r
+\r
+       public int onHangup(String uuid, String cause) {\r
+               return 1; // SWITCH_STATUS_FALSE\r
+       }\r
+\r
+}
\ No newline at end of file
diff --git a/src/mod/languages/mod_java/src/org/freeswitch/StateHandler.java b/src/mod/languages/mod_java/src/org/freeswitch/StateHandler.java
new file mode 100644 (file)
index 0000000..b5f9ba2
--- /dev/null
@@ -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);
+       }
+
+}
+