为什么 jain sip return 481 收到再见?

why jain sip return 481 on received bye?

我使用 Jain Sip 创建一个 sip 应用程序。它可以send/receiveINVITE/ACK/BYE,必要时用SDP发回响应。 但是当它收到对方的 BYE 时,Jain Sip 会抛出一个 481。 我试图弄清楚发生了什么事一个星期仍然不明白。

我使用来自传入请求的 ServerTransaction.sendResponse 有状态地发送响应。自动对话已打开。


这里是完整的源码(界面我用的是swing)

public class SipClient extends JFrame implements SipListener {

SipFactory sipFactory; // used to access the SIP API
SipStack sipStack;
SipProvider sipProvider; // used to send SIP messages
MessageFactory messageFactory; // used to create SIP message factory
HeaderFactory headerFactory; // used to create SIP headers
AddressFactory addressFactory; // used to create SIP URIs
ListeningPoint listeningPoint; // SIP listening IP address & port
Properties properties;

// local configuration
String ip; // locap IP address
int port = 5060; // local port
String protocol = "udp"; // local protocol
int tag = (new Random().nextInt()); // local tag
Address contactAddress;
ContactHeader contactHeader;

public static final boolean callerSendsBye = true;
private Dialog dialog;
private ServerTransaction servTransaction;
private ClientTransaction cliTransaction;
private long cseq = 1L;
private Request inviteRequest;
private Request ackRequest;

/**
 * Creates new form SipClient
 */
public SipClient() {
    initComponents();
}

/**
 * This method is called from within the constructor to initialize the form.
 * WARNING: Do NOT modify this code. The content of this method is always
 * regenerated by the Form Editor.
 */
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed"
// desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {}


private void onOpen(java.awt.event.WindowEvent evt) {
    // A method called when you open the application

    try {


        // get the local IP address
        this.ip = "127.0.0.12";

        // create the SIP factory and set the path name
        this.sipFactory = SipFactory.getInstance();
        this.sipFactory.setPathName("gov.nist");

        // create and set the SIP stack properties
        this.properties = new Properties();
        this.properties.setProperty("javax.sip.STACK_NAME", "stack");
        this.properties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", "on");

        // create the SIP stack
        this.sipStack = this.sipFactory.createSipStack(this.properties);

        // create the SIP message factory
        this.messageFactory = this.sipFactory.createMessageFactory();

        // create the SIP header factory
        this.headerFactory = this.sipFactory.createHeaderFactory();

        // create the SIP address factory
        this.addressFactory = this.sipFactory.createAddressFactory();

        // create the SIP listening point and bind it to the local IP
        // address, port & protocol
        this.listeningPoint = this.sipStack.createListeningPoint(this.ip,
                this.port, this.protocol);

        // create the SIP provider
        this.sipProvider = this.sipStack.createSipProvider(listeningPoint);

        // add application as sip listener
        this.sipProvider.addSipListener(this);

        // create contact address used for all SIP messages
        this.contactAddress = this.addressFactory.createAddress("sip:"
                + this.ip + ":" + this.port);

        // create contact header used for all SIP messages
        this.contactHeader = this.headerFactory
                .createContactHeader(contactAddress);

        // display local IP address and port in text area
        this.textArea.append("Local address:" + this.ip + ":" + this.port
                + "\n Tag:" + this.tag + "\n");

    }

    catch (Exception e) {

        // if error occurs, display an error message box and exit
        JOptionPane.showMessageDialog(this, e.getMessage(), "Error",
                JOptionPane.ERROR_MESSAGE);
        System.exit(-1);

    }
}

private void onRegisterStateless(java.awt.event.ActionEvent evt) {
    // A method called when you click on the "Reg (SL)" button

    try {
        // Get the destination address from the text field
        Address addressTo = this.addressFactory
                .createAddress(this.textField.getText());

        // Create the request URI for the SIP message
        javax.sip.address.URI requestURI = addressTo.getURI();

        // Create the SIP message headers
        // The " Via " headers
        ArrayList viaHeaders = new ArrayList();
        ViaHeader viaHeader = this.headerFactory.createViaHeader(this.ip,
                this.port, "udp", null);
        viaHeaders.add(viaHeader);

        // The " Max - Forwards " header
        MaxForwardsHeader maxForwardsHeader = this.headerFactory
                .createMaxForwardsHeader(70);

        // The " Call - Id " header
        CallIdHeader callIdHeader = this.sipProvider.getNewCallId();

        // The " CSeq " header
        CSeqHeader cSeqHeader = this.headerFactory.createCSeqHeader(1L,
                Request.REGISTER);

        // The " From " header
        FromHeader fromHeader = this.headerFactory.createFromHeader(
                this.contactAddress, String.valueOf(this.tag));

        // The " To " header
        ToHeader toHeader = this.headerFactory.createToHeader(addressTo,
                null);

        // Create the REGISTER request
        Request request = this.messageFactory.createRequest(requestURI,
                Request.REGISTER, callIdHeader, cSeqHeader, fromHeader,
                toHeader, viaHeaders, maxForwardsHeader);

        // Add the " Contact " header to the request .
        request.addHeader(contactHeader);

        // Send the request statelessly through the SIP provider .
        this.sipProvider.sendRequest(request);

        // Display the message in the text area .
        this.textArea.append("Request sent :\n " + request.toString()
                + "\n\n");
    }

    catch (Exception e) {

        // If an error occurred , display the error .
        this.textArea.append("Request sent failed : " + e.getMessage()
                + "\n");
    }
}

private void onRegisterStatefull(java.awt.event.ActionEvent evt) {
    // A method called when you click on the "Reg (SF)" button
    try {
        // Get the destination address from the text field
        Address addressTo = this.addressFactory
                .createAddress(this.textField.getText());

        // Create the request URI for the SIP message
        javax.sip.address.URI requestURI = addressTo.getURI();

        // Create the SIP message headers
        // The " Via " headers
        ArrayList viaHeaders = new ArrayList();
        ViaHeader viaHeader = this.headerFactory.createViaHeader(this.ip,
                this.port, "udp", null);
        viaHeaders.add(viaHeader);

        // The " Max - Forwards " header
        MaxForwardsHeader maxForwardsHeader = this.headerFactory
                .createMaxForwardsHeader(70);

        // The " Call - Id " header
        CallIdHeader callIdHeader = this.sipProvider.getNewCallId();

        // The " CSeq " header
        CSeqHeader cSeqHeader = this.headerFactory.createCSeqHeader(1L,
                Request.REGISTER);

        // The " From " header
        FromHeader fromHeader = this.headerFactory.createFromHeader(
                this.contactAddress, String.valueOf(this.tag));

        // The " To " header
        ToHeader toHeader = this.headerFactory.createToHeader(addressTo,
                null);

        // Create the REGISTER request
        Request request = this.messageFactory.createRequest(requestURI,
                Request.REGISTER, callIdHeader, cSeqHeader, fromHeader,
                toHeader, viaHeaders, maxForwardsHeader);

        // Add the " Contact " header to the request .
        request.addHeader(contactHeader);

        // Send the request statelessly through the SIP provider .
        // this.sipProvider.sendRequest(request);

        // create new SIP client transaction
        ClientTransaction transaction = this.sipProvider
                .getNewClientTransaction(request);

        // send the request statefully, through the client transaction
        transaction.sendRequest();

        // Display the message in the text area .
        this.textArea.append("Request sent :\n " + request.toString()
                + "\n\n");
    }

    catch (Exception e) {

        // If an error occurred , display the error .
        this.textArea.append("Request sent failed : " + e.getMessage()
                + "\n");
    }

}

private void onInvite(java.awt.event.ActionEvent evt) {
    // A method called when you click on the "Invite" button.
    try {
        // Get the destination address from the text field
        Address addressTo = this.addressFactory
                .createAddress(this.textField.getText());

        // Create the request URI for the SIP message
        javax.sip.address.URI requestURI = addressTo.getURI();

        // Create the SIP message headers
        // The " Via " headers
        ArrayList viaHeaders = new ArrayList();
        ViaHeader viaHeader = this.headerFactory.createViaHeader(this.ip,
                this.port, "udp", null);
        viaHeaders.add(viaHeader);

        // The " Max - Forwards " header
        MaxForwardsHeader maxForwardsHeader = this.headerFactory
                .createMaxForwardsHeader(70);

        // The " Call - Id " header
        CallIdHeader callIdHeader = this.sipProvider.getNewCallId();

        // The " CSeq " header
        CSeqHeader cSeqHeader = this.headerFactory.createCSeqHeader(cseq,
                Request.INVITE);
        cseq++;

        // The " From " header
        FromHeader fromHeader = this.headerFactory.createFromHeader(
                this.contactAddress, String.valueOf(this.tag));

        // The " To " header
        ToHeader toHeader = this.headerFactory.createToHeader(addressTo,
                null);

        // Create the REGISTER request
        Request request = this.messageFactory.createRequest(requestURI,
                Request.INVITE, callIdHeader, cSeqHeader, fromHeader,
                toHeader, viaHeaders, maxForwardsHeader);

        // Add the " Contact " header to the request .
        request.addHeader(contactHeader);

        // create new SIP client transaction
        cliTransaction = this.sipProvider.getNewClientTransaction(request);

        // send the request statefully, through the client transaction
        cliTransaction.sendRequest();
        dialog = cliTransaction.getDialog();


        // Display the message in the text area .
        this.textArea.append("Request sent :\n " + request.toString()
                + "\n");
    }

    catch (Exception e) {
        // If an error occurred , display the error .
        this.textArea.append("Request sent failed : " + e.getMessage()
                + "\n");
    }

}

private void onBye(java.awt.event.ActionEvent evt) {
    // A method called when you click on the "Bye" button.

    try {

        Request byeRequest = dialog.createRequest(Request.BYE);
        cliTransaction = sipProvider
                .getNewClientTransaction(byeRequest);
        dialog.sendRequest(cliTransaction);
        this.textArea.append("Request sent :\n " + byeRequest.toString()
                + "\n");
    } catch (Exception e) {
        // If an error occurred , display the error .
        this.textArea.append("Request sent failed : " + e.getMessage()
                + "\n");
    }
}

/**
 * @param args
 *            the command line arguments
 */
public static void main(String args[]) {
    /* Set the Nimbus look and feel */
    // <editor-fold defaultstate="collapsed"
    // desc=" Look and feel setting code (optional) ">
    /*
     * If Nimbus (introduced in Java SE 6) is not available, stay with the
     * default look and feel. For details see
     * http://download.oracle.com/javase
     * /tutorial/uiswing/lookandfeel/plaf.html
     */
    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager
                .getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(SipClient.class.getName()).log(
                java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(SipClient.class.getName()).log(
                java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(SipClient.class.getName()).log(
                java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(SipClient.class.getName()).log(
                java.util.logging.Level.SEVERE, null, ex);
    }
    // </editor-fold>

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            new SipClient().setVisible(true);
        }
    });
}

// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton buttonBye;
private javax.swing.JButton buttonInvite;
private javax.swing.JButton buttonRegisterStatefull;
private javax.swing.JButton buttonRegisterStateless;
private javax.swing.JScrollPane scrollPane;
private javax.swing.JTextArea textArea;
private javax.swing.JTextField textField;

// End of variables declaration//GEN-END:variables

@Override
public void processRequest(RequestEvent requestEvent) {
    // A method called when you receive a SIP request
    // Get the request.
    Request request = requestEvent.getRequest();
    sipProvider = (SipProvider) requestEvent.getSource();
    this.textArea.append("\nRECEIVED " + request.getMethod() + " "
            + request.getRequestURI().toString());

    try {
        // Get or create the server transaction.
        servTransaction = requestEvent.getServerTransaction();
        if (null == servTransaction) {
            servTransaction = this.sipProvider
                    .getNewServerTransaction(request);
        }
        // Process the request and send a response.
        if (request.getMethod().equals(Request.INVITE)) {
            // If the request is an INVITE.
            processInvite(request, servTransaction);
        } else if (request.getMethod().equals(Request.ACK)) {
            // If the request is an ACK.
            this.textArea.append("\n RECEIVED : " + request.getMethod());
        } else if (request.getMethod().equals(Request.BYE)) {
            // If the request is a BYE.
            processBye(request, servTransaction);
        } else if (request.getMethod().equals(Request.CANCEL)) {
            processCancel(request, servTransaction);
        }
    } catch (SipException e) {
        this.textArea.append("\nERROR (SIP): " + e.getMessage());
    } catch (Exception e) {
        this.textArea.append("\nERROR: " + e.getMessage());
    }
}

