package com.voxeo.moho.remote.sipbased; import java.util.HashMap; import java.util.Map; import java.util.concurrent.Callable; import javax.media.mscontrol.join.Joinable.Direction; import javax.servlet.sip.SipURI; import org.apache.log4j.Logger; import com.voxeo.moho.Participant; import com.voxeo.moho.ParticipantContainer; import com.voxeo.moho.Unjoint; import com.voxeo.moho.UnjointImpl; import com.voxeo.moho.common.event.MohoCallCompleteEvent; import com.voxeo.moho.common.event.MohoUnjoinCompleteEvent; import com.voxeo.moho.event.CallCompleteEvent; import com.voxeo.moho.event.JoinCompleteEvent; import com.voxeo.moho.event.UnjoinCompleteEvent; import com.voxeo.moho.media.GenericMediaService; import com.voxeo.moho.remotejoin.RemoteParticipant; import com.voxeo.moho.sip.RemoteParticipantImpl; import com.voxeo.moho.sip.SIPEndpoint; import com.voxeo.moho.sip.SIPOutgoingCall; import com.voxeo.moho.spi.ExecutionContext; public class RemoteJoinOutgoingCall extends SIPOutgoingCall implements RemoteParticipant { private static final Logger LOG = Logger.getLogger(RemoteJoinOutgoingCall.class); private Direction _x_Join_Direction; private JoinType _x_Join_Type; private boolean _x_Join_Force; private SipURI joiner; private SipURI joinee; public RemoteJoinOutgoingCall(ExecutionContext context, SIPEndpoint from, SIPEndpoint to, Map<String, String> headers) { super(context, from, to, headers); if (_headers == null) { _headers = new HashMap<String, String>(); } joiner = from.getSipURI(); joinee = to.getSipURI(); } public void setCallID(String id) { _id = id; } public Direction getX_Join_Direction() { return _x_Join_Direction; } public void setX_Join_Direction(Direction x_Join_Direction) { _x_Join_Direction = x_Join_Direction; _headers.put(Constants.x_Join_Direction, x_Join_Direction.name()); if(_invite != null){ _invite.addHeader(Constants.x_Join_Direction, x_Join_Direction.name()); } } public JoinType getX_Join_Type() { return _x_Join_Type; } public void setX_Join_Type(JoinType x_Join_Type) { _x_Join_Type = x_Join_Type; _headers.put(Constants.x_Join_Type, x_Join_Type.name()); if(_invite != null){ _invite.addHeader(Constants.x_Join_Type, x_Join_Type.name()); } } public boolean getX_Join_Force() { return _x_Join_Force; } public void setX_Join_Force(boolean x_Join_Force) { _x_Join_Force = x_Join_Force; _headers.put(Constants.x_Join_Force, String.valueOf(x_Join_Force)); if(_invite != null){ _invite.addHeader(Constants.x_Join_Force, String.valueOf(x_Join_Force)); } } public SipURI getJoiner() { return joiner; } public SipURI getJoinee() { return joinee; } @Override public Unjoint unjoin(final Participant other, final boolean isInitiator) { Unjoint task = new UnjointImpl(_context.getExecutor(), new Callable<UnjoinCompleteEvent>() { @Override public UnjoinCompleteEvent call() throws Exception { UnjoinCompleteEvent event = doUnjoin(other, isInitiator); RemoteJoinOutgoingCall.this.disconnect(); return event; } }); return task; } protected synchronized void terminate(final CallCompleteEvent.Cause cause, final Exception exception, final Map<String, String> headers) { _context.removeCall(getId()); if (_service != null) { ((GenericMediaService) _service) .release((cause == CallCompleteEvent.Cause.DISCONNECT || cause == CallCompleteEvent.Cause.NEAR_END_DISCONNECT) ? true : false); _service = null; } destroyNetworkConnection(); Participant[] _joineesArray = _joinees.getJoinees(); for (Participant participant : _joineesArray) { UnjoinCompleteEvent.Cause unjoinCause = UnjoinCompleteEvent.Cause.ERROR; if (cause == CallCompleteEvent.Cause.DISCONNECT || cause == CallCompleteEvent.Cause.NEAR_END_DISCONNECT) { unjoinCause = UnjoinCompleteEvent.Cause.DISCONNECT; } dispatch(new MohoUnjoinCompleteEvent(this, participant, unjoinCause, exception, true)); if (participant instanceof ParticipantContainer) { try { ((ParticipantContainer) participant).doUnjoin(this, false); } catch (Exception e) { LOG.error("", e); } } } _joinees.clear(); synchronized (_peers) { // for (final Call peer : _peers) { // try { // peer.disconnect(); // } // catch (final Throwable t) { // LOG.warn("", t); // } // } _peers.clear(); } // TODO if (_joinDelegate != null) { if (cause == CallCompleteEvent.Cause.NEAR_END_DISCONNECT) { _joinDelegate.done(JoinCompleteEvent.Cause.DISCONNECTED, exception); } else { _joinDelegate.done(JoinCompleteEvent.Cause.ERROR, exception); } } this.dispatch(new MohoCallCompleteEvent(this, cause, exception, headers)); _callDelegate = null; } @Override public String toString() { return new StringBuilder().append(this.getClass().getSimpleName()).append("[").append(_signal).append(",") .append(_id).append(",").append(_cstate).append(",").append(_x_Join_Type).append(",").append(_x_Join_Force) .append(",").append(_x_Join_Direction).append("]").toString(); } @Override public String getRemoteParticipantID() { return joinee.getUser(); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((joinee.getUser() == null) ? 0 : joinee.getUser().hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass() && !(obj instanceof RemoteParticipant)) return false; if (obj instanceof RemoteParticipantImpl) { RemoteParticipantImpl other = (RemoteParticipantImpl) obj; if (this.getJoinee().getUser().equalsIgnoreCase(other.getId())) { return true; } else { return false; } } else { RemoteJoinIncomingCall other = (RemoteJoinIncomingCall) obj; if (_id == null) { if (other.getId() != null) return false; } else if (!_id.equals(other.getId())) return false; return true; } } }