Skip to content
This repository
Browse code

implement remote join based on sip.

  • Loading branch information...
commit e2e491d4d85fd0182dfdd3f45147ccd093ffdb4b 1 parent 3bf4345
Williezhu Williezhu authored
2  moho-api/src/main/java/com/voxeo/moho/remotejoin/RemoteParticipant.java
@@ -10,4 +10,6 @@
10 10
11 11 public final String RemoteParticipant_TYPE_DIALOG = "dialog";
12 12
  13 + public String getRemoteParticipantID();
  14 +
13 15 }
11 moho-impl/src/main/java/com/voxeo/moho/remote/sipbased/Constants.java
... ... @@ -0,0 +1,11 @@
  1 +package com.voxeo.moho.remote.sipbased;
  2 +
  3 +public class Constants {
  4 +
  5 + public static String x_Join_Direction = "x-Join-Direction";
  6 +
  7 + public static String x_Join_Type = "x-Join-Type";
  8 +
  9 + public static String x_Join_Force = "x-Join-Force";
  10 +
  11 +}
208 moho-impl/src/main/java/com/voxeo/moho/remote/sipbased/RemoteJoinIncomingCall.java
... ... @@ -0,0 +1,208 @@
  1 +package com.voxeo.moho.remote.sipbased;
  2 +
  3 +import java.util.Map;
  4 +import java.util.concurrent.Callable;
  5 +
  6 +import javax.media.mscontrol.join.Joinable.Direction;
  7 +import javax.servlet.sip.SipServletRequest;
  8 +import javax.servlet.sip.SipURI;
  9 +
  10 +import org.apache.log4j.Logger;
  11 +
  12 +import com.voxeo.moho.Participant;
  13 +import com.voxeo.moho.ParticipantContainer;
  14 +import com.voxeo.moho.Unjoint;
  15 +import com.voxeo.moho.UnjointImpl;
  16 +import com.voxeo.moho.common.event.MohoCallCompleteEvent;
  17 +import com.voxeo.moho.common.event.MohoUnjoinCompleteEvent;
  18 +import com.voxeo.moho.event.CallCompleteEvent;
  19 +import com.voxeo.moho.event.JoinCompleteEvent;
  20 +import com.voxeo.moho.event.UnjoinCompleteEvent;
  21 +import com.voxeo.moho.media.GenericMediaService;
  22 +import com.voxeo.moho.remotejoin.RemoteParticipant;
  23 +import com.voxeo.moho.sip.RemoteParticipantImpl;
  24 +import com.voxeo.moho.sip.SIPIncomingCall;
  25 +import com.voxeo.moho.spi.ExecutionContext;
  26 +
  27 +public class RemoteJoinIncomingCall extends SIPIncomingCall implements RemoteParticipant {
  28 +
  29 + private static final Logger LOG = Logger.getLogger(RemoteJoinIncomingCall.class);
  30 +
  31 + private Direction _x_Join_Direction;
  32 +
  33 + private JoinType _x_Join_Type;
  34 +
  35 + private boolean _x_Join_Force;
  36 +
  37 + private SipURI joiner;
  38 +
  39 + private SipURI joinee;
  40 +
  41 + public RemoteJoinIncomingCall(ExecutionContext context, SipServletRequest req) {
  42 + super(context, req);
  43 + _x_Join_Direction = Direction.valueOf(req.getHeader(Constants.x_Join_Direction));
  44 + _x_Join_Type = JoinType.valueOf(req.getHeader(Constants.x_Join_Type));
  45 + _x_Join_Force = Boolean.valueOf(req.getHeader(Constants.x_Join_Force));
  46 + joiner = (SipURI) req.getFrom().getURI();
  47 + joinee = (SipURI) req.getTo().getURI();
  48 + }
  49 +
  50 + public void setCallID(String id) {
  51 + _id = id;
  52 + }
  53 +
  54 + public Direction getX_Join_Direction() {
  55 + return _x_Join_Direction;
  56 + }
  57 +
  58 + public void setX_Join_Direction(Direction x_Join_Direction) {
  59 + _x_Join_Direction = x_Join_Direction;
  60 + }
  61 +
  62 + public JoinType getX_Join_Type() {
  63 + return _x_Join_Type;
  64 + }
  65 +
  66 + public void setX_Join_Type(JoinType x_Join_Type) {
  67 + _x_Join_Type = x_Join_Type;
  68 + }
  69 +
  70 + public boolean getX_Join_Force() {
  71 + return _x_Join_Force;
  72 + }
  73 +
  74 + public void setX_Join_Force(boolean x_Join_Force) {
  75 + _x_Join_Force = x_Join_Force;
  76 + }
  77 +
  78 + public SipURI getJoiner() {
  79 + return joiner;
  80 + }
  81 +
  82 + public SipURI getJoinee() {
  83 + return joinee;
  84 + }
  85 +
  86 + @Override
  87 + public Unjoint unjoin(final Participant other, final boolean isInitiator) {
  88 + Unjoint task = new UnjointImpl(_context.getExecutor(), new Callable<UnjoinCompleteEvent>() {
  89 + @Override
  90 + public UnjoinCompleteEvent call() throws Exception {
  91 + UnjoinCompleteEvent event = doUnjoin(other, isInitiator);
  92 + RemoteJoinIncomingCall.this.disconnect();
  93 + return event;
  94 + }
  95 + });
  96 +
  97 + return task;
  98 + }
  99 +
  100 + protected synchronized void terminate(final CallCompleteEvent.Cause cause, final Exception exception,
  101 + final Map<String, String> headers) {
  102 + _context.removeCall(getId());
  103 +
  104 + if (_service != null) {
  105 + ((GenericMediaService) _service)
  106 + .release((cause == CallCompleteEvent.Cause.DISCONNECT || cause == CallCompleteEvent.Cause.NEAR_END_DISCONNECT) ? true
  107 + : false);
  108 + _service = null;
  109 + }
  110 +
  111 + destroyNetworkConnection();
  112 +
  113 + Participant[] _joineesArray = _joinees.getJoinees();
  114 + for (Participant participant : _joineesArray) {
  115 + UnjoinCompleteEvent.Cause unjoinCause = UnjoinCompleteEvent.Cause.ERROR;
  116 + if (cause == CallCompleteEvent.Cause.DISCONNECT || cause == CallCompleteEvent.Cause.NEAR_END_DISCONNECT) {
  117 + unjoinCause = UnjoinCompleteEvent.Cause.DISCONNECT;
  118 + }
  119 +
  120 + dispatch(new MohoUnjoinCompleteEvent(this, participant, unjoinCause, exception, true));
  121 +
  122 + if (participant instanceof ParticipantContainer) {
  123 + try {
  124 + ((ParticipantContainer) participant).doUnjoin(this, false);
  125 + }
  126 + catch (Exception e) {
  127 + LOG.error("", e);
  128 + }
  129 + }
  130 + }
  131 + _joinees.clear();
  132 +
  133 + synchronized (_peers) {
  134 + // for (final Call peer : _peers) {
  135 + // try {
  136 + // peer.disconnect();
  137 + // }
  138 + // catch (final Throwable t) {
  139 + // LOG.warn("", t);
  140 + // }
  141 + // }
  142 + _peers.clear();
  143 + }
  144 +
  145 + // TODO
  146 + if (_joinDelegate != null) {
  147 + if (cause == CallCompleteEvent.Cause.NEAR_END_DISCONNECT) {
  148 + _joinDelegate.done(JoinCompleteEvent.Cause.DISCONNECTED, exception);
  149 + }
  150 + else {
  151 + _joinDelegate.done(JoinCompleteEvent.Cause.ERROR, exception);
  152 + }
  153 + }
  154 +
  155 + this.dispatch(new MohoCallCompleteEvent(this, cause, exception, headers));
  156 +
  157 + _callDelegate = null;
  158 + }
  159 +
  160 + @Override
  161 + public String toString() {
  162 + return new StringBuilder().append(this.getClass().getSimpleName()).append("[").append(_signal).append(",")
  163 + .append(_id).append(",").append(_cstate).append(", ").append(_x_Join_Type).append(",").append(_x_Join_Force)
  164 + .append(",").append(_x_Join_Direction).append("]").toString();
  165 + }
  166 +
  167 + @Override
  168 + public String getRemoteParticipantID() {
  169 + return joiner.getUser();
  170 + }
  171 +
  172 + @Override
  173 + public int hashCode() {
  174 + final int prime = 31;
  175 + int result = 1;
  176 + result = prime * result + ((joiner.getUser() == null) ? 0 : joiner.getUser().hashCode());
  177 + return result;
  178 + }
  179 +
  180 + @Override
  181 + public boolean equals(Object obj) {
  182 + if (this == obj)
  183 + return true;
  184 + if (obj == null)
  185 + return false;
  186 + if (getClass() != obj.getClass() && !(obj instanceof RemoteParticipant))
  187 + return false;
  188 + if (obj instanceof RemoteParticipantImpl) {
  189 + RemoteParticipantImpl other = (RemoteParticipantImpl) obj;
  190 + if (this.getJoiner().getUser().equalsIgnoreCase(other.getId())) {
  191 + return true;
  192 + }
  193 + else {
  194 + return false;
  195 + }
  196 + }
  197 + else {
  198 + RemoteJoinIncomingCall other = (RemoteJoinIncomingCall) obj;
  199 + if (_id == null) {
  200 + if (other.getId() != null)
  201 + return false;
  202 + }
  203 + else if (!_id.equals(other.getId()))
  204 + return false;
  205 + return true;
  206 + }
  207 + }
  208 +}
212 moho-impl/src/main/java/com/voxeo/moho/remote/sipbased/RemoteJoinOutgoingCall.java
... ... @@ -0,0 +1,212 @@
  1 +package com.voxeo.moho.remote.sipbased;
  2 +
  3 +import java.util.HashMap;
  4 +import java.util.Map;
  5 +import java.util.concurrent.Callable;
  6 +
  7 +import javax.media.mscontrol.join.Joinable.Direction;
  8 +import javax.servlet.sip.SipURI;
  9 +
  10 +import org.apache.log4j.Logger;
  11 +
  12 +import com.voxeo.moho.Participant;
  13 +import com.voxeo.moho.ParticipantContainer;
  14 +import com.voxeo.moho.Unjoint;
  15 +import com.voxeo.moho.UnjointImpl;
  16 +import com.voxeo.moho.common.event.MohoCallCompleteEvent;
  17 +import com.voxeo.moho.common.event.MohoUnjoinCompleteEvent;
  18 +import com.voxeo.moho.event.CallCompleteEvent;
  19 +import com.voxeo.moho.event.JoinCompleteEvent;
  20 +import com.voxeo.moho.event.UnjoinCompleteEvent;
  21 +import com.voxeo.moho.media.GenericMediaService;
  22 +import com.voxeo.moho.remotejoin.RemoteParticipant;
  23 +import com.voxeo.moho.sip.RemoteParticipantImpl;
  24 +import com.voxeo.moho.sip.SIPEndpoint;
  25 +import com.voxeo.moho.sip.SIPOutgoingCall;
  26 +import com.voxeo.moho.spi.ExecutionContext;
  27 +
  28 +public class RemoteJoinOutgoingCall extends SIPOutgoingCall implements RemoteParticipant {
  29 +
  30 + private static final Logger LOG = Logger.getLogger(RemoteJoinOutgoingCall.class);
  31 +
  32 + private Direction _x_Join_Direction;
  33 +
  34 + private JoinType _x_Join_Type;
  35 +
  36 + private boolean _x_Join_Force;
  37 +
  38 + private SipURI joiner;
  39 +
  40 + private SipURI joinee;
  41 +
  42 + public RemoteJoinOutgoingCall(ExecutionContext context, SIPEndpoint from, SIPEndpoint to, Map<String, String> headers) {
  43 + super(context, from, to, headers);
  44 + if (_headers == null) {
  45 + _headers = new HashMap<String, String>();
  46 + }
  47 + joiner = from.getSipURI();
  48 + joinee = to.getSipURI();
  49 + }
  50 +
  51 + public void setCallID(String id) {
  52 + _id = id;
  53 + }
  54 +
  55 + public Direction getX_Join_Direction() {
  56 + return _x_Join_Direction;
  57 + }
  58 +
  59 + public void setX_Join_Direction(Direction x_Join_Direction) {
  60 + _x_Join_Direction = x_Join_Direction;
  61 + _headers.put(Constants.x_Join_Direction, x_Join_Direction.name());
  62 + }
  63 +
  64 + public JoinType getX_Join_Type() {
  65 + return _x_Join_Type;
  66 + }
  67 +
  68 + public void setX_Join_Type(JoinType x_Join_Type) {
  69 + _x_Join_Type = x_Join_Type;
  70 + _headers.put(Constants.x_Join_Type, x_Join_Type.name());
  71 + }
  72 +
  73 + public boolean getX_Join_Force() {
  74 + return _x_Join_Force;
  75 + }
  76 +
  77 + public void setX_Join_Force(boolean x_Join_Force) {
  78 + _x_Join_Force = x_Join_Force;
  79 + _headers.put(Constants.x_Join_Force, String.valueOf(x_Join_Force));
  80 + }
  81 +
  82 + public SipURI getJoiner() {
  83 + return joiner;
  84 + }
  85 +
  86 + public SipURI getJoinee() {
  87 + return joinee;
  88 + }
  89 +
  90 + @Override
  91 + public Unjoint unjoin(final Participant other, final boolean isInitiator) {
  92 + Unjoint task = new UnjointImpl(_context.getExecutor(), new Callable<UnjoinCompleteEvent>() {
  93 + @Override
  94 + public UnjoinCompleteEvent call() throws Exception {
  95 + UnjoinCompleteEvent event = doUnjoin(other, isInitiator);
  96 + RemoteJoinOutgoingCall.this.disconnect();
  97 + return event;
  98 + }
  99 + });
  100 +
  101 + return task;
  102 + }
  103 +
  104 + protected synchronized void terminate(final CallCompleteEvent.Cause cause, final Exception exception,
  105 + final Map<String, String> headers) {
  106 + _context.removeCall(getId());
  107 +
  108 + if (_service != null) {
  109 + ((GenericMediaService) _service)
  110 + .release((cause == CallCompleteEvent.Cause.DISCONNECT || cause == CallCompleteEvent.Cause.NEAR_END_DISCONNECT) ? true
  111 + : false);
  112 + _service = null;
  113 + }
  114 +
  115 + destroyNetworkConnection();
  116 +
  117 + Participant[] _joineesArray = _joinees.getJoinees();
  118 + for (Participant participant : _joineesArray) {
  119 + UnjoinCompleteEvent.Cause unjoinCause = UnjoinCompleteEvent.Cause.ERROR;
  120 + if (cause == CallCompleteEvent.Cause.DISCONNECT || cause == CallCompleteEvent.Cause.NEAR_END_DISCONNECT) {
  121 + unjoinCause = UnjoinCompleteEvent.Cause.DISCONNECT;
  122 + }
  123 +
  124 + dispatch(new MohoUnjoinCompleteEvent(this, participant, unjoinCause, exception, true));
  125 +
  126 + if (participant instanceof ParticipantContainer) {
  127 + try {
  128 + ((ParticipantContainer) participant).doUnjoin(this, false);
  129 + }
  130 + catch (Exception e) {
  131 + LOG.error("", e);
  132 + }
  133 + }
  134 + }
  135 + _joinees.clear();
  136 +
  137 + synchronized (_peers) {
  138 + // for (final Call peer : _peers) {
  139 + // try {
  140 + // peer.disconnect();
  141 + // }
  142 + // catch (final Throwable t) {
  143 + // LOG.warn("", t);
  144 + // }
  145 + // }
  146 + _peers.clear();
  147 + }
  148 +
  149 + // TODO
  150 + if (_joinDelegate != null) {
  151 + if (cause == CallCompleteEvent.Cause.NEAR_END_DISCONNECT) {
  152 + _joinDelegate.done(JoinCompleteEvent.Cause.DISCONNECTED, exception);
  153 + }
  154 + else {
  155 + _joinDelegate.done(JoinCompleteEvent.Cause.ERROR, exception);
  156 + }
  157 + }
  158 +
  159 + this.dispatch(new MohoCallCompleteEvent(this, cause, exception, headers));
  160 +
  161 + _callDelegate = null;
  162 + }
  163 +
  164 + @Override
  165 + public String toString() {
  166 + return new StringBuilder().append(this.getClass().getSimpleName()).append("[").append(_signal).append(",")
  167 + .append(_id).append(",").append(_cstate).append(",").append(_x_Join_Type).append(",").append(_x_Join_Force)
  168 + .append(",").append(_x_Join_Direction).append("]").toString();
  169 + }
  170 +
  171 + @Override
  172 + public String getRemoteParticipantID() {
  173 + return joinee.getUser();
  174 + }
  175 +
  176 + @Override
  177 + public int hashCode() {
  178 + final int prime = 31;
  179 + int result = 1;
  180 + result = prime * result + ((joinee.getUser() == null) ? 0 : joinee.getUser().hashCode());
  181 + return result;
  182 + }
  183 +
  184 + @Override
  185 + public boolean equals(Object obj) {
  186 + if (this == obj)
  187 + return true;
  188 + if (obj == null)
  189 + return false;
  190 + if (getClass() != obj.getClass() && !(obj instanceof RemoteParticipant))
  191 + return false;
  192 + if (obj instanceof RemoteParticipantImpl) {
  193 + RemoteParticipantImpl other = (RemoteParticipantImpl) obj;
  194 + if (this.getJoinee().getUser().equalsIgnoreCase(other.getId())) {
  195 + return true;
  196 + }
  197 + else {
  198 + return false;
  199 + }
  200 + }
  201 + else {
  202 + RemoteJoinIncomingCall other = (RemoteJoinIncomingCall) obj;
  203 + if (_id == null) {
  204 + if (other.getId() != null)
  205 + return false;
  206 + }
  207 + else if (!_id.equals(other.getId()))
  208 + return false;
  209 + return true;
  210 + }
  211 + }
  212 +}
