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();
junit.framework.TestCase.fail("Exit JVM");
}
}
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();
junit.framework.TestCase.fail("Exit JVM");
}
}
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);
}
}