diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetTelephonyConferencingJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetTelephonyConferencingJabberImpl.java
index 2c8922489..8ee101de9 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetTelephonyConferencingJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetTelephonyConferencingJabberImpl.java
@@ -54,12 +54,6 @@ public class OperationSetTelephonyConferencingJabberImpl
*/
private final Object lock = new Object();
- /**
- * The value of the version attribute to be specified in the
- * outgoing conference-info root XML elements.
- */
- private int version = 1;
-
/**
* Initializes a new OperationSetTelephonyConferencingJabberImpl
* instance which is to provide telephony conferencing services for the
@@ -98,8 +92,6 @@ protected void notifyCallPeers(Call call)
{
notify(i.next());
}
-
- version++;
}
}
}
@@ -115,10 +107,14 @@ private void notify(CallPeer callPeer)
if(!(callPeer instanceof CallPeerJabberImpl))
return;
+ CallPeerJabberImpl callPeerJabber = (CallPeerJabberImpl)callPeer;
+
// check that callPeer supports COIN before sending him a
// conference-info
String to = getBasicTelephony().getFullCalleeURI(callPeer.getAddress());
+ // XXX if this generates actual disco#info requests we might want to
+ // cache it.
try
{
DiscoverInfo discoverInfo
@@ -136,135 +132,32 @@ private void notify(CallPeer callPeer)
logger.warn("Failed to retrieve DiscoverInfo for " + to, xmppe);
}
- IQ iq = getConferenceInfo((CallPeerJabberImpl) callPeer, version);
-
- if (iq != null)
- parentProvider.getConnection().sendPacket(iq);
- }
+ ConferenceInfoDocument currentConfInfo
+ = getCurrentConferenceInfo(callPeer);
+ ConferenceInfoDocument lastSentConfInfo
+ = callPeerJabber.getLastConferenceInfoSent();
- /**
- * Get media packet extension for the specified CallPeerJabberImpl.
- *
- * @param callPeer CallPeer
- * @param remote if the callPeer is remote or local
- * @return list of media packet extension
- */
- private List getMedia(
- MediaAwareCallPeer,?,?> callPeer,
- boolean remote)
- {
- CallPeerMediaHandler> mediaHandler = callPeer.getMediaHandler();
- List ret = new ArrayList();
- long i = 1;
+ ConferenceInfoDocument diff
+ = getConferenceInfoDiff(lastSentConfInfo, currentConfInfo);
- for(MediaType mediaType : MediaType.values())
+ if (diff != null)
{
- MediaStream stream = mediaHandler.getStream(mediaType);
-
- if (stream != null)
- {
- MediaPacketExtension ext
- = new MediaPacketExtension(Long.toString(i));
- long srcId
- = remote
- ? getRemoteSourceID(callPeer, mediaType)
- : stream.getLocalSourceID();
-
- if (srcId != -1)
- ext.setSrcID(Long.toString(srcId));
-
- ext.setType(mediaType.toString());
-
- MediaDirection direction
- = remote
- ? getRemoteDirection(callPeer, mediaType)
- : stream.getDirection();
-
- if (direction == null)
- direction = MediaDirection.INACTIVE;
-
- ext.setStatus(direction.toString());
- ret.add(ext);
- i++;
- }
- }
-
- return ret;
- }
-
- /**
- * Get user packet extension for the specified CallPeerJabberImpl.
- *
- * @param callPeer CallPeer
- * @return user packet extension
- */
- private UserPacketExtension getUser(CallPeer callPeer)
- {
- UserPacketExtension ext
- = new UserPacketExtension(callPeer.getAddress());
+ int newVersion
+ = lastSentConfInfo == null
+ ? 1
+ : lastSentConfInfo.getVersion() + 1;
+ diff.setVersion(newVersion);
- ext.setDisplayText(callPeer.getDisplayName());
-
- EndpointPacketExtension endpoint
- = new EndpointPacketExtension(callPeer.getURI());
-
- endpoint.setStatus(getEndpointStatus(callPeer));
-
- if (callPeer instanceof MediaAwareCallPeer,?,?>)
- {
- List medias
- = getMedia((MediaAwareCallPeer,?,?>) callPeer, true);
+ IQ iq = getConferenceInfo(callPeerJabber, diff);
+ parentProvider.getConnection().sendPacket(iq);
- if(medias != null)
- {
- for(MediaPacketExtension media : medias)
- endpoint.addChildExtension(media);
- }
+ // We save currentConfInfo, because it is of state "full", while
+ // diff could be a partial
+ currentConfInfo.setVersion(newVersion);
+ callPeerJabber.setLastConferenceInfoSent(currentConfInfo);
+ callPeerJabber.setLastConferenceInfoSentTimestamp(
+ System.currentTimeMillis());
}
-
- ext.addChildExtension(endpoint);
-
- return ext;
- }
-
- /**
- * Generates the text content to be put in the status XML element
- * of an endpoint XML element and which describes the state of a
- * specific CallPeer.
- *
- * @param callPeer the CallPeer which is to get its state described
- * in a status XML element of an endpoint XML element
- * @return the text content to be put in the status XML element of
- * an endpoint XML element and which describes the state of the
- * specified callPeer
- */
- private EndpointStatusType getEndpointStatus(CallPeer callPeer)
- {
- CallPeerState callPeerState = callPeer.getState();
-
- if (CallPeerState.ALERTING_REMOTE_SIDE.equals(callPeerState))
- return EndpointStatusType.alerting;
- if (CallPeerState.CONNECTING.equals(callPeerState)
- || CallPeerState
- .CONNECTING_WITH_EARLY_MEDIA.equals(callPeerState))
- return EndpointStatusType.pending;
- if (CallPeerState.DISCONNECTED.equals(callPeerState))
- return EndpointStatusType.disconnected;
- if (CallPeerState.INCOMING_CALL.equals(callPeerState))
- return EndpointStatusType.dialing_in;
- if (CallPeerState.INITIATING_CALL.equals(callPeerState))
- return EndpointStatusType.dialing_out;
-
- /*
- * he/she is neither "hearing" the conference mix nor is his/her media
- * being mixed in the conference
- */
- if (CallPeerState.ON_HOLD_LOCALLY.equals(callPeerState)
- || CallPeerState.ON_HOLD_MUTUALLY.equals(callPeerState))
- return EndpointStatusType.on_hold;
- if (CallPeerState.CONNECTED.equals(callPeerState))
- return EndpointStatusType.connected;
- return null;
}
/**
@@ -273,67 +166,37 @@ private EndpointStatusType getEndpointStatus(CallPeer callPeer)
* conference managed by the local peer.
*
* @param callPeer the CallPeer to generate conference-info XML for
- * @param version the value of the version attribute of the
- * conference-info root element of the conference-info XML to be
- * generated
+ * @param confInfo the ConferenceInformationDocument which is to be
+ * included in the IQ
* @return the conference-info IQ to be sent to the specified
* callPeer in order to notify it of the current state of the
* conference managed by the local peer
*/
- private IQ getConferenceInfo(CallPeerJabberImpl callPeer, int version)
+ private IQ getConferenceInfo(CallPeerJabberImpl callPeer,
+ final ConferenceInfoDocument confInfo)
{
String callPeerSID = callPeer.getSID();
if (callPeerSID == null)
return null;
- CoinIQ iq = new CoinIQ();
+ IQ iq = new IQ(){
+ @Override
+ public String getChildElementXML()
+ {
+ return confInfo.toString();
+ }
+ };
+
+
CallJabberImpl call = callPeer.getCall();
iq.setFrom(call.getProtocolProvider().getOurJID());
iq.setTo(callPeer.getAddress());
iq.setType(Type.SET);
- iq.setEntity(getBasicTelephony().getProtocolProvider().getOurJID());
- iq.setVersion(version);
- iq.setState(StateType.full);
- iq.setSID(callPeerSID);
-
- // conference-description
- iq.addExtension(new DescriptionPacketExtension());
-
- // conference-state
- StatePacketExtension state = new StatePacketExtension();
- List conferenceCallPeers = CallConference.getCallPeers(call);
-
- state.setUserCount(
- 1 /* the local peer/user */ + conferenceCallPeers.size());
- iq.addExtension(state);
-
- // users
- UsersPacketExtension users = new UsersPacketExtension();
-
- // user
- UserPacketExtension user
- = new UserPacketExtension("xmpp:" + parentProvider.getOurJID());
-
- // endpoint
- EndpointPacketExtension endpoint = new EndpointPacketExtension(
- "xmpp:" + parentProvider.getOurJID());
- endpoint.setStatus(EndpointStatusType.connected);
-
- // media
- List medias = getMedia(callPeer, false);
- for(MediaPacketExtension media : medias)
- endpoint.addChildExtension(media);
- user.addChildExtension(endpoint);
- users.addChildExtension(user);
- // other users
- for (CallPeer conferenceCallPeer : conferenceCallPeers)
- users.addChildExtension(getUser(conferenceCallPeer));
- iq.addExtension(users);
return iq;
}
diff --git a/src/net/java/sip/communicator/service/protocol/AbstractCallPeer.java b/src/net/java/sip/communicator/service/protocol/AbstractCallPeer.java
index a1fbf9976..7a44d2009 100644
--- a/src/net/java/sip/communicator/service/protocol/AbstractCallPeer.java
+++ b/src/net/java/sip/communicator/service/protocol/AbstractCallPeer.java
@@ -131,19 +131,6 @@ public abstract class AbstractCallPeer unmodifiableConferenceMembers;
- /**
- * The last Conference Information (RFC4575) document sent to this
- * CallPeer
- */
- private ConferenceInfoDocument lastConferenceInfoSent = null;
-
- /**
- * The time (as obtained by System.currentTimeMillis() at which
- * a Conference Information (RFC4575) document was last sent to this
- * CallPeer.
- */
- private long lastConferenceInfoSentTimestamp = -1;
-
/**
* Initializes a new AbstractCallPeer instance.
*/
diff --git a/src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetTelephonyConferencing.java b/src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetTelephonyConferencing.java
index 048f17bf8..793f61aa5 100644
--- a/src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetTelephonyConferencing.java
+++ b/src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetTelephonyConferencing.java
@@ -997,7 +997,9 @@ protected static String stripParametersFromAddress(String address)
/**
* Creates a ConferenceInfoDocument which describes the current
- * state of the conference in which callPeer participates.
+ * state of the conference in which callPeer participates. The
+ * created document contains a "full" description (as opposed to a partial
+ * description, see RFC4575).
*
* @return a ConferenceInfoDocument which describes the current
* state of the conference in which this CallPeer participates.
@@ -1165,4 +1167,13 @@ private ConferenceInfoDocument.EndpointStatusType getEndpointStatus(
return ConferenceInfoDocument.EndpointStatusType.connected;
return null;
}
+
+ //to and from need to be "full"
+ protected ConferenceInfoDocument getConferenceInfoDiff(
+ ConferenceInfoDocument from,
+ ConferenceInfoDocument to)
+ {
+ return to;
+ }
+
}
diff --git a/src/net/java/sip/communicator/service/protocol/media/MediaAwareCallPeer.java b/src/net/java/sip/communicator/service/protocol/media/MediaAwareCallPeer.java
index 36017d7ac..23bca7c33 100644
--- a/src/net/java/sip/communicator/service/protocol/media/MediaAwareCallPeer.java
+++ b/src/net/java/sip/communicator/service/protocol/media/MediaAwareCallPeer.java
@@ -33,6 +33,7 @@
*
* @author Emil Ivov
* @author Lyubomir Marinov
+ * @author Boris Grozev
*/
public abstract class MediaAwareCallPeer
,
@@ -121,11 +122,25 @@ public abstract class MediaAwareCallPeer
private final List videoPropertyChangeListeners
= new LinkedList();
+ /**
+ * Represents the last Conference Information (RFC4575) document sent to
+ * this CallPeer. This is always a document with state "full", even
+ * if the last document actually sent was a "partial"
+ */
+ private ConferenceInfoDocument lastConferenceInfoSent = null;
+
+ /**
+ * The time (as obtained by System.currentTimeMillis()) at which
+ * a Conference Information (RFC4575) document was last sent to this
+ * CallPeer.
+ */
+ private long lastConferenceInfoSentTimestamp = -1;
/**
* Creates a new call peer with address peerAddress.
*
* @param owningCall the call that contains this call peer.
*/
+
public MediaAwareCallPeer(T owningCall)
{
this.call = owningCall;
@@ -1003,4 +1018,24 @@ public void setState(CallPeerState newState, String reason, int reasonCode)
}
}
}
+
+ public ConferenceInfoDocument getLastConferenceInfoSent()
+ {
+ return lastConferenceInfoSent;
+ }
+
+ public void setLastConferenceInfoSent(ConferenceInfoDocument confInfo)
+ {
+ lastConferenceInfoSent = confInfo;
+ }
+
+ public long getLastConferenceInfoSentTimestamp()
+ {
+ return lastConferenceInfoSentTimestamp;
+ }
+
+ public void setLastConferenceInfoSentTimestamp(long newTimestamp)
+ {
+ lastConferenceInfoSentTimestamp = newTimestamp;
+ }
}