@Override
public void processResponse(ResponseEvent responseEvent) {
    // A method called when you receive a SIP request.
    // Get the response .
    // Get or create the server transaction.
    Response response = responseEvent.getResponse();
    int status = response.getStatusCode();
    CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME);

    switch (status) {

    case Response.TRYING: // trying
        try {
            this.textArea.append("\n RECEIVED RESPONSE : " + status
                    + response.toString());
        } catch (Exception e) {
            this.textArea.append("\n ERROR: " + e.getMessage());
        }
        break;

    case Response.RINGING: // ringing
        try {
            this.textArea.append("\n RECEIVED RESPONSE : " + status
                    + response.toString());
        } catch (Exception e) {
            this.textArea.append("\n ERROR: " + e.getMessage());
        }
        break;

    case Response.OK: // OK
        this.textArea.append("\n RECEIVED RESPONSE : " + status
                + response.toString());
        if (cseq.getMethod().equals(Request.INVITE)) {
            try {
                ackRequest = dialog.createAck(((CSeqHeader) response
                        .getHeader(CSeqHeader.NAME)).getSeqNumber());
                dialog.sendAck(ackRequest);
                this.textArea.append("\n Request sent :\n "
                        + ackRequest.toString() + "\n");
            } catch (Exception e) {
                this.textArea.append("\n ERROR: " + e.getMessage());
            }
        }
        break;

    default:
        break;

    }
}

