Android上的JainSip:发送REGISTER抛出异常

时间:2013-01-05 13:54:00

标签: java android multithreading sip jain-sip

在过去的几天里,我试图让JAIN SIP在Android上运行。我采用了一些在Java应用程序上运行良好的代码,并将其移植到Android应用程序中。

我查了一下:

  • 清单中的权限(INTERNET / ALL)
  • JAIN SIP API工作正常(stackoverflow上的其他线程重点关注)。
  • 通信在自己的线程上运行,而不是MainThread。
  • IP有效。
  • 如果我没有使用Android作为平台而是使用Ubuntu,则代码可以正常运行。
  • 我尝试过Android 4.0.3及更高版本。

我的代码:

public class MainActivity extends Activity implements SipListener {

private static final String LOG = "JAIN";
private static final int PORT = 5060;
private SipFactory mSipFactory;
private AddressFactory mAddressFactory;
private MessageFactory mMessageFacory;
private HeaderFactory mHeaderFactory;
private SipStack mSipStack;
private SipProvider mSipProvider;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    new Thread(new Runnable(){

        @Override
        public void run() {
            try {
                // Create factories
                mSipFactory = SipFactory.getInstance();
                mAddressFactory = mSipFactory.createAddressFactory();
                mMessageFacory = mSipFactory.createMessageFactory();
                mHeaderFactory = mSipFactory.createHeaderFactory();

                // Create the SipStack
                Properties properties = new Properties();
                properties.setProperty("javax.sip.STACK_NAME","Stack");
                mSipStack = mSipFactory.createSipStack(properties);

                // Create the SipProvider 
                String localIP = InetAddress.getLocalHost().getHostAddress();
                ListeningPoint listeningPoint = mSipStack
                        .createListeningPoint(localIP, PORT, "udp");
                mSipProvider = mSipStack.createSipProvider(listeningPoint);
                mSipProvider.addSipListener(MainActivity.this);

                // Create addresses and via header for the request
                Address fromToAddress = mAddressFactory
                        .createAddress("sip:192.168.0.198");
                Address contactAddress = mAddressFactory
                        .createAddress("sip:me@192.168.0.195");
                ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
                ViaHeader myViaHeader = mHeaderFactory
                        .createViaHeader("me.bla.com", PORT, "udp", "tlf64");
                viaHeaders.add(myViaHeader);

                // Build the request
                final Request request = mMessageFacory.createRequest(
                        mAddressFactory.createAddress("sip:192.168.0.195:9876").getURI(), 
                        "REGISTER",
                        mHeaderFactory.createCallIdHeader("12345678"),
                        mHeaderFactory.createCSeqHeader(1234l, "REGISTER"), 
                        mHeaderFactory.createFromHeader(fromToAddress, "sdf6"),
                        mHeaderFactory.createToHeader(fromToAddress, null), 
                        viaHeaders, 
                        mHeaderFactory.createMaxForwardsHeader(70));

                // Add the contact header
                request.addHeader(mHeaderFactory.createContactHeader(contactAddress));

                // Print the request
                System.out.println(request.toString());

                // Send the request --- triggers an IOException
                mSipProvider.sendRequest(request);
            } catch (Exception e) {
                Log.d(LOG, Log.getStackTraceString(e));
            }
        }}).start();
}

正如您在StackTrace中看到的,发生IOException:

javax.sip.SipException: IO Exception occured while Sending Request
at gov.nist.javax.sip.SipProviderImpl.sendRequest(SipProviderImpl.java:722)
at com.example.jainsiptest.MainActivity$1.run(MainActivity.java:97)
at java.lang.Thread.run(Thread.java:856)
 Caused by: java.net.SocketException: sendto failed: EINVAL (Invalid argument)
at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:506)
at libcore.io.IoBridge.sendto(IoBridge.java:475)
at java.net.PlainDatagramSocketImpl.send(PlainDatagramSocketImpl.java:182)
at java.net.DatagramSocket.send(DatagramSocket.java:284)
at gov.nist.javax.sip.stack.UDPMessageChannel.sendMessage(UDPMessageChannel.java:724)
at gov.nist.javax.sip.stack.MessageChannel.sendMessage(MessageChannel.java:222)
at gov.nist.javax.sip.SipProviderImpl.sendRequest(SipProviderImpl.java:711)
... 2 more
 Caused by: libcore.io.ErrnoException: sendto failed: EINVAL (Invalid argument)
at libcore.io.Posix.sendtoBytes(Native Method)
at libcore.io.Posix.sendto(Posix.java:151)
at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:177)
at libcore.io.IoBridge.sendto(IoBridge.java:473)
... 7 more

java.net.SocketException: sendto failed: EINVAL (Invalid argument)
在具有相同参数的Ubuntu上不会抛出

有任何想法如何修复它?非常感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

似乎Android OS以与Ubuntu OS不同的方式处理给定的Strings。我不知道为什么。


毕竟,我通过使用MjSip而不是JAIN SIP来解决问题。

由于我需要RTP,SDP以及SIP旁边的一些东西,我决定修改使用MjSip 1.6的开源Android App Sipdroid,直到它符合我的要求。

  1. 为此,请先获取code

  2. 将项目导入Eclipse:文件 - &gt;导入 - &gt;现有的Android代码进入工作区。

  3. 根据API等级创建一个满足您需求的新Android项目。

  4. <uses-permission android:name="android.permission.INTERNET" />添加到项目的清单中。

  5. 将Sipdroid项目中的以下所有软件包复制到您的项目中:

    • org.sipdroid.codecs和org.sipdroid.media(我不需要,也许以后)
    • org.sipdroid.sipua和subpackages。
  6. 删除或评论损坏的参考文献。

  7. 请参阅以下代码,将REGISTER发送到服务器。

  8. 使用android.util.Log而不是给定代码修复Log机制抛出的Exeptions。最后,删除或注释触发NullPointerException的flush命令。

  9. 就是这样。

    import org.zoolu.sip.address.NameAddress;
    import org.zoolu.sip.message.Message;
    import org.zoolu.sip.message.MessageFactory;
    import org.zoolu.sip.provider.SipProvider;
    import org.zoolu.sip.provider.SipStack;
    import org.zoolu.sip.transaction.TransactionClient;
    import org.zoolu.sip.transaction.TransactionClientListener;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.Menu;
    
    public class MainActivity extends Activity implements TransactionClientListener{
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        new Thread(new Runnable(){
    
            @Override
            public void run() {
                try{
                    SipStack.init();
    
                    SipProvider sipProvider = new SipProvider(
                            "192.168.0.198", 5060, new String[]{"udp"}, null);
                    NameAddress toAddress = new NameAddress(
                            "sip:192.168.0.195:9876");
                    NameAddress fromAddress = new NameAddress(
                            "sip:192.168.0.198:9876");
    
                    Message message = MessageFactory.createRegisterRequest(
                            sipProvider, 
                            toAddress, 
                            fromAddress, 
                            fromAddress, 
                            null, 
                            null);
    
                    TransactionClient t = new TransactionClient(
                            sipProvider, 
                            message,
                            MainActivity.this);
    
                    t.request();
    
                }catch(Exception e){
                    Log.d("MYSIP", Log.getStackTraceString(e));
                }
            }}).start();
    }
    
    // Interface methods
    
    }
    

答案 1 :(得分:0)

而不是将localIPAddress取为:

String localIP = InetAddress.getLocalHost().getHostAddress();

使用NetworkInterfaceWifiManager

获取IP地址