| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- /*
- 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];
- }
-
- }
|