【问题标题】:SIP ACK Dialog is nullSIP ACK 对话框为空
【发布时间】:2015-04-22 20:23:48
【问题描述】:

我正在使用 JAIN SIP 在 java 中创建一个 SIP 客户端。

我已成功注册并发送 INVITE,但是当将 ACK 发送回服务器时,我收到错误消息:

Cannot Create ACK - no remote Target

我检查了对话框的值,它是空的

在processResponce()中,我得到的值也是null

this.dialog = responseEvent.getClientTransaction().getDialog();

我将它传递给 ack(responseEvent.getResponse(), dialog)

request =this.dialog.createAck(((CSeqHeader)response.getHeader("CSeq")).getSeqNumber());
dialog.sendAck(request);

也在Register()和Call()中

this.dialog = inviteTid.getDialog();

这里dialog的值也是null

我也试过

dialog = sipProvider.getNewDialog(inviteID);

但它给出的错误为

AUTOMATIC_DIALOG_SUPPORT is on

我是否必须初始化对话框或进行更多调用才能设置其值?

如何实现 ACK?

REGISTER sip:SipIP SIP/2.0
Call-ID: b83eb80b195f6802c283c5927fb6415a@localHost
CSeq: 1 REGISTER
From: <sip:username@SipIP>;tag=1626086046
To: <sip:username@SipIP>
Via: SIP/2.0/UDP localHost:52216;rport;branch=z9hG4bK-363935-33f876b2e3720a123b62c68fc23cfa68
Max-Forwards: 70
Contact: <sip:username@localHost:52216;transport=UDP>
Content-Length: 0

SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP localHost:52216;branch=z9hG4bK-363935-33f876b2e3720a123b62c68fc23cfa68;received=localHost;rport=52216
From: <sip:username@SipIP>;tag=1626086046
To: <sip:username@SipIP>;tag=as3c3695d2
Call-ID: b83eb80b195f6802c283c5927fb6415a@localHost
CSeq: 1 REGISTER
Server: Asterisk PBX 10.5.1
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH
Supported: replaces,timer
WWW-Authenticate: Digest algorithm=MD5,realm="xyz.com",nonce="65dfb3ad"
Content-Length: 0


REGISTER sip:SipIP SIP/2.0
Call-ID: b83eb80b195f6802c283c5927fb6415a@localHost
CSeq: 2 REGISTER
From: <sip:username@SipIP>;tag=1626086046
To: <sip:username@SipIP>
Via: SIP/2.0/UDP localHost:52216;rport;branch=z9hG4bK-363935-150b07c1e9409d05aafaa7652859024a
Max-Forwards: 70
Contact: <sip:username@localHost:52216;transport=UDP>
Authorization: Digest username="username",realm="xyz.com",nonce="65dfb3ad",uri="sip:SipIP",algorithm=MD5,response="b34005eb8ded9180fb5f5667f1ee842d"
Content-Length: 0


---------------------------Registered200--------------------

SIP/2.0 200 OK
Via: SIP/2.0/UDP localHost:52216;branch=z9hG4bK-363935-    150b07c1e9409d05aafaa7652859024a;received=localHost;rport=52216
From: <sip:username@SipIP>;tag=1626086046
To: <sip:username@SipIP>;tag=as3c3695d2
Call-ID: b83eb80b195f6802c283c5927fb6415a@localHost
CSeq: 2 REGISTER
Server: Asterisk PBX 10.5.1
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH
Supported: replaces,timer
Expires: 240
Contact: <sip:username@localHost:52216;transport=UDP>;expires=240
Date: Wed, 22 Apr 2015 23:52:44 GMT
Content-Length: 0


Dialog created: gov.nist.javax.sip.stack.SIPDialog@d15ad713
Dialog: gov.nist.javax.sip.stack.SIPDialog@d15ad713

INVITE sip:SipIP SIP/2.0
Call-ID: b83eb80b195f6802c283c5927fb6415a@localHost
CSeq: 3 INVITE
From: <sip:username@SipIP>;tag=1626086046
To: <sip:160@SipIP>
Via: SIP/2.0/UDP localHost:52216;rport;branch=z9hG4bK-363935-3d3a34f99499b96c6c1f709065ed4c85
Max-Forwards: 70
Content-Type: application/sdp
Contact: <sip:username@localHost:52216;transport=UDP>
Content-Length: 300

v=0
o=fraunhofer 392867480 292042336 IN IP4 localHost
s=-
c=IN IP4 localHost
t=0 0
m=audio 8000 RTP/AVP 0 8 101
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=sendrecv
------------------Invite 401--------------------

SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP localHost:52216;branch=z9hG4bK-363935-        3d3a34f99499b96c6c1f709065ed4c85;received=localHost;rport=52216
From: <sip:username@SipIP>;tag=1626086046
To: <sip:160@SipIP>;tag=as3c3695d2
Call-ID: b83eb80b195f6802c283c5927fb6415a@localHost
CSeq: 3 INVITE
Server: Asterisk PBX 10.5.1
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH
Supported: replaces,timer
WWW-Authenticate: Digest algorithm=MD5,realm="xyz.com",nonce="4c1d89c8"
Content-Length: 0


