The SIP Servlet Tutorial

The CallSipServlet

The CallSipServlet SIP servlet connects registered SIP users to one another, allowing users to place calls to one another. There are 5 main SIP methods in CallSipServlet: doSuccessResponse, sendInviteToClient, sendAckToClient, sendAckToServer, and sent200OKToClient.

CallSipServlet is annotated at the class-level with a @SipServlet and @SipListener annotation.

@javax.servlet.sip.annotation.SipServlet
@SipListener
public class CallSipServlet extends SipServlet implements SipSessionListener {
    ...
}

The doSuccessResponse method connects a call between two registered users. When the first user Alice initiates a call to the second user Bob, first Alice's phone rings. If Alice answers her phone, a SIP OK message is sent. At that point, Bob's address is extracted from the request, a SIP INVITE message is sent to Bob's address by calling the sendInviteToClient private method, and Bob's phone rings. If Bob answers the phone, a SIP OK message is sent. The two SIP sessions, from Alice and Bob respectively, are linked, and a SIP ACK message is sent to both user's phones by calling the sendAckToClient and sendAckToServer private methods. Alice and Bob are now connected and can have a conversation. When the call is terminated, a BYE message is sent from the server, and the send200OKToClient private method is called.


Example 2–5 The doSuccessResponse Method

@Override
protected void doSuccessResponse(SipServletResponse resp)
        throws ServletException, IOException {
    logger.info("Received a response.\n" + resp);

    if (resp.getMethod().equals("INVITE")) {
        List<SipSession> sipSessions = getSipSessions(resp.getApplicationSession());
        if (sipSessions.size() == 1) {
            sipSessions.get(0).setAttribute("ACK", resp.createAck());
            sendInviteToClient(resp);
        } else { // 200 OK from Client
            sendAckToClient(resp);
            sendAckToServer(resp);
        }
    } else if (resp.getMethod().equals("BYE")) {
        send200OKToClient(resp);
    }
}


Example 2–6 The sendInviteToClient Method

private void sendInviteToClient(SipServletResponse serverResp)
        throws ServletException, IOException {
    SipServletRequest serverReq = serverResp.getRequest();
    B2buaHelper b2buaHelper = serverReq.getB2buaHelper();

    // Swap To & From headers.
    Map<String, List<String>> headerMap = new HashMap<String, List<String>>();
    List<String> from = new ArrayList<String>();
    from.add(serverResp.getHeader("From"));
    headerMap.put("To", from);
    List<String> to = new ArrayList<String>();
    to.add(serverResp.getHeader("To"));
    headerMap.put("From", to);

    SipServletRequest clientRequest = b2buaHelper
				.createRequest(serverReq, true, headerMap);
    clientRequest.setRequestURI(clientRequest.getAddressHeader("To").getURI());
    if (serverResp.getContent() != null) { // set sdp1
        clientRequest.setContent(serverResp.getContent(),
               serverResp.getContentType());
    }
    logger.info("Sending INVITE to client.\n" + clientRequest);
    clientRequest.send();
}


Example 2–7 The sendAckToClient Method

private void sendAckToClient(SipServletResponse clientResp) 
        throws ServletException, IOException {
    SipServletRequest ack = clientResp.createAck();
    logger.info("Sending ACK to client.\n" + ack);
    ack.send();
}


Example 2–8 The sendAckToServer Method

private void sendAckToServer(SipServletResponse clientResp) 
        throws ServletException, IOException {
    B2buaHelper b2buaHelper = clientResp.getRequest().getB2buaHelper();
    SipSession clientSession = clientResp.getSession();
    SipSession serverSession = b2buaHelper.getLinkedSession(clientSession);
    SipServletRequest ack = (SipServletRequest) serverSession.getAttribute("ACK");
    serverSession.removeAttribute("ACK");
    if (clientResp.getContent() != null) { // set sdp2
        ack.setContent(clientResp.getContent(), clientResp.getContentType());
    }
    logger.info("Sending ACK to server.\n" + ack);
    ack.send();
}


Example 2–9 The send200OKToClient Method

    protected void doBye(SipServletRequest request)
        throws ServletException, IOException 
    {
        logger.info("Got bye");
        
        SipSession session = request.getSession();
        
        // end the linked call 
        SipSession linkedSession = (SipSession) session.getAttribute("LinkedSession");
        if (linkedSession != null) {
            // create a BYE request to the linked session
            SipServletRequest bye = linkedSession.createRequest("BYE");
            
            logger.info("Sending bye to " + linkedSession.getRemoteParty());
            
            // send the BYE request
            bye.send();
        }
        
        // send an OK for the BYE
        SipServletResponse ok = request.createResponse(SipServletResponse.SC_OK);
        ok.send();
    }

There are three SIP session listener methods implemented in CallSipServlet, from the SipSessionListener interface: sessionCreated, sessionDestroyed, and sessionReadyToInvalidate. In CallSipServlet, the methods simply log the events.


Example 2–10 SipSessionListener Methods Implemented in CallSipServlet

public void sessionCreated(SipSessionEvent sse) {
    logger.info("Session created");
}

public void sessionDestroyed(SipSessionEvent sse) {
    logger.info("Session destroyed");
}
    
public void sessionReadyToInvalidate(SipSessionEvent sse) {
    logger.info("Session ready to be invalidated");
}