/** * Place to put some hacks if needed on incoming requests. * * @param event the incoming request event. * @return status <code>true</code> if we don't need to process this message, just discard it and * <code>false</code> otherwise. */ private boolean applyNonConformanceHacks(RequestEvent event) { Request request = event.getRequest(); try { /* * Max-Forwards is required, yet there are UAs which do not * place it. SipProvider#getNewServerTransaction(Request) * will throw an exception in the case of a missing * Max-Forwards header and this method will eventually just * log it thus ignoring the whole event. */ if (request.getHeader(MaxForwardsHeader.NAME) == null) { // it appears that some buggy providers do send requests // with no Max-Forwards headers, as we are at application level // and we know there will be no endless loops // there is no problem of adding headers and process normally // this messages MaxForwardsHeader maxForwards = SipFactory.getInstance().createHeaderFactory().createMaxForwardsHeader(70); request.setHeader(maxForwards); } } catch (Throwable ex) { logger.warn("Cannot apply incoming request modification!", ex); } try { // using asterisk voice mail initial notify for messages // is ok, but on the fly received messages their notify comes // without subscription-state, so we add it in order to be able to // process message. if (request.getMethod().equals(Request.NOTIFY) && request.getHeader(EventHeader.NAME) != null && ((EventHeader) request.getHeader(EventHeader.NAME)) .getEventType() .equals(OperationSetMessageWaitingSipImpl.EVENT_PACKAGE) && request.getHeader(SubscriptionStateHeader.NAME) == null) { request.addHeader( new HeaderFactoryImpl().createSubscriptionStateHeader(SubscriptionStateHeader.ACTIVE)); } } catch (Throwable ex) { logger.warn("Cannot apply incoming request modification!", ex); } try { // receiving notify message without subscription state // used for keep-alive pings, they have done their job // and are no more need. Skip processing them to avoid // filling logs with unneeded exceptions. if (request.getMethod().equals(Request.NOTIFY) && request.getHeader(SubscriptionStateHeader.NAME) == null) { return true; } } catch (Throwable ex) { logger.warn("Cannot apply incoming request modification!", ex); } return false; }
/** * Dispatches the event received from a JAIN-SIP <tt>SipProvider</tt> to one of our "candidate * recipient" listeners. * * @param event the event received for a <tt>SipProvider</tt>. */ public void processResponse(ResponseEvent event) { try { // we don't have to accept the transaction since we // created the request ClientTransaction transaction = event.getClientTransaction(); if (logger.isTraceEnabled()) logger.trace( "received response: " + event.getResponse().getStatusCode() + " " + event.getResponse().getReasonPhrase()); if (transaction == null) { logger.warn("Transaction is null, probably already expired!"); return; } ProtocolProviderServiceSipImpl service = getServiceData(transaction); if (service != null) { // Mark the dialog for the dispatching of later in-dialog // responses. If there is no dialog then the initial request // sure is marked otherwise we won't have found the service with // getServiceData(). The request has to be marked in case we // receive one more response in an out-of-dialog transaction. if (event.getDialog() != null) { SipApplicationData.setApplicationData( event.getDialog(), SipApplicationData.KEY_SERVICE, service); } service.processResponse(event); } else { logger.error( "We received a response which " + "wasn't marked, please report this to " + "*****@*****.**"); } } catch (Throwable exc) { // any exception thrown within our code should be caught here // so that we could log it rather than interrupt stack activity with // it. this.logApplicationException(DialogTerminatedEvent.class, exc); } }