001: package test.unit.gov.nist.javax.sip.stack;
002:
003: import java.text.ParseException;
004: import java.util.ArrayList;
005: import java.util.Properties;
006: import java.util.Timer;
007: import java.util.TimerTask;
008:
009: import javax.sip.ClientTransaction;
010: import javax.sip.Dialog;
011: import javax.sip.DialogState;
012: import javax.sip.DialogTerminatedEvent;
013: import javax.sip.IOExceptionEvent;
014: import javax.sip.InvalidArgumentException;
015: import javax.sip.ListeningPoint;
016: import javax.sip.PeerUnavailableException;
017: import javax.sip.RequestEvent;
018: import javax.sip.ResponseEvent;
019: import javax.sip.ServerTransaction;
020: import javax.sip.SipException;
021: import javax.sip.SipFactory;
022: import javax.sip.SipListener;
023: import javax.sip.SipProvider;
024: import javax.sip.SipStack;
025: import javax.sip.Transaction;
026: import javax.sip.TransactionState;
027: import javax.sip.TransactionTerminatedEvent;
028: import javax.sip.address.Address;
029: import javax.sip.address.AddressFactory;
030: import javax.sip.address.SipURI;
031: import javax.sip.header.CSeqHeader;
032: import javax.sip.header.CallIdHeader;
033: import javax.sip.header.ContactHeader;
034: import javax.sip.header.ContentTypeHeader;
035: import javax.sip.header.FromHeader;
036: import javax.sip.header.Header;
037: import javax.sip.header.HeaderFactory;
038: import javax.sip.header.MaxForwardsHeader;
039: import javax.sip.header.ToHeader;
040: import javax.sip.header.ViaHeader;
041: import javax.sip.message.MessageFactory;
042: import javax.sip.message.Request;
043: import javax.sip.message.Response;
044:
045: import junit.framework.TestCase;
046:
047: public class RejectInvalidResponseTest extends TestCase {
048:
049: public class Shootme implements SipListener {
050:
051: private AddressFactory addressFactory;
052:
053: private MessageFactory messageFactory;
054:
055: private HeaderFactory headerFactory;
056:
057: private SipStack sipStack;
058:
059: private static final String myAddress = "127.0.0.1";
060:
061: private static final int myPort = 5070;
062:
063: private Dialog dialog;
064:
065: public static final boolean callerSendsBye = true;
066:
067: public void processRequest(RequestEvent requestEvent) {
068: Request request = requestEvent.getRequest();
069: ServerTransaction serverTransactionId = requestEvent
070: .getServerTransaction();
071:
072: System.out.println("\n\nRequest " + request.getMethod()
073: + " received at " + sipStack.getStackName()
074: + " with server transaction id "
075: + serverTransactionId);
076:
077: if (request.getMethod().equals(Request.INVITE)) {
078: processInvite(requestEvent, serverTransactionId);
079: }
080:
081: }
082:
083: public void processResponse(ResponseEvent responseEvent) {
084: }
085:
086: /**
087: * Process the ACK request. Send the bye and complete the call flow.
088: */
089: public void processAck(RequestEvent requestEvent,
090: ServerTransaction serverTransaction) {
091: try {
092: System.out.println("shootme: got an ACK! ");
093: System.out.println("Dialog State = "
094: + dialog.getState());
095: SipProvider provider = (SipProvider) requestEvent
096: .getSource();
097: if (!callerSendsBye) {
098: Request byeRequest = dialog
099: .createRequest(Request.BYE);
100: ClientTransaction ct = provider
101: .getNewClientTransaction(byeRequest);
102: dialog.sendRequest(ct);
103: }
104: } catch (Exception ex) {
105: ex.printStackTrace();
106: }
107:
108: }
109:
110: /**
111: * Process the invite request.
112: */
113: public void processInvite(RequestEvent requestEvent,
114: ServerTransaction serverTransaction) {
115: SipProvider sipProvider = (SipProvider) requestEvent
116: .getSource();
117: Request request = requestEvent.getRequest();
118: try {
119:
120: Response okResponse = messageFactory.createResponse(
121: Response.OK, request);
122: FromHeader from = (FromHeader) okResponse
123: .getHeader(FromHeader.NAME);
124: from.removeParameter("tag");
125: Address address = addressFactory
126: .createAddress("Shootme <sip:" + myAddress
127: + ":" + myPort + ">");
128: ContactHeader contactHeader = headerFactory
129: .createContactHeader(address);
130: ToHeader toHeader = (ToHeader) okResponse
131: .getHeader(ToHeader.NAME);
132: toHeader.setTag("4321"); // Application is supposed to set.
133: okResponse.addHeader(contactHeader);
134: sipProvider.sendResponse(okResponse); // Send it through the Provider.
135:
136: } catch (Exception ex) {
137: ex.printStackTrace();
138: System.exit(0);
139: }
140: }
141:
142: public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) {
143: Transaction transaction;
144: if (timeoutEvent.isServerTransaction()) {
145: transaction = timeoutEvent.getServerTransaction();
146: } else {
147: transaction = timeoutEvent.getClientTransaction();
148: }
149: System.out.println("state = " + transaction.getState());
150: System.out.println("dialog = " + transaction.getDialog());
151: System.out.println("dialogState = "
152: + transaction.getDialog().getState());
153: System.out.println("Transaction Time out");
154: }
155:
156: public void init() {
157: SipFactory sipFactory = null;
158: sipStack = null;
159: sipFactory = SipFactory.getInstance();
160: sipFactory.setPathName("gov.nist");
161: Properties properties = new Properties();
162: properties.setProperty("javax.sip.STACK_NAME", "shootme");
163: // You need 16 for logging traces. 32 for debug + traces.
164: // Your code will limp at 32 but it is best for debugging.
165: properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL",
166: "32");
167: properties.setProperty("gov.nist.javax.sip.DEBUG_LOG",
168: "shootmedebug.txt");
169: properties.setProperty("gov.nist.javax.sip.SERVER_LOG",
170: "shootmelog.txt");
171:
172: try {
173: // Create SipStack object
174: sipStack = sipFactory.createSipStack(properties);
175: System.out.println("sipStack = " + sipStack);
176: } catch (PeerUnavailableException e) {
177: // could not find
178: // gov.nist.jain.protocol.ip.sip.SipStackImpl
179: // in the classpath
180: e.printStackTrace();
181: System.err.println(e.getMessage());
182: if (e.getCause() != null)
183: e.getCause().printStackTrace();
184: System.exit(0);
185: }
186:
187: try {
188: headerFactory = sipFactory.createHeaderFactory();
189: addressFactory = sipFactory.createAddressFactory();
190: messageFactory = sipFactory.createMessageFactory();
191: ListeningPoint lp = sipStack.createListeningPoint(
192: "127.0.0.1", myPort, "udp");
193:
194: Shootme listener = this ;
195:
196: SipProvider sipProvider = sipStack
197: .createSipProvider(lp);
198: System.out.println("udp provider " + sipProvider);
199: sipProvider.addSipListener(listener);
200:
201: } catch (Exception ex) {
202: ex.printStackTrace();
203: fail("Unexpected exception");
204: }
205:
206: }
207:
208: public void processIOException(IOExceptionEvent exceptionEvent) {
209: fail("IOException");
210:
211: }
212:
213: public void processTransactionTerminated(
214: TransactionTerminatedEvent transactionTerminatedEvent) {
215: if (transactionTerminatedEvent.isServerTransaction())
216: System.out
217: .println("Transaction terminated event recieved"
218: + transactionTerminatedEvent
219: .getServerTransaction());
220: else
221: System.out.println("Transaction terminated "
222: + transactionTerminatedEvent
223: .getClientTransaction());
224:
225: }
226:
227: public void processDialogTerminated(
228: DialogTerminatedEvent dialogTerminatedEvent) {
229: Dialog d = dialogTerminatedEvent.getDialog();
230: System.out.println("Local Party = " + d.getLocalParty());
231:
232: }
233:
234: public void terminate() {
235: this .sipStack.stop();
236: }
237:
238: }
239:
240: public class Shootist implements SipListener {
241:
242: private SipProvider sipProvider;
243:
244: private AddressFactory addressFactory;
245:
246: private MessageFactory messageFactory;
247:
248: private HeaderFactory headerFactory;
249:
250: private SipStack sipStack;
251:
252: private ContactHeader contactHeader;
253:
254: private ListeningPoint udpListeningPoint;
255:
256: private Dialog dialog;
257:
258: private boolean timeoutRecieved;
259:
260: public void processRequest(RequestEvent requestReceivedEvent) {
261: fail("Unexpected request recieved");
262:
263: }
264:
265: public void processResponse(ResponseEvent responseReceivedEvent) {
266: if (responseReceivedEvent.getResponse().getStatusCode() == Response.OK)
267: fail("Unexpected event -- response is supposed to be dropped ! ");
268:
269: }
270:
271: public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) {
272:
273: System.out.println("Got a timeout "
274: + timeoutEvent.getClientTransaction());
275:
276: this .timeoutRecieved = true;
277: }
278:
279: public void init() {
280: SipFactory sipFactory = null;
281: sipStack = null;
282: sipFactory = SipFactory.getInstance();
283: sipFactory.setPathName("gov.nist");
284: Properties properties = new Properties();
285: // If you want to try TCP transport change the following to
286: String transport = "udp";
287: String peerHostPort = "127.0.0.1:5070";
288: properties.setProperty("javax.sip.OUTBOUND_PROXY",
289: peerHostPort + "/" + transport);
290: // If you want to use UDP then uncomment this.
291: properties.setProperty("javax.sip.STACK_NAME", "shootist");
292:
293: // The following properties are specific to nist-sip
294: // and are not necessarily part of any other jain-sip
295: // implementation.
296: // You can set a max message size for tcp transport to
297: // guard against denial of service attack.
298: properties.setProperty("gov.nist.javax.sip.DEBUG_LOG",
299: "shootistdebug.txt");
300: properties.setProperty("gov.nist.javax.sip.SERVER_LOG",
301: "shootistlog.txt");
302:
303: // Drop the client connection after we are done with the transaction.
304: properties.setProperty(
305: "gov.nist.javax.sip.CACHE_CLIENT_CONNECTIONS",
306: "false");
307: // Set to 0 (or NONE) in your production code for max speed.
308: // You need 16 (or TRACE) for logging traces. 32 (or DEBUG) for debug + traces.
309: // Your code will limp at 32 but it is best for debugging.
310: properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL",
311: "DEBUG");
312:
313: try {
314: // Create SipStack object
315: sipStack = sipFactory.createSipStack(properties);
316: System.out.println("createSipStack " + sipStack);
317: } catch (PeerUnavailableException e) {
318: // could not find
319: // gov.nist.jain.protocol.ip.sip.SipStackImpl
320: // in the classpath
321: e.printStackTrace();
322: System.err.println(e.getMessage());
323: fail("Problem with setup");
324: }
325:
326: try {
327: headerFactory = sipFactory.createHeaderFactory();
328: addressFactory = sipFactory.createAddressFactory();
329: messageFactory = sipFactory.createMessageFactory();
330: udpListeningPoint = sipStack.createListeningPoint(
331: "127.0.0.1", 5060, "udp");
332: sipProvider = sipStack
333: .createSipProvider(udpListeningPoint);
334: Shootist listener = this ;
335: sipProvider.addSipListener(listener);
336:
337: String fromName = "BigGuy";
338: String fromSipAddress = "here.com";
339: String fromDisplayName = "The Master Blaster";
340:
341: String toSipAddress = "there.com";
342: String toUser = "LittleGuy";
343: String toDisplayName = "The Little Blister";
344:
345: // create >From Header
346: SipURI fromAddress = addressFactory.createSipURI(
347: fromName, fromSipAddress);
348:
349: Address fromNameAddress = addressFactory
350: .createAddress(fromAddress);
351: fromNameAddress.setDisplayName(fromDisplayName);
352: FromHeader fromHeader = headerFactory.createFromHeader(
353: fromNameAddress, "12345");
354:
355: // create To Header
356: SipURI toAddress = addressFactory.createSipURI(toUser,
357: toSipAddress);
358: Address toNameAddress = addressFactory
359: .createAddress(toAddress);
360: toNameAddress.setDisplayName(toDisplayName);
361: ToHeader toHeader = headerFactory.createToHeader(
362: toNameAddress, null);
363:
364: // create Request URI
365: SipURI requestURI = addressFactory.createSipURI(toUser,
366: peerHostPort);
367:
368: // Create ViaHeaders
369:
370: ArrayList viaHeaders = new ArrayList();
371: String ipAddress = udpListeningPoint.getIPAddress();
372: ViaHeader viaHeader = headerFactory.createViaHeader(
373: ipAddress, sipProvider.getListeningPoint(
374: transport).getPort(), transport, null);
375:
376: // add via headers
377: viaHeaders.add(viaHeader);
378:
379: // Create ContentTypeHeader
380: ContentTypeHeader contentTypeHeader = headerFactory
381: .createContentTypeHeader("application", "sdp");
382:
383: // Create a new CallId header
384: CallIdHeader callIdHeader = sipProvider.getNewCallId();
385:
386: // Create a new Cseq header
387: CSeqHeader cSeqHeader = headerFactory.createCSeqHeader(
388: 1L, Request.INVITE);
389:
390: // Create a new MaxForwardsHeader
391: MaxForwardsHeader maxForwards = headerFactory
392: .createMaxForwardsHeader(70);
393:
394: // Create the request.
395: Request request = messageFactory.createRequest(
396: requestURI, Request.INVITE, callIdHeader,
397: cSeqHeader, fromHeader, toHeader, viaHeaders,
398: maxForwards);
399: // Create contact headers
400: String host = "127.0.0.1";
401:
402: SipURI contactUrl = addressFactory.createSipURI(
403: fromName, host);
404: contactUrl.setPort(udpListeningPoint.getPort());
405: contactUrl.setLrParam();
406:
407: // Create the contact name address.
408: SipURI contactURI = addressFactory.createSipURI(
409: fromName, host);
410: contactURI.setPort(sipProvider.getListeningPoint(
411: transport).getPort());
412:
413: Address contactAddress = addressFactory
414: .createAddress(contactURI);
415:
416: // Add the contact address.
417: contactAddress.setDisplayName(fromName);
418:
419: contactHeader = headerFactory
420: .createContactHeader(contactAddress);
421: request.addHeader(contactHeader);
422:
423: // You can add extension headers of your own making
424: // to the outgoing SIP request.
425: // Add the extension header.
426: Header extensionHeader = headerFactory.createHeader(
427: "My-Header", "my header value");
428: request.addHeader(extensionHeader);
429:
430: String sdpData = "v=0\r\n"
431: + "o=4855 13760799956958020 13760799956958020"
432: + " IN IP4 129.6.55.78\r\n"
433: + "s=mysession session\r\n"
434: + "p=+46 8 52018010\r\n"
435: + "c=IN IP4 129.6.55.78\r\n" + "t=0 0\r\n"
436: + "m=audio 6022 RTP/AVP 0 4 18\r\n"
437: + "a=rtpmap:0 PCMU/8000\r\n"
438: + "a=rtpmap:4 G723/8000\r\n"
439: + "a=rtpmap:18 G729A/8000\r\n"
440: + "a=ptime:20\r\n";
441: byte[] contents = sdpData.getBytes();
442:
443: request.setContent(contents, contentTypeHeader);
444: // You can add as many extension headers as you
445: // want.
446:
447: extensionHeader = headerFactory.createHeader(
448: "My-Other-Header", "my new header value ");
449: request.addHeader(extensionHeader);
450:
451: Header callInfoHeader = headerFactory.createHeader(
452: "Call-Info", "<http://www.antd.nist.gov>");
453: request.addHeader(callInfoHeader);
454:
455: // Create the client transaction.
456: ClientTransaction inviteTid = sipProvider
457: .getNewClientTransaction(request);
458:
459: // send the request out.
460: inviteTid.sendRequest();
461:
462: dialog = inviteTid.getDialog();
463:
464: } catch (Exception ex) {
465: fail("cannot create or send initial invite");
466: }
467: }
468:
469: public void processIOException(IOExceptionEvent exceptionEvent) {
470: System.out.println("IOException happened for "
471: + exceptionEvent.getHost() + " port = "
472: + exceptionEvent.getPort());
473:
474: }
475:
476: public void processTransactionTerminated(
477: TransactionTerminatedEvent transactionTerminatedEvent) {
478: System.out.println("Transaction terminated event recieved");
479: }
480:
481: public void processDialogTerminated(
482: DialogTerminatedEvent dialogTerminatedEvent) {
483: System.out.println("dialogTerminatedEvent");
484:
485: }
486:
487: public void terminate() {
488: this .sipStack.stop();
489: }
490: }
491:
492: private test.unit.gov.nist.javax.sip.stack.RejectInvalidResponseTest.Shootme shootme;
493: private test.unit.gov.nist.javax.sip.stack.RejectInvalidResponseTest.Shootist shootist;
494:
495: public void setUp() {
496: this .shootme = new Shootme();
497: this .shootist = new Shootist();
498:
499: }
500:
501: public void tearDown() {
502: shootist.terminate();
503: shootme.terminate();
504: }
505:
506: public void testRejectInvalidResponse() {
507: this .shootme.init();
508: this .shootist.init();
509: try {
510: Thread.sleep(40000);
511: } catch (Exception ex) {
512:
513: }
514: assertTrue(
515: "Should get timeout for client transaction even if branch id matches for response ",
516: shootist.timeoutRecieved);
517: }
518:
519: }
|