From eb17eca54aba68112788af79d81bd2614c3ef6f6 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 22 Jul 2016 16:27:55 +0200 Subject: [PATCH] Added JNI methods for LinphoneXmlRpc stack --- coreapi/linphonecore_jni.cc | 126 ++++++++++++++++++ .../linphone/core/LinphoneXmlRpcRequest.java | 111 +++++++++++++++ .../linphone/core/LinphoneXmlRpcSession.java | 24 ++++ .../core/LinphoneXmlRpcRequestImpl.java | 84 ++++++++++++ .../core/LinphoneXmlRpcSessionImpl.java | 43 ++++++ 5 files changed, 388 insertions(+) create mode 100644 java/common/org/linphone/core/LinphoneXmlRpcRequest.java create mode 100644 java/common/org/linphone/core/LinphoneXmlRpcSession.java create mode 100644 java/impl/org/linphone/core/LinphoneXmlRpcRequestImpl.java create mode 100644 java/impl/org/linphone/core/LinphoneXmlRpcSessionImpl.java diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 9392eb9aa..e7425439e 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -338,6 +338,7 @@ public: env->DeleteGlobalRef(friendClass); env->DeleteGlobalRef(friendListClass); env->DeleteGlobalRef(friendListSyncStateClass); + env->DeleteGlobalRef(natPolicyClass); env->DeleteGlobalRef(infoMessageClass); env->DeleteGlobalRef(linphoneEventClass); env->DeleteGlobalRef(subscriptionStateClass); @@ -642,6 +643,29 @@ jobject getEvent(JNIEnv *env, LinphoneEvent *lev){ return jev; } +jobject getXmlRpcRequest(JNIEnv *env, LinphoneXmlRpcRequest *lrequest) { + jobject jobj = 0; + + if (lrequest != NULL) { + jclass xmlRpcSessionClass = (jclass)env->FindClass("org/linphone/core/LinphoneXmlRpcRequestImpl"); + jmethodID xmlRpcSessionCtrId = env->GetMethodID(xmlRpcSessionClass, "", "(J)V"); + + void *up = linphone_xml_rpc_request_get_user_data(lrequest); + if (up == NULL) { + jobj = env->NewObject(xmlRpcSessionClass, xmlRpcSessionCtrId, (jlong)lrequest); + linphone_xml_rpc_request_set_user_data(lrequest, (void *)env->NewWeakGlobalRef(jobj)); + linphone_xml_rpc_request_ref(lrequest); + } else { + jobj = env->NewLocalRef((jobject)up); + if (jobj == NULL) { + jobj = env->NewObject(xmlRpcSessionClass, xmlRpcSessionCtrId, (jlong)lrequest); + linphone_xml_rpc_request_set_user_data(lrequest, (void *)env->NewWeakGlobalRef(jobj)); + } + } + } + return jobj; +} + class LinphoneCoreData { public: LinphoneCoreData(JNIEnv *env, jobject lc, LinphoneCoreVTable *vTable, jobject alistener, LinphoneJavaBindings *ljb) { @@ -7589,3 +7613,105 @@ JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneNatPolicyImpl_setStunServe linphone_nat_policy_set_stun_server_username(nat_policy, stun_server_username); ReleaseStringUTFChars(env, jStunServerUsername, stun_server_username); } + +// XML RPC wrapper + +static void xml_request_response(LinphoneXmlRpcRequest *request) { + JNIEnv *env = 0; + jint result = jvm->AttachCurrentThread(&env,NULL); + if (result != 0) { + ms_error("cannot attach VM\n"); + return; + } + + LinphoneXmlRpcRequestCbs *cbs = linphone_xml_rpc_request_get_callbacks(request); + jobject listener = (jobject) linphone_xml_rpc_request_cbs_get_user_data(cbs); + if (listener == NULL) { + ms_error("xml_request_response() notification without listener"); + return ; + } + + jclass clazz = (jclass) env->GetObjectClass(listener); + jmethodID method = env->GetMethodID(clazz, "onXmlRpcRequestResponse","(Lorg/linphone/core/LinphoneXmlRpcRequest;)V"); + env->DeleteLocalRef(clazz); + + env->CallVoidMethod(listener, method, getXmlRpcRequest(env, request)); +} + +extern "C" jlong Java_org_linphone_core_LinphoneXmlRpcRequestImpl_newLinphoneXmlRpcRequest(JNIEnv *env, jobject thiz, jstring jmethodname, jint returntype) { + const char *methodname = GetStringUTFChars(env, jmethodname); + LinphoneXmlRpcRequest *request = linphone_xml_rpc_request_new(methodname, (LinphoneXmlRpcArgType)returntype); + ReleaseStringUTFChars(env, jmethodname, methodname); + return (jlong) request; +} + +extern "C" void Java_org_linphone_core_LinphoneXmlRpcRequestImpl_finalize(JNIEnv *env, jobject thiz, jlong ptr) { + LinphoneXmlRpcRequest *request = (LinphoneXmlRpcRequest *)ptr; + linphone_xml_rpc_request_set_user_data(request, NULL); + linphone_xml_rpc_request_unref(request); +} + +extern "C" void Java_org_linphone_core_LinphoneXmlRpcRequestImpl_addIntArg(JNIEnv *env, jobject thiz, jlong ptr, jint arg) { + LinphoneXmlRpcRequest *request = (LinphoneXmlRpcRequest *)ptr; + linphone_xml_rpc_request_add_int_arg(request, (int)arg); +} + +extern "C" void Java_org_linphone_core_LinphoneXmlRpcRequestImpl_addStringArg(JNIEnv *env, jobject thiz, jlong ptr, jstring jarg) { + LinphoneXmlRpcRequest *request = (LinphoneXmlRpcRequest *)ptr; + const char *arg = GetStringUTFChars(env, jarg); + linphone_xml_rpc_request_add_string_arg(request, arg); + ReleaseStringUTFChars(env, jarg, arg); +} + +extern "C" jstring Java_org_linphone_core_LinphoneXmlRpcRequestImpl_getContent(JNIEnv *env, jobject thiz, jlong ptr) { + LinphoneXmlRpcRequest *request = (LinphoneXmlRpcRequest *)ptr; + const char *content = linphone_xml_rpc_request_get_content(request); + return content ? env->NewStringUTF(content) : NULL; +} + +extern "C" jint Java_org_linphone_core_LinphoneXmlRpcRequestImpl_getStatus(JNIEnv *env, jobject thiz, jlong ptr) { + LinphoneXmlRpcRequest *request = (LinphoneXmlRpcRequest *)ptr; + return (jint) linphone_xml_rpc_request_get_status(request); +} + +extern "C" jint Java_org_linphone_core_LinphoneXmlRpcRequestImpl_getIntResponse(JNIEnv *env, jobject thiz, jlong ptr) { + LinphoneXmlRpcRequest *request = (LinphoneXmlRpcRequest *)ptr; + return (jint) linphone_xml_rpc_request_get_int_response(request); +} + +extern "C" jstring Java_org_linphone_core_LinphoneXmlRpcRequestImpl_getStringResponse(JNIEnv *env, jobject thiz, jlong ptr) { + LinphoneXmlRpcRequest *request = (LinphoneXmlRpcRequest *)ptr; + const char *response = linphone_xml_rpc_request_get_string_response(request); + return response ? env->NewStringUTF(response) : NULL; +} + +extern "C" void Java_org_linphone_core_LinphoneXmlRpcRequestImpl_setListener(JNIEnv* env, jobject thiz, jlong ptr, jobject jlistener) { + LinphoneXmlRpcRequest *request = (LinphoneXmlRpcRequest *)ptr; + jobject listener = env->NewGlobalRef(jlistener); + LinphoneXmlRpcRequestCbs *cbs; + + cbs = linphone_xml_rpc_request_get_callbacks(request); + linphone_xml_rpc_request_cbs_set_user_data(cbs, listener); + linphone_xml_rpc_request_cbs_set_response(cbs, xml_request_response); +} + + +extern "C" jlong Java_org_linphone_core_LinphoneXmlRpcSessionImpl_newLinphoneXmlRpcSession(JNIEnv *env, jobject thiz, jlong ptr, jstring jurl) { + LinphoneCore *lc = (LinphoneCore *)ptr; + const char *url = GetStringUTFChars(env, jurl); + LinphoneXmlRpcSession *session = linphone_xml_rpc_session_new(lc, url); + ReleaseStringUTFChars(env, jurl, url); + return (jlong) session; +} + +extern "C" void Java_org_linphone_core_LinphoneXmlRpcSessionImpl_finalize(JNIEnv *env, jobject thiz, jlong ptr) { + LinphoneXmlRpcSession *session = (LinphoneXmlRpcSession *)ptr; + linphone_xml_rpc_session_set_user_data(session, NULL); + linphone_xml_rpc_session_unref(session); +} + +extern "C" void Java_org_linphone_core_LinphoneXmlRpcSessionImpl_sendRequest(JNIEnv *env, jobject thiz, jlong ptr, jlong requestPtr) { + LinphoneXmlRpcSession *session = (LinphoneXmlRpcSession *)ptr; + LinphoneXmlRpcRequest *request = (LinphoneXmlRpcRequest *)requestPtr; + linphone_xml_rpc_session_send_request(session, request); +} \ No newline at end of file diff --git a/java/common/org/linphone/core/LinphoneXmlRpcRequest.java b/java/common/org/linphone/core/LinphoneXmlRpcRequest.java new file mode 100644 index 000000000..9b38ae4cf --- /dev/null +++ b/java/common/org/linphone/core/LinphoneXmlRpcRequest.java @@ -0,0 +1,111 @@ +/* +LinphoneXmlRpcRequest.java +Copyright (C) 2016 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +package org.linphone.core; + +import java.util.Vector; + +public interface LinphoneXmlRpcRequest { + interface LinphoneXmlRpcRequestListener { + void onXmlRpcRequestResponse(LinphoneXmlRpcRequest request); + } + + public static class ArgType { + static private Vector values = new Vector(); + private final int mValue; + private final String mStringValue; + + public final int value() { return mValue; } + + public final static ArgType None = new ArgType(0, "None"); + public final static ArgType Int = new ArgType(1, "Int"); + public final static ArgType String = new ArgType(2, "String"); + + private ArgType(int value, String stringValue) { + mValue = value; + values.addElement(this); + mStringValue = stringValue; + } + + public static ArgType fromInt(int value) { + + for (int i=0; i < values.size(); i++) { + ArgType state = (ArgType) values.elementAt(i); + if (state.mValue == value) return state; + } + throw new RuntimeException("ArgType not found [" + value + "]"); + } + + public String toString() { + return mStringValue; + } + + public int toInt() { + return mValue; + } + } + + public static class Status { + static private Vector values = new Vector(); + private final int mValue; + private final String mStringValue; + + public final int value() { return mValue; } + + public final static Status Pending = new Status(0, "Pending"); + public final static Status Ok = new Status(1, "Ok"); + public final static Status Failed = new Status(2, "Failed"); + + private Status(int value, String stringValue) { + mValue = value; + values.addElement(this); + mStringValue = stringValue; + } + + public static Status fromInt(int value) { + + for (int i=0; i < values.size(); i++) { + Status state = (Status) values.elementAt(i); + if (state.mValue == value) return state; + } + throw new RuntimeException("Status not found [" + value + "]"); + } + + public String toString() { + return mStringValue; + } + + public int toInt() { + return mValue; + } + } + + void addIntArg(int arg); + + void addStringArg(String arg); + + String getContent(); + + Status getStatus(); + + int getIntResponse(); + + String getStringResponse(); + + void setListener(LinphoneXmlRpcRequestListener listener); +} diff --git a/java/common/org/linphone/core/LinphoneXmlRpcSession.java b/java/common/org/linphone/core/LinphoneXmlRpcSession.java new file mode 100644 index 000000000..37d50d80b --- /dev/null +++ b/java/common/org/linphone/core/LinphoneXmlRpcSession.java @@ -0,0 +1,24 @@ +/* +LinphoneXmlRpcSession.java +Copyright (C) 2016 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +package org.linphone.core; + + +public interface LinphoneXmlRpcSession { + void sendRequest(LinphoneXmlRpcRequest request); +} diff --git a/java/impl/org/linphone/core/LinphoneXmlRpcRequestImpl.java b/java/impl/org/linphone/core/LinphoneXmlRpcRequestImpl.java new file mode 100644 index 000000000..1dd7e4107 --- /dev/null +++ b/java/impl/org/linphone/core/LinphoneXmlRpcRequestImpl.java @@ -0,0 +1,84 @@ +/* +LinphoneXmlRpcRequestImpl.java +Copyright (C) 2016 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +package org.linphone.core; + + +public class LinphoneXmlRpcRequestImpl implements LinphoneXmlRpcRequest { + protected long nativePtr; + + protected LinphoneXmlRpcRequestImpl(long aNativePtr) { + nativePtr = aNativePtr; + } + + private native long newLinphoneXmlRpcRequest(String methodName, int returnType); + public LinphoneXmlRpcRequestImpl(String methodName, ArgType returnType) { + nativePtr = newLinphoneXmlRpcRequest(methodName, returnType.value()); + } + + public long getNativePtr() { + return nativePtr; + } + + private native void unref(long ptr); + protected void finalize(){ + unref(nativePtr); + } + + private native void addIntArg(long ptr, int arg); + @Override + public void addIntArg(int arg) { + addIntArg(nativePtr, arg); + } + + private native void addStringArg(long ptr, String arg); + @Override + public void addStringArg(String arg) { + addStringArg(nativePtr, arg); + } + + private native String getContent(long ptr); + @Override + public String getContent() { + return getContent(nativePtr); + } + + private native int getStatus(long ptr); + @Override + public Status getStatus() { + return Status.fromInt(getStatus(nativePtr)); + } + + private native int getIntResponse(long ptr); + @Override + public int getIntResponse() { + return getIntResponse(nativePtr); + } + + private native String getStringResponse(long ptr); + @Override + public String getStringResponse() { + return getStringResponse(nativePtr); + } + + private native void setListener(long ptr, LinphoneXmlRpcRequestListener listener); + @Override + public void setListener(LinphoneXmlRpcRequestListener listener) { + setListener(nativePtr, listener); + } +} diff --git a/java/impl/org/linphone/core/LinphoneXmlRpcSessionImpl.java b/java/impl/org/linphone/core/LinphoneXmlRpcSessionImpl.java new file mode 100644 index 000000000..d803610b2 --- /dev/null +++ b/java/impl/org/linphone/core/LinphoneXmlRpcSessionImpl.java @@ -0,0 +1,43 @@ +/* +LinphoneXmlRpcSessionImpl.java +Copyright (C) 2016 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +package org.linphone.core; + +public class LinphoneXmlRpcSessionImpl implements LinphoneXmlRpcSession { + protected long nativePtr; + + private native long newLinphoneXmlRpcSession(long nativePtr, String url); + public LinphoneXmlRpcSessionImpl(LinphoneCore lc, String url) { + nativePtr = newLinphoneXmlRpcSession(((LinphoneCoreImpl)lc).nativePtr, url); + } + + public long getNativePtr() { + return nativePtr; + } + + private native void unref(long ptr); + protected void finalize(){ + unref(nativePtr); + } + + private native void sendRequest(long ptr, long requestPtr); + @Override + public void sendRequest(LinphoneXmlRpcRequest request) { + sendRequest(nativePtr, ((LinphoneXmlRpcRequestImpl)request).getNativePtr()); + } +}