@Override
public void processTimeout(TimeoutEvent timeoutEvent) {
    // A method called when a SIP operation times out.
    this.textArea.append(" \n Transaction Time out");
}

@Override
public void processIOException(IOExceptionEvent exceptionEvent) {
    // A method called when a SIP operation results in an I/O error.
    this.textArea.append("\n IOException happened for "
            + exceptionEvent.getHost() + " port = "
            + exceptionEvent.getPort());
}

@Override
public void processTransactionTerminated(
        TransactionTerminatedEvent transactionTerminatedEvent) {
    // A method called when a SIP transaction terminates.
    this.textArea.append("\n Transaction terminated event received");
}

@Override
public void processDialogTerminated(
        DialogTerminatedEvent dialogTerminatedEvent) {
    // A method called when a SIP dialog terminates.
    this.textArea.append("\n Dialog Terminated event received");
}

/**
 * Process the invite request.
 */
public void processInvite(Request request,
        ServerTransaction serverTransaction) {

    try {
        this.textArea.append("\n" + request.toString()
                + "\n sending TRYING & RINGING");
        // trying
        Response tryResponse = messageFactory.createResponse(
                Response.TRYING, request);
        serverTransaction.sendResponse(tryResponse);
        this.textArea.append("\n SENT " + tryResponse.getStatusCode() + " "
                + tryResponse.getReasonPhrase());

        // ringing
        Response ringResponse = messageFactory.createResponse(
                Response.RINGING, request);
        serverTransaction.sendResponse(ringResponse);
        this.textArea.append("\n SENT " + ringResponse.getStatusCode()
                + " " + ringResponse.getReasonPhrase());

        Response okResponse = messageFactory.createResponse(Response.OK,
                request);
        ((ToHeader) okResponse.getHeader("To")).setTag(String
                .valueOf(this.tag));
        okResponse.addHeader(this.contactHeader);
        serverTransaction.sendResponse(okResponse);
        this.textArea.append("\n SENT " + okResponse.getStatusCode() + " "
                + okResponse.getReasonPhrase());
        this.textArea.append("\n"+okResponse.toString());

    } catch (Exception e) {
        this.textArea.append("\n ERROR: " + e.getMessage());
    }
}

