SIP ACK 对话框为空

SIP ACK Dialog is null

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

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

Cannot Create ACK - no remote Target

我检查了 Dialog 的值,它是 null

在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

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

A UAC needs to send an ACK for every final Response it receives, however the procedure for sending the ACK depends on the type of Response. For final responses between 300 and 699, the ACK processing is done by the transaction layer i.e. handled by the implementation. For 2xx responses, the ACK processing is done by the UAC application, to guarantee the three way handshake of an INVITE transaction

对于 200 OK,您必须明确发送 ACK,过程如下 获得 this.dialog = responseEvent.getDialog();。该对话框将具有远程目标和远程标记。


用新问题更新答案。

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

  2. 当您发送 INVITE 时,您会收到 401 Unauthorized 响应。您的 SIP 代理似乎配置为需要 INVITE 授权。您以与 REGISTER:

    相同的方式解决该问题
    • 您发送 INVITE 并收到 401 Unathorized 回复。寻找 WWW-Authenticate header 进行挑战。
    • JAIN SIP 堆栈将处理最终响应的 ACK。
    • 在同一个 Call-ID 内再次发送 INVITE,这次使用授权 header,响应挑战。

让我们尝试更详细一点。

我所做的是获取 JAIN SIP 1.2 下载中可用的示例 UAC 代码 JAIN SIP's Jenkins 并修改它以涵盖 REGISTER 和初始 INVITE。

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

在高层结构方面,我有:

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

  1. 在 main 上,我初始化堆栈,设置侦听器,读取任何配置,最后我调用 sendRegister() 将发送第一个 REGISTER 并启动进程。
  2. processResponse() 回调中。根据响应的 CSeq 方法,我可以区分:
    • 对注册的回应(processRegisterResponse()
    • 对 INVITE 的响应(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 示例)用于回复重传的 200 OK 的 ackRequest 副本。

// 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。在第二种情况下,它将请求发送 INVITE:

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();
}

最后,接下来我们将收到 INVITE 的 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。

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