mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-27 00:32:07 +01:00
Payload Negotiation Refactoring and bug fixes
git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@7362 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
parent
945561242a
commit
76bd42da26
7 changed files with 109 additions and 61 deletions
|
@ -43,11 +43,6 @@ public abstract class JingleMediaManager {
|
||||||
*/
|
*/
|
||||||
public abstract List<PayloadType> getPayloads();
|
public abstract List<PayloadType> getPayloads();
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the preferred Payload Type
|
|
||||||
*/
|
|
||||||
public abstract PayloadType getPreferredPayloadType();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a Media Session Implementation
|
* Create a Media Session Implementation
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,3 +1,22 @@
|
||||||
|
/**
|
||||||
|
* $RCSfile$
|
||||||
|
* $Revision: 7329 $
|
||||||
|
* $Date: 2007-02-28 20:59:28 -0300 (qua, 28 fev 2007) $
|
||||||
|
*
|
||||||
|
* Copyright 2003-2005 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. 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 org.jivesoftware.smackx.jingle.media;
|
package org.jivesoftware.smackx.jingle.media;
|
||||||
|
|
||||||
import org.jivesoftware.smack.XMPPException;
|
import org.jivesoftware.smack.XMPPException;
|
||||||
|
@ -17,12 +36,13 @@ import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manager for jmf descriptor negotiation.
|
* Manager for jmf descriptor negotiation.
|
||||||
*
|
* <p/>
|
||||||
*
|
* <p/>
|
||||||
* This class is responsible for managing the descriptor negotiation process,
|
* This class is responsible for managing the descriptor negotiation process,
|
||||||
* handling all the xmpp packets interchange and the stage control.
|
* handling all the xmpp packets interchange and the stage control.
|
||||||
*
|
*
|
||||||
* @author Alvaro Saurin
|
* @author Alvaro Saurin
|
||||||
|
* @author Thiago Camargo
|
||||||
*/
|
*/
|
||||||
public class MediaNegotiator extends JingleNegotiator {
|
public class MediaNegotiator extends JingleNegotiator {
|
||||||
|
|
||||||
|
@ -90,31 +110,37 @@ public class MediaNegotiator extends JingleNegotiator {
|
||||||
// With a null packet, we are just inviting the other end...
|
// With a null packet, we are just inviting the other end...
|
||||||
setState(inviting);
|
setState(inviting);
|
||||||
jout = getState().eventInvite();
|
jout = getState().eventInvite();
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (iq instanceof Jingle) {
|
if (iq instanceof Jingle) {
|
||||||
// If there is no specific jmf action associated, then we
|
// If there is no specific jmf action associated, then we
|
||||||
// are being invited to a new session...
|
// are being invited to a new session...
|
||||||
setState(accepting);
|
setState(accepting);
|
||||||
jout = getState().eventInitiate((Jingle) iq);
|
jout = getState().eventInitiate((Jingle) iq);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Invitation IQ received is not a Jingle packet in Media negotiator.");
|
"Invitation IQ received is not a Jingle packet in Media negotiator.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (iq == null) {
|
if (iq == null) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (iq.getType().equals(IQ.Type.ERROR)) {
|
if (iq.getType().equals(IQ.Type.ERROR)) {
|
||||||
// Process errors
|
// Process errors
|
||||||
getState().eventError(iq);
|
getState().eventError(iq);
|
||||||
} else if (iq.getType().equals(IQ.Type.RESULT)) {
|
}
|
||||||
|
else if (iq.getType().equals(IQ.Type.RESULT)) {
|
||||||
// Process ACKs
|
// Process ACKs
|
||||||
if (isExpectedId(iq.getPacketID())) {
|
if (isExpectedId(iq.getPacketID())) {
|
||||||
jout = getState().eventAck(iq);
|
jout = getState().eventAck(iq);
|
||||||
removeExpectedId(iq.getPacketID());
|
removeExpectedId(iq.getPacketID());
|
||||||
}
|
}
|
||||||
} else if (iq instanceof Jingle) {
|
}
|
||||||
|
else if (iq instanceof Jingle) {
|
||||||
// Get the action from the Jingle packet
|
// Get the action from the Jingle packet
|
||||||
Jingle jin = (Jingle) iq;
|
Jingle jin = (Jingle) iq;
|
||||||
Jingle.Action action = jin.getAction();
|
Jingle.Action action = jin.getAction();
|
||||||
|
@ -122,11 +148,14 @@ public class MediaNegotiator extends JingleNegotiator {
|
||||||
if (action != null) {
|
if (action != null) {
|
||||||
if (action.equals(Jingle.Action.CONTENTACCEPT)) {
|
if (action.equals(Jingle.Action.CONTENTACCEPT)) {
|
||||||
jout = getState().eventAccept(jin);
|
jout = getState().eventAccept(jin);
|
||||||
} else if (action.equals(Jingle.Action.CONTENTDECLINE)) {
|
}
|
||||||
|
else if (action.equals(Jingle.Action.CONTENTDECLINE)) {
|
||||||
jout = getState().eventDecline(jin);
|
jout = getState().eventDecline(jin);
|
||||||
} else if (action.equals(Jingle.Action.DESCRIPTIONINFO)) {
|
}
|
||||||
|
else if (action.equals(Jingle.Action.DESCRIPTIONINFO)) {
|
||||||
jout = getState().eventInfo(jin);
|
jout = getState().eventInfo(jin);
|
||||||
} else if (action.equals(Jingle.Action.CONTENTMODIFY)) {
|
}
|
||||||
|
else if (action.equals(Jingle.Action.CONTENTMODIFY)) {
|
||||||
jout = getState().eventModify(jin);
|
jout = getState().eventModify(jin);
|
||||||
}
|
}
|
||||||
// Any unknown action will be ignored: it is not a msg
|
// Any unknown action will be ignored: it is not a msg
|
||||||
|
@ -139,7 +168,8 @@ public class MediaNegotiator extends JingleNegotiator {
|
||||||
// Save the Id for any ACK
|
// Save the Id for any ACK
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
addExpectedId(id);
|
addExpectedId(id);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (jout != null) {
|
if (jout != null) {
|
||||||
addExpectedId(jout.getPacketID());
|
addExpectedId(jout.getPacketID());
|
||||||
}
|
}
|
||||||
|
@ -169,8 +199,8 @@ public class MediaNegotiator extends JingleNegotiator {
|
||||||
// Payload types
|
// Payload types
|
||||||
|
|
||||||
private PayloadType.Audio calculateBestCommonAudioPt(List remoteAudioPts) {
|
private PayloadType.Audio calculateBestCommonAudioPt(List remoteAudioPts) {
|
||||||
final ArrayList commonAudioPtsHere = new ArrayList();
|
final ArrayList<PayloadType> commonAudioPtsHere = new ArrayList<PayloadType>();
|
||||||
final ArrayList commonAudioPtsThere = new ArrayList();
|
final ArrayList<PayloadType> commonAudioPtsThere = new ArrayList<PayloadType>();
|
||||||
PayloadType.Audio result = null;
|
PayloadType.Audio result = null;
|
||||||
|
|
||||||
if (!remoteAudioPts.isEmpty()) {
|
if (!remoteAudioPts.isEmpty()) {
|
||||||
|
@ -181,26 +211,28 @@ public class MediaNegotiator extends JingleNegotiator {
|
||||||
commonAudioPtsThere.retainAll(localAudioPts);
|
commonAudioPtsThere.retainAll(localAudioPts);
|
||||||
|
|
||||||
if (!commonAudioPtsHere.isEmpty() && !commonAudioPtsThere.isEmpty()) {
|
if (!commonAudioPtsHere.isEmpty() && !commonAudioPtsThere.isEmpty()) {
|
||||||
PayloadType.Audio bestPtHere = (PayloadType.Audio) commonAudioPtsHere
|
|
||||||
.get(0);
|
|
||||||
PayloadType.Audio bestPtThere = (PayloadType.Audio) commonAudioPtsThere
|
|
||||||
.get(0);
|
|
||||||
|
|
||||||
// If both match, use it
|
PayloadType.Audio bestPtHere = null;
|
||||||
if (bestPtHere.equals(bestPtThere)) {
|
|
||||||
result = bestPtHere;
|
|
||||||
} else {
|
|
||||||
// Otherwise, use the one of the initiator...
|
|
||||||
// FIXME: this is an invented behavior!!!
|
|
||||||
String initiator = session.getInitiator();
|
|
||||||
String me = session.getConnection().getUser();
|
|
||||||
|
|
||||||
if (initiator.equals(me)) {
|
if (bestPtHere == null)
|
||||||
result = bestPtHere;
|
for (PayloadType payloadType : commonAudioPtsHere)
|
||||||
} else {
|
if (payloadType instanceof PayloadType.Audio) {
|
||||||
result = bestPtThere;
|
bestPtHere = (PayloadType.Audio) payloadType;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
PayloadType.Audio bestPtThere = null;
|
||||||
|
for (PayloadType payloadType : commonAudioPtsThere)
|
||||||
|
if (payloadType instanceof PayloadType.Audio) {
|
||||||
|
bestPtThere = (PayloadType.Audio) payloadType;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if (session.getInitiator().equals(session.getConnection().getUser()))
|
||||||
|
result = bestPtHere;
|
||||||
|
else
|
||||||
|
result = bestPtThere;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,6 +364,7 @@ public class MediaNegotiator extends JingleNegotiator {
|
||||||
* First stage when we send a session request.
|
* First stage when we send a session request.
|
||||||
*/
|
*/
|
||||||
public class Inviting extends JingleNegotiator.State {
|
public class Inviting extends JingleNegotiator.State {
|
||||||
|
|
||||||
public Inviting(MediaNegotiator neg) {
|
public Inviting(MediaNegotiator neg) {
|
||||||
super(neg);
|
super(neg);
|
||||||
}
|
}
|
||||||
|
@ -391,7 +424,8 @@ public class MediaNegotiator extends JingleNegotiator {
|
||||||
// and send an accept if we havee an agreement...
|
// and send an accept if we havee an agreement...
|
||||||
if (bestCommonAudioPt != null) {
|
if (bestCommonAudioPt != null) {
|
||||||
response = createAcceptMessage();
|
response = createAcceptMessage();
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
throw new JingleException(JingleError.NO_COMMON_PAYLOAD);
|
throw new JingleException(JingleError.NO_COMMON_PAYLOAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,6 +441,7 @@ public class MediaNegotiator extends JingleNegotiator {
|
||||||
* accepts or not...
|
* accepts or not...
|
||||||
*/
|
*/
|
||||||
public class Pending extends JingleNegotiator.State {
|
public class Pending extends JingleNegotiator.State {
|
||||||
|
|
||||||
public Pending(MediaNegotiator neg) {
|
public Pending(MediaNegotiator neg) {
|
||||||
super(neg);
|
super(neg);
|
||||||
}
|
}
|
||||||
|
@ -441,7 +476,8 @@ public class MediaNegotiator extends JingleNegotiator {
|
||||||
if (oldBestCommonAudioPt == null || ptChange) {
|
if (oldBestCommonAudioPt == null || ptChange) {
|
||||||
response = createAcceptMessage();
|
response = createAcceptMessage();
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
throw new JingleException(JingleError.NO_COMMON_PAYLOAD);
|
throw new JingleException(JingleError.NO_COMMON_PAYLOAD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -481,7 +517,8 @@ public class MediaNegotiator extends JingleNegotiator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (offeredPayloads.size() > 1) {
|
}
|
||||||
|
else if (offeredPayloads.size() > 1) {
|
||||||
throw new JingleException(JingleError.MALFORMED_STANZA);
|
throw new JingleException(JingleError.MALFORMED_STANZA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,23 @@
|
||||||
|
/**
|
||||||
|
* $RCSfile$
|
||||||
|
* $Revision: 7329 $
|
||||||
|
* $Date: 2007-02-28 20:59:28 -0300 (qua, 28 fev 2007) $
|
||||||
|
*
|
||||||
|
* Copyright 2003-2005 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. 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 org.jivesoftware.smackx.packet;
|
package org.jivesoftware.smackx.packet;
|
||||||
|
|
||||||
import org.jivesoftware.smack.packet.PacketExtension;
|
import org.jivesoftware.smack.packet.PacketExtension;
|
||||||
|
@ -19,7 +39,7 @@ public class JingleError implements PacketExtension {
|
||||||
// Non standard error messages
|
// Non standard error messages
|
||||||
|
|
||||||
public static final JingleError NO_COMMON_PAYLOAD = new JingleError(
|
public static final JingleError NO_COMMON_PAYLOAD = new JingleError(
|
||||||
"no-common-payload");
|
"unsupported-codecs");
|
||||||
|
|
||||||
public static final JingleError NEGOTIATION_ERROR = new JingleError(
|
public static final JingleError NEGOTIATION_ERROR = new JingleError(
|
||||||
"negotiation-error");
|
"negotiation-error");
|
||||||
|
@ -76,7 +96,7 @@ public class JingleError implements PacketExtension {
|
||||||
return UNSUPPORTED_CONTENT;
|
return UNSUPPORTED_CONTENT;
|
||||||
} else if (value.equals("unsupported-transports")) {
|
} else if (value.equals("unsupported-transports")) {
|
||||||
return UNSUPPORTED_TRANSPORTS;
|
return UNSUPPORTED_TRANSPORTS;
|
||||||
} else if (value.equals("no-common-payload")) {
|
} else if (value.equals("unsupported-codecs")) {
|
||||||
return NO_COMMON_PAYLOAD;
|
return NO_COMMON_PAYLOAD;
|
||||||
} else if (value.equals("negotiation-error")) {
|
} else if (value.equals("negotiation-error")) {
|
||||||
return NEGOTIATION_ERROR;
|
return NEGOTIATION_ERROR;
|
||||||
|
|
|
@ -849,7 +849,7 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
return new ArrayList();
|
return new ArrayList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PayloadType getPreferredPayloadType() {
|
public PayloadType.Audio getPreferredAudioPayloadType() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,15 +78,7 @@ public class JmfMediaManager extends JingleMediaManager {
|
||||||
public List<PayloadType> getPayloads() {
|
public List<PayloadType> getPayloads() {
|
||||||
return payloads;
|
return payloads;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the preferred Payload Type
|
|
||||||
*/
|
|
||||||
public PayloadType getPreferredPayloadType() {
|
|
||||||
//TODO a better way to choose the preferred Payload
|
|
||||||
return payloads.size() > 0 ? payloads.get(0) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs JMFInit the first time the application is started so that capture
|
* Runs JMFInit the first time the application is started so that capture
|
||||||
* devices are properly detected and initialized by JMF.
|
* devices are properly detected and initialized by JMF.
|
||||||
|
|
|
@ -65,14 +65,7 @@ public class SpeexMediaManager extends JingleMediaManager {
|
||||||
public List<PayloadType> getPayloads() {
|
public List<PayloadType> getPayloads() {
|
||||||
return payloads;
|
return payloads;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the preferred Payload Type
|
|
||||||
*/
|
|
||||||
public PayloadType getPreferredPayloadType() {
|
|
||||||
return payloads.size() > 0 ? payloads.get(0) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs JMFInit the first time the application is started so that capture
|
* Runs JMFInit the first time the application is started so that capture
|
||||||
* devices are properly detected and initialized by JMF.
|
* devices are properly detected and initialized by JMF.
|
||||||
|
|
|
@ -15,6 +15,7 @@ import org.jivesoftware.smackx.jingle.media.JingleMediaManager;
|
||||||
import org.jivesoftware.smackx.jingle.nat.BridgedTransportManager;
|
import org.jivesoftware.smackx.jingle.nat.BridgedTransportManager;
|
||||||
import org.jivesoftware.smackx.jingle.nat.ICETransportManager;
|
import org.jivesoftware.smackx.jingle.nat.ICETransportManager;
|
||||||
import org.jivesoftware.smackx.jingle.nat.STUNTransportManager;
|
import org.jivesoftware.smackx.jingle.nat.STUNTransportManager;
|
||||||
|
import org.jivesoftware.smackx.jingle.nat.BasicTransportManager;
|
||||||
|
|
||||||
import javax.media.MediaLocator;
|
import javax.media.MediaLocator;
|
||||||
import javax.media.format.AudioFormat;
|
import javax.media.format.AudioFormat;
|
||||||
|
@ -109,6 +110,7 @@ public class JingleMediaTest extends SmackTestCase {
|
||||||
XMPPConnection x0 = getConnection(0);
|
XMPPConnection x0 = getConnection(0);
|
||||||
XMPPConnection x1 = getConnection(1);
|
XMPPConnection x1 = getConnection(1);
|
||||||
|
|
||||||
|
/*
|
||||||
ICETransportManager icetm0 = new ICETransportManager(x0, "jivesoftware.com", 3478);
|
ICETransportManager icetm0 = new ICETransportManager(x0, "jivesoftware.com", 3478);
|
||||||
ICETransportManager icetm1 = new ICETransportManager(x1, "jivesoftware.com", 3478);
|
ICETransportManager icetm1 = new ICETransportManager(x1, "jivesoftware.com", 3478);
|
||||||
|
|
||||||
|
@ -119,11 +121,20 @@ public class JingleMediaTest extends SmackTestCase {
|
||||||
|
|
||||||
jm0.addCreationListener(icetm0);
|
jm0.addCreationListener(icetm0);
|
||||||
jm1.addCreationListener(icetm1);
|
jm1.addCreationListener(icetm1);
|
||||||
|
*/
|
||||||
|
|
||||||
|
final JingleManager jm0 = new JingleManager(
|
||||||
|
x0, new BasicTransportManager());
|
||||||
|
final JingleManager jm1 = new JingleManager(
|
||||||
|
x1, new BasicTransportManager());
|
||||||
|
|
||||||
MultiMediaManager jingleMediaManager0 = new MultiMediaManager();
|
MultiMediaManager jingleMediaManager0 = new MultiMediaManager();
|
||||||
jingleMediaManager0.addMediaManager(new SpeexMediaManager());
|
jingleMediaManager0.addMediaManager(new SpeexMediaManager());
|
||||||
jingleMediaManager0.addMediaManager(new JmfMediaManager());
|
jingleMediaManager0.addMediaManager(new JmfMediaManager());
|
||||||
JingleMediaManager jingleMediaManager1 = new JmfMediaManager();
|
jingleMediaManager0.addMediaManager(new JmfMediaManager());
|
||||||
|
MultiMediaManager jingleMediaManager1 = new MultiMediaManager();
|
||||||
|
jingleMediaManager1.addMediaManager(new JmfMediaManager());
|
||||||
|
jingleMediaManager1.addMediaManager(new SpeexMediaManager());
|
||||||
|
|
||||||
jm0.setMediaManager(jingleMediaManager0);
|
jm0.setMediaManager(jingleMediaManager0);
|
||||||
jm1.setMediaManager(jingleMediaManager1);
|
jm1.setMediaManager(jingleMediaManager1);
|
||||||
|
|
Loading…
Reference in a new issue