public void processBye(Request request, ServerTransaction serverTransaction) {
    try {
        this.textArea.append("\n" + request.toString());
        if (serverTransaction == null) {
            this.textArea.append("\n null transaction");
            return;
        }

        Response response = messageFactory.createResponse(Response.OK,
                request);
        serverTransaction.sendResponse(response);

    } catch (Exception e) {
        this.textArea.append("\n ERROR: " + e.getMessage());
    }
}

public void processCancel(Request request,
        ServerTransaction serverTransaction) {
    try {
        if (serverTransaction == null) {
            this.textArea.append("null ServerTransaction");
            return;
        }
        this.textArea.append("Received a Cancel sending OK");
        Response response = messageFactory.createResponse(Response.OK,
                request);
        serverTransaction.sendResponse(response);
        if (dialog.getState() != DialogState.CONFIRMED) {
            response = messageFactory.createResponse(
                    Response.REQUEST_TERMINATED, inviteRequest);
            serverTransaction.sendResponse(response);
        }

    } catch (Exception e) {
        this.textArea.append("\n ERROR: " + e.getMessage());

    }
}

这里是log(没有收到client发送的bye,client收到的481 Callleg/Transaction不存在)

日志

<!-- Use the  Trace Viewer in src/tools/tracesviewer to view this  trace  
Here are the stack configuration properties 
javax.sip.IP_ADDRESS= null
javax.sip.STACK_NAME= stack
javax.sip.ROUTER_PATH= null
javax.sip.OUTBOUND_PROXY= null
-->
<description
 logDescription="stack"
 name="stack"
 auxInfo="null"/>

<message
from="127.0.0.12:5060" 
to="127.0.0.11:5060" 
time="1437463865920"
isSender="true" 
transactionId="z9hg4bk-393131-d6f070870ff38a7bc7a5764e8e3f6d3b" 
callId="123c727958f6588323a087db02e6a235@127.0.0.12" 
firstLine="INVITE sip:alice@127.0.0.11:5060 SIP/2.0" 
>
<![CDATA[INVITE sip:alice@127.0.0.11:5060 SIP/2.0
Call-ID: 123c727958f6588323a087db02e6a235@127.0.0.12
CSeq: 1 INVITE
From: <sip:127.0.0.12:5060>;tag=2074886745
To: <sip:alice@127.0.0.11:5060>
Via: SIP/2.0/UDP 127.0.0.12:5060;branch=z9hG4bK-393131-d6f070870ff38a7bc7a5764e8e3f6d3b
Max-Forwards: 70
Contact: <sip:127.0.0.12:5060>
Content-Length: 0

]]>
</message>

<message
from="127.0.0.11:5060" 
to="127.0.0.12:5060" 
time="1437463866010"
isSender="false" 
transactionId="z9hg4bk-393131-d6f070870ff38a7bc7a5764e8e3f6d3b" 
callId="123c727958f6588323a087db02e6a235@127.0.0.12" 
firstLine="SIP/2.0 100 Trying" 
>
<![CDATA[SIP/2.0 100 Trying
Via: SIP/2.0/UDP 127.0.0.12:5060;branch=z9hG4bK-393131-d6f070870ff38a7bc7a5764e8e3f6d3b
From: <sip:127.0.0.12:5060>;tag=2074886745
To: <sip:alice@127.0.0.11:5060>
Call-ID: 123c727958f6588323a087db02e6a235@127.0.0.12
CSeq: 1 INVITE
Contact: <sip:101@127.0.0.11:5060;transport=udp>;reg-id=1
Content-Length: 0

]]>
</message>