-------------------------Dialog:gov.nist.javax.sip.stack.SIPDialog@d15ad713
Dialog get Remote Target: null
javax.sip.SipException: Cannot create ACK - no remote Target!
at gov.nist.javax.sip.stack.SIPDialog.createAck(SIPDialog.java:3021)
at test.ack(test.java:507)
at test.processResponse(test.java:214)
at gov.nist.javax.sip.EventScanner.deliverEvent(EventScanner.java:296)
at gov.nist.javax.sip.EventScanner.run(EventScanner.java:519)
at java.lang.Thread.run(Thread.java:745)

更改呼叫 ID 的新响应

REGISTER sip:SIPIP SIP/2.0
Call-ID: 01bb8e9788fc251f8d44f2c709542fa5@LOCALIP
CSeq: 1 REGISTER
From: <sip:username@SIPIP>;tag=2125326583
To: <sip:username@SIPIP>
Via: SIP/2.0/UDP LOCALIP:52216;rport;branch=z9hG4bK-3833-142aff6ad1e359c2b618eba23fa04453
Max-Forwards: 70
Contact: <sip:username@LOCALIP:52216;transport=UDP>
Content-Length: 0

SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP LOCALIP:52216;branch=z9hG4bK-3833-142aff6ad1e359c2b618eba23fa04453;received=LOCALIP;rport=52216
From: <sip:username@SIPIP>;tag=2125326583
To: <sip:username@SIPIP>;tag=as2e8e5e8d
Call-ID: 01bb8e9788fc251f8d44f2c709542fa5@LOCALIP
CSeq: 1 REGISTER
Server: Asterisk PBX 10.5.1
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH
Supported: replaces,timer
WWW-Authenticate: Digest algorithm=MD5,realm="xyz.com",nonce="6223df47"
Content-Length: 0


REGISTER sip:SIPIP SIP/2.0
Call-ID: 01bb8e9788fc251f8d44f2c709542fa5@LOCALIP
CSeq: 2 REGISTER
From: <sip:username@SIPIP>;tag=2125326583
To: <sip:username@SIPIP>
Via: SIP/2.0/UDP LOCALIP:52216;rport;branch=z9hG4bK-3833-36d48a4c062bbb9e83db9a12f36414b3
Max-Forwards: 70
Contact: <sip:username@LOCALIP:52216;transport=UDP>
Authorization: Digest username="username",realm="xyz.com",nonce="6223df47",uri="sip:SIPIP",algorithm=MD5,response="d4ac55bbc8dacb87f66cf9f4041af03c"
Content-Length: 0


---------------------------Registered200--------------------

SIP/2.0 200 OK
Via: SIP/2.0/UDP LOCALIP:52216;branch=z9hG4bK-3833-36d48a4c062bbb9e83db9a12f36414b3;received=LOCALIP;rport=52216
From: <sip:username@SIPIP>;tag=2125326583
To: <sip:username@SIPIP>;tag=as2e8e5e8d
Call-ID: 01bb8e9788fc251f8d44f2c709542fa5@LOCALIP
CSeq: 2 REGISTER
Server: Asterisk PBX 10.5.1
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH
Supported: replaces,timer
Expires: 240
Contact: <sip:username@LOCALIP:52216;transport=UDP>;expires=240
Date: Thu, 23 Apr 2015 08:38:28 GMT
Content-Length: 0


Dialog: createdgov.nist.javax.sip.stack.SIPDialog@977c31a5
INVITE sip:SIPIP SIP/2.0
Call-ID: a86cc90138ad50d9716664b7925cb205@LOCALIP
CSeq: 3 INVITE
From: <sip:username@SIPIP>;tag=2125326583
To: <sip:160@SIPIP>
Via: SIP/2.0/UDP LOCALIP:52216;rport;branch=z9hG4bK-            3833-0db5ef4b4e463aee4fa22c3379915d5e
Max-Forwards: 70
Content-Type: application/sdp
Contact: <sip:username@LOCALIP:52216;transport=UDP>
Content-Length: 300

v=0
o=fraunhofer 392867480 292042336 IN IP4 LOCALIP
s=-
c=IN IP4 LOCALIP
t=0 0
m=audio 8000 RTP/AVP 0 8 101
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=sendrecv
------------------Invite 401--------------------

SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP LOCALIP:52216;branch=z9hG4bK-   3833-0db5ef4b4e463aee4fa22c3379915d5e;received=LOCALIP;rport=52216
From: <sip:username@SIPIP>;tag=2125326583
To: <sip:160@SIPIP>;tag=as54bd3315
Call-ID: a86cc90138ad50d9716664b7925cb205@LOCALIP
CSeq: 3 INVITE
Server: Asterisk PBX 10.5.1
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH
Supported: replaces,timer
WWW-Authenticate: Digest algorithm=MD5,realm="xyz.com",nonce="1e960014"
Content-Length: 0

呼叫(响应)

enterpublic void call(Response response) {
    try {
        cseq++;
        String callee = "160";
        current_process = cseq + "INVITE";
        ArrayList viaHeaders = new ArrayList();
        ViaHeader viaHeader = headerFactory.createViaHeader(localIP,
                rport, "udp", null);
        viaHeader.setRPort();
        viaHeaders.add(viaHeader);
        // The "Max-Forwards" header.
        MaxForwardsHeader maxForwardsHeader = headerFactory.createMaxForwardsHeader(70);
        // The "Call-Id" header.
        CallIdHeader callIdHeader = this.sipProvider.getNewCallId();;
        // The "CSeq" header.
        CSeqHeader cSeqHeader = headerFactory.createCSeqHeader(cseq, "INVITE");

        Address fromAddress = addressFactory.createAddress("sip:"
                + username + '@' + server);

        Address toAddress = addressFactory.createAddress("sip:"+callee+'@'+sipIP);

        FromHeader fromHeader = headerFactory.createFromHeader(
                fromAddress, String.valueOf(this.tag));
        // The "To" header.
        ToHeader toHeader = headerFactory.createToHeader(toAddress,
                null);

        ContentLengthHeader contentLength = headerFactory.createContentLengthHeader(211);
        ContentTypeHeader contentType = headerFactory.createContentTypeHeader("application", "sdp");

        String sdpData = "v=0\n" + 
                "o=user1 795808818 480847547 IN IP4 10.99.70.106\n" + 
                "s=-\n" + 
                "c=IN IP4 10.99.70.106\n" + 
                "t=0 0\n" + 
                "m=audio 8000 RTP/AVP 0 8 101\n" + 
                "a=rtpmap:0 PCMU/8000\n" + 
                "a=rtpmap:8 PCMA/8000\n" + 
                "a=rtpmap:101 telephone-event/8000\n" + 
                "a=sendrecv";
         byte[] contents = sdpData.getBytes();
         this.contactHeader = this.headerFactory
         .createContactHeader(contactAddress);

         URI requestURI = addressFactory.createURI("sip:"
                +callee+ '@'+ server); 

        request = this.messageFactory.createRequest(requestURI, Request.INVITE, 
                callIdHeader,cSeqHeader, fromHeader, toHeader, viaHeaders, maxForwardsHeader, contentType, contents);

        request.addHeader(contactHeader);
        request.addHeader(contentLength);
        test listener =this;
        if (response != null) {
            boolean retry = true;
            System.out.println("DEBUG: Response: "+response);
        }
        listener.inviteTid = sipProvider.getNewClientTransaction(request);


        if(dialog!= null && logger.isDebugEnabled()){
            logger.debug("Obtain dialog from ClientTransaction: automatic dialog support on");
//              System.out.println("Obtain dialog from ClientTransaction: automatic dialog support on");
        }
        if(dialog == null){
            //Automatic Dialog support turned off

            dialog = sipProvider.getNewDialog(inviteTid);

        }
        System.out.println("Dialog: created" + dialog);
        // send the request out.
        listener.inviteTid.sendRequest();

        this.dialog = this.inviteTid.getDialog();
 //         System.out.println("Dialog:" + dialog);

        // Send the request statelessly through the SIP provider.
        // this.sipProvider.sendRequest(request);
        System.out.println(request.toString());
        // Display the message in the text area.
        logger.debug("Request sent:\n" + "\n\n");
    } catch (Exception e) {
        // If an error occurred, display the error.
        e.printStackTrace();
        logger.debug("Request sent failed: " + e.getMessage() + "\n");
    }
}

无法创建 ACK 的日志 - 没有远程目标

enter REGISTER sip:localIP SIP/2.0
Call-ID: 5fd6c07f15259d4aaeabdfb9e306cd12@10.99.136.136
CSeq: 1 REGISTER
From: <sip:username@localIP>;tag=1825098223
To: <sip:username@localIP>
Via: SIP/2.0/UDP 10.99.136.136:52216;rport;branch=z9hG4bK-363735-0dd0a58b853bb23070f706fc3b058461
Max-Forwards: 70
Contact: <sip:username@10.99.136.136:52216;transport=UDP>
Content-Length: 0


-----------StatusCode:401----------------------------
-----------currentREsponse:Unauthorized----------------------------
SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 10.99.136.136:52216;branch=z9hG4bK-    363735-0dd0a58b853bb23070f706fc3b058461;received=10.99.136.136;rport=52216
From: <sip:username@localIP>;tag=1825098223
To: <sip:username@localIP>;tag=as78941717
Call-ID: 5fd6c07f15259d4aaeabdfb9e306cd12@10.99.136.136
CSeq: 1 REGISTER
Server: Asterisk PBX 10.5.1
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH
Supported: replaces,timer
WWW-Authenticate: Digest algorithm=MD5,realm="xyz.com",nonce="49a39764"
Content-Length: 0


REGISTER sip:localIP SIP/2.0
Call-ID: 5fd6c07f15259d4aaeabdfb9e306cd12@10.99.136.136
CSeq: 2 REGISTER
From: <sip:username@localIP>;tag=1825098223
To: <sip:username@localIP>
Via: SIP/2.0/UDP 10.99.136.136:52216;rport;branch=z9hG4bK-363735-0a214e6d4a1bc50c0faf1657cf109e31
Max-Forwards: 70
Contact: <sip:username@10.99.136.136:52216;transport=UDP>
Authorization: Digest username="username",realm="xyz.com",nonce="49a39764",uri="sip:localIP",algorithm=MD5,response="1af91bd8169339ec8c77decfab59fd21"
Content-Length: 0


-----------StatusCode:200----------------------------
-----------currentREsponse:OK----------------------------
SIP/2.0 200 OK
Via: SIP/2.0/UDP 10.99.136.136:52216;branch=z9hG4bK-    363735-0a214e6d4a1bc50c0faf1657cf109e31;received=10.99.136.136;rport=52216
From: <sip:username@localIP>;tag=1825098223
To: <sip:username@localIP>;tag=as78941717
Call-ID: 5fd6c07f15259d4aaeabdfb9e306cd12@10.99.136.136
CSeq: 2 REGISTER
Server: Asterisk PBX 10.5.1
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH
Supported: replaces,timer
Expires: 240
Contact: <sip:username@10.99.136.136:52216;transport=UDP>;expires=240
Date: Fri, 24 Apr 2015 16:58:50 GMT
Content-Length: 0


---------------------------Registered: 200--------------------

SIP/2.0 200 OK
Via: SIP/2.0/UDP 10.99.136.136:52216;branch=z9hG4bK-363735-0a214e6d4a1bc50c0faf1657cf109e31;received=10.99.136.136;rport=52216
From: <sip:username@localIP>;tag=1825098223
To: <sip:username@localIP>;tag=as78941717
Call-ID: 5fd6c07f15259d4aaeabdfb9e306cd12@10.99.136.136
CSeq: 2 REGISTER
Server: Asterisk PBX 10.5.1
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH
Supported: replaces,timer
Expires: 240
Contact: <sip:username@10.99.136.136:52216;transport=UDP>;expires=240
Date: Fri, 24 Apr 2015 16:58:50 GMT
Content-Length: 0


DEBUG: Response: SIP/2.0 200 OK
Via: SIP/2.0/UDP 10.99.136.136:52216;branch=z9hG4bK-    363735-0a214e6d4a1bc50c0faf1657cf109e31;received=10.99.136.136;rport=52216
From: <sip:username@localIP>;tag=1825098223
To: <sip:username@localIP>;tag=as78941717
Call-ID: 5fd6c07f15259d4aaeabdfb9e306cd12@10.99.136.136
CSeq: 2 REGISTER
Server: Asterisk PBX 10.5.1
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH
Supported: replaces,timer
Expires: 240
Contact: <sip:username@10.99.136.136:52216;transport=UDP>;expires=240
Date: Fri, 24 Apr 2015 16:58:50 GMT
Content-Length: 0


Dialog: createdgov.nist.javax.sip.stack.SIPDialog@393895ed
INVITE sip:160@localIP SIP/2.0
Call-ID: 5fd6c07f15259d4aaeabdfb9e306cd12@10.99.136.136
CSeq: 3 INVITE
From: <sip:username@localIP>;tag=1825098223
To: <sip:160@localIP>
Via: SIP/2.0/UDP 10.99.136.136:52216;rport;branch=z9hG4bK-363735-312eacb8db309d6c6794e2eb7adf8b92
Max-Forwards: 70
Content-Type: application/sdp
Contact: <sip:username@10.99.136.136:52216;transport=UDP>
Authorization: Digest username="username",realm="xyz.com",nonce="49a39764",uri="sip:localIP",algorithm=MD5,response="1af91bd8169339ec8c77decfab59fd21"
Content-Length: 211

v=0
o=user1 795808818 480847547 IN IP4 localIP
s=-
c=IN IP4 localIP
t=0 0
m=audio 8000 RTP/AVP 0 8 101
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=sendrecv


Request OPTIONSreceived at stackwith server transaction idnull
-----------StatusCode:401----------------------------
-----------currentREsponse:Unauthorized----------------------------
------------------Invite 401--------------------

SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 10.99.136.136:52216;branch=z9hG4bK-    363735-312eacb8db309d6c6794e2eb7adf8b92;received=10.99.136.136;rport=52216
From: <sip:username@localIP>;tag=1825098223
To: <sip:160@localIP>;tag=as4f6f7f78
Call-ID: 5fd6c07f15259d4aaeabdfb9e306cd12@10.99.136.136
CSeq: 3 INVITE
Server: Asterisk PBX 10.5.1
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH
Supported: replaces,timer
WWW-Authenticate: Digest algorithm=MD5,realm="xyz.com",nonce="7e048345"
Content-Length: 0


DEBUG: Response: SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 10.99.136.136:52216;branch=z9hG4bK-363735-312eacb8db309d6c6794e2eb7adf8b92;received=10.99.136.136;rport=52216
From: <sip:username@localIP>;tag=1825098223
To: <sip:160@localIP>;tag=as4f6f7f78
Call-ID: 5fd6c07f15259d4aaeabdfb9e306cd12@10.99.136.136
CSeq: 3 INVITE
Server: Asterisk PBX 10.5.1
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH
Supported: replaces,timer
WWW-Authenticate: Digest algorithm=MD5,realm="xyz.com",nonce="7e048345"
Content-Length: 0


Dialog: createdgov.nist.javax.sip.stack.SIPDialog@393895ed
INVITE sip:160@localIP SIP/2.0
Call-ID: 5fd6c07f15259d4aaeabdfb9e306cd12@10.99.136.136
CSeq: 4 INVITE
From: <sip:username@localIP>;tag=1825098223
To: <sip:160@localIP>
Via: SIP/2.0/UDP 10.99.136.136:52216;rport;branch=z9hG4bK-363735-dae4419c9405bb40dda573fe9c276518
Max-Forwards: 70
Content-Type: application/sdp
Contact: <sip:username@10.99.136.136:52216;transport=UDP>
Authorization: Digest username="username",realm="xyz.com",nonce="49a39764",uri="sip:localIP",algorithm=MD5,response="1af91bd8169339ec8c77decfab59fd21"
Content-Length: 211

v=0
o=user1 795808818 480847547 IN IP4 localIP
s=-
c=IN IP4 localIP
t=0 0
m=audio 8000 RTP/AVP 0 8 101
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=sendrecv
-----------StatusCode:401----------------------------
-----------currentREsponse:Unauthorized----------------------------
------------------Invite 401--------------------

SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 10.99.136.136:52216;branch=z9hG4bK-363735-1a2fd8de5c389de950ecbb1a3d9a7d3e;received=10.99.136.136;rport=52216
From: <sip:username@localIP>;tag=1825098223
To: <sip:160@localIP>;tag=as22472833
Call-ID: 5fd6c07f15259d4aaeabdfb9e306cd12@10.99.136.136
CSeq: 4 INVITE
Server: Asterisk PBX 10.5.1
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH
Supported: replaces,timer
WWW-Authenticate: Digest algorithm=MD5,realm="xyz.com",nonce="599cd63b"
Content-Length: 0


DEBUG: Response: SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 10.99.136.136:52216;branch=z9hG4bK-363735-1a2fd8de5c389de950ecbb1a3d9a7d3e;received=10.99.136.136;rport=52216
From: <sip:username@localIP>;tag=1825098223
To: <sip:160@localIP>;tag=as22472833
Call-ID: 5fd6c07f15259d4aaeabdfb9e306cd12@10.99.136.136
CSeq: 4 INVITE
Server: Asterisk PBX 10.5.1
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH
Supported: replaces,timer
WWW-Authenticate: Digest algorithm=MD5,realm="xyz.com",nonce="599cd63b"
Content-Length: 0


Dialog: createdgov.nist.javax.sip.stack.SIPDialog@393895ed
INVITE sip:160@localIP SIP/2.0
Call-ID: 5fd6c07f15259d4aaeabdfb9e306cd12@10.99.136.136
CSeq: 5 INVITE
From: <sip:username@localIP>;tag=1825098223
To: <sip:160@localIP>
Via: SIP/2.0/UDP 10.99.136.136:52216;rport;branch=z9hG4bK-363735-633d808b788771fa1e211672ddc3e903
Max-Forwards: 70
Content-Type: application/sdp
Contact: <sip:username@10.99.136.136:52216;transport=UDP>
Authorization: Digest username="username",realm="xyz.com",nonce="49a39764",uri="sip:localIP",algorithm=MD5,response="1af91bd8169339ec8c77decfab59fd21"
Content-Length: 211

v=0
o=user1 795808818 480847547 IN IP4 localIP
s=-
c=IN IP4 localIP
t=0 0
m=audio 8000 RTP/AVP 0 8 101
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=sendrecv
-----------StatusCode:401----------------------------
-----------currentREsponse:Unauthorized----------------------------
-----------StatusCode:100----------------------------
-----------currentREsponse:Trying----------------------------
------------------- Status Code: 100--------------------------
SIP/2.0 100 Trying
Via: SIP/2.0/UDP 10.99.136.136:52216;branch=z9hG4bK-363735-a872936256c40065a4b147d4981cc74a;received=10.99.136.136;rport=52216
From: <sip:username@localIP>;tag=1825098223
To: <sip:160@localIP>
Call-ID: 5fd6c07f15259d4aaeabdfb9e306cd12@10.99.136.136
CSeq: 5 INVITE
Server: Asterisk PBX 10.5.1
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH
Supported: replaces,timer
Contact: <sip:160@localIP:5060>
Content-Length: 0


-----------StatusCode:401----------------------------
-----------currentREsponse:Unauthorized----------------------------


Request OPTIONSreceived at stackwith server transaction idnull
-----------StatusCode:180----------------------------
-----------currentREsponse:Ringing----------------------------

SIP/2.0 180 Ringing
Via: SIP/2.0/UDP 10.99.136.136:52216;branch=z9hG4bK-363735-a872936256c40065a4b147d4981cc74a;received=10.99.136.136;rport=52216
From: <sip:username@localIP>;tag=1825098223
To: <sip:160@localIP>;tag=as78f593d4
Call-ID: 5fd6c07f15259d4aaeabdfb9e306cd12@10.99.136.136
CSeq: 5 INVITE
Server: Asterisk PBX 10.5.1
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH
Supported: replaces,timer
Contact: <sip:160@localIP:5060>
Content-Length: 0

-


Request OPTIONSreceived at stackwith server transaction idnull


Request OPTIONSreceived at stackwith server transaction idnull


Request OPTIONSreceived at stackwith server transaction idnull
-----------StatusCode:200----------------------------
-----------currentREsponse:OK----------------------------
SIP/2.0 200 OK
Via: SIP/2.0/UDP 10.99.136.136:52216;branch=z9hG4bK-363735-a872936256c40065a4b147d4981cc74a;received=10.99.136.136;rport=52216
From: <sip:username@localIP>;tag=1825098223
To: <sip:160@localIP>;tag=as78f593d4
Call-ID: 5fd6c07f15259d4aaeabdfb9e306cd12@10.99.136.136
CSeq: 5 INVITE
Server: Asterisk PBX 10.5.1
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH
Supported: replaces,timer
Contact: <sip:160@localIP:5060>
Content-Type: application/sdp
Content-Length: 256

v=0
o=root 698934329 698934329 IN IP4 localIP
s=Asterisk PBX 10.5.1
c=IN IP4 localIP
t=0 0
m=audio 23142 RTP/AVP 8 101
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=silenceSupp:off - - - -
a=ptime:20
a=sendrecv

javax.sip.SipException: Cannot create ACK - no remote Target!
    at gov.nist.javax.sip.stack.SIPDialog.createAck(SIPDialog.java:3021)
    at test.processResponse(test.java:323)
    at gov.nist.javax.sip.EventScanner.deliverEvent(EventScanner.java:296)
    at gov.nist.javax.sip.EventScanner.run(EventScanner.java:519)
    at java.lang.Thread.run(Thread.java:745)
-----------StatusCode:200----------------------------
-----------currentREsponse:OK----------------------------
SIP/2.0 200 OK
Via: SIP/2.0/UDP 10.99.136.136:52216;branch=z9hG4bK-363735-a872936256c40065a4b147d4981cc74a;received=10.99.136.136;rport=52216
From: <sip:username@localIP>;tag=1825098223
To: <sip:160@localIP>;tag=as78f593d4
Call-ID: 5fd6c07f15259d4aaeabdfb9e306cd12@10.99.136.136
CSeq: 5 INVITE
Server: Asterisk PBX 10.5.1
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH
Supported: replaces,timer
Contact: <sip:160@localIP:5060>
Content-Type: application/sdp
Content-Length: 256

v=0
o=root 698934329 698934329 IN IP4 localIP
s=Asterisk PBX 10.5.1
c=IN IP4 localIP
t=0 0
m=audio 23142 RTP/AVP 8 101
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=silenceSupp:off - - - -
a=ptime:20
a=sendrecv

javax.sip.SipException: Cannot create ACK - no remote Target!
    at gov.nist.javax.sip.stack.SIPDialog.createAck(SIPDialog.java:3021)
    at test.processResponse(test.java:323)
    at gov.nist.javax.sip.EventScanner.deliverEvent(EventScanner.java:296)
    at gov.nist.javax.sip.EventScanner.run(EventScanner.java:519)
    at java.lang.Thread.run(Thread.java:745)
-----------StatusCode:200----------------------------
-----------currentREsponse:OK----------------------------
SIP/2.0 200 OK
Via: SIP/2.0/UDP 10.99.136.136:52216;branch=z9hG4bK-363735-a872936256c40065a4b147d4981cc74a;received=10.99.136.136;rport=52216
From: <sip:username@localIP>;tag=1825098223
To: <sip:160@localIP>;tag=as78f593d4
Call-ID: 5fd6c07f15259d4aaeabdfb9e306cd12@10.99.136.136
CSeq: 5 INVITE
Server: Asterisk PBX 10.5.1
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH
Supported: replaces,timer
Contact: <sip:160@localIP:5060>
Content-Type: application/sdp
Content-Length: 256

v=0
o=root 698934329 698934329 IN IP4 localIP
s=Asterisk PBX 10.5.1
c=IN IP4 localIP
t=0 0
m=audio 23142 RTP/AVP 8 101
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=silenceSupp:off - - - -
a=ptime:20
a=sendrecv

javax.sip.SipException: Cannot create ACK - no remote Target!
    at gov.nist.javax.sip.stack.SIPDialog.createAck(SIPDialog.java:3021)
    at test.processResponse(test.java:323)
    at gov.nist.javax.sip.EventScanner.deliverEvent(EventScanner.java:296)
    at gov.nist.javax.sip.EventScanner.run(EventScanner.java:519)
    at java.lang.Thread.run(Thread.java:745)


Request OPTIONSreceived at stackwith server transaction idnull
-----------StatusCode:200----------------------------
-----------currentREsponse:OK----------------------------
SIP/2.0 200 OK
Via: SIP/2.0/UDP 10.99.136.136:52216;branch=z9hG4bK-363735-a872936256c40065a4b147d4981cc74a;received=10.99.136.136;rport=52216
From: <sip:username@localIP>;tag=1825098223
To: <sip:160@localIP>;tag=as78f593d4
Call-ID: 5fd6c07f15259d4aaeabdfb9e306cd12@10.99.136.136
CSeq: 5 INVITE
Server: Asterisk PBX 10.5.1
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH
Supported: replaces,timer
Contact: <sip:160@localIP:5060>
Content-Type: application/sdp
Content-Length: 256

v=0
o=root 698934329 698934329 IN IP4 localIP
s=Asterisk PBX 10.5.1
c=IN IP4 localIP
t=0 0
m=audio 23142 RTP/AVP 8 101
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=silenceSupp:off - - - -
a=ptime:20
a=sendrecv

