mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-09-26 17:49:33 +02:00
437 lines
13 KiB
Java
437 lines
13 KiB
Java
/**
|
|
*
|
|
* Copyright 2003-2005 Jive Software.
|
|
*
|
|
* 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.jingleold.packet;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
|
|
import org.jivesoftware.smack.packet.ExtensionElement;
|
|
|
|
import org.jivesoftware.smackx.jingleold.nat.ICECandidate;
|
|
import org.jivesoftware.smackx.jingleold.nat.TransportCandidate;
|
|
|
|
/**
|
|
* A jingle transport extension.
|
|
*
|
|
* @author Alvaro Saurin
|
|
*/
|
|
public class JingleTransport implements ExtensionElement {
|
|
|
|
// static
|
|
|
|
public static final String NODENAME = "transport";
|
|
|
|
// non-static
|
|
|
|
protected String namespace;
|
|
|
|
protected final List<JingleTransportCandidate> candidates = new ArrayList<JingleTransportCandidate>();
|
|
|
|
/**
|
|
* Default constructor.
|
|
*/
|
|
public JingleTransport() {
|
|
super();
|
|
}
|
|
|
|
/**
|
|
* Utility constructor, with a transport candidate element.
|
|
*
|
|
* @param candidate A transport candidate element to add.
|
|
*/
|
|
public JingleTransport(final JingleTransportCandidate candidate) {
|
|
super();
|
|
addCandidate(candidate);
|
|
}
|
|
|
|
/**
|
|
* Copy constructor.
|
|
*
|
|
* @param tr the other jingle transport.
|
|
*/
|
|
public JingleTransport(final JingleTransport tr) {
|
|
if (tr != null) {
|
|
namespace = tr.namespace;
|
|
|
|
if (tr.candidates.size() > 0) {
|
|
candidates.addAll(tr.candidates);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adds a transport candidate.
|
|
*
|
|
* @param candidate the candidate
|
|
*/
|
|
public void addCandidate(final JingleTransportCandidate candidate) {
|
|
if (candidate != null) {
|
|
synchronized (candidates) {
|
|
candidates.add(candidate);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get an iterator for the candidates.
|
|
*
|
|
* @return an iterator
|
|
*/
|
|
public Iterator<JingleTransportCandidate> getCandidates() {
|
|
return Collections.unmodifiableList(getCandidatesList()).iterator();
|
|
}
|
|
|
|
/**
|
|
* Get the list of candidates.
|
|
*
|
|
* @return The candidates list.
|
|
*/
|
|
public List<JingleTransportCandidate> getCandidatesList() {
|
|
ArrayList<JingleTransportCandidate> res;
|
|
synchronized (candidates) {
|
|
res = new ArrayList<>(candidates);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
/**
|
|
* Get the number of transport candidates.
|
|
*
|
|
* @return The number of transport candidates contained.
|
|
*/
|
|
public int getCandidatesCount() {
|
|
return getCandidatesList().size();
|
|
}
|
|
|
|
/**
|
|
* Returns the XML element name of the element.
|
|
*
|
|
* @return the XML element name of the element.
|
|
*/
|
|
@Override
|
|
public String getElementName() {
|
|
return NODENAME;
|
|
}
|
|
|
|
/**
|
|
* Set the namespace.
|
|
*
|
|
* @param ns The namespace
|
|
*/
|
|
protected void setNamespace(final String ns) {
|
|
namespace = ns;
|
|
}
|
|
|
|
/**
|
|
* Get the namespace.
|
|
*
|
|
* @return The namespace
|
|
*/
|
|
@Override
|
|
public String getNamespace() {
|
|
return namespace;
|
|
}
|
|
|
|
/**
|
|
* Return the XML representation for this element.
|
|
*/
|
|
@Override
|
|
public String toXML(org.jivesoftware.smack.packet.XmlEnvironment enclosingNamespace) {
|
|
StringBuilder buf = new StringBuilder();
|
|
|
|
buf.append('<').append(getElementName()).append(" xmlns=\"");
|
|
buf.append(getNamespace()).append("\" ");
|
|
|
|
synchronized (candidates) {
|
|
if (getCandidatesCount() > 0) {
|
|
buf.append('>');
|
|
Iterator<JingleTransportCandidate> iter = getCandidates();
|
|
|
|
while (iter.hasNext()) {
|
|
JingleTransportCandidate candidate = iter.next();
|
|
buf.append(candidate.toXML());
|
|
}
|
|
buf.append("</").append(getElementName()).append('>');
|
|
} else {
|
|
buf.append("/>");
|
|
}
|
|
}
|
|
|
|
return buf.toString();
|
|
}
|
|
|
|
/**
|
|
* Candidate element in the transport. This class acts as a view of the
|
|
* "TransportCandidate" in the Jingle space.
|
|
*
|
|
* @author Alvaro Saurin
|
|
* @see TransportCandidate
|
|
*/
|
|
public abstract static class JingleTransportCandidate {
|
|
|
|
public static final String NODENAME = "candidate";
|
|
|
|
// The transport candidate contained in the element.
|
|
protected TransportCandidate transportCandidate;
|
|
|
|
/**
|
|
* Creates a new TransportNegotiator child.
|
|
*/
|
|
public JingleTransportCandidate() {
|
|
super();
|
|
}
|
|
|
|
/**
|
|
* Creates a new TransportNegotiator child.
|
|
*
|
|
* @param candidate the jmf transport candidate
|
|
*/
|
|
public JingleTransportCandidate(final TransportCandidate candidate) {
|
|
super();
|
|
setMediaTransport(candidate);
|
|
}
|
|
|
|
/**
|
|
* Returns the XML element name of the element.
|
|
*
|
|
* @return the XML element name of the element.
|
|
*/
|
|
public static String getElementName() {
|
|
return NODENAME;
|
|
}
|
|
|
|
/**
|
|
* Get the current transportElement candidate.
|
|
*
|
|
* @return the transportElement candidate
|
|
*/
|
|
public TransportCandidate getMediaTransport() {
|
|
return transportCandidate;
|
|
}
|
|
|
|
/**
|
|
* Set the transportElement candidate.
|
|
*
|
|
* @param cand the transportElement candidate
|
|
*/
|
|
public void setMediaTransport(final TransportCandidate cand) {
|
|
if (cand != null) {
|
|
transportCandidate = cand;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the list of attributes.
|
|
*
|
|
* @return a string with the list of attributes.
|
|
*/
|
|
protected String getChildElements() {
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Obtain a valid XML representation of a transport candidate.
|
|
*
|
|
* @return A string containing the XML dump of the transport candidate.
|
|
*/
|
|
public String toXML() {
|
|
StringBuilder buf = new StringBuilder();
|
|
String childElements = getChildElements();
|
|
|
|
if (transportCandidate != null && childElements != null) {
|
|
buf.append('<').append(getElementName()).append(' ');
|
|
buf.append(childElements);
|
|
buf.append("/>");
|
|
}
|
|
|
|
return buf.toString();
|
|
}
|
|
}
|
|
|
|
// Subclasses
|
|
|
|
/**
|
|
* RTP-ICE profile.
|
|
*/
|
|
public static class Ice extends JingleTransport {
|
|
public static final String NAMESPACE = "urn:xmpp:tmp:jingle:transports:ice-udp";
|
|
|
|
public Ice() {
|
|
super();
|
|
setNamespace(NAMESPACE);
|
|
}
|
|
|
|
/**
|
|
* Add a transport candidate.
|
|
*
|
|
* @see org.jivesoftware.smackx.jingleold.packet.JingleTransport#addCandidate(org.jivesoftware.smackx.jingleold.packet.JingleTransport.JingleTransportCandidate)
|
|
*/
|
|
@Override
|
|
public void addCandidate(final JingleTransportCandidate candidate) {
|
|
super.addCandidate(candidate);
|
|
}
|
|
|
|
/**
|
|
* Get the list of candidates. As a "raw-udp" transport can only contain
|
|
* one candidate, we use the first in the list...
|
|
*
|
|
* @see org.jivesoftware.smackx.jingleold.packet.JingleTransport#getCandidates()
|
|
*/
|
|
@Override
|
|
public List<JingleTransportCandidate> getCandidatesList() {
|
|
List<JingleTransportCandidate> copy = new ArrayList<>();
|
|
List<JingleTransportCandidate> superCandidatesList = super.getCandidatesList();
|
|
for (int i = 0; i < superCandidatesList.size(); i++) {
|
|
copy.add(superCandidatesList.get(i));
|
|
}
|
|
|
|
return copy;
|
|
}
|
|
|
|
public static class Candidate extends JingleTransportCandidate {
|
|
/**
|
|
* Default constructor.
|
|
*/
|
|
public Candidate() {
|
|
super();
|
|
}
|
|
|
|
/**
|
|
* Constructor with a transport candidate.
|
|
*/
|
|
public Candidate(final TransportCandidate tc) {
|
|
super(tc);
|
|
}
|
|
|
|
/**
|
|
* Get the elements of this candidate.
|
|
*/
|
|
@Override
|
|
protected String getChildElements() {
|
|
StringBuilder buf = new StringBuilder();
|
|
|
|
if (transportCandidate != null) { // && transportCandidate instanceof ICECandidate) {
|
|
ICECandidate tci = (ICECandidate) transportCandidate;
|
|
|
|
// We convert the transportElement candidate to XML here...
|
|
buf.append(" generation=\"").append(tci.getGeneration()).append('"');
|
|
buf.append(" ip=\"").append(tci.getIp()).append('"');
|
|
buf.append(" port=\"").append(tci.getPort()).append('"');
|
|
buf.append(" network=\"").append(tci.getNetwork()).append('"');
|
|
buf.append(" username=\"").append(tci.getUsername()).append('"');
|
|
buf.append(" password=\"").append(tci.getPassword()).append('"');
|
|
buf.append(" preference=\"").append(tci.getPreference()).append('"');
|
|
buf.append(" type=\"").append(tci.getType()).append('"');
|
|
|
|
// Optional elements
|
|
if (transportCandidate.getName() != null) {
|
|
buf.append(" name=\"").append(tci.getName()).append('"');
|
|
}
|
|
}
|
|
|
|
return buf.toString();
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Raw UDP profile.
|
|
*/
|
|
public static class RawUdp extends JingleTransport {
|
|
public static final String NAMESPACE = "http://www.xmpp.org/extensions/xep-0177.html#ns";
|
|
|
|
public RawUdp() {
|
|
super();
|
|
setNamespace(NAMESPACE);
|
|
}
|
|
|
|
/**
|
|
* Add a transport candidate.
|
|
*
|
|
* @see org.jivesoftware.smackx.jingleold.packet.JingleTransport#addCandidate(org.jivesoftware.smackx.jingleold.packet.JingleTransport.JingleTransportCandidate)
|
|
*/
|
|
@Override
|
|
public void addCandidate(final JingleTransportCandidate candidate) {
|
|
candidates.clear();
|
|
super.addCandidate(candidate);
|
|
}
|
|
|
|
/**
|
|
* Get the list of candidates. As a "raw-udp" transport can only contain
|
|
* one candidate, we use the first in the list...
|
|
*
|
|
* @see org.jivesoftware.smackx.jingleold.packet.JingleTransport#getCandidates()
|
|
*/
|
|
@Override
|
|
public List<JingleTransportCandidate> getCandidatesList() {
|
|
List<JingleTransportCandidate> copy = new ArrayList<>();
|
|
List<JingleTransportCandidate> superCandidatesList = super.getCandidatesList();
|
|
if (superCandidatesList.size() > 0) {
|
|
copy.add(superCandidatesList.get(0));
|
|
}
|
|
|
|
return copy;
|
|
}
|
|
|
|
/**
|
|
* Raw-udp transport candidate.
|
|
*/
|
|
public static class Candidate extends JingleTransportCandidate {
|
|
/**
|
|
* Default constructor.
|
|
*/
|
|
public Candidate() {
|
|
super();
|
|
}
|
|
|
|
/**
|
|
* Constructor with a transport candidate.
|
|
*/
|
|
public Candidate(final TransportCandidate tc) {
|
|
super(tc);
|
|
}
|
|
|
|
/**
|
|
* Get the elements of this candidate.
|
|
*/
|
|
@Override
|
|
protected String getChildElements() {
|
|
StringBuilder buf = new StringBuilder();
|
|
|
|
if (transportCandidate != null && transportCandidate instanceof TransportCandidate.Fixed) {
|
|
TransportCandidate.Fixed tcf = (TransportCandidate.Fixed) transportCandidate;
|
|
|
|
buf.append(" generation=\"").append(tcf.getGeneration()).append('"');
|
|
buf.append(" ip=\"").append(tcf.getIp()).append('"');
|
|
buf.append(" port=\"").append(tcf.getPort()).append('"');
|
|
|
|
// Optional parameters
|
|
String name = tcf.getName();
|
|
if (name != null) {
|
|
buf.append(" name=\"").append(name).append('"');
|
|
}
|
|
}
|
|
return buf.toString();
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|