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