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

package test.unit.gov.nist.javax.sip.stack;

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 org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Logger;
import org.apache.log4j.SimpleLayout;

import test.tck.msgflow.callflows.ScenarioHarness;

import examples.cancel.ProtocolObjects;
import examples.cancel.Shootist;

import junit.framework.TestCase;

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 static int port = 6050;

	private static int peerPort = 6060;
	
	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 = "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 + stackname + "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());

			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 UAS 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 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;

		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 + stackname + "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());

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

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

		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();
		Thread.sleep(40000);
		assertTrue ( shootist.conditionMet());
	}
	
	public void tearDown() {
		shootist.destroy();
		shootme.destroy();
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy