/** Invoked for SIP INVITE requests. */ @Override protected void doInvite(final SipServletRequest req) throws ServletException, IOException { if (req.isInitial()) { // Get a reference to the Proxy helper. final Proxy proxy = req.getProxy(); // Set Proxy parameters to control various aspects of the proxying // operation: proxy.setRecordRoute(true); proxy.setSupervised(true); // Set the flag indicates the working mode. True for Follow-Me; false for // Find-me. proxy.setParallel(m_parallel); // Proxies a SIP request to the specified set of destinations. proxy.proxyTo(m_targets); } }
public void dispatch() throws DispatcherException { final SipServletRequestImpl sipServletRequest = (SipServletRequestImpl) sipServletMessage; final Request request = (Request) sipServletRequest.getMessage(); final ServerTransaction inviteTransaction = ((ServerTransactionExt) sipServletRequest.getTransaction()) .getCanceledInviteTransaction(); if (inviteTransaction == null) { if (logger.isDebugEnabled()) { logger.debug( "couldn't find the original invite transaction for this cancel " + request + ", it may be a retransmission and the transaction has already been terminated"); } return; } final TransactionApplicationData inviteAppData = (TransactionApplicationData) inviteTransaction.getApplicationData(); if (inviteAppData == null) { if (logger.isDebugEnabled()) { logger.debug( "couldn't find the original transaction app data for this cancel " + request + ", it may be a retransmission and the transaction has already been terminated or is being cleaned up"); } return; } final SipServletRequestImpl inviteRequest = (SipServletRequestImpl) inviteAppData.getSipServletMessage(); final MobicentsSipSession sipSession = inviteRequest.getSipSession(); sipServletRequest.setSipSession(sipSession); sipSession.setRequestsPending(0); if (logger.isDebugEnabled()) { logger.debug( "message associated with the inviteAppData " + "of the CANCEL " + inviteRequest); } if (logger.isDebugEnabled()) { logger.debug( "invite transaction associated with the inviteAppData " + "of the CANCEL " + inviteTransaction); } if (logger.isDebugEnabled()) { logger.debug( "app data of the invite transaction associated with the inviteAppData " + "of the CANCEL " + inviteAppData); } if (logger.isDebugEnabled()) { logger.debug( "routing state of the INVITE request for the CANCEL = " + inviteRequest.getRoutingState()); } final MobicentsSipApplicationSession sipApplicationSession = sipSession.getSipApplicationSession(); final SipContext sipContext = sipApplicationSession.getSipContext(); try { sipContext.enterSipApp(sipApplicationSession, sipSession); final Proxy proxy = sipSession.getProxy(); if (proxy != null) { if (logger.isDebugEnabled()) { logger.debug("proxying the CANCEL " + sipServletRequest); } // Routing State : PROXY case if (!RoutingState.PROXIED.equals(inviteRequest.getRoutingState())) { // 10.2.6 if the original request has not been proxied yet the container // responds to it with a 487 final response try { send487Response(inviteTransaction, inviteRequest); } catch (IllegalStateException iae) { logger.info("request already proxied, dropping the cancel"); return; } } else { // otherwise, all branches are cancelled, and response processing continues as usual proxy.cancel(); } // Fix for Issue 796 : SIP servlet (simple proxy) does not receive "Cancel" requests. // (http://code.google.com/p/mobicents/issues/detail?id=796) // JSR 289 Section 10.2.6 Receiving CANCEL : In either case, the application is // subsequently invoked with the CANCEL request try { callServlet(sipServletRequest); } catch (ServletException e) { throw new DispatcherException( Response.SERVER_INTERNAL_ERROR, "An unexpected servlet exception occured while routing the following CANCEL " + request, e); } catch (IOException e) { throw new DispatcherException( Response.SERVER_INTERNAL_ERROR, "An unexpected IO exception occured while routing the following CANCEL " + request, e); } catch (Throwable e) { throw new DispatcherException( Response.SERVER_INTERNAL_ERROR, "An unexpected exception occured while routing the following CANCEL " + request, e); } } else if (RoutingState.FINAL_RESPONSE_SENT.equals(inviteRequest.getRoutingState())) { if (logger.isDebugEnabled()) { logger.debug("the final response has already been sent, nothing to do here"); } } else { if (logger.isDebugEnabled()) { logger.debug("invite transaction of the CANCEL " + inviteTransaction); } if (logger.isDebugEnabled()) { logger.debug( "invite message : 1xx response was generated ? " + ((SipServletRequestImpl) inviteAppData.getSipServletMessage()) .is1xxResponseGenerated()); } if (logger.isDebugEnabled()) { logger.debug( "invite message : Final response was generated ? " + ((SipServletRequestImpl) inviteAppData.getSipServletMessage()) .isFinalResponseGenerated()); } if (logger.isDebugEnabled()) { logger.debug("replying 487 to INVITE cancelled"); } // otherwise it means that this is for the app try { send487Response(inviteTransaction, inviteRequest); } catch (IllegalStateException iae) { logger.info("request already proxied, dropping the cancel"); return; } try { callServlet(sipServletRequest); } catch (ServletException e) { throw new DispatcherException( Response.SERVER_INTERNAL_ERROR, "An unexpected servlet exception occured while routing the following CANCEL " + request, e); } catch (IOException e) { throw new DispatcherException( Response.SERVER_INTERNAL_ERROR, "An unexpected IO exception occured while routing the following CANCEL " + request, e); } catch (Throwable e) { throw new DispatcherException( Response.SERVER_INTERNAL_ERROR, "An unexpected exception occured while routing the following CANCEL " + request, e); } } } finally { sipContext.exitSipApp(sipApplicationSession, sipSession); } }