@Override public synchronized void forwardTo(final Call call, final Map<String, String> headers) throws SignalException { if (!(call instanceof SIPCall)) { throw new UnsupportedOperationException("Cannot forward to non-SIPCall."); } if (_req.isInitial()) { throw new IllegalArgumentException("Cannot forward initial SIP request."); } final SIPCallImpl scall = (SIPCallImpl) call; if (!scall.isAnswered()) { throw new IllegalStateException("Cannot forward to no-answered call."); } this.checkState(); _forwarded = true; final SipSession session = scall.getSipSession(); final SipServletRequest req = session.createRequest(_req.getMethod()); SIPHelper.addHeaders(req, headers); SIPHelper.copyContent(_req, req); SIPHelper.linkSIPMessage(_req, req); try { req.send(); } catch (final IOException e) { throw new SignalException(e); } }
@Override public synchronized void forwardTo(final Endpoint endpoint, final Map<String, String> headers) throws SignalException, IllegalStateException { URI target = null; try { target = _ctx.getSipFactory().createURI(endpoint.getURI().toString()); } catch (final ServletParseException e) { throw new IllegalArgumentException(e); } this.checkState(); _forwarded = true; final SipServletRequest req = _ctx.getSipFactory() .createRequest( _req.getApplicationSession(), _req.getMethod(), _req.getFrom(), _req.getTo()); req.setRequestURI(target); SIPHelper.addHeaders(req, headers); SIPHelper.copyContent(_req, req); SIPHelper.linkSIPMessage(_req, req); try { req.send(); } catch (final IOException e) { throw new SignalException(e); } }
public void connectionOpenResponse(MsConnectionEvent event, SipServletResponse response) { logger.info("connection opened " + event); String sdp = event.getConnection().getLocalDescriptor(); SipServletRequest ack = response.createAck(); try { ack.setContent(sdp, "application/sdp"); ack.send(); } catch (Exception e) { logger.error(e); } provider = ConferenceCenter.getInstance().getProvider(); MsConnection connection = event.getConnection(); MsEndpoint endpoint = connection.getEndpoint(); MsSession session = connection.getSession(); String callerName = response.getTo().getURI().toString(); ConferenceParticipant participant = new EndpointConferenceParticipant(callerName, endpoint, session, response, connection); String key = SipGwtConferenceConsole.CONFERENCE_NAME; ConferenceCenter.getInstance().getConference(key).joinParticipant(participant); }
@Override protected void handleAck(final SIPCallImpl call, final SipServletRequest req) throws Exception { final SipServletResponse res = (SipServletResponse) req.getSession().getAttribute(REINVITE_PEER_RES); final SipServletRequest newReq = res.createAck(); SIPHelper.copyContent(req, newReq); newReq.send(); }
@Override protected void unmute(SIPCallImpl call) throws IOException, SdpException { final SIPCallImpl peer = (SIPCallImpl) call.getLastPeer(); SipServletRequest reInvite = call.getSipSession().createRequest("INVITE"); reInvite.setAttribute(SIPCallDelegate.SIPCALL_UNMUTE_REQUEST, "true"); reInvite.setContent(createSendrecvSDP(call, peer.getRemoteSdp()), "application/sdp"); reInvite.send(); }
@Override protected void handleReinvite( final SIPCallImpl call, final SipServletRequest req, final Map<String, String> headers) throws Exception { final SIPCallImpl peer = (SIPCallImpl) call.getLastPeer(); final SipServletRequest newReq = peer.getSipSession().createRequest(req.getMethod()); SIPHelper.addHeaders(newReq, headers); SIPHelper.copyContent(req, newReq); SIPHelper.linkSIPMessage(req, newReq); newReq.send(); }
@Override protected void hold(SIPCallImpl call, boolean send) throws MsControlException, IOException, SdpException { final SIPCallImpl peer = (SIPCallImpl) call.getLastPeer(); SipServletRequest reInvite = call.getSipSession().createRequest("INVITE"); reInvite.setAttribute(SIPCallDelegate.SIPCALL_HOLD_REQUEST, "true"); reInvite.setContent(createSendonlySDP(call, peer.getRemoteSdp()), "application/sdp"); reInvite.send(); peer.hold(); }
@Override protected void doBye(SipServletRequest request) throws ServletException, IOException { logger.info("Got bye"); SipSession session = request.getSession(); SipSession linkedSession = (SipSession) session.getAttribute("LinkedSession"); if (linkedSession != null) { SipServletRequest bye = linkedSession.createRequest("BYE"); logger.info("Sending bye to " + linkedSession.getRemoteParty()); bye.send(); } CallStatusContainer calls = (CallStatusContainer) getServletContext().getAttribute("activeCalls"); calls.removeCall(request.getFrom().getURI().toString(), request.getTo().getURI().toString()); calls.removeCall(request.getTo().getURI().toString(), request.getFrom().getURI().toString()); SipServletResponse ok = request.createResponse(SipServletResponse.SC_OK); ok.send(); }
public void onEvent(PlayerEvent event) { try { logger.info("ENDING CALL "); Player player = event.getSource(); MediaGroup mg = player.getContainer(); if (event.isSuccessful() && (PlayerEvent.PLAY_COMPLETED == event.getEventType())) { MediaSession session = (MediaSession) sipSession.getAttribute("mediaSession"); session.release(); Thread.sleep(1500); SipServletRequest byeRequest = sipSession.createRequest("BYE"); byeRequest.send(); } } catch (Exception e) { logger.error("Error", e); } }
private void doBye(SipSession session, SipServletRequest request) { // send bye to its linked user session and notify SipSession reqSession = request.getSession(false); if (null == reqSession.getAttribute(Constant.INVITE_USER_REQUEST)) { logger.info("callee ok"); SipServletRequest bye = session.createRequest(Constant.BYE); try { bye.send(); } catch (IOException e) { e.printStackTrace(); } } // send 200 OK to the session SipServletResponse resp = request.createResponse(SipServletResponse.SC_OK); try { resp.send(); } catch (IOException e) { e.printStackTrace(); } }
@Override protected void doSuccessResponse(SipServletResponse resp) throws ServletException, IOException { logger.info("Got OK"); SipSession session = resp.getSession(); if (resp.getStatus() == SipServletResponse.SC_OK) { Boolean inviteSent = (Boolean) session.getAttribute("InviteSent"); if (inviteSent != null && inviteSent.booleanValue()) { return; } Address secondPartyAddress = (Address) resp.getSession().getAttribute("SecondPartyAddress"); if (secondPartyAddress != null) { SipServletRequest invite = sipFactory.createRequest( resp.getApplicationSession(), "INVITE", session.getRemoteParty(), secondPartyAddress); logger.info("Found second party -- sending INVITE to " + secondPartyAddress); String contentType = resp.getContentType(); if (contentType.trim().equals("application/sdp")) { invite.setContent(resp.getContent(), "application/sdp"); } session.setAttribute("LinkedSession", invite.getSession()); invite.getSession().setAttribute("LinkedSession", session); SipServletRequest ack = resp.createAck(); invite.getSession().setAttribute("FirstPartyAck", ack); invite.getSession().setAttribute("FirstPartyContent", resp.getContent()); Call call = (Call) session.getAttribute("call"); // The call links the two sessions, add the new session to the call call.addSession(invite.getSession()); invite.getSession().setAttribute("call", call); invite.send(); session.setAttribute("InviteSent", Boolean.TRUE); } else { String cSeqValue = resp.getHeader("CSeq"); if (cSeqValue.indexOf("INVITE") != -1) { logger.info("Got OK from second party -- sending ACK"); SipServletRequest secondPartyAck = resp.createAck(); SipServletRequest firstPartyAck = (SipServletRequest) resp.getSession().getAttribute("FirstPartyAck"); // if (resp.getContentType() != null && // resp.getContentType().equals("application/sdp")) { firstPartyAck.setContent(resp.getContent(), "application/sdp"); secondPartyAck.setContent( resp.getSession().getAttribute("FirstPartyContent"), "application/sdp"); // } firstPartyAck.send(); secondPartyAck.send(); } } } }
/** * @param request * @param client * @param toClient * @throws IOException */ public static boolean redirectToB2BUA( final SipServletRequest request, final Client client, Client toClient, DaoManager storage, SipFactory sipFactory) throws IOException { request.getSession().setAttribute("lastRequest", request); if (logger.isInfoEnabled()) { logger.info("B2BUA (p2p proxy): Got request:\n" + request.getMethod()); logger.info( String.format( "B2BUA: Proxying a session between %s and %s", client.getUri(), toClient.getUri())); } if (daoManager == null) { daoManager = storage; } String user = ((SipURI) request.getTo().getURI()).getUser(); final RegistrationsDao registrations = daoManager.getRegistrationsDao(); final Registration registration = registrations.getRegistration(user); if (registration != null) { final String location = registration.getLocation(); SipURI to; SipURI from; try { to = (SipURI) sipFactory.createURI(location); from = (SipURI) sipFactory.createURI( (registrations.getRegistration(client.getLogin())).getLocation()); final SipSession incomingSession = request.getSession(); // create and send the outgoing invite and do the session linking incomingSession.setAttribute(B2BUA_LAST_REQUEST, request); SipServletRequest outRequest = sipFactory.createRequest( request.getApplicationSession(), request.getMethod(), request.getFrom().getURI(), request.getTo().getURI()); outRequest.setRequestURI(to); if (request.getContent() != null) { final byte[] sdp = request.getRawContent(); String offer = null; if (request.getContentType().equalsIgnoreCase("application/sdp")) { // Issue 308: https://telestax.atlassian.net/browse/RESTCOMM-308 String externalIp = request.getInitialRemoteAddr(); // Issue 306: https://telestax.atlassian.net/browse/RESTCOMM-306 final String initialIpBeforeLB = request.getHeader("X-Sip-Balancer-InitialRemoteAddr"); try { if (initialIpBeforeLB != null && !initialIpBeforeLB.isEmpty()) { offer = patch(sdp, initialIpBeforeLB); } else { offer = patch(sdp, externalIp); } } catch (SdpException e) { logger.error("Unexpected exception while patching sdp ", e); } } if (offer != null) { outRequest.setContent(offer, request.getContentType()); } else { outRequest.setContent(sdp, request.getContentType()); } } final SipSession outgoingSession = outRequest.getSession(); if (request.isInitial()) { incomingSession.setAttribute(B2BUA_LINKED_SESSION, outgoingSession); outgoingSession.setAttribute(B2BUA_LINKED_SESSION, incomingSession); } outgoingSession.setAttribute(B2BUA_LAST_REQUEST, outRequest); request.createResponse(100).send(); // Issue #307: https://telestax.atlassian.net/browse/RESTCOMM-307 request.getSession().setAttribute("toInetUri", to); outRequest.send(); outRequest.getSession().setAttribute("fromInetUri", from); final CallDetailRecord.Builder builder = CallDetailRecord.builder(); builder.setSid(Sid.generate(Sid.Type.CALL)); builder.setDateCreated(DateTime.now()); builder.setAccountSid(client.getAccountSid()); builder.setTo(toClient.getFriendlyName()); builder.setCallerName(client.getFriendlyName()); builder.setFrom(client.getFriendlyName()); // builder.setForwardedFrom(callInfo.forwardedFrom()); // builder.setPhoneNumberSid(phoneId); builder.setStatus(CallStateChanged.State.QUEUED.name()); builder.setDirection("Client-To-Client"); builder.setApiVersion(client.getApiVersion()); builder.setPrice(new BigDecimal("0.00")); // TODO implement currency property to be read from Configuration builder.setPriceUnit(Currency.getInstance("USD")); final StringBuilder buffer = new StringBuilder(); buffer.append("/").append(client.getApiVersion()).append("/Accounts/"); buffer.append(client.getAccountSid().toString()).append("/Calls/"); buffer.append(client.getSid().toString()); final URI uri = URI.create(buffer.toString()); builder.setUri(uri); CallDetailRecordsDao records = daoManager.getCallDetailRecordsDao(); CallDetailRecord callRecord = builder.build(); records.addCallDetailRecord(callRecord); incomingSession.setAttribute(CDR_SID, callRecord.getSid()); outgoingSession.setAttribute(CDR_SID, callRecord.getSid()); return true; // successfully proxied the SIP request between two registered clients } catch (ServletParseException badUriEx) { if (logger.isInfoEnabled()) { logger.info( String.format("B2BUA: Error parsing Client Contact URI: %s", location), badUriEx); } } } return false; }
@Override protected void doInviteResponse( final SipServletResponse res, final SIPCallImpl call, final Map<String, String> headers) throws Exception { try { if (_call2.equals(call)) { if (SIPHelper.isProvisionalResponse(res)) { call.setSIPCallState(SIPCall.State.ANSWERING); if (res.getStatus() == SipServletResponse.SC_SESSION_PROGRESS) { if (SIPHelper.getRawContentWOException(res) != null) { ((SIPOutgoingCall) _call1) .call(res.getRawContent(), _call2.getSipSession().getApplicationSession()); _invitedCall1 = true; } try { res.createPrack().send(); } catch (Rel100Exception ex) { LOG.warn(ex.getMessage()); } catch (IllegalStateException ex) { LOG.warn(ex.getMessage()); } } } else if (SIPHelper.isSuccessResponse(res)) { _response = res; if (!_invitedCall1) { ((SIPOutgoingCall) _call1) .call(res.getRawContent(), _call2.getSipSession().getApplicationSession()); } } else if (SIPHelper.isErrorResponse(res)) { Exception ex = getExceptionByResponse(res); done(getJoinCompleteCauseByResponse(res), ex); _call2.disconnect(true, getCallCompleteCauseByResponse(res), ex, null); } } else if (_call1.equals(call)) { if (SIPHelper.isProvisionalResponse(res)) { call.setSIPCallState(SIPCall.State.ANSWERING); if (res.getStatus() == SipServletResponse.SC_SESSION_PROGRESS) { if (SIPHelper.getRawContentWOException(res) != null) { SipServletRequest ack2 = null; if (_response != null) { final SipServletResponse origRes = _response; _response = null; ack2 = origRes.createAck(); SIPHelper.copyContent(res, ack2); } ack2.send(); _ackedCall2 = true; } try { res.createPrack().send(); } catch (Rel100Exception ex) { LOG.warn("", ex); } } } else if (SIPHelper.isSuccessResponse(res)) { final SipServletRequest ack1 = res.createAck(); ack1.send(); if (!_ackedCall2) { SipServletRequest ack2 = null; if (_response != null) { final SipServletResponse origRes = _response; _response = null; ack2 = origRes.createAck(); SIPHelper.copyContent(res, ack2); } ack2.send(); } _call2.setSIPCallState(State.ANSWERED); _call1.setSIPCallState(State.ANSWERED); _call1.linkCall(_call2, JoinType.DIRECT, _direction); done(JoinCompleteEvent.Cause.JOINED, null); } else if (SIPHelper.isErrorResponse(res)) { Exception ex = getExceptionByResponse(res); done(getJoinCompleteCauseByResponse(res), ex); _call1.disconnect(true, getCallCompleteCauseByResponse(res), ex, null); _call2.disconnect(true, getCallCompleteCauseByResponse(res), ex, null); } } } catch (final Exception e) { done(JoinCompleteEvent.Cause.ERROR, e); _call1.fail(e); _call2.fail(e); throw e; } }
/** * Synchronously ends this dialog. * * @param request * @throws IOException */ public void terminate(SipServletRequest request) throws IOException { if (_session == null) return; request.send(); _sessionHandler.waitForFinalResponse(); }
@Override protected void handleReinviteResponse( final SIPCallImpl call, final SipServletResponse res, final Map<String, String> headers) { if (res.getRequest().getAttribute(SIPCallDelegate.SIPCALL_HOLD_REQUEST) != null || res.getRequest().getAttribute(SIPCallDelegate.SIPCALL_UNHOLD_REQUEST) != null || res.getRequest().getAttribute(SIPCallDelegate.SIPCALL_DEAF_REQUEST) != null) { try { res.createAck().send(); if (call.getHoldState() == HoldState.Holding) { call.setHoldState(HoldState.Held); } else if (call.getHoldState() == HoldState.UnHolding) { call.setHoldState(HoldState.None); } else if (call.getDeafState() == HoldState.Deafing) { call.setDeafState(HoldState.Deafed); } else if (call.getDeafState() == HoldState.Undeafing) { call.setDeafState(HoldState.None); } } catch (IOException e) { LOG.error("IOException when sending back ACK.", e); call.setHoldState(HoldState.None); call.setDeafState(HoldState.None); call.fail(e); } finally { call.notify(); } } else if (res.getRequest().getAttribute(SIPCallDelegate.SIPCALL_MUTE_REQUEST) != null || res.getRequest().getAttribute(SIPCallDelegate.SIPCALL_UNMUTE_REQUEST) != null) { // send ACK. try { res.createAck().send(); // send the received SDP to peer. final SIPCallImpl peer = (SIPCallImpl) call.getLastPeer(); synchronized (peer) { if (call.getMuteState() == HoldState.Muting) { peer.setDeafState(HoldState.Deafing); } else { peer.setDeafState(HoldState.Undeafing); } SipServletRequest reInvite = peer.getSipSession().createRequest("INVITE"); reInvite.setAttribute(SIPCallDelegate.SIPCALL_DEAF_REQUEST, "true"); reInvite.setContent(res.getRawContent(), "application/sdp"); reInvite.send(); while (peer.getDeafState() != HoldState.Deafed && peer.getDeafState() != HoldState.None) { try { peer.wait(); } catch (InterruptedException e) { LOG.warn( "InterruptedException when wait make peer deaf, the peer's DeafState " + peer.getDeafState()); } } // set call deaf state if (call.getMuteState() == HoldState.Muting) { peer.setDeafState(HoldState.Deafed); call.setMuteState(HoldState.Muted); } else if (call.getMuteState() == HoldState.UnMuting) { peer.setDeafState(HoldState.None); call.setMuteState(HoldState.None); } } } catch (IOException e1) { LOG.error("IOException", e1); call.setMuteState(HoldState.None); call.fail(e1); } finally { call.notify(); } } else { try { final SipServletRequest req = res.getRequest(); final SipServletRequest newReq = (SipServletRequest) SIPHelper.getLinkSIPMessage(req); if (newReq != null) { SIPHelper.unlinkSIPMessage(req); final SipServletResponse newRes = newReq.createResponse(res.getStatus(), res.getReasonPhrase()); SIPHelper.addHeaders(newRes, headers); SIPHelper.copyContent(res, newRes); if (SIPHelper.isReinvite(newRes)) { newRes.getSession().setAttribute(REINVITE_PEER_RES, res); } newRes.send(); } } catch (final Exception e) { LOG.warn("", e); return; } } }