6

I am trying to add PJSip to a project I am working on. I have this method for registering my account but a 'Fatal signal 11' error occurs everytime.

Here is the method

public int setRegistration() {
    int status = pjsuaConstants.PJ_FALSE;
    /* Register to SIP server by creating SIP account. */
    int[] accId = new int[1];
    accId[0] = 1;

    String uName = getUserName();
    String passwd = getPassword();
    String server = getSIPServer();

    pjsua_acc_config acc_cfg = new pjsua_acc_config();
    pjsua.acc_config_default(acc_cfg);

    acc_cfg.setId(pjsua.pj_str_copy("sip:" + uName + "@" + server));
    acc_cfg.setReg_uri(pjsua.pj_str_copy("sip:" + server));
    acc_cfg.setCred_count(1);

    acc_cfg.getCred_info().setRealm(pjsua.pj_str_copy(server));
    acc_cfg.getCred_info().setScheme(pjsua.pj_str_copy("digest"));
    acc_cfg.getCred_info().setUsername(pjsua.pj_str_copy(uName));
    acc_cfg.getCred_info().setData_type(pjsip_cred_data_type.PJSIP_CRED_DATA_PLAIN_PASSWD.swigValue());
    acc_cfg.getCred_info().setData(pjsua.pj_str_copy(passwd));

    Log.d("status", "acc is adding..");
    status = pjsua.acc_add(acc_cfg, pjsuaConstants.PJ_TRUE, accId);
    Log.d("status", "acc is added");

    if (status == pjsuaConstants.PJ_SUCCESS) {
        status = pjsua.acc_set_online_status(accId[0], 1);
        Log.d("acc_set_online_status returned stauts=", String.valueOf(status));
    } else {
        Log.d("Error status=", String.valueOf(status));
    }
    return status;
}

I receive the error on the status = pjsua.acc_add(acc_cfg, pjsuaConstants.PJ_TRUE, accId); line. I know that the username, server, and password are not null. I have looked at multiple questions relating to this and no use.

How can I register my account?

Thanks

*****EDIT****** After tracking down this through blogs and forums I got passed this error but received another. The reason this error occurred was because pjsua_init was never successful. It was successful because it gave me this error

11-04 10:19:20.973: E/AndroidRuntime(2961): FATAL EXCEPTION: main
11-04 10:19:20.973: E/AndroidRuntime(2961): java.lang.UnsatisfiedLinkError: Native method not found: org.pjsip.pjsua.pjsuaJNI.init:(JLorg/pjsip/pjsua/pjsua_config;JLorg/pjsip/pjsua/pjsua_logging_config;JLorg/pjsip/pjsua/pjsua_media_config;)I
11-04 10:19:20.973: E/AndroidRuntime(2961):     at org.pjsip.pjsua.pjsuaJNI.init(Native Method)
11-04 10:19:20.973: E/AndroidRuntime(2961):     at org.pjsip.pjsua.pjsua.init(pjsua.java:812)

I have received this warning as well

No implementation found for native Lorg/pjsip/pjsua/pjsuaJNI;.init (JLorg/pjsip/pjsua/pjsua_config;JLorg/pjsip/pjsua/pjsua_logging_config;JLorg/pjsip/pjsua/pjsua_media_config;)I

Why isn't this a native method? I am looking into the libraries I have called but other than that I don't know why this isn't working.

Any help on this matter would be great. Thanks

PJ Code

pjsua.java

public synchronized static int init(pjsua_config ua_cfg, pjsua_logging_config log_cfg, pjsua_media_config media_cfg) {
   return pjsuaJNI.init(pjsua_config.getCPtr(ua_cfg), ua_cfg, pjsua_logging_config.getCPtr(log_cfg), log_cfg, pjsua_media_config.getCPtr(media_cfg), media_cfg);
}

pjsuaJNI.java

public final static native int init(long jarg1, pjsua_config jarg1_, long jarg2, pjsua_logging_config jarg2_, long jarg3, pjsua_media_config jarg3_);

pjsua_wrap.cpp

