001: /*
002: * Conditions Of Use
003: *
004: * This software was developed by employees of the National Institute of
005: * Standards and Technology (NIST), and others.
006: * This software is has been contributed to the public domain.
007: * As a result, a formal license is not needed to use the software.
008: *
009: * This software is provided "AS IS."
010: * NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
011: * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
012: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
013: * AND DATA ACCURACY. NIST does not warrant or make any representations
014: * regarding the use of the software or the results thereof, including but
015: * not limited to the correctness, accuracy, reliability or usefulness of
016: * the software.
017: *
018: *
019: */
020: /**
021: *
022: */package test.unit.gov.nist.javax.sip.stack;
023:
024: import java.util.ArrayList;
025: import java.util.EventObject;
026:
027: import javax.sip.ClientTransaction;
028: import javax.sip.Dialog;
029: import javax.sip.DialogTerminatedEvent;
030: import javax.sip.IOExceptionEvent;
031: import javax.sip.ListeningPoint;
032: import javax.sip.RequestEvent;
033: import javax.sip.ResponseEvent;
034: import javax.sip.ServerTransaction;
035: import javax.sip.SipListener;
036: import javax.sip.SipProvider;
037: import javax.sip.TimeoutEvent;
038: import javax.sip.Transaction;
039: import javax.sip.TransactionTerminatedEvent;
040: import javax.sip.address.Address;
041: import javax.sip.address.SipURI;
042: import javax.sip.header.CSeqHeader;
043: import javax.sip.header.CallIdHeader;
044: import javax.sip.header.ContactHeader;
045: import javax.sip.header.ContentTypeHeader;
046: import javax.sip.header.FromHeader;
047: import javax.sip.header.Header;
048: import javax.sip.header.MaxForwardsHeader;
049: import javax.sip.header.RouteHeader;
050: import javax.sip.header.ToHeader;
051: import javax.sip.header.ViaHeader;
052: import javax.sip.message.Request;
053: import javax.sip.message.Response;
054:
055: import org.apache.log4j.ConsoleAppender;
056: import org.apache.log4j.Logger;
057: import org.apache.log4j.SimpleLayout;
058: import org.apache.log4j.helpers.NullEnumeration;
059:
060: import test.tck.msgflow.callflows.ProtocolObjects;
061: import test.tck.msgflow.callflows.ScenarioHarness;
062:
063: /**
064: *
065: */
066: public class AckReTransmissionTest extends ScenarioHarness implements
067: SipListener {
068:
069: protected Shootist shootist;
070:
071: private Shootme shootme;
072:
073: private static Logger logger = Logger.getLogger("test.tck");
074:
075: static {
076: if (!logger.isAttached(console))
077: logger.addAppender(console);
078: }
079:
080: class Shootme implements SipListener {
081:
082: private ProtocolObjects protocolObjects;
083:
084: // To run on two machines change these to suit.
085: public static final String myAddress = "127.0.0.1";
086:
087: public static final int myPort = 5070;
088:
089: private ServerTransaction inviteTid;
090:
091: private Dialog dialog;
092:
093: private ServerTransaction reSendSt = null;
094: private Response reSendResponse = null;
095: private int dropAckCount = 0;
096:
097: public Shootme(ProtocolObjects protocolObjects) {
098: this .protocolObjects = protocolObjects;
099: }
100:
101: public void processRequest(RequestEvent requestEvent) {
102: Request request = requestEvent.getRequest();
103: ServerTransaction serverTransactionId = requestEvent
104: .getServerTransaction();
105:
106: logger.info("\n\nRequest " + request.getMethod()
107: + " received at "
108: + protocolObjects.sipStack.getStackName()
109: + " with server transaction id "
110: + serverTransactionId);
111:
112: if (request.getMethod().equals(Request.INVITE)) {
113: processInvite(requestEvent, serverTransactionId);
114: } else if (request.getMethod().equals(Request.ACK)) {
115: processAck(requestEvent, serverTransactionId);
116: }
117:
118: }
119:
120: /**
121: * Process the ACK request. Send the bye and complete the call flow.
122: */
123: public void processAck(RequestEvent requestEvent,
124: ServerTransaction serverTransaction) {
125: logger.info("shootme: got an ACK "
126: + requestEvent.getRequest());
127: if (dropAckCount <= 3) {
128: boolean skip = false;
129: //drop the ACK, resend 200 OK
130: try {
131: reSendSt.sendResponse(reSendResponse);
132: logger.info("shootme: resending the previous 200");
133: } catch (Exception ex) {
134: String s = "Unexpected error";
135: logger.error(s, ex);
136: AckReTransmissionTest.fail(s);
137: skip = true;
138: }
139: if (!skip) {
140: dropAckCount++;
141: return;
142: }
143: }
144: SipProvider sipProvider = (SipProvider) requestEvent
145: .getSource();
146: try {
147: AckReTransmissionTest
148: .assertTrue(
149: "ACK was not successfully retransmitted 4 times",
150: 4 == dropAckCount);
151: //Create BYE request
152: Request byeRequest = dialog.createRequest(Request.BYE);
153: ClientTransaction ct = sipProvider
154: .getNewClientTransaction(byeRequest);
155: dialog.sendRequest(ct);
156: reSendSt = null;
157: reSendResponse = null;
158: logger.info("shootme: Sending a BYE");
159: } catch (Exception ex) {
160: String s = "Unexpected error";
161: logger.error(s, ex);
162: AckReTransmissionTest.fail(s);
163: }
164: }
165:
166: /**
167: * Process the invite request.
168: */
169: public void processInvite(RequestEvent requestEvent,
170: ServerTransaction serverTransaction) {
171: SipProvider sipProvider = (SipProvider) requestEvent
172: .getSource();
173: Request request = requestEvent.getRequest();
174: logger.info("Got an INVITE " + request);
175: try {
176: Response response = protocolObjects.messageFactory
177: .createResponse(180, request);
178: ToHeader toHeader = (ToHeader) response
179: .getHeader(ToHeader.NAME);
180: toHeader.setTag("4321");
181: Address address = protocolObjects.addressFactory
182: .createAddress("Shootme <sip:" + myAddress
183: + ":" + myPort + ">");
184: ContactHeader contactHeader = protocolObjects.headerFactory
185: .createContactHeader(address);
186: response.addHeader(contactHeader);
187: ServerTransaction st = requestEvent
188: .getServerTransaction();
189:
190: if (st == null) {
191: st = sipProvider.getNewServerTransaction(request);
192: logger
193: .info("Server transaction created!"
194: + request);
195:
196: logger.info("Dialog = " + st.getDialog());
197: }
198:
199: byte[] content = request.getRawContent();
200: if (content != null) {
201: logger.info(" content = " + new String(content));
202: ContentTypeHeader contentTypeHeader = protocolObjects.headerFactory
203: .createContentTypeHeader("application",
204: "sdp");
205: logger.info("response = " + response);
206: response.setContent(content, contentTypeHeader);
207: }
208: dialog = st.getDialog();
209: if (dialog != null) {
210: logger.info("Dialog " + dialog);
211: logger.info("Dialog state " + dialog.getState());
212: }
213: st.sendResponse(response);
214: response = protocolObjects.messageFactory
215: .createResponse(200, request);
216: toHeader = (ToHeader) response.getHeader(ToHeader.NAME);
217: toHeader.setTag("4321");
218: // Application is supposed to set.
219: response.addHeader(contactHeader);
220: st.sendResponse(response);
221: reSendSt = st;
222: reSendResponse = response;
223: logger.info("TxState after sendResponse = "
224: + st.getState());
225: this .inviteTid = st;
226: } catch (Exception ex) {
227: String s = "unexpected exception";
228:
229: logger.error(s, ex);
230: AckReTransmissionTest.fail(s);
231: }
232: }
233:
234: public void processResponse(ResponseEvent responseReceivedEvent) {
235: logger.info("Got a response");
236: Response response = (Response) responseReceivedEvent
237: .getResponse();
238: Transaction tid = responseReceivedEvent
239: .getClientTransaction();
240:
241: logger.info("Response received with client transaction id "
242: + tid + ":\n" + response);
243: try {
244: if (response.getStatusCode() == Response.OK
245: && ((CSeqHeader) response
246: .getHeader(CSeqHeader.NAME))
247: .getMethod().equals(Request.INVITE)) {
248: Dialog dialog = tid.getDialog();
249: CSeqHeader cseq = (CSeqHeader) response
250: .getHeader(CSeqHeader.NAME);
251: Request ackRequest = dialog.createAck(cseq
252: .getSeqNumber());
253: dialog.sendAck(ackRequest);
254: }
255: if (tid != null) {
256: Dialog dialog = tid.getDialog();
257: logger.info("Dialog State = " + dialog.getState());
258: }
259: } catch (Exception ex) {
260: String s = "Unexpected exception";
261: logger.error(s, ex);
262: AckReTransmissionTest.fail(s);
263: }
264:
265: }
266:
267: public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) {
268: Transaction transaction;
269: if (timeoutEvent.isServerTransaction()) {
270: transaction = timeoutEvent.getServerTransaction();
271: } else {
272: transaction = timeoutEvent.getClientTransaction();
273: }
274: logger.info("state = " + transaction.getState());
275: logger.info("dialog = " + transaction.getDialog());
276: logger.info("dialogState = "
277: + transaction.getDialog().getState());
278: logger.info("Transaction Time out");
279: }
280:
281: public SipProvider createSipProvider() throws Exception {
282: ListeningPoint lp = protocolObjects.sipStack
283: .createListeningPoint(myAddress, myPort,
284: protocolObjects.transport);
285:
286: SipProvider sipProvider = protocolObjects.sipStack
287: .createSipProvider(lp);
288: return sipProvider;
289: }
290:
291: public void checkState() {
292: AckReTransmissionTest.assertTrue(
293: "ACK was not successfully retransmitted 4 times",
294: 4 == dropAckCount);
295: }
296:
297: /*
298: * (non-Javadoc)
299: *
300: * @see javax.sip.SipListener#processIOException(javax.sip.IOExceptionEvent)
301: */
302: public void processIOException(IOExceptionEvent exceptionEvent) {
303: logger.error("An IO Exception was detected : "
304: + exceptionEvent.getHost());
305:
306: }
307:
308: /*
309: * (non-Javadoc)
310: *
311: * @see javax.sip.SipListener#processTransactionTerminated(javax.sip.TransactionTerminatedEvent)
312: */
313: public void processTransactionTerminated(
314: TransactionTerminatedEvent transactionTerminatedEvent) {
315: logger.info("Tx terminated event ");
316:
317: }
318:
319: /*
320: * (non-Javadoc)
321: *
322: * @see javax.sip.SipListener#processDialogTerminated(javax.sip.DialogTerminatedEvent)
323: */
324: public void processDialogTerminated(
325: DialogTerminatedEvent dialogTerminatedEvent) {
326: logger.info("Dialog terminated event detected ");
327:
328: }
329:
330: }
331:
332: class Shootist implements SipListener {
333:
334: private SipProvider provider;
335:
336: private int reInviteCount;
337:
338: private ContactHeader contactHeader;
339:
340: private ListeningPoint listeningPoint;
341:
342: private int counter;
343:
344: private String PEER_ADDRESS = Shootme.myAddress;
345:
346: private int PEER_PORT = Shootme.myPort;
347:
348: private String peerHostPort = PEER_ADDRESS + ":" + PEER_PORT;
349:
350: // To run on two machines change these to suit.
351: public static final String myAddress = "127.0.0.1";
352:
353: private static final int myPort = 5060;
354:
355: protected ClientTransaction inviteTid;
356:
357: private ProtocolObjects protocolObjects;
358:
359: private Dialog dialog;
360:
361: public Shootist(ProtocolObjects protocolObjects) {
362: super ();
363: this .protocolObjects = protocolObjects;
364:
365: }
366:
367: public void processRequest(RequestEvent requestReceivedEvent) {
368: Request request = requestReceivedEvent.getRequest();
369: ServerTransaction serverTransactionId = requestReceivedEvent
370: .getServerTransaction();
371:
372: logger.info("\n\nRequest " + request.getMethod()
373: + " received at "
374: + protocolObjects.sipStack.getStackName()
375: + " with server transaction id "
376: + serverTransactionId);
377:
378: if (request.getMethod().equals(Request.BYE))
379: processBye(request, serverTransactionId);
380: }
381:
382: public void processBye(Request request,
383: ServerTransaction serverTransactionId) {
384: try {
385: logger.info("shootist: got a bye .");
386: if (serverTransactionId == null) {
387: logger.info("shootist: null TID.");
388: return;
389: }
390: Response response = protocolObjects.messageFactory
391: .createResponse(200, request);
392: serverTransactionId.sendResponse(response);
393: } catch (Exception ex) {
394: logger.error("unexpected exception", ex);
395: AckReTransmissionTest.fail("unexpected exception");
396:
397: }
398: }
399:
400: public void processResponse(ResponseEvent responseReceivedEvent) {
401: logger.info("Got a response");
402:
403: Response response = (Response) responseReceivedEvent
404: .getResponse();
405: Transaction tid = responseReceivedEvent
406: .getClientTransaction();
407:
408: logger.info("Response received with client transaction id "
409: + tid + ":\n" + response.getStatusCode());
410: if (tid == null) {
411: logger.info("Stray response -- dropping ");
412: return;
413: }
414: logger.info("transaction state is " + tid.getState());
415: logger.info("Dialog = " + tid.getDialog());
416: logger
417: .info("Dialog State is "
418: + tid.getDialog().getState());
419: SipProvider provider = (SipProvider) responseReceivedEvent
420: .getSource();
421:
422: try {
423: if (response.getStatusCode() == Response.OK
424: && ((CSeqHeader) response
425: .getHeader(CSeqHeader.NAME))
426: .getMethod().equals(Request.INVITE)) {
427:
428: Dialog dialog = tid.getDialog();
429: CSeqHeader cseq = (CSeqHeader) response
430: .getHeader(CSeqHeader.NAME);
431: Request ackRequest = dialog.createAck(cseq
432: .getSeqNumber());
433: logger.info("Ack request to send = " + ackRequest);
434: logger.info("Sending ACK");
435: dialog.sendAck(ackRequest);
436: }
437: } catch (Exception ex) {
438: logger.error(ex);
439: AckReTransmissionTest.fail("unexpected exception");
440: }
441:
442: }
443:
444: public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) {
445:
446: logger.info("Transaction Time out");
447: logger.info("TimeoutEvent " + timeoutEvent.getTimeout());
448: }
449:
450: public SipProvider createSipProvider() {
451: try {
452: listeningPoint = protocolObjects.sipStack
453: .createListeningPoint(myAddress, myPort,
454: protocolObjects.transport);
455:
456: provider = protocolObjects.sipStack
457: .createSipProvider(listeningPoint);
458: return provider;
459: } catch (Exception ex) {
460: logger.error(ex);
461: AckReTransmissionTest.fail("unable to create provider");
462: return null;
463: }
464: }
465:
466: public void sendInvite() {
467:
468: try {
469:
470: // Note that a provider has multiple listening points.
471: // all the listening points must have the same IP address
472: // and port but differ in their transport parameters.
473:
474: String fromName = "BigGuy";
475: String fromSipAddress = "here.com";
476: String fromDisplayName = "The Master Blaster";
477:
478: String toSipAddress = "there.com";
479: String toUser = "LittleGuy";
480: String toDisplayName = "The Little Blister";
481:
482: // create >From Header
483: SipURI fromAddress = protocolObjects.addressFactory
484: .createSipURI(fromName, fromSipAddress);
485:
486: Address fromNameAddress = protocolObjects.addressFactory
487: .createAddress(fromAddress);
488: fromNameAddress.setDisplayName(fromDisplayName);
489: FromHeader fromHeader = protocolObjects.headerFactory
490: .createFromHeader(
491: fromNameAddress,
492: new Integer(
493: (int) (Math.random() * Integer.MAX_VALUE))
494: .toString());
495:
496: // create To Header
497: SipURI toAddress = protocolObjects.addressFactory
498: .createSipURI(toUser, toSipAddress);
499: Address toNameAddress = protocolObjects.addressFactory
500: .createAddress(toAddress);
501: toNameAddress.setDisplayName(toDisplayName);
502: ToHeader toHeader = protocolObjects.headerFactory
503: .createToHeader(toNameAddress, null);
504:
505: // create Request URI
506: SipURI requestURI = protocolObjects.addressFactory
507: .createSipURI(toUser, peerHostPort);
508:
509: // Create ViaHeaders
510:
511: ArrayList viaHeaders = new ArrayList();
512: int port = provider.getListeningPoint(
513: protocolObjects.transport).getPort();
514:
515: ViaHeader viaHeader = protocolObjects.headerFactory
516: .createViaHeader(myAddress, port,
517: protocolObjects.transport, null);
518:
519: // add via headers
520: viaHeaders.add(viaHeader);
521:
522: // Create ContentTypeHeader
523: ContentTypeHeader contentTypeHeader = protocolObjects.headerFactory
524: .createContentTypeHeader("application", "sdp");
525:
526: // Create a new CallId header
527: CallIdHeader callIdHeader = provider.getNewCallId();
528: // JvB: Make sure that the implementation matches the messagefactory
529: callIdHeader = protocolObjects.headerFactory
530: .createCallIdHeader(callIdHeader.getCallId());
531:
532: // Create a new Cseq header
533: CSeqHeader cSeqHeader = protocolObjects.headerFactory
534: .createCSeqHeader(1L, Request.INVITE);
535:
536: // Create a new MaxForwardsHeader
537: MaxForwardsHeader maxForwards = protocolObjects.headerFactory
538: .createMaxForwardsHeader(70);
539:
540: // Create the request.
541: Request request = protocolObjects.messageFactory
542: .createRequest(requestURI, Request.INVITE,
543: callIdHeader, cSeqHeader, fromHeader,
544: toHeader, viaHeaders, maxForwards);
545: // Create contact headers
546:
547: // Create the contact name address.
548: SipURI contactURI = protocolObjects.addressFactory
549: .createSipURI(fromName, myAddress);
550: contactURI.setPort(provider.getListeningPoint(
551: protocolObjects.transport).getPort());
552:
553: Address contactAddress = protocolObjects.addressFactory
554: .createAddress(contactURI);
555:
556: // Add the contact address.
557: contactAddress.setDisplayName(fromName);
558:
559: contactHeader = protocolObjects.headerFactory
560: .createContactHeader(contactAddress);
561: request.addHeader(contactHeader);
562:
563: // Add the extension header.
564: Header extensionHeader = protocolObjects.headerFactory
565: .createHeader("My-Header", "my header value");
566: request.addHeader(extensionHeader);
567:
568: String sdpData = "v=0\r\n"
569: + "o=4855 13760799956958020 13760799956958020"
570: + " IN IP4 129.6.55.78\r\n"
571: + "s=mysession session\r\n"
572: + "p=+46 8 52018010\r\n"
573: + "c=IN IP4 129.6.55.78\r\n" + "t=0 0\r\n"
574: + "m=audio 6022 RTP/AVP 0 4 18\r\n"
575: + "a=rtpmap:0 PCMU/8000\r\n"
576: + "a=rtpmap:4 G723/8000\r\n"
577: + "a=rtpmap:18 G729A/8000\r\n"
578: + "a=ptime:20\r\n";
579:
580: request.setContent(sdpData, contentTypeHeader);
581:
582: // The following is the preferred method to route requests
583: // to the peer. Create a route header and set the "lr"
584: // parameter for the router header.
585:
586: Address address = protocolObjects.addressFactory
587: .createAddress("<sip:" + PEER_ADDRESS + ":"
588: + PEER_PORT + ">");
589: // SipUri sipUri = (SipUri) address.getURI();
590: // sipUri.setPort(PEER_PORT);
591:
592: RouteHeader routeHeader = protocolObjects.headerFactory
593: .createRouteHeader(address);
594: ((SipURI) address.getURI()).setLrParam();
595: request.addHeader(routeHeader);
596: extensionHeader = protocolObjects.headerFactory
597: .createHeader("My-Other-Header",
598: "my new header value ");
599: request.addHeader(extensionHeader);
600:
601: Header callInfoHeader = protocolObjects.headerFactory
602: .createHeader("Call-Info",
603: "<http://www.antd.nist.gov>");
604: request.addHeader(callInfoHeader);
605:
606: // Create the client transaction.
607: this .inviteTid = provider
608: .getNewClientTransaction(request);
609: this .dialog = this .inviteTid.getDialog();
610: // Note that the response may have arrived right away so
611: // we cannot check after the message is sent.
612: AckReTransmissionTest
613: .assertTrue(this .dialog.getState() == null);
614:
615: // send the request out.
616: this .inviteTid.sendRequest();
617:
618: } catch (Exception ex) {
619: logger.error("Unexpected exception", ex);
620: AckReTransmissionTest.fail("unexpected exception");
621: }
622: }
623:
624: /*
625: * (non-Javadoc)
626: *
627: * @see javax.sip.SipListener#processIOException(javax.sip.IOExceptionEvent)
628: */
629: public void processIOException(IOExceptionEvent exceptionEvent) {
630: logger.error("IO Exception!");
631: AckReTransmissionTest.fail("Unexpected exception");
632:
633: }
634:
635: /*
636: * (non-Javadoc)
637: *
638: * @see javax.sip.SipListener#processTransactionTerminated(javax.sip.TransactionTerminatedEvent)
639: */
640: public void processTransactionTerminated(
641: TransactionTerminatedEvent transactionTerminatedEvent) {
642:
643: logger.info("Transaction Terminated Event!");
644: }
645:
646: /*
647: * (non-Javadoc)
648: *
649: * @see javax.sip.SipListener#processDialogTerminated(javax.sip.DialogTerminatedEvent)
650: */
651: public void processDialogTerminated(
652: DialogTerminatedEvent dialogTerminatedEvent) {
653: logger.info("Dialog Terminated Event!");
654:
655: }
656: }
657:
658: private SipListener getSipListener(EventObject sipEvent) {
659: SipProvider source = (SipProvider) sipEvent.getSource();
660: SipListener listener = (SipListener) providerTable.get(source);
661: assertTrue(listener != null);
662: return listener;
663: }
664:
665: public AckReTransmissionTest() {
666: super ("AckReTransmissionTest", true);
667: }
668:
669: public void setUp() {
670:
671: try {
672: this .transport = "udp";
673:
674: super .setUp();
675: shootist = new Shootist(riProtocolObjects);
676: SipProvider shootistProvider = shootist.createSipProvider();
677: providerTable.put(shootistProvider, shootist);
678:
679: shootme = new Shootme(tiProtocolObjects);
680: SipProvider shootmeProvider = shootme.createSipProvider();
681: providerTable.put(shootmeProvider, shootme);
682: shootistProvider.addSipListener(this );
683: shootmeProvider.addSipListener(this );
684:
685: riProtocolObjects.start();
686: if (tiProtocolObjects != riProtocolObjects)
687: tiProtocolObjects.start();
688: } catch (Exception ex) {
689: ex.printStackTrace();
690: fail("unexpected exception ");
691: }
692: }
693:
694: public void testAckReTransmission() {
695: this .shootist.sendInvite();
696: }
697:
698: public void tearDown() {
699: try {
700: Thread.sleep(2000);
701: this .shootme.checkState();
702: tiProtocolObjects.destroy();
703: if (tiProtocolObjects != riProtocolObjects)
704: riProtocolObjects.destroy();
705: Thread.sleep(1000);
706: this .providerTable.clear();
707: logTestCompleted();
708: } catch (Exception ex) {
709: ex.printStackTrace();
710: }
711:
712: }
713:
714: public void processRequest(RequestEvent requestEvent) {
715: getSipListener(requestEvent).processRequest(requestEvent);
716:
717: }
718:
719: public void processResponse(ResponseEvent responseEvent) {
720: getSipListener(responseEvent).processResponse(responseEvent);
721:
722: }
723:
724: public void processTimeout(TimeoutEvent timeoutEvent) {
725: getSipListener(timeoutEvent).processTimeout(timeoutEvent);
726: }
727:
728: public void processIOException(IOExceptionEvent exceptionEvent) {
729: fail("unexpected exception");
730:
731: }
732:
733: public void processTransactionTerminated(
734: TransactionTerminatedEvent transactionTerminatedEvent) {
735: getSipListener(transactionTerminatedEvent)
736: .processTransactionTerminated(
737: transactionTerminatedEvent);
738:
739: }
740:
741: public void processDialogTerminated(
742: DialogTerminatedEvent dialogTerminatedEvent) {
743: getSipListener(dialogTerminatedEvent).processDialogTerminated(
744: dialogTerminatedEvent);
745:
746: }
747:
748: }
|