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

examples.redirect.Shootist Maven / Gradle / Ivy

package examples.redirect;

import javax.sip.*;
import javax.sip.address.*;
import javax.sip.header.*;
import javax.sip.message.*;

import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Logger;
import org.apache.log4j.SimpleLayout;

import java.util.*;

import junit.framework.TestCase;

/**
 * This class is a UAC template. Shootist is the guy that shoots and shootme is
 * the guy that gets shot.
 * 
 * @author M. Ranganathan
 */

public class Shootist extends TestCase implements SipListener {

	private SipProvider sipProvider;

	private ProtocolObjects protocolObjects;

	private ContactHeader contactHeader;

	private ListeningPoint listeningPoint;

	private ClientTransaction inviteTid;

	private Dialog dialog;

	public static final int myPort = 5080;

	private int peerPort;

	private String peerHostPort;

	private int dialogTerminatedCount;

	private int transctionTerminatedCount;

	private int transactionCount;

	private int dialogCount;

	private boolean byeReceived;

	private boolean redirectReceived;

	private SipURI requestURI;
	
	private static Logger logger = Logger.getLogger(Shootist.class);

	

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

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

		// We are the UAC so the only request we get is the BYE.
		if (request.getMethod().equals(Request.BYE))
			processBye(request, serverTransactionId);

	}

	public void processBye(Request request,
			ServerTransaction serverTransactionId) {
		try {
			logger.info("shootist:  got a bye . ServerTxId = " + serverTransactionId);
			this.byeReceived  = true;
			if (serverTransactionId == null) {
				logger.info("shootist:  null TID.");
				return;
			}
			
			Dialog dialog = serverTransactionId.getDialog();
			assertTrue(dialog == this.dialog);
			logger.info("Dialog State = " + dialog.getState());
			Response response = protocolObjects.messageFactory.createResponse(
					200, request);
			serverTransactionId.sendResponse(response);
			this.transactionCount++;
			logger.info("shootist:  Sending OK.");
			logger.info("Dialog State = " + dialog.getState());
			assertTrue(serverTransactionId.getState() == TransactionState.COMPLETED);
			assertTrue(dialog.getState() == DialogState.TERMINATED);

		} catch (Exception ex) {
			ex.printStackTrace();
			System.exit(0);

		}
	}

	public void processResponse(ResponseEvent responseReceivedEvent) {
		logger.info("Got a response");
		Response response = (Response) responseReceivedEvent.getResponse();
		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());

		try {
			if (response.getStatusCode() == Response.OK) {
				logger.info("response = " + response);
				if (cseq.getMethod().equals(Request.INVITE)) {
					Request ackRequest = dialog.createAck(cseq.getSeqNumber());
					logger.info("Sending ACK");
					dialog.sendAck(ackRequest);
				} 
			} else if  (response.getStatusCode() == Response.MOVED_TEMPORARILY) {
				// Dialog dies as soon as you get an error response.
				assertTrue(tid.getDialog().getState() == DialogState.TERMINATED);
				assertTrue(tid.getDialog() == this.dialog);
				this.redirectReceived = true;
				if (cseq.getMethod().equals(Request.INVITE)) {
					// lookup the contact header
					ContactHeader contHdr = (ContactHeader) response
							.getHeader(ContactHeader.NAME);
					// we can re-use the from header
					FromHeader from = ((FromHeader) response
							.getHeader(FromHeader.NAME));
					// we use the to-address, but without the tag
					ToHeader to = (ToHeader) (response.getHeader(ToHeader.NAME)).clone();
					to.removeParameter("tag");
					// the call-id can be re-used
					CallIdHeader callID = ((CallIdHeader) response
							.getHeader(CallIdHeader.NAME));
					// we take the next cseq
					long seqNo = (((CSeqHeader) response
							.getHeader(CSeqHeader.NAME)).getSeqNumber());
					logger.info("seqNo = " + seqNo);
					CSeqHeader cseqNew = protocolObjects.headerFactory
							.createCSeqHeader(++seqNo, "INVITE");
					// Create ViaHeaders (either use tcp or udp)
					ArrayList viaHeaders = new ArrayList();
					ViaHeader viaHeader = protocolObjects.headerFactory
							.createViaHeader("127.0.0.1", sipProvider
									.getListeningPoint(protocolObjects.transport).getPort(), 
									protocolObjects.transport,
									null);
					// add via headers
					viaHeaders.add(viaHeader);
					// create max forwards
					MaxForwardsHeader maxForwardsHeader = protocolObjects.headerFactory
							.createMaxForwardsHeader(10);
					// create invite Request
					SipURI newUri = (SipURI)this.requestURI.clone();
					newUri.setParameter("redirection", "true");
				
					Request invRequest = protocolObjects.messageFactory
							.createRequest(newUri,
									"INVITE", callID, cseqNew, from, to,
									viaHeaders, maxForwardsHeader);
					// we set the Request URI to the address given
					SipURI contactURI = 
					protocolObjects.addressFactory.createSipURI(null, this.listeningPoint.getIPAddress());
					
					contactURI.setPort(this.listeningPoint.getPort());
					contactURI.setTransportParam(protocolObjects.transport);
					
					Address address = protocolObjects.addressFactory.createAddress(contactURI);
					ContactHeader contact = protocolObjects.headerFactory.createContactHeader(address);
					invRequest.addHeader(contact);
					
					// the contacat header in the response contains where to redirect
					// the request to -- which in this case happens to be back to the
					// same location.
					ContactHeader chdr = (ContactHeader)response.getHeader(ContactHeader.NAME);
					
					SipURI sipUri = (SipURI)chdr.getAddress().getURI();
					sipUri.setLrParam();
					RouteHeader routeHeader = 
						protocolObjects.headerFactory.createRouteHeader(chdr.getAddress());
					invRequest.addHeader(routeHeader);
				
					logger.info("Sending INVITE to "
							+ contHdr.getAddress().getURI().toString());
					inviteTid = sipProvider.getNewClientTransaction(invRequest);
					this.transactionCount++;
					
					logger.info("New TID = " + inviteTid);
					inviteTid.sendRequest();
					assertTrue(inviteTid.getState() == TransactionState.CALLING);
					logger.info("sendReqeust succeeded " + inviteTid);
					Dialog dialog = inviteTid.getDialog();
					assertTrue("Stack must allocate a new dialog", dialog != this.dialog);
					this.dialogCount ++;
					this.dialog = dialog;
				
		
				}
			}
			/**
			 * end of modified code
			 */
		} catch (Exception ex) {
			ex.printStackTrace();
			fail("unexpeced exception");
		}

	}

	public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) {

		logger.info("Transaction Time out");
		fail("Unexpected event");
	}

	

	public SipProvider createProvider() throws Exception {
		logger.info("Shootist: createProvider()");
		listeningPoint = protocolObjects.sipStack.createListeningPoint(
				"127.0.0.1", myPort, protocolObjects.transport);
		this.sipProvider = protocolObjects.sipStack
				.createSipProvider(listeningPoint);
		assertTrue("listening point should be the same as what the provider returns for this transport",
				listeningPoint == sipProvider.getListeningPoint(protocolObjects.transport));
		return sipProvider;

	}

	public void sendInvite() {

		try {
			/**
			 * either use udp or tcp
			 */

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

			String toSipAddress = "there.com";
			String toUser = "LittleGuy";
			String toDisplayName = "The Little Blister";

			// create >From Header
			SipURI fromAddress = protocolObjects.addressFactory.createSipURI(
					fromName, fromSipAddress);

			Address fromNameAddress = protocolObjects.addressFactory
					.createAddress(fromAddress);
			fromNameAddress.setDisplayName(fromDisplayName);
			FromHeader fromHeader = protocolObjects.headerFactory
					.createFromHeader(fromNameAddress, "12345");

			// create To Header
			SipURI toAddress = protocolObjects.addressFactory.createSipURI(
					toUser, toSipAddress);
			Address toNameAddress = protocolObjects.addressFactory
					.createAddress(toAddress);
			toNameAddress.setDisplayName(toDisplayName);
			ToHeader toHeader = protocolObjects.headerFactory.createToHeader(
					toNameAddress, null);

			// create Request URI
			this.requestURI = protocolObjects.addressFactory.createSipURI(
					toUser, peerHostPort);

			// Create ViaHeaders

			ArrayList viaHeaders = new ArrayList();
			ViaHeader viaHeader = protocolObjects.headerFactory
					.createViaHeader("127.0.0.1", sipProvider
							.getListeningPoint(protocolObjects.transport).getPort(), protocolObjects.transport,
							null);

			// add via headers
			viaHeaders.add(viaHeader);

			// Create ContentTypeHeader
			ContentTypeHeader contentTypeHeader = protocolObjects.headerFactory
					.createContentTypeHeader("application", "sdp");

			// Create a new CallId header
			CallIdHeader callIdHeader = sipProvider.getNewCallId();

			// Create a new Cseq header
			CSeqHeader cSeqHeader = protocolObjects.headerFactory
					.createCSeqHeader(1L, Request.INVITE);

			// Create a new MaxForwardsHeader
			MaxForwardsHeader maxForwards = protocolObjects.headerFactory
					.createMaxForwardsHeader(70);

			// Create the request.
			Request request = protocolObjects.messageFactory.createRequest(
					requestURI, Request.INVITE, callIdHeader, cSeqHeader,
					fromHeader, toHeader, viaHeaders, maxForwards);
			// Create contact headers
			String host = "127.0.0.1";

			SipURI contactUrl = protocolObjects.addressFactory.createSipURI(
					fromName, host);
			/**
			 * either use tcp or udp
			 */
			contactUrl.setPort(listeningPoint.getPort());
			contactUrl.setTransportParam(protocolObjects.transport);
		
			// Create the contact name address.
			
			Address contactAddress = protocolObjects.addressFactory
					.createAddress(contactUrl);
			contactUrl.setLrParam();

			// Add the contact address.
			contactAddress.setDisplayName(fromName);

			contactHeader = protocolObjects.headerFactory
					.createContactHeader(contactAddress);
			request.addHeader(contactHeader);
			
			SipURI uri = protocolObjects.addressFactory.createSipURI(null, "127.0.0.1");
			
			uri.setLrParam();
			uri.setTransportParam(protocolObjects.transport);
			uri.setPort(this.peerPort);
			

			Address address = protocolObjects.addressFactory.createAddress(uri);
			RouteHeader routeHeader = protocolObjects.headerFactory.createRouteHeader(address);
			request.addHeader(routeHeader);
			// Add the extension header.
			Header extensionHeader = protocolObjects.headerFactory
					.createHeader("My-Header", "my header value");
			request.addHeader(extensionHeader);

			String sdpData = "v=0\r\n"
					+ "o=4855 13760799956958020 13760799956958020"
					+ " IN IP4  129.6.55.78\r\n" + "s=mysession session\r\n"
					+ "p=+46 8 52018010\r\n" + "c=IN IP4  129.6.55.78\r\n"
					+ "t=0 0\r\n" + "m=audio 6022 RTP/AVP 0 4 18\r\n"
					+ "a=rtpmap:0 PCMU/8000\r\n" + "a=rtpmap:4 G723/8000\r\n"
					+ "a=rtpmap:18 G729A/8000\r\n" + "a=ptime:20\r\n";
			byte[] contents = sdpData.getBytes();

			request.setContent(contents, contentTypeHeader);

			extensionHeader = protocolObjects.headerFactory.createHeader(
					"My-Other-Header", "my new header value ");
			request.addHeader(extensionHeader);

			Header callInfoHeader = protocolObjects.headerFactory.createHeader(
					"Call-Info", "");
			request.addHeader(callInfoHeader);

			// Create the client transaction.
			inviteTid = sipProvider.getNewClientTransaction(request);

			// send the request out.
			inviteTid.sendRequest();

			this.transactionCount ++;
			
			assertTrue(inviteTid.getState() == TransactionState.CALLING);
			
			logger.info("client tx = " + inviteTid);
			dialog = inviteTid.getDialog();
			this.dialogCount++;
			assertTrue(dialog != null);
			assertTrue(dialog.getState() == null);

		} catch (Exception ex) {
			logger.error(ex.getMessage(),ex);
			fail("unexpected exception");
		}
	}
	
	public Shootist (ProtocolObjects protocolObjects) {
		this.protocolObjects = protocolObjects;
		this.peerPort = Shootme.myPort;
		this.peerHostPort = "127.0.0.1:"+ peerPort;
	}

	public static void main(String args[]) throws Exception {
		ProtocolObjects  protocolObjects = new ProtocolObjects ("shootist",true,"udp","");
		logger.addAppender(new ConsoleAppender(new SimpleLayout()));
		Shootist shootist = new Shootist(protocolObjects);
		shootist.createProvider();
		shootist.sipProvider.addSipListener(shootist);
		shootist.sendInvite();

	}

	public void processIOException(IOExceptionEvent exceptionEvent) {
		logger.info("IOException happened for "
				+ exceptionEvent.getHost() + " port = "
				+ exceptionEvent.getPort());

	}

	public void processTransactionTerminated(
			TransactionTerminatedEvent transactionTerminatedEvent) {
		logger.info("Transaction terminated event recieved for " + 
				transactionTerminatedEvent.getClientTransaction());
		this.transctionTerminatedCount++;
	}

	public void processDialogTerminated(
			DialogTerminatedEvent dialogTerminatedEvent) {
		this.dialogTerminatedCount++;

	}

	public void checkState() {
		assertTrue(dialogTerminatedCount == dialogCount);
		assertTrue(this.byeReceived  && this.redirectReceived );
		
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy