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.
@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); } }
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(); }
private void sendAckToClient(SipServletResponse clientResp) throws ServletException, IOException { SipServletRequest ack = clientResp.createAck(); logger.info("Sending ACK to client.\n" + ack); ack.send(); }
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(); }
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.
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"); }