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

examples.forked.invite.Proxy Maven / Gradle / Ivy

package examples.forked.invite;

import gov.nist.javax.sip.address.SipUri;

import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Properties;

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.SipFactory;
import javax.sip.SipListener;
import javax.sip.SipProvider;
import javax.sip.SipStack;
import javax.sip.TimeoutEvent;
import javax.sip.TransactionTerminatedEvent;
import javax.sip.address.Address;
import javax.sip.address.AddressFactory;
import javax.sip.address.SipURI;
import javax.sip.header.CSeqHeader;
import javax.sip.header.HeaderFactory;
import javax.sip.header.RecordRouteHeader;
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.ConsoleAppender;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Logger;
import org.apache.log4j.SimpleLayout;

/**
 * A very simple forking proxy server.
 * 
 * @author M. Ranganathan
 * 
 */
public class Proxy extends TestCase implements SipListener {

	
	
	
	//private ServerTransaction st;
	
	private SipProvider inviteServerTxProvider;

	private Hashtable clientTxTable = new Hashtable();

	private static String transport = "udp";
	
	private static String host = "127.0.0.1";
	
	private int port = 5070;

	private SipProvider sipProvider;
	
	private static String unexpectedException = "Unexpected exception";
	
	private static Logger logger = Logger.getLogger(Proxy.class);
	
	static {
		try {
			logger.addAppender(new FileAppender(new SimpleLayout(),
					ProtocolObjects.logFileDirectory + "proxlog.txt"));
		} catch (Exception ex) {
			throw new RuntimeException("could not open shootistconsolelog.txt");
		}
	}

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

				ListeningPoint lp = sipProvider.getListeningPoint(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();
				SipURI sipUri = ProtocolObjects.addressFactory.createSipURI("UA1", "127.0.0.1");
				sipUri.setPort(5080);
				sipUri.setLrParam();
				Address address = ProtocolObjects.addressFactory.createAddress("client1",
						sipUri);
				RouteHeader rheader = ProtocolObjects.headerFactory.createRouteHeader(address);
				
				newRequest.addFirst(rheader);
				ViaHeader viaHeader = ProtocolObjects.headerFactory.createViaHeader(host, port,
						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(5070);
				sipUri.setLrParam();
				RecordRouteHeader recordRoute = ProtocolObjects.headerFactory.createRecordRouteHeader(address);
				newRequest.addHeader(recordRoute);
				ct1.setApplicationData(st);
				this.clientTxTable.put(new Integer(5080), ct1);

				newRequest = (Request) request.clone();
				sipUri = ProtocolObjects.addressFactory.createSipURI("UA2", "127.0.0.1");
				sipUri.setLrParam();
				sipUri.setPort(5090);
				address = ProtocolObjects.addressFactory.createAddress("client2", sipUri);
				rheader = ProtocolObjects.headerFactory.createRouteHeader(address);
				newRequest.addFirst(rheader);
				viaHeader = ProtocolObjects.headerFactory.createViaHeader(host, port,
						transport, null);
				newRequest.addFirst(viaHeader);
				sipUri = ProtocolObjects.addressFactory.createSipURI("proxy", "127.0.0.1");
				sipUri.setPort(5070);
				sipUri.setLrParam();
				sipUri.setTransportParam(transport);
				address = ProtocolObjects.addressFactory.createAddress("proxy",sipUri);
				
				recordRoute = ProtocolObjects.headerFactory.createRecordRouteHeader(address);
				
				newRequest.addHeader(recordRoute);
				ClientTransaction ct2 = sipProvider
						.getNewClientTransaction(newRequest);
				ct2.setApplicationData(st);
				this.clientTxTable.put(new Integer(5090), ct2);
				
				// Send the requests out to the two listening points of the client.
				
				ct2.sendRequest();
				ct1.sendRequest();
				
			} else {
				// Remove the topmost route header
				// The route header will make sure it gets to the right place.
				logger.info("proxy: Got a request " + request.getMethod());
				Request newRequest = (Request) request.clone();
				newRequest.removeFirst(RouteHeader.NAME);
				sipProvider.sendRequest(newRequest);
			
			}  

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

	}

	public void processResponse(ResponseEvent responseEvent) {
		try {
			Response response = responseEvent.getResponse();
			CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
			logger.info("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;
			
			
			if (cseq.getMethod().equals(Request.INVITE)) {
				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.
					
					st.sendResponse(newResponse);
				} 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
					this.inviteServerTxProvider.sendResponse(newResponse);
				}
			} else {
				// Can be BYE due to Record-Route
				logger.info("Got a non-invite response " + response);
				SipProvider p = (SipProvider) responseEvent.getSource();
				response.removeFirst( ViaHeader.NAME );
				p.sendResponse( response );
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			System.exit(0);
		}
	}

	public void processTimeout(TimeoutEvent timeoutEvent) {
		logger.info("Timeout occured");
	}

	public void processIOException(IOExceptionEvent exceptionEvent) {
		logger.info("IOException occured");
	}
	public SipProvider createSipProvider() {
		try {
			ListeningPoint listeningPoint = ProtocolObjects.sipStack.createListeningPoint(
					host, port, transport);

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

	}
	
	public void processTransactionTerminated(
			TransactionTerminatedEvent transactionTerminatedEvent) {
		logger.info("Transaction terminated event occured -- cleaning up");
		if (!transactionTerminatedEvent.isServerTransaction()) {
			ClientTransaction ct = transactionTerminatedEvent
					.getClientTransaction();
			for (Iterator it = this.clientTxTable.values().iterator(); it
					.hasNext();) {
				if (it.next().equals(ct)) {
					it.remove();
				}
			}
		} else {
			logger.info("Server tx terminated! ");
		}
	}

	public void processDialogTerminated(
			DialogTerminatedEvent dialogTerminatedEvent) {
		logger.info("HUH!! why do i see this event??");
	}

	
	public static void main(String[] args) throws Exception {
		logger.addAppender(new ConsoleAppender(new SimpleLayout()));
		ProtocolObjects.init("proxy",false);
		Proxy proxy = new Proxy();
		proxy.createSipProvider();
		proxy.sipProvider.addSipListener(proxy);
		

	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy