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

test.tck.msgflow.callflows.recroute.Proxy Maven / Gradle / Ivy

There is a newer version: 1.3.0-91
Show newest version
package test.tck.msgflow.callflows.recroute;

import java.util.Hashtable;

import javax.sip.ClientTransaction;
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.SipListener;
import javax.sip.SipProvider;
import javax.sip.TimeoutEvent;
import javax.sip.TransactionState;
import javax.sip.TransactionTerminatedEvent;
import javax.sip.address.Address;
import javax.sip.address.SipURI;
import javax.sip.header.CSeqHeader;
import javax.sip.header.RecordRouteHeader;
import javax.sip.header.RouteHeader;
import javax.sip.header.ViaHeader;
import javax.sip.message.Request;
import javax.sip.message.Response;

import org.apache.log4j.Logger;

import test.tck.TestHarness;
import test.tck.msgflow.callflows.ProtocolObjects;
import test.tck.msgflow.callflows.TestAssertion;

/**
 * A very simple Record-Routing proxy server.
 *
 * @author M. Ranganathan
 * @author Jeroen van Bemmel
 *
 */
public class Proxy extends TestHarness implements SipListener {

    // private ServerTransaction st;

    private static String host = "127.0.0.1";

    private int port = 5070;
    
    private int peerPort;

    private SipProvider sipProvider;

    private static String unexpectedException = "Unexpected exception";

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

    private ProtocolObjects protocolObjects;

    private boolean ackSeen;

    private boolean inviteSeen;

    private boolean byeSeen;

    private int infoCount = 0;


    public TestAssertion getAssertion() {
        return new TestAssertion() {
            
            @Override
            public boolean assertCondition() {
                return inviteSeen && (infoCount == 2) && byeSeen && ackSeen;
            }
        };
    }
    
    public void checkState() {
        TestHarness.assertTrue("INVITE should be seen by proxy", inviteSeen);
        TestHarness.assertTrue("Should see two INFO messages", infoCount == 2);
        TestHarness.assertTrue("BYE should be seen by proxy", byeSeen);
        TestHarness.assertTrue("ACK should be seen by proxy", ackSeen);
    }

    public void processRequest(RequestEvent requestEvent) {
        try {
            Request request = requestEvent.getRequest();
            SipProvider sipProvider = (SipProvider) requestEvent.getSource();
            if (request.getMethod().equals(Request.INVITE)) {
                inviteSeen = true;

                ListeningPoint lp = sipProvider
                        .getListeningPoint(protocolObjects.transport);
                String host = lp.getIPAddress();
                int port = lp.getPort();

                ServerTransaction st = null;
                if (requestEvent.getServerTransaction() == null) {
                    st = sipProvider.getNewServerTransaction(request);
                }
                Request newRequest = (Request) request.clone();

                //
                // Add a Route: header to 5080
                //
                SipURI sipUri = protocolObjects.addressFactory.createSipURI(
                        "UA1", "127.0.0.1");
                sipUri.setPort(peerPort);
                sipUri.setLrParam();
                sipUri.setTransportParam( protocolObjects.transport );
                Address address = protocolObjects.addressFactory.createAddress(
                        "client1", sipUri);
                RouteHeader rheader = protocolObjects.headerFactory
                        .createRouteHeader(address);
                newRequest.addFirst(rheader);

                //
                // Add a Via header + Record-Route
                //
                ViaHeader viaHeader = protocolObjects.headerFactory
                        .createViaHeader(host, port, protocolObjects.transport,
                                null);
                newRequest.addFirst(viaHeader);

                ClientTransaction ct1 = sipProvider
                        .getNewClientTransaction(newRequest);

                sipUri = protocolObjects.addressFactory.createSipURI("proxy",
                        "127.0.0.1");
                address = protocolObjects.addressFactory.createAddress("proxy",
                        sipUri);
                sipUri.setPort(this.port);
                sipUri.setLrParam();
                sipUri.setTransportParam(protocolObjects.transport);

                RecordRouteHeader recordRoute = protocolObjects.headerFactory
                        .createRecordRouteHeader(address);
                newRequest.addHeader(recordRoute);
                ct1.setApplicationData(st);

                // Send the request out to the two listening point of the
                // client.
                ct1.sendRequest();

                TestHarness.assertNull(ct1.getDialog());
            } else if (request.getMethod().equals(Request.ACK)) {
                Request newRequest = (Request) request.clone();
                newRequest.removeFirst(RouteHeader.NAME);
                ViaHeader viaHeader = protocolObjects.headerFactory
                        .createViaHeader(host, port, protocolObjects.transport,
                                null);
                newRequest.addFirst(viaHeader);
                this.ackSeen = true;
                logger.debug("PROXY : sendingAck "  + newRequest);
                sipProvider.sendRequest(newRequest);
            } else {
                // Remove the topmost route header
                // The route header will make sure it gets to the right place.
                logger.debug("proxy: Got a request\n" + request);
                if (request.getMethod().equals(Request.BYE)) {
                    this.byeSeen = true;
                }
                if (request.getMethod().equals(Request.INFO)) {
                    this.infoCount++;
                }

                if (requestEvent.getServerTransaction() == null) {
                    TestHarness.assertNull("Dialog should be null",
                            requestEvent.getDialog());
                    ServerTransaction stx = sipProvider
                            .getNewServerTransaction(request);
                    Request newRequest = (Request) request.clone();
                    newRequest.removeFirst(RouteHeader.NAME);
                    ViaHeader viaHeader = protocolObjects.headerFactory
                            .createViaHeader(host, port,
                                    protocolObjects.transport, null);
                    newRequest.addFirst(viaHeader);

                    ClientTransaction ctx = sipProvider
                            .getNewClientTransaction(newRequest);
                    ctx.setApplicationData(stx);
                    stx.setApplicationData(ctx);
                    ctx.sendRequest();
                } else {
                    logger.debug("Saw a retransmission? State = "
                            + requestEvent.getServerTransaction().getState());
                }
            }

        } catch (Exception ex) {
            ex.printStackTrace();
            logger.error("Unexpected error forwarding request", ex);
            TestHarness.fail("Unexpected exception forwarding request");
        }

    }