javax.sip.SipException: Cannot create ACK - no remote Target!
    at gov.nist.javax.sip.stack.SIPDialog.createAck(SIPDialog.java:3021)
    at test.processResponse(test.java:323)
    at gov.nist.javax.sip.EventScanner.deliverEvent(EventScanner.java:296)
    at gov.nist.javax.sip.EventScanner.run(EventScanner.java:519)
    at java.lang.Thread.run(Thread.java:745)




Request OPTIONSreceived at stackwith server transaction idnull


Request BYEreceived at stackwith server transaction idnull
----------------Received a BYE-----------------------
 null TID


Request BYEreceived at stackwith server transaction idnull
----------------Received a BYE-----------------------
 null TID


Request BYEreceived at stackwith server transaction idnull
----------------Received a BYE-----------------------
     null TID

【问题讨论】:

  • 也许可以试试this.dialog = responseEvent.getDialog(); 我在文档中看到:"这个方法将事务支持与对话框支持分开。这使应用程序开发人员能够访问与此事件关联的对话框,而无需查询事务与事件关联。例如,与事件关联的事务可能会返回“null”,因为已经收到事务的最终响应并且堆栈没有更多的事务记录”
  • 是的,我试过了,对话框不为空,但 dialog.getRemoteTarget() 或 dialog.getRemoteTag() 返回 null,我需要 createAck()
  • 现在您发布了消息,我看到这是一个错误响应 (401):您不需要明确确认最终的错误响应,JAIN SIP 实现会为您完成,请参阅下面的答案.顺便说一句,INVITE 应该启动一个新对话(与 REGISTER 不同的 Call-ID)。
  • 好的。我很抱歉延迟回答。我不得不抽出时间编写一个工作示例并在我的环境中进行测试。由于它有点长,我试图在新答案中提供最相关的摘录。

标签: java sip jain-sip


【解决方案1】:

让我们尝试更详细一点。

我所做的是从JAIN SIP's Jenkins 下载 JAIN SIP 1.2 中提供的示例 UAC 代码,并对其进行修改以涵盖 REGISTER 和初始邀请。

我已经使用 IMS 核心进行了测试,因此它可能与您使用 Asterisk PBX 的体验略有不同,特别是我不需要验证 INVITE。

在高层结构方面,我有:

一个类 (TestUAC) 既是主类又实现了 SipListener 接口。

  1. 在 main 上,我初始化堆栈、设置侦听器、读取任何配置,最后我调用 sendRegister(),它将发送第一个 REGISTER 并启动进程。
  2. 开启processResponse() 回调。基于响应的CSeq的方法,我可以区分:
    • 对 REGISTER (processRegisterResponse()) 的回复
    • 对邀请的回复 (processInviteResponse())
    • 回复 BYE (processByeResponse())
  3. processRequest() 和其他回调上,我只有痕迹。

一般来说,我只保留很少的信息作为对象属性:

  • 堆栈内容:对sipFactorysipProvidersipStackaddressFactorymessageFactoryheaderFactory 的引用
  • 关于我的身份和我想与谁交谈的信息:

例如

   private String callingURI;
   private String calledURI;
   private String username;
   private String password;
   private Address fromNameAddress;
   private ContactHeader contactHeader;

我还为 cseq 保留一个递增计数器,并(按照 JAIN SIP 示例)一个 ackRequest 的副本,用于回复重新传输的 200 OK。

// Save the created ACK request, to respond to retransmitted 2xx
private Request ackRequest;

private long cseq=1L;

正如我所说,processResponse() 只是基于 CSeq 方法分发:

public void processResponse(ResponseEvent responseReceivedEvent) {
    System.out.println("Got a response");
    Response response = (Response) responseReceivedEvent.getResponse();
    CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME);

    System.out.println("Response received : Status Code = "
            + response.getStatusCode() + " " + cseq);

    try {
        if(cseq.getMethod().equals(Request.REGISTER)) {
            processRegisterResponse(responseReceivedEvent);
        }
        else if(cseq.getMethod().equals(Request.INVITE)) {
            processInviteResponse(responseReceivedEvent);
        }
        else if(cseq.getMethod().equals(Request.BYE)) {
            processByeResponse(responseReceivedEvent);
        }
        else {
            System.out.println("Response to unexpected request");
        }
    } catch(Exception e)  {
        e.printStackTrace();
    }
}

processRegisterResponse() 区分 401 Unauthorized 和 200 OK 响应。在第一种情况下,它将触发发送带有身份验证的 REGISTER。在第二种情况下,它将请求发送邀请:

private void processRegisterResponse(ResponseEvent responseReceivedEvent) throws TransactionUnavailableException, ParseException, InvalidArgumentException, SipException, NoSuchAlgorithmException {
    Response response = (Response) responseReceivedEvent.getResponse();

    if(response.getStatusCode() == Response.UNAUTHORIZED) {
        sendRegister(response);
    }
    else if (response.getStatusCode() == Response.OK) {
        contactHeader=(ContactHeader)response.getHeader(ContactHeader.NAME);
        sendInvite();
    }               
}

现在,对于 sendInvite()(我将尝试将其提炼到相关部分)。

