/*
* 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 javax.annotation.Resource;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.sip.ServletTimer;
import javax.servlet.sip.SipApplicationSession;
import javax.servlet.sip.SipFactory;
import javax.servlet.sip.SipServlet;
import javax.servlet.sip.SipServletContextEvent;
import javax.servlet.sip.SipServletListener;
import javax.servlet.sip.SipServletRequest;
import javax.servlet.sip.SipServletResponse;
import javax.servlet.sip.SipSession;
import javax.servlet.sip.SipSessionEvent;
import javax.servlet.sip.SipSessionListener;
import javax.servlet.sip.SipURI;
import javax.servlet.sip.TimerListener;
import javax.servlet.sip.TimerService;
import javax.servlet.sip.URI;
import org.apache.log4j.Logger;
/**
*
* @author <A HREF="mailto:jean.deruelle@gmail.com">Jean Deruelle</A>
*
*/
public class ReferSipServlet extends SipServlet implements SipServletListener, TimerListener, SipSessionListener {
private static final long serialVersionUID = 1L;
private static final String REFER_SESSION = "referSession";
private static transient Logger logger = Logger.getLogger(ReferSipServlet.class);
private final static String TRYING_CONTENT = "SIP/2.0 100 Trying";
private final static String OK_CONTENT = "SIP/2.0 200 OK";
private final static String SUBSEQUENT_CONTENT = "SIP/2.0 100 Subsequent";
private static final String CONTENT_TYPE = "text/plain;charset=UTF-8";
private static final String SIP_SESSION_READY_TO_BE_INVALIDATED = "sipSessionReadyToBeInvalidated";
@Resource
SipFactory sipFactory;
/** Creates a new instance of ReferSipServlet */
public ReferSipServlet() {
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
logger.info("the refer sip servlet has been started");
super.init(servletConfig);
}
/**
* {@inheritDoc}
*/
protected void doInvite(SipServletRequest request) throws ServletException,
IOException {
logger.info("from : " + request.getFrom());
logger.info("Got request: "
+ request.getMethod());
//If we receive an INVITE, we cancel the timer to avoid acting as UAC and sending REFER
ServletTimer servletTimer = (ServletTimer)getServletContext().getAttribute("servletTimer");
servletTimer.cancel();
SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_RINGING);
sipServletResponse.send();
request.getSession().setAttribute("inviteReceived", "true");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sipServletResponse = request.createResponse(SipServletResponse.SC_OK);
sipServletResponse.send();
}
/**
* {@inheritDoc}
*/
protected void doRefer(SipServletRequest request) throws ServletException,
IOException {
logger.info("Got REFER: "
+ request);
//If we receive a Refer, we cancel the timer to avoid acting as UAC and sending REFER
ServletTimer servletTimer = (ServletTimer)getServletContext().getAttribute("servletTimer");
servletTimer.cancel();
SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_ACCEPTED);
sipServletResponse.send();
// send notify
SipServletRequest notifyRequest = request.getSession().createRequest("NOTIFY");
notifyRequest.addHeader("Subscription-State", "active;expires=3600");
notifyRequest.addHeader("Event", "refer");
if(request.isInitial() || request.getSession().getAttribute("inviteReceived") != null) {
notifyRequest.setContentLength(TRYING_CONTENT.length());
notifyRequest.setContent(TRYING_CONTENT, "message/sipfrag;version=2.0");
} else {
notifyRequest.setContentLength(TRYING_CONTENT.length());
notifyRequest.setContent(SUBSEQUENT_CONTENT, "message/sipfrag;version=2.0");
}
notifyRequest.send();
if(request.isInitial() || request.getSession().getAttribute("inviteReceived") != null) {
request.getSession().removeAttribute("inviteReceived");
SipFactory sipFactory = (SipFactory)getServletContext().getAttribute(SIP_FACTORY);
SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession();
sipApplicationSession.setAttribute(REFER_SESSION, request.getSession());
String inviteUri = request.getHeader("Refer-To");
SipURI fromURI = sipFactory.createSipURI("receiver", "example.com");
URI toURI = sipFactory.createURI(inviteUri.substring(1,inviteUri.length()-1));
SipURI requestURI = sipFactory.createSipURI(((SipURI)toURI).getUser(), "127.0.0.1:5090");
SipServletRequest inviteRequest = sipFactory.createRequest(sipApplicationSession, "INVITE", fromURI, toURI);
inviteRequest.setRequestURI(requestURI);
inviteRequest.setHeader("Referred-By", request.getFrom().getURI().toString());
try {
inviteRequest.send();
} catch (IOException e) {
logger.error(e);
}
}
}
@Override
protected void doSuccessResponse(SipServletResponse resp)
throws ServletException, IOException {
if("INVITE".equals(resp.getMethod())) {
resp.createAck().send();
SipSession referSession = (SipSession) resp.getApplicationSession().getAttribute(REFER_SESSION);
if(referSession != null) {
SipServletRequest notifyRequest = referSession.createRequest("NOTIFY");
notifyRequest.addHeader("Subscription-State", "terminated;reason=noresource");
notifyRequest.addHeader("Event", "refer");
notifyRequest.setContentLength(OK_CONTENT.length());
notifyRequest.setContent(OK_CONTENT, "message/sipfrag;version=2.0");
notifyRequest.send();
}
}
}
@Override
protected void doBye(SipServletRequest req) throws ServletException,
IOException {
req.createResponse(SipServletResponse.SC_OK).send();
}
@Override
protected void doNotify(SipServletRequest req) throws ServletException,
IOException {
req.createResponse(SipServletResponse.SC_OK).send();
if(req.getRawContent() != null) {
String content = new String(req.getRawContent());
if("SIP/2.0 200 OK".equals(content) && req.getHeader("Out-Of-Dialog") == null) {
SipServletRequest sipServletRequest = req.getSession().createRequest("REFER");
SipFactory sipFactory = (SipFactory)getServletContext().getAttribute(SIP_FACTORY);
SipURI requestURI = sipFactory.createSipURI("sender", "127.0.0.1:5080");
sipServletRequest.setRequestURI(requestURI);
sipServletRequest.addHeader("Refer-To", "sip:refer-to@nist.gov");
sipServletRequest.send();
} else if ("SIP/2.0 100 Subsequent".equals(content)) {
SipServletRequest messageRequest = req.getSession().createRequest("MESSAGE");
SipFactory sipFactory = (SipFactory)getServletContext().getAttribute(SIP_FACTORY);
SipURI requestURI = sipFactory.createSipURI("sender", "127.0.0.1:5080");
messageRequest.setRequestURI(requestURI);
messageRequest.setContentLength(req.getContentLength());
messageRequest.setContent("SIP/2.0 100 Subsequent", "text/plain;charset=UTF-8");
messageRequest.send();
}
}
}
// Listener methods
/*
* (non-Javadoc)
* @see javax.servlet.sip.SipServletListener#servletInitialized(javax.servlet.sip.SipServletContextEvent)
*/
public void servletInitialized(SipServletContextEvent ce) {
SipFactory sipFactory = (SipFactory)ce.getServletContext().getAttribute(SIP_FACTORY);
SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession();
TimerService timerService = (TimerService)ce.getServletContext().getAttribute(TIMER_SERVICE);
sipApplicationSession.setAttribute("sipFactory", sipFactory);
ServletTimer servletTimer = timerService.createTimer(sipApplicationSession, 2000, false, null);
ce.getServletContext().setAttribute("servletTimer", servletTimer);
}
/*
* (non-Javadoc)
* @see javax.servlet.sip.TimerListener#timeout(javax.servlet.sip.ServletTimer)
*/
public void timeout(ServletTimer timer) {
SipFactory sipFactory = (SipFactory) timer.getApplicationSession().getAttribute("sipFactory");
SipURI fromURI = sipFactory.createSipURI("receiver", "nist.gov");
SipURI toURI = sipFactory.createSipURI("sender", "nist.gov");
SipServletRequest sipServletRequest =
sipFactory.createRequest(timer.getApplicationSession(), "REFER", fromURI, toURI);
SipURI requestURI = sipFactory.createSipURI("sender", "127.0.0.1:5080");
sipServletRequest.setRequestURI(requestURI);
sipServletRequest.addHeader("Refer-To", "sip:refer-to@nist.gov");
try {
sipServletRequest.send();
} catch (IOException e) {
logger.error(e);
}
}
public void sessionCreated(SipSessionEvent se) {
// TODO Auto-generated method stub
}
public void sessionDestroyed(SipSessionEvent se) {
// TODO Auto-generated method stub
}
public void sessionReadyToInvalidate(SipSessionEvent se) {
logger.info("sip session expired " + se.getSession());
try {
SipServletRequest sipServletRequest = sipFactory.createRequest(
sipFactory.createApplicationSession(),
"MESSAGE",
se.getSession().getLocalParty(),
se.getSession().getRemoteParty());
SipURI sipUri=sipFactory.createSipURI("LittleGuy", "127.0.0.1:5080");
sipServletRequest.setRequestURI(sipUri);
sipServletRequest.setContentLength(SIP_SESSION_READY_TO_BE_INVALIDATED.length());
sipServletRequest.setContent(SIP_SESSION_READY_TO_BE_INVALIDATED, CONTENT_TYPE);
sipServletRequest.send();
} catch (IOException e) {
logger.error("Exception occured while sending the request",e);
}
}
}