    public void processResponse(ResponseEvent responseEvent) {
        try {
            Response response = responseEvent.getResponse();
            CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
            logger.debug("ClientTxID = "
                    + responseEvent.getClientTransaction()
                    + " client tx id "
                    + ((ViaHeader) response.getHeader(ViaHeader.NAME))
                            .getBranch() + " CSeq header = "
                    + response.getHeader(CSeqHeader.NAME) + " status code = "
                    + response.getStatusCode());

            // JvB: stateful proxy MUST NOT forward 100 Trying
            if (response.getStatusCode() == 100)
                return;

            ClientTransaction ct = responseEvent.getClientTransaction();
            if (ct != null) {
                ServerTransaction st = (ServerTransaction) ct
                        .getApplicationData();

                // Strip the topmost via header
                Response newResponse = (Response) response.clone();
                newResponse.removeFirst(ViaHeader.NAME);
                // The server tx goes to the terminated state.
                if ( st.getState() != TransactionState.TERMINATED)
                 st.sendResponse(newResponse);

                TestHarness.assertNull(st.getDialog());
            } else {
                // Client tx has already terminated but the UA is
                // retransmitting
                // just forward the response statelessly.
                // Strip the topmost via header

                Response newResponse = (Response) response.clone();
                newResponse.removeFirst(ViaHeader.NAME);
                // Send the retransmission statelessly
                SipProvider sipProvider = (SipProvider) responseEvent
                        .getSource();
                sipProvider.sendResponse(newResponse);
            }

        } catch (Exception ex) {
            ex.printStackTrace();
            TestHarness.fail("unexpected exception",ex);
        }
    }

    public void processTimeout(TimeoutEvent timeoutEvent) {
        logger.error("Timeout occured");
        fail("unexpected event");
    }

    public void processIOException(IOExceptionEvent exceptionEvent) {
        logger.error("IOException occured");
        fail("unexpected exception io exception");
    }

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

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

    }

    public void processTransactionTerminated(
            TransactionTerminatedEvent transactionTerminatedEvent) {
        logger.debug("Transaction terminated event occured -- cleaning up");
    }

    public void processDialogTerminated(
            DialogTerminatedEvent dialogTerminatedEvent) {
        fail("unexpected event");
    }

    public Proxy(int myPort, int peerPort, ProtocolObjects protocolObjects) {
        this.port = myPort;
        this.peerPort = peerPort;
        this.protocolObjects = protocolObjects;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy