001: package examples.tls;
002:
003: import javax.sip.*;
004: import javax.sip.address.*;
005: import javax.sip.header.*;
006: import javax.sip.message.*;
007: import java.util.*;
008:
009: /**
010: * This class is a UAC template. Shootist is the guy that shoots and shootme
011: * is the guy that gets shot.
012: *
013: *@author Daniel Martinez
014: */
015:
016: public class Shootme implements SipListener {
017:
018: private static AddressFactory addressFactory;
019: private static MessageFactory messageFactory;
020: private static HeaderFactory headerFactory;
021: private static SipStack sipStack;
022: private static final String myAddress = "127.0.0.1";
023: private static final int myPort = 5071;
024:
025: protected ServerTransaction inviteTid;
026:
027: Dialog dialog;
028:
029: class ApplicationData {
030: protected int ackCount;
031: }
032:
033: protected static final String usageString = "java "
034: + "examples.shootistTLS.Shootist \n"
035: + ">>>> is your class path set to the root?";
036:
037: private static void usage() {
038: System.out.println(usageString);
039: System.exit(0);
040:
041: }
042:
043: public void processRequest(RequestEvent requestEvent) {
044: Request request = requestEvent.getRequest();
045: ServerTransaction serverTransactionId = requestEvent
046: .getServerTransaction();
047:
048: System.out.println("\n\nRequest " + request.getMethod()
049: + " received at " + sipStack.getStackName()
050: + " with server transaction id " + serverTransactionId);
051:
052: if (request.getMethod().equals(Request.INVITE)) {
053: processInvite(requestEvent, serverTransactionId);
054: } else if (request.getMethod().equals(Request.ACK)) {
055: processAck(requestEvent, serverTransactionId);
056: } else if (request.getMethod().equals(Request.BYE)) {
057: processBye(requestEvent, serverTransactionId);
058: }
059:
060: }
061:
062: /** Process the ACK request. Send the bye and complete the call flow.
063: */
064: public void processAck(RequestEvent requestEvent,
065: ServerTransaction serverTransaction) {
066: SipProvider sipProvider = (SipProvider) requestEvent
067: .getSource();
068: try {
069: System.out.println("shootme: got an ACK "
070: + requestEvent.getRequest());
071: int ackCount = ((ApplicationData) dialog
072: .getApplicationData()).ackCount;
073: if (ackCount == 1) {
074: dialog = inviteTid.getDialog();
075: Request byeRequest = dialog.createRequest(Request.BYE);
076: ClientTransaction tr = sipProvider
077: .getNewClientTransaction(byeRequest);
078: System.out
079: .println("shootme: got an ACK -- sending bye! ");
080: dialog.sendRequest(tr);
081: System.out.println("Dialog State = "
082: + dialog.getState());
083: } else
084: ((ApplicationData) dialog.getApplicationData()).ackCount++;
085: } catch (Exception ex) {
086: ex.printStackTrace();
087: System.exit(0);
088: }
089: }
090:
091: /** Process the invite request.
092: */
093: public void processInvite(RequestEvent requestEvent,
094: ServerTransaction serverTransaction) {
095: SipProvider sipProvider = (SipProvider) requestEvent
096: .getSource();
097: Request request = requestEvent.getRequest();
098: System.out.println("Got an INVITE " + request);
099: try {
100: System.out.println("shootme: got an Invite sending OK");
101: //System.out.println("shootme: " + request);
102: Response response = messageFactory.createResponse(180,
103: request);
104: ToHeader toHeader = (ToHeader) response
105: .getHeader(ToHeader.NAME);
106: toHeader.setTag("4321"); // Application is supposed to set.
107: Address address = addressFactory
108: .createAddress("Shootme <sip:" + myAddress + ":"
109: + myPort + ">"
110: /*+ ";transport=tls>"*/);
111: ContactHeader contactHeader = headerFactory
112: .createContactHeader(address);
113:
114: response.addHeader(contactHeader);
115: ServerTransaction st = requestEvent.getServerTransaction();
116:
117: if (st == null) {
118: st = sipProvider.getNewServerTransaction(request);
119: if (st.getDialog().getApplicationData() == null) {
120: st.getDialog().setApplicationData(
121: new ApplicationData());
122: }
123: } else {
124: System.out.println("This is a RE INVITE ");
125: if (st.getDialog() != dialog) {
126: System.out.println("Whoopsa Daisy Dialog Mismatch");
127: System.exit(0);
128: }
129: }
130:
131: // Thread.sleep(5000);
132: System.out.println("got a server tranasaction " + st);
133: byte[] content = request.getRawContent();
134: if (content != null) {
135: ContentTypeHeader contentTypeHeader = headerFactory
136: .createContentTypeHeader("application", "sdp");
137: System.out.println("response = " + response);
138: response.setContent(content, contentTypeHeader);
139: }
140: dialog = st.getDialog();
141: if (dialog != null) {
142: System.out.println("Dialog " + dialog);
143: System.out.println("Dialog state " + dialog.getState());
144: }
145: st.sendResponse(response);
146: response = messageFactory.createResponse(200, request);
147: toHeader = (ToHeader) response.getHeader(ToHeader.NAME);
148: toHeader.setTag("4321"); // Application is supposed to set.
149: response.addHeader(contactHeader);
150: st.sendResponse(response);
151: this .inviteTid = st;
152: } catch (Exception ex) {
153: ex.printStackTrace();
154: System.exit(0);
155: }
156: }
157:
158: /** Process the bye request.
159: */
160: public void processBye(RequestEvent requestEvent,
161: ServerTransaction serverTransactionId) {
162: // SipProvider sipProvider = (SipProvider) requestEvent.getSource();
163: Request request = requestEvent.getRequest();
164: try {
165: System.out.println("shootme: got a bye sending OK.");
166: Response response = messageFactory.createResponse(200,
167: request, null, null);
168: serverTransactionId.sendResponse(response);
169: System.out.println("Dialog State is "
170: + serverTransactionId.getDialog().getState());
171:
172: } catch (Exception ex) {
173: ex.printStackTrace();
174: System.exit(0);
175:
176: }
177: }
178:
179: public void processResponse(ResponseEvent responseReceivedEvent) {
180: System.out.println("Got a response");
181: Response response = (Response) responseReceivedEvent
182: .getResponse();
183: Transaction tid = responseReceivedEvent.getClientTransaction();
184:
185: System.out
186: .println("Response received with client transaction id "
187: + tid + ":\n" + response);
188: try {
189: if (response.getStatusCode() == Response.OK
190: && ((CSeqHeader) response
191: .getHeader(CSeqHeader.NAME)).getMethod()
192: .equals(Request.INVITE)) {
193: if (tid != this .inviteTid) {
194: new Exception().printStackTrace();
195: System.exit(0);
196: }
197: Dialog dialog = tid.getDialog();
198: // Save the tags for the dialog here.
199: Request request = tid.getRequest();
200: dialog.sendAck(request);
201: }
202: Dialog dialog = tid.getDialog();
203: System.out.println("Dalog State = " + dialog.getState());
204: } catch (Exception ex) {
205: ex.printStackTrace();
206: System.exit(0);
207: }
208:
209: }
210:
211: public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) {
212: Transaction transaction;
213: if (timeoutEvent.isServerTransaction()) {
214: transaction = timeoutEvent.getServerTransaction();
215: } else {
216: transaction = timeoutEvent.getClientTransaction();
217: }
218: System.out.println("state = " + transaction.getState());
219: System.out.println("dialog = " + transaction.getDialog());
220: System.out.println("dialogState = "
221: + transaction.getDialog().getState());
222: System.out.println("Transaction Time out");
223: }
224:
225: public void init() {
226: SipFactory sipFactory = null;
227: sipStack = null;
228: sipFactory = SipFactory.getInstance();
229: sipFactory.setPathName("gov.nist");
230: Properties properties = new Properties();
231: //ifdef SIMULATION
232: /*
233: properties.setProperty("javax.sip.IP_ADDRESS","129.6.55.62");
234: //else
235: */
236: properties.setProperty("javax.sip.IP_ADDRESS", myAddress);
237: //endif
238: //
239: properties.setProperty("javax.sip.RETRANSMISSION_FILTER",
240: "true");
241: properties.setProperty("javax.sip.STACK_NAME", "shootme");
242: // You need 16 for logging traces. 32 for debug + traces.
243: // Your code will limp at 32 but it is best for debugging.
244: properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "16");
245: properties.setProperty("gov.nist.javax.sip.DEBUG_LOG",
246: "shootmedebug.txt");
247: properties.setProperty("gov.nist.javax.sip.SERVER_LOG",
248: "shootmelog.txt");
249: // Guard against starvation.
250: properties.setProperty("gov.nist.javax.sip.READ_TIMEOUT",
251: "1000");
252: // properties.setProperty("gov.nist.javax.sip.MAX_MESSAGE_SIZE", "4096");
253: properties.setProperty(
254: "gov.nist.javax.sip.CACHE_SERVER_CONNECTIONS", "false");
255:
256: try {
257: // Create SipStack object
258: sipStack = sipFactory.createSipStack(properties);
259: System.out.println("sipStack = " + sipStack);
260: } catch (PeerUnavailableException e) {
261: // could not find
262: // gov.nist.jain.protocol.ip.sip.SipStackImpl
263: // in the classpath
264: e.printStackTrace();
265: System.err.println(e.getMessage());
266: if (e.getCause() != null)
267: e.getCause().printStackTrace();
268: System.exit(0);
269: }
270:
271: try {
272: headerFactory = sipFactory.createHeaderFactory();
273: addressFactory = sipFactory.createAddressFactory();
274: messageFactory = sipFactory.createMessageFactory();
275: ListeningPoint lpTLS = sipStack.createListeningPoint(
276: sipStack.getIPAddress(), myPort, "tcp");
277:
278: Shootme listener = this ;
279:
280: SipProvider sipProvider = sipStack.createSipProvider(lpTLS);
281: System.out.println("tls provider " + sipProvider);
282: sipProvider.addSipListener(listener);
283:
284: } catch (Exception ex) {
285: System.out.println(ex.getMessage());
286: ex.printStackTrace();
287: usage();
288: }
289:
290: }
291:
292: public static void main(String args[]) {
293: new Shootme().init();
294: }
295:
296: public void processIOException(IOExceptionEvent exceptionEvent) {
297: System.out
298: .println("IOException occured while retransmitting requests:"
299: + exceptionEvent);
300: }
301:
302: public void processTransactionTerminated(
303: TransactionTerminatedEvent transactionTerminatedEvent) {
304: System.out.println("Transaction Terminated event: "
305: + transactionTerminatedEvent);
306: }
307:
308: public void processDialogTerminated(
309: DialogTerminatedEvent dialogTerminatedEvent) {
310: System.out.println("Dialog Terminated event: "
311: + dialogTerminatedEvent);
312: }
313:
314: }
315: /*
316: * $Log: Shootme.java,v $
317: * Revision 1.7 2008/01/24 21:20:44 jbemmel
318: * call createAck instead of createRequest(ACK)
319: *
320: * Revision 1.6 2007/02/12 19:45:45 jbemmel
321: * use sips
322: *
323: * Revision 1.5 2006/12/13 15:15:28 mranga
324: * Issue number: 90
325: * Obtained from:
326: * Submitted by: Zohair
327: * Reviewed by: mranga
328: *
329: * Fixed transport = tls in the example.
330: * CVS: ----------------------------------------------------------------------
331: * CVS: Issue number:
332: * CVS: If this change addresses one or more issues,
333: * CVS: then enter the issue number(s) here.
334: * CVS: Obtained from:
335: * CVS: If this change has been taken from another system,
336: * CVS: then name the system in this line, otherwise delete it.
337: * CVS: Submitted by:
338: * CVS: If this code has been contributed to the project by someone else; i.e.,
339: * CVS: they sent us a patch or a set of diffs, then include their name/email
340: * CVS: address here. If this is your work then delete this line.
341: * CVS: Reviewed by:
342: * CVS: If we are doing pre-commit code reviews and someone else has
343: * CVS: reviewed your changes, include their name(s) here.
344: * CVS: If you have not had it reviewed then delete this line.
345: *
346: * Revision 1.4 2006/07/13 09:02:54 mranga
347: * Issue number:
348: * Obtained from:
349: * Submitted by: jeroen van bemmel
350: * Reviewed by: mranga
351: * Moved some changes from jain-sip-1.2 to java.net
352: *
353: * CVS: ----------------------------------------------------------------------
354: * CVS: Issue number:
355: * CVS: If this change addresses one or more issues,
356: * CVS: then enter the issue number(s) here.
357: * CVS: Obtained from:
358: * CVS: If this change has been taken from another system,
359: * CVS: then name the system in this line, otherwise delete it.
360: * CVS: Submitted by:
361: * CVS: If this code has been contributed to the project by someone else; i.e.,
362: * CVS: they sent us a patch or a set of diffs, then include their name/email
363: * CVS: address here. If this is your work then delete this line.
364: * CVS: Reviewed by:
365: * CVS: If we are doing pre-commit code reviews and someone else has
366: * CVS: reviewed your changes, include their name(s) here.
367: * CVS: If you have not had it reviewed then delete this line.
368: *
369: * Revision 1.2 2006/01/16 21:36:07 ivelin
370: * cleaned up usage of deprecated APIs, fixed some script paths and stale imports
371: *
372: * Revision 1.1.1.1 2005/10/04 17:12:33 mranga
373: *
374: * Import
375: *
376: *
377: * Revision 1.1 2004/11/24 21:00:38 mranga
378: *
379: * Added
380: *
381: * Revision 1.20 2004/09/26 14:48:01 mranga
382: * Submitted by: John Martin
383: * Reviewed by: mranga
384: *
385: * Remove unnecssary synchronization.
386: *
387: * Revision 1.19 2004/06/16 02:53:17 mranga
388: * Submitted by: mranga
389: * Reviewed by: implement re-entrant multithreaded listener model.
390: *
391: * Revision 1.18 2004/06/15 09:54:39 mranga
392: * Reviewed by: mranga
393: * re-entrant listener model added.
394: * (see configuration property gov.nist.javax.sip.REENTRANT_LISTENER)
395: *
396: * Revision 1.17 2004/05/16 14:13:20 mranga
397: * Reviewed by: mranga
398: * Fixed the use-count issue reported by Peter Parnes.
399: * Added property to prevent against content-length dos attacks.
400: *
401: * Revision 1.16 2004/04/07 13:46:30 mranga
402: * Reviewed by: mranga
403: * move processing of delayed responses outside the synchronized block.
404: *
405: * Revision 1.15 2004/04/07 00:19:22 mranga
406: * Reviewed by: mranga
407: * Fixes a potential race condition for client transactions.
408: * Handle re-invites statefully within an established dialog.
409: *
410: * Revision 1.14 2004/03/30 18:10:53 mranga
411: * Reviewed by: mranga
412: * added code to demonstrate cleanup
413: *
414: * Revision 1.13 2004/03/12 21:53:08 mranga
415: * Reviewed by: mranga
416: * moved some comments around for ifdef support.
417: *
418: * Revision 1.12 2004/03/07 22:25:22 mranga
419: * Reviewed by: mranga
420: * Added a new configuration parameter that instructs the stack to
421: * drop a server connection after server transaction termination
422: * set gov.nist.javax.sip.CACHE_SERVER_CONNECTIONS=false for this
423: * Default behavior is true.
424: *
425: * Revision 1.11 2004/03/05 20:36:54 mranga
426: * Reviewed by: mranga
427: * put in some debug printfs and cleaned some things up.
428: *
429: * Revision 1.10 2004/02/26 14:28:50 mranga
430: * Reviewed by: mranga
431: * Moved some code around (no functional change) so that dialog state is set
432: * when the transaction is added to the dialog.
433: * Cleaned up the Shootist example a bit.
434: *
435: * Revision 1.9 2004/02/13 13:55:31 mranga
436: * Reviewed by: mranga
437: * per the spec, Transactions must always have a valid dialog pointer. Assigned a dummy dialog for transactions that are not assigned to any dialog (such as Message).
438: *
439: * Revision 1.8 2004/01/22 13:26:27 sverker
440: * Issue number:
441: * Obtained from:
442: * Submitted by: sverker
443: * Reviewed by: mranga
444: *
445: * Major reformat of code to conform with style guide. Resolved compiler and javadoc warnings. Added CVS tags.
446: *
447: * CVS: ----------------------------------------------------------------------
448: * CVS: Issue number:
449: * CVS: If this change addresses one or more issues,
450: * CVS: then enter the issue number(s) here.
451: * CVS: Obtained from:
452: * CVS: If this change has been taken from another system,
453: * CVS: then name the system in this line, otherwise delete it.
454: * CVS: Submitted by:
455: * CVS: If this code has been contributed to the project by someone else; i.e.,
456: * CVS: they sent us a patch or a set of diffs, then include their name/email
457: * CVS: address here. If this is your work then delete this line.
458: * CVS: Reviewed by:
459: * CVS: If we are doing pre-commit code reviews and someone else has
460: * CVS: reviewed your changes, include their name(s) here.
461: * CVS: If you have not had it reviewed then delete this line.
462: *
463: */
|