create stub objects for most of what’s in description and transport
This commit is contained in:
parent
43cf1783a4
commit
4e13893662
|
@ -38,6 +38,7 @@ public final class Namespace {
|
|||
public static final String JINGLE_APPS_DTLS = "urn:xmpp:jingle:apps:dtls:0";
|
||||
public static final String JINGLE_FEATURE_AUDIO = "urn:xmpp:jingle:apps:rtp:audio";
|
||||
public static final String JINGLE_FEATURE_VIDEO = "urn:xmpp:jingle:apps:rtp:video";
|
||||
public static final String JINGLE_RTP_HEADER_EXTENSIONS = "urn:xmpp:jingle:apps:rtp:rtp-hdrext:0";
|
||||
public static final String IBB = "http://jabber.org/protocol/ibb";
|
||||
public static final String PING = "urn:xmpp:ping";
|
||||
public static final String PUSH = "urn:xmpp:push:0";
|
||||
|
|
|
@ -73,6 +73,7 @@ public class JingleRtpConnection extends AbstractJingleConnection {
|
|||
final State oldState = this.state;
|
||||
if (transition(State.SESSION_INITIALIZED)) {
|
||||
if (oldState == State.PROCEED) {
|
||||
processContents(contents);
|
||||
sendSessionAccept();
|
||||
} else {
|
||||
//TODO start ringing
|
||||
|
@ -82,6 +83,23 @@ public class JingleRtpConnection extends AbstractJingleConnection {
|
|||
}
|
||||
}
|
||||
|
||||
private void processContents(final Map<String,DescriptionTransport> contents) {
|
||||
for(Map.Entry<String,DescriptionTransport> content : contents.entrySet()) {
|
||||
final DescriptionTransport descriptionTransport = content.getValue();
|
||||
final RtpDescription rtpDescription = descriptionTransport.description;
|
||||
Log.d(Config.LOGTAG,"receive content with name "+content.getKey()+" and media="+rtpDescription.getMedia());
|
||||
for(RtpDescription.PayloadType payloadType : rtpDescription.getPayloadTypes()) {
|
||||
Log.d(Config.LOGTAG,"payload type: "+payloadType.toString());
|
||||
}
|
||||
for(RtpDescription.RtpHeaderExtension extension : rtpDescription.getHeaderExtensions()) {
|
||||
Log.d(Config.LOGTAG,"extension: "+extension.toString());
|
||||
}
|
||||
final IceUdpTransportInfo iceUdpTransportInfo = descriptionTransport.transport;
|
||||
Log.d(Config.LOGTAG,"transport: "+descriptionTransport.transport);
|
||||
Log.d(Config.LOGTAG,"fingerprint "+iceUdpTransportInfo.getFingerprint());
|
||||
}
|
||||
}
|
||||
|
||||
void deliveryMessage(final Jid from, final Element message) {
|
||||
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": delivered message to JingleRtpConnection " + message);
|
||||
switch (message.getName()) {
|
||||
|
@ -175,7 +193,7 @@ public class JingleRtpConnection extends AbstractJingleConnection {
|
|||
}
|
||||
}
|
||||
|
||||
private static class DescriptionTransport {
|
||||
public static class DescriptionTransport {
|
||||
private final RtpDescription description;
|
||||
private final IceUdpTransportInfo transport;
|
||||
|
||||
|
@ -192,6 +210,7 @@ public class JingleRtpConnection extends AbstractJingleConnection {
|
|||
if (description instanceof RtpDescription) {
|
||||
rtpDescription = (RtpDescription) description;
|
||||
} else {
|
||||
Log.d(Config.LOGTAG,"description was "+description);
|
||||
throw new IllegalArgumentException("Content does not contain RtpDescription");
|
||||
}
|
||||
if (transportInfo instanceof IceUdpTransportInfo) {
|
||||
|
@ -203,13 +222,13 @@ public class JingleRtpConnection extends AbstractJingleConnection {
|
|||
}
|
||||
|
||||
public static Map<String, DescriptionTransport> of(final Map<String,Content> contents) {
|
||||
return Maps.transformValues(contents, new Function<Content, DescriptionTransport>() {
|
||||
return ImmutableMap.copyOf(Maps.transformValues(contents, new Function<Content, DescriptionTransport>() {
|
||||
@NullableDecl
|
||||
@Override
|
||||
public DescriptionTransport apply(@NullableDecl Content content) {
|
||||
return content == null ? null : of(content);
|
||||
}
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
package eu.siacs.conversations.xmpp.jingle;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class SdpUtils {
|
||||
|
||||
public static String toSdpString(Map<String, JingleRtpConnection.DescriptionTransport> contents) {
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
|
@ -51,9 +51,11 @@ public class Content extends Element {
|
|||
if (description == null) {
|
||||
return null;
|
||||
}
|
||||
final String xmlns = description.getNamespace();
|
||||
if (FileTransferDescription.NAMESPACES.contains(xmlns)) {
|
||||
final String namespace = description.getNamespace();
|
||||
if (FileTransferDescription.NAMESPACES.contains(namespace)) {
|
||||
return FileTransferDescription.upgrade(description);
|
||||
} else if (Namespace.JINGLE_APPS_RTP.equals(namespace)) {
|
||||
return RtpDescription.upgrade(description);
|
||||
} else {
|
||||
return GenericDescription.upgrade(description);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package eu.siacs.conversations.xmpp.jingle.stanzas;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import eu.siacs.conversations.xml.Element;
|
||||
import eu.siacs.conversations.xml.Namespace;
|
||||
|
@ -11,6 +14,21 @@ public class IceUdpTransportInfo extends GenericTransportInfo {
|
|||
super(name, xmlns);
|
||||
}
|
||||
|
||||
public Fingerprint getFingerprint() {
|
||||
final Element fingerprint = this.findChild("fingerprint", Namespace.JINGLE_APPS_DTLS);
|
||||
return fingerprint == null ? null : Fingerprint.upgrade(fingerprint);
|
||||
}
|
||||
|
||||
public List<Candidate> getCandidates() {
|
||||
final ImmutableList.Builder<Candidate> builder = new ImmutableList.Builder<>();
|
||||
for(final Element child : getChildren()) {
|
||||
if ("candidate".equals(child.getName())) {
|
||||
builder.add(Candidate.upgrade(child));
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public static IceUdpTransportInfo upgrade(final Element element) {
|
||||
Preconditions.checkArgument("transport".equals(element.getName()), "Name of provided element is not transport");
|
||||
Preconditions.checkArgument(Namespace.JINGLE_TRANSPORT_ICE_UDP.equals(element.getNamespace()), "Element does not match ice-udp transport namespace");
|
||||
|
@ -19,4 +37,104 @@ public class IceUdpTransportInfo extends GenericTransportInfo {
|
|||
transportInfo.setChildren(element.getChildren());
|
||||
return transportInfo;
|
||||
}
|
||||
|
||||
public static class Candidate extends Element {
|
||||
|
||||
private Candidate() {
|
||||
super("candidate");
|
||||
}
|
||||
|
||||
public int getComponent() {
|
||||
return getAttributeAsInt("component");
|
||||
}
|
||||
|
||||
public int getFoundation() {
|
||||
return getAttributeAsInt("foundation");
|
||||
}
|
||||
|
||||
public int getGeneration() {
|
||||
return getAttributeAsInt("generation");
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return getAttribute("id");
|
||||
}
|
||||
|
||||
public String getIp() {
|
||||
return getAttribute("ip");
|
||||
}
|
||||
|
||||
public int getNetwork() {
|
||||
return getAttributeAsInt("network");
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return getAttributeAsInt("port");
|
||||
}
|
||||
|
||||
public int getPriority() {
|
||||
return getAttributeAsInt("priority");
|
||||
}
|
||||
|
||||
public String getProtocol() {
|
||||
return getAttribute("protocol");
|
||||
}
|
||||
|
||||
public String getRelAddr() {
|
||||
return getAttribute("rel-addr");
|
||||
}
|
||||
|
||||
public int getRelPort() {
|
||||
return getAttributeAsInt("rel-port");
|
||||
}
|
||||
|
||||
public String getType() { //TODO might be converted to enum
|
||||
return getAttribute("type");
|
||||
}
|
||||
|
||||
private int getAttributeAsInt(final String name) {
|
||||
final String value = this.getAttribute(name);
|
||||
if (value == null) {
|
||||
return 0;
|
||||
}
|
||||
try {
|
||||
return Integer.parseInt(value);
|
||||
} catch (NumberFormatException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static Candidate upgrade(final Element element) {
|
||||
Preconditions.checkArgument("candidate".equals(element.getName()));
|
||||
final Candidate candidate = new Candidate();
|
||||
candidate.setAttributes(element.getAttributes());
|
||||
candidate.setChildren(element.getChildren());
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class Fingerprint extends Element {
|
||||
|
||||
public String getHash() {
|
||||
return this.getAttribute("hash");
|
||||
}
|
||||
|
||||
public String getSetup() {
|
||||
return this.getAttribute("setup");
|
||||
}
|
||||
|
||||
private Fingerprint() {
|
||||
super("fingerprint", Namespace.JINGLE_APPS_DTLS);
|
||||
}
|
||||
|
||||
public static Fingerprint upgrade(final Element element) {
|
||||
Preconditions.checkArgument("fingerprint".equals(element.getName()));
|
||||
Preconditions.checkArgument(Namespace.JINGLE_APPS_DTLS.equals(element.getNamespace()));
|
||||
final Fingerprint fingerprint = new Fingerprint();
|
||||
fingerprint.setAttributes(element.getAttributes());
|
||||
fingerprint.setContent(element.getContent());
|
||||
return fingerprint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ public class JinglePacket extends IqPacket {
|
|||
return jinglePacket;
|
||||
}
|
||||
|
||||
//TODO can have multiple contents
|
||||
//TODO deprecate this somehow and make file transfer fail if there are multiple (or something)
|
||||
public Content getJingleContent() {
|
||||
final Element content = getJingleChild("content");
|
||||
return content == null ? null : Content.upgrade(content);
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
package eu.siacs.conversations.xmpp.jingle.stanzas;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import eu.siacs.conversations.xml.Element;
|
||||
import eu.siacs.conversations.xml.Namespace;
|
||||
|
@ -12,6 +16,30 @@ public class RtpDescription extends GenericDescription {
|
|||
super(name, namespace);
|
||||
}
|
||||
|
||||
public Media getMedia() {
|
||||
return Media.of(this.getAttribute("media"));
|
||||
}
|
||||
|
||||
public List<PayloadType> getPayloadTypes() {
|
||||
final ImmutableList.Builder<PayloadType> builder = new ImmutableList.Builder<>();
|
||||
for(Element child : getChildren()) {
|
||||
if ("payload-type".equals(child.getName())) {
|
||||
builder.add(PayloadType.of(child));
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public List<RtpHeaderExtension> getHeaderExtensions() {
|
||||
final ImmutableList.Builder<RtpHeaderExtension> builder = new ImmutableList.Builder<>();
|
||||
for(final Element child : getChildren()) {
|
||||
if ("rtp-hdrext".equals(child.getName()) && Namespace.JINGLE_RTP_HEADER_EXTENSIONS.equals(child.getNamespace())) {
|
||||
builder.add(RtpHeaderExtension.upgrade(child));
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public static RtpDescription upgrade(final Element element) {
|
||||
Preconditions.checkArgument("description".equals(element.getName()), "Name of provided element is not description");
|
||||
Preconditions.checkArgument(Namespace.JINGLE_APPS_RTP.equals(element.getNamespace()), "Element does not match the jingle rtp namespace");
|
||||
|
@ -20,4 +48,133 @@ public class RtpDescription extends GenericDescription {
|
|||
description.setChildren(element.getChildren());
|
||||
return description;
|
||||
}
|
||||
|
||||
//TODO: support for https://xmpp.org/extensions/xep-0293.html
|
||||
|
||||
|
||||
public static class RtpHeaderExtension extends Element {
|
||||
|
||||
private RtpHeaderExtension() {
|
||||
super("rtp-hdrext", Namespace.JINGLE_RTP_HEADER_EXTENSIONS);
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return this.getAttribute("id");
|
||||
}
|
||||
|
||||
public String getUri() {
|
||||
return this.getAttribute("uri");
|
||||
}
|
||||
|
||||
public static RtpHeaderExtension upgrade(final Element element) {
|
||||
Preconditions.checkArgument("rtp-hdrext".equals(element.getName()));
|
||||
Preconditions.checkArgument(Namespace.JINGLE_RTP_HEADER_EXTENSIONS.equals(element.getNamespace()));
|
||||
final RtpHeaderExtension extension = new RtpHeaderExtension();
|
||||
extension.setAttributes(element.getAttributes());
|
||||
extension.setChildren(element.getChildren());
|
||||
return extension;
|
||||
}
|
||||
}
|
||||
|
||||
public static class PayloadType extends Element {
|
||||
|
||||
private PayloadType(String name, String xmlns) {
|
||||
super(name, xmlns);
|
||||
}
|
||||
public String getId() {
|
||||
return this.getAttribute("id");
|
||||
}
|
||||
|
||||
public String getPayloadTypeName() {
|
||||
return this.getAttribute("name");
|
||||
}
|
||||
|
||||
public int getClockRate() {
|
||||
final String clockRate = this.getAttribute("clockrate");
|
||||
if (clockRate == null) {
|
||||
return 0;
|
||||
}
|
||||
try {
|
||||
return Integer.parseInt(clockRate);
|
||||
} catch (NumberFormatException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public int getChannels() {
|
||||
final String channels = this.getAttribute("channels");
|
||||
if (channels == null) {
|
||||
return 1; // The number of channels; if omitted, it MUST be assumed to contain one channel
|
||||
}
|
||||
try {
|
||||
return Integer.parseInt(channels);
|
||||
} catch (NumberFormatException e) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public List<Parameter> getParameters() {
|
||||
final ImmutableList.Builder<Parameter> builder = new ImmutableList.Builder<>();
|
||||
for (Element child : getChildren()) {
|
||||
if ("parameter".equals(child.getName())) {
|
||||
builder.add(Parameter.of(child));
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public static PayloadType of(final Element element) {
|
||||
Preconditions.checkArgument("payload-type".equals(element.getName()), "element name must be called payload-type");
|
||||
PayloadType payloadType = new PayloadType("payload-type", Namespace.JINGLE_APPS_RTP);
|
||||
payloadType.setAttributes(element.getAttributes());
|
||||
payloadType.setChildren(element.getChildren());
|
||||
return payloadType;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Parameter extends Element {
|
||||
|
||||
private Parameter() {
|
||||
super("parameter", Namespace.JINGLE_APPS_RTP);
|
||||
}
|
||||
|
||||
public Parameter(String name, String value) {
|
||||
super("parameter", Namespace.JINGLE_APPS_RTP);
|
||||
this.setAttribute("name", name);
|
||||
this.setAttribute("value", value);
|
||||
}
|
||||
|
||||
public String getParameterName() {
|
||||
return this.getAttribute("name");
|
||||
}
|
||||
|
||||
public String getParameterValue() {
|
||||
return this.getAttribute("value");
|
||||
}
|
||||
|
||||
public static Parameter of(final Element element) {
|
||||
Preconditions.checkArgument("parameter".equals(element.getName()), "element name must be called parameter");
|
||||
Parameter parameter = new Parameter();
|
||||
parameter.setAttributes(element.getAttributes());
|
||||
parameter.setChildren(element.getChildren());
|
||||
return parameter;
|
||||
}
|
||||
}
|
||||
|
||||
public enum Media {
|
||||
VIDEO, AUDIO, UNKNOWN;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString().toLowerCase(Locale.ROOT);
|
||||
}
|
||||
|
||||
public static Media of(String value) {
|
||||
try {
|
||||
return value == null ? UNKNOWN : Media.valueOf(value.toUpperCase(Locale.ROOT));
|
||||
} catch (IllegalArgumentException e) {
|
||||
return UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue