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