From e2e4390d51537b19ba6518e178a27e656a044b3d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 4 Apr 2020 10:45:42 +0200 Subject: [PATCH] untested sdp parser --- .../xmpp/jingle/MediaBuilder.java | 46 ++++++ .../conversations/xmpp/jingle/SdpUtils.java | 11 -- .../xmpp/jingle/SessionDescription.java | 145 ++++++++++++++++++ .../jingle/SessionDescriptionBuilder.java | 40 +++++ 4 files changed, 231 insertions(+), 11 deletions(-) create mode 100644 src/main/java/eu/siacs/conversations/xmpp/jingle/MediaBuilder.java delete mode 100644 src/main/java/eu/siacs/conversations/xmpp/jingle/SdpUtils.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/jingle/SessionDescription.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/jingle/SessionDescriptionBuilder.java diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/MediaBuilder.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/MediaBuilder.java new file mode 100644 index 000000000..e92c6b100 --- /dev/null +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/MediaBuilder.java @@ -0,0 +1,46 @@ +package eu.siacs.conversations.xmpp.jingle; + +import java.util.List; + +public class MediaBuilder { + private String media; + private int port; + private String protocol; + private List formats; + private String connectionData; + private List attributes; + + public MediaBuilder setMedia(String media) { + this.media = media; + return this; + } + + public MediaBuilder setPort(int port) { + this.port = port; + return this; + } + + public MediaBuilder setProtocol(String protocol) { + this.protocol = protocol; + return this; + } + + public MediaBuilder setFormats(List formats) { + this.formats = formats; + return this; + } + + public MediaBuilder setConnectionData(String connectionData) { + this.connectionData = connectionData; + return this; + } + + public MediaBuilder setAttributes(List attributes) { + this.attributes = attributes; + return this; + } + + public SessionDescription.Media createMedia() { + return new SessionDescription.Media(media, port, protocol, formats, connectionData, attributes); + } +} \ No newline at end of file diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/SdpUtils.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/SdpUtils.java deleted file mode 100644 index f70f3d299..000000000 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/SdpUtils.java +++ /dev/null @@ -1,11 +0,0 @@ -package eu.siacs.conversations.xmpp.jingle; - -import java.util.Map; - -public class SdpUtils { - - public static String toSdpString(Map contents) { - return ""; - } - -} diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/SessionDescription.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/SessionDescription.java new file mode 100644 index 000000000..2a129b3e8 --- /dev/null +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/SessionDescription.java @@ -0,0 +1,145 @@ +package eu.siacs.conversations.xmpp.jingle; + +import android.util.Log; + +import com.google.common.collect.ImmutableList; + +import java.util.List; +import java.util.Map; + +import eu.siacs.conversations.Config; + +public class SessionDescription { + + private final int version; + private final String name; + private final String connectionData; + private final List attributes; + private final List media; + + + public SessionDescription(int version, String name, String connectionData, List attributes, List media) { + this.version = version; + this.name = name; + this.connectionData = connectionData; + this.attributes = attributes; + this.media = media; + } + + public static SessionDescription parse(final Map contents) { + final SessionDescriptionBuilder sessionDescriptionBuilder = new SessionDescriptionBuilder(); + return sessionDescriptionBuilder.createSessionDescription(); + } + + public static SessionDescription parse(final String input) { + final SessionDescriptionBuilder sessionDescriptionBuilder = new SessionDescriptionBuilder(); + MediaBuilder currentMediaBuilder = null; + ImmutableList.Builder attributeBuilder = new ImmutableList.Builder<>(); + ImmutableList.Builder mediaBuilder = new ImmutableList.Builder<>(); + for(final String line : input.split("\n")) { + final String[] pair = line.split("=",2); + if (pair.length < 2 || pair[0].length() != 1) { + Log.d(Config.LOGTAG,"skipping sdp parsing on line "+line); + continue; + } + final char key = pair[0].charAt(0); + final String value = pair[1]; + switch (key) { + case 'v': + sessionDescriptionBuilder.setVersion(ignorantIntParser(value)); + break; + case 'c': + if (currentMediaBuilder != null) { + currentMediaBuilder.setConnectionData(value); + } else { + sessionDescriptionBuilder.setConnectionData(value); + } + break; + case 's': + sessionDescriptionBuilder.setName(value); + break; + case 'a': + attributeBuilder.add(Attribute.parse(value)); + break; + case 'm': + if (currentMediaBuilder == null) { + sessionDescriptionBuilder.setAttributes(attributeBuilder.build());; + } else { + currentMediaBuilder.setAttributes(attributeBuilder.build()); + mediaBuilder.add(currentMediaBuilder.createMedia()); + } + attributeBuilder = new ImmutableList.Builder<>(); + currentMediaBuilder = new MediaBuilder(); + final String[] parts = value.split(" "); + if (parts.length >= 3) { + currentMediaBuilder.setMedia(parts[0]); + currentMediaBuilder.setPort(ignorantIntParser(parts[1])); + currentMediaBuilder.setProtocol(parts[2]); + ImmutableList.Builder formats = new ImmutableList.Builder<>(); + for(int i = 3; i < parts.length; ++i) { + formats.add(ignorantIntParser(parts[i])); + } + currentMediaBuilder.setFormats(formats.build()); + } else { + Log.d(Config.LOGTAG,"skipping media line "+line); + } + break; + } + + } + if (currentMediaBuilder != null) { + currentMediaBuilder.setAttributes(attributeBuilder.build()); + mediaBuilder.add(currentMediaBuilder.createMedia()); + } + sessionDescriptionBuilder.setMedia(mediaBuilder.build()); + return sessionDescriptionBuilder.createSessionDescription(); + } + + private static int ignorantIntParser(final String input) { + try { + return Integer.parseInt(input); + } catch (NumberFormatException e) { + return 0; + } + } + + public static class Attribute { + private final String key; + private final String value; + + public Attribute(String key, String value) { + this.key = key; + this.value = value; + } + + public static Attribute parse(String input) { + final String[] pair = input.split(":",2); + if (pair.length == 2) { + return new Attribute(pair[0],pair[1]); + } else { + return new Attribute(pair[0], null); + } + } + + + } + + public static class Media { + private final String media; + private final int port; + private final String protocol; + private final List formats; + private final String connectionData; + private final List attributes; + + public Media(String media, int port, String protocol, List formats, String connectionData, List attributes) { + this.media = media; + this.port = port; + this.protocol = protocol; + this.formats = formats; + this.connectionData = connectionData; + this.attributes = attributes; + } + } + +} diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/SessionDescriptionBuilder.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/SessionDescriptionBuilder.java new file mode 100644 index 000000000..d45c53461 --- /dev/null +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/SessionDescriptionBuilder.java @@ -0,0 +1,40 @@ +package eu.siacs.conversations.xmpp.jingle; + +import java.util.List; + +public class SessionDescriptionBuilder { + private int version; + private String name; + private String connectionData; + private List attributes; + private List media; + + public SessionDescriptionBuilder setVersion(int version) { + this.version = version; + return this; + } + + public SessionDescriptionBuilder setName(String name) { + this.name = name; + return this; + } + + public SessionDescriptionBuilder setConnectionData(String connectionData) { + this.connectionData = connectionData; + return this; + } + + public SessionDescriptionBuilder setAttributes(List attributes) { + this.attributes = attributes; + return this; + } + + public SessionDescriptionBuilder setMedia(List media) { + this.media = media; + return this; + } + + public SessionDescription createSessionDescription() { + return new SessionDescription(version, name, connectionData, attributes, media); + } +} \ No newline at end of file