All Downloads are FREE. Search and download functionalities are using the official Maven repository.

test.unit.gov.nist.javax.sip.stack.CancelEventTest Maven / Gradle / Ivy

There is a newer version: 1.3.0-91
Show newest version
package test.unit.gov.nist.javax.sip.stack;

import gov.nist.javax.sip.stack.NioMessageProcessorFactory;

import java.util.ArrayList;
import java.util.Properties;
import java.util.Random;

import javax.sip.ClientTransaction;
import javax.sip.Dialog;
import javax.sip.DialogTerminatedEvent;
import javax.sip.IOExceptionEvent;
import javax.sip.ListeningPoint;
import javax.sip.RequestEvent;
import javax.sip.ResponseEvent;
import javax.sip.ServerTransaction;
import javax.sip.SipException;
import javax.sip.SipFactory;
import javax.sip.SipListener;
import javax.sip.SipProvider;
import javax.sip.SipStack;
import javax.sip.Transaction;
import javax.sip.TransactionState;
import javax.sip.TransactionTerminatedEvent;
import javax.sip.address.Address;
import javax.sip.address.AddressFactory;
import javax.sip.address.URI;
import javax.sip.header.CSeqHeader;
import javax.sip.header.CallIdHeader;
import javax.sip.header.ContactHeader;
import javax.sip.header.ContentTypeHeader;
import javax.sip.header.FromHeader;
import javax.sip.header.HeaderFactory;
import javax.sip.header.MaxForwardsHeader;
import javax.sip.header.RouteHeader;
import javax.sip.header.ToHeader;
import javax.sip.header.ViaHeader;
import javax.sip.message.MessageFactory;
import javax.sip.message.Request;
import javax.sip.message.Response;

import junit.framework.TestCase;

import org.apache.log4j.Logger;
import test.tck.msgflow.callflows.AssertUntil;
import test.tck.msgflow.callflows.NetworkPortAssigner;

import test.tck.msgflow.callflows.ScenarioHarness;
import test.tck.msgflow.callflows.TestAssertion;

public class CancelEventTest extends  ScenarioHarness {

    private static String transport = "udp";
    private static String unexpectedException = "Unexpected Exception ";

    private static String host = "127.0.0.1";

    private int port = NetworkPortAssigner.retrieveNextPort();

    private int peerPort = NetworkPortAssigner.retrieveNextPort();

    private static Logger logger = Logger.getLogger("test.tck");

    static {
        if (!logger.isAttached(console))
            logger.addAppender(console);
    }

    public CancelEventTest() {
        super("CanceEventTest",true);
    }


    class Shootist implements SipListener {

        private SipProvider sipProvider;

        private ContactHeader contactHeader;

        private ListeningPoint listeningPoint;

        private String peerHost = "127.0.0.1";

        private ClientTransaction inviteTid;

        private Dialog dialog;

        private boolean cancelOk = false;
        private boolean cancelSent = false;
        private boolean cancelTxTerm = false;
        private boolean inviteTxTerm = false;
        private boolean dialogTerminated = false;



        AddressFactory addressFactory;

        MessageFactory messageFactory;

        HeaderFactory headerFactory;

        SipStack sipStack;

        int logLevel = 32;

        String logFileDirectory = "./target/logs/";

        Shootist() {
            SipFactory sipFactory = null;

            sipFactory = SipFactory.getInstance();
            sipFactory.setPathName("gov.nist");
            Properties properties = new Properties();
            // If you want to try TCP transport change the following to

            // If you want to use UDP then uncomment this.
            String stackname = "shootist";
            properties.setProperty("javax.sip.STACK_NAME", stackname);

            // The following properties are specific to nist-sip
            // and are not necessarily part of any other jain-sip
            // implementation.
            properties.setProperty("gov.nist.javax.sip.DEBUG_LOG",
                    logFileDirectory + this.getClass().getName()  + ".debug.txt");
            properties.setProperty("gov.nist.javax.sip.SERVER_LOG",
                    logFileDirectory + stackname + "log.txt");

            // Set to 0 in your production code for max speed.
            // You need 16 for logging traces. 32 for debug + traces.
            // Your code will limp at 32 but it is best for debugging.
            properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL",
                    new Integer(logLevel).toString());

