001: package test.unit.gov.nist.javax.sip.stack;
002:
003: import junit.framework.TestCase;
004:
005: import javax.sip.*;
006: import javax.sip.address.*;
007: import javax.sip.header.*;
008: import javax.sip.message.*;
009:
010: import org.apache.log4j.ConsoleAppender;
011: import org.apache.log4j.Logger;
012: import org.apache.log4j.SimpleLayout;
013:
014: import java.text.ParseException;
015: import java.util.*;
016:
017: import junit.framework.TestCase;
018:
019: public class SetRetransmissionTimerTest extends TestCase {
020: public static final boolean callerSendsBye = true;
021:
022: private static Logger logger = Logger
023: .getLogger(ServerTransactionRetransmissionTimerTest.class);
024: static {
025: if (!logger.getAllAppenders().hasMoreElements())
026: logger.addAppender(new ConsoleAppender(new SimpleLayout()));
027: }
028:
029: class Shootist implements SipListener {
030:
031: private SipProvider sipProvider;
032:
033: private AddressFactory addressFactory;
034:
035: private MessageFactory messageFactory;
036:
037: private HeaderFactory headerFactory;
038:
039: private SipStack sipStack;
040:
041: private ContactHeader contactHeader;
042:
043: private ListeningPoint udpListeningPoint;
044:
045: private ClientTransaction inviteTid;
046:
047: private Dialog dialog;
048:
049: private long startTime = System.currentTimeMillis();
050:
051: private boolean byeTaskRunning;
052:
053: class ByeTask extends TimerTask {
054: Dialog dialog;
055:
056: public ByeTask(Dialog dialog) {
057: this .dialog = dialog;
058: }
059:
060: public void run() {
061: try {
062: Request byeRequest = this .dialog
063: .createRequest(Request.BYE);
064: ClientTransaction ct = sipProvider
065: .getNewClientTransaction(byeRequest);
066: logger.info("15s are over: sending BYE now");
067: dialog.sendRequest(ct);
068: } catch (Exception ex) {
069: ex.printStackTrace();
070: System.exit(0);
071: }
072:
073: }
074:
075: }
076:
077: private static final String usageString = "java "
078: + "examples.shootist.Shootist \n"
079: + ">>>> is your class path set to the root?";
080:
081: public void processRequest(RequestEvent requestReceivedEvent) {
082: Request request = requestReceivedEvent.getRequest();
083: ServerTransaction serverTransactionId = requestReceivedEvent
084: .getServerTransaction();
085:
086: logger.info("\n\nRequest " + request.getMethod()
087: + " received at " + sipStack.getStackName()
088: + " with server transaction id "
089: + serverTransactionId);
090:
091: // We are the UAC so the only request we get is the BYE.
092: if (request.getMethod().equals(Request.BYE))
093: processBye(request, serverTransactionId);
094: else {
095: try {
096: serverTransactionId.sendResponse(messageFactory
097: .createResponse(202, request));
098: } catch (Exception e) {
099: fail("Unexpected exception");
100: logger.error("Unexpected exception", e);
101: }
102: }
103:
104: }
105:
106: public void processBye(Request request,
107: ServerTransaction serverTransactionId) {
108: try {
109: logger.info("shootist: got a bye .");
110: if (serverTransactionId == null) {
111: logger.info("shootist: null TID.");
112: return;
113: }
114: Dialog dialog = serverTransactionId.getDialog();
115: logger.info("Dialog State = " + dialog.getState());
116: Response response = messageFactory.createResponse(200,
117: request);
118: serverTransactionId.sendResponse(response);
119: logger.info("shootist: Sending OK.");
120: logger.info("Dialog State = " + dialog.getState());
121:
122: } catch (Exception ex) {
123: ex.printStackTrace();
124: System.exit(0);
125:
126: }
127: }
128:
129: // Save the created ACK request, to respond to retransmitted 2xx
130: private Request ackRequest;
131:
132: public void processResponse(ResponseEvent responseReceivedEvent) {
133: logger.info(System.currentTimeMillis() - startTime
134: + "ms: Got a response");
135: Response response = (Response) responseReceivedEvent
136: .getResponse();
137: ClientTransaction tid = responseReceivedEvent
138: .getClientTransaction();
139: CSeqHeader cseq = (CSeqHeader) response
140: .getHeader(CSeqHeader.NAME);
141:
142: logger.info("Response received : Status Code = "
143: + response.getStatusCode() + " " + cseq);
144:
145: if (tid == null) {
146:
147: // RFC3261: MUST respond to every 2xx
148: if (ackRequest != null && dialog != null) {
149: logger.info("re-sending ACK");
150: try {
151: dialog.sendAck(ackRequest);
152: } catch (SipException se) {
153: se.printStackTrace();
154: }
155: }
156: return;
157: }
158: // If the caller is supposed to send the bye
159: if (callerSendsBye && !byeTaskRunning) {
160: byeTaskRunning = true;
161: new Timer().schedule(new ByeTask(dialog), 30000);
162: }
163: logger.info("transaction state is " + tid.getState());
164: logger.info("Dialog = " + tid.getDialog());
165: logger
166: .info("Dialog State is "
167: + tid.getDialog().getState());
168:
169: try {
170: if (response.getStatusCode() == Response.OK) {
171: if (cseq.getMethod().equals(Request.INVITE)) {
172: logger.info("Sending ACK after 15s ...");
173: new Timer().schedule(new AckTimerTask(dialog,
174: cseq.getSeqNumber()), 15000);
175: } else if (cseq.getMethod().equals(Request.CANCEL)) {
176: if (dialog.getState() == DialogState.CONFIRMED) {
177: // oops cancel went in too late. Need to hang up the
178: // dialog.
179: System.out
180: .println("Sending BYE -- cancel went in too late !!");
181: Request byeRequest = dialog
182: .createRequest(Request.BYE);
183: ClientTransaction ct = sipProvider
184: .getNewClientTransaction(byeRequest);
185: dialog.sendRequest(ct);
186:
187: }
188:
189: }
190: }
191: } catch (Exception ex) {
192: logger.error("Unexpected exception", ex);
193: fail("Unexpected exception");
194:
195: }
196:
197: }
198:
199: class AckTimerTask extends TimerTask {
200: Dialog dialog;
201: private final long cseq;
202:
203: public AckTimerTask(Dialog dialog, long cseq) {
204: this .dialog = dialog;
205: this .cseq = cseq;
206: }
207:
208: public void run() {
209: logger.info("15s are over: now sending ACK");
210: try {
211: Request ackRequest = dialog.createAck(cseq);
212: dialog.sendAck(ackRequest);
213: } catch (Exception e) {
214: logger.error("Unexpected exception", e);
215: fail("Unexpected exception");
216: }
217: }
218: }
219:
220: // ***************************************************************** END
221:
222: public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) {
223:
224: logger.info("Transaction Time out");
225: fail("Unexpected exception -- ");
226: }
227:
228: public void init() {
229: SipFactory sipFactory = null;
230: sipStack = null;
231: sipFactory = SipFactory.getInstance();
232: sipFactory.setPathName("gov.nist");
233: Properties properties = new Properties();
234: // If you want to try TCP transport change the following to
235: String transport = "udp";
236: String peerHostPort = "127.0.0.1:5070";
237: properties.setProperty("javax.sip.OUTBOUND_PROXY",
238: peerHostPort + "/" + transport);
239: // If you want to use UDP then uncomment this.
240: properties.setProperty("javax.sip.STACK_NAME", "shootist");
241:
242: // The following properties are specific to nist-sip
243: // and are not necessarily part of any other jain-sip
244: // implementation.
245: // You can set a max message size for tcp transport to
246: // guard against denial of service attack.
247: properties.setProperty("gov.nist.javax.sip.DEBUG_LOG",
248: "logs/shootistdebug.txt");
249: properties.setProperty("gov.nist.javax.sip.SERVER_LOG",
250: "logs/shootistlog.txt");
251:
252: // Drop the client connection after we are done with the
253: // transaction.
254: properties.setProperty(
255: "gov.nist.javax.sip.CACHE_CLIENT_CONNECTIONS",
256: "false");
257: // Set to 0 (or NONE) in your production code for max speed.
258: // You need 16 (or TRACE) for logging traces. 32 (or DEBUG) for
259: // debug + traces.
260: // Your code will limp at 32 but it is best for debugging.
261: properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL",
262: "0");
263:
264: try {
265: // Create SipStack object
266: sipStack = sipFactory.createSipStack(properties);
267: logger.info("createSipStack " + sipStack);
268: } catch (PeerUnavailableException e) {
269: // could not find
270: // gov.nist.jain.protocol.ip.sip.SipStackImpl
271: // in the classpath
272: e.printStackTrace();
273: System.err.println(e.getMessage());
274: System.exit(0);
275: }
276:
277: try {
278: headerFactory = sipFactory.createHeaderFactory();
279: addressFactory = sipFactory.createAddressFactory();
280: messageFactory = sipFactory.createMessageFactory();
281: udpListeningPoint = sipStack.createListeningPoint(
282: "127.0.0.1", 5060, "udp");
283: sipProvider = sipStack
284: .createSipProvider(udpListeningPoint);
285: Shootist listener = this ;
286: sipProvider.addSipListener(listener);
287:
288: String fromName = "BigGuy";
289: String fromSipAddress = "here.com";
290: String fromDisplayName = "The Master Blaster";
291:
292: String toSipAddress = "there.com";
293: String toUser = "LittleGuy";
294: String toDisplayName = "The Little Blister";
295:
296: // create >From Header
297: SipURI fromAddress = addressFactory.createSipURI(
298: fromName, fromSipAddress);
299:
300: Address fromNameAddress = addressFactory
301: .createAddress(fromAddress);
302: fromNameAddress.setDisplayName(fromDisplayName);
303: FromHeader fromHeader = headerFactory.createFromHeader(
304: fromNameAddress, "12345");
305:
306: // create To Header
307: SipURI toAddress = addressFactory.createSipURI(toUser,
308: toSipAddress);
309: Address toNameAddress = addressFactory
310: .createAddress(toAddress);
311: toNameAddress.setDisplayName(toDisplayName);
312: ToHeader toHeader = headerFactory.createToHeader(
313: toNameAddress, null);
314:
315: // create Request URI
316: SipURI requestURI = addressFactory.createSipURI(toUser,
317: peerHostPort);
318:
319: // Create ViaHeaders
320:
321: ArrayList viaHeaders = new ArrayList();
322: String ipAddress = udpListeningPoint.getIPAddress();
323: ViaHeader viaHeader = headerFactory.createViaHeader(
324: ipAddress, sipProvider.getListeningPoint(
325: transport).getPort(), transport, null);
326:
327: // add via headers
328: viaHeaders.add(viaHeader);
329:
330: // Create ContentTypeHeader
331: ContentTypeHeader contentTypeHeader = headerFactory
332: .createContentTypeHeader("application", "sdp");
333:
334: // Create a new CallId header
335: CallIdHeader callIdHeader = sipProvider.getNewCallId();
336:
337: // Create a new Cseq header
338: CSeqHeader cSeqHeader = headerFactory.createCSeqHeader(
339: 1L, Request.INVITE);
340:
341: // Create a new MaxForwardsHeader
342: MaxForwardsHeader maxForwards = headerFactory
343: .createMaxForwardsHeader(70);
344:
345: // Create the request.
346: Request request = messageFactory.createRequest(
347: requestURI, Request.INVITE, callIdHeader,
348: cSeqHeader, fromHeader, toHeader, viaHeaders,
349: maxForwards);
350: // Create contact headers
351: String host = "127.0.0.1";
352:
353: SipURI contactUrl = addressFactory.createSipURI(
354: fromName, host);
355: contactUrl.setPort(udpListeningPoint.getPort());
356: contactUrl.setLrParam();
357:
358: // Create the contact name address.
359: SipURI contactURI = addressFactory.createSipURI(
360: fromName, host);
361: contactURI.setPort(sipProvider.getListeningPoint(
362: transport).getPort());
363:
364: Address contactAddress = addressFactory
365: .createAddress(contactURI);
366:
367: // Add the contact address.
368: contactAddress.setDisplayName(fromName);
369:
370: contactHeader = headerFactory
371: .createContactHeader(contactAddress);
372: request.addHeader(contactHeader);
373:
374: // You can add extension headers of your own making
375: // to the outgoing SIP request.
376: // Add the extension header.
377: Header extensionHeader = headerFactory.createHeader(
378: "My-Header", "my header value");
379: request.addHeader(extensionHeader);
380:
381: String sdpData = "v=0\r\n"
382: + "o=4855 13760799956958020 13760799956958020"
383: + " IN IP4 129.6.55.78\r\n"
384: + "s=mysession session\r\n"
385: + "p=+46 8 52018010\r\n"
386: + "c=IN IP4 129.6.55.78\r\n" + "t=0 0\r\n"
387: + "m=audio 6022 RTP/AVP 0 4 18\r\n"
388: + "a=rtpmap:0 PCMU/8000\r\n"
389: + "a=rtpmap:4 G723/8000\r\n"
390: + "a=rtpmap:18 G729A/8000\r\n"
391: + "a=ptime:20\r\n";
392: byte[] contents = sdpData.getBytes();
393:
394: request.setContent(contents, contentTypeHeader);
395: // You can add as many extension headers as you
396: // want.
397:
398: extensionHeader = headerFactory.createHeader(
399: "My-Other-Header", "my new header value ");
400: request.addHeader(extensionHeader);
401:
402: Header callInfoHeader = headerFactory.createHeader(
403: "Call-Info", "<http://www.antd.nist.gov>");
404: request.addHeader(callInfoHeader);
405:
406: // Create the client transaction.
407: inviteTid = sipProvider
408: .getNewClientTransaction(request);
409: inviteTid.setRetransmitTimer(100);
410:
411: // send the request out.
412: inviteTid.sendRequest();
413:
414: dialog = inviteTid.getDialog();
415:
416: } catch (Exception ex) {
417: logger.error("Unexpected exception", ex);
418: fail("Unexpected exception ");
419: }
420: }
421:
422: public void processIOException(IOExceptionEvent exceptionEvent) {
423: logger.error("IOException happened for "
424: + exceptionEvent.getHost() + " port = "
425: + exceptionEvent.getPort());
426:
427: }
428:
429: public void processTransactionTerminated(
430: TransactionTerminatedEvent transactionTerminatedEvent) {
431: if (transactionTerminatedEvent.getServerTransaction() != null)
432: logger
433: .info("Shootist: Transaction terminated event recieved on transaction : "
434: + transactionTerminatedEvent
435: .getServerTransaction());
436: else
437: logger
438: .info("Shootist : Transaction terminated event recieved on transaction : "
439: + transactionTerminatedEvent
440: .getClientTransaction());
441: }
442:
443: public void processDialogTerminated(
444: DialogTerminatedEvent dialogTerminatedEvent) {
445: logger.info("dialogTerminatedEvent");
446:
447: }
448:
449: public void terminate() {
450: sipStack.stop();
451: }
452: }
453:
454: public class Shootme implements SipListener {
455:
456: private AddressFactory addressFactory;
457:
458: private MessageFactory messageFactory;
459:
460: private HeaderFactory headerFactory;
461:
462: private SipStack sipStack;
463:
464: private static final String myAddress = "127.0.0.1";
465:
466: private static final int myPort = 5070;
467:
468: protected ServerTransaction inviteTid;
469:
470: private Response okResponse;
471:
472: private Request inviteRequest;
473:
474: private Dialog dialog;
475:
476: class MyTimerTask extends TimerTask {
477: Shootme shootme;
478:
479: public MyTimerTask(Shootme shootme) {
480: this .shootme = shootme;
481:
482: }
483:
484: public void run() {
485: shootme.sendInviteOK();
486: }
487:
488: }
489:
490: protected static final String usageString = "java "
491: + "examples.shootist.Shootist \n"
492: + ">>>> is your class path set to the root?";
493:
494: public void processRequest(RequestEvent requestEvent) {
495: Request request = requestEvent.getRequest();
496: ServerTransaction serverTransactionId = requestEvent
497: .getServerTransaction();
498:
499: logger.info("\n\nRequest " + request.getMethod()
500: + " received at " + sipStack.getStackName()
501: + " with server transaction id "
502: + serverTransactionId);
503:
504: if (request.getMethod().equals(Request.INVITE)) {
505: processInvite(requestEvent, serverTransactionId);
506: } else if (request.getMethod().equals(Request.ACK)) {
507: processAck(requestEvent, serverTransactionId);
508: } else if (request.getMethod().equals(Request.BYE)) {
509: processBye(requestEvent, serverTransactionId);
510: } else if (request.getMethod().equals(Request.CANCEL)) {
511: processCancel(requestEvent, serverTransactionId);
512: }
513:
514: }
515:
516: public void processResponse(ResponseEvent responseEvent) {
517: fail("Unexpected event");
518: }
519:
520: /**
521: * Process the ACK request. Send the bye and complete the call flow.
522: */
523: public void processAck(RequestEvent requestEvent,
524: ServerTransaction serverTransaction) {
525: try {
526: logger.info("shootme: got an ACK! ");
527: logger.info("Dialog State = " + dialog.getState());
528: SipProvider provider = (SipProvider) requestEvent
529: .getSource();
530: if (!callerSendsBye) {
531: Request byeRequest = dialog
532: .createRequest(Request.BYE);
533: ClientTransaction ct = provider
534: .getNewClientTransaction(byeRequest);
535: dialog.sendRequest(ct);
536: }
537: } catch (Exception ex) {
538: logger.error("Unexpected exception", ex);
539: fail("unexpected exception");
540: }
541:
542: }
543:
544: /**
545: * Process the invite request.
546: */
547: public void processInvite(RequestEvent requestEvent,
548: ServerTransaction serverTransaction) {
549: SipProvider sipProvider = (SipProvider) requestEvent
550: .getSource();
551: Request request = requestEvent.getRequest();
552: try {
553: logger.info("shootme: got an Invite sending Trying");
554: // logger.info("shootme: " + request);
555: Response response = messageFactory.createResponse(
556: Response.TRYING, request);
557: ServerTransaction st = requestEvent
558: .getServerTransaction();
559:
560: if (st == null) {
561: st = sipProvider.getNewServerTransaction(request);
562: st.setRetransmitTimer(100);
563: }
564: dialog = st.getDialog();
565:
566: st.sendResponse(response);
567:
568: this .okResponse = messageFactory.createResponse(
569: Response.OK, request);
570: Address address = addressFactory
571: .createAddress("Shootme <sip:" + myAddress
572: + ":" + myPort + ">");
573: ContactHeader contactHeader = headerFactory
574: .createContactHeader(address);
575: response.addHeader(contactHeader);
576: ToHeader toHeader = (ToHeader) okResponse
577: .getHeader(ToHeader.NAME);
578: toHeader.setTag("4321"); // Application is supposed to set.
579: okResponse.addHeader(contactHeader);
580: this .inviteTid = st;
581: // Defer sending the OK to simulate the phone ringing.
582: // Answered in 1 second ( this guy is fast at taking calls)
583: this .inviteRequest = request;
584:
585: new Timer().schedule(new MyTimerTask(this ), 1000);
586: } catch (Exception ex) {
587: ex.printStackTrace();
588: logger.error("Unexpected exception");
589: fail("Unexpected exception");
590: }
591: }
592:
593: private void sendInviteOK() {
594: try {
595: if (inviteTid.getState() != TransactionState.COMPLETED) {
596: logger.info("shootme: Dialog state before 200: "
597: + inviteTid.getDialog().getState());
598: inviteTid.sendResponse(okResponse);
599: logger.info("shootme: Dialog state after 200: "
600: + inviteTid.getDialog().getState());
601: }
602: } catch (Exception ex) {
603: logger.error("Unexpected exception", ex);
604: fail("Unexpected exception");
605: }
606: }
607:
608: /**
609: * Process the bye request.
610: */
611: public void processBye(RequestEvent requestEvent,
612: ServerTransaction serverTransactionId) {
613: SipProvider sipProvider = (SipProvider) requestEvent
614: .getSource();
615: Request request = requestEvent.getRequest();
616: Dialog dialog = requestEvent.getDialog();
617: logger.info("shootme: local party = "
618: + dialog.getLocalParty());
619: try {
620: logger.info("shootme: got a bye sending OK.");
621: Response response = messageFactory.createResponse(200,
622: request);
623: serverTransactionId.sendResponse(response);
624: logger.info("shootme: Dialog State is "
625: + serverTransactionId.getDialog().getState());
626:
627: } catch (Exception ex) {
628: logger.error("UNexpected exception", ex);
629: fail("UNexpected exception");
630:
631: }
632: }
633:
634: public void processCancel(RequestEvent requestEvent,
635: ServerTransaction serverTransactionId) {
636: SipProvider sipProvider = (SipProvider) requestEvent
637: .getSource();
638: Request request = requestEvent.getRequest();
639: try {
640: logger.info("shootme: got a cancel.");
641: if (serverTransactionId == null) {
642: logger.info("shootme: null tid.");
643: return;
644: }
645: Response response = messageFactory.createResponse(200,
646: request);
647: serverTransactionId.sendResponse(response);
648: if (dialog.getState() != DialogState.CONFIRMED) {
649: response = messageFactory.createResponse(
650: Response.REQUEST_TERMINATED, inviteRequest);
651: inviteTid.sendResponse(response);
652: }
653:
654: } catch (Exception ex) {
655: ex.printStackTrace();
656: System.exit(0);
657:
658: }
659: }
660:
661: public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) {
662: Transaction transaction;
663: if (timeoutEvent.isServerTransaction()) {
664: transaction = timeoutEvent.getServerTransaction();
665: } else {
666: transaction = timeoutEvent.getClientTransaction();
667: }
668: logger.info("Shootme: Transaction Time out : "
669: + transaction);
670: }
671:
672: public void init() {
673: SipFactory sipFactory = null;
674: sipStack = null;
675: sipFactory = SipFactory.getInstance();
676: sipFactory.setPathName("gov.nist");
677: Properties properties = new Properties();
678: properties.setProperty("javax.sip.STACK_NAME", "shootme");
679: // You need 16 for logging traces. 32 for debug + traces.
680: // Your code will limp at 32 but it is best for debugging.
681: properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL",
682: "0");
683: properties.setProperty("gov.nist.javax.sip.DEBUG_LOG",
684: "shootmedebug.txt");
685: properties.setProperty("gov.nist.javax.sip.SERVER_LOG",
686: "shootmelog.txt");
687:
688: try {
689: // Create SipStack object
690: sipStack = sipFactory.createSipStack(properties);
691: logger.info("sipStack = " + sipStack);
692: } catch (PeerUnavailableException e) {
693: // could not find
694: // gov.nist.jain.protocol.ip.sip.SipStackImpl
695: // in the classpath
696: e.printStackTrace();
697: System.err.println(e.getMessage());
698: if (e.getCause() != null)
699: e.getCause().printStackTrace();
700: logger.error("Unexpected error creating stack", e);
701: fail("Unexpected error");
702: }
703:
704: try {
705: headerFactory = sipFactory.createHeaderFactory();
706: addressFactory = sipFactory.createAddressFactory();
707: messageFactory = sipFactory.createMessageFactory();
708: ListeningPoint lp = sipStack.createListeningPoint(
709: "127.0.0.1", myPort, "udp");
710:
711: Shootme listener = this ;
712:
713: SipProvider sipProvider = sipStack
714: .createSipProvider(lp);
715: logger.info("udp provider " + sipProvider);
716: sipProvider.addSipListener(listener);
717:
718: } catch (Exception ex) {
719: fail("Unexpected exception");
720: }
721:
722: }
723:
724: public void terminate() {
725: this .sipStack.stop();
726: }
727:
728: public void processIOException(IOExceptionEvent exceptionEvent) {
729: logger.info("IOException");
730:
731: }
732:
733: public void processTransactionTerminated(
734: TransactionTerminatedEvent transactionTerminatedEvent) {
735: if (transactionTerminatedEvent.isServerTransaction())
736: logger.info("Transaction terminated event recieved"
737: + transactionTerminatedEvent
738: .getServerTransaction());
739: else
740: logger.info("Transaction terminated "
741: + transactionTerminatedEvent
742: .getClientTransaction());
743:
744: }
745:
746: public void processDialogTerminated(
747: DialogTerminatedEvent dialogTerminatedEvent) {
748: logger.info("Shootme: Dialog terminated event recieved");
749: Dialog d = dialogTerminatedEvent.getDialog();
750: logger.info("Local Party = " + d.getLocalParty());
751:
752: }
753:
754: }
755:
756: private Shootist shootist;
757: private Shootme shootme;
758:
759: public void setUp() {
760: this .shootme = new Shootme();
761: this .shootist = new Shootist();
762:
763: }
764:
765: public void tearDown() {
766: shootist.terminate();
767: shootme.terminate();
768: }
769:
770: public void testRetransmit() {
771: this .shootme.init();
772: this .shootist.init();
773: try {
774: Thread.sleep(60000);
775: } catch (Exception ex) {
776:
777: }
778: }
779:
780: }
|