package com.voxeo.moho.remote.impl; import java.util.Map; import javax.media.mscontrol.join.Joinable.Direction; import org.apache.log4j.Logger; import com.rayo.core.AnsweredEvent; import com.rayo.core.CallRef; import com.rayo.core.DialCommand; import com.rayo.core.EndEvent; import com.rayo.core.RingingEvent; import com.voxeo.moho.Call; import com.voxeo.moho.CallableEndpoint; import com.voxeo.moho.Endpoint; import com.voxeo.moho.Joint; import com.voxeo.moho.OutgoingCall; import com.voxeo.moho.common.event.MohoCallCompleteEvent; import com.voxeo.moho.common.event.MohoJoinCompleteEvent; import com.voxeo.moho.event.CallCompleteEvent; import com.voxeo.moho.event.JoinCompleteEvent; import com.voxeo.moho.remote.MohoRemoteException; import com.voxeo.moho.remote.impl.event.MohoAnsweredEventImpl; import com.voxeo.moho.remote.impl.event.MohoHangupEventImpl; import com.voxeo.moho.remote.impl.event.MohoRingEventImpl; import com.voxeo.rayo.client.XmppException; import com.voxeo.rayo.client.xmpp.stanza.Presence; public class OutgoingCallImpl extends CallImpl implements OutgoingCall { private static final Logger LOG = Logger.getLogger(OutgoingCallImpl.class); protected JointImpl waitAnswerJoint = null; protected OutgoingCallImpl(MohoRemoteImpl mohoRemote, String callID, CallableEndpoint caller, CallableEndpoint callee, Map<String, String> headers) { super(mohoRemote, callID, caller, callee, headers); } protected boolean internalCall(Direction direction, boolean dispatchJoinToMediaEvent) throws MohoRemoteException { _mohoRemote.getParticipantsLock().lock(); try { if (_id == null) { DialCommand command = new DialCommand(); command.setFrom(_caller.getURI()); command.setTo(_callee.getURI()); command.setHeaders(_headers); waitAnswerJoint = new JointImpl(this, null, direction, dispatchJoinToMediaEvent); CallRef dialRef = _mohoRemote.getRayoClient().dial(command); setID(dialRef.getCallId()); return true; } else { return false; } } catch (XmppException ex) { this.setCallState(null); waitAnswerJoint = null; throw new MohoRemoteException(ex); } finally { _mohoRemote.getParticipantsLock().unlock(); } } @Override public Joint join(Direction direction) { internalCall(direction, true); return waitAnswerJoint; } private void setID(String id) { _id = id; if (_id != null) { _mohoRemote.addParticipant(this); } } @Override public void onRayoEvent(JID from, Presence presence) { Object object = presence.getExtension().getObject(); LOG.debug("OutgoingCallImpl Recived presence, processing:" + presence); if (object instanceof AnsweredEvent) { AnsweredEvent event = (AnsweredEvent) object; MohoAnsweredEventImpl<Call> mohoEvent = new MohoAnsweredEventImpl<Call>(this, event.getHeaders()); this.setCallState(State.CONNECTED); this.dispatch(mohoEvent); MohoJoinCompleteEvent joinComplete = new MohoJoinCompleteEvent(this, null, JoinCompleteEvent.Cause.JOINED, true); if (waitAnswerJoint.isDispatchJoinToMediaEvent()) { this.dispatch(joinComplete); } waitAnswerJoint.done(joinComplete); } else if (object instanceof RingingEvent) { RingingEvent event = (RingingEvent) object; MohoRingEventImpl mohoEvent = new MohoRingEventImpl(this, event.getHeaders()); this.dispatch(mohoEvent); } else if (object instanceof EndEvent) { EndEvent event = (EndEvent) object; EndEvent.Reason rayoReason = event.getReason(); if (rayoReason == EndEvent.Reason.HANGUP) { MohoHangupEventImpl mohoEvent = new MohoHangupEventImpl(this); this.dispatch(mohoEvent); } if (!compareAndsetState(State.CONNECTED, State.DISCONNECTED)) { MohoJoinCompleteEvent joinComplete = new MohoJoinCompleteEvent(this, null, getMohoJoinCompleteReasonByRayoEndEventReason(rayoReason), true); waitAnswerJoint.done(joinComplete); } if(getMohoReasonByRayoEndEventReason(event.getReason()) == CallCompleteEvent.Cause.DISCONNECT){ this.setCallState(State.DISCONNECTED); } else{ this.setCallState(State.FAILED); } MohoCallCompleteEvent mohoEvent = new MohoCallCompleteEvent(this, getMohoReasonByRayoEndEventReason(event.getReason()), null, event.getHeaders()); this.dispatch(mohoEvent); cleanUp(); } else { super.onRayoEvent(from, presence); } } @Override public String startJoin() throws MohoRemoteException { internalCall(Direction.DUPLEX, false); return _id; } protected JoinCompleteEvent.Cause getMohoJoinCompleteReasonByRayoEndEventReason(EndEvent.Reason reason) { switch (reason) { case TIMEOUT: return JoinCompleteEvent.Cause.TIMEOUT; case BUSY: return JoinCompleteEvent.Cause.BUSY; case REJECT: return JoinCompleteEvent.Cause.REJECT; case REDIRECT: return JoinCompleteEvent.Cause.REDIRECT; case ERROR: return JoinCompleteEvent.Cause.ERROR; default: return JoinCompleteEvent.Cause.ERROR; } } @Override public Endpoint getAddress() { return _callee; } @Override public String getRemoteAddress() { return _caller.getURI().toString(); } }