18 moho-impl/src/main/java/com/voxeo/moho/sip/JoinDelegate.java
@@ -42,6 +42,7 @@
42 42 import com.voxeo.moho.event.CallCompleteEvent;
43 43 import com.voxeo.moho.event.JoinCompleteEvent;
44 44 import com.voxeo.moho.event.JoinCompleteEvent.Cause;
  45 +import com.voxeo.moho.remotejoin.RemoteParticipant;
45 46
46 47 public abstract class JoinDelegate {
47 48
@@ -82,13 +83,26 @@ public synchronized void done(final Cause cause, Exception exception) {
82 83 _exception = exception;
83 84
84 85 _call1.joinDone(_call2, this);
85   - JoinCompleteEvent joinCompleteEvent = new MohoJoinCompleteEvent(_call1, _call2, cause, exception,
  86 +
  87 + //for remote join
  88 + Participant p1 = _call1;
  89 + if (_call1 instanceof RemoteParticipant) {
  90 + p1 = _call1.getApplicationContext().getParticipant(((RemoteParticipant) _call1).getRemoteParticipantID());
  91 + }
  92 + //for remote join
  93 + Participant p2 = _call2;
  94 + if (_call2 != null && _call2 instanceof RemoteParticipant) {
  95 + p2 = _call2.getApplicationContext().getParticipant(((RemoteParticipant) _call2).getRemoteParticipantID());
  96 + }
  97 +
  98 + JoinCompleteEvent joinCompleteEvent = new MohoJoinCompleteEvent(p1, p2, cause, exception,
86 99 _call2 == null ? true : _peer.equals(_call2));
87 100 _call1.dispatch(joinCompleteEvent);
88 101
89 102 if (_call2 != null) {
90 103 _call2.joinDone(_call1, this);
91   - JoinCompleteEvent peerJoinCompleteEvent = new MohoJoinCompleteEvent(_call2, _call1, cause, exception, !_peer.equals(_call2));
  104 + JoinCompleteEvent peerJoinCompleteEvent = new MohoJoinCompleteEvent(p2, p1, cause, exception,
  105 + !_peer.equals(_call2));
92 106 _call2.dispatch(peerJoinCompleteEvent);
93 107 }
94 108
46 moho-impl/src/main/java/com/voxeo/moho/sip/RemoteParticipantImpl.java
@@ -28,6 +28,8 @@
28 28 import com.voxeo.moho.event.Observer;
29 29 import com.voxeo.moho.event.UnjoinCompleteEvent;
30 30 import com.voxeo.moho.remote.RemoteEndpointImpl;
  31 +import com.voxeo.moho.remote.sipbased.RemoteJoinIncomingCall;
  32 +import com.voxeo.moho.remote.sipbased.RemoteJoinOutgoingCall;
31 33 import com.voxeo.moho.remotejoin.RemoteParticipant;
32 34
33 35 public class RemoteParticipantImpl implements RemoteParticipant, ParticipantContainer {
@@ -363,15 +365,45 @@ public boolean equals(Object obj) {
363 365 return true;
364 366 if (obj == null)
365 367 return false;
366   - if (getClass() != obj.getClass())
  368 + if (getClass() != obj.getClass() && !(obj instanceof RemoteParticipant))
367 369 return false;
368   - RemoteParticipantImpl other = (RemoteParticipantImpl) obj;
369   - if (_id == null) {
370   - if (other._id != null)
  370 + if (obj instanceof RemoteJoinOutgoingCall) {
  371 + RemoteJoinOutgoingCall other = (RemoteJoinOutgoingCall) obj;
  372 + if (other.getJoinee().getUser().equalsIgnoreCase(_id)) {
  373 + return true;
  374 + }
  375 + else {
371 376 return false;
  377 + }
372 378 }
373   - else if (!_id.equals(other._id))
374   - return false;
375   - return true;
  379 + else if (obj instanceof RemoteJoinIncomingCall) {
  380 + RemoteJoinIncomingCall other = (RemoteJoinIncomingCall) obj;
  381 + if (other.getJoiner().getUser().equalsIgnoreCase(_id)) {
  382 + return true;
  383 + }
  384 + else {
  385 + return false;
  386 + }
  387 + }
  388 + else {
  389 + RemoteParticipantImpl other = (RemoteParticipantImpl) obj;
  390 + if (_id == null) {
  391 + if (other._id != null)
  392 + return false;
  393 + }
  394 + else if (!_id.equals(other._id))
  395 + return false;
  396 + return true;
  397 + }
  398 + }
  399 +
  400 + @Override
  401 + public String getRemoteParticipantID() {
  402 + return _id;
  403 + }
  404 +
  405 + @Override
  406 + public String toString() {
  407 + return "RemoteParticipantImpl [_id=" + _id + "]";
376 408 }
377 409 }
94 moho-impl/src/main/java/com/voxeo/moho/sip/SIPCallImpl.java
@@ -71,8 +71,10 @@
71 71 import com.voxeo.moho.event.JoinCompleteEvent.Cause;
72 72 import com.voxeo.moho.event.UnjoinCompleteEvent;
73 73 import com.voxeo.moho.media.GenericMediaService;
  74 +import com.voxeo.moho.remote.sipbased.RemoteJoinOutgoingCall;
74 75 import com.voxeo.moho.remotejoin.RemoteParticipant;
75 76 import com.voxeo.moho.spi.ExecutionContext;
  77 +import com.voxeo.moho.util.ParticipantIDParser;
76 78 import com.voxeo.moho.util.SessionUtils;
77 79
78 80 public abstract class SIPCallImpl extends CallImpl implements SIPCall, MediaEventListener<SdpPortManagerEvent>,
@@ -187,7 +189,7 @@ public boolean equals(final Object o) {
187 189
188 190 @Override
189 191 public String toString() {
190   - return new StringBuilder().append(SIPCallImpl.class.getSimpleName()).append("[").append(_signal).append(",")
  192 + return new StringBuilder().append(this.getClass().getSimpleName()).append("[").append(_signal).append(", ").append(_id).append(", ")
191 193 .append(_cstate).append("]").toString();
192 194 }
193 195
@@ -376,43 +378,56 @@ public synchronized MohoUnjoinCompleteEvent doUnjoin(final Participant p, boolea
376 378 SIPCallImpl.this.dispatch(event);
377 379 return event;
378 380 }
  381 + Participant participant = p;
  382 + Participant local = this;
  383 +
379 384 try {
380 385 JoinData joinData = _joinees.remove(p);
381   - if (p instanceof Call) {
  386 +
  387 + Participant other = joinData.getParticipant();
  388 +
  389 + if (other instanceof Call) {
382 390 synchronized (_peers) {
383   - _peers.remove(p);
  391 + _peers.remove(other);
384 392 }
385 393 }
386   - if (p.getMediaObject() instanceof Joinable) {
  394 + if (other.getMediaObject() instanceof Joinable) {
387 395 if (initiator) {
388 396 if (joinData.getRealJoined() == null) {
389   - JoinDelegate.bridgeUnjoin(this, p);
  397 + JoinDelegate.bridgeUnjoin(this, other);
390 398 }
391 399 else {
392   - JoinDelegate.bridgeUnjoin(joinData.getRealJoined(), p);
  400 + JoinDelegate.bridgeUnjoin(joinData.getRealJoined(), other);
393 401 }
394 402 }
395 403 }
396 404
397 405 if (initiator) {
398   - ((ParticipantContainer) p).unjoin(SIPCallImpl.this, false);
  406 + ((ParticipantContainer) other).unjoin(SIPCallImpl.this, false);
  407 + }
  408 +
  409 + //for remote unjoin
  410 + if( p instanceof RemoteParticipant){
  411 + participant = this.getApplicationContext().getParticipant(((RemoteParticipant) p).getRemoteParticipantID());
  412 + }
  413 + if(this instanceof RemoteParticipant){
  414 + local = this.getApplicationContext().getParticipant(((RemoteParticipant) this).getRemoteParticipantID());
399 415 }
400 416
401   - event = new MohoUnjoinCompleteEvent(SIPCallImpl.this, p, UnjoinCompleteEvent.Cause.SUCCESS_UNJOIN, initiator);
  417 + event = new MohoUnjoinCompleteEvent(local, participant, UnjoinCompleteEvent.Cause.SUCCESS_UNJOIN, initiator);
402 418 }
403 419 catch (final Exception e) {
404 420 LOG.error("", e);
405   - event = new MohoUnjoinCompleteEvent(SIPCallImpl.this, p, UnjoinCompleteEvent.Cause.FAIL_UNJOIN, e, true);
  421 + event = new MohoUnjoinCompleteEvent(local, participant, UnjoinCompleteEvent.Cause.FAIL_UNJOIN, e, true);
406 422 throw e;
407 423 }
408 424 finally {
409 425 if (event == null) {
410   - event = new MohoUnjoinCompleteEvent(SIPCallImpl.this, p, UnjoinCompleteEvent.Cause.FAIL_UNJOIN, initiator);
  426 + event = new MohoUnjoinCompleteEvent(local, participant, UnjoinCompleteEvent.Cause.FAIL_UNJOIN, initiator);
411 427 }
412 428 SIPCallImpl.this.dispatch(event);
413 429 }
414 430 return event;
415   -
416 431 }
417 432
418 433 @Override
@@ -586,7 +601,7 @@ else if (other instanceof RemoteParticipant) {
586 601 return doJoin((SIPCallImpl) other, type, force, direction);
587 602 }
588 603 else if (other instanceof RemoteParticipant) {
589   - return doJoin((RemoteParticipant) other, type, direction);
  604 + return doJoin((RemoteParticipant) other, type, force, direction);
590 605 }
591 606 else {
592 607 return doJoin(other, type, false, direction);
@@ -1100,22 +1115,47 @@ protected Joint doJoin(final SIPCallImpl other, final JoinType type, final boole
1100 1115 return joint;
1101 1116 }
1102 1117
1103   - protected Joint doJoin(final RemoteParticipant other, final JoinType type, final Direction direction)
  1118 + //RMI based.
  1119 + // protected Joint doJoin(final RemoteParticipant other, final JoinType type,
  1120 + // final Direction direction)
  1121 + // throws Exception {
  1122 + // JoinDelegate joinDelegate = null;
  1123 + // if (type != JoinType.DIRECT) {
  1124 + // joinDelegate = new LocalRemoteJoinDelegate(this, other, direction);
  1125 + // }
  1126 + // else {
  1127 + // joinDelegate = new DirectLocalRemoteJoinDelegate(this, other, direction);
  1128 + // }
  1129 + //
  1130 + // SettableJointImpl joint = new SettableJointImpl();
  1131 + // joinDelegate.setSettableJoint(joint);
  1132 + //
  1133 + // joinDelegate.doJoin();
  1134 + //
  1135 + // return joint;
  1136 + // }
  1137 +
  1138 + protected Joint doJoin(final RemoteParticipant other, final JoinType type, boolean force, final Direction direction)
1104 1139 throws Exception {
1105   - JoinDelegate joinDelegate = null;
1106   - if (type != JoinType.DIRECT) {
1107   - joinDelegate = new LocalRemoteJoinDelegate(this, other, direction);
1108   - }
1109   - else {
1110   - joinDelegate = new DirectLocalRemoteJoinDelegate(this, other, direction);
1111   - }
1112   -
1113   - SettableJointImpl joint = new SettableJointImpl();
1114   - joinDelegate.setSettableJoint(joint);
1115   -
1116   - joinDelegate.doJoin();
1117   -
1118   - return joint;
  1140 + // 1 create outgoing call.
  1141 + // 2 join the outgoing call and return joint.
  1142 + String[] parsedJoinerID = ParticipantIDParser.parseEncodedId(this.getId());
  1143 + String[] parsedJoineeID = ParticipantIDParser.parseEncodedId(other.getId());
  1144 +
  1145 + SIPEndpoint joinerEndpoint = (SIPEndpoint) this.getApplicationContext().createEndpoint(
  1146 + "sip:" + this.getId() + "@" + parsedJoinerID[0]);
  1147 + SIPEndpoint joineeEndpoint = (SIPEndpoint) this.getApplicationContext().createEndpoint(
  1148 + "sip:" + other.getId() + "@" + parsedJoineeID[0]);
  1149 +
  1150 +
  1151 + RemoteJoinOutgoingCall outgoingCall = new RemoteJoinOutgoingCall((ExecutionContext) this.getApplicationContext(),
  1152 + joinerEndpoint, joineeEndpoint, null);
  1153 + outgoingCall.setX_Join_Direction(direction);
  1154 + outgoingCall.setX_Join_Force(force);
  1155 + outgoingCall.setX_Join_Type(type);
  1156 + LOG.debug("Starting remotejoin. joiner:"+this+". joinee:"+other.getId()+". created RemoteJoinOutgoingCall:"+outgoingCall);
  1157 + _operationInProcess = false;
  1158 + return this.join(outgoingCall, type, force, direction);
1119 1159 }
1120 1160
1121 1161 protected Joint doJoin(final Participant other, final JoinType type, final boolean force, final Direction direction)
45 moho-impl/src/main/java/com/voxeo/moho/sip/SIPDriverImpl.java
@@ -34,11 +34,16 @@
34 34 import com.voxeo.moho.Endpoint;
35 35 import com.voxeo.moho.Framework;
36 36 import com.voxeo.moho.IncomingCall;
  37 +import com.voxeo.moho.Participant;
  38 +import com.voxeo.moho.State;
37 39 import com.voxeo.moho.Subscription;
38 40 import com.voxeo.moho.common.event.MohoInputDetectedEvent;
39 41 import com.voxeo.moho.event.CallEvent;
40 42 import com.voxeo.moho.event.EventSource;
  43 +import com.voxeo.moho.event.JoinCompleteEvent;
  44 +import com.voxeo.moho.event.JoinCompleteEvent.Cause;
41 45 import com.voxeo.moho.event.NotifyEvent;
  46 +import com.voxeo.moho.event.Observer;
42 47 import com.voxeo.moho.event.PublishEvent;
43 48 import com.voxeo.moho.event.RegisterEvent;
44 49 import com.voxeo.moho.event.RequestEvent;
@@ -46,6 +51,8 @@
46 51 import com.voxeo.moho.event.TextEvent;
47 52 import com.voxeo.moho.event.UnknownRequestEvent;
48 53 import com.voxeo.moho.reg.Registration;
  54 +import com.voxeo.moho.remote.sipbased.Constants;
  55 +import com.voxeo.moho.remote.sipbased.RemoteJoinIncomingCall;
49 56 import com.voxeo.moho.spi.ExecutionContext;
50 57 import com.voxeo.moho.spi.SIPDriver;
51 58 import com.voxeo.moho.spi.SpiFramework;
@@ -78,7 +85,7 @@ public void init(SpiFramework framework) {
78 85
79 86 @Override
80 87 public void destroy() {
81   -
  88 +
82 89 }
83 90
84 91 @Override
@@ -133,10 +140,40 @@ else if ("PRACK".equals(s)) {
133 140
134 141 protected void doInvite(final SipServletRequest req) throws ServletException, IOException {
135 142 if (req.isInitial()) {
136   - final IncomingCall ev = _app.getApplicationContext().getService(IncomingCallFactory.class)
137   - .createIncomingCall(req);
  143 + // process remote join
  144 + if (req.getHeader(Constants.x_Join_Direction) != null && req.getHeader(Constants.x_Join_Direction).trim() != "") {
  145 + RemoteJoinIncomingCall joinCall = new RemoteJoinIncomingCall((ExecutionContext) this.getFramework()
  146 + .getApplicationContext(), req);
  147 + SipURI joineeURI = joinCall.getJoinee();
  148 + Participant participant = this.getFramework().getApplicationContext().getParticipant(joineeURI.getUser());
  149 +
  150 + joinCall.addObserver(new Observer() {
  151 + @State
  152 + public void handleJoinComplete(JoinCompleteEvent event) {
  153 + if (event.getCause() == Cause.BUSY) {
  154 + LOG.warn("Join Policy violated when processing incoming remotejoin.");
  155 + try {
  156 + req.createResponse(SipServletResponse.SC_BUSY_HERE,
  157 + event.getException() != null ? event.getException().getMessage() : "").send();
  158 + }
  159 + catch (Exception ex) {
  160 + LOG.warn("Exception when sending back remotejoin response.", ex);
  161 + }
  162 + }
  163 + }
  164 + });
  165 +
  166 + LOG.debug("Received remotejoin, joining. joiner:" + joinCall.getJoiner().getUser() + ". joinee:"
  167 + + joinCall.getJoinee().getUser() + ". created RemoteJoinIncomingCall:" + joinCall);
  168 + joinCall.join(participant, joinCall.getX_Join_Type(), joinCall.getX_Join_Force(),
  169 + joinCall.getX_Join_Direction());
  170 + }
  171 + else {
  172 + final IncomingCall ev = _app.getApplicationContext().getService(IncomingCallFactory.class)
  173 + .createIncomingCall(req);
138 174
139   - _app.dispatch(ev);
  175 + _app.dispatch(ev);
  176 + }
140 177 }
141 178 else {
142 179 final EventSource source = SessionUtils.getEventSource(req);

0 comments on commit e2e491d

Please sign in to comment.
Something went wrong with that request. Please try again.