1package eu.siacs.conversations.xmpp.jingle;
2
3import android.util.Log;
4
5import com.google.common.collect.ImmutableList;
6
7import java.util.List;
8import java.util.Map;
9
10import eu.siacs.conversations.Config;
11
12public class SessionDescription {
13
14 public final int version;
15 public final String name;
16 public final String connectionData;
17 public final List<Attribute> attributes;
18 public final List<Media> media;
19
20
21 public SessionDescription(int version, String name, String connectionData, List<Attribute> attributes, List<Media> media) {
22 this.version = version;
23 this.name = name;
24 this.connectionData = connectionData;
25 this.attributes = attributes;
26 this.media = media;
27 }
28
29 public static SessionDescription parse(final Map<String, JingleRtpConnection.DescriptionTransport> contents) {
30 final SessionDescriptionBuilder sessionDescriptionBuilder = new SessionDescriptionBuilder();
31 return sessionDescriptionBuilder.createSessionDescription();
32 }
33
34 public static SessionDescription parse(final String input) {
35 final SessionDescriptionBuilder sessionDescriptionBuilder = new SessionDescriptionBuilder();
36 MediaBuilder currentMediaBuilder = null;
37 ImmutableList.Builder<Attribute> attributeBuilder = new ImmutableList.Builder<>();
38 ImmutableList.Builder<Media> mediaBuilder = new ImmutableList.Builder<>();
39 for (final String line : input.split("\n")) {
40 final String[] pair = line.split("=", 2);
41 if (pair.length < 2 || pair[0].length() != 1) {
42 Log.d(Config.LOGTAG, "skipping sdp parsing on line " + line);
43 continue;
44 }
45 final char key = pair[0].charAt(0);
46 final String value = pair[1];
47 switch (key) {
48 case 'v':
49 sessionDescriptionBuilder.setVersion(ignorantIntParser(value));
50 break;
51 case 'c':
52 if (currentMediaBuilder != null) {
53 currentMediaBuilder.setConnectionData(value);
54 } else {
55 sessionDescriptionBuilder.setConnectionData(value);
56 }
57 break;
58 case 's':
59 sessionDescriptionBuilder.setName(value);
60 break;
61 case 'a':
62 attributeBuilder.add(Attribute.parse(value));
63 break;
64 case 'm':
65 if (currentMediaBuilder == null) {
66 sessionDescriptionBuilder.setAttributes(attributeBuilder.build());
67 ;
68 } else {
69 currentMediaBuilder.setAttributes(attributeBuilder.build());
70 mediaBuilder.add(currentMediaBuilder.createMedia());
71 }
72 attributeBuilder = new ImmutableList.Builder<>();
73 currentMediaBuilder = new MediaBuilder();
74 final String[] parts = value.split(" ");
75 if (parts.length >= 3) {
76 currentMediaBuilder.setMedia(parts[0]);
77 currentMediaBuilder.setPort(ignorantIntParser(parts[1]));
78 currentMediaBuilder.setProtocol(parts[2]);
79 ImmutableList.Builder<Integer> formats = new ImmutableList.Builder<>();
80 for (int i = 3; i < parts.length; ++i) {
81 formats.add(ignorantIntParser(parts[i]));
82 }
83 currentMediaBuilder.setFormats(formats.build());
84 } else {
85 Log.d(Config.LOGTAG, "skipping media line " + line);
86 }
87 break;
88 }
89
90 }
91 if (currentMediaBuilder != null) {
92 currentMediaBuilder.setAttributes(attributeBuilder.build());
93 mediaBuilder.add(currentMediaBuilder.createMedia());
94 }
95 sessionDescriptionBuilder.setMedia(mediaBuilder.build());
96 return sessionDescriptionBuilder.createSessionDescription();
97 }
98
99 private static int ignorantIntParser(final String input) {
100 try {
101 return Integer.parseInt(input);
102 } catch (NumberFormatException e) {
103 return 0;
104 }
105 }
106
107 public static class Attribute {
108 public final String key;
109 public final String value;
110
111 public Attribute(String key, String value) {
112 this.key = key;
113 this.value = value;
114 }
115
116 public static Attribute parse(String input) {
117 final String[] pair = input.split(":", 2);
118 if (pair.length == 2) {
119 return new Attribute(pair[0], pair[1]);
120 } else {
121 return new Attribute(pair[0], null);
122 }
123 }
124
125
126 }
127
128 public static class Media {
129 public final String media;
130 public final int port;
131 public final String protocol;
132 public final List<Integer> formats;
133 public final String connectionData;
134 public final List<Attribute> attributes;
135
136 public Media(String media, int port, String protocol, List<Integer> formats, String connectionData, List<Attribute> attributes) {
137 this.media = media;
138 this.port = port;
139 this.protocol = protocol;
140 this.formats = formats;
141 this.connectionData = connectionData;
142 this.attributes = attributes;
143 }
144 }
145
146}