FileDocCategorySizeDatePackage
EventScanner.javaAPI DocphoneME MR2 API (J2ME)12976Wed May 02 18:00:42 BST 2007gov.nist.siplite

EventScanner

public class EventScanner extends Object implements Runnable
Event scanner.

Fields Summary
private SipStack
sipStack
Current SIP stack context.
private Vector
pendingEvents
Vector of pending events.
private SipListener
sipListener
Current SIP event listener.
private boolean
isStopped
Flag to indicate if event processing is stopped.
Constructors Summary
public EventScanner(SipStack sipStack)
Constructor.

param
sipStack the current transaction context

        this.sipStack = sipStack;
        this.pendingEvents = new Vector();
    
Methods Summary
public voidaddEvent(EventWrapper eventWrapper)
Adds a new event to be processed.

param
eventWrapper the event filter handler to be added

        synchronized (pendingEvents) {
            pendingEvents.addElement(eventWrapper);
            pendingEvents.notify();
        }
    
public voidrun()
Starts the scanner procesing.

        while (true) {
            SipEvent sipEvent = null;
            EventWrapper eventWrapper = null;
            
            synchronized (this.pendingEvents) {
                if (pendingEvents.isEmpty()) {
                    try {
                        pendingEvents.wait();
                    } catch (InterruptedException ex) {
                        if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
                            Logging.report(Logging.INFORMATION,
                                LogChannels.LC_JSR180, "Interrupted!");
                        }
                        continue;
                    }
                }

                if (this.isStopped) {
                    return;
                }

                SipListener sipListener = sipStack.getSipListener();
                Enumeration iterator = pendingEvents.elements();
                
                while (iterator.hasMoreElements()) {
                    eventWrapper = (EventWrapper) iterator.nextElement();
                    sipEvent = eventWrapper.sipEvent;

                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
                        Logging.report(Logging.INFORMATION,
                            LogChannels.LC_JSR180,
                            "Processing "
                            + sipEvent
                            + "nevents "
                            + pendingEvents.size());
                    }

                    try {
                        if (sipEvent instanceof RequestEvent) {
                            // Check if this request has already created a
                            // transaction
                            Request sipRequest = (Request)
                                ((RequestEvent) sipEvent).getRequest();
                            // Check if this request has already created a
                            // transaction. If this is a dialog creating
                            // method for which a server transaction
                            // already exists or a method which is not
                            // dialog creating and not within an existing
                            // dialog (special handling for cancel) then
                            // check to see if the listener already
                            // created a transaction to handle this
                            // request and discard the duplicate request
                            // if a transaction already exists. If the
                            // listener chose to handle the request
                            // statelessly, then the listener will see the
                            // retransmission.  Note that in both of these
                            // two cases, JAIN SIP will allow you to
                            // handle the request statefully or
                            // statelessly.  An example of the latter case
                            // is REGISTER and an example of the former
                            // case is INVITE.


                            /*
                             * The transaction was added to the list
                             * in SIPTransactionStack, so it is not the right
                             * place to check if the transaction already exists.
                             *
                             * IMPL_NOTE: remove the following block of code after
                             *       ensuring that it doesn't break anything.
                             */

/*
                            if (sipStack.
                                isDialogCreated(sipRequest.getMethod())) {
                                SipProvider sipProvider =
                                    (SipProvider)sipEvent.getSource();
                                sipProvider.currentTransaction =
                                    (ServerTransaction)
                                        eventWrapper.transaction;
                                ServerTransaction tr = (ServerTransaction)
                                    sipStack.findTransaction(sipRequest, true);
                                Dialog dialog = sipStack.getDialog
                                    (sipRequest.getDialogId(true));

                                if (tr != null && !tr.passToListener()) {
                                    if (Logging.REPORT_LEVEL <=
                                        Logging.INFORMATION) {
                                        Logging.report(Logging.INFORMATION,
                                        LogChannels.LC_JSR180,
                                        "transaction already exists!");
                                    }
                                    continue;
                                }
                            } else if (!sipRequest.getMethod()
                                .equals(Request.CANCEL) &&
                                sipStack.getDialog(sipRequest
                                .getDialogId(true))
                                == null) {
                                // not dialog creating and not a cancel.
                                // transaction already processed this message.
                                Transaction tr = sipStack
                                    .findTransaction(sipRequest,
                                    true);
                                //
                                // Should this be allowed?
                                // SipProvider sipProvider =
                                //     (SipProvider) sipEvent.getSource();
                                // sipProvider.currentTransaction =
                                // (ServerTransaction) eventWrapper.transaction;
                                // If transaction already exists bail.
                                if (tr != null) {
                                    if (Logging.REPORT_LEVEL <=
                                        Logging.INFORMATION) {
                                        Logging.report(Logging.INFORMATION,
                                        LogChannels.LC_JSR180,
                                        "transaction already exists!");
                                    }
                                    continue;
                                }
                            }
*/

                            // Processing incoming CANCEL.
                            if (sipRequest.getMethod().equals(Request.CANCEL)) {
                                Transaction tr =
                                    sipStack.findTransaction(sipRequest, true);
                                if (tr != null &&
                                    tr.getState() ==
                                    Transaction.TERMINATED_STATE) {
                                    // If transaction already exists but it is
                                    // too late to cancel the transaction then
                                    // just respond OK to the CANCEL and bail.
                                    if (Logging.REPORT_LEVEL <=
                                        Logging.INFORMATION) {
                                        Logging.report(Logging.INFORMATION,
                                        LogChannels.LC_JSR180,
                                        "Too late to cancel Transaction");
                                    }

                                    // send OK and just ignore the CANCEL.
                                    try {
                                        tr.sendMessage
                                            (sipRequest
                                            .createResponse(Response.OK));
                                    } catch (IOException ex) {
                                        // Ignore?
                                    }
                                    continue;
                                }
                            }

                            sipListener.processRequest
                                ((RequestEvent) sipEvent);
                        } else if (sipEvent instanceof ResponseEvent) {
                            sipListener.processResponse
                                ((ResponseEvent) sipEvent);
                            ClientTransaction ct =
                                ((ResponseEvent) sipEvent).
                                    getClientTransaction();
                            ct.clearEventPending();
                        } else if (sipEvent instanceof TimeoutEvent) {
                            sipListener.processTimeout
                                ((TimeoutEvent) sipEvent);
                            // Mark that Timeout event has been processed
                            if (eventWrapper.transaction != null) {
                                if (eventWrapper.transaction instanceof
                                    ClientTransaction) {
                                    ((ClientTransaction) eventWrapper.
                                        transaction).clearEventPending();
                                }
                            }
                        } else {
                            if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
                                Logging.report(Logging.INFORMATION,
                                    LogChannels.LC_JSR180, "bad event");
                            }
                        }
                    } catch (Throwable exc) { // ignore
                        if (Logging.REPORT_LEVEL <=
                            Logging.INFORMATION) {
                            Logging.report(Logging.INFORMATION,
                            LogChannels.LC_JSR180,
                            "Uncaught exception ");
                        }
                    }
                }

                pendingEvents.removeAllElements();
            } // end of Synchronized block
        } // end While
    
public voidstart()
Starts the scanning for events.

        Thread myThread = new Thread(this);
        myThread.setPriority(Thread.MAX_PRIORITY);
        myThread.start();
    
public voidstop()
Stops the scanning for events.

        synchronized (this.pendingEvents) {
            this.isStopped = true;
            this.pendingEvents.notify();
        }