            if(System.getProperty("enableNIO") != null && System.getProperty("enableNIO").equalsIgnoreCase("true")) {
            	logger.info("\nNIO Enabled\n");
            	properties.setProperty("gov.nist.javax.sip.MESSAGE_PROCESSOR_FACTORY", NioMessageProcessorFactory.class.getName());
            }
            
            try {
                // Create SipStack object
                sipStack = sipFactory.createSipStack(properties);

                System.out.println("createSipStack " + sipStack);
            } catch (Exception e) {
                // could not find
                // gov.nist.jain.protocol.ip.sip.SipStackImpl
                // in the classpath
                e.printStackTrace();
                System.err.println(e.getMessage());
                throw new RuntimeException("Stack failed to initialize");
            }

            try {
                headerFactory = sipFactory.createHeaderFactory();
                addressFactory = sipFactory.createAddressFactory();
                messageFactory = sipFactory.createMessageFactory();
            } catch (SipException ex) {
                ex.printStackTrace();
                throw new RuntimeException(ex);
            }
        }

        public void destroy() {
            sipStack.stop();
        }

        public void start() throws Exception {
            sipStack.start();

        }

        public void processRequest(RequestEvent requestReceivedEvent) {
            Request request = requestReceivedEvent.getRequest();
            ServerTransaction serverTransactionId = requestReceivedEvent
                    .getServerTransaction();

            logger.info("\n\nRequest " + request.getMethod() + " received at "
                    + sipStack.getStackName() + " with server transaction id "
                    + serverTransactionId);

        }

        public void processResponse(ResponseEvent responseReceivedEvent) {
            Response response = (Response) responseReceivedEvent.getResponse();
            logger.info("Got a response"
                    + ((CSeqHeader) response.getHeader(CSeqHeader.NAME))
                            .getMethod());

            ClientTransaction tid = responseReceivedEvent
                    .getClientTransaction();
            CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME);

            logger.info("Response received : Status Code = "
                    + response.getStatusCode() + " " + cseq);
            if (tid == null) {
                logger.info("Stray response -- dropping ");
                return;
            }
            logger.info("transaction state is " + tid.getState());
            logger.info("Dialog = " + tid.getDialog());
            logger.info("Dialog State is " + tid.getDialog().getState());

            if (dialog == null) {
                logger.info("SETTING DIALOG SINCE IT WAS NULL!!!!!!");
                dialog = tid.getDialog();
            }

