/** * Copyright 2010 Voxeo Corporation Licensed under the Apache License, Version * 2.0 (the "License"); you may not use this file except in compliance with the * License. You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law * or agreed to in writing, software distributed under the License is * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ package com.voxeo.moho.sip; import java.util.Map; import javax.media.mscontrol.MsControlException; import javax.media.mscontrol.join.Joinable.Direction; import javax.servlet.sip.SipServletRequest; import javax.servlet.sip.SipServletResponse; import com.voxeo.moho.Participant.JoinType; import com.voxeo.moho.event.JoinCompleteEvent; import com.voxeo.moho.sip.SIPCall.State; public class DirectNI2AOJoinDelegate extends JoinDelegate { protected Direction _direction; protected SipServletResponse _response; protected boolean call1Processed; protected DirectNI2AOJoinDelegate(final SIPIncomingCall call1, final SIPOutgoingCall call2, final Direction direction, final SIPCallImpl peer) { _call1 = call1; _call2 = call2; _direction = direction; _peer = peer; } @Override public void doJoin() throws Exception { super.doJoin(); if (_call1.getSIPCallState() == SIPCall.State.PROGRESSED) { call1Processed = true; ((SIPOutgoingCall) _call2).call(null, _call1.getSipSession().getApplicationSession()); } else { ((SIPOutgoingCall) _call2).call(_call1.getRemoteSdp()); } } @Override protected void doInviteResponse(final SipServletResponse res, final SIPCallImpl call, final Map<String, String> headers) throws Exception { if (_call2.equals(call)) { if (SIPHelper.isErrorResponse(res)) { done(getJoinCompleteCauseByResponse(res), getExceptionByResponse(res)); } else if (SIPHelper.isProvisionalResponse(res)) { SIPHelper.trySendPrack(res); } else if (SIPHelper.isSuccessResponse(res)) { try { _response = res; if(call1Processed) { final SipServletResponse newRes = _call1.getSipInitnalRequest().createResponse(res.getStatus(), res.getReasonPhrase()); newRes.send(); } else { final SipServletResponse newRes = _call1.getSipInitnalRequest().createResponse(res.getStatus(), res.getReasonPhrase()); SIPHelper.copyContent(res, newRes); newRes.send(); } } catch (final Exception e) { done(JoinCompleteEvent.Cause.ERROR, e); failCall(_call1, e); throw e; } } } else { if (SIPHelper.isErrorResponse(res)) { done(getJoinCompleteCauseByResponse(res), getExceptionByResponse(res)); } else if (SIPHelper.isProvisionalResponse(res)) { SIPHelper.trySendPrack(res); } else if (SIPHelper.isSuccessResponse(res)) { try { res.createAck().send(); SipServletRequest ack2 = _response.createAck(); if (call1Processed) { SIPHelper.copyContent(res, ack2); } ack2.send(); successJoin(); } catch (final Exception e) { done(JoinCompleteEvent.Cause.ERROR, e); failCall(_call1, e); throw e; } } } } /** * ACK * * @param req * @param call * @throws Exception */ @Override protected void doAck(final SipServletRequest req, final SIPCallImpl call) throws Exception { if (_call1.equals(call)) { _call1.setSIPCallState(State.ANSWERED); try { if (!call1Processed) { final SipServletRequest ack = _response.createAck(); SIPHelper.copyContent(req, ack); ack.send(); successJoin(); } else { _call1.reInviteRemote(_response.getContent(), null, null); } } catch (final Exception e) { done(JoinCompleteEvent.Cause.ERROR, e); failCall(_call1, e); throw e; } } } private void successJoin() throws MsControlException { doDisengage(_call2, JoinType.DIRECT); doDisengage(_call1, JoinType.DIRECT); _call1.linkCall(_call2, JoinType.DIRECT, _direction); _response = null; done(JoinCompleteEvent.Cause.JOINED, null); } }