<message
from="127.0.0.11:5060" 
to="127.0.0.12:5060" 
time="1437463866028"
isSender="false" 
transactionId="z9hg4bk-393131-d6f070870ff38a7bc7a5764e8e3f6d3b" 
callId="123c727958f6588323a087db02e6a235@127.0.0.12" 
firstLine="SIP/2.0 180 Ringing" 
>
<![CDATA[SIP/2.0 180 Ringing
Via: SIP/2.0/UDP 127.0.0.12:5060;branch=z9hG4bK-393131-d6f070870ff38a7bc7a5764e8e3f6d3b
From: <sip:127.0.0.12:5060>;tag=2074886745
To: <sip:alice@127.0.0.11:5060>
Call-ID: 123c727958f6588323a087db02e6a235@127.0.0.12
CSeq: 1 INVITE
Contact: <sip:101@127.0.0.11:5060;transport=udp>;reg-id=1
Allow: INVITE,ACK,CANCEL,BYE,REFER,OPTIONS,NOTIFY,SUBSCRIBE,PRACK,MESSAGE,INFO,UPDATE
Allow-Events: talk,hold,refer,call-info
Content-Length: 0

]]>
</message>

<message
from="127.0.0.11:5060" 
to="127.0.0.12:5060" 
time="1437463866047"
isSender="false" 
transactionId="z9hg4bk-393131-d6f070870ff38a7bc7a5764e8e3f6d3b" 
callId="123c727958f6588323a087db02e6a235@127.0.0.12" 
firstLine="SIP/2.0 183 PROGRESS" 
>
<![CDATA[SIP/2.0 183 PROGRESS
Via: SIP/2.0/UDP 127.0.0.12:5060;branch=z9hG4bK-393131-d6f070870ff38a7bc7a5764e8e3f6d3b
From: <sip:127.0.0.12:5060>;tag=2074886745
To: <sip:alice@127.0.0.11:5060>
Call-ID: 123c727958f6588323a087db02e6a235@127.0.0.12
CSeq: 1 INVITE
Contact: <sip:101@127.0.0.11:5060;transport=udp>;reg-id=1
Allow: INVITE,ACK,CANCEL,BYE,REFER,OPTIONS,NOTIFY,SUBSCRIBE,PRACK,MESSAGE,INFO,UPDATE
Allow-Events: talk,hold,refer,call-info
Content-Length: 0

]]>
</message>

<message
from="127.0.0.11:5060" 
to="127.0.0.12:5060" 
time="1437463870629"
isSender="false" 
transactionId="z9hg4bk-393131-d6f070870ff38a7bc7a5764e8e3f6d3b" 
callId="123c727958f6588323a087db02e6a235@127.0.0.12" 
firstLine="SIP/2.0 200 OK" 
>
<![CDATA[SIP/2.0 200 OK
Via: SIP/2.0/UDP 127.0.0.12:5060;branch=z9hG4bK-393131-d6f070870ff38a7bc7a5764e8e3f6d3b
From: <sip:127.0.0.12:5060>;tag=2074886745
To: <sip:alice@127.0.0.11:5060>;tag=dqixl8jjv0w
Call-ID: 123c727958f6588323a087db02e6a235@127.0.0.12
CSeq: 1 INVITE
Contact: <sip:101@127.0.0.11:5060;transport=udp>;reg-id=1
User-Agent: snom300/8.7.3.10
Content-Type: application/sdp
Content-Length: 161

]]>
</message>

<message
from="127.0.0.12:5060" 
to="127.0.0.11:5060" 
time="1437463870636"
isSender="true" 
transactionId="z9hg4bk-393131-78a57efafa9f181708d9e4ee05b324a3" 
callId="123c727958f6588323a087db02e6a235@127.0.0.12" 
firstLine="ACK sip:101@127.0.0.11:5060;transport=udp SIP/2.0" 
>
<![CDATA[ACK sip:101@127.0.0.11:5060;transport=udp SIP/2.0
Call-ID: 123c727958f6588323a087db02e6a235@127.0.0.12
CSeq: 1 ACK
Via: SIP/2.0/UDP 127.0.0.12:5060;branch=z9hG4bK-393131-78a57efafa9f181708d9e4ee05b324a3
From: <sip:127.0.0.12:5060>;tag=2074886745
To: <sip:alice@127.0.0.11:5060>;tag=dqixl8jjv0w
Max-Forwards: 70
Content-Length: 0

]]>
</message>