            if (response.getStatusCode() == 180) {
                sendCancel();
            } else if (response.getStatusCode() == 200)// more checks?
            {
                cancelOk = true;
            } else {
                logger.info("Got weird response:" + response);
            }

        }

        public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) {
            Transaction transaction = null;
            if (timeoutEvent.isServerTransaction()) {
                transaction = timeoutEvent.getServerTransaction();
            } else {
                transaction = timeoutEvent.getClientTransaction();
            }
            logger.info("state = " + transaction.getState());
            logger.info("dialog = " + transaction.getDialog());
            logger.info("dialogState = " + transaction.getDialog().getState());
            logger.info("Transaction Time out");
            fail("Timeout Shouldnt happen on UAC side!!!");
        }

        private void sendCancel() {
            try {
                logger.info("Sending cancel");

                Request cancelRequest = inviteTid.createCancel();
                ClientTransaction cancelTid = sipProvider
                        .getNewClientTransaction(cancelRequest);
                cancelTid.sendRequest();
                cancelSent = true;
            } catch (Exception ex) {
                ex.printStackTrace();
                logger.error(unexpectedException, ex);
                fail(unexpectedException);
            }
        }

        public SipProvider createSipProvider() {
            try {
                listeningPoint = sipStack.createListeningPoint(host, port,
                        transport);

                sipProvider = sipStack.createSipProvider(listeningPoint);
                return sipProvider;
            } catch (Exception ex) {
                logger.error(unexpectedException, ex);
                fail(unexpectedException);
                return null;
            }

        }

        public void sendInvite() {

            String fromName = "BigGuy";
            // String fromSipAddress = "here.com";
            String fromDisplayName = "The Master Blaster";

            // String toSipAddress = "there.com";
            String toUser = "LittleGuy";
            String toDisplayName = "The Little Blister";
            String localAddress = sipProvider.getListeningPoint("udp")
                    .getIPAddress();
            int localPort = sipProvider.getListeningPoint("udp").getPort();
            String localTransport = sipProvider.getListeningPoint("udp")
                    .getTransport();

            ContactHeader contactHeader = null;
            ToHeader toHeader = null;
            FromHeader fromHeader = null;
            CSeqHeader cseqHeader = null;
            ViaHeader viaHeader = null;
            CallIdHeader callIdHeader = null;
            MaxForwardsHeader maxForwardsHeader = null;
            ContentTypeHeader contentTypeHeader = null;
            RouteHeader routeHeader = null;
            // LETS CREATEOUR HEADERS

            try {
                cseqHeader = headerFactory.createCSeqHeader(1L, Request.INVITE);
                viaHeader = headerFactory.createViaHeader(localAddress,
                        localPort, localTransport, null);
                Address fromAddres = addressFactory
                        .createAddress("sip:SimpleSIPPing@" + localAddress
                                + ":" + localPort);
                // Address
                // toAddress=addressFactory.createAddress("sip:pingReceiver@"+peerAddres+":"+peerPort);
                Address toAddress = addressFactory.createAddress("sip:"
                        + this.peerHost + ":" + peerPort);

                contactHeader = headerFactory.createContactHeader(fromAddres);
                toHeader = headerFactory.createToHeader(toAddress, null);
                fromHeader = headerFactory.createFromHeader(fromAddres, Integer
                        .toString(new Random().nextInt()));
                callIdHeader = sipProvider.getNewCallId();
                maxForwardsHeader = headerFactory.createMaxForwardsHeader(70);
                contentTypeHeader = headerFactory.createContentTypeHeader(
                        "text", "plain");
                Address routeAddress = addressFactory.createAddress("sip:"
                        + this.peerHost + ":" + peerPort);
                routeHeader = headerFactory.createRouteHeader(routeAddress);

                // LETS CREATE OUR REQUEST AND
                ArrayList list = new ArrayList();
                list.add(viaHeader);
                URI requestURI = null;
                Request request = null;
                Request cancel = null;
                Request inviteRequest = null;

                requestURI = addressFactory.createURI("sip:" + localAddress);
                inviteRequest = request = messageFactory.createRequest(
                        requestURI, Request.INVITE, callIdHeader, cseqHeader,
                        fromHeader, toHeader, list, maxForwardsHeader,
                        contentTypeHeader, "CANCEL".getBytes());
                request.addHeader(routeHeader);
                request.addHeader(contactHeader);

                // ClientTransaction CTInvite = null;
                // ClientTransaction CTCancel = null;

                inviteTid = sipProvider.getNewClientTransaction(request);

                inviteTid.sendRequest();
                dialog = inviteTid.getDialog();
                logger.info("SET DIALOG TO[" + dialog + "]");
            } catch (Exception e) {

                logger.error("Unexpected exception", e);
                fail("Unexpected exception");

            }

        }

        public void processIOException(IOExceptionEvent exceptionEvent) {
            logger.info("Got an IO Exception");
            fail("unexpected event");

        }

        public void processTransactionTerminated(
                TransactionTerminatedEvent transactionTerminatedEvent) {
            if (!transactionTerminatedEvent.isServerTransaction()) {
                ClientTransaction clientTx = transactionTerminatedEvent
                        .getClientTransaction();

                String method = clientTx.getRequest().getMethod();

                logger.info("Server Tx : " + method + " terminated ");
                if (method.equals("INVITE")) {
                    inviteTxTerm = true;
                } else if (method.equals("CANCEL")) {
                    cancelTxTerm = true;
                } else {
                    fail("Unexpected transaction has ended!!![" + method + "]");
                }
            }
        }

        public void processDialogTerminated(
                DialogTerminatedEvent dialogTerminatedEvent) {
            logger.info("Got a dialog terminated event");
            if (dialog == dialogTerminatedEvent.getDialog()) {
                logger.info("Dialog matches dialog created before");
                dialogTerminated = true;
            }

        }
        
        public TestAssertion getAssertion() {
            return new TestAssertion() {
                    @Override
                    public boolean assertCondition() {
                        return cancelOk && cancelTxTerm && inviteTxTerm && dialogTerminated;
                    }
                };
        }

        public boolean conditionMet() {
            System.out.println("cancelOK = " + cancelOk);
            System.out.println("cancelTerm = " + cancelTxTerm);
            System.out.println("inviteTxTerm = " + inviteTxTerm);
            System.out.println("dialogTerminated = " + dialogTerminated);

            return cancelOk && cancelTxTerm && inviteTxTerm && dialogTerminated;
        }

        public String[] conditionsState() {
            String[] result = new String[5];
            result[0] = "[" + cancelOk + "] - OK received for CANCEL Req";
            result[1] = "[" + cancelTxTerm + "] - CANCEL STX terminated";
            result[2] = "[" + inviteTxTerm + "] - INVITE STX terminated";
            // echhh
            String state = null;
            if (dialog == null)
                state = "DIALOG IS NULL";
            else
                state = dialog.getState().toString();
            result[3] = "[" + dialogTerminated + "] - Dialog terminated state["
                    + state + "]";
            result[4] = "[" + cancelSent + "] - CANCEL sent";
            return result;
        }



    }

    class Shootme  implements SipListener {

        private static final String myAddress = "127.0.0.1";

        private int myPort = peerPort;

        private ServerTransaction inviteTid;

        private SipProvider sipProvider;

        private Dialog dialog;

        private boolean cancelOk = false;
        private boolean cancelTxTerm = false;
        private boolean inviteTxTerm = false;
        private boolean dialogTerminated = false;
        private int dteCount = 0;

        private static final String unexpectedException = "Unexpected Exception ";

        SipStack sipStack;

        int logLevel = 32;

        String logFileDirectory = "logs/";

        AddressFactory addressFactory;

        MessageFactory messageFactory;

        HeaderFactory headerFactory;

		private boolean dialogOnCancelTx = true;

        Shootme () {
            SipFactory sipFactory = null;
            String stackname = "shootme";

            sipFactory = SipFactory.getInstance();
            sipFactory.setPathName("gov.nist");
            Properties properties = new Properties();
            // If you want to try TCP transport change the following to

            // If you want to use UDP then uncomment this.
            properties.setProperty("javax.sip.STACK_NAME", stackname);

            // The following properties are specific to nist-sip
            // and are not necessarily part of any other jain-sip
            // implementation.
            properties.setProperty("gov.nist.javax.sip.DEBUG_LOG",
                    logFileDirectory + this.getClass().getName() + ".debug.txt");
            properties.setProperty("gov.nist.javax.sip.SERVER_LOG",
                    logFileDirectory + stackname + "log.txt");

            // Set to 0 in your production code for max speed.
            // You need 16 for logging traces. 32 for debug + traces.
            // Your code will limp at 32 but it is best for debugging.
            properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL",
                    new Integer(logLevel).toString());

            if(System.getProperty("enableNIO") != null && System.getProperty("enableNIO").equalsIgnoreCase("true")) {
            	logger.info("\nNIO Enabled\n");
            	properties.setProperty("gov.nist.javax.sip.MESSAGE_PROCESSOR_FACTORY", NioMessageProcessorFactory.class.getName());
            }
            
            try {
                // Create SipStack object
                sipStack = sipFactory.createSipStack(properties);

                System.out.println("createSipStack " + sipStack);
            } catch (Exception e) {
                // could not find
                // gov.nist.jain.protocol.ip.sip.SipStackImpl
                // in the classpath
                e.printStackTrace();
                System.err.println(e.getMessage());
                throw new RuntimeException("Stack failed to initialize");
            }

            try {
                headerFactory = sipFactory.createHeaderFactory();
                addressFactory = sipFactory.createAddressFactory();
                messageFactory = sipFactory.createMessageFactory();
            } catch (SipException ex) {
                ex.printStackTrace();
                throw new RuntimeException(ex);
            }
        }

        public void destroy() {
            sipStack.stop();
        }

        public void start() throws Exception {
            sipStack.start();

        }

        public void processRequest(RequestEvent requestEvent) {
            Request request = requestEvent.getRequest();
            ServerTransaction serverTransactionId = requestEvent
                    .getServerTransaction();

            logger.info("\n\nRequest " + request.getMethod() + " received at "
                    + sipStack.getStackName() + " with server transaction id "
                    + serverTransactionId);

            if (request.getMethod().equals(Request.INVITE)) {
                processInvite(requestEvent, serverTransactionId);

            } else if (request.getMethod().equals(Request.CANCEL)) {
                processCancel(requestEvent, serverTransactionId);
            }

        }

        public void processResponse(ResponseEvent responseEvent) {
        }

        /**
         * Process the invite request.
         */
        public void processInvite(RequestEvent requestEvent,
                ServerTransaction serverTransaction) {
            SipProvider sipProvider = (SipProvider) requestEvent.getSource();
            Request request = requestEvent.getRequest();
            try {
                logger.info("shootme: got an Invite sending RINGING");
                // logger.info("shootme: " + request);
                Response response = messageFactory.createResponse(180, request);
                ToHeader toHeader = (ToHeader) response
                        .getHeader(ToHeader.NAME);
                toHeader.setTag("4321"); // Application is supposed to set.
                Address address = addressFactory.createAddress("Shootme ");
                ContactHeader contactHeader = headerFactory
                        .createContactHeader(address);
                response.addHeader(contactHeader);
                ServerTransaction st = requestEvent.getServerTransaction();

                if (st == null) {
                    st = sipProvider.getNewServerTransaction(request);
                    logger.info("Created a new server transaction for "
                            + request.getMethod() + " serverTransaction = "
                            + st);
                }
                inviteTid = st;

                dialog = st.getDialog();

                st.sendResponse(response);

            } catch (Exception ex) {
                logger.error(ex);
                fail(unexpectedException);
            }
        }

        public void processCancel(RequestEvent requestEvent,
                ServerTransaction serverTransactionId) {

            Request request = requestEvent.getRequest();
            try {
                logger.info("shootme:  got a cancel.");
                if (serverTransactionId == null) {
                    logger.info("shootme:  null tid.");
                    return;
                }
                TestCase.assertTrue(inviteTid != serverTransactionId);
                Response response = messageFactory.createResponse(200, request);
                serverTransactionId.sendResponse(response);
                Request inviteRequest = inviteTid.getRequest();
                if (inviteTid.getState() != TransactionState.TERMINATED) {
                    response = messageFactory.createResponse(
                            Response.REQUEST_TERMINATED, inviteRequest);
                    inviteTid.sendResponse(response);
                }
                cancelOk = true;
                if(serverTransactionId.getDialog() == null) {
                	dialogOnCancelTx = false;
                }
            } catch (Exception ex) {
                // logger.error(ex);
                ex.printStackTrace();
                fail(unexpectedException);

            }
        }

        public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) {
            Transaction transaction;
            if (timeoutEvent.isServerTransaction()) {
                transaction = timeoutEvent.getServerTransaction();
            } else {
                transaction = timeoutEvent.getClientTransaction();
            }
            logger.info("state = " + transaction.getState());
            logger.info("dialog = " + transaction.getDialog());
            logger.info("dialogState = " + transaction.getDialog().getState());
            logger.info("Transaction Time out");
            fail("Timeout Shouldnt happen on UAS side!!!");
        }

        public SipProvider createProvider() {
            try {

                ListeningPoint lp = sipStack.createListeningPoint(myAddress,
                        myPort, transport);

                sipProvider = sipStack.createSipProvider(lp);
                logger.info("udp provider " + sipProvider);
                return sipProvider;
            } catch (Exception ex) {
                logger.error(ex);
                fail(unexpectedException);
                return null;

            }

        }

        public void processIOException(IOExceptionEvent exceptionEvent) {
            // TODO Auto-generated method stub

        }

        public void processTransactionTerminated(
                TransactionTerminatedEvent transactionTerminatedEvent) {
            if (transactionTerminatedEvent.isServerTransaction()) {
                ServerTransaction serverTx = transactionTerminatedEvent
                        .getServerTransaction();

                String method = serverTx.getRequest().getMethod();

                logger.info("Server Tx : " + method + " terminated ");
                if (method.equals("INVITE")) {
                    inviteTxTerm = true;
                } else if (method.equals("CANCEL")) {
                    cancelTxTerm = true;
                } else {
                    fail("Unexpected transaction has ended!!![" + method + "]");
                }
            }
        }

        public void processDialogTerminated(
                DialogTerminatedEvent dialogTerminatedEvent) {

            dialogTerminated = true;
            dteCount++;
        }
        
        public TestAssertion getAssertion() {
            return new TestAssertion() {
                    @Override
                    public boolean assertCondition() {
                        return cancelOk && cancelTxTerm && inviteTxTerm && dialogTerminated && dialogOnCancelTx;
                    }
                };
        }        

        public boolean conditionMet() {
             System.out.println("cancelOK = " + cancelOk);
             System.out.println("cancelTerm = " + cancelTxTerm);
             System.out.println("inviteTxTerm = " + inviteTxTerm);
             System.out.println("dialogTerminated = " + dialogTerminated);
             System.out.println("dialogOnCancelTx = " + dialogOnCancelTx);

             return cancelOk && cancelTxTerm && inviteTxTerm && dialogTerminated && dialogOnCancelTx;
        }

        public String[] conditionsState() {
            String[] result = new String[4];
            result[0] = "[" + cancelOk + "] - OK sent for CANCEL Req";
            result[1] = "[" + cancelTxTerm + "] - CANCEL STX terminated";
            result[2] = "[" + inviteTxTerm + "] - INVITE STX terminated";
            // echhh
            String state = null;
            if (dialog == null)
                state = "DIALOG IS NULL";
            else
                state = dialog.getState().toString();
            result[3] = "[" + dialogTerminated + "] - Dialog terminated state["
                    + state + "] count [" + dteCount + "]";
            return result;
        }

    }

    Shootist shootist;
    Shootme shootme;

    public void setUp() throws Exception {


        shootist = new Shootist();
        shootist.createSipProvider();
        shootist.sipProvider.addSipListener(shootist);
        shootme = new Shootme();
        shootme.createProvider();
        shootme.sipProvider.addSipListener(shootme);



    }

    public void testCancelEvent() throws Exception {
        shootist.sendInvite();
        AssertUntil.assertUntil(shootist.getAssertion(), 40000);
        AssertUntil.assertUntil(shootme.getAssertion(), 40000);
        assertTrue ( shootist.conditionMet());
        assertTrue ( shootme.conditionMet());
    }

    public void tearDown() {
        shootist.destroy();
        shootme.destroy();
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy