be more liberal in 0167 payload-type parameter parsing

some implementations will transform the following SDP coming from Firefox

m=audio 12346 RTP/AVP 101
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15

to

<payload-type channels="1" name="telephone-event" clockrate="8000" id="101">
  <parameter value="0-15" xmlns="urn:xmpp:jingle:apps:rtp:1"/>
</payload-type>

While a missing name attribute is not legal according to the XEP; and 0-15 are
technically not just one value the following commit will accept it if there is
just one paramater.
This commit is contained in:
Daniel Gultsch 2020-06-17 21:15:09 +02:00
parent 47804205b6
commit 7bcb29c482
2 changed files with 20 additions and 5 deletions

View File

@ -168,8 +168,10 @@ public class SessionDescription {
} }
formatBuilder.add(payloadType.getIntId()); formatBuilder.add(payloadType.getIntId());
mediaAttributes.put("rtpmap", payloadType.toSdpAttribute()); mediaAttributes.put("rtpmap", payloadType.toSdpAttribute());
List<RtpDescription.Parameter> parameters = payloadType.getParameters(); final List<RtpDescription.Parameter> parameters = payloadType.getParameters();
if (parameters.size() > 0) { if (parameters.size() == 1) {
mediaAttributes.put("fmtp", RtpDescription.Parameter.toSdpString(id, parameters.get(0)));
} else if (parameters.size() > 0) {
mediaAttributes.put("fmtp", RtpDescription.Parameter.toSdpString(id, parameters)); mediaAttributes.put("fmtp", RtpDescription.Parameter.toSdpString(id, parameters));
} }
for (RtpDescription.FeedbackNegotiation feedbackNegotiation : payloadType.getFeedbackNegotiations()) { for (RtpDescription.FeedbackNegotiation feedbackNegotiation : payloadType.getFeedbackNegotiations()) {

View File

@ -3,6 +3,7 @@ package eu.siacs.conversations.xmpp.jingle.stanzas;
import android.util.Pair; import android.util.Pair;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@ -369,7 +370,7 @@ public class RtpDescription extends GenericDescription {
final StringBuilder stringBuilder = new StringBuilder(); final StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(id).append(' '); stringBuilder.append(id).append(' ');
for (int i = 0; i < parameters.size(); ++i) { for (int i = 0; i < parameters.size(); ++i) {
Parameter p = parameters.get(i); final Parameter p = parameters.get(i);
final String name = p.getParameterName(); final String name = p.getParameterName();
Preconditions.checkArgument(name != null, String.format("parameter for %s must have a name", id)); Preconditions.checkArgument(name != null, String.format("parameter for %s must have a name", id));
SessionDescription.checkNoWhitespace(name, String.format("parameter names for %s must not contain whitespaces", id)); SessionDescription.checkNoWhitespace(name, String.format("parameter names for %s must not contain whitespaces", id));
@ -386,11 +387,23 @@ public class RtpDescription extends GenericDescription {
return stringBuilder.toString(); return stringBuilder.toString();
} }
public static Pair<String, List<Parameter>> ofSdpString(final String sdp) { public static String toSdpString(final String id, final Parameter parameter) {
final String name = parameter.getParameterName();
final String value = parameter.getParameterValue();
Preconditions.checkArgument(value != null, String.format("parameter for %s must have a value", id));
SessionDescription.checkNoWhitespace(value, String.format("parameter values for %s must not contain whitespaces", id));
if (Strings.isNullOrEmpty(name)) {
return String.format("%s %s", id, value);
} else {
return String.format("%s %s=%s", id, name, value);
}
}
static Pair<String, List<Parameter>> ofSdpString(final String sdp) {
final String[] pair = sdp.split(" "); final String[] pair = sdp.split(" ");
if (pair.length == 2) { if (pair.length == 2) {
final String id = pair[0]; final String id = pair[0];
ImmutableList.Builder<Parameter> builder = new ImmutableList.Builder<>(); final ImmutableList.Builder<Parameter> builder = new ImmutableList.Builder<>();
for (final String parameter : pair[1].split(";")) { for (final String parameter : pair[1].split(";")) {
final String[] parts = parameter.split("=", 2); final String[] parts = parameter.split("=", 2);
if (parts.length == 2) { if (parts.length == 2) {