<message
from="127.0.0.11:5060" 
to="127.0.0.12:5060" 
time="1437463873314"
isSender="false" 
transactionId="z9hg4bk-xxjolo9mn9hi" 
callId="123c727958f6588323a087db02e6a235@127.0.0.12" 
firstLine="BYE sip:null@127.0.0.12:5060 SIP/2.0" 
>
<![CDATA[BYE sip:null@127.0.0.12:5060 SIP/2.0
Via: SIP/2.0/UDP 127.0.0.11:5060;branch=z9hG4bK-xxjolo9mn9hi
From: <sip:127.0.0.12:5060>;tag=2074886745
To: <sip:alice@127.0.0.11:5060>;tag=dqixl8jjv0w
Call-ID: 123c727958f6588323a087db02e6a235@127.0.0.12
CSeq: 1 BYE
Max-Forwards: 70
Contact: <sip:101@127.0.0.11:5060;transport=udp>;reg-id=1
User-Agent: snom300/8.7.3.10
RTP-RxStat: Total_Rx_Pkts=815,Rx_Pkts=0,Rx_Pkts_Lost=0,Remote_Rx_Pkts_Lost=0
RTP-TxStat: Total_Tx_Pkts=812,Tx_Pkts=812,Remote_Tx_Pkts=0
Content-Length: 0

]]>
</message>

<message
from="127.0.0.12:5060" 
to="127.0.0.11:5060" 
time="1437463873322"
isSender="true" 
transactionId="z9hg4bk-xxjolo9mn9hi" 
callId="123c727958f6588323a087db02e6a235@127.0.0.12" 
firstLine="SIP/2.0 481 Call leg/Transaction does not exist" 
>
<![CDATA[SIP/2.0 481 Call leg/Transaction does not exist
To: <sip:alice@127.0.0.11:5060>;tag=dqixl8jjv0w
Via: SIP/2.0/UDP 127.0.0.11:5060;branch=z9hG4bK-xxjolo9mn9hi
CSeq: 1 BYE
Call-ID: 123c727958f6588323a087db02e6a235@127.0.0.12
From: <sip:127.0.0.12:5060>;tag=2074886745
Content-Length: 0

]]>
</message>

<message
from="127.0.0.11:5060" 
to="127.0.0.12:5060" 
time="1437463873384"
isSender="false" 
transactionId="z9hg4bk-xxjolo9mn9hi" 
callId="123c727958f6588323a087db02e6a235@127.0.0.12" 
firstLine="ACK sip:null@127.0.0.12:5060 SIP/2.0" 
>
<![CDATA[ACK sip:null@127.0.0.12:5060 SIP/2.0
Via: SIP/2.0/UDP 127.0.0.11:5060;branch=z9hG4bK-xxjolo9mn9hi
From: <sip:127.0.0.12:5060>;tag=2074886745
To: <sip:alice@127.0.0.11:5060>;tag=dqixl8jjv0w
Call-ID: 123c727958f6588323a087db02e6a235@127.0.0.12
CSeq: 1 ACK
Max-Forwards: 70
Route: <sip:127.0.0.12:5060;transport=udp;lr>
Content-Length: 0

]]>
</message>

正在查看更新的日志。

您发送邀请 From: <sip:127.0.0.12:5060>;tag=2074886745

对端再次发送BYEFrom: <sip:127.0.0.12:5060>;tag=2074886745

端点代表同一地址发送消息 <sip:127.0.0.12:5060> 这是错误的。您的远程方应发送 From: <sip:alice@127.0.0.11:5060>;tag=dqixl8jjv0w。呼叫段 ID 倒序,因此未找到。