/* * JBoss, Home of Professional Open Source * Copyright 2011, Red Hat, Inc. and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.restcomm.media.rtp.sdp; import java.text.ParseException; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import org.restcomm.media.spi.utils.Text; /** * Session Descriptor. * * @author kulikov * @author Henrique Rosa (henrique.rosa@telestax.com) * * @deprecated use new /io/sdp library */ public class SessionDescription { private Text version; private OriginField origin; private Text session; private ConnectionField connection; private TimeField time; /* MEDIA */ protected final static Text RTPMAP = new Text("a=rtpmap"); protected final static Text FMTP = new Text("a=fmtp"); protected final static Text AUDIO = new Text("audio"); protected final static Text VIDEO = new Text("video"); private ArrayList<MediaDescriptorField> mds = new ArrayList<MediaDescriptorField>(3); private MediaDescriptorField md; private MediaDescriptorField audioDescriptor; private MediaDescriptorField videoDescriptor; private MediaDescriptorField applicationDescriptor; /* ICE */ protected static final Text ICE_UFRAG = new Text("a=ice-ufrag"); protected static final Text ICE_PWD = new Text("a=ice-pwd"); protected static final Text ICE_CANDIDATE = CandidateField.CANDIDATE_FIELD; private boolean ice = false; /* WebRTC */ protected final static Text WEBRTC_FINGERPRINT = new Text("a=fingerprint"); private Text fingerprint; public SessionDescription() { this.origin = new OriginField(); this.connection = new ConnectionField(); this.time = new TimeField(); } /** * Reads descriptor from binary data * @param data the binary data * @throws ParseException */ public void parse(byte[] data) throws ParseException { Text text = new Text(); text.strain(data, 0, data.length); init(text); } public void init(Text text) throws ParseException { //clean previous data reset(); while (text.hasMoreLines()) { Text line = text.nextLine(); if (line.length() == 0) continue; switch (line.charAt(0)) { case 'v': Iterator<Text> it = line.split('=').iterator(); it.next(); version = it.next(); version.trim(); break; case 'o': origin.strain(line); break; case 's': it = line.split('=').iterator(); it.next(); session = it.next(); session.trim(); break; case 'c': if (md == null) { connection.strain(line); } else { md.setConnection(line); } break; case 't': time.strain(line); break; case 'm': md = new MediaDescriptorField(); mds.add(md); md.setDescriptor(line); MediaType mediaType = MediaType.fromDescription(md.getMediaType()); if (mediaType != null) { switch (mediaType) { case AUDIO: this.audioDescriptor = md; break; case VIDEO: this.videoDescriptor = md; break; case APPLICATION: this.applicationDescriptor = md; break; default: break; } } break; case 'a': if (md != null) { md.addAttribute(line); } else { // Identify ICE usage if(!this.ice) { this.ice = isIceAttribute(line); } if (line.startsWith(WEBRTC_FINGERPRINT)) { addFingerprintAttribute(line); break; } } break; } } } /** * Gets version attribute. * * @return the value of version attribute */ public Text getVersion() { return version; } public void setVersion(String version) { this.version = new Text(version); } /** * Gets the origin attribute * * @return origin attribute */ public OriginField getOrigin() { return origin; } public void setOrigin(String name, String sessionID, String sessionVersion, String netType, String addressType, String address) { this.origin = new OriginField(name, sessionID, sessionVersion, netType, addressType, address); } /** * Gets session identifier. * * @return session identifier value. */ public String getSession() { return session.toString(); } /** * Gets connection attribute. * * @return the connection attribute. */ public ConnectionField getConnection() { return connection; } /** * Gets the time attribute. * * @return time attribute. */ public TimeField getTime() { return time; } public Text getFingerprint() { return fingerprint; } public Text getFingerprint(MediaType mediaType) { if(MediaType.AUDIO.equals(mediaType)) { return getFingerprint(this.audioDescriptor); } return this.fingerprint; } private Text getFingerprint(MediaDescriptorField mediaStream) { Text value = mediaStream.getWebRTCFingerprint(); if(value != null && value.length() > 0) { return value; } return this.fingerprint; } /** * Gets the media attributes. * * @return collection of media attributes. */ public Collection<MediaDescriptorField> getMedia() { return mds; } /** * Gets the description of audio stream. * * @return the descriptor object. */ public MediaDescriptorField getAudioDescriptor() { return this.audioDescriptor; } /** * Gets the description of video stream. * * @return the descriptor object. */ public MediaDescriptorField getVideoDescriptor() { return this.videoDescriptor; } /** * Gets the description of application stream * @return the description object */ public MediaDescriptorField getApplicationDescriptor() { return applicationDescriptor; } public boolean hasAudioDescriptor() { return this.audioDescriptor != null; } public boolean hasVideoDescriptor() { return this.videoDescriptor != null; } public boolean hasApplicationDescriptor() { return this.applicationDescriptor != null; } private boolean isIceAttribute(Text line) { return line.startsWith(ICE_UFRAG) || line.startsWith(ICE_PWD) || line.startsWith(ICE_CANDIDATE); } public boolean isIce() { return ice; } public boolean isAudioIce() { return this.ice || this.getAudioDescriptor().isIce(); } /** * Register a new fingerprint attribute for WebRTC calls.<br> * Example: <code>a=fingerprint:sha-256 E5:52:E5:88:CC:B6:7A:D7:8E:...</code> * * @param attribute * The attribute line to be registered. * @throws IllegalArgumentException * If the attribute is not a valid FMT line. */ private void addFingerprintAttribute(Text attribute) throws IllegalArgumentException { // Remove line type 'a=fingerprint:' Text fingerprint = (Text) attribute.subSequence(WEBRTC_FINGERPRINT.length(), attribute.length()); this.fingerprint = fingerprint; } public void reset() { this.version = null; this.session = null; // TODO this.origin.reset(); this.connection.reset(); this.time.reset(); this.mds.clear(); this.md = null; this.audioDescriptor = null; this.videoDescriptor = null; this.applicationDescriptor = null; this.fingerprint = null; this.ice = false; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append(String.format("v=%s\n", version.toString())); builder.append(origin.toString()); return builder.toString(); } }