mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-17 01:32:06 +01:00
646271abac
git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@10419 b35dd754-fafc-0310-a699-88a17e54d16e
195 lines
7.3 KiB
Java
195 lines
7.3 KiB
Java
package org.jivesoftware.smackx.jingle;
|
|
|
|
import org.jivesoftware.smack.XMPPException;
|
|
import org.jivesoftware.smack.packet.IQ;
|
|
import org.jivesoftware.smackx.jingle.media.JingleMediaManager;
|
|
import org.jivesoftware.smackx.jingle.media.MediaNegotiator;
|
|
import org.jivesoftware.smackx.jingle.media.PayloadType;
|
|
import org.jivesoftware.smackx.jingle.nat.JingleTransportManager;
|
|
import org.jivesoftware.smackx.jingle.nat.TransportNegotiator;
|
|
import org.jivesoftware.smackx.jingle.nat.TransportResolver;
|
|
import org.jivesoftware.smackx.packet.Jingle;
|
|
import org.jivesoftware.smackx.packet.JingleContent;
|
|
import org.jivesoftware.smackx.packet.JingleDescription;
|
|
import org.jivesoftware.smackx.packet.JingleError;
|
|
import org.jivesoftware.smackx.packet.JingleTransport;
|
|
|
|
/**
|
|
* @author Jeff Williams
|
|
* @see JingleSessionState
|
|
*/
|
|
public class JingleSessionStateUnknown extends JingleSessionState {
|
|
private static JingleSessionStateUnknown INSTANCE = null;
|
|
|
|
protected JingleSessionStateUnknown() {
|
|
// Prevent instantiation of the class.
|
|
}
|
|
|
|
/**
|
|
* A thread-safe means of getting the one instance of this class.
|
|
* @return The singleton instance of this class.
|
|
*/
|
|
public synchronized static JingleSessionState getInstance() {
|
|
if (INSTANCE == null) {
|
|
INSTANCE = new JingleSessionStateUnknown();
|
|
}
|
|
return INSTANCE;
|
|
}
|
|
|
|
public void enter() {
|
|
// TODO Auto-generated method stub
|
|
|
|
}
|
|
|
|
public void exit() {
|
|
// TODO Auto-generated method stub
|
|
|
|
}
|
|
|
|
public IQ processJingle(JingleSession session, Jingle jingle, JingleActionEnum action) {
|
|
IQ response = null;
|
|
|
|
switch (action) {
|
|
case SESSION_INITIATE:
|
|
response = receiveSessionInitiateAction(session, jingle);
|
|
break;
|
|
|
|
case SESSION_TERMINATE:
|
|
response = receiveSessionTerminateAction(session, jingle);
|
|
break;
|
|
|
|
default:
|
|
// Anything other than session-initiate is an error.
|
|
response = session.createJingleError(jingle, JingleError.MALFORMED_STANZA);
|
|
break;
|
|
}
|
|
|
|
return response;
|
|
}
|
|
|
|
/**
|
|
* In the UNKNOWN state we received a <session-initiate> action.
|
|
* This method processes that action.
|
|
*/
|
|
|
|
private IQ receiveSessionInitiateAction(JingleSession session, Jingle inJingle) {
|
|
|
|
IQ response = null;
|
|
boolean shouldAck = true;
|
|
|
|
// According to XEP-166 when we get a session-initiate we need to check for:
|
|
// 1. Initiator unknown
|
|
// 2. Receiver redirection
|
|
// 3. Does not support Jingle
|
|
// 4. Does not support any <description> formats
|
|
// 5. Does not support any <transport> formats
|
|
// If all of the above are OK then we send an IQ type = result to ACK the session-initiate.
|
|
|
|
// 1. Initiator unknown
|
|
// TODO
|
|
|
|
// 2. Receiver redirection
|
|
// TODO
|
|
|
|
// 3. Does not support Jingle
|
|
// Handled by Smack's lower layer.
|
|
|
|
// 4. Does not support any <description> formats
|
|
// TODO
|
|
|
|
// 5. Does not support any <transport> formats
|
|
// TODO
|
|
|
|
if (!shouldAck) {
|
|
|
|
response = session.createJingleError(inJingle, JingleError.NEGOTIATION_ERROR);
|
|
|
|
} else {
|
|
|
|
// Create the Ack
|
|
response = session.createAck(inJingle);
|
|
|
|
session.setSessionState(JingleSessionStatePending.getInstance());
|
|
|
|
// Now set up all of the initial content negotiators for the session.
|
|
for (JingleContent jingleContent : inJingle.getContentsList()) {
|
|
// First create the content negotiator for this <content> section.
|
|
ContentNegotiator contentNeg = new ContentNegotiator(session, jingleContent.getCreator(), jingleContent
|
|
.getName());
|
|
|
|
// Get the media negotiator that goes with the <description> of this content.
|
|
JingleDescription jingleDescription = jingleContent.getDescription();
|
|
|
|
// Loop through each media manager looking for the ones that matches the incoming
|
|
// session-initiate <content> choices.
|
|
// (Set the first media manager as the default, so that in case things don't match we can still negotiate.)
|
|
JingleMediaManager chosenMediaManager = session.getMediaManagers().get(0);
|
|
for (JingleMediaManager mediaManager : session.getMediaManagers()) {
|
|
boolean matches = true;
|
|
for (PayloadType mediaPayloadType : mediaManager.getPayloads()) {
|
|
for (PayloadType descPayloadType2 : jingleDescription.getPayloadTypesList()) {
|
|
if (mediaPayloadType.getId() != descPayloadType2.getId()) {
|
|
matches = false;
|
|
}
|
|
}
|
|
if (matches) {
|
|
chosenMediaManager = mediaManager;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Create the media negotiator for this content description.
|
|
contentNeg.setMediaNegotiator(new MediaNegotiator(session, chosenMediaManager, jingleDescription
|
|
.getPayloadTypesList(), contentNeg));
|
|
|
|
// For each transport type in this content, try to find the corresponding transport manager.
|
|
// Then create a transport negotiator for that transport.
|
|
for (JingleTransport jingleTransport : jingleContent.getJingleTransportsList()) {
|
|
for (JingleMediaManager mediaManager : session.getMediaManagers()) {
|
|
|
|
JingleTransportManager transportManager = mediaManager.getTransportManager();
|
|
TransportResolver resolver = null;
|
|
try {
|
|
resolver = transportManager.getResolver(session);
|
|
} catch (XMPPException e) {
|
|
e.printStackTrace();
|
|
}
|
|
|
|
if (resolver.getType().equals(TransportResolver.Type.rawupd)) {
|
|
contentNeg.setTransportNegotiator(new TransportNegotiator.RawUdp(session, resolver, contentNeg));
|
|
}
|
|
if (resolver.getType().equals(TransportResolver.Type.ice)) {
|
|
contentNeg.setTransportNegotiator(new TransportNegotiator.Ice(session, resolver, contentNeg));
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add the content negotiator to the session.
|
|
session.addContentNegotiator(contentNeg);
|
|
}
|
|
|
|
// Now setup to track the media negotiators, so that we know when (if) to send a session-accept.
|
|
session.setupListeners();
|
|
}
|
|
|
|
return response;
|
|
}
|
|
|
|
/**
|
|
* Receive and process the <session-terminate> action.
|
|
*/
|
|
private IQ receiveSessionTerminateAction(JingleSession session, Jingle jingle) {
|
|
|
|
// According to XEP-166 the only thing we can do is ack.
|
|
IQ response = session.createAck(jingle);
|
|
|
|
try {
|
|
session.terminate("Closed remotely");
|
|
} catch (XMPPException e) {
|
|
e.printStackTrace();
|
|
}
|
|
|
|
return response;
|
|
}
|
|
|
|
}
|