001: package examples.forked.invite;
002:
003: import gov.nist.javax.sip.address.SipUri;
004:
005: import java.util.HashSet;
006: import java.util.Hashtable;
007: import java.util.Iterator;
008: import java.util.Properties;
009:
010: import javax.sip.ClientTransaction;
011: import javax.sip.DialogTerminatedEvent;
012: import javax.sip.IOExceptionEvent;
013: import javax.sip.ListeningPoint;
014: import javax.sip.RequestEvent;
015: import javax.sip.ResponseEvent;
016: import javax.sip.ServerTransaction;
017: import javax.sip.SipFactory;
018: import javax.sip.SipListener;
019: import javax.sip.SipProvider;
020: import javax.sip.SipStack;
021: import javax.sip.TimeoutEvent;
022: import javax.sip.TransactionTerminatedEvent;
023: import javax.sip.address.Address;
024: import javax.sip.address.AddressFactory;
025: import javax.sip.address.SipURI;
026: import javax.sip.header.CSeqHeader;
027: import javax.sip.header.HeaderFactory;
028: import javax.sip.header.RecordRouteHeader;
029: import javax.sip.header.RouteHeader;
030: import javax.sip.header.ToHeader;
031: import javax.sip.header.ViaHeader;
032: import javax.sip.message.MessageFactory;
033: import javax.sip.message.Request;
034: import javax.sip.message.Response;
035:
036: import junit.framework.TestCase;
037:
038: import org.apache.log4j.ConsoleAppender;
039: import org.apache.log4j.FileAppender;
040: import org.apache.log4j.Logger;
041: import org.apache.log4j.SimpleLayout;
042:
043: /**
044: * A very simple forking proxy server.
045: *
046: * @author M. Ranganathan
047: *
048: */
049: public class Proxy extends TestCase implements SipListener {
050:
051: //private ServerTransaction st;
052:
053: private SipProvider inviteServerTxProvider;
054:
055: private Hashtable clientTxTable = new Hashtable();
056:
057: private static String transport = "udp";
058:
059: private static String host = "127.0.0.1";
060:
061: private int port = 5070;
062:
063: private SipProvider sipProvider;
064:
065: private static String unexpectedException = "Unexpected exception";
066:
067: private static Logger logger = Logger.getLogger(Proxy.class);
068:
069: static {
070: try {
071: logger.addAppender(new FileAppender(new SimpleLayout(),
072: ProtocolObjects.logFileDirectory + "proxlog.txt"));
073: } catch (Exception ex) {
074: throw new RuntimeException(
075: "could not open shootistconsolelog.txt");
076: }
077: }
078:
079: public void processRequest(RequestEvent requestEvent) {
080: try {
081: Request request = requestEvent.getRequest();
082: SipProvider sipProvider = (SipProvider) requestEvent
083: .getSource();
084: this .inviteServerTxProvider = sipProvider;
085: if (request.getMethod().equals(Request.INVITE)) {
086:
087: ListeningPoint lp = sipProvider
088: .getListeningPoint(transport);
089: String host = lp.getIPAddress();
090: int port = lp.getPort();
091:
092: ServerTransaction st = null;
093: if (requestEvent.getServerTransaction() == null) {
094: st = sipProvider.getNewServerTransaction(request);
095:
096: }
097: Request newRequest = (Request) request.clone();
098: SipURI sipUri = ProtocolObjects.addressFactory
099: .createSipURI("UA1", "127.0.0.1");
100: sipUri.setPort(5080);
101: sipUri.setLrParam();
102: Address address = ProtocolObjects.addressFactory
103: .createAddress("client1", sipUri);
104: RouteHeader rheader = ProtocolObjects.headerFactory
105: .createRouteHeader(address);
106:
107: newRequest.addFirst(rheader);
108: ViaHeader viaHeader = ProtocolObjects.headerFactory
109: .createViaHeader(host, port, transport, null);
110: newRequest.addFirst(viaHeader);
111: ClientTransaction ct1 = sipProvider
112: .getNewClientTransaction(newRequest);
113: sipUri = ProtocolObjects.addressFactory.createSipURI(
114: "proxy", "127.0.0.1");
115: address = ProtocolObjects.addressFactory.createAddress(
116: "proxy", sipUri);
117: sipUri.setPort(5070);
118: sipUri.setLrParam();
119: RecordRouteHeader recordRoute = ProtocolObjects.headerFactory
120: .createRecordRouteHeader(address);
121: newRequest.addHeader(recordRoute);
122: ct1.setApplicationData(st);
123: this .clientTxTable.put(new Integer(5080), ct1);
124:
125: newRequest = (Request) request.clone();
126: sipUri = ProtocolObjects.addressFactory.createSipURI(
127: "UA2", "127.0.0.1");
128: sipUri.setLrParam();
129: sipUri.setPort(5090);
130: address = ProtocolObjects.addressFactory.createAddress(
131: "client2", sipUri);
132: rheader = ProtocolObjects.headerFactory
133: .createRouteHeader(address);
134: newRequest.addFirst(rheader);
135: viaHeader = ProtocolObjects.headerFactory
136: .createViaHeader(host, port, transport, null);
137: newRequest.addFirst(viaHeader);
138: sipUri = ProtocolObjects.addressFactory.createSipURI(
139: "proxy", "127.0.0.1");
140: sipUri.setPort(5070);
141: sipUri.setLrParam();
142: sipUri.setTransportParam(transport);
143: address = ProtocolObjects.addressFactory.createAddress(
144: "proxy", sipUri);
145:
146: recordRoute = ProtocolObjects.headerFactory
147: .createRecordRouteHeader(address);
148:
149: newRequest.addHeader(recordRoute);
150: ClientTransaction ct2 = sipProvider
151: .getNewClientTransaction(newRequest);
152: ct2.setApplicationData(st);
153: this .clientTxTable.put(new Integer(5090), ct2);
154:
155: // Send the requests out to the two listening points of the client.
156:
157: ct2.sendRequest();
158: ct1.sendRequest();
159:
160: } else {
161: // Remove the topmost route header
162: // The route header will make sure it gets to the right place.
163: logger.info("proxy: Got a request "
164: + request.getMethod());
165: Request newRequest = (Request) request.clone();
166: newRequest.removeFirst(RouteHeader.NAME);
167: sipProvider.sendRequest(newRequest);
168:
169: }
170:
171: } catch (Exception ex) {
172: ex.printStackTrace();
173: System.exit(0);
174: }
175:
176: }
177:
178: public void processResponse(ResponseEvent responseEvent) {
179: try {
180: Response response = responseEvent.getResponse();
181: CSeqHeader cseq = (CSeqHeader) response
182: .getHeader(CSeqHeader.NAME);
183: logger.info("ClientTxID = "
184: + responseEvent.getClientTransaction()
185: + " client tx id "
186: + ((ViaHeader) response.getHeader(ViaHeader.NAME))
187: .getBranch() + " CSeq header = "
188: + response.getHeader(CSeqHeader.NAME)
189: + " status code = " + response.getStatusCode());
190:
191: // JvB: stateful proxy MUST NOT forward 100 Trying
192: if (response.getStatusCode() == 100)
193: return;
194:
195: if (cseq.getMethod().equals(Request.INVITE)) {
196: ClientTransaction ct = responseEvent
197: .getClientTransaction();
198: if (ct != null) {
199: ServerTransaction st = (ServerTransaction) ct
200: .getApplicationData();
201:
202: // Strip the topmost via header
203: Response newResponse = (Response) response.clone();
204: newResponse.removeFirst(ViaHeader.NAME);
205: // The server tx goes to the terminated state.
206:
207: st.sendResponse(newResponse);
208: } else {
209: // Client tx has already terminated but the UA is retransmitting
210: // just forward the response statelessly.
211: // Strip the topmost via header
212:
213: Response newResponse = (Response) response.clone();
214: newResponse.removeFirst(ViaHeader.NAME);
215: // Send the retransmission statelessly
216: this .inviteServerTxProvider
217: .sendResponse(newResponse);
218: }
219: } else {
220: // Can be BYE due to Record-Route
221: logger.info("Got a non-invite response " + response);
222: SipProvider p = (SipProvider) responseEvent.getSource();
223: response.removeFirst(ViaHeader.NAME);
224: p.sendResponse(response);
225: }
226: } catch (Exception ex) {
227: ex.printStackTrace();
228: System.exit(0);
229: }
230: }
231:
232: public void processTimeout(TimeoutEvent timeoutEvent) {
233: logger.info("Timeout occured");
234: }
235:
236: public void processIOException(IOExceptionEvent exceptionEvent) {
237: logger.info("IOException occured");
238: }
239:
240: public SipProvider createSipProvider() {
241: try {
242: ListeningPoint listeningPoint = ProtocolObjects.sipStack
243: .createListeningPoint(host, port, transport);
244:
245: sipProvider = ProtocolObjects.sipStack
246: .createSipProvider(listeningPoint);
247: return sipProvider;
248: } catch (Exception ex) {
249: logger.error(unexpectedException, ex);
250: fail(unexpectedException);
251: return null;
252: }
253:
254: }
255:
256: public void processTransactionTerminated(
257: TransactionTerminatedEvent transactionTerminatedEvent) {
258: logger
259: .info("Transaction terminated event occured -- cleaning up");
260: if (!transactionTerminatedEvent.isServerTransaction()) {
261: ClientTransaction ct = transactionTerminatedEvent
262: .getClientTransaction();
263: for (Iterator it = this .clientTxTable.values().iterator(); it
264: .hasNext();) {
265: if (it.next().equals(ct)) {
266: it.remove();
267: }
268: }
269: } else {
270: logger.info("Server tx terminated! ");
271: }
272: }
273:
274: public void processDialogTerminated(
275: DialogTerminatedEvent dialogTerminatedEvent) {
276: logger.info("HUH!! why do i see this event??");
277: }
278:
279: public static void main(String[] args) throws Exception {
280: logger.addAppender(new ConsoleAppender(new SimpleLayout()));
281: ProtocolObjects.init("proxy", false);
282: Proxy proxy = new Proxy();
283: proxy.createSipProvider();
284: proxy.sipProvider.addSipListener(proxy);
285:
286: }
287:
288: }
|