private static final String CONTACT_HEADER = "Contact";
private static final String SDPContent = "application/sdp";
private static final String HoldFlag = "a=sendonly";
private static final String ResFlag = "a=recvonly";
//call status
private static final String BUSY = "busy";
private static final String HELD = "held";
private static final String WAITING = "waiting";
private static CallStatusContainer callsc;
/**
* The SIP Factory. Can be used to create URI and requests.
*/
@Resource
private SipFactory sipFactory;
public MyServlet(){
}
/**
* @inheritDoc
*/
@SuppressWarnings("unchecked")
protected void doRegister(SipServletRequest req)
throws ServletException, IOException {
int response = SipServletResponse.SC_OK;
SipServletResponse resp = req.createResponse(response);
HashMap<String,String> users = (HashMap<String,String>)getServletContext().getAttribute("registeredUsersMap");
if(users == null)
users = new HashMap<String,String>();
getServletContext().setAttribute("registeredUserMap", users);
Address address = req.getAddressHeader(CONTACT_HEADER);
String fromURI = req.getFrom().getURI().toString();
int expires = address.getExpires();
if( expires < 0) {
expires = req.getExpires();
}
if(expires == 0) {
users.remove(fromURI);
if( callsc.getSpecStatus(req.getFrom().toString()) != null) {
callsc.removeSpecCall(req.getFrom().toString());
}
} else {
resp.setAddressHeader(CONTACT_HEADER, address);
users.put(fromURI, address.getURI().toString());
}
resp.send();
}
/**
* @inheritDoc
*/
protected void doSuccessResponse(SipServletResponse resp)
throws ServletException, IOException {
int response = SipServletResponse.SC_OK;
if(resp.getStatus() == response)
{
String status = callsc.getSpecStatus(resp.getTo().toString());
if( status == HELD )
{
resp.setContentLength(0);
resp.send();
KeyStepOfCallWait(resp);
} else
{
callsc.addCall(resp.getFrom().toString(), resp.getTo().toString(), BUSY);
callsc.addCall(resp.getTo().toString(), resp.getFrom().toString(), BUSY);
}
}
}
/**
* If receive a 182 queued,set the call to HELD,and change response to 183.
* This mechanism focus on To.So when doSuccessResponse also focus on To
* callsc.getSpecStatus(String To)
*/
protected void doProvisionalResponse(SipServletResponse resp)
throws ServletException, IOException {
int response = SipServletResponse.SC_SESSION_PROGRESS;
if( resp.getStatus() == SipServletResponse.SC_CALL_QUEUED)
{
Call call = new Call(resp.getFrom().toString(),resp.getTo().toString());
call.setStatus(HELD);
callsc.addCall(call.getFrom(),call.getTo(), HELD);//actually only To is HELD,and is needed.
resp.setStatus(response);
resp.send();
}
}
/**
* Check the session of the request,if it's a INITIAL state,handle it as
* a normal Invite,else if it's a CONFIRMED state,check if it contains
* SDP message.And send 200 back.
*/
protected void doInvite(SipServletRequest req)
throws ServletException, IOException {
SipSession session = req.getSession();
if( session.getState().equals(SipSession.State.INITIAL)) //This is a normal Invite
{
Proxy proxy = req.getProxy();
proxy.setRecordRoute(true);
proxy.setSupervised(true);
proxy.proxyTo(req.getRequestURI());
} else if(session.getState().equals(SipSession.State.CONFIRMED))//This's sent by a CONFIRMED session,so it's a re-invite
{
if(req.getContentType().equalsIgnoreCase(SDPContent) && req.getContentLength() != 0) { //The request contains a SDP info
String str = req.getContent().toString();
if(str.indexOf(HoldFlag) != -1 ) { //check if is a Call-Hold re-Invite
int response = SipServletResponse.SC_OK;
SipServletResponse resp = req.createResponse(response);
resp.send();
callsc.addCall(req.getFrom().toString(), req.getTo().toString(), HELD);
/*
* Add SDP MRS to request
*/
Proxy proxy = req.getProxy();
proxy.setSupervised(true);
proxy.setRecordRoute(true);
proxy.proxyTo(req.getRequestURI());
}
}
}
}
/**
* @inheritDoc
*/
protected void doAck(SipServletRequest req)
throws ServletException, IOException {
//TODO: Implement this method
}
/**
* @inheritDoc
*/
protected void doBye(SipServletRequest req)
throws ServletException, IOException {
callsc.removeCall(req.getFrom().toString(), req.getTo().toString());
callsc.removeCall(req.getTo().toString(), req.getFrom().toString());
}
/**
* @inheritDoc
*/
protected void doErrorResponse(SipServletResponse resp)
throws ServletException, IOException {
callsc.removeCall(resp.getFrom().toString(), resp.getTo().toString());
callsc.removeCall(resp.getTo().toString(), resp.getFrom().toString());
}
@Override
public void noAckReceived(SipErrorEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void noPrackReceived(SipErrorEvent arg0) {
// TODO Auto-generated method stub
}
public void KeyStepOfCallWait(SipServletResponse resp) throws IOException {
Address To = (Address) resp.getTo().getURI();
Address From = (Address) resp.getFrom().getURI();
SipSession session = resp.getSession();
SipServletRequest request = session.createRequest("INVITE");
request.setAddressHeader("From", From);
request.setAddressHeader("To", To);
request.send();
request.setAddressHeader("To", From);
request.setAddressHeader("From", To);
request.send();
}
}