diff --git a/coreapi/help/java/org/linphone/core/tutorials/TutorialBuddyStatus.java b/coreapi/help/java/org/linphone/core/tutorials/TutorialBuddyStatus.java index 5bd39d03b..a65e0528c 100644 --- a/coreapi/help/java/org/linphone/core/tutorials/TutorialBuddyStatus.java +++ b/coreapi/help/java/org/linphone/core/tutorials/TutorialBuddyStatus.java @@ -29,6 +29,7 @@ import org.linphone.core.LinphoneCoreException; import org.linphone.core.LinphoneCoreFactory; import org.linphone.core.LinphoneCoreListener; import org.linphone.core.LinphoneFriend; +import org.linphone.core.LinphoneInfoMessage; import org.linphone.core.LinphoneProxyConfig; import org.linphone.core.OnlineStatus; import org.linphone.core.LinphoneCall.State; @@ -248,5 +249,11 @@ public class TutorialBuddyStatus implements LinphoneCoreListener { } + @Override + public void infoReceived(LinphoneCore lc, LinphoneInfoMessage info) { + // TODO Auto-generated method stub + + } + } diff --git a/coreapi/help/java/org/linphone/core/tutorials/TutorialChatRoom.java b/coreapi/help/java/org/linphone/core/tutorials/TutorialChatRoom.java index 0c5edda7e..e64750122 100644 --- a/coreapi/help/java/org/linphone/core/tutorials/TutorialChatRoom.java +++ b/coreapi/help/java/org/linphone/core/tutorials/TutorialChatRoom.java @@ -32,6 +32,7 @@ import org.linphone.core.LinphoneCoreException; import org.linphone.core.LinphoneCoreFactory; import org.linphone.core.LinphoneCoreListener; import org.linphone.core.LinphoneFriend; +import org.linphone.core.LinphoneInfoMessage; import org.linphone.core.LinphoneProxyConfig; @@ -170,5 +171,11 @@ public class TutorialChatRoom implements LinphoneCoreListener, LinphoneChatMessa } + @Override + public void infoReceived(LinphoneCore lc, LinphoneInfoMessage info) { + // TODO Auto-generated method stub + + } + } diff --git a/coreapi/help/java/org/linphone/core/tutorials/TutorialHelloWorld.java b/coreapi/help/java/org/linphone/core/tutorials/TutorialHelloWorld.java index bf5421d6d..ea659e60b 100644 --- a/coreapi/help/java/org/linphone/core/tutorials/TutorialHelloWorld.java +++ b/coreapi/help/java/org/linphone/core/tutorials/TutorialHelloWorld.java @@ -29,6 +29,7 @@ import org.linphone.core.LinphoneCoreException; import org.linphone.core.LinphoneCoreFactory; import org.linphone.core.LinphoneCoreListener; import org.linphone.core.LinphoneFriend; +import org.linphone.core.LinphoneInfoMessage; import org.linphone.core.LinphoneProxyConfig; import org.linphone.core.LinphoneCall.State; import org.linphone.core.LinphoneCore.GlobalState; @@ -174,5 +175,11 @@ public class TutorialHelloWorld implements LinphoneCoreListener { } + @Override + public void infoReceived(LinphoneCore lc, LinphoneInfoMessage info) { + // TODO Auto-generated method stub + + } + } diff --git a/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java b/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java index 89e53f5c5..c8a827511 100644 --- a/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java +++ b/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java @@ -29,6 +29,7 @@ import org.linphone.core.LinphoneCoreException; import org.linphone.core.LinphoneCoreFactory; import org.linphone.core.LinphoneCoreListener; import org.linphone.core.LinphoneFriend; +import org.linphone.core.LinphoneInfoMessage; import org.linphone.core.LinphoneProxyConfig; import org.linphone.core.LinphoneCall.State; import org.linphone.core.LinphoneCore.GlobalState; @@ -205,6 +206,12 @@ public class TutorialRegistration implements LinphoneCoreListener { } + @Override + public void infoReceived(LinphoneCore lc, LinphoneInfoMessage info) { + // TODO Auto-generated method stub + + } + } diff --git a/coreapi/info.c b/coreapi/info.c index 6ab5f5837..961fa0b04 100644 --- a/coreapi/info.c +++ b/coreapi/info.c @@ -102,6 +102,15 @@ void linphone_info_message_destroy(LinphoneInfoMessage *im){ ms_free(im); } + +LinphoneInfoMessage *linphone_info_message_copy(const LinphoneInfoMessage *orig){ + LinphoneInfoMessage *im=ms_new0(LinphoneInfoMessage,1); + linphone_content_copy(&im->content,&orig->content); + if (orig->headers) im->headers=sal_custom_header_clone(orig->headers); + if (orig->op) im->op=sal_op_ref(orig->op); + return im; +} + /** * Creates an empty info message. * @param lc the LinphoneCore object. @@ -152,7 +161,7 @@ const char *linphone_info_message_get_header(const LinphoneInfoMessage *im, cons /** * Returns origin of received LinphoneInfoMessage **/ -const char *linphone_info_message_get_from(LinphoneInfoMessage *im){ +const char *linphone_info_message_get_from(const LinphoneInfoMessage *im){ return sal_op_get_from(im->op); } diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index ebfdaa1b5..e363192ac 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -250,7 +250,9 @@ LINPHONE_PUBLIC void linphone_info_message_add_header(LinphoneInfoMessage *im, c LINPHONE_PUBLIC const char *linphone_info_message_get_header(const LinphoneInfoMessage *im, const char *name); LINPHONE_PUBLIC void linphone_info_message_set_content(LinphoneInfoMessage *im, const LinphoneContent *content); LINPHONE_PUBLIC const LinphoneContent * linphone_info_message_get_content(const LinphoneInfoMessage *im); +LINPHONE_PUBLIC const char *linphone_info_message_get_from(const LinphoneInfoMessage *im); LINPHONE_PUBLIC void linphone_info_message_destroy(LinphoneInfoMessage *im); +LINPHONE_PUBLIC LinphoneInfoMessage *linphone_info_message_copy(const LinphoneInfoMessage *orig); /** * Enum describing failure reasons. diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 0701f1f37..85dd369d5 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -52,15 +52,15 @@ extern "C" void libmsbcg729_init(); static JavaVM *jvm=0; static const char* LogDomain = "Linphone"; +static jclass handler_class; +static jmethodID loghandler_id; +static jobject handler_obj=NULL; #ifdef ANDROID -void linphone_android_log_handler(int prio, const char *fmt, va_list args) { - char str[4096]; +void linphone_android_log_handler(int prio, char *str) { char *current; char *next; - vsnprintf(str, sizeof(str) - 1, fmt, args); - str[sizeof(str) - 1] = '\0'; if (strlen(str) < 512) { __android_log_write(prio, LogDomain, str); } else { @@ -75,16 +75,25 @@ void linphone_android_log_handler(int prio, const char *fmt, va_list args) { } static void linphone_android_ortp_log_handler(OrtpLogLevel lev, const char *fmt, va_list args) { + char str[4096]; + const char *levname="undef"; + vsnprintf(str, sizeof(str) - 1, fmt, args); + str[sizeof(str) - 1] = '\0'; + int prio; switch(lev){ - case ORTP_DEBUG: prio = ANDROID_LOG_DEBUG; break; - case ORTP_MESSAGE: prio = ANDROID_LOG_INFO; break; - case ORTP_WARNING: prio = ANDROID_LOG_WARN; break; - case ORTP_ERROR: prio = ANDROID_LOG_ERROR; break; - case ORTP_FATAL: prio = ANDROID_LOG_FATAL; break; - default: prio = ANDROID_LOG_DEFAULT; break; + case ORTP_DEBUG: prio = ANDROID_LOG_DEBUG; levname="debug"; break; + case ORTP_MESSAGE: prio = ANDROID_LOG_INFO; levname="message"; break; + case ORTP_WARNING: prio = ANDROID_LOG_WARN; levname="warning"; break; + case ORTP_ERROR: prio = ANDROID_LOG_ERROR; levname="error"; break; + case ORTP_FATAL: prio = ANDROID_LOG_FATAL; levname="fatal"; break; + default: prio = ANDROID_LOG_DEFAULT; break; } - linphone_android_log_handler(prio, fmt, args); + if (handler_obj){ + JNIEnv *env=ms_get_jni_env(); + env->CallVoidMethod(handler_obj,loghandler_id,env->NewStringUTF(LogDomain),(jint)lev,env->NewStringUTF(levname),env->NewStringUTF(str),NULL); + }else + linphone_android_log_handler(prio, str); } int dumbMethodForAllowingUsageOfCpuFeaturesFromStaticLibMediastream() { @@ -140,6 +149,7 @@ public: vTable.notify_presence_recv = notify_presence_recv; vTable.call_stats_updated = callStatsUpdated; vTable.transfer_state_changed = transferStateChanged; + vTable.info_received = infoReceived; listenerClass = (jclass)env->NewGlobalRef(env->GetObjectClass( alistener)); @@ -187,6 +197,7 @@ public: textReceivedId = env->GetMethodID(listenerClass,"textReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatRoom;Lorg/linphone/core/LinphoneAddress;Ljava/lang/String;)V"); messageReceivedId = env->GetMethodID(listenerClass,"messageReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatRoom;Lorg/linphone/core/LinphoneChatMessage;)V"); dtmfReceivedId = env->GetMethodID(listenerClass,"dtmfReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;I)V"); + infoReceivedId = env->GetMethodID(listenerClass,"infoReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneInfoMessage;)V"); proxyClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneProxyConfigImpl")); proxyCtrId = env->GetMethodID(proxyClass,"", "(J)V"); @@ -210,6 +221,9 @@ public: callStatsId = env->GetMethodID(callStatsClass, "", "(JJ)V"); callSetAudioStatsId = env->GetMethodID(callClass, "setAudioStats", "(Lorg/linphone/core/LinphoneCallStats;)V"); callSetVideoStatsId = env->GetMethodID(callClass, "setVideoStats", "(Lorg/linphone/core/LinphoneCallStats;)V"); + + infoMessageClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneInfoMessageImpl")); + infoMessageCtor = env->GetMethodID(infoMessageClass,"", "(J)V"); } ~LinphoneCoreData() { @@ -222,14 +236,13 @@ public: env->DeleteGlobalRef(globalStateClass); env->DeleteGlobalRef(registrationStateClass); env->DeleteGlobalRef(callStateClass); - env->DeleteGlobalRef(callStatsClass); env->DeleteGlobalRef(chatMessageStateClass); env->DeleteGlobalRef(proxyClass); env->DeleteGlobalRef(callClass); env->DeleteGlobalRef(chatMessageClass); env->DeleteGlobalRef(chatRoomClass); env->DeleteGlobalRef(friendClass); - + env->DeleteGlobalRef(infoMessageClass); } jobject core; jobject listener; @@ -244,6 +257,7 @@ public: jmethodID dtmfReceivedId; jmethodID callStatsUpdatedId; jmethodID transferStateId; + jmethodID infoReceivedId; jclass globalStateClass; jmethodID globalStateId; @@ -288,6 +302,9 @@ public: jclass addressClass; jmethodID addressCtrId; + + jclass infoMessageClass; + jmethodID infoMessageCtor; LinphoneCoreVTable vTable; @@ -519,6 +536,22 @@ public: ,env->CallStaticObjectMethod(lcData->callStateClass,lcData->callStateFromIntId,(jint)remote_call_state) ); } + static void infoReceived(LinphoneCore *lc, const LinphoneInfoMessage *info){ + JNIEnv *env = 0; + jint result = jvm->AttachCurrentThread(&env,NULL); + jobject jcall; + if (result != 0) { + ms_error("cannot attach VM\n"); + return; + } + LinphoneInfoMessage *copy_info=linphone_info_message_copy(info); + LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_get_user_data(lc); + env->CallVoidMethod(lcData->listener + ,lcData->infoReceivedId + ,lcData->core + ,env->NewObject(lcData->infoMessageClass,lcData->infoMessageCtor,(jlong)copy_info) + ); + } }; extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_newLinphoneCore(JNIEnv* env @@ -2588,3 +2621,116 @@ extern "C" void Java_org_linphone_core_LpConfigImpl_setInt(JNIEnv *env, jobject env->ReleaseStringUTFChars(key, ckey); } +static jobject create_java_linphone_content(JNIEnv *env, const LinphoneContent *content){ + jclass contentClass; + jmethodID ctor; + jstring jtype, jsubtype, jdata; + + contentClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneContentImpl")); + ctor = env->GetMethodID(contentClass,"", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); + + jtype=env->NewStringUTF(content->type); + jsubtype=env->NewStringUTF(content->subtype); + jdata=content->data ? env->NewStringUTF((const char*)content->data) : NULL; + jobject jobj=env->NewObject(contentClass,ctor,jtype, jsubtype, jdata); + + env->DeleteGlobalRef(contentClass); + return jobj; +} + +/* + * Class: org_linphone_core_LinphoneInfoMessageImpl + * Method: getContent + * Signature: (J)Ljava/lang/Object; + */ +JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneInfoMessageImpl_getContent(JNIEnv *env, jobject jobj, jlong infoptr){ + const LinphoneContent *content=linphone_info_message_get_content((LinphoneInfoMessage*)infoptr); + if (content){ + return create_java_linphone_content(env,content); + } + return NULL; +} + +/* + * Class: org_linphone_core_LinphoneInfoMessageImpl + * Method: setContent + * Signature: (JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneInfoMessageImpl_setContent(JNIEnv *env, jobject jobj, jlong infoptr, jstring jtype, jstring jsubtype, jstring jdata){ + const char *type,*subtype,*data; + LinphoneContent content; + + content.type=(char*)env->GetStringUTFChars(jtype,NULL); + content.subtype=(char*)env->GetStringUTFChars(jsubtype,NULL); + content.data=(void*)env->GetStringUTFChars(jdata,NULL); + content.size=strlen((char*)content.data); + linphone_info_message_set_content((LinphoneInfoMessage*)infoptr,&content); + env->ReleaseStringUTFChars(jtype,content.type); + env->ReleaseStringUTFChars(jsubtype,content.subtype); + env->ReleaseStringUTFChars(jdata,(char*)content.data); +} + +/* + * Class: org_linphone_core_LinphoneInfoMessageImpl + * Method: addHeader + * Signature: (JLjava/lang/String;Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneInfoMessageImpl_addHeader(JNIEnv *env, jobject jobj, jlong infoptr, jstring jname, jstring jvalue){ + const char *name=NULL,*value=NULL; + name=env->GetStringUTFChars(jname,NULL); + value=env->GetStringUTFChars(jvalue,NULL); + linphone_info_message_add_header((LinphoneInfoMessage*)infoptr,name,value); + env->ReleaseStringUTFChars(jname,name); + env->ReleaseStringUTFChars(jvalue,value); +} + +/* + * Class: org_linphone_core_LinphoneInfoMessageImpl + * Method: getHeader + * Signature: (JLjava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_linphone_core_LinphoneInfoMessageImpl_getHeader(JNIEnv *env, jobject jobj, jlong infoptr, jstring jname){ + const char *name=name=env->GetStringUTFChars(jname,NULL); + const char *ret=linphone_info_message_get_header((LinphoneInfoMessage*)infoptr,name); + env->ReleaseStringUTFChars(jname,name); + return ret ? env->NewStringUTF(ret) : NULL; +} + +/* + * Class: org_linphone_core_LinphoneInfoMessageImpl + * Method: getFrom + * Signature: (J)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_linphone_core_LinphoneInfoMessageImpl_getFrom(JNIEnv *env , jobject jobj, jlong infoptr){ + const char *from=linphone_info_message_get_from((LinphoneInfoMessage*)infoptr); + return from ? env->NewStringUTF(from) : NULL; +} + +/* + * Class: org_linphone_core_LinphoneInfoMessageImpl + * Method: delete + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneInfoMessageImpl_delete(JNIEnv *env, jobject jobj , jlong infoptr){ + linphone_info_message_destroy((LinphoneInfoMessage*)infoptr); +} + +JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneCoreFactoryImpl__1setLogHandler(JNIEnv *env, jobject jfactory, jobject jhandler){ + static int init_done=FALSE; + + if (!init_done){ + handler_class=(jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneLogHandler")); + loghandler_id=env->GetMethodID(handler_class,"log", "(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V"); + if (loghandler_id==NULL) ms_fatal("log method not found"); + init_done=TRUE; + } + if (handler_obj) { + env->DeleteGlobalRef(handler_obj); + handler_obj=NULL; + } + if (jhandler){ + handler_obj=env->NewGlobalRef(jhandler); + } +} + + diff --git a/java/common/org/linphone/core/LinphoneCoreFactory.java b/java/common/org/linphone/core/LinphoneCoreFactory.java index 88aa4343f..281d89e46 100644 --- a/java/common/org/linphone/core/LinphoneCoreFactory.java +++ b/java/common/org/linphone/core/LinphoneCoreFactory.java @@ -107,5 +107,8 @@ abstract public class LinphoneCoreFactory { */ abstract public LinphoneFriend createLinphoneFriend(); - + /** + * Create a LinphoneContent object + */ + abstract public LinphoneContent createLinphoneContent(String type, String subType, String data); } diff --git a/java/common/org/linphone/core/LinphoneCoreListener.java b/java/common/org/linphone/core/LinphoneCoreListener.java index d8487c69a..1d85a07ca 100644 --- a/java/common/org/linphone/core/LinphoneCoreListener.java +++ b/java/common/org/linphone/core/LinphoneCoreListener.java @@ -125,6 +125,13 @@ public interface LinphoneCoreListener { **/ void transferState(LinphoneCore lc, LinphoneCall call, LinphoneCall.State new_call_state); + /** + * Notifies an incoming INFO message. + * @param lc the LinphoneCore. + * @param info the info message + */ + void infoReceived(LinphoneCore lc, LinphoneInfoMessage info); + /**< @Deprecated Notifies the application that it should show up * @return */ void show(LinphoneCore lc); diff --git a/java/common/org/linphone/core/LinphoneLogHandler.java b/java/common/org/linphone/core/LinphoneLogHandler.java index 9465dccc7..ee88ee5f8 100644 --- a/java/common/org/linphone/core/LinphoneLogHandler.java +++ b/java/common/org/linphone/core/LinphoneLogHandler.java @@ -24,10 +24,10 @@ package org.linphone.core; */ public interface LinphoneLogHandler { public static final int Fatal=1<<4; - public static final int Error=1<<3|Fatal; - public static final int Warn=1<<2|Error; - public static final int Info=1<<1|Warn; - public static final int Debug=1|Info; + public static final int Error=1<<3; + public static final int Warn=1<<2; + public static final int Info=1<<1; + public static final int Debug=1; /** * Method invoked for each traces diff --git a/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java b/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java index d1bef5bf6..b3c638b68 100644 --- a/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java +++ b/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java @@ -140,10 +140,11 @@ public class LinphoneCoreFactoryImpl extends LinphoneCoreFactory { @Override public native void setDebugMode(boolean enable, String tag); + + private native void _setLogHandler(Object handler); @Override public void setLogHandler(LinphoneLogHandler handler) { - //not implemented on Android - + _setLogHandler(handler); } @Override @@ -172,4 +173,10 @@ public class LinphoneCoreFactoryImpl extends LinphoneCoreFactory { String passwd, String ha1, String realm) { return new LinphoneAuthInfoImpl(username,userid,passwd,ha1,realm); } + + @Override + public LinphoneContent createLinphoneContent(String type, String subType, + String data) { + return new LinphoneContentImpl(type,subType,data); + } } diff --git a/java/impl/org/linphone/core/LinphoneInfoMessageImpl.java b/java/impl/org/linphone/core/LinphoneInfoMessageImpl.java index 604fbc961..06c31dd42 100644 --- a/java/impl/org/linphone/core/LinphoneInfoMessageImpl.java +++ b/java/impl/org/linphone/core/LinphoneInfoMessageImpl.java @@ -4,7 +4,7 @@ public class LinphoneInfoMessageImpl implements LinphoneInfoMessage { protected long nativePtr; private LinphoneContent mContent; - private native Object getContent(long nativeptr); + private native Object getContent(long infoptr); public LinphoneInfoMessageImpl(long ptr){ nativePtr=ptr; mContent=(LinphoneContent)getContent(nativePtr);