/* * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.mobicents.servlet.sip.testsuite; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.sip.AuthInfo; import javax.servlet.sip.B2buaHelper; import javax.servlet.sip.SipErrorEvent; import javax.servlet.sip.SipErrorListener; import javax.servlet.sip.SipFactory; import javax.servlet.sip.SipServlet; import javax.servlet.sip.SipServletRequest; import javax.servlet.sip.SipServletResponse; import javax.servlet.sip.SipSession; import javax.servlet.sip.SipURI; import org.apache.log4j.Logger; public class CallForwardingB2BUASipServlet extends SipServlet implements SipErrorListener { private static final long serialVersionUID = 1L; private static final String ACT_AS_UAS = "actAsUas"; private static transient Logger logger = Logger.getLogger(CallForwardingB2BUASipServlet.class); private static Map<String, String[]> forwardingUris = null; static { forwardingUris = new HashMap<String, String[]>(); forwardingUris.put("sip:forward-sender@sip-servlets.com", new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@127.0.0.1:5090"}); forwardingUris.put("sip:blocked-sender@sip-servlets.com", new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@127.0.0.1:5090"}); forwardingUris.put("sip:forward-sender@127.0.0.1", new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@127.0.0.1:5090"}); forwardingUris.put("sip:blocked-sender@127.0.0.1", new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@127.0.0.1:5090"}); forwardingUris.put("sip:forward-tcp-sender@sip-servlets.com", new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@127.0.0.1:5090;transport=tcp"}); forwardingUris.put("sip:forward-sender@127.0.0.1:5090", new String[]{"sip:forward-receiver@127.0.0.1:5090", "sip:forward-receiver@127.0.0.1:5090"}); forwardingUris.put("sip:composition@127.0.0.1:5090", new String[]{"sip:forward-composition@127.0.0.1:5070", "sip:forward-composition@127.0.0.1:5070"}); forwardingUris.put("sip:composition@sip-servlets.com", new String[]{"sip:forward-composition@127.0.0.1:5070", "sip:forward-composition@127.0.0.1:5070"}); forwardingUris.put("sip:sender@sip-servlets.com", new String[]{"sip:fromB2BUA@sip-servlets.com", "sip:fromB2BUA@127.0.0.1:5090"}); forwardingUris.put("sip:samesipsession@sip-servlets.com", new String[]{"sip:forward-samesipsession@127.0.0.1:5070", "sip:forward-samesipsession@127.0.0.1:5070"}); forwardingUris.put("sip:cancel-samesipsession@sip-servlets.com", new String[]{"sip:cancel-forward-samesipsession@127.0.0.1:5070", "sip:cancel-forward-samesipsession@127.0.0.1:5070"}); forwardingUris.put("sip:error-samesipsession@sip-servlets.com", new String[]{"sip:error-forward-samesipsession@127.0.0.1:5070", "sip:error-forward-samesipsession@127.0.0.1:5070"}); } @Override public void init(ServletConfig servletConfig) throws ServletException { logger.info("the call forwarding B2BUA sip servlet has been started"); super.init(servletConfig); } @Override protected void doAck(SipServletRequest request) throws ServletException, IOException { logger.info("Got : " + request.toString()); SipSession session = request.getSession(); if(request.getTo().toString().contains("b2bua@sip-servlet")) { session.createRequest("MESSAGE").send(); } // SipSession linkedSession = helper.getLinkedSession(session); // SipServletRequest forkedRequest = linkedSession.createRequest("ACK"); // forkedRequest.setContentLength(request.getContentLength()); // forkedRequest.setContent(request.getContent(), request.getContentType()); // logger.info("forkedRequest = " + forkedRequest); // // forkedRequest.send(); } @Override protected void doInvite(SipServletRequest request) throws ServletException, IOException { logger.info("Got INVITE: " + request.toString()); logger.info(request.getFrom().getURI().toString()); String[] forwardingUri = forwardingUris.get(request.getFrom().getURI().toString()); if(((SipURI)request.getTo().getURI()).getUser().contains("forward-samesipsession")) { request.getSession().setAttribute(ACT_AS_UAS, Boolean.TRUE); if(request.getSession().getAttribute("originalRequest") == null) { if(((SipURI)request.getTo().getURI()).getUser().contains("cancel")) { request.createResponse(SipServletResponse.SC_RINGING).send(); } else if(((SipURI)request.getTo().getURI()).getUser().contains("error")) { request.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR, "expected error").send(); } else { request.createResponse(SipServletResponse.SC_OK).send(); } } else { request.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR, "same sip session").send(); } return ; } if(forwardingUri != null && forwardingUri.length > 0) { B2buaHelper helper = request.getB2buaHelper(); helper.createResponseToOriginalRequest(request.getSession(), SipServletResponse.SC_TRYING, "").send(); SipFactory sipFactory = (SipFactory) getServletContext().getAttribute( SIP_FACTORY); Map<String, List<String>> headers=new HashMap<String, List<String>>(); List<String> toHeaderList = new ArrayList<String>(); toHeaderList.add(forwardingUri[0]); headers.put("To", toHeaderList); SipServletRequest forkedRequest = helper.createRequest(request, true, headers); SipURI sipUri = (SipURI) sipFactory.createURI(forwardingUri[1]); forkedRequest.setRequestURI(sipUri); logger.info("forkedRequest = " + forkedRequest); forkedRequest.getSession().setAttribute("originalRequest", request); forkedRequest.send(); } else { logger.info("INVITE has not been forwarded."); } } @Override protected void doBye(SipServletRequest request) throws ServletException, IOException { logger.info("Got BYE: " + request.toString()); //we send the OK directly to the first call leg SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); sipServletResponse.send(); if(request.getSession().getAttribute(ACT_AS_UAS) == null) { //we forward the BYE SipSession session = request.getSession(); SipSession linkedSession = request.getB2buaHelper().getLinkedSession(session); SipServletRequest forkedRequest = linkedSession.createRequest("BYE"); logger.info("forkedRequest = " + forkedRequest); forkedRequest.send(); } } @Override protected void doCancel(SipServletRequest request) throws ServletException, IOException { if(!((SipURI)request.getTo().getURI()).getUser().equals("cancel-forward-samesipsession")) { logger.info("Got CANCEL: " + request.toString()); SipSession session = request.getSession(); B2buaHelper b2buaHelper = request.getB2buaHelper(); SipSession linkedSession = b2buaHelper.getLinkedSession(session); SipServletRequest originalRequest = (SipServletRequest)linkedSession.getAttribute("originalRequest"); SipServletRequest cancelRequest = b2buaHelper.getLinkedSipServletRequest(originalRequest).createCancel(); logger.info("forkedRequest = " + cancelRequest); cancelRequest.send(); } } @Override protected void doSuccessResponse(SipServletResponse sipServletResponse) throws ServletException, IOException { logger.info("Got : " + sipServletResponse.toString()); SipSession originalSession = sipServletResponse.getRequest().getB2buaHelper().getLinkedSession(sipServletResponse.getSession()); String cSeqValue = sipServletResponse.getHeader("CSeq"); //if this is a response to an INVITE we ack it and forward the OK if(originalSession!= null && cSeqValue.indexOf("INVITE") != -1) { SipServletRequest ackRequest = sipServletResponse.createAck(); logger.info("Sending " + ackRequest); ackRequest.send(); //create and sends OK for the first call leg SipServletRequest originalRequest = (SipServletRequest) sipServletResponse.getSession().getAttribute("originalRequest"); SipServletResponse responseToOriginalRequest = originalRequest.createResponse(sipServletResponse.getStatus()); logger.info("Sending OK on 1st call leg" + responseToOriginalRequest); responseToOriginalRequest.setContentLength(sipServletResponse.getContentLength()); //responseToOriginalRequest.setContent(sipServletResponse.getContent(), sipServletResponse.getContentType()); responseToOriginalRequest.send(); } } @Override protected void doErrorResponse(SipServletResponse sipServletResponse) throws ServletException, IOException { logger.info("Got : " + sipServletResponse.getStatus() + " " + sipServletResponse.getReasonPhrase()); //create and sends the error response for the first call leg if(sipServletResponse.getStatus() == SipServletResponse.SC_UNAUTHORIZED || sipServletResponse.getStatus() == SipServletResponse.SC_PROXY_AUTHENTICATION_REQUIRED) { // Avoid re-sending if the auth repeatedly fails. if(!"true".equals(getServletContext().getAttribute("FirstResponseRecieved"))) { getServletContext().setAttribute("FirstResponseRecieved", "true"); SipFactory sipFactory = (SipFactory) getServletContext().getAttribute( SIP_FACTORY); AuthInfo authInfo = sipFactory.createAuthInfo(); authInfo.addAuthInfo(sipServletResponse.getStatus(), "sip-servlets-realm", "user", "pass"); SipServletRequest req2 = sipServletResponse.getRequest(); B2buaHelper helper = req2.getB2buaHelper(); // SipServletRequest req1 = helper.getLinkedSipServletRequest(req2); SipServletRequest challengeRequest = helper.createRequest(sipServletResponse.getSession(), req2, null); challengeRequest.addAuthHeader(sipServletResponse, authInfo); challengeRequest.send(); } } else { if(sipServletResponse.getStatus() != SipServletResponse.SC_REQUEST_TERMINATED) { SipServletRequest originalRequest = (SipServletRequest) sipServletResponse.getSession().getAttribute("originalRequest"); SipServletResponse responseToOriginalRequest = originalRequest.createResponse(sipServletResponse.getStatus()); logger.info("Sending on the first call leg " + responseToOriginalRequest.toString()); responseToOriginalRequest.send(); } } } // SipErrorListener methods /** * {@inheritDoc} */ public void noAckReceived(SipErrorEvent ee) { logger.error("noAckReceived."); } /** * {@inheritDoc} */ public void noPrackReceived(SipErrorEvent ee) { logger.error("noPrackReceived."); } }