/** * Process a request from a distant contact * * @param requestEvent the <tt>RequestEvent</tt> containing the newly received request. * @return <tt>true</tt> if the specified event has been handled by this processor and shouldn't * be offered to other processors registered for the same method; <tt>false</tt>, otherwise */ @Override public boolean processRequest(RequestEvent requestEvent) { synchronized (messageProcessors) { for (SipMessageProcessor listener : messageProcessors) if (!listener.processMessage(requestEvent)) return true; } // get the content String content = null; Request req = requestEvent.getRequest(); try { content = new String(req.getRawContent(), getCharset(req)); } catch (UnsupportedEncodingException ex) { if (logger.isDebugEnabled()) logger.debug("failed to convert the message charset"); content = new String(requestEvent.getRequest().getRawContent()); } // who sent this request ? FromHeader fromHeader = (FromHeader) requestEvent.getRequest().getHeader(FromHeader.NAME); if (fromHeader == null) { logger.error("received a request without a from header"); return false; } Contact from = opSetPersPresence.resolveContactID(fromHeader.getAddress().getURI().toString()); ContentTypeHeader ctheader = (ContentTypeHeader) req.getHeader(ContentTypeHeader.NAME); String ctype = null; String cencoding = null; if (ctheader == null) { ctype = DEFAULT_MIME_TYPE; } else { ctype = ctheader.getContentType() + "/" + ctheader.getContentSubType(); cencoding = ctheader.getParameter("charset"); } if (cencoding == null) cencoding = DEFAULT_MIME_ENCODING; Message newMessage = createMessage(content, ctype, cencoding, null); if (from == null) { if (logger.isDebugEnabled()) logger.debug( "received a message from an unknown contact: " + fromHeader.getAddress().getURI().toString()); // create the volatile contact from = opSetPersPresence.createVolatileContact(fromHeader.getAddress().getURI().toString()); } // answer ok try { Response ok = sipProvider.getMessageFactory().createResponse(Response.OK, requestEvent.getRequest()); SipStackSharing.getOrCreateServerTransaction(requestEvent).sendResponse(ok); } catch (ParseException exc) { logger.error("failed to build the response", exc); } catch (SipException exc) { logger.error("failed to send the response : " + exc.getMessage(), exc); } catch (InvalidArgumentException exc) { if (logger.isDebugEnabled()) logger.debug("Invalid argument for createResponse : " + exc.getMessage(), exc); } // fire an event MessageReceivedEvent msgReceivedEvt = new MessageReceivedEvent(newMessage, from, System.currentTimeMillis()); fireMessageEvent(msgReceivedEvt); return true; }
/** * Process a response from a distant contact. * * @param responseEvent the <tt>ResponseEvent</tt> containing the newly received SIP response. * @return <tt>true</tt> if the specified event has been handled by this processor and shouldn't * be offered to other processors registered for the same method; <tt>false</tt>, otherwise */ @Override public boolean processResponse(ResponseEvent responseEvent) { synchronized (messageProcessors) { for (SipMessageProcessor listener : messageProcessors) if (!listener.processResponse(responseEvent, sentMsg)) return true; } Request req = responseEvent.getClientTransaction().getRequest(); int status = responseEvent.getResponse().getStatusCode(); // content of the response String content = null; try { content = new String(req.getRawContent(), getCharset(req)); } catch (UnsupportedEncodingException exc) { if (logger.isDebugEnabled()) logger.debug("failed to convert the message charset", exc); content = new String(req.getRawContent()); } // to who did we send the original message ? ToHeader toHeader = (ToHeader) req.getHeader(ToHeader.NAME); if (toHeader == null) { // should never happen logger.error("send a request without a to header"); return false; } Contact to = opSetPersPresence.resolveContactID(toHeader.getAddress().getURI().toString()); if (to == null) { logger.error( "Error received a response from an unknown contact : " + toHeader.getAddress().getURI().toString() + " : " + responseEvent.getResponse().getStatusCode() + " " + responseEvent.getResponse().getReasonPhrase()); // error for delivering the message fireMessageDeliveryFailed( // we don't know what message it concerns createMessage(content), to, MessageDeliveryFailedEvent.INTERNAL_ERROR); return false; } // we retrieve the original message String key = ((CallIdHeader) req.getHeader(CallIdHeader.NAME)).getCallId(); Message newMessage = sentMsg.get(key); if (newMessage == null) { // should never happen logger.error("Couldn't find the message sent"); // error for delivering the message fireMessageDeliveryFailed( // we don't know what message it is createMessage(content), to, MessageDeliveryFailedEvent.INTERNAL_ERROR); return true; } // status 401/407 = proxy authentification if (status >= 400 && status != 401 && status != 407) { if (logger.isInfoEnabled()) logger.info( responseEvent.getResponse().getStatusCode() + " " + responseEvent.getResponse().getReasonPhrase()); // error for delivering the message MessageDeliveryFailedEvent evt = new MessageDeliveryFailedEvent( newMessage, to, MessageDeliveryFailedEvent.NETWORK_FAILURE, System.currentTimeMillis(), responseEvent.getResponse().getStatusCode() + " " + responseEvent.getResponse().getReasonPhrase()); fireMessageEvent(evt); sentMsg.remove(key); } else if (status == 401 || status == 407) { // proxy ask for authentification if (logger.isDebugEnabled()) logger.debug( "proxy asks authentication : " + responseEvent.getResponse().getStatusCode() + " " + responseEvent.getResponse().getReasonPhrase()); ClientTransaction clientTransaction = responseEvent.getClientTransaction(); SipProvider sourceProvider = (SipProvider) responseEvent.getSource(); try { processAuthenticationChallenge( clientTransaction, responseEvent.getResponse(), sourceProvider); } catch (OperationFailedException ex) { logger.error("can't solve the challenge", ex); // error for delivering the message MessageDeliveryFailedEvent evt = new MessageDeliveryFailedEvent( newMessage, to, MessageDeliveryFailedEvent.NETWORK_FAILURE, System.currentTimeMillis(), ex.getMessage()); fireMessageEvent(evt); sentMsg.remove(key); } } else if (status >= 200) { if (logger.isDebugEnabled()) logger.debug( "Ack received from the network : " + responseEvent.getResponse().getStatusCode() + " " + responseEvent.getResponse().getReasonPhrase()); // we delivered the message MessageDeliveredEvent msgDeliveredEvt = new MessageDeliveredEvent(newMessage, to, System.currentTimeMillis()); fireMessageEvent(msgDeliveredEvt); // we don't need this message anymore sentMsg.remove(key); } return true; }
@Override public boolean processTimeout(TimeoutEvent timeoutEvent) { synchronized (messageProcessors) { for (SipMessageProcessor listener : messageProcessors) if (!listener.processTimeout(timeoutEvent, sentMsg)) return true; } // this is normaly handled by the SIP stack logger.error("Timeout event thrown : " + timeoutEvent.toString()); if (timeoutEvent.isServerTransaction()) { logger.warn("The sender has probably not received our OK"); return false; } Request req = timeoutEvent.getClientTransaction().getRequest(); // get the content String content = null; try { content = new String(req.getRawContent(), getCharset(req)); } catch (UnsupportedEncodingException ex) { logger.warn("failed to convert the message charset", ex); content = new String(req.getRawContent()); } // to who this request has been sent ? ToHeader toHeader = (ToHeader) req.getHeader(ToHeader.NAME); if (toHeader == null) { logger.error("received a request without a to header"); return false; } Contact to = opSetPersPresence.resolveContactID(toHeader.getAddress().getURI().toString()); Message failedMessage = null; if (to == null) { logger.error( "timeout on a message sent to an unknown contact : " + toHeader.getAddress().getURI().toString()); // we don't know what message it concerns, so create a new // one failedMessage = createMessage(content); } else { // try to retrieve the original message String key = ((CallIdHeader) req.getHeader(CallIdHeader.NAME)).getCallId(); failedMessage = sentMsg.get(key); if (failedMessage == null) { // should never happen logger.error("Couldn't find the sent message."); // we don't know what the message is so create a new one // based on the content of the failed request. failedMessage = createMessage(content); } } // error for delivering the message fireMessageDeliveryFailed( // we don't know what message it concerns failedMessage, to, MessageDeliveryFailedEvent.INTERNAL_ERROR); return true; }