|
@@ -1,230 +0,0 @@
|
|
|
-/*
|
|
|
|
|
- This file is part of Peers, a java SIP softphone.
|
|
|
|
|
-
|
|
|
|
|
- This program is free software: you can redistribute it and/or modify
|
|
|
|
|
- it under the terms of the GNU General Public License as published by
|
|
|
|
|
- the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
- any later version.
|
|
|
|
|
-
|
|
|
|
|
- This program 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 General Public License for more details.
|
|
|
|
|
-
|
|
|
|
|
- You should have received a copy of the GNU General Public License
|
|
|
|
|
- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
-
|
|
|
|
|
- Copyright 2007, 2008, 2009, 2010 Yohann Martineau
|
|
|
|
|
-*/
|
|
|
|
|
-
|
|
|
|
|
-package com.genersoft.iot.vmp.gb28181.sdp;
|
|
|
|
|
-
|
|
|
|
|
-import java.io.BufferedReader;
|
|
|
|
|
-import java.io.ByteArrayInputStream;
|
|
|
|
|
-import java.io.IOException;
|
|
|
|
|
-import java.io.InputStreamReader;
|
|
|
|
|
-import java.net.InetAddress;
|
|
|
|
|
-import java.util.ArrayList;
|
|
|
|
|
-import java.util.Hashtable;
|
|
|
|
|
-import java.util.List;
|
|
|
|
|
-
|
|
|
|
|
-public class SdpParser {
|
|
|
|
|
-
|
|
|
|
|
- public SessionDescription parse(byte[] body) throws IOException {
|
|
|
|
|
- if (body == null || body.length == 0) {
|
|
|
|
|
- return null;
|
|
|
|
|
- }
|
|
|
|
|
- ByteArrayInputStream in = new ByteArrayInputStream(body);
|
|
|
|
|
- InputStreamReader inputStreamReader = new InputStreamReader(in);
|
|
|
|
|
- BufferedReader reader = new BufferedReader(inputStreamReader);
|
|
|
|
|
- SessionDescription sessionDescription = new SessionDescription();
|
|
|
|
|
-
|
|
|
|
|
- //version
|
|
|
|
|
-
|
|
|
|
|
- String line = reader.readLine();
|
|
|
|
|
- if (line.length() < 3) {
|
|
|
|
|
- return null;
|
|
|
|
|
- }
|
|
|
|
|
- if (line.charAt(0) != RFC4566_28181.TYPE_VERSION
|
|
|
|
|
- || line.charAt(1) != RFC4566_28181.SEPARATOR
|
|
|
|
|
- || line.charAt(2) != RFC4566_28181.VERSION) {
|
|
|
|
|
- return null;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- //origin
|
|
|
|
|
-
|
|
|
|
|
- line = reader.readLine();
|
|
|
|
|
- if (line.length() < 3) {
|
|
|
|
|
- return null;
|
|
|
|
|
- }
|
|
|
|
|
- if (line.charAt(0) != RFC4566_28181.TYPE_ORIGIN
|
|
|
|
|
- || line.charAt(1) != RFC4566_28181.SEPARATOR) {
|
|
|
|
|
- return null;
|
|
|
|
|
- }
|
|
|
|
|
- line = line.substring(2);
|
|
|
|
|
- String[] originArr = line.split(" ");
|
|
|
|
|
- if (originArr == null || originArr.length != 6) {
|
|
|
|
|
- return null;
|
|
|
|
|
- }
|
|
|
|
|
- sessionDescription.setUsername(originArr[0]);
|
|
|
|
|
- sessionDescription.setId(Long.parseLong(originArr[1]));
|
|
|
|
|
- sessionDescription.setVersion(Long.parseLong(originArr[2]));
|
|
|
|
|
- sessionDescription.setIpAddress(InetAddress.getByName(originArr[5]));
|
|
|
|
|
-
|
|
|
|
|
- //name
|
|
|
|
|
-
|
|
|
|
|
- line = reader.readLine();
|
|
|
|
|
- if (line.length() < 3) {
|
|
|
|
|
- return null;
|
|
|
|
|
- }
|
|
|
|
|
- if (line.charAt(0) != RFC4566_28181.TYPE_SUBJECT
|
|
|
|
|
- || line.charAt(1) != RFC4566_28181.SEPARATOR) {
|
|
|
|
|
- return null;
|
|
|
|
|
- }
|
|
|
|
|
- sessionDescription.setName(line.substring(2));
|
|
|
|
|
-
|
|
|
|
|
- //session connection and attributes
|
|
|
|
|
- Hashtable<String, String> sessionAttributes = new Hashtable<String, String>();
|
|
|
|
|
- sessionDescription.setAttributes(sessionAttributes);
|
|
|
|
|
-
|
|
|
|
|
- while ((line = reader.readLine()) != null
|
|
|
|
|
- && line.charAt(0) != RFC4566_28181.TYPE_MEDIA) {
|
|
|
|
|
- if (line.length() > 3
|
|
|
|
|
- && line.charAt(0) == RFC4566_28181.TYPE_CONNECTION
|
|
|
|
|
- && line.charAt(1) == RFC4566_28181.SEPARATOR) {
|
|
|
|
|
- String connection = parseConnection(line.substring(2));
|
|
|
|
|
- if (connection == null) {
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
- sessionDescription.setIpAddress(InetAddress.getByName(connection));
|
|
|
|
|
- } else if (line.length() > 3
|
|
|
|
|
- && line.charAt(0) == RFC4566_28181.TYPE_ATTRIBUTE
|
|
|
|
|
- && line.charAt(1) == RFC4566_28181.SEPARATOR) {
|
|
|
|
|
- String value = line.substring(2);
|
|
|
|
|
- int pos = value.indexOf(RFC4566_28181.ATTR_SEPARATOR);
|
|
|
|
|
- if (pos > -1) {
|
|
|
|
|
- sessionAttributes.put(value.substring(0, pos),
|
|
|
|
|
- value.substring(pos + 1));
|
|
|
|
|
- } else {
|
|
|
|
|
- sessionAttributes.put(value, "");
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- if (line == null) {
|
|
|
|
|
- return null;
|
|
|
|
|
- }
|
|
|
|
|
- //we are at the first media line
|
|
|
|
|
-
|
|
|
|
|
- ArrayList<SdpLine> mediaLines = new ArrayList<SdpLine>();
|
|
|
|
|
- do {
|
|
|
|
|
- if (line.length() < 2) {
|
|
|
|
|
- return null;
|
|
|
|
|
- }
|
|
|
|
|
- if (line.charAt(1) != RFC4566_28181.SEPARATOR) {
|
|
|
|
|
- return null;
|
|
|
|
|
- }
|
|
|
|
|
- if (line.charAt(0) == RFC4566_28181.TYPE_SSRC) {
|
|
|
|
|
- sessionDescription.setSsrc(line.length() >=2 ?line.substring(2):"");
|
|
|
|
|
- }else if (line.charAt(0) == RFC4566_28181.TYPE_MEDIA_DES) {
|
|
|
|
|
- sessionDescription.setGbMediaDescriptions(line.length() >=2 ?line.substring(2):"");
|
|
|
|
|
- }else {
|
|
|
|
|
- SdpLine mediaLine = new SdpLine();
|
|
|
|
|
- mediaLine.setType(line.charAt(0));
|
|
|
|
|
- mediaLine.setValue(line.substring(2));
|
|
|
|
|
- mediaLines.add(mediaLine);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- }
|
|
|
|
|
- while ((line = reader.readLine()) != null );
|
|
|
|
|
-
|
|
|
|
|
- ArrayList<MediaDescription> mediaDescriptions = new ArrayList<MediaDescription>();
|
|
|
|
|
- sessionDescription.setMediaDescriptions(mediaDescriptions);
|
|
|
|
|
-
|
|
|
|
|
- for (SdpLine sdpLine : mediaLines) {
|
|
|
|
|
- MediaDescription mediaDescription;
|
|
|
|
|
- if (sdpLine.getType() == RFC4566_28181.TYPE_MEDIA) {
|
|
|
|
|
- String[] mediaArr = sdpLine.getValue().split(" ");
|
|
|
|
|
- if (mediaArr == null || mediaArr.length < 4) {
|
|
|
|
|
- return null;
|
|
|
|
|
- }
|
|
|
|
|
- mediaDescription = new MediaDescription();
|
|
|
|
|
- mediaDescription.setType(mediaArr[0]);
|
|
|
|
|
- //TODO manage port range
|
|
|
|
|
- mediaDescription.setPort(Integer.parseInt(mediaArr[1]));
|
|
|
|
|
- mediaDescription.setAttributes(new Hashtable<String, String>());
|
|
|
|
|
- List<Codec> codecs = new ArrayList<Codec>();
|
|
|
|
|
- for (int i = 3; i < mediaArr.length; ++i) {
|
|
|
|
|
- int payloadType = Integer.parseInt(mediaArr[i]);
|
|
|
|
|
- Codec codec = new Codec();
|
|
|
|
|
- codec.setPayloadType(payloadType);
|
|
|
|
|
- codec.setName("unsupported");
|
|
|
|
|
- codecs.add(codec);
|
|
|
|
|
- }
|
|
|
|
|
- mediaDescription.setCodecs(codecs);
|
|
|
|
|
- mediaDescriptions.add(mediaDescription);
|
|
|
|
|
- } else {
|
|
|
|
|
- mediaDescription = mediaDescriptions.get(mediaDescriptions.size() - 1);
|
|
|
|
|
- String sdpLineValue = sdpLine.getValue();
|
|
|
|
|
- if (sdpLine.getType() == RFC4566_28181.TYPE_CONNECTION) {
|
|
|
|
|
- String ipAddress = parseConnection(sdpLineValue);
|
|
|
|
|
- mediaDescription.setIpAddress(InetAddress.getByName(ipAddress));
|
|
|
|
|
- } else if (sdpLine.getType() == RFC4566_28181.TYPE_ATTRIBUTE) {
|
|
|
|
|
- Hashtable<String, String> attributes = mediaDescription.getAttributes();
|
|
|
|
|
- int pos = sdpLineValue.indexOf(RFC4566_28181.ATTR_SEPARATOR);
|
|
|
|
|
- if (pos > -1) {
|
|
|
|
|
- String name = sdpLineValue.substring(0, pos);
|
|
|
|
|
- String value = sdpLineValue.substring(pos + 1);
|
|
|
|
|
- pos = value.indexOf(" ");
|
|
|
|
|
- if (pos > -1) {
|
|
|
|
|
- int payloadType;
|
|
|
|
|
- try {
|
|
|
|
|
- payloadType = Integer.parseInt(value.substring(0, pos));
|
|
|
|
|
- List<Codec> codecs = mediaDescription.getCodecs();
|
|
|
|
|
- for (Codec codec: codecs) {
|
|
|
|
|
- if (codec.getPayloadType() == payloadType) {
|
|
|
|
|
- value = value.substring(pos + 1);
|
|
|
|
|
- pos = value.indexOf("/");
|
|
|
|
|
- if (pos > -1) {
|
|
|
|
|
- value = value.substring(0, pos);
|
|
|
|
|
- codec.setName(value);
|
|
|
|
|
- }
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- } catch (NumberFormatException e) {
|
|
|
|
|
- attributes.put(name, value);
|
|
|
|
|
- }
|
|
|
|
|
- } else {
|
|
|
|
|
- attributes.put(name, value);
|
|
|
|
|
- }
|
|
|
|
|
- } else {
|
|
|
|
|
- attributes.put(sdpLineValue, "");
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- sessionDescription.setMediaDescriptions(mediaDescriptions);
|
|
|
|
|
-
|
|
|
|
|
- for (MediaDescription description : mediaDescriptions) {
|
|
|
|
|
- if (description.getIpAddress() == null) {
|
|
|
|
|
- InetAddress sessionAddress = sessionDescription.getIpAddress();
|
|
|
|
|
- if (sessionAddress == null) {
|
|
|
|
|
- return null;
|
|
|
|
|
- }
|
|
|
|
|
- description.setIpAddress(sessionAddress);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- return sessionDescription;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private String parseConnection(String line) {
|
|
|
|
|
- String[] connectionArr = line.split(" ");
|
|
|
|
|
- if (connectionArr == null || connectionArr.length != 3) {
|
|
|
|
|
- return null;
|
|
|
|
|
- }
|
|
|
|
|
- return connectionArr[2];
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
-}
|
|
|