private void sendInvite() throws ParseException, InvalidArgumentException, TransactionUnavailableException, SipException {

    // create To Header
    URI toAddress = addressFactory.createURI(calledURI);
    Address toNameAddress = addressFactory.createAddress(toAddress);
    ToHeader toHeader = headerFactory.createToHeader(toNameAddress,null);

    FromHeader fromHeader = headerFactory.createFromHeader(fromNameAddress, "12345");
    // Create ViaHeaders
    ArrayList<ViaHeader> viaHeaders = getViaHeaders();

    // Create a new CallId header
    CallIdHeader callIdHeader = sipProvider.getNewCallId();

    // Create a new Cseq header
    CSeqHeader cSeqHeader = headerFactory.createCSeqHeader(cseq,Request.INVITE);
    cseq++;

    // Create a new MaxForwardsHeader
    MaxForwardsHeader maxForwards = headerFactory.createMaxForwardsHeader(70);

    // Create the request.
    Request request = messageFactory.createRequest(toAddress,
            Request.INVITE, callIdHeader, cSeqHeader, fromHeader,
            toHeader, viaHeaders, maxForwards);

    request.addHeader(contactHeader);

    // at this point you should add the rest of the headers, content, etc.

    // Create the client transaction.
    ClientTransaction currentTid = sipProvider.getNewClientTransaction(request);
    // send the request out.
    currentTid.sendRequest();
}

最后,接下来发生的事情是我们将收到 200 OK 的邀请。这主要是来自 JAIN SLEE 示例的代码,我已将其移至 processInviteResponse()(我将再次尝试将其提炼为基本内容)。

private void processInviteResponse(ResponseEvent responseReceivedEvent) throws SipException, InvalidArgumentException {
    Response response = (Response) responseReceivedEvent.getResponse();
    ClientTransaction tid = responseReceivedEvent.getClientTransaction();
    CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME);     
    Dialog dialog = responseReceivedEvent.getDialog();

    if (tid == null) {
        // RFC3261: MUST respond to every 2xx
        if (ackRequest!=null && dialog!=null) {
            System.out.println("re-sending ACK");
            dialog.sendAck(ackRequest);
        }
        return;
    }

    if (response.getStatusCode() == Response.OK) {
        System.out.println("Dialog after 200 OK  " + dialog);
        System.out.println("Dialog State after 200 OK  " + dialog.getState());
        ackRequest = dialog.createAck(cseq.getSeqNumber() );
        System.out.println("Sending ACK");
        dialog.sendAck(ackRequest);
    }
}

在收到 200 OK 并发送 ACK 之后,您可能应该考虑下一步该做什么:例如,在 JAIN SLEE UAC 示例中,它会启动 TimerTask 在一段时间后发送 BYE。

您还可以在此处添加对其他错误(或临时)响应的处理。但请记住,堆栈会自动确认(无需代码)最终的错误响应。

【讨论】:

  • 我没有正确处理 INVITE 的响应,所以我得到了错误。现在它就像你解释的那样工作。但是我仍然有些疑问,为什么即使我添加了 Contents 并输入了 request , TimerTask 也会发送 Bye 。我还需要处理吗?
  • @gourig,JAIN 示例使用 TimerTask 在一段时间后关闭调用......它在发送 ACK 后显式创建并安排任务,但您不必这样做。如果您有更多问题,您可能应该开始一个新问题......这个问题已经太复杂了。
【解决方案2】:

对于最终的错误响应,JAIN SIP 实现应该负责为您发送 ACK。例如参见SipListener.processResponse()javadoc:

UAC 需要为它收到的每个最终响应发送一个 ACK​​, 但是发送 ACK 的过程取决于 回复。对于 300 到 699 之间的最终响应,ACK 处理 由事务层完成,即由实现处理。 对于 2xx 响应,ACK 处理由 UAC 应用程序完成, 保证 INVITE 交易的三次握手

对于 200 OK,您必须显式发送 ACK,过程将是 获取this.dialog = responseEvent.getDialog();。该对话框将具有远程目标和远程标记。


用新问题更新答案。

  1. 您正试图为 REGISTER 的 200 OK 发送 ACK。这是错误的。 ACK 仅在需要可靠答案时使用。目前,INVITE 是唯一需要它的 SIP 方法。

  2. 当您发送 INVITE 时,您会收到 401 Unauthorized 回复。您的 SIP 代理似乎配置为需要 INVITE 的授权。您可以通过与 REGISTER 相同的方式解决该问题:

    • 您发送邀请并收到 401 Unathorized 回复。查找挑战的 WWW-Authenticate 标头。
    • JAIN SIP 堆栈将处理最终响应的 ACK。
    • 在同一个 Call-ID 内再次发送 INVITE,这次使用 Authorization 标头响应质询。

【讨论】:

  • 嗨,即使我在注册 200 OK 后得到对话框,我仍然得到一个空值
  • 为什么要为 REGISTER 发送 ACK?
  • 啊哦。但是在收到 200 OK 进行注册后。发出INVITE,INVITE发送Unauthorized。那么是INVITE的问题吗?
  • @gourig,可能是因为您在与 REGISTER 相同的 Dialog (Call-ID) 中发送 INVITE。
  • 不,我更改了 Call -Id。我将粘贴新的回复。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-24
  • 2021-05-25
相关资源
最近更新 更多