SWIGEXPORT jint JNICALL Java_org_pjsip_pjsua_pjsuaJNI_init(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_, jlong jarg3, jobject jarg3_) {
   jint jresult = 0 ;
   pjsua_config *arg1 = (pjsua_config *) 0 ;
   pjsua_logging_config *arg2 = (pjsua_logging_config *) 0 ;
   pjsua_media_config *arg3 = (pjsua_media_config *) 0 ;
   pj_status_t result;

   (void)jenv;
   (void)jcls;
   (void)jarg1_;
   (void)jarg2_;
   (void)jarg3_;
   arg1 = *(pjsua_config **)&jarg1;
   arg2 = *(pjsua_logging_config **)&jarg2;
   arg3 = *(pjsua_media_config **)&jarg3;

   result = (pj_status_t)pjsua_init((pjsua_config const *)arg1,(pjsua_logging_config const *)arg2,(pjsua_media_config const *)arg3);
   jresult = (jint)result;
   return jresult;
}

{"init", "(JLorg/pjsip/pjsua/pjsua_config;JLorg/pjsip/pjsua/pjsua_logging_config;JLorg/pjsip/pjsua/pjsua_media_config;)I", (void*)& Java_org_pjsip_pjsua_pjsuaJNI_init},

EDIT 2

So after working on this I have gotten to a point of frustration. I am not seeing what I am doing wrong so I will put my entire process here to see if someone has a suggestion.

  1. I start by getting the pjsip library: svn co http://svn.pjsip.org/repos/pjproject/trunk pjproject
  2. run `./configure --prefix=/usr/local
  3. make dep & make
  4. sudo make install

  5. I then get the pjjni code svn checkout svn://svn.code.sf.net/p/pjsip-jni/code/ pjsip-jni-code

  6. I follow the Makefile instructions
  7. After Makefile runs successfully (after some code cleanup) I have 2 .so files (libpjsua_jni.so and libpjsua_jni_x64.so)
  8. Create jni folder with Android.mk file and .so libraries
  9. Run ndk-build (How to load another .so file in your android project?)
  10. Add to ADT
  11. Close project. Change native support from Java to Android. Open project (Convert existing project into Android project in Eclipse?)
  12. Add that project to my TestPJ project (Android -> Library -> Add)
  13. Call System.loadLibrary("pjsualib") -- Name of the new lib.so
  14. Receive Error

    11-22 13:55:44.784: W/dalvikvm(11464): No implementation found for native Lorg/pjsip/pjsua/pjsuaJNI;.swig_module_init:()V 11-22 13:55:48.792: W/dalvikvm(11464): Exception Ljava/lang/UnsatisfiedLinkError; thrown while initializing Lorg/pjsip/pjsua/pjsuaJNI; 11-22 13:55:51.417: E/AndroidRuntime(11464): java.lang.UnsatisfiedLinkError: Native method not found: org.pjsip.pjsua.pjsuaJNI.swig_module_init:()V 11-22 13:55:51.417: E/AndroidRuntime(11464): at org.pjsip.pjsua.pjsuaJNI.swig_module_init(Native Method) 11-22 13:55:51.417: E/AndroidRuntime(11464): at org.pjsip.pjsua.pjsuaJNI.(pjsuaJNI.java:1450)

Any help would be great. Thanks!

Community
  • 1
  • 1
BigT
  • 1,413
  • 5
  • 24
  • 52
  • where is your SIPServer, constant or variable, set? what is the value. where is the username set and what is the current value? – alinoz Oct 21 '13 at 11:52
  • They are set in the saveUserInfo method. That is getting called and the values are being filled in. I don't see a need to give my server and username information – BigT Oct 22 '13 at 13:57
  • you don't have to give me the information but you must make sure they are not null when you reach that lines. from the errors i am seeing is possible that this 2 variables are null. you can try to put a breakpoint there and have a look at what values are stored in the SIPServer and userName variables. – alinoz Oct 22 '13 at 17:43
  • Even if I hard code them the lines after through the error. I get to the `pjsua.csipsimple_set_acc_user_data(cfg, css_cfg);` line and then a fatal error occurs. – BigT Oct 22 '13 at 18:01
  • Are you calling [pjsua_create()](http://www.pjsip.org/pjsip/docs/html/group__PJSUA__LIB__BASE.htm#ga2bb341e9b189b6716d146519f84e0d72) and [pjsua_init(...)](http://www.pjsip.org/pjsip/docs/html/group__PJSUA__LIB__BASE.htm#ga72ccd5cc7dbf6f26b4ffedc0d9728a2d) before `acc_add(...)`? – Vikram Nov 02 '13 at 22:52
  • @user2558882 I have called those but I received an error on pjsua_init. See edit. – BigT Nov 04 '13 at 15:31
  • @BigT What version of pjsip you are using? Some android port? – Michael Nov 05 '13 at 15:39
  • @Michael The one from the repository. So i think 2.2. – BigT Nov 05 '13 at 16:24
  • @BigT Did you check this JNI method? Looks like it is wrong (maybe it has different signature). I mean org_pjsip_pjsua_pjsuaJNI_init() – Michael Nov 05 '13 at 16:26
  • @Michael this is a native method though. What do you mean that it has a different signature? – BigT Nov 05 '13 at 16:36
  • @BigT Sorry, I mixed my thoughts a little. This error means that JNI cannot find native method which matches to java method. So there can be two reasons: java method has a signature || class || package which doesn't correspond to native method or native method has a name/list of parameters which doesn't correspond to java method. I had some similar problems but with linphone library. – Michael Nov 05 '13 at 16:45
  • @Michael Do you mind displaying an answer with your thoughts – BigT Nov 05 '13 at 16:50
  • @BigT Done. Maybe it will helpful to you. And not sure how pjsip Java interface is organized in details but if it is too complex or inconvenient you can use its native interface, build a C/C++ wrapper to it and explore a simplest JNI calls with elementary parameters (string, int, double etc) to access this wrapper from your Java code. – Michael Nov 05 '13 at 19:13

2 Answers2

3

An example of project which explores JNI calls from Java and from C can be found here.
The error mentioned in the question (java.lang.UnsatisfiedLinkError: Native method not found: org.pjsip.pjsua.pjsuaJNI) means one of the following problems:

- wrong native method name or/and its arguments/return value. If you have access to native code of the library than you can fix it. According to the error message and JNI considerations native method must have name Java_org_pjsip_pjsua_pjsuaJNI_init(JNIEnv *env, jobject obj, ..), where env is a pointer to JVM interface, obj is a "this" pointer and the remaining arguments can be determined from java init method of pjsuaJNI class of package org.pjsip.pjsua. Simple parameter types must be jint, jstring etc. Also return value must be correct as well. Fixing all these allows to use this method from pjsuaJNI class. Additional details can be found from Oracle Documentation to Oracle Documentation to Java 6 JNI (or Java 7 if you're using android 4.4).

- wrong java method name/signature/class name or package name. This case is almost reverse to the first one. Again, according to the mentioned error name of the method must be "init", class name pjsuaJNI and package org.pjsip.pjsua. If at least one of them is wrong the mentioned exception will happen. Signature or parameters must also be correct. In the boundaries of this error it can be considered as a parameters of the method (in addition in native JNIEnv* and jobject appears). So also must be checked and fixed if necessary.
In case of call from native code to java signature can be considered as a representation of java method with parameters as a string and can be viewed with javap -s *.class command applied to java *.class file. And in the last warning from question this signature of the method can be seen.

Also to use method pjsip library must be loaded with System.loadLibrary() in some static section of the Java class.

Unfortunately, this problem happens at runtime (it would be nice if it happened during compilation time).

Michael
  • 1,505
  • 14
  • 26
  • I am pretty sure I followed everything you said in your answer. I added the code above if I missed something and someone else see it – BigT Nov 05 '13 at 19:37
  • @BigT Did you try to generate C header for pjsuaJNI.java with javah utility and compare its output with a native functions from pjsua_wrap.cpp? – Michael Nov 05 '13 at 20:06
  • How would I create the pjsuaJNI header? – BigT Nov 05 '13 at 20:09
  • You have to compile project and that use next command from root of the project (may need some modifications - sdk path etc): javah -bootclasspath $ANDROID_SDK_ROOT/platforms/android-17/android.jar -classpath bin/classes org.pjsip.pjsua.pjsuaJNI – Michael Nov 05 '13 at 20:14
  • @BigT Also try using extern "C" for native function definition or extern "C" { } to wrap all the native calls. – Michael Nov 05 '13 at 20:21
  • @BigT And the last thing - do you really need static modificator in Java code for init function? I guess removing it should fix the problem. – Michael Nov 05 '13 at 20:31
0

It's a bit late but I'll try to help on this. I think that your problem should be related to your native method not been surrounded by extern "C"{} and name mangling in C++.

If you don't declare one native C function as extern "C", C++ build mangles it and JNI mechanism can not find native method matching provided signature. On the other hand, declaring it as external C function, the builder creates both, mangled and unmanged, versions and JNI can find the proper one.

Hope this helps.

jcm
  • 2,568